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?= <tbae...@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);

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to