[clang] [clang][bytecode] Diagnose pseudo dtor calls before C++20 (PR #137303)
via cfe-commits
cfe-commits at lists.llvm.org
Fri Apr 25 02:50:38 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Timm Baeder (tbaederr)
<details>
<summary>Changes</summary>
---
Full diff: https://github.com/llvm/llvm-project/pull/137303.diff
4 Files Affected:
- (modified) clang/lib/AST/ByteCode/Compiler.cpp (+2)
- (modified) clang/lib/AST/ByteCode/Interp.h (+7)
- (modified) clang/lib/AST/ByteCode/Opcodes.td (+1)
- (modified) clang/test/AST/ByteCode/cxx11.cpp (+15-2)
``````````diff
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}}
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/137303
More information about the cfe-commits
mailing list