summaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGDeclCXX.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2010-05-05 15:38:32 +0000
committerDouglas Gregor <dgregor@apple.com>2010-05-05 15:38:32 +0000
commitcc6a44b8bdecd9fc70211146e8ba3853b1fac784 (patch)
tree7bf18b33b17a8ae8a3c474fe915ca6e2e7cb49a7 /lib/CodeGen/CGDeclCXX.cpp
parent4bfe1968410ea8ffe3b4f629addd7c4bcf484765 (diff)
downloadclang-cc6a44b8bdecd9fc70211146e8ba3853b1fac784.tar.gz
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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@103088 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGDeclCXX.cpp')
-rw-r--r--lib/CodeGen/CGDeclCXX.cpp81
1 files changed, 48 insertions, 33 deletions
diff --git a/lib/CodeGen/CGDeclCXX.cpp b/lib/CodeGen/CGDeclCXX.cpp
index 6afa53868e..036be92885 100644
--- a/lib/CodeGen/CGDeclCXX.cpp
+++ b/lib/CodeGen/CGDeclCXX.cpp
@@ -22,7 +22,6 @@ static void EmitDeclInit(CodeGenFunction &CGF, const VarDecl &D,
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 @@ static void EmitDeclInit(CodeGenFunction &CGF, const VarDecl &D,
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 @@ void CodeGenFunction::EmitCXXGlobalVarDeclInit(const VarDecl &D,
if (!T->isReferenceType()) {
EmitDeclInit(*this, D, DeclPtr);
+ EmitDeclDestroy(*this, D, DeclPtr);
return;
}
if (Init->isLvalue(getContext()) == Expr::LV_Valid) {
@@ -349,5 +360,9 @@ CodeGenFunction::EmitStaticCXXBlockVarDeclInit(const VarDecl &D,
Builder.CreateStore(One, Builder.CreateBitCast(GuardVariable, PtrTy));
}
+ // Register the call to the destructor.
+ if (!D.getType()->isReferenceType())
+ EmitDeclDestroy(*this, D, GV);
+
EmitBlock(EndBlock);
}