Patch to provide guard when initializing instances

of static data member of a class template.
Fixes //rdar :// 8562966 and pr8409.

llvm-svn: 117410
This commit is contained in:
Fariborz Jahanian 2010-10-26 22:47:47 +00:00
parent 1e4d9a17c2
commit 67ca8c4c7b
3 changed files with 44 additions and 2 deletions

View File

@ -253,7 +253,15 @@ void CodeGenFunction::GenerateCXXGlobalVarDeclInitFunc(llvm::Function *Fn,
SourceLocation());
llvm::Constant *DeclPtr = CGM.GetAddrOfGlobalVar(D);
EmitCXXGlobalVarDeclInit(*D, DeclPtr);
if (D->isStaticDataMember() &&
D->getInstantiatedFromStaticDataMember() && D->getInit()){
llvm::GlobalVariable *GV = dyn_cast<llvm::GlobalVariable>(DeclPtr);
assert(GV && "GenerateCXXGlobalVarDeclInitFunc - GV is null");
GV->setConstant(false);
EmitCXXStaticLocalInit(*D, GV);
}
else
EmitCXXGlobalVarDeclInit(*D, DeclPtr);
FinishFunction();
}

View File

@ -1092,9 +1092,14 @@ void ItaniumCXXABI::EmitStaticLocalInit(CodeGenFunction &CGF,
// Create the guard variable.
llvm::SmallString<256> GuardVName;
getMangleContext().mangleItaniumGuardVariable(&D, GuardVName);
llvm::GlobalValue::LinkageTypes Linkage = GV->getLinkage();
if (D.isStaticDataMember() &&
D.getInstantiatedFromStaticDataMember())
Linkage = llvm::GlobalVariable::WeakAnyLinkage;
llvm::GlobalVariable *GuardVariable =
new llvm::GlobalVariable(CGM.getModule(), GuardTy,
false, GV->getLinkage(),
false, Linkage,
llvm::ConstantInt::get(GuardTy, 0),
GuardVName.str());

View File

@ -0,0 +1,29 @@
// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s
// rdar: // 8562966
// pr8409
// CHECK: @_ZN1CIiE11needs_guardE = weak global
// CHECK: @_ZGVN1CIiE11needs_guardE = weak global
struct K
{
K();
K(const K &);
~K();
void PrintNumK();
};
template<typename T>
struct C
{
void Go() { needs_guard.PrintNumK(); }
static K needs_guard;
};
template<typename T> K C<T>::needs_guard;
void F()
{
C<int>().Go();
}