llvm::ConstantInt *Zero = llvm::ConstantInt::get(GuardTy, 0);
// Get the guard variable for this function if we have one already.
- GuardInfo &GI = GuardVariableMap[D.getDeclContext()];
+ GuardInfo EmptyGuardInfo;
+ GuardInfo *GI = &EmptyGuardInfo;
+ if (isa<FunctionDecl>(D.getDeclContext())) {
+ GI = &GuardVariableMap[D.getDeclContext()];
+ }
unsigned BitIndex;
- if (D.isExternallyVisible()) {
+ if (D.isStaticLocal() && D.isExternallyVisible()) {
// Externally visible variables have to be numbered in Sema to properly
// handle unreachable VarDecls.
BitIndex = getContext().getStaticLocalNumber(&D);
BitIndex--;
} else {
// Non-externally visible variables are numbered here in CodeGen.
- BitIndex = GI.BitIndex++;
+ BitIndex = GI->BitIndex++;
}
if (BitIndex >= 32) {
if (D.isExternallyVisible())
ErrorUnsupportedABI(CGF, "more than 32 guarded initializations");
BitIndex %= 32;
- GI.Guard = 0;
+ GI->Guard = 0;
}
// Lazily create the i32 bitfield for this function.
- if (!GI.Guard) {
+ if (!GI->Guard) {
// Mangle the name for the guard.
SmallString<256> GuardName;
{
// Create the guard variable with a zero-initializer. Just absorb linkage
// and visibility from the guarded variable.
- GI.Guard = new llvm::GlobalVariable(CGM.getModule(), GuardTy, false,
- GV->getLinkage(), Zero, GuardName.str());
- GI.Guard->setVisibility(GV->getVisibility());
+ GI->Guard =
+ new llvm::GlobalVariable(CGM.getModule(), GuardTy, false,
+ GV->getLinkage(), Zero, GuardName.str());
+ GI->Guard->setVisibility(GV->getVisibility());
} else {
- assert(GI.Guard->getLinkage() == GV->getLinkage() &&
+ assert(GI->Guard->getLinkage() == GV->getLinkage() &&
"static local from the same function had different linkage");
}
// Test our bit from the guard variable.
llvm::ConstantInt *Bit = llvm::ConstantInt::get(GuardTy, 1U << BitIndex);
- llvm::LoadInst *LI = Builder.CreateLoad(GI.Guard);
+ llvm::LoadInst *LI = Builder.CreateLoad(GI->Guard);
llvm::Value *IsInitialized =
Builder.CreateICmpNE(Builder.CreateAnd(LI, Bit), Zero);
llvm::BasicBlock *InitBlock = CGF.createBasicBlock("init");
// Set our bit in the guard variable and emit the initializer and add a global
// destructor if appropriate.
CGF.EmitBlock(InitBlock);
- Builder.CreateStore(Builder.CreateOr(LI, Bit), GI.Guard);
+ Builder.CreateStore(Builder.CreateOr(LI, Bit), GI->Guard);
CGF.EmitCXXGlobalVarDeclInit(D, GV, PerformInit);
Builder.CreateBr(EndBlock);
-// RUN: %clang_cc1 -emit-llvm %s -o - -mconstructor-aliases -triple=i386-pc-win32 | FileCheck %s
+// RUN: %clang_cc1 -fms-extensions -emit-llvm %s -o - -mconstructor-aliases -triple=i386-pc-win32 | FileCheck %s
// CHECK: @llvm.global_ctors = appending global [2 x { i32, void ()* }]
// CHECK: [{ i32, void ()* } { i32 65535, void ()* @"\01??__Efoo@?$B@H@@2VA@@A@YAXXZ"
// CHECK: call x86_thiscallcc void @"\01??1S@@QAE@XZ"
// CHECK: ret void
+// These globals should use distinct guard variables, and not different bits of
+// the same global.
+__declspec(selectany) S selectany1;
+__declspec(selectany) S selectany2;
+// CHECK: define internal void @"\01??__Eselectany1@@YAXXZ"() [[NUW:#[0-9]+]]
+// CHECK: load i32* @"\01??_Bselectany1@@3US@@A@5"
+// CHECK: ret void
+// CHECK: define internal void @"\01??__Eselectany2@@YAXXZ"() [[NUW:#[0-9]+]]
+// CHECK: load i32* @"\01??_Bselectany2@@3US@@A@5"
+// CHECK: ret void
+
void StaticLocal() {
static S TheS;
}