Skip to content

Commit d775b91

Browse files
authored
[clang][bytecode] Diagnose pseudo dtor calls before C++20 (#137303)
1 parent 2d00c73 commit d775b91

File tree

4 files changed

+25
-2
lines changed

4 files changed

+25
-2
lines changed

clang/lib/AST/ByteCode/Compiler.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4933,6 +4933,8 @@ bool Compiler<Emitter>::VisitCallExpr(const CallExpr *E) {
49334933
}
49344934
} else if (const auto *PD =
49354935
dyn_cast<CXXPseudoDestructorExpr>(E->getCallee())) {
4936+
if (!this->emitCheckPseudoDtor(E))
4937+
return false;
49364938
const Expr *Base = PD->getBase();
49374939
if (!Base->isGLValue())
49384940
return this->discard(Base);

clang/lib/AST/ByteCode/Interp.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2947,6 +2947,13 @@ inline bool SizelessVectorElementSize(InterpState &S, CodePtr OpPC) {
29472947
return false;
29482948
}
29492949

2950+
inline bool CheckPseudoDtor(InterpState &S, CodePtr OpPC) {
2951+
if (!S.getLangOpts().CPlusPlus20)
2952+
S.CCEDiag(S.Current->getSource(OpPC),
2953+
diag::note_constexpr_pseudo_destructor);
2954+
return true;
2955+
}
2956+
29502957
inline bool Assume(InterpState &S, CodePtr OpPC) {
29512958
const auto Val = S.Stk.pop<Boolean>();
29522959

clang/lib/AST/ByteCode/Opcodes.td

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -783,6 +783,7 @@ def SideEffect : Opcode {}
783783
def InvalidCast : Opcode {
784784
let Args = [ArgCastKind, ArgBool];
785785
}
786+
def CheckPseudoDtor : Opcode {}
786787

787788
def InvalidDeclRef : Opcode {
788789
let Args = [ArgDeclRef, ArgBool];

clang/test/AST/ByteCode/cxx11.cpp

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
// RUN: %clang_cc1 -triple x86_64-linux -fexperimental-new-constant-interpreter -verify=both,expected -std=c++11 %s
2-
// RUN: %clang_cc1 -triple x86_64-linux -verify=both,ref -std=c++11 %s
1+
// RUN: %clang_cc1 -triple x86_64-linux -verify=both,expected -std=c++11 %s -fexperimental-new-constant-interpreter
2+
// RUN: %clang_cc1 -triple x86_64-linux -verify=both,ref -std=c++11 %s
33

44
namespace IntOrEnum {
55
const int k = 0;
@@ -208,3 +208,16 @@ namespace ExternPointer {
208208
extern const S pu;
209209
constexpr const int *pua = &pu.a; // Ok.
210210
}
211+
212+
namespace PseudoDtor {
213+
typedef int I;
214+
constexpr int f(int a = 1) { // both-error {{never produces a constant expression}} \
215+
// ref-note {{destroying object 'a' whose lifetime has already ended}}
216+
return (
217+
a.~I(), // both-note {{pseudo-destructor call is not permitted}} \
218+
// expected-note {{pseudo-destructor call is not permitted}}
219+
0);
220+
}
221+
static_assert(f() == 0, ""); // both-error {{constant expression}} \
222+
// expected-note {{in call to}}
223+
}

0 commit comments

Comments
 (0)