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

None

>From 5677e610e30479b2da672fad3c2606115873bdbe Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbae...@redhat.com>
Date: Fri, 25 Apr 2025 11:48:03 +0200
Subject: [PATCH] [clang][bytecode] Diagnose pseudo dtor calls before C++20

---
 clang/lib/AST/ByteCode/Compiler.cpp |  2 ++
 clang/lib/AST/ByteCode/Interp.h     |  7 +++++++
 clang/lib/AST/ByteCode/Opcodes.td   |  1 +
 clang/test/AST/ByteCode/cxx11.cpp   | 17 +++++++++++++++--
 4 files changed, 25 insertions(+), 2 deletions(-)

diff --git a/clang/lib/AST/ByteCode/Compiler.cpp 
b/clang/lib/AST/ByteCode/Compiler.cpp
index 3c774c16696dc..fd306c0669d6c 100644
--- a/clang/lib/AST/ByteCode/Compiler.cpp
+++ b/clang/lib/AST/ByteCode/Compiler.cpp
@@ -4933,6 +4933,8 @@ bool Compiler<Emitter>::VisitCallExpr(const CallExpr *E) {
     }
   } else if (const auto *PD =
                  dyn_cast<CXXPseudoDestructorExpr>(E->getCallee())) {
+    if (!this->emitCheckPseudoDtor(E))
+      return false;
     const Expr *Base = PD->getBase();
     if (!Base->isGLValue())
       return this->discard(Base);
diff --git a/clang/lib/AST/ByteCode/Interp.h b/clang/lib/AST/ByteCode/Interp.h
index 0cfeed86f0b51..ac5e095ffa1f1 100644
--- a/clang/lib/AST/ByteCode/Interp.h
+++ b/clang/lib/AST/ByteCode/Interp.h
@@ -2947,6 +2947,13 @@ inline bool SizelessVectorElementSize(InterpState &S, 
CodePtr OpPC) {
   return false;
 }
 
+inline bool CheckPseudoDtor(InterpState &S, CodePtr OpPC) {
+  if (!S.getLangOpts().CPlusPlus20)
+    S.CCEDiag(S.Current->getSource(OpPC),
+              diag::note_constexpr_pseudo_destructor);
+  return true;
+}
+
 inline bool Assume(InterpState &S, CodePtr OpPC) {
   const auto Val = S.Stk.pop<Boolean>();
 
diff --git a/clang/lib/AST/ByteCode/Opcodes.td 
b/clang/lib/AST/ByteCode/Opcodes.td
index 8451e54ad0c41..7a1cc4e8c408a 100644
--- a/clang/lib/AST/ByteCode/Opcodes.td
+++ b/clang/lib/AST/ByteCode/Opcodes.td
@@ -783,6 +783,7 @@ def SideEffect : Opcode {}
 def InvalidCast : Opcode {
   let Args = [ArgCastKind, ArgBool];
 }
+def CheckPseudoDtor : Opcode {}
 
 def InvalidDeclRef : Opcode {
   let Args = [ArgDeclRef, ArgBool];
diff --git a/clang/test/AST/ByteCode/cxx11.cpp 
b/clang/test/AST/ByteCode/cxx11.cpp
index cb05f26d11206..18806801bdd33 100644
--- a/clang/test/AST/ByteCode/cxx11.cpp
+++ b/clang/test/AST/ByteCode/cxx11.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -triple x86_64-linux 
-fexperimental-new-constant-interpreter -verify=both,expected -std=c++11 %s
-// RUN: %clang_cc1 -triple x86_64-linux -verify=both,ref -std=c++11 %s
+// RUN: %clang_cc1 -triple x86_64-linux -verify=both,expected -std=c++11 %s 
-fexperimental-new-constant-interpreter
+// RUN: %clang_cc1 -triple x86_64-linux -verify=both,ref      -std=c++11 %s
 
 namespace IntOrEnum {
   const int k = 0;
@@ -208,3 +208,16 @@ namespace ExternPointer {
   extern const S pu;
   constexpr const int *pua = &pu.a; // Ok.
 }
+
+namespace PseudoDtor {
+  typedef int I;
+  constexpr int f(int a = 1) { // both-error {{never produces a constant 
expression}} \
+                               // ref-note {{destroying object 'a' whose 
lifetime has already ended}}
+    return (
+        a.~I(), // both-note {{pseudo-destructor call is not permitted}} \
+                // expected-note {{pseudo-destructor call is not permitted}}
+        0);
+  }
+  static_assert(f() == 0, ""); // both-error {{constant expression}} \
+                               // expected-note {{in call to}}
+}

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

Reply via email to