[clang] [clang][bytecode] Diagnose pseudo dtor calls before C++20 (PR #137303)
Timm Baeder via cfe-commits
cfe-commits at lists.llvm.org
Fri Apr 25 02:50:05 PDT 2025
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?= <tbaeder at 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}}
+}
More information about the cfe-commits
mailing list