https://github.com/tbaederr created 
https://github.com/llvm/llvm-project/pull/207959

Rename the `EndLifetimePop` op (which was only used for pseudo dtors) to 
`PseudoDtor` and call `checkDestructor()` in there, so we get the full suite of 
checks.

>From aa29b0c46e6934d122120c22af97ab1caa6362a2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= <[email protected]>
Date: Tue, 7 Jul 2026 12:18:34 +0200
Subject: [PATCH] [clang][bytecode] Add more checks for pseudo dtors

Rename the `EndLifetimePop` op (which was only used for pseudo dtors) to
`PseudoDtor` and call `checkDestructor()` in there, so we get the full
suite of checks.
---
 clang/lib/AST/ByteCode/Compiler.cpp |  2 +-
 clang/lib/AST/ByteCode/Interp.cpp   |  9 ++++-----
 clang/lib/AST/ByteCode/Interp.h     |  6 +++---
 clang/lib/AST/ByteCode/Opcodes.td   |  2 +-
 clang/test/AST/ByteCode/cxx2a.cpp   | 17 ++++++++++++++++-
 5 files changed, 25 insertions(+), 11 deletions(-)

diff --git a/clang/lib/AST/ByteCode/Compiler.cpp 
b/clang/lib/AST/ByteCode/Compiler.cpp
index b4468c94ff675..48f5ee8115429 100644
--- a/clang/lib/AST/ByteCode/Compiler.cpp
+++ b/clang/lib/AST/ByteCode/Compiler.cpp
@@ -6189,7 +6189,7 @@ bool Compiler<Emitter>::VisitCallExpr(const CallExpr *E) {
       return this->discard(Base);
     if (!this->visit(Base))
       return false;
-    return this->emitEndLifetimePop(E);
+    return this->emitPseudoDtor(E);
   } else if (!FuncDecl) {
     const Expr *Callee = E->getCallee();
     CalleeOffset =
diff --git a/clang/lib/AST/ByteCode/Interp.cpp 
b/clang/lib/AST/ByteCode/Interp.cpp
index ce044e7b47e11..8a6d024eda3af 100644
--- a/clang/lib/AST/ByteCode/Interp.cpp
+++ b/clang/lib/AST/ByteCode/Interp.cpp
@@ -1719,7 +1719,7 @@ static bool diagnoseOutOfLifetimeDestroy(InterpState &S, 
CodePtr OpPC,
   return false;
 }
 
-bool CheckDestructor(InterpState &S, CodePtr OpPC, const Pointer &Ptr) {
+bool checkDestructor(InterpState &S, CodePtr OpPC, const Pointer &Ptr) {
   if (!CheckLive(S, OpPC, Ptr, AK_Destroy))
     return false;
   if (!CheckTemporary(S, OpPC, Ptr.block(), AK_Destroy))
@@ -1920,7 +1920,7 @@ bool Call(InterpState &S, CodePtr OpPC, const Function 
*Func,
 
     if (Func->isConstructor() && !checkConstructor(S, OpPC, Func, ThisPtr))
       return false;
-    if (Func->isDestructor() && !CheckDestructor(S, OpPC, ThisPtr))
+    if (Func->isDestructor() && !checkDestructor(S, OpPC, ThisPtr))
       return false;
 
     InstancePtrTracked = (Func->isConstructor() || Func->isDestructor());
@@ -2448,11 +2448,10 @@ bool EndLifetime(InterpState &S, CodePtr OpPC) {
 }
 
 /// Ends the lifetime of the pop'd pointer.
-bool EndLifetimePop(InterpState &S, CodePtr OpPC) {
+bool PseudoDtor(InterpState &S, CodePtr OpPC) {
   const auto &Ptr = S.Stk.pop<Pointer>();
-  if (Ptr.isBlockPointer() && !CheckDummy(S, OpPC, Ptr.block(), AK_Destroy))
+  if (!checkDestructor(S, OpPC, Ptr))
     return false;
-
   setLifeStateRecurse(Ptr.view().narrow(), Lifetime::Ended);
   return true;
 }
diff --git a/clang/lib/AST/ByteCode/Interp.h b/clang/lib/AST/ByteCode/Interp.h
index d16a00414f45a..201679017c98b 100644
--- a/clang/lib/AST/ByteCode/Interp.h
+++ b/clang/lib/AST/ByteCode/Interp.h
@@ -132,7 +132,7 @@ bool InvalidShuffleVectorIndex(InterpState &S, CodePtr 
OpPC, uint32_t Index);
 bool CheckBitCast(InterpState &S, CodePtr OpPC, bool HasIndeterminateBits,
                   bool TargetIsUCharOrByte);
 bool CheckBCPResult(InterpState &S, const Pointer &Ptr);
-bool CheckDestructor(InterpState &S, CodePtr OpPC, const Pointer &Ptr);
+bool checkDestructor(InterpState &S, CodePtr OpPC, const Pointer &Ptr);
 bool CheckFunctionDecl(InterpState &S, CodePtr OpPC, const FunctionDecl *FD);
 bool CheckBitCast(InterpState &S, CodePtr OpPC, const Type *TargetType,
                   bool SrcIsVoidPtr);
@@ -1627,7 +1627,7 @@ bool GetLocal(InterpState &S, CodePtr OpPC, uint32_t I) {
 }
 
 bool EndLifetime(InterpState &S, CodePtr OpPC);
-bool EndLifetimePop(InterpState &S, CodePtr OpPC);
+bool PseudoDtor(InterpState &S, CodePtr OpPC);
 bool StartThisLifetime(InterpState &S);
 bool StartThisLifetime1(InterpState &S);
 bool MarkDestroyed(InterpState &S, CodePtr OpPC);
@@ -4070,7 +4070,7 @@ bool DiagTypeid(InterpState &S, CodePtr OpPC);
 
 inline bool CheckDestruction(InterpState &S, CodePtr OpPC) {
   const auto &Ptr = S.Stk.peek<Pointer>();
-  return CheckDestructor(S, OpPC, Ptr);
+  return checkDestructor(S, OpPC, Ptr);
 }
 
 
//===----------------------------------------------------------------------===//
diff --git a/clang/lib/AST/ByteCode/Opcodes.td 
b/clang/lib/AST/ByteCode/Opcodes.td
index 577c8523ab6c3..1705ad9d9d24b 100644
--- a/clang/lib/AST/ByteCode/Opcodes.td
+++ b/clang/lib/AST/ByteCode/Opcodes.td
@@ -457,7 +457,7 @@ def SetLocal : AccessOpcode {
   let NeedsOpPC = 0;
 }
 
-def EndLifetimePop : Opcode;
+def PseudoDtor : Opcode;
 def EndLifetime : Opcode;
 def MarkDestroyed : Opcode;
 def StartThisLifetime : Opcode {
diff --git a/clang/test/AST/ByteCode/cxx2a.cpp 
b/clang/test/AST/ByteCode/cxx2a.cpp
index 78769a4def5b0..cc9ec1666440c 100644
--- a/clang/test/AST/ByteCode/cxx2a.cpp
+++ b/clang/test/AST/ByteCode/cxx2a.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++2a -fsyntax-only -fcxx-exceptions -verify=ref,both 
%s
+// RUN: %clang_cc1 -std=c++2a -fsyntax-only -fcxx-exceptions -verify=ref,both  
    %s
 // RUN: %clang_cc1 -std=c++2a -fsyntax-only -fcxx-exceptions 
-verify=expected,both %s -fexperimental-new-constant-interpreter
 
 
@@ -254,3 +254,18 @@ namespace DependentRequiresExpr {
 
   template <class T> using P = p<T>::type; // both-note {{while checking a 
default template argument}}
 }
+
+namespace PseudoDtorOnGlobal {
+  struct A {
+    int m;
+    mutable int n;
+    constexpr int f() const { return m; }
+    constexpr int g() const { return n; }
+  };
+
+  constexpr A a = {1, 2};
+  using T = int;
+  constexpr void destroy2() { // both-error {{never produces a constant 
expression}}
+    a.m.~T(); // both-note {{cannot modify an object that is visible outside}}
+  }
+}

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to