Emit guard variables for any weak global that has a run-time

initializer. Previously, we only used guard variables for weak static
data members. Fixes <rdar://problem/9692249>.

llvm-svn: 134266
This commit is contained in:
Douglas Gregor 2011-07-01 21:54:36 +00:00
parent 2f37bdc392
commit fa918f69f6
2 changed files with 19 additions and 15 deletions

View File

@ -269,12 +269,11 @@ void CodeGenFunction::GenerateCXXGlobalVarDeclInitFunc(llvm::Function *Fn,
getTypes().getNullaryFunctionInfo(),
FunctionArgList(), SourceLocation());
// Use guarded initialization if the global variable is weak due to
// 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()) {
// Use guarded initialization if the global variable is weak. This
// occurs for, e.g., instantiated static data members and
// definitions explicitly marked weak.
if (Addr->getLinkage() == llvm::GlobalValue::WeakODRLinkage ||
Addr->getLinkage() == llvm::GlobalValue::WeakAnyLinkage) {
EmitCXXGuardedInit(*D, Addr);
} else {
EmitCXXGlobalVarDeclInit(*D, Addr);

View File

@ -70,6 +70,20 @@ namespace test3 {
const char *test() { return var; }
}
namespace test6 {
struct A {
A();
};
extern int foo();
// This needs an initialization function and guard variables.
// CHECK: load i8* bitcast (i64* @_ZGVN5test61xE
// CHECK: [[CALL:%.*]] = call i32 @_ZN5test63fooEv
// CHECK-NEXT: store i32 [[CALL]], i32* @_ZN5test61xE
// CHECK-NEXT: store i64 1, i64* @_ZGVN5test61xE
__attribute__((weak)) int x = foo();
}
namespace PR5974 {
struct A { int a; };
struct B { int b; };
@ -97,15 +111,6 @@ 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.