forked from OSchip/llvm-project
Template static data members can have weak_odr linkage, not just
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. llvm-svn: 129342
This commit is contained in:
parent
b4744a3f4d
commit
a97f329869
|
@ -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);
|
||||
|
|
|
@ -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>()) &&
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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" {
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 { };
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in New Issue