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