Author: Timm Baeder
Date: 2025-04-27T20:02:58+02:00
New Revision: e045d55dd51bfa6ee4ef29d518393cb57b4dc0c4

URL: 
https://github.com/llvm/llvm-project/commit/e045d55dd51bfa6ee4ef29d518393cb57b4dc0c4
DIFF: 
https://github.com/llvm/llvm-project/commit/e045d55dd51bfa6ee4ef29d518393cb57b4dc0c4.diff

LOG: [clang][bytecode] Check for global decls in destructors (#137525)

Destructors can't be called on global variables.

Added: 
    

Modified: 
    clang/lib/AST/ByteCode/Interp.cpp
    clang/lib/AST/ByteCode/Interp.h
    clang/test/AST/ByteCode/records.cpp

Removed: 
    


################################################################################
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}}
+  }
+}


        
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to