diff options
author | Douglas Gregor <dgregor@apple.com> | 2011-07-01 21:54:36 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2011-07-01 21:54:36 +0000 |
commit | fa918f69f67d19bc55a4eac8d2304c42d28cdfc9 (patch) | |
tree | c684da82f8c4d59f16fc1b22c0968d70ac413ce0 | |
parent | 2f37bdc39223dcfc129a92accd17cc0b7fd6e7f1 (diff) | |
download | bcm5719-llvm-fa918f69f67d19bc55a4eac8d2304c42d28cdfc9.tar.gz bcm5719-llvm-fa918f69f67d19bc55a4eac8d2304c42d28cdfc9.zip |
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
-rw-r--r-- | clang/lib/CodeGen/CGDeclCXX.cpp | 11 | ||||
-rw-r--r-- | clang/test/CodeGenCXX/global-init.cpp | 23 |
2 files changed, 19 insertions, 15 deletions
diff --git a/clang/lib/CodeGen/CGDeclCXX.cpp b/clang/lib/CodeGen/CGDeclCXX.cpp index c305f01fe3a..42a07df5e47 100644 --- a/clang/lib/CodeGen/CGDeclCXX.cpp +++ b/clang/lib/CodeGen/CGDeclCXX.cpp @@ -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); diff --git a/clang/test/CodeGenCXX/global-init.cpp b/clang/test/CodeGenCXX/global-init.cpp index 9bd7390d076..fd8734c5fad 100644 --- a/clang/test/CodeGenCXX/global-init.cpp +++ b/clang/test/CodeGenCXX/global-init.cpp @@ -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. |