[cfe-commits] r109849 - in /cfe/trunk: lib/CodeGen/CGDeclCXX.cpp test/CodeGenCXX/global-init.cpp
John McCall
rjmccall at apple.com
Thu Jul 29 21:56:58 PDT 2010
Author: rjmccall
Date: Thu Jul 29 23:56:58 2010
New Revision: 109849
URL: http://llvm.org/viewvc/llvm-project?rev=109849&view=rev
Log:
Emit global destructors even if the destroyed object has no initializers or has
an initializer requiring temporary object disposal.
Fixes rdar:://problem/8246444.
Modified:
cfe/trunk/lib/CodeGen/CGDeclCXX.cpp
cfe/trunk/test/CodeGenCXX/global-init.cpp
Modified: cfe/trunk/lib/CodeGen/CGDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDeclCXX.cpp?rev=109849&r1=109848&r2=109849&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGDeclCXX.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGDeclCXX.cpp Thu Jul 29 23:56:58 2010
@@ -45,19 +45,15 @@
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;
+ // Drill down past array types.
const ConstantArrayType *Array = Context.getAsConstantArrayType(T);
if (Array)
T = Context.getBaseElementType(Array);
+ /// If that's not a record, we're done.
+ /// FIXME: __attribute__((cleanup)) ?
const RecordType *RT = T->getAs<RecordType>();
if (!RT)
return;
Modified: cfe/trunk/test/CodeGenCXX/global-init.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/global-init.cpp?rev=109849&r1=109848&r2=109849&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/global-init.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/global-init.cpp Thu Jul 29 23:56:58 2010
@@ -37,6 +37,22 @@
const int z = ~y; // This also gets deferred, but gets "undeferred" before y.
int test() { return z; }
// CHECK: define i32 @_ZN5test14testEv() {
+
+ // All of these initializers end up delayed, so we check them later.
+}
+
+// <rdar://problem/8246444>
+namespace test2 {
+ struct allocator { allocator(); ~allocator(); };
+ struct A { A(const allocator &a = allocator()); ~A(); };
+
+ A a;
+// CHECK: call void @_ZN5test29allocatorC1Ev(
+// CHECK: invoke void @_ZN5test21AC1ERKNS_9allocatorE(
+// CHECK: call void @_ZN5test29allocatorD1Ev(
+// CHECK: call i32 @__cxa_atexit({{.*}} @_ZN5test21AD1Ev {{.*}} @_ZN5test21aE
+}
+
// CHECK: define internal void [[TEST1_Z_INIT:@.*]]()
// CHECK: load i32* @_ZN5test1L1yE
// CHECK-NEXT: xor
@@ -46,8 +62,7 @@
// CHECK-NEXT: sub
// CHECK-NEXT: store i32 {{.*}}, i32* @_ZN5test1L1yE
-// Later on, we check that y is initialized before z.
-}
+// At the end of the file, we check that y is initialized before z.
// CHECK: define internal void @_GLOBAL__I_a() section "__TEXT,__StaticInit,regular,pure_instructions" {
// CHECK: call void [[TEST1_Y_INIT]]
More information about the cfe-commits
mailing list