[cfe-commits] r153768 - in /cfe/trunk: lib/CodeGen/CGCXXABI.cpp lib/CodeGen/CGCXXABI.h lib/CodeGen/CGDecl.cpp lib/CodeGen/CGDeclCXX.cpp lib/CodeGen/CodeGenFunction.h lib/CodeGen/CodeGenModule.cpp lib/CodeGen/CodeGenModule.h lib/CodeGen/ItaniumCXXABI.cpp test/CodeGenCXX/static-init.cpp

Chandler Carruth chandlerc at gmail.com
Fri Mar 30 12:44:53 PDT 2012


Author: chandlerc
Date: Fri Mar 30 14:44:53 2012
New Revision: 153768

URL: http://llvm.org/viewvc/llvm-project?rev=153768&view=rev
Log:
Revert r153723, and its follow-ups r153728 and r153733.

These patches cause us to miscompile and/or reject code with static
function-local variables in an extern-C context. Previously, we were
papering over this as long as the variables are within the same
translation unit, and had not seen any failures in the wild. We still
need a proper fix, which involves mangling static locals inside of an
extern-C block (as GCC already does), but this patch causes pretty
widespread regressions. Firefox, and many other applications no longer
build.

Lots of test cases have been posted to the list in response to this
commit, so there should be no problem reproducing the issues.

Modified:
    cfe/trunk/lib/CodeGen/CGCXXABI.cpp
    cfe/trunk/lib/CodeGen/CGCXXABI.h
    cfe/trunk/lib/CodeGen/CGDecl.cpp
    cfe/trunk/lib/CodeGen/CGDeclCXX.cpp
    cfe/trunk/lib/CodeGen/CodeGenFunction.h
    cfe/trunk/lib/CodeGen/CodeGenModule.cpp
    cfe/trunk/lib/CodeGen/CodeGenModule.h
    cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp
    cfe/trunk/test/CodeGenCXX/static-init.cpp

Modified: cfe/trunk/lib/CodeGen/CGCXXABI.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCXXABI.cpp?rev=153768&r1=153767&r2=153768&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCXXABI.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCXXABI.cpp Fri Mar 30 14:44:53 2012
@@ -172,7 +172,7 @@
 
 void CGCXXABI::EmitGuardedInit(CodeGenFunction &CGF,
                                const VarDecl &D,
-                               llvm::Constant *GV,
+                               llvm::GlobalVariable *GV,
                                bool PerformInit) {
   ErrorUnsupportedABI(CGF, "static local variable initialization");
 }

Modified: cfe/trunk/lib/CodeGen/CGCXXABI.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCXXABI.h?rev=153768&r1=153767&r2=153768&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCXXABI.h (original)
+++ cfe/trunk/lib/CodeGen/CGCXXABI.h Fri Mar 30 14:44:53 2012
@@ -246,9 +246,8 @@
   /// The variable may be:
   ///   - a static local variable
   ///   - a static data member of a class template instantiation
-  /// In either case, it will be a (possibly casted) llvm::GlobalVariable.
   virtual void EmitGuardedInit(CodeGenFunction &CGF, const VarDecl &D,
-                               llvm::Constant *addr, bool PerformInit);
+                               llvm::GlobalVariable *DeclPtr, bool PerformInit);
 
 };
 

Modified: cfe/trunk/lib/CodeGen/CGDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDecl.cpp?rev=153768&r1=153767&r2=153768&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGDecl.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGDecl.cpp Fri Mar 30 14:44:53 2012
@@ -169,24 +169,7 @@
   return ContextName + Separator + D.getNameAsString();
 }
 
-/// We wanted to make a variable of one type, but the variable already
-/// exists with another.  Is that type good enough?
-///
-/// The problem we're working around here is that giving a global
-/// variable an initializer can require changing its type in some
-/// convoluted circumstances.
-static bool isExistingVarAdequate(CodeGenModule &CGM,
-                                  llvm::Type *existing, llvm::Type *desired) {
-  // Equality makes for a good fast path.
-  if (existing == desired) return true;
-
-  // Otherwise, just require them to have the same size.
-  return (CGM.getTargetData().getTypeStoreSize(existing)
-            == CGM.getTargetData().getTypeStoreSize(desired));
-}
-                                   
-
-llvm::Constant *
+llvm::GlobalVariable *
 CodeGenFunction::CreateStaticVarDecl(const VarDecl &D,
                                      const char *Separator,
                                      llvm::GlobalValue::LinkageTypes Linkage) {
@@ -201,37 +184,12 @@
     Name = GetStaticDeclName(*this, D, Separator);
 
   llvm::Type *LTy = CGM.getTypes().ConvertTypeForMem(Ty);
-  unsigned addrspace = CGM.getContext().getTargetAddressSpace(Ty);
-
-  // In C++, there are strange possibilities here involving the
-  // double-emission of constructors and destructors.
-  if (CGM.getLangOpts().CPlusPlus) {
-    llvm::GlobalValue *value = CGM.getModule().getNamedValue(Name);
-    if (value && isa<llvm::GlobalVariable>(value)) {
-      // Check that the type is compatible with the type we want.  The
-      // simple equality check isn't good enough because initializers
-      // can force the changing of a type (e.g.  with unions).
-      if (value->getType()->getAddressSpace() == addrspace &&
-          isExistingVarAdequate(CGM, value->getType()->getElementType(), LTy))
-        return llvm::ConstantExpr::getBitCast(value,
-                                              LTy->getPointerTo(addrspace));
-    }
-
-    if (value) {
-      CGM.Error(D.getLocation(),
-                "problem emitting static variable '" + Name +
-                "': already present as different kind of symbol");
-
-      // Fall through and implicitly give it a uniqued name.
-    }
-  }
-    
   llvm::GlobalVariable *GV =
     new llvm::GlobalVariable(CGM.getModule(), LTy,
                              Ty.isConstant(getContext()), Linkage,
                              CGM.EmitNullConstant(D.getType()), Name, 0,
                              D.isThreadSpecified(),
-                             addrspace);
+                             CGM.getContext().getTargetAddressSpace(Ty));
   GV->setAlignment(getContext().getDeclAlign(&D).getQuantity());
   if (Linkage != llvm::GlobalValue::InternalLinkage)
     GV->setVisibility(CurFn->getVisibility());
@@ -246,85 +204,80 @@
   return RD && !RD->hasTrivialDestructor();
 }
 
