aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/CodeGen/CGDeclCXX.cpp7
-rw-r--r--lib/CodeGen/CodeGenModule.cpp4
-rw-r--r--test/CXX/temp/temp.spec/temp.explicit/p1-emit.cpp8
-rw-r--r--test/CodeGenCXX/explicit-instantiation.cpp2
-rw-r--r--test/CodeGenCXX/global-init.cpp10
-rw-r--r--test/CodeGenCXX/specialized-static-data-mem-init.cpp4
-rw-r--r--test/CodeGenCXX/static-data-member.cpp4
-rw-r--r--test/CodeGenCXX/static-init-3.cpp4
-rw-r--r--test/CodeGenCXX/template-inner-struct-visibility-hidden.cpp2
9 files changed, 28 insertions, 17 deletions
diff --git a/lib/CodeGen/CGDeclCXX.cpp b/lib/CodeGen/CGDeclCXX.cpp
index cb1c8ed192..45b0b969be 100644
--- a/lib/CodeGen/CGDeclCXX.cpp
+++ b/lib/CodeGen/CGDeclCXX.cpp
@@ -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);
diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp
index d22991db04..f740f707e0 100644
--- a/lib/CodeGen/CodeGenModule.cpp
+++ b/lib/CodeGen/CodeGenModule.cpp
@@ -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>()) &&
diff --git a/test/CXX/temp/temp.spec/temp.explicit/p1-emit.cpp b/test/CXX/temp/temp.spec/temp.explicit/p1-emit.cpp
index d8f7b52145..d0df305941 100644
--- a/test/CXX/temp/temp.spec/temp.explicit/p1-emit.cpp
+++ b/test/CXX/temp/temp.spec/temp.explicit/p1-emit.cpp
@@ -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
diff --git a/test/CodeGenCXX/explicit-instantiation.cpp b/test/CodeGenCXX/explicit-instantiation.cpp
index b82958568a..8daf3c6800 100644
--- a/test/CodeGenCXX/explicit-instantiation.cpp
+++ b/test/CodeGenCXX/explicit-instantiation.cpp
@@ -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 {
diff --git a/test/CodeGenCXX/global-init.cpp b/test/CodeGenCXX/global-init.cpp
index 53cfe05fd7..f9eeb59145 100644
--- a/test/CodeGenCXX/global-init.cpp
+++ b/test/CodeGenCXX/global-init.cpp
@@ -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" {
diff --git a/test/CodeGenCXX/specialized-static-data-mem-init.cpp b/test/CodeGenCXX/specialized-static-data-mem-init.cpp
index 8f5765bcbb..c2a2ddb112 100644
--- a/test/CodeGenCXX/specialized-static-data-mem-init.cpp
+++ b/test/CodeGenCXX/specialized-static-data-mem-init.cpp
@@ -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
{
diff --git a/test/CodeGenCXX/static-data-member.cpp b/test/CodeGenCXX/static-data-member.cpp
index 64fca2eb68..b19067af61 100644
--- a/test/CodeGenCXX/static-data-member.cpp
+++ b/test/CodeGenCXX/static-data-member.cpp
@@ -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 {
diff --git a/test/CodeGenCXX/static-init-3.cpp b/test/CodeGenCXX/static-init-3.cpp
index 5bf76a6170..bd717caaa1 100644
--- a/test/CodeGenCXX/static-init-3.cpp
+++ b/test/CodeGenCXX/static-init-3.cpp
@@ -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 { };
diff --git a/test/CodeGenCXX/template-inner-struct-visibility-hidden.cpp b/test/CodeGenCXX/template-inner-struct-visibility-hidden.cpp
index ca4446cd20..2c62b60b11 100644
--- a/test/CodeGenCXX/template-inner-struct-visibility-hidden.cpp
+++ b/test/CodeGenCXX/template-inner-struct-visibility-hidden.cpp
@@ -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