This revision was automatically updated to reflect the committed changes.
Closed by commit rG9e2579dbf434: Fix infinite recursion during IR emission if a 
constant-initialized lifetime… (authored by rsmith).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D97733/new/

https://reviews.llvm.org/D97733

Files:
  clang/lib/CodeGen/CodeGenModule.cpp
  clang/test/CodeGenCXX/temporaries.cpp


Index: clang/test/CodeGenCXX/temporaries.cpp
===================================================================
--- clang/test/CodeGenCXX/temporaries.cpp
+++ clang/test/CodeGenCXX/temporaries.cpp
@@ -53,6 +53,17 @@
   // CHECK: @_ZN9BraceInit1xE ={{.*}} constant i32* @_ZGRN9BraceInit1xE_
 }
 
+namespace RefTempSubobject {
+  struct SelfReferential {
+    int *p = ints;
+    int ints[3] = {1, 2, 3};
+  };
+
+  // CHECK: @_ZGRN16RefTempSubobject2srE_ = internal global { i32*, [3 x i32] 
} { {{.*}} getelementptr {{.*}} @_ZGRN16RefTempSubobject2srE_ {{.*}}, [3 x i32] 
[i32 1, i32 2, i32 3] }
+  // CHECK: @_ZN16RefTempSubobject2srE = {{.*}} constant {{.*}} 
@_ZGRN16RefTempSubobject2srE_
+  constexpr const SelfReferential &sr = SelfReferential();
+}
+
 struct A {
   A();
   ~A();
Index: clang/lib/CodeGen/CodeGenModule.cpp
===================================================================
--- clang/lib/CodeGen/CodeGenModule.cpp
+++ clang/lib/CodeGen/CodeGenModule.cpp
@@ -5325,8 +5325,21 @@
 
   CharUnits Align = getContext().getTypeAlignInChars(MaterializedType);
 
-  if (llvm::Constant *Slot = MaterializedGlobalTemporaryMap[E])
-    return ConstantAddress(Slot, Align);
+  auto InsertResult = MaterializedGlobalTemporaryMap.insert({E, nullptr});
+  if (!InsertResult.second) {
+    // We've seen this before: either we already created it or we're in the
+    // process of doing so.
+    if (!InsertResult.first->second) {
+      // We recursively re-entered this function, probably during emission of
+      // the initializer. Create a placeholder. We'll clean this up in the
+      // outer call, at the end of this function.
+      llvm::Type *Type = getTypes().ConvertTypeForMem(MaterializedType);
+      InsertResult.first->second = new llvm::GlobalVariable(
+          getModule(), Type, false, llvm::GlobalVariable::InternalLinkage,
+          nullptr);
+    }
+    return ConstantAddress(InsertResult.first->second, Align);
+  }
 
   // FIXME: If an externally-visible declaration extends multiple temporaries,
   // we need to give each temporary the same name in every translation unit 
(and
@@ -5405,7 +5418,17 @@
         *this, GV, AddrSpace, LangAS::Default,
         Type->getPointerTo(
             getContext().getTargetAddressSpace(LangAS::Default)));
-  MaterializedGlobalTemporaryMap[E] = CV;
+
+  // Update the map with the new temporary. If we created a placeholder above,
+  // replace it with the new global now.
+  llvm::Constant *&Entry = MaterializedGlobalTemporaryMap[E];
+  if (Entry) {
+    Entry->replaceAllUsesWith(
+        llvm::ConstantExpr::getBitCast(CV, Entry->getType()));
+    llvm::cast<llvm::GlobalVariable>(Entry)->eraseFromParent();
+  }
+  Entry = CV;
+
   return ConstantAddress(CV, Align);
 }
 


Index: clang/test/CodeGenCXX/temporaries.cpp
===================================================================
--- clang/test/CodeGenCXX/temporaries.cpp
+++ clang/test/CodeGenCXX/temporaries.cpp
@@ -53,6 +53,17 @@
   // CHECK: @_ZN9BraceInit1xE ={{.*}} constant i32* @_ZGRN9BraceInit1xE_
 }
 
+namespace RefTempSubobject {
+  struct SelfReferential {
+    int *p = ints;
+    int ints[3] = {1, 2, 3};
+  };
+
+  // CHECK: @_ZGRN16RefTempSubobject2srE_ = internal global { i32*, [3 x i32] } { {{.*}} getelementptr {{.*}} @_ZGRN16RefTempSubobject2srE_ {{.*}}, [3 x i32] [i32 1, i32 2, i32 3] }
+  // CHECK: @_ZN16RefTempSubobject2srE = {{.*}} constant {{.*}} @_ZGRN16RefTempSubobject2srE_
+  constexpr const SelfReferential &sr = SelfReferential();
+}
+
 struct A {
   A();
   ~A();
Index: clang/lib/CodeGen/CodeGenModule.cpp
===================================================================
--- clang/lib/CodeGen/CodeGenModule.cpp
+++ clang/lib/CodeGen/CodeGenModule.cpp
@@ -5325,8 +5325,21 @@
 
   CharUnits Align = getContext().getTypeAlignInChars(MaterializedType);
 
-  if (llvm::Constant *Slot = MaterializedGlobalTemporaryMap[E])
-    return ConstantAddress(Slot, Align);
+  auto InsertResult = MaterializedGlobalTemporaryMap.insert({E, nullptr});
+  if (!InsertResult.second) {
+    // We've seen this before: either we already created it or we're in the
+    // process of doing so.
+    if (!InsertResult.first->second) {
+      // We recursively re-entered this function, probably during emission of
+      // the initializer. Create a placeholder. We'll clean this up in the
+      // outer call, at the end of this function.
+      llvm::Type *Type = getTypes().ConvertTypeForMem(MaterializedType);
+      InsertResult.first->second = new llvm::GlobalVariable(
+          getModule(), Type, false, llvm::GlobalVariable::InternalLinkage,
+          nullptr);
+    }
+    return ConstantAddress(InsertResult.first->second, Align);
+  }
 
   // FIXME: If an externally-visible declaration extends multiple temporaries,
   // we need to give each temporary the same name in every translation unit (and
@@ -5405,7 +5418,17 @@
         *this, GV, AddrSpace, LangAS::Default,
         Type->getPointerTo(
             getContext().getTargetAddressSpace(LangAS::Default)));
-  MaterializedGlobalTemporaryMap[E] = CV;
+
+  // Update the map with the new temporary. If we created a placeholder above,
+  // replace it with the new global now.
+  llvm::Constant *&Entry = MaterializedGlobalTemporaryMap[E];
+  if (Entry) {
+    Entry->replaceAllUsesWith(
+        llvm::ConstantExpr::getBitCast(CV, Entry->getType()));
+    llvm::cast<llvm::GlobalVariable>(Entry)->eraseFromParent();
+  }
+  Entry = CV;
+
   return ConstantAddress(CV, Align);
 }
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
  • [PATCH] D97733: F... Richard Smith - zygoloid via Phabricator via cfe-commits
    • [PATCH] D977... Richard Smith - zygoloid via Phabricator via cfe-commits
    • [PATCH] D977... John McCall via Phabricator via cfe-commits
    • [PATCH] D977... Richard Smith - zygoloid via Phabricator via cfe-commits

Reply via email to