Skip to content

Commit e045d55

Browse files
authored
[clang][bytecode] Check for global decls in destructors (llvm#137525)
Destructors can't be called on global variables.
1 parent b546baf commit e045d55

File tree

3 files changed

+20
-5
lines changed

3 files changed

+20
-5
lines changed

clang/lib/AST/ByteCode/Interp.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1387,9 +1387,14 @@ static bool checkConstructor(InterpState &S, CodePtr OpPC, const Function *Func,
13871387
return false;
13881388
}
13891389

1390-
static bool checkDestructor(InterpState &S, CodePtr OpPC, const Function *Func,
1391-
const Pointer &ThisPtr) {
1392-
return CheckActive(S, OpPC, ThisPtr, AK_Destroy);
1390+
bool CheckDestructor(InterpState &S, CodePtr OpPC, const Pointer &Ptr) {
1391+
// Can't call a dtor on a global variable.
1392+
if (Ptr.block()->isStatic()) {
1393+
const SourceInfo &E = S.Current->getSource(OpPC);
1394+
S.FFDiag(E, diag::note_constexpr_modify_global);
1395+
return false;
1396+
}
1397+
return CheckActive(S, OpPC, Ptr, AK_Destroy);
13931398
}
13941399

13951400
static void compileFunction(InterpState &S, const Function *Func) {
@@ -1486,7 +1491,7 @@ bool Call(InterpState &S, CodePtr OpPC, const Function *Func,
14861491

14871492
if (Func->isConstructor() && !checkConstructor(S, OpPC, Func, ThisPtr))
14881493
return false;
1489-
if (Func->isDestructor() && !checkDestructor(S, OpPC, Func, ThisPtr))
1494+
if (Func->isDestructor() && !CheckDestructor(S, OpPC, ThisPtr))
14901495
return false;
14911496
}
14921497

clang/lib/AST/ByteCode/Interp.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ bool InvalidShuffleVectorIndex(InterpState &S, CodePtr OpPC, uint32_t Index);
162162
bool CheckBitCast(InterpState &S, CodePtr OpPC, bool HasIndeterminateBits,
163163
bool TargetIsUCharOrByte);
164164
bool CheckBCPResult(InterpState &S, const Pointer &Ptr);
165+
bool CheckDestructor(InterpState &S, CodePtr OpPC, const Pointer &Ptr);
165166

166167
template <typename T>
167168
static bool handleOverflow(InterpState &S, CodePtr OpPC, const T &SrcValue) {
@@ -3242,7 +3243,7 @@ bool DiagTypeid(InterpState &S, CodePtr OpPC);
32423243

32433244
inline bool CheckDestruction(InterpState &S, CodePtr OpPC) {
32443245
const auto &Ptr = S.Stk.peek<Pointer>();
3245-
return CheckActive(S, OpPC, Ptr, AK_Destroy);
3246+
return CheckDestructor(S, OpPC, Ptr);
32463247
}
32473248

32483249
//===----------------------------------------------------------------------===//

clang/test/AST/ByteCode/records.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1810,3 +1810,12 @@ namespace AccessMismatch {
18101810
static_assert(B().cmp(), ""); // both-error {{constant expression}} \
18111811
// both-note {{in call}}
18121812
}
1813+
1814+
namespace GlobalDtor {
1815+
struct A {
1816+
};
1817+
constexpr A a = {};
1818+
constexpr void destroy1() { // both-error {{constexpr}}
1819+
a.~A(); // both-note {{cannot modify an object that is visible outside}}
1820+
}
1821+
}

0 commit comments

Comments
 (0)