[cfe-commits] r103088 - in /cfe/trunk: lib/CodeGen/CGDeclCXX.cpp test/CodeGenCXX/static-init.cpp

Douglas Gregor dgregor at apple.com
Wed May 5 08:38:32 PDT 2010


Author: dgregor
Date: Wed May  5 10:38:32 2010
New Revision: 103088

URL: http://llvm.org/viewvc/llvm-project?rev=103088&view=rev
Log:
For thread-safe static initialization of local statics with
destructors, place the __cxa_atexit call after the __cxa_guard_release
call, mimicking GCC/LLVM-GCC behavior. Noticed while debugging
something related.

Modified:
    cfe/trunk/lib/CodeGen/CGDeclCXX.cpp
    cfe/trunk/test/CodeGenCXX/static-init.cpp

Modified: cfe/trunk/lib/CodeGen/CGDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDeclCXX.cpp?rev=103088&r1=103087&r2=103088&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGDeclCXX.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGDeclCXX.cpp Wed May  5 10:38:32 2010
@@ -22,7 +22,6 @@
   assert(!D.getType()->isReferenceType() && 
          "Should not call EmitDeclInit on a reference!");
   
-  CodeGenModule &CGM = CGF.CGM;
   ASTContext &Context = CGF.getContext();
     
   const Expr *Init = D.getInit();
@@ -36,41 +35,52 @@
     CGF.EmitComplexExprIntoAddr(Init, DeclPtr, isVolatile);
   } else {
     CGF.EmitAggExpr(Init, DeclPtr, isVolatile);
-    
-    // Avoid generating destructor(s) for initialized objects. 
-    if (!isa<CXXConstructExpr>(Init))
-      return;
-    
-    const ConstantArrayType *Array = Context.getAsConstantArrayType(T);
-    if (Array)
-      T = Context.getBaseElementType(Array);
-    
-    const RecordType *RT = T->getAs<RecordType>();
-    if (!RT)
-      return;
-    
-    CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
-    if (RD->hasTrivialDestructor())
-      return;
-    
-    CXXDestructorDecl *Dtor = RD->getDestructor(Context);
-    
-    llvm::Constant *DtorFn;
-    if (Array) {
-      DtorFn = 
-        CodeGenFunction(CGM).GenerateCXXAggrDestructorHelper(Dtor, 
-                                                             Array, 
-                                                             DeclPtr);
-      const llvm::Type *Int8PtrTy =
-        llvm::Type::getInt8PtrTy(CGM.getLLVMContext());
-      DeclPtr = llvm::Constant::getNullValue(Int8PtrTy);
-     } else
-      DtorFn = CGM.GetAddrOfCXXDestructor(Dtor, Dtor_Complete);
-
-    CGF.EmitCXXGlobalDtorRegistration(DtorFn, DeclPtr);
   }
 }
 
+static void EmitDeclDestroy(CodeGenFunction &CGF, const VarDecl &D,
+                            llvm::Constant *DeclPtr) {
+  CodeGenModule &CGM = CGF.CGM;
+  ASTContext &Context = CGF.getContext();
+  
+  const Expr *Init = D.getInit();
+  QualType T = D.getType();
+  if (!CGF.hasAggregateLLVMType(T) || T->isAnyComplexType())
+    return;
+                                
+  // Avoid generating destructor(s) for initialized objects. 
+  if (!isa<CXXConstructExpr>(Init))
+    return;
+  
+  const ConstantArrayType *Array = Context.getAsConstantArrayType(T);
+  if (Array)
+    T = Context.getBaseElementType(Array);
+  
+  const RecordType *RT = T->getAs<RecordType>();
+  if (!RT)
+    return;
+  
+  CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
+  if (RD->hasTrivialDestructor())
+    return;
+  
+  CXXDestructorDecl *Dtor = RD->getDestructor(Context);
+  
+  llvm::Constant *DtorFn;
+  if (Array) {
+    DtorFn = 
+    CodeGenFunction(CGM).GenerateCXXAggrDestructorHelper(Dtor, 
+                                                         Array, 
+                                                         DeclPtr);
+    const llvm::Type *Int8PtrTy =
+    llvm::Type::getInt8PtrTy(CGM.getLLVMContext());
+    DeclPtr = llvm::Constant::getNullValue(Int8PtrTy);
+  } else
+    DtorFn = CGM.GetAddrOfCXXDestructor(Dtor, Dtor_Complete);
+  
+  CGF.EmitCXXGlobalDtorRegistration(DtorFn, DeclPtr);
+}
+
 void CodeGenFunction::EmitCXXGlobalVarDeclInit(const VarDecl &D,
                                                llvm::Constant *DeclPtr) {
 
@@ -79,6 +89,7 @@
 
   if (!T->isReferenceType()) {
     EmitDeclInit(*this, D, DeclPtr);
+    EmitDeclDestroy(*this, D, DeclPtr);
     return;
   }
   if (Init->isLvalue(getContext()) == Expr::LV_Valid) {
@@ -349,5 +360,9 @@
     Builder.CreateStore(One, Builder.CreateBitCast(GuardVariable, PtrTy));
   }
 
+  // Register the call to the destructor.
+  if (!D.getType()->isReferenceType())
+    EmitDeclDestroy(*this, D, GV);
+  
   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=103088&r1=103087&r2=103088&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/static-init.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/static-init.cpp Wed May  5 10:38:32 2010
@@ -11,7 +11,9 @@
 };
 
 void f() {
-  // CHECK: call void @_ZN1AC1Ev(
+  // CHECK: call i32 @__cxa_guard_acquire
+  // CHECK: call void @_ZN1AC1Ev
+  // CHECK: call void @__cxa_guard_release
   // CHECK: call i32 @__cxa_atexit(void (i8*)* bitcast (void (%struct.A*)* @_ZN1AD1Ev to void (i8*)*), i8* getelementptr inbounds (%struct.A* @_ZZ1fvE1a, i32 0, i32 0), i8* bitcast (i8** @__dso_handle to i8*))
   static A a;
 }





More information about the cfe-commits mailing list