]> granicus.if.org Git - clang/commitdiff
Fix a case where we forgot to make a static local variable comdat
authorReid Kleckner <reid@kleckner.net>
Mon, 20 Jul 2015 20:35:30 +0000 (20:35 +0000)
committerReid Kleckner <reid@kleckner.net>
Mon, 20 Jul 2015 20:35:30 +0000 (20:35 +0000)
Sometimes we can provide an initializer for static locals, in which case
we sometimes might need to change the type. Changing the type requires
making a new LLVM GlobalVariable, and in this codepath we were
forgetting to transfer the comdat.

Fixes PR23838.

Patch by Ivan Garramona.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@242704 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGDecl.cpp
test/CodeGenCXX/static-init.cpp

index 96aa8c68e004c9c4351e31095519a46f4a78f7a8..ebd1776e50504b1ca5ac167ccf97d60cb1270a7a 100644 (file)
@@ -311,6 +311,7 @@ CodeGenFunction::AddInitializerToStaticVarDecl(const VarDecl &D,
                                   OldGV->getThreadLocalMode(),
                            CGM.getContext().getTargetAddressSpace(D.getType()));
     GV->setVisibility(OldGV->getVisibility());
+    GV->setComdat(OldGV->getComdat());
 
     // Steal the name of the old global
     GV->takeName(OldGV);
index 25489f022ce695df893e9533ae99c69284243d93..255251e707bf6e8ce728ecb931728c7a495c607a 100644 (file)
@@ -9,6 +9,7 @@
 // CHECK: @_ZZ2h2vE1i = linkonce_odr global i32 0, comdat, align
 // CHECK: @_ZGVZ2h2vE1i = linkonce_odr global i64 0, comdat{{$}}
 // CHECK: @_ZZN5test1L6getvarEiE3var = internal constant [4 x i32] [i32 1, i32 0, i32 2, i32 4], align 16
+// CHECK: @_ZZN5test414useStaticLocalEvE3obj = linkonce_odr global %"struct.test4::HasVTable" zeroinitializer, comdat, align 8
 
 struct A {
   A();
@@ -154,3 +155,19 @@ namespace test3 {
   // CHECK-LABEL: define void @_ZN5test31BC2Ev(
   // CHECK-LABEL: define void @_ZN5test31BC1Ev(
 }
+
+// We forgot to set the comdat when replacing the global with a different type.
+namespace test4 {
+struct HasVTable {
+  virtual void f();
+};
+inline HasVTable &useStaticLocal() {
+  static HasVTable obj;
+  return obj;
+}
+void useit() {
+  useStaticLocal();
+}
+// CHECK: define linkonce_odr dereferenceable(8) %"struct.test4::HasVTable"* @_ZN5test414useStaticLocalEv()
+// CHECK: ret %"struct.test4::HasVTable"* @_ZZN5test414useStaticLocalEvE3obj
+}