]> granicus.if.org Git - clang/commitdiff
Template static data members can have weak_odr linkage, not just
authorJohn McCall <rjmccall@apple.com>
Tue, 12 Apr 2011 01:46:54 +0000 (01:46 +0000)
committerJohn McCall <rjmccall@apple.com>
Tue, 12 Apr 2011 01:46:54 +0000 (01:46 +0000)
weak linkage.  Also, fix a problem where global weak variables
with non-trivial initializers were getting guard variables, or at
least were checking for them and then crashing.

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

lib/CodeGen/CGDeclCXX.cpp
lib/CodeGen/CodeGenModule.cpp
test/CXX/temp/temp.spec/temp.explicit/p1-emit.cpp
test/CodeGenCXX/explicit-instantiation.cpp
test/CodeGenCXX/global-init.cpp
test/CodeGenCXX/specialized-static-data-mem-init.cpp
test/CodeGenCXX/static-data-member.cpp
test/CodeGenCXX/static-init-3.cpp
test/CodeGenCXX/template-inner-struct-visibility-hidden.cpp

index cb1c8ed192dcbddbdc94c5ecf884739a2cf4f7fb..45b0b969be67879c708192c24863989c02474650 100644 (file)
@@ -275,8 +275,11 @@ void CodeGenFunction::GenerateCXXGlobalVarDeclInitFunc(llvm::Function *Fn,
                 FunctionArgList(), SourceLocation());
 
   // Use guarded initialization if the global variable is weak due to
