Skip to content

Commit f00de5a

Browse files
committed
[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
1 parent 7786ac0 commit f00de5a

File tree

3 files changed

+41
-1
lines changed

3 files changed

+41
-1
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -670,6 +670,7 @@ Bug Fixes in This Version
670670
- Fixed an assertion failure in serialization of constexpr structs containing unions. (#GH140130)
671671
- Fixed duplicate entries in TableGen that caused the wrong attribute to be selected. (GH#140701)
672672
- Fixed type mismatch error when 'builtin-elementwise-math' arguments have different qualifiers, this should be well-formed. (#GH141397)
673+
- Fix constant evaluation in for loop not calling destructor (#GH139818)
673674

674675
Bug Fixes to Compiler Builtins
675676
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

clang/lib/AST/ExprConstant.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5756,8 +5756,12 @@ static EvalStmtResult EvaluateStmt(StmtResult &Result, EvalInfo &Info,
57565756
if (FS->getCond() && !EvaluateCond(Info, FS->getConditionVariable(),
57575757
FS->getCond(), Continue))
57585758
return ESR_Failed;
5759-
if (!Continue)
5759+
5760+
if (!Continue) {
5761+
if (!IterScope.destroy())
5762+
return ESR_Failed;
57605763
break;
5764+
}
57615765

57625766
EvalStmtResult ESR = EvaluateLoopBody(Result, Info, FS->getBody());
57635767
if (ESR != ESR_Continue) {

clang/test/SemaCXX/static-assert-cxx26.cpp

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -416,3 +416,38 @@ static_assert(
416416
// expected-note@-1 {{read of dereferenced one-past-the-end pointer is not allowed in a constant expression}}
417417
);
418418
}
419+
420+
// taken from: https://github.com/llvm/llvm-project/issues/139818
421+
namespace GH139818{
422+
struct A {
423+
constexpr ~A() { ref = false; }
424+
constexpr operator bool() {
425+
return b;
426+
}
427+
bool b;
428+
bool& ref;
429+
};
430+
431+
constexpr bool f1() {
432+
bool ret = true;
433+
for (bool b = false; A x{b, ret}; b = true) {}
434+
return ret;
435+
}
436+
437+
static_assert(!f1());
438+
439+
struct Y {
440+
constexpr ~Y() noexcept(false) { throw "oops"; } // expected-error {{cannot use 'throw' with exceptions disabled}}
441+
// expected-note@-1 {{subexpression not valid in a constant expression}}
442+
constexpr operator bool() {
443+
return b;
444+
}
445+
bool b;
446+
};
447+
constexpr bool f2() {
448+
for (bool b = false; Y x = {b}; b = true) {} // expected-note {{in call to 'x.~Y()'}}
449+
return true;
450+
}
451+
static_assert(f2()); // expected-error {{static assertion expression is not an integral constant expression}}
452+
// expected-note@-1 {{in call to 'f2()'}}
453+
};

0 commit comments

Comments
 (0)