Author: Vincent Date: 2025-06-05T23:50:20+02:00 New Revision: 49386f40dd66ababe9bfde64c14cf3bfba5774c1
URL: https://github.com/llvm/llvm-project/commit/49386f40dd66ababe9bfde64c14cf3bfba5774c1 DIFF: https://github.com/llvm/llvm-project/commit/49386f40dd66ababe9bfde64c14cf3bfba5774c1.diff LOG: [Clang] Run destructors of variables declared in the second part of a `for` loop during constant evaluation (#140278) Within the condition statement of the for block, the destructor doesn't get called when evaluating compile time constants. Resolves #139818 Added: clang/test/SemaCXX/gh139818.cpp Modified: clang/docs/ReleaseNotes.rst clang/lib/AST/ExprConstant.cpp Removed: ################################################################################ diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 747388fb985aa..e926d60589808 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -685,6 +685,8 @@ Bug Fixes in This Version - Fixed an assertion failure in serialization of constexpr structs containing unions. (#GH140130) - Fixed duplicate entries in TableGen that caused the wrong attribute to be selected. (GH#140701) - Fixed type mismatch error when 'builtin-elementwise-math' arguments have diff erent qualifiers, this should be well-formed. (#GH141397) +- Constant evaluation now correctly runs the destructor of a variable declared in + the second clause of a C-style ``for`` loop. (#GH139818) Bug Fixes to Compiler Builtins ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 78dd9770f65f6..dd86eddecc682 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -5761,8 +5761,12 @@ static EvalStmtResult EvaluateStmt(StmtResult &Result, EvalInfo &Info, if (FS->getCond() && !EvaluateCond(Info, FS->getConditionVariable(), FS->getCond(), Continue)) return ESR_Failed; - if (!Continue) + + if (!Continue) { + if (!IterScope.destroy()) + return ESR_Failed; break; + } EvalStmtResult ESR = EvaluateLoopBody(Result, Info, FS->getBody()); if (ESR != ESR_Continue) { diff --git a/clang/test/SemaCXX/gh139818.cpp b/clang/test/SemaCXX/gh139818.cpp new file mode 100644 index 0000000000000..71a1e6e3b4547 --- /dev/null +++ b/clang/test/SemaCXX/gh139818.cpp @@ -0,0 +1,36 @@ +// RUN: %clang_cc1 -std=c++23 -fsyntax-only %s -verify -fcxx-exceptions +// RUN: %clang_cc1 -std=c++23 -fsyntax-only %s -verify -fexperimental-new-constant-interpreter -fcxx-exceptions + +namespace GH139818{ + struct A { + constexpr ~A() { ref = false; } + constexpr operator bool() { + return b; + } + bool b; + bool& ref; + }; + + constexpr bool f1() { + bool ret = true; + for (bool b = false; A x{b, ret}; b = true) {} + return ret; + } + + static_assert(!f1()); + + struct Y { + constexpr ~Y() noexcept(false) { throw "oops"; } // expected-note {{subexpression not valid in a constant expression}} + + constexpr operator bool() { + return b; + } + bool b; + }; + constexpr bool f2() { + for (bool b = false; Y x = {b}; b = true) {} // expected-note {{in call to 'x.~Y()'}} + return true; + } + static_assert(f2()); // expected-error {{static assertion expression is not an integral constant expression}} + // expected-note@-1 {{in call to 'f2()'}} +}; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits