r207008 - MS ABI: Use a different guard variable for each weak global

Reid Kleckner reid at kleckner.net
Wed Apr 23 11:22:11 PDT 2014


Author: rnk
Date: Wed Apr 23 13:22:11 2014
New Revision: 207008

URL: http://llvm.org/viewvc/llvm-project?rev=207008&view=rev
Log:
MS ABI: Use a different guard variable for each weak global

We were using the same guard variable and failing to initialize the
second global.

Clang is still not MS ABI compatible in this area.  Fixing that is
PR16959, which will require LLVM changes to @llvm.global_ctors.

Modified:
    cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp
    cfe/trunk/test/CodeGenCXX/microsoft-abi-static-initializers.cpp

Modified: cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp?rev=207008&r1=207007&r2=207008&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp (original)
+++ cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp Wed Apr 23 13:22:11 2014
@@ -1273,10 +1273,14 @@ void MicrosoftCXXABI::EmitGuardedInit(Co
   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);
@@ -1284,18 +1288,18 @@ void MicrosoftCXXABI::EmitGuardedInit(Co
     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;
     {
@@ -1306,11 +1310,12 @@ void MicrosoftCXXABI::EmitGuardedInit(Co
 
     // 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");
   }
 
@@ -1322,7 +1327,7 @@ void MicrosoftCXXABI::EmitGuardedInit(Co
 
   // 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");
@@ -1332,7 +1337,7 @@ void MicrosoftCXXABI::EmitGuardedInit(Co
   // 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);
 

Modified: cfe/trunk/test/CodeGenCXX/microsoft-abi-static-initializers.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/microsoft-abi-static-initializers.cpp?rev=207008&r1=207007&r2=207008&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/microsoft-abi-static-initializers.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/microsoft-abi-static-initializers.cpp Wed Apr 23 13:22:11 2014
@@ -1,4 +1,4 @@
-// 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 at H@@2VA@@A at YAXXZ"
@@ -20,6 +20,17 @@ S s;
 // CHECK: call x86_thiscallcc void @"\01??1S@@QAE at 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 at 5"
+// CHECK: ret void
+// CHECK: define internal void @"\01??__Eselectany2@@YAXXZ"() [[NUW:#[0-9]+]]
+// CHECK: load i32* @"\01??_Bselectany2@@3US@@A at 5"
+// CHECK: ret void
+
 void StaticLocal() {
   static S TheS;
 }





More information about the cfe-commits mailing list