[clang] a113b4e - [clang][Interp] Remove GlobalDecl flag (#101995)

via cfe-commits cfe-commits at lists.llvm.org
Mon Aug 5 09:16:36 PDT 2024


Author: Timm Baeder
Date: 2024-08-05T18:16:32+02:00
New Revision: a113b4e52736b8d32499edf391b8ca53268a641f

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

LOG: [clang][Interp] Remove GlobalDecl flag (#101995)

When initializing global variables, we still need to create local
variables for temporaries created in the process. Otherwise, we will
never call their destructors.

Added: 
    

Modified: 
    clang/lib/AST/Interp/Compiler.cpp
    clang/lib/AST/Interp/Compiler.h
    clang/lib/AST/Interp/Context.cpp
    clang/lib/AST/Interp/Descriptor.cpp
    clang/test/AST/Interp/codegen.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/AST/Interp/Compiler.cpp b/clang/lib/AST/Interp/Compiler.cpp
index 1295555f4cf22..e5280491dfd73 100644
--- a/clang/lib/AST/Interp/Compiler.cpp
+++ b/clang/lib/AST/Interp/Compiler.cpp
@@ -29,9 +29,7 @@ template <class Emitter> class DeclScope final : public LocalScope<Emitter> {
 public:
   DeclScope(Compiler<Emitter> *Ctx, const ValueDecl *VD)
       : LocalScope<Emitter>(Ctx, VD), Scope(Ctx->P, VD),
-        OldGlobalDecl(Ctx->GlobalDecl),
         OldInitializingDecl(Ctx->InitializingDecl) {
-    Ctx->GlobalDecl = Context::shouldBeGloballyIndexed(VD);
     Ctx->InitializingDecl = VD;
     Ctx->InitStack.push_back(InitLink::Decl(VD));
   }
@@ -41,14 +39,12 @@ template <class Emitter> class DeclScope final : public LocalScope<Emitter> {
   }
 
   ~DeclScope() {
-    this->Ctx->GlobalDecl = OldGlobalDecl;
     this->Ctx->InitializingDecl = OldInitializingDecl;
     this->Ctx->InitStack.pop_back();
   }
 
 private:
   Program::DeclScope Scope;
-  bool OldGlobalDecl;
   const ValueDecl *OldInitializingDecl;
 };
 
@@ -2265,7 +2261,7 @@ bool Compiler<Emitter>::VisitMaterializeTemporaryExpr(
   // the temporary is explicitly static, create a global variable.
   std::optional<PrimType> SubExprT = classify(SubExpr);
   bool IsStatic = E->getStorageDuration() == SD_Static;
-  if (GlobalDecl || IsStatic) {
+  if (IsStatic) {
     std::optional<unsigned> GlobalIndex = P.createGlobal(E);
     if (!GlobalIndex)
       return false;

diff  --git a/clang/lib/AST/Interp/Compiler.h b/clang/lib/AST/Interp/Compiler.h
index eabde051b4278..244a600d061f4 100644
--- a/clang/lib/AST/Interp/Compiler.h
+++ b/clang/lib/AST/Interp/Compiler.h
@@ -389,9 +389,6 @@ class Compiler : public ConstStmtVisitor<Compiler<Emitter>, bool>,
   llvm::SmallVector<InitLink> InitStack;
   bool InitStackActive = false;
 
-  /// Flag indicating if we're initializing a global variable.
-  bool GlobalDecl = false;
-
   /// Type of the expression returned by the function.
   std::optional<PrimType> ReturnType;
 

diff  --git a/clang/lib/AST/Interp/Context.cpp b/clang/lib/AST/Interp/Context.cpp
index b1e06cd4d8a4c..92ac28137fdb4 100644
--- a/clang/lib/AST/Interp/Context.cpp
+++ b/clang/lib/AST/Interp/Context.cpp
@@ -56,6 +56,7 @@ bool Context::evaluateAsRValue(State &Parent, const Expr *E, APValue &Result) {
 
   if (!Recursing) {
     assert(Stk.empty());
+    C.cleanup();
 #ifndef NDEBUG
     // Make sure we don't rely on some value being still alive in
     // InterpStack memory.
@@ -82,6 +83,7 @@ bool Context::evaluate(State &Parent, const Expr *E, APValue &Result) {
 
   if (!Recursing) {
     assert(Stk.empty());
+    C.cleanup();
 #ifndef NDEBUG
     // Make sure we don't rely on some value being still alive in
     // InterpStack memory.
@@ -111,6 +113,7 @@ bool Context::evaluateAsInitializer(State &Parent, const VarDecl *VD,
 
   if (!Recursing) {
     assert(Stk.empty());
+    C.cleanup();
 #ifndef NDEBUG
     // Make sure we don't rely on some value being still alive in
     // InterpStack memory.

diff  --git a/clang/lib/AST/Interp/Descriptor.cpp b/clang/lib/AST/Interp/Descriptor.cpp
index 8becdca6f5c24..23dd08ca48627 100644
--- a/clang/lib/AST/Interp/Descriptor.cpp
+++ b/clang/lib/AST/Interp/Descriptor.cpp
@@ -225,12 +225,21 @@ static void dtorRecord(Block *B, std::byte *Ptr, const Descriptor *D) {
 
 static void moveRecord(Block *B, const std::byte *Src, std::byte *Dst,
                        const Descriptor *D) {
-  for (const auto &F : D->ElemRecord->fields()) {
-    auto FieldOff = F.Offset;
-    auto *FieldDesc = F.Desc;
+  assert(D);
+  assert(D->ElemRecord);
 
-    if (auto Fn = FieldDesc->MoveFn)
-      Fn(B, Src + FieldOff, Dst + FieldOff, FieldDesc);
+  // FIXME: There might be cases where we need to move over the (v)bases as
+  // well.
+  for (const auto &F : D->ElemRecord->fields()) {
+    auto FieldOffset = F.Offset;
+    const auto *SrcDesc =
+        reinterpret_cast<const InlineDescriptor *>(Src + FieldOffset) - 1;
+    auto *DestDesc =
+        reinterpret_cast<InlineDescriptor *>(Dst + FieldOffset) - 1;
+    std::memcpy(DestDesc, SrcDesc, sizeof(InlineDescriptor));
+
+    if (auto Fn = F.Desc->MoveFn)
+      Fn(B, Src + FieldOffset, Dst + FieldOffset, F.Desc);
   }
 }
 

diff  --git a/clang/test/AST/Interp/codegen.cpp b/clang/test/AST/Interp/codegen.cpp
index 42d98a079e120..920a5ad7ba3e8 100644
--- a/clang/test/AST/Interp/codegen.cpp
+++ b/clang/test/AST/Interp/codegen.cpp
@@ -54,3 +54,13 @@ namespace reinterpretcast {
   // CHECK: define {{.*}} ptr @_ZN15reinterpretcast2f1Em
   // CHECK: inttoptr
 }
+
+namespace Bitfield {
+  struct S { int a : 5; ~S(); };
+  // CHECK: alloca
+  // CHECK: call {{.*}}memset
+  // CHECK: store i32 {{.*}}, ptr @_ZGRN8Bitfield1rE_
+  // CHECK: call void @_ZN8Bitfield1SD1
+  // CHECK: store ptr @_ZGRN8Bitfield1rE_, ptr @_ZN8Bitfield1rE, align 8
+  int &&r = S().a;
+}


        


More information about the cfe-commits mailing list