-  // being a class template's static data member.
-  if (Addr->hasWeakLinkage() && D->getInstantiatedFromStaticDataMember()) {
+  // being a class template's static data member.  These will always
+  // have weak_odr linkage.
+  if (Addr->getLinkage() == llvm::GlobalValue::WeakODRLinkage &&
+      D->isStaticDataMember() &&
+      D->getInstantiatedFromStaticDataMember()) {
     EmitCXXGuardedInit(*D, Addr);
   } else {
     EmitCXXGlobalVarDeclInit(*D, Addr);
index d22991db041da994ac8bb7602f7cc56a17015582..f740f707e07e19c0df2d57a292b5162510aaf54e 100644 (file)
@@ -1316,9 +1316,7 @@ CodeGenModule::GetLLVMLinkageVarDefinition(const VarDecl *D,
       return llvm::GlobalVariable::WeakAnyLinkage;
   } else if (Linkage == GVA_TemplateInstantiation ||
              Linkage == GVA_ExplicitTemplateInstantiation)
-    // FIXME: It seems like we can provide more specific linkage here
-    // (LinkOnceODR, WeakODR).
-    return llvm::GlobalVariable::WeakAnyLinkage;
+    return llvm::GlobalVariable::WeakODRLinkage;
   else if (!getLangOptions().CPlusPlus && 
            ((!CodeGenOpts.NoCommon && !D->getAttr<NoCommonAttr>()) ||
              D->getAttr<CommonAttr>()) &&
index d8f7b52145dd95572fc5079ddb8242109924f058..d0df305941d96cbdd27ff44b3b0517d65f2cdc3e 100644 (file)
@@ -12,16 +12,16 @@ T X<T>::member1;
 template<typename T>
 T X<T>::member2 = 17;
 
-// CHECK: @_ZN1XIiE7member1E = weak global i32 0
+// CHECK: @_ZN1XIiE7member1E = weak_odr global i32 0
 template int X<int>::member1;
 
-// CHECK: @_ZN1XIiE7member2E = weak global i32 17
+// CHECK: @_ZN1XIiE7member2E = weak_odr global i32 17
 template int X<int>::member2;
 
 // For implicit instantiation of 
 long& get(bool Cond1, bool Cond2) {
-  // CHECK: @_ZN1XIlE7member1E = weak global i64 0
-  // CHECK: @_ZN1XIlE7member2E = weak global i64 17
+  // CHECK: @_ZN1XIlE7member1E = weak_odr global i64 0
+  // CHECK: @_ZN1XIlE7member2E = weak_odr global i64 17
   // CHECK: @_ZN1XIlE7member3E = external global i64
   return Cond1? X<long>::member1 
        : Cond2? X<long>::member2
index b82958568a8ac648023f41b6b4c5813aaceb3d75..8daf3c6800068fe70d8dc03ebb2a9e2c0e20159b 100644 (file)
@@ -1,7 +1,7 @@
 // RUN: %clang_cc1 -emit-llvm -triple i686-pc-linux-gnu -o - %s | FileCheck %s
 
 // This check logically is attached to 'template int S<int>::i;' below.
-// CHECK: @_ZN1SIiE1iE = weak global i32
+// CHECK: @_ZN1SIiE1iE = weak_odr global i32
 
 template<typename T, typename U, typename Result>
 struct plus {
index 53cfe05fd77690ff9b79663e719ca1ad837d8a0f..f9eeb59145f7f28856401ef141c6e3f5e72e44bc 100644 (file)
@@ -97,6 +97,16 @@ namespace test5 {
   };
 }
 
+namespace test6 {
+  struct A {
+    A();
+  };
+  extern int foo();
+
+  // This needs an initialization function but not guard variables.
+  __attribute__((weak)) int x = foo();
+}
+
 // At the end of the file, we check that y is initialized before z.
 
 // CHECK: define internal void @_GLOBAL__I_a() section "__TEXT,__StaticInit,regular,pure_instructions" {
index 8f5765bcbbe9f657901073a92a1d5dcd8e7488ec..c2a2ddb11254a812a5ca7669b474f05d076cd3e3 100644 (file)
@@ -2,8 +2,8 @@
 // rdar: // 8562966
 // pr8409
 
-// CHECK: @_ZN1CIiE11needs_guardE = weak global
-// CHECK: @_ZGVN1CIiE11needs_guardE = weak global
+// CHECK: @_ZN1CIiE11needs_guardE = weak_odr global
+// CHECK: @_ZGVN1CIiE11needs_guardE = weak_odr global
 
 struct K
 {
index 64fca2eb6837de7b89764d4ae7749c0211c00836..b19067af61df2146a3c7def239a1d751331d31f7 100644 (file)
@@ -2,8 +2,8 @@
 
 // CHECK: @_ZN5test11A1aE = constant i32 10, align 4
 // CHECK: @_ZN5test212_GLOBAL__N_11AIiE1xE = internal global i32 0, align 4
-// CHECK: @_ZN5test31AIiE1xE = weak global i32 0, align 4
-// CHECK: @_ZGVN5test31AIiE1xE = weak global i64 0
+// CHECK: @_ZN5test31AIiE1xE = weak_odr global i32 0, align 4
+// CHECK: @_ZGVN5test31AIiE1xE = weak_odr global i64 0
 
 // PR5564.
 namespace test1 {
index 5bf76a61708e3ace546c5f50afcf91b129207511..bd717caaa172854c82bec8349cd2ebf7f1e95b3c 100644 (file)
@@ -16,8 +16,8 @@ struct X1
     }
 };
 
-// CHECK: @_ZN2X1I2X2I1BEE8instanceE = weak global %struct.X0* null, align 8
-// CHECJ: @_ZN2X1I2X2I1AEE8instanceE = weak global %struct.X0* null, align 8
+// CHECK: @_ZN2X1I2X2I1BEE8instanceE = weak_odr global %struct.X0* null, align 8
+// CHECJ: @_ZN2X1I2X2I1AEE8instanceE = weak_odr global %struct.X0* null, align 8
 template<class T> T & X1<T>::instance = X1<T>::get();
 
 class A { };
index ca4446cd200eda727a4a6fb7ef4616465fe51390..2c62b60b1100b88b3d329cf185e0ec4db7617366 100644 (file)
@@ -1,7 +1,7 @@
 // RUN: %clang_cc1 -fvisibility hidden -emit-llvm -o - %s | FileCheck %s
 
 // Verify that symbols are hidden.
-// CHECK: @_ZN1CIiE5Inner6Inner26StaticE = weak hidden global
+// CHECK: @_ZN1CIiE5Inner6Inner26StaticE = weak_odr hidden global
 // CHECK: define weak_odr hidden void @_ZN1CIiE5Inner1fEv
 // CHECK: define weak_odr hidden void @_ZN1CIiE5Inner6Inner21gEv