Ensure that static local variables in function templates inherit the

visibility of their function.

llvm-svn: 118065
This commit is contained in:
John McCall 2010-11-02 21:04:24 +00:00
parent bba85850e3
commit 8e7cb6dcfa
4 changed files with 33 additions and 1 deletions

View File

@ -172,6 +172,8 @@ CodeGenFunction::CreateStaticVarDecl(const VarDecl &D,
CGM.EmitNullConstant(D.getType()), Name, 0,
D.isThreadSpecified(), Ty.getAddressSpace());
GV->setAlignment(getContext().getDeclAlign(&D).getQuantity());
if (Linkage != llvm::GlobalValue::InternalLinkage)
GV->setVisibility(CurFn->getVisibility());
return GV;
}
@ -209,8 +211,10 @@ CodeGenFunction::AddInitializerToStaticVarDecl(const VarDecl &D,
GV = new llvm::GlobalVariable(CGM.getModule(), Init->getType(),
OldGV->isConstant(),
OldGV->getLinkage(), Init, "",
0, D.isThreadSpecified(),
/*InsertBefore*/ OldGV,
D.isThreadSpecified(),
D.getType().getAddressSpace());
GV->setVisibility(OldGV->getVisibility());
// Steal the name of the old global
GV->takeName(OldGV);

View File

@ -1344,9 +1344,16 @@ void CodeGenModule::EmitGlobalFunctionDefinition(GlobalDecl GD) {
Entry = NewFn;
}
// We need to set linkage and visibility on the function before
// generating code for it because various parts of IR generation
// want to propagate this information down (e.g. to local static
// declarations).
llvm::Function *Fn = cast<llvm::Function>(Entry);
setFunctionLinkage(D, Fn);
// FIXME: this is redundant with part of SetFunctionDefinitionAttributes
setGlobalVisibility(Fn, D, /*ForDef*/ true);
CodeGenFunction(*this).GenerateCode(D, Fn);
SetFunctionDefinitionAttributes(D, Fn);

View File

@ -1092,6 +1092,9 @@ void ItaniumCXXABI::EmitStaticLocalInit(CodeGenFunction &CGF,
// Create the guard variable.
llvm::SmallString<256> GuardVName;
getMangleContext().mangleItaniumGuardVariable(&D, GuardVName);
// FIXME: we should just absorb linkage and visibility from the
// variable, but that's not always set up properly just yet.
llvm::GlobalValue::LinkageTypes Linkage = GV->getLinkage();
if (D.isStaticDataMember() &&
D.getInstantiatedFromStaticDataMember())
@ -1102,6 +1105,7 @@ void ItaniumCXXABI::EmitStaticLocalInit(CodeGenFunction &CGF,
false, Linkage,
llvm::ConstantInt::get(GuardTy, 0),
GuardVName.str());
GuardVariable->setVisibility(GV->getVisibility());
// Test whether the variable has completed initialization.
llvm::Value *IsInitialized;

View File

@ -22,6 +22,10 @@
// CHECK-HIDDEN: @_ZN6Test143varE = external global
// CHECK: @_ZN6Test154TempINS_1AEE5Inner6bufferE = external global [0 x i8]
// CHECK-HIDDEN: @_ZN6Test154TempINS_1AEE5Inner6bufferE = external global [0 x i8]
// CHECK: @_ZZN6Test193fooIiEEvvE1a = linkonce_odr global
// CHECK: @_ZGVZN6Test193fooIiEEvvE1a = linkonce_odr global i64
// CHECK-HIDDEN: @_ZZN6Test193fooIiEEvvE1a = linkonce_odr hidden global
// CHECK-HIDDEN: @_ZGVZN6Test193fooIiEEvvE1a = linkonce_odr hidden global i64
// CHECK-HIDDEN: @_ZTTN6Test161AIcEE = external constant
// CHECK-HIDDEN: @_ZTVN6Test161AIcEE = external constant
// CHECK: @_ZTVN5Test63fooE = weak_odr hidden constant
@ -339,3 +343,16 @@ namespace Test18 {
// CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE1B3barEv()
// CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE1B3bazEv()
}
namespace Test19 {
struct A { A(); ~A(); };
// Tested at top of file.
template <class T> void foo() {
static A a;
}
void test() {
foo<int>();
}
}