[clang] [clang][bytecode] Create a temporary for discarded CXXBindTemporaryExprs (PR #147303)
Timm Baeder via cfe-commits
cfe-commits at lists.llvm.org
Mon Jul 7 06:54:07 PDT 2025
https://github.com/tbaederr created https://github.com/llvm/llvm-project/pull/147303
So we run the destructor.
>From c567da7e6be38496e428015af6fb2a5daf60b450 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbaeder at redhat.com>
Date: Mon, 7 Jul 2025 15:48:14 +0200
Subject: [PATCH] [clang][bytecode] Create a temporary for discarded
CXXBindTemporaryExprs
So we run the destructor.
---
clang/lib/AST/ByteCode/Compiler.cpp | 15 ++++++++++++++-
clang/lib/AST/ByteCode/Context.cpp | 3 ++-
clang/test/SemaCXX/cxx2a-constexpr-dynalloc.cpp | 5 +++++
3 files changed, 21 insertions(+), 2 deletions(-)
diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp
index d1c93e4694667..51c234d0d0471 100644
--- a/clang/lib/AST/ByteCode/Compiler.cpp
+++ b/clang/lib/AST/ByteCode/Compiler.cpp
@@ -2886,7 +2886,20 @@ bool Compiler<Emitter>::VisitMaterializeTemporaryExpr(
template <class Emitter>
bool Compiler<Emitter>::VisitCXXBindTemporaryExpr(
const CXXBindTemporaryExpr *E) {
- return this->delegate(E->getSubExpr());
+ const Expr *SubExpr = E->getSubExpr();
+
+ if (Initializing)
+ return this->delegate(SubExpr);
+
+ // Make sure we create a temporary even if we're discarding, since that will
+ // make sure we will also call the destructor.
+
+ if (!this->visit(SubExpr))
+ return false;
+
+ if (DiscardResult)
+ return this->emitPopPtr(E);
+ return true;
}
template <class Emitter>
diff --git a/clang/lib/AST/ByteCode/Context.cpp b/clang/lib/AST/ByteCode/Context.cpp
index 971eb7fd58876..a629ff9569428 100644
--- a/clang/lib/AST/ByteCode/Context.cpp
+++ b/clang/lib/AST/ByteCode/Context.cpp
@@ -67,7 +67,8 @@ bool Context::evaluateAsRValue(State &Parent, const Expr *E, APValue &Result) {
}
if (!Recursing) {
- assert(Stk.empty());
+ // We *can* actually get here with a non-empty stack, since
+ // things like InterpState::noteSideEffect() exist.
C.cleanup();
#ifndef NDEBUG
// Make sure we don't rely on some value being still alive in
diff --git a/clang/test/SemaCXX/cxx2a-constexpr-dynalloc.cpp b/clang/test/SemaCXX/cxx2a-constexpr-dynalloc.cpp
index c5d5427170394..86bed5f14441e 100644
--- a/clang/test/SemaCXX/cxx2a-constexpr-dynalloc.cpp
+++ b/clang/test/SemaCXX/cxx2a-constexpr-dynalloc.cpp
@@ -3,6 +3,11 @@
// RUN: %clang_cc1 -std=c++2a -verify=expected,cxx20 %s "-DNEW=::operator new" "-DDELETE=::operator delete"
// RUN: %clang_cc1 -std=c++2c -verify=expected,cxx26 %s "-DNEW=::operator new" "-DDELETE=::operator delete"
+// RUN: %clang_cc1 -std=c++2a -verify=expected,cxx20 %s -DNEW=__builtin_operator_new -DDELETE=__builtin_operator_delete
+// RUN: %clang_cc1 -std=c++2a -verify=expected,cxx20 %s "-DNEW=operator new" "-DDELETE=operator delete"
+// RUN: %clang_cc1 -std=c++2a -verify=expected,cxx20 %s "-DNEW=::operator new" "-DDELETE=::operator delete"
+// RUN: %clang_cc1 -std=c++2c -verify=expected,cxx26 %s "-DNEW=::operator new" "-DDELETE=::operator delete"
+
constexpr bool alloc_from_user_code() {
void *p = NEW(sizeof(int)); // expected-note {{cannot allocate untyped memory in a constant expression; use 'std::allocator<T>::allocate'}}
DELETE(p);
More information about the cfe-commits
mailing list