[clang] [clang][bytecode] Check for global decls in destructors (PR #137525)
Timm Baeder via cfe-commits
cfe-commits at lists.llvm.org
Sun Apr 27 08:53:47 PDT 2025
https://github.com/tbaederr created https://github.com/llvm/llvm-project/pull/137525
Destructors can't be called on global variables.
>From 6cae24d12cd68d9a4227dfbdb2566fe7a605e3f8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbaeder at redhat.com>
Date: Sun, 27 Apr 2025 17:51:57 +0200
Subject: [PATCH] [clang][bytecode] Check for global decls in destructors
---
clang/lib/AST/ByteCode/Interp.cpp | 13 +++++++++----
clang/lib/AST/ByteCode/Interp.h | 3 ++-
clang/test/AST/ByteCode/records.cpp | 9 +++++++++
3 files changed, 20 insertions(+), 5 deletions(-)
diff --git a/clang/lib/AST/ByteCode/Interp.cpp b/clang/lib/AST/ByteCode/Interp.cpp
index 37111343178dd..080f694e27da2 100644
--- a/clang/lib/AST/ByteCode/Interp.cpp
+++ b/clang/lib/AST/ByteCode/Interp.cpp
@@ -1387,9 +1387,14 @@ static bool checkConstructor(InterpState &S, CodePtr OpPC, const Function *Func,
return false;
}
-static bool checkDestructor(InterpState &S, CodePtr OpPC, const Function *Func,
- const Pointer &ThisPtr) {
- return CheckActive(S, OpPC, ThisPtr, AK_Destroy);
+bool CheckDestructor(InterpState &S, CodePtr OpPC, const Pointer &Ptr) {
+ // Can't call a dtor on a global variable.
+ if (Ptr.block()->isStatic()) {
+ const SourceInfo &E = S.Current->getSource(OpPC);
+ S.FFDiag(E, diag::note_constexpr_modify_global);
+ return false;
+ }
+ return CheckActive(S, OpPC, Ptr, AK_Destroy);
}
static void compileFunction(InterpState &S, const Function *Func) {
@@ -1486,7 +1491,7 @@ bool Call(InterpState &S, CodePtr OpPC, const Function *Func,
if (Func->isConstructor() && !checkConstructor(S, OpPC, Func, ThisPtr))
return false;
- if (Func->isDestructor() && !checkDestructor(S, OpPC, Func, ThisPtr))
+ if (Func->isDestructor() && !CheckDestructor(S, OpPC, ThisPtr))
return false;
}
diff --git a/clang/lib/AST/ByteCode/Interp.h b/clang/lib/AST/ByteCode/Interp.h
index 63a1f3e8033b7..27e73bb72fecb 100644
--- a/clang/lib/AST/ByteCode/Interp.h
+++ b/clang/lib/AST/ByteCode/Interp.h
@@ -162,6 +162,7 @@ bool InvalidShuffleVectorIndex(InterpState &S, CodePtr OpPC, uint32_t Index);
bool CheckBitCast(InterpState &S, CodePtr OpPC, bool HasIndeterminateBits,
bool TargetIsUCharOrByte);
bool CheckBCPResult(InterpState &S, const Pointer &Ptr);
+bool CheckDestructor(InterpState &S, CodePtr OpPC, const Pointer &Ptr);
template <typename T>
static bool handleOverflow(InterpState &S, CodePtr OpPC, const T &SrcValue) {
@@ -3242,7 +3243,7 @@ bool DiagTypeid(InterpState &S, CodePtr OpPC);
inline bool CheckDestruction(InterpState &S, CodePtr OpPC) {
const auto &Ptr = S.Stk.peek<Pointer>();
- return CheckActive(S, OpPC, Ptr, AK_Destroy);
+ return CheckDestructor(S, OpPC, Ptr);
}
//===----------------------------------------------------------------------===//
diff --git a/clang/test/AST/ByteCode/records.cpp b/clang/test/AST/ByteCode/records.cpp
index b4059f009b887..9abfe6b8a15e7 100644
--- a/clang/test/AST/ByteCode/records.cpp
+++ b/clang/test/AST/ByteCode/records.cpp
@@ -1810,3 +1810,12 @@ namespace AccessMismatch {
static_assert(B().cmp(), ""); // both-error {{constant expression}} \
// both-note {{in call}}
}
+
+namespace GlobalDtor {
+ struct A {
+ };
+ constexpr A a = {};
+ constexpr void destroy1() { // both-error {{constexpr}}
+ a.~A(); // both-note {{cannot modify an object that is visible outside}}
+ }
+}
More information about the cfe-commits
mailing list