-/// AddInitializerToStaticVarDecl - Add the initializer for 'D' to
-/// the global variable that has already been created for it.  If
-/// the initializer has a different type than GV does, this may
-/// force the underlying variable to change.  Otherwise it just
-/// returns it.
-///
-/// The argument must be a (potentially casted) global variable,
-/// and the result will be one, too.
-llvm::Constant *
+/// AddInitializerToStaticVarDecl - Add the initializer for 'D' to the
+/// global variable that has already been created for it.  If the initializer
+/// has a different type than GV does, this may free GV and return a different
+/// one.  Otherwise it just returns GV.
+llvm::GlobalVariable *
 CodeGenFunction::AddInitializerToStaticVarDecl(const VarDecl &D,
-                                               llvm::Constant *addr) {
-  llvm::Constant *init = CGM.EmitConstantInit(D, this);
-
-  llvm::GlobalVariable *var =
-    cast<llvm::GlobalVariable>(addr->stripPointerCasts());
+                                               llvm::GlobalVariable *GV) {
+  llvm::Constant *Init = CGM.EmitConstantInit(D, this);
 
   // If constant emission failed, then this should be a C++ static
   // initializer.
-  if (!init) {
+  if (!Init) {
     if (!getContext().getLangOpts().CPlusPlus)
       CGM.ErrorUnsupported(D.getInit(), "constant l-value expression");
     else if (Builder.GetInsertBlock()) {
       // Since we have a static initializer, this global variable can't
       // be constant.
-      var->setConstant(false);
+      GV->setConstant(false);
 
-      EmitCXXGuardedInit(D, addr, /*PerformInit*/true);
+      EmitCXXGuardedInit(D, GV, /*PerformInit*/true);
     }
-    return addr;
+    return GV;
   }
 
   // The initializer may differ in type from the global. Rewrite
   // the global to match the initializer.  (We have to do this
   // because some types, like unions, can't be completely represented
   // in the LLVM type system.)
-  if (var->getType()->getElementType() != init->getType()) {
-    llvm::GlobalVariable *newVar
-      = new llvm::GlobalVariable(CGM.getModule(), init->getType(),
-                                 var->isConstant(),
-                                 var->getLinkage(), init, "",
-                                 /*InsertBefore*/ var,
-                                 D.isThreadSpecified(),
-                                 var->getType()->getAddressSpace());
-    newVar->setVisibility(var->getVisibility());
+  if (GV->getType()->getElementType() != Init->getType()) {
+    llvm::GlobalVariable *OldGV = GV;
+
+    GV = new llvm::GlobalVariable(CGM.getModule(), Init->getType(),
+                                  OldGV->isConstant(),
+                                  OldGV->getLinkage(), Init, "",
+                                  /*InsertBefore*/ OldGV,
+                                  D.isThreadSpecified(),
+                           CGM.getContext().getTargetAddressSpace(D.getType()));
+    GV->setVisibility(OldGV->getVisibility());
 
     // Steal the name of the old global
-    newVar->takeName(var);
+    GV->takeName(OldGV);
 
     // Replace all uses of the old global with the new global
-    addr = llvm::ConstantExpr::getBitCast(newVar, addr->getType());
-    var->replaceAllUsesWith(addr);
+    llvm::Constant *NewPtrForOldDecl =
+    llvm::ConstantExpr::getBitCast(GV, OldGV->getType());
+    OldGV->replaceAllUsesWith(NewPtrForOldDecl);
 
     // Erase the old global, since it is no longer used.
-    var->eraseFromParent();
-    var = newVar;
+    OldGV->eraseFromParent();
   }
 
-  var->setConstant(CGM.isTypeConstant(D.getType(), true));
-  var->setInitializer(init);
+  GV->setConstant(CGM.isTypeConstant(D.getType(), true));
+  GV->setInitializer(Init);
 
   if (hasNontrivialDestruction(D.getType())) {
     // We have a constant initializer, but a nontrivial destructor. We still
     // need to perform a guarded "initialization" in order to register the
     // destructor.
-    EmitCXXGuardedInit(D, addr, /*PerformInit*/false);
+    EmitCXXGuardedInit(D, GV, /*PerformInit*/false);
   }
 
-  return addr;
+  return GV;
 }
 
 void CodeGenFunction::EmitStaticVarDecl(const VarDecl &D,
                                       llvm::GlobalValue::LinkageTypes Linkage) {
+  llvm::Value *&DMEntry = LocalDeclMap[&D];
+  assert(DMEntry == 0 && "Decl already exists in localdeclmap!");
 
-  llvm::Constant *addr = CreateStaticVarDecl(D, ".", Linkage);
+  llvm::GlobalVariable *GV = CreateStaticVarDecl(D, ".", Linkage);
 
   // Store into LocalDeclMap before generating initializer to handle
   // circular references.
-  assert(!LocalDeclMap.count(&D) && "Decl already exists in localdeclmap!");
-  LocalDeclMap[&D] = addr;
+  DMEntry = GV;
 
   // We can't have a VLA here, but we can have a pointer to a VLA,
   // even though that doesn't really make any sense.
@@ -334,34 +287,40 @@
 
   // Local static block variables must be treated as globals as they may be
   // referenced in their RHS initializer block-literal expresion.
-  CGM.setStaticLocalDeclAddress(&D, addr);
+  CGM.setStaticLocalDeclAddress(&D, GV);
 
   // If this value has an initializer, emit it.
-  // This can leave us with a casted pointer.
   if (D.getInit())
-    addr = AddInitializerToStaticVarDecl(D, addr);
+    GV = AddInitializerToStaticVarDecl(D, GV);
 
-  llvm::GlobalVariable *var =
-    cast<llvm::GlobalVariable>(addr->stripPointerCasts());
-  var->setAlignment(getContext().getDeclAlign(&D).getQuantity());
+  GV->setAlignment(getContext().getDeclAlign(&D).getQuantity());
 
   if (D.hasAttr<AnnotateAttr>())
-    CGM.AddGlobalAnnotations(&D, var);
+    CGM.AddGlobalAnnotations(&D, GV);
 
   if (const SectionAttr *SA = D.getAttr<SectionAttr>())
-    var->setSection(SA->getName());
+    GV->setSection(SA->getName());
 
   if (D.hasAttr<UsedAttr>())
-    CGM.AddUsedGlobal(var);
+    CGM.AddUsedGlobal(GV);
 
-  LocalDeclMap[&D] = addr;
-  CGM.setStaticLocalDeclAddress(&D, addr);
+  // We may have to cast the constant because of the initializer
+  // mismatch above.
+  //
+  // FIXME: It is really dangerous to store this in the map; if anyone
+  // RAUW's the GV uses of this constant will be invalid.
+  llvm::Type *LTy = CGM.getTypes().ConvertTypeForMem(D.getType());
+  llvm::Type *LPtrTy =
+    LTy->getPointerTo(CGM.getContext().getTargetAddressSpace(D.getType()));
+  llvm::Constant *CastedVal = llvm::ConstantExpr::getBitCast(GV, LPtrTy);
+  DMEntry = CastedVal;
+  CGM.setStaticLocalDeclAddress(&D, CastedVal);
 
   // Emit global variable debug descriptor for static vars.
   CGDebugInfo *DI = getDebugInfo();
   if (DI) {
     DI->setLocation(D.getLocation());
-    DI->EmitGlobalVariable(var, &D);
+    DI->EmitGlobalVariable(static_cast<llvm::GlobalVariable *>(GV), &D);
   }
 }
 

Modified: cfe/trunk/lib/CodeGen/CGDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDeclCXX.cpp?rev=153768&r1=153767&r2=153768&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGDeclCXX.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGDeclCXX.cpp Fri Mar 30 14:44:53 2012
@@ -179,7 +179,7 @@
 }
 
 void CodeGenFunction::EmitCXXGuardedInit(const VarDecl &D,
-                                         llvm::Constant *addr,
+                                         llvm::GlobalVariable *DeclPtr,
                                          bool PerformInit) {
   // If we've been asked to forbid guard variables, emit an error now.
   // This diagnostic is hard-coded for Darwin's use case;  we can find
@@ -189,7 +189,7 @@
               "this initialization requires a guard variable, which "
               "the kernel does not support");
 
-  CGM.getCXXABI().EmitGuardedInit(*this, D, addr, PerformInit);
+  CGM.getCXXABI().EmitGuardedInit(*this, D, DeclPtr, PerformInit);
 }
 
 static llvm::Function *

Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=153768&r1=153767&r2=153768&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Fri Mar 30 14:44:53 2012
@@ -2392,17 +2392,17 @@
 
   /// CreateStaticVarDecl - Create a zero-initialized LLVM global for
   /// a static local variable.
-  llvm::Constant *CreateStaticVarDecl(const VarDecl &D,
-                                      const char *Separator,
-                                      llvm::GlobalValue::LinkageTypes Linkage);
-
-  /// AddInitializerToStaticVarDecl - Add the initializer for 'D' to
-  /// the global variable that has already been created for it.  If
-  /// the initializer has a different type than GV does, this may
-  /// force the underlying variable to change.  Otherwise it just
-  /// returns it.
-  llvm::Constant *
-  AddInitializerToStaticVarDecl(const VarDecl &D, llvm::Constant *GV);
+  llvm::GlobalVariable *CreateStaticVarDecl(const VarDecl &D,
+                                            const char *Separator,
+                                       llvm::GlobalValue::LinkageTypes Linkage);
+
+  /// AddInitializerToStaticVarDecl - Add the initializer for 'D' to the
+  /// global variable that has already been created for it.  If the initializer
+  /// has a different type than GV does, this may free GV and return a different
+  /// one.  Otherwise it just returns GV.
+  llvm::GlobalVariable *
+  AddInitializerToStaticVarDecl(const VarDecl &D,
+                                llvm::GlobalVariable *GV);
 
 
   /// EmitCXXGlobalVarDeclInit - Create the initializer for a C++
@@ -2420,7 +2420,7 @@
   /// possible to prove that an initialization will be done exactly
   /// once, e.g. with a static local variable or a static data member
   /// of a class template.
-  void EmitCXXGuardedInit(const VarDecl &D, llvm::Constant *addr,
+  void EmitCXXGuardedInit(const VarDecl &D, llvm::GlobalVariable *DeclPtr,
                           bool PerformInit);
 
   /// GenerateCXXGlobalInitFunc - Generates code for initializing global

Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=153768&r1=153767&r2=153768&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Fri Mar 30 14:44:53 2012
@@ -197,9 +197,8 @@
   return getContext().getTargetInfo().getTriple().isOSDarwin();
 }
 
-void CodeGenModule::Error(SourceLocation loc, const Twine &error) {
-  unsigned diagID = getDiags().getCustomDiagID(DiagnosticsEngine::Error,
-                                               error.str());
+void CodeGenModule::Error(SourceLocation loc, StringRef error) {
+  unsigned diagID = getDiags().getCustomDiagID(DiagnosticsEngine::Error, error);
   getDiags().Report(Context.getFullLoc(loc), diagID);
 }
 

Modified: cfe/trunk/lib/CodeGen/CodeGenModule.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.h?rev=153768&r1=153767&r2=153768&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.h Fri Mar 30 14:44:53 2012
@@ -733,7 +733,7 @@
   llvm::Constant *EmitNullConstantForBase(const CXXRecordDecl *Record);
 
   /// Error - Emit a general error that something can't be done.
-  void Error(SourceLocation loc, const Twine &error);
+  void Error(SourceLocation loc, StringRef error);
 
   /// ErrorUnsupported - Print out an error that codegen doesn't support the
   /// specified stmt yet.

Modified: cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp?rev=153768&r1=153767&r2=153768&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp (original)
+++ cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp Fri Mar 30 14:44:53 2012
@@ -123,7 +123,7 @@
                        llvm::Value *&AllocPtr, CharUnits &CookieSize);
 
   void EmitGuardedInit(CodeGenFunction &CGF, const VarDecl &D,
-                       llvm::Constant *addr, bool PerformInit);
+                       llvm::GlobalVariable *DeclPtr, bool PerformInit);
 };
 
 class ARMCXXABI : public ItaniumCXXABI {
@@ -1051,7 +1051,7 @@
 namespace {
   struct CallGuardAbort : EHScopeStack::Cleanup {
     llvm::GlobalVariable *Guard;
-    CallGuardAbort(llvm::GlobalVariable *guard) : Guard(guard) {}
+    CallGuardAbort(llvm::GlobalVariable *Guard) : Guard(Guard) {}
 
     void Emit(CodeGenFunction &CGF, Flags flags) {
       CGF.Builder.CreateCall(getGuardAbortFn(CGF.CGM, Guard->getType()), Guard)
@@ -1064,7 +1064,7 @@
 /// just special-case it at particular places.
 void ItaniumCXXABI::EmitGuardedInit(CodeGenFunction &CGF,
                                     const VarDecl &D,
-                                    llvm::Constant *varAddr,
+                                    llvm::GlobalVariable *GV,
                                     bool PerformInit) {
   CGBuilderTy &Builder = CGF.Builder;
 
@@ -1073,60 +1073,35 @@
   bool threadsafe =
     (getContext().getLangOpts().ThreadsafeStatics && D.isLocalVarDecl());
 
-  llvm::IntegerType *guardTy;
-
-  // Find the underlying global variable for linkage purposes.
-  // This may not have the right type for actual evaluation purposes.
-  llvm::GlobalVariable *var =
-    cast<llvm::GlobalVariable>(varAddr->stripPointerCasts());
+  llvm::IntegerType *GuardTy;
 
   // If we have a global variable with internal linkage and thread-safe statics
   // are disabled, we can just let the guard variable be of type i8.
-  bool useInt8GuardVariable = !threadsafe && var->hasInternalLinkage();
+  bool useInt8GuardVariable = !threadsafe && GV->hasInternalLinkage();
   if (useInt8GuardVariable) {
-    guardTy = CGF.Int8Ty;
+    GuardTy = CGF.Int8Ty;
   } else {
     // Guard variables are 64 bits in the generic ABI and 32 bits on ARM.
-    guardTy = (IsARM ? CGF.Int32Ty : CGF.Int64Ty);
+    GuardTy = (IsARM ? CGF.Int32Ty : CGF.Int64Ty);
   }
-  llvm::PointerType *guardPtrTy = guardTy->getPointerTo();
+  llvm::PointerType *GuardPtrTy = GuardTy->getPointerTo();
 
   // Create the guard variable.
-  SmallString<256> guardName;
-  {
-    llvm::raw_svector_ostream out(guardName);
-    getMangleContext().mangleItaniumGuardVariable(&D, out);
-    out.flush();
-  }
+  SmallString<256> GuardVName;
+  llvm::raw_svector_ostream Out(GuardVName);
+  getMangleContext().mangleItaniumGuardVariable(&D, Out);
+  Out.flush();
+
+  // Just absorb linkage and visibility from the variable.
+  llvm::GlobalVariable *GuardVariable =
+    new llvm::GlobalVariable(CGM.getModule(), GuardTy,
+                             false, GV->getLinkage(),
+                             llvm::ConstantInt::get(GuardTy, 0),
+                             GuardVName.str());
+  GuardVariable->setVisibility(GV->getVisibility());
 
-  // There are strange possibilities here involving the
-  // double-emission of constructors and destructors.
-  llvm::GlobalVariable *guard = 0;
-  if (llvm::GlobalValue *existingGuard 
-        = CGM.getModule().getNamedValue(guardName.str())) {
-    if (isa<llvm::GlobalVariable>(existingGuard) &&
-        existingGuard->getType() == guardPtrTy) {
-      guard = cast<llvm::GlobalVariable>(existingGuard); // okay
-    } else {
-      CGM.Error(D.getLocation(), "problem emitting static variable '"
-                                 + guardName.str() +
-                "': already present as different kind of symbol");
-
-      // Fall through and implicitly give it a uniqued name.
-    }
-  }
-
-  if (!guard) {
-    // Just absorb linkage and visibility from the variable.
-    guard = new llvm::GlobalVariable(CGM.getModule(), guardTy,
-                                     false, var->getLinkage(),
-                                     llvm::ConstantInt::get(guardTy, 0),
-                                     guardName.str());
-    guard->setVisibility(var->getVisibility());
-  }
-    
   // Test whether the variable has completed initialization.
-  llvm::Value *isInitialized;
+  llvm::Value *IsInitialized;
 
   // ARM C++ ABI 3.2.3.1:
   //   To support the potential use of initialization guard variables
@@ -1140,9 +1115,9 @@
   //         ...
   //     }
   if (IsARM && !useInt8GuardVariable) {
-    llvm::Value *V = Builder.CreateLoad(guard);
+    llvm::Value *V = Builder.CreateLoad(GuardVariable);
     V = Builder.CreateAnd(V, Builder.getInt32(1));
-    isInitialized = Builder.CreateIsNull(V, "guard.uninitialized");
+    IsInitialized = Builder.CreateIsNull(V, "guard.uninitialized");
 
   // Itanium C++ ABI 3.3.2:
   //   The following is pseudo-code showing how these functions can be used:
@@ -1160,9 +1135,10 @@
   //     }
   } else {
     // Load the first byte of the guard variable.
-    llvm::LoadInst *load = 
-      Builder.CreateLoad(Builder.CreateBitCast(guard, CGM.Int8PtrTy));
-    load->setAlignment(1);
+    llvm::Type *PtrTy = Builder.getInt8PtrTy();
+    llvm::LoadInst *LI = 
+      Builder.CreateLoad(Builder.CreateBitCast(GuardVariable, PtrTy));
+    LI->setAlignment(1);
 
     // Itanium ABI:
     //   An implementation supporting thread-safety on multiprocessor
@@ -1171,16 +1147,16 @@
     //
     // In LLVM, we do this by marking the load Acquire.
     if (threadsafe)
-      load->setAtomic(llvm::Acquire);
+      LI->setAtomic(llvm::Acquire);
 
-    isInitialized = Builder.CreateIsNull(load, "guard.uninitialized");
+    IsInitialized = Builder.CreateIsNull(LI, "guard.uninitialized");
   }
 
   llvm::BasicBlock *InitCheckBlock = CGF.createBasicBlock("init.check");
   llvm::BasicBlock *EndBlock = CGF.createBasicBlock("init.end");
 
   // Check if the first byte of the guard variable is zero.
-  Builder.CreateCondBr(isInitialized, InitCheckBlock, EndBlock);
+  Builder.CreateCondBr(IsInitialized, InitCheckBlock, EndBlock);
 
   CGF.EmitBlock(InitCheckBlock);
 
@@ -1188,7 +1164,7 @@
   if (threadsafe) {    
     // Call __cxa_guard_acquire.
     llvm::Value *V
-      = Builder.CreateCall(getGuardAcquireFn(CGM, guardPtrTy), guard);
+      = Builder.CreateCall(getGuardAcquireFn(CGM, GuardPtrTy), GuardVariable);
                
     llvm::BasicBlock *InitBlock = CGF.createBasicBlock("init");
   
@@ -1196,22 +1172,22 @@
                          InitBlock, EndBlock);
   
     // Call __cxa_guard_abort along the exceptional edge.
-    CGF.EHStack.pushCleanup<CallGuardAbort>(EHCleanup, guard);
+    CGF.EHStack.pushCleanup<CallGuardAbort>(EHCleanup, GuardVariable);
     
     CGF.EmitBlock(InitBlock);
   }
 
   // Emit the initializer and add a global destructor if appropriate.
-  CGF.EmitCXXGlobalVarDeclInit(D, varAddr, PerformInit);
+  CGF.EmitCXXGlobalVarDeclInit(D, GV, PerformInit);
 
   if (threadsafe) {
     // Pop the guard-abort cleanup if we pushed one.
     CGF.PopCleanupBlock();
 
     // Call __cxa_guard_release.  This cannot throw.
-    Builder.CreateCall(getGuardReleaseFn(CGM, guardPtrTy), guard);
+    Builder.CreateCall(getGuardReleaseFn(CGM, GuardPtrTy), GuardVariable);
   } else {
-    Builder.CreateStore(llvm::ConstantInt::get(guardTy, 1), guard);
+    Builder.CreateStore(llvm::ConstantInt::get(GuardTy, 1), GuardVariable);
   }
 
   CGF.EmitBlock(EndBlock);

Modified: cfe/trunk/test/CodeGenCXX/static-init.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/static-init.cpp?rev=153768&r1=153767&r2=153768&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/static-init.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/static-init.cpp Fri Mar 30 14:44:53 2012
@@ -3,7 +3,6 @@
 // CHECK: @_ZZ1hvE1i = internal global i32 0, align 4
 // CHECK: @base_req = global [4 x i8] c"foo\00", align 1
 
-// CHECK: @_ZZN5test31BC1EvE1u = internal global { i8, [3 x i8] } { i8 97, [3 x i8] undef }, align 4
 // CHECK: @_ZZN5test1L6getvarEiE3var = internal constant [4 x i32] [i32 1, i32 0, i32 2, i32 4], align 16
 // CHECK: @_ZZ2h2vE1i = linkonce_odr global i32 0
 // CHECK: @_ZGVZ2h2vE1i = linkonce_odr global i64 0
@@ -80,73 +79,3 @@
     c::main();
   }
 }
-
-// rdar://problem/11091093
-//   Static variables should be consistent across constructor
-//   or destructor variants.
-namespace test2 {
-  struct A {
-    A();
-    ~A();
-  };
-
-  struct B : virtual A {
-    B();
-    ~B();
-  };
-
-  // If we ever implement this as a delegate ctor call, just change
-  // this to take variadic arguments or something.
-  extern int foo();
-  B::B() {
-    static int x = foo();
-  }
-  // CHECK: define void @_ZN5test21BC1Ev
-  // CHECK:   load atomic i8* bitcast (i64* @_ZGVZN5test21BC1EvE1x to i8*) acquire,
-  // CHECK:   call i32 @__cxa_guard_acquire(i64* @_ZGVZN5test21BC1EvE1x)
-  // CHECK:   [[T0:%.*]] = call i32 @_ZN5test23fooEv()
-  // CHECK:   store i32 [[T0]], i32* @_ZZN5test21BC1EvE1x,
-  // CHECK:   call void @__cxa_guard_release(i64* @_ZGVZN5test21BC1EvE1x)
-
-  // CHECK: define void @_ZN5test21BC2Ev
-  // CHECK:   load atomic i8* bitcast (i64* @_ZGVZN5test21BC1EvE1x to i8*) acquire,
-  // CHECK:   call i32 @__cxa_guard_acquire(i64* @_ZGVZN5test21BC1EvE1x)
-  // CHECK:   [[T0:%.*]] = call i32 @_ZN5test23fooEv()
-  // CHECK:   store i32 [[T0]], i32* @_ZZN5test21BC1EvE1x,
-  // CHECK:   call void @__cxa_guard_release(i64* @_ZGVZN5test21BC1EvE1x)
-
-  // This is just for completeness, because we actually emit this
-  // using a delegate dtor call.
-  B::~B() {
-    static int y = foo();
-  }
-  // CHECK: define void @_ZN5test21BD1Ev(
-  // CHECK:   call void @_ZN5test21BD2Ev(
-
-  // CHECK: define void @_ZN5test21BD2Ev(
-  // CHECK:   load atomic i8* bitcast (i64* @_ZGVZN5test21BD1EvE1y to i8*) acquire,
-  // CHECK:   call i32 @__cxa_guard_acquire(i64* @_ZGVZN5test21BD1EvE1y)
-  // CHECK:   [[T0:%.*]] = call i32 @_ZN5test23fooEv()
-  // CHECK:   store i32 [[T0]], i32* @_ZZN5test21BD1EvE1y,
-  // CHECK:   call void @__cxa_guard_release(i64* @_ZGVZN5test21BD1EvE1y)
-}
-
-// This shouldn't error out.
-namespace test3 {
-  struct A {
-    A();
-    ~A();
-  };
-
-  struct B : virtual A {
-    B();
-    ~B();
-  };
-
-  B::B() {
-    union U { char x; int i; };
-    static U u = { 'a' };
-  }
-  // CHECK: define void @_ZN5test31BC1Ev(
-  // CHECK: define void @_ZN5test31BC2Ev(
-}





More information about the cfe-commits mailing list