Skip to content

Commit 4c98da2

Browse files
authored
[clang][bytecode] Create a temporary for discarded CXXBindTemporaryExprs (#147303)
So we run the destructor.
1 parent 862c2fc commit 4c98da2

File tree

3 files changed

+21
-2
lines changed

3 files changed

+21
-2
lines changed

clang/lib/AST/ByteCode/Compiler.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2886,7 +2886,20 @@ bool Compiler<Emitter>::VisitMaterializeTemporaryExpr(
28862886
template <class Emitter>
28872887
bool Compiler<Emitter>::VisitCXXBindTemporaryExpr(
28882888
const CXXBindTemporaryExpr *E) {
2889-
return this->delegate(E->getSubExpr());
2889+
const Expr *SubExpr = E->getSubExpr();
2890+
2891+
if (Initializing)
2892+
return this->delegate(SubExpr);
2893+
2894+
// Make sure we create a temporary even if we're discarding, since that will
2895+
// make sure we will also call the destructor.
2896+
2897+
if (!this->visit(SubExpr))
2898+
return false;
2899+
2900+
if (DiscardResult)
2901+
return this->emitPopPtr(E);
2902+
return true;
28902903
}
28912904

28922905
template <class Emitter>

clang/lib/AST/ByteCode/Context.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,8 @@ bool Context::evaluateAsRValue(State &Parent, const Expr *E, APValue &Result) {
6767
}
6868

6969
if (!Recursing) {
70-
assert(Stk.empty());
70+
// We *can* actually get here with a non-empty stack, since
71+
// things like InterpState::noteSideEffect() exist.
7172
C.cleanup();
7273
#ifndef NDEBUG
7374
// Make sure we don't rely on some value being still alive in

clang/test/SemaCXX/cxx2a-constexpr-dynalloc.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@
33
// RUN: %clang_cc1 -std=c++2a -verify=expected,cxx20 %s "-DNEW=::operator new" "-DDELETE=::operator delete"
44
// RUN: %clang_cc1 -std=c++2c -verify=expected,cxx26 %s "-DNEW=::operator new" "-DDELETE=::operator delete"
55

6+
// RUN: %clang_cc1 -std=c++2a -verify=expected,cxx20 %s -DNEW=__builtin_operator_new -DDELETE=__builtin_operator_delete
7+
// RUN: %clang_cc1 -std=c++2a -verify=expected,cxx20 %s "-DNEW=operator new" "-DDELETE=operator delete"
8+
// RUN: %clang_cc1 -std=c++2a -verify=expected,cxx20 %s "-DNEW=::operator new" "-DDELETE=::operator delete"
9+
// RUN: %clang_cc1 -std=c++2c -verify=expected,cxx26 %s "-DNEW=::operator new" "-DDELETE=::operator delete"
10+
611
constexpr bool alloc_from_user_code() {
712
void *p = NEW(sizeof(int)); // expected-note {{cannot allocate untyped memory in a constant expression; use 'std::allocator<T>::allocate'}}
813
DELETE(p);

0 commit comments

Comments
 (0)