[clang] [clang] Fixed Constant Evaluation don't Call Destructor (PR #140278)
via cfe-commits
cfe-commits at lists.llvm.org
Tue May 20 14:12:37 PDT 2025
https://github.com/Mr-Anyone updated https://github.com/llvm/llvm-project/pull/140278
>From f710719f3e7260c5406997013d893f8f532940ac Mon Sep 17 00:00:00 2001
From: Vincent <llvm at viceroygroup.ca>
Date: Wed, 14 May 2025 16:36:35 -0400
Subject: [PATCH 1/4] [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 0c12091a90add..76c139632b31c 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -623,6 +623,7 @@ Bug Fixes in This Version
- Fix crash due to unknown references and pointer implementation and handling of
base classes. (GH139452)
- Fixed an assertion failure in serialization of constexpr structs containing unions. (#GH140130)
+- 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 ca1fbdf7e652f..d8364977258a1 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -5742,8 +5742,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 at -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 at -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 at -1 {{in call to 'f2()'}}
+};
>From fb3f878df13c770e5c4543c8e0b093546d4e2150 Mon Sep 17 00:00:00 2001
From: Vincent <vincent0710 at outlook.com>
Date: Tue, 20 May 2025 16:24:55 -0400
Subject: [PATCH 2/4] Update clang/docs/ReleaseNotes.rst
Co-authored-by: Sirraide <aeternalmail at 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 76c139632b31c..89c86f706857d 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -623,7 +623,8 @@ Bug Fixes in This Version
- Fix crash due to unknown references and pointer implementation and handling of
base classes. (GH139452)
- Fixed an assertion failure in serialization of constexpr structs containing unions. (#GH140130)
-- 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 a99bd67ccf046679d8f85e5d7e9fdd1b2c8b539b Mon Sep 17 00:00:00 2001
From: Vincent <llvm at viceroygroup.ca>
Date: Tue, 20 May 2025 16:40:52 -0400
Subject: [PATCH 3/4] 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 at -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 at -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 at -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 at -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 at -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 at -1 {{in call to 'f2()'}}
-};
>From c475e9e2938f5efaa65c49a2eba37b814ebda1bf Mon Sep 17 00:00:00 2001
From: Vincent <llvm at viceroygroup.ca>
Date: Tue, 20 May 2025 17:12:22 -0400
Subject: [PATCH 4/4] 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 at -1 {{subexpression not valid in a constant expression}}
+ // expected-error at -1 {{constexpr function never produces a constant expression}}
+ // expected-note at -2 {{subexpression not valid in a constant expression}}
+ // expected-note at -3 {{subexpression not valid in a constant expression}}
constexpr operator bool() {
return b;
}
More information about the cfe-commits
mailing list