https://github.com/Mr-Anyone updated https://github.com/llvm/llvm-project/pull/140278
>From f00de5a405f7d59493d21a379cdfa66900e62a93 Mon Sep 17 00:00:00 2001 From: Vincent <l...@viceroygroup.ca> Date: Wed, 14 May 2025 16:36:35 -0400 Subject: [PATCH 1/5] [clang] Fixed Constant Evaluation don't Call Destructor Within the condition statement of the for block, the destructor doesn't get called during compile time evaluated constants. resolves #139818 --- clang/docs/ReleaseNotes.rst | 1 + clang/lib/AST/ExprConstant.cpp | 6 +++- clang/test/SemaCXX/static-assert-cxx26.cpp | 35 ++++++++++++++++++++++ 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index dc97883de05d0..f6782c6c68ad0 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -670,6 +670,7 @@ 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 different qualifiers, this should be well-formed. (#GH141397) +- Fix constant evaluation in for loop not calling destructor (#GH139818) Bug Fixes to Compiler Builtins ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index b20e2690d0eee..f4e5adf676c5b 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -5756,8 +5756,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/static-assert-cxx26.cpp b/clang/test/SemaCXX/static-assert-cxx26.cpp index b53c67ee67932..7a47f2784ceb3 100644 --- a/clang/test/SemaCXX/static-assert-cxx26.cpp +++ b/clang/test/SemaCXX/static-assert-cxx26.cpp @@ -416,3 +416,38 @@ static_assert( // expected-note@-1 {{read of dereferenced one-past-the-end pointer is not allowed in a constant expression}} ); } + +// taken from: https://github.com/llvm/llvm-project/issues/139818 +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-error {{cannot use 'throw' with exceptions disabled}} + // expected-note@-1 {{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()'}} +}; >From f8affc57fbba7ccf001ada5d420c6d2c29655436 Mon Sep 17 00:00:00 2001 From: Vincent <vincent0...@outlook.com> Date: Tue, 20 May 2025 16:24:55 -0400 Subject: [PATCH 2/5] Update clang/docs/ReleaseNotes.rst Co-authored-by: Sirraide <aeternalm...@gmail.com> --- clang/docs/ReleaseNotes.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index f6782c6c68ad0..0af088e133917 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -670,7 +670,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 different qualifiers, this should be well-formed. (#GH141397) -- Fix constant evaluation in for loop not calling destructor (#GH139818) +- 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 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ >From 517082534c4259708cf6ecdcabfca1182f723d3c Mon Sep 17 00:00:00 2001 From: Vincent <l...@viceroygroup.ca> Date: Tue, 20 May 2025 16:40:52 -0400 Subject: [PATCH 3/5] Moved Test to `cxx2a-consteval.cpp` --- clang/test/SemaCXX/cxx2a-consteval.cpp | 33 ++++++++++++++++++++ clang/test/SemaCXX/static-assert-cxx26.cpp | 35 ---------------------- 2 files changed, 33 insertions(+), 35 deletions(-) diff --git a/clang/test/SemaCXX/cxx2a-consteval.cpp b/clang/test/SemaCXX/cxx2a-consteval.cpp index d9932e4dd8241..3df503fa1277f 100644 --- a/clang/test/SemaCXX/cxx2a-consteval.cpp +++ b/clang/test/SemaCXX/cxx2a-consteval.cpp @@ -1321,4 +1321,37 @@ namespace GH139160{ // expected-note@-2 {{non-constexpr function 'make_struct' cannot be used in a constant expression}} }; +// taken from: https://github.com/llvm/llvm-project/issues/139818 +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-error {{cannot use 'throw' with exceptions disabled}} + // expected-note@-1 {{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()'}} +}; diff --git a/clang/test/SemaCXX/static-assert-cxx26.cpp b/clang/test/SemaCXX/static-assert-cxx26.cpp index 7a47f2784ceb3..b53c67ee67932 100644 --- a/clang/test/SemaCXX/static-assert-cxx26.cpp +++ b/clang/test/SemaCXX/static-assert-cxx26.cpp @@ -416,38 +416,3 @@ static_assert( // expected-note@-1 {{read of dereferenced one-past-the-end pointer is not allowed in a constant expression}} ); } - -// taken from: https://github.com/llvm/llvm-project/issues/139818 -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-error {{cannot use 'throw' with exceptions disabled}} - // expected-note@-1 {{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()'}} -}; >From 953fa463eb89420d8faa52e58200de7eb5908845 Mon Sep 17 00:00:00 2001 From: Vincent <l...@viceroygroup.ca> Date: Tue, 20 May 2025 17:12:22 -0400 Subject: [PATCH 4/5] update error messages --- clang/test/SemaCXX/cxx2a-consteval.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/clang/test/SemaCXX/cxx2a-consteval.cpp b/clang/test/SemaCXX/cxx2a-consteval.cpp index 3df503fa1277f..bf71894caa339 100644 --- a/clang/test/SemaCXX/cxx2a-consteval.cpp +++ b/clang/test/SemaCXX/cxx2a-consteval.cpp @@ -1342,7 +1342,9 @@ namespace GH139818{ struct Y { constexpr ~Y() noexcept(false) { throw "oops"; } // expected-error {{cannot use 'throw' with exceptions disabled}} - // expected-note@-1 {{subexpression not valid in a constant expression}} + // expected-error@-1 {{constexpr function never produces a constant expression}} + // expected-note@-2 {{subexpression not valid in a constant expression}} + // expected-note@-3 {{subexpression not valid in a constant expression}} constexpr operator bool() { return b; } >From 123f6b5df9fec088863cbc7118c991b4117532e0 Mon Sep 17 00:00:00 2001 From: Vincent <l...@viceroygroup.ca> Date: Wed, 21 May 2025 15:04:26 -0400 Subject: [PATCH 5/5] Moved Test to Different File --- clang/test/SemaCXX/cxx2a-consteval.cpp | 35 ------------------------- clang/test/SemaCXX/gh139818.cpp | 36 ++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 35 deletions(-) create mode 100644 clang/test/SemaCXX/gh139818.cpp diff --git a/clang/test/SemaCXX/cxx2a-consteval.cpp b/clang/test/SemaCXX/cxx2a-consteval.cpp index bf71894caa339..d9932e4dd8241 100644 --- a/clang/test/SemaCXX/cxx2a-consteval.cpp +++ b/clang/test/SemaCXX/cxx2a-consteval.cpp @@ -1321,39 +1321,4 @@ namespace GH139160{ // expected-note@-2 {{non-constexpr function 'make_struct' cannot be used in a constant expression}} }; -// taken from: https://github.com/llvm/llvm-project/issues/139818 -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-error {{cannot use 'throw' with exceptions disabled}} - // expected-error@-1 {{constexpr function never produces a constant expression}} - // expected-note@-2 {{subexpression not valid in a constant expression}} - // expected-note@-3 {{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()'}} -}; diff --git a/clang/test/SemaCXX/gh139818.cpp b/clang/test/SemaCXX/gh139818.cpp new file mode 100644 index 0000000000000..384445c38b60d --- /dev/null +++ b/clang/test/SemaCXX/gh139818.cpp @@ -0,0 +1,36 @@ +// RUN: %clang_cc1 -std=c++23 -fsyntax-only %s -verify +// RUN: %clang_cc1 -std=c++23 -fsyntax-only %s -verify -fexperimental-new-constant-interpreter + +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-error {{cannot use 'throw' with exceptions disabled}} + // expected-note@-1 {{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