[cfe-commits] r130803 - in /cfe/trunk: lib/CodeGen/CGClass.cpp lib/Sema/SemaDeclCXX.cpp test/CodeGenCXX/cxx0x-delegating-ctors.cpp test/SemaCXX/cxx0x-delegating-ctors.cpp

Sean Hunt scshunt at csclub.uwaterloo.ca
Tue May 3 16:05:34 PDT 2011


Author: coppro
Date: Tue May  3 18:05:34 2011
New Revision: 130803

URL: http://llvm.org/viewvc/llvm-project?rev=130803&view=rev
Log:
Ensure that destructors are properly inovked when an exception leaves
the body of a delegating constructor call.

This means that the delegating constructor implementation should be
complete and correct, though there are some rough edges (diagnostic
quality with the cycle detection and using a deleted destructor).

Modified:
    cfe/trunk/lib/CodeGen/CGClass.cpp
    cfe/trunk/lib/Sema/SemaDeclCXX.cpp
    cfe/trunk/test/CodeGenCXX/cxx0x-delegating-ctors.cpp
    cfe/trunk/test/SemaCXX/cxx0x-delegating-ctors.cpp

Modified: cfe/trunk/lib/CodeGen/CGClass.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGClass.cpp?rev=130803&r1=130802&r2=130803&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGClass.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGClass.cpp Tue May  3 18:05:34 2011
@@ -1270,6 +1270,23 @@
            ReturnValueSlot(), DelegateArgs, Ctor);
 }
 
+namespace {
+  struct CallDelegatingCtorDtor : EHScopeStack::Cleanup {
+    const CXXDestructorDecl *Dtor;
+    llvm::Value *Addr;
+    CXXDtorType Type;
+
+    CallDelegatingCtorDtor(const CXXDestructorDecl *D, llvm::Value *Addr,
+                           CXXDtorType Type)
+      : Dtor(D), Addr(Addr), Type(Type) {}
+
+    void Emit(CodeGenFunction &CGF, bool IsForEH) {
+      CGF.EmitCXXDestructorCall(Dtor, Type, /*ForVirtualBase=*/false,
+                                Addr);
+    }
+  };
+}
+
 void
 CodeGenFunction::EmitDelegatingCXXConstructorCall(const CXXConstructorDecl *Ctor,
                                                   const FunctionArgList &Args) {
@@ -1280,8 +1297,17 @@
   AggValueSlot AggSlot = AggValueSlot::forAddr(ThisPtr, false, /*Lifetime*/ true);
 
   EmitAggExpr(Ctor->init_begin()[0]->getInit(), AggSlot);
-}
 
+  const CXXRecordDecl *ClassDecl = Ctor->getParent();
+  if (CGM.getLangOptions().Exceptions && !ClassDecl->hasTrivialDestructor()) {
+    CXXDtorType Type =
+      CurGD.getCtorType() == Ctor_Complete ? Dtor_Complete : Dtor_Base;
+
+    EHStack.pushCleanup<CallDelegatingCtorDtor>(EHCleanup,
+                                                ClassDecl->getDestructor(),
+                                                ThisPtr, Type);
+  }
+}
 
 void CodeGenFunction::EmitCXXDestructorCall(const CXXDestructorDecl *DD,
                                             CXXDtorType Type,

Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=130803&r1=130802&r2=130803&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Tue May  3 18:05:34 2011
@@ -2095,6 +2095,11 @@
   memcpy(initializer, &Initializer, sizeof (CXXCtorInitializer*));
   Constructor->setCtorInitializers(initializer);
 
+  if (CXXDestructorDecl *Dtor = LookupDestructor(Constructor->getParent())) {
+    MarkDeclarationReferenced(Initializer->getSourceLocation(), Dtor);
+    DiagnoseUseOfDecl(Dtor, Initializer->getSourceLocation());
+  }
+
   return false;
 }
 

Modified: cfe/trunk/test/CodeGenCXX/cxx0x-delegating-ctors.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/cxx0x-delegating-ctors.cpp?rev=130803&r1=130802&r2=130803&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/cxx0x-delegating-ctors.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/cxx0x-delegating-ctors.cpp Tue May  3 18:05:34 2011
@@ -22,27 +22,35 @@
   throw 0;
 }
 
+
+delegator::delegator(bool)
+{}
+
+// CHECK: define void @_ZN9delegatorC1Ec
+// CHECK: void @_ZN9delegatorC1Eb
+// CHECK: void @__cxa_throw
+// CHECK: lpad
+// CHECK: void @_ZN9delegatorD1Ev
+// CHECK: define void @_ZN9delegatorC2Ec
+// CHECK: void @_ZN9delegatorC2Eb
+// CHECK: void @__cxa_throw
+// CHECK: lpad
+// CHECK: invoke void @_ZN9delegatorD2Ev
+delegator::delegator(char)
+  : delegator(true) {
+  throw 0;
+}
+
 // CHECK: define void @_ZN9delegatorC1Ei
-// CHECK: call void @_ZN9delegatorC1Ev
+// CHECK: void @_ZN9delegatorC1Ev
 // CHECK-NOT: lpad
 // CHECK: ret
 // CHECK-NOT: lpad
 // CHECK: define void @_ZN9delegatorC2Ei
-// CHECK: call void @_ZN9delegatorC2Ev
+// CHECK: void @_ZN9delegatorC2Ev
 // CHECK-NOT: lpad
 // CHECK: ret
 // CHECK-NOT: lpad
 delegator::delegator(int)
   : delegator()
 {}
-
-delegator::delegator(bool)
-{}
-
-// CHECK: define void @_ZN9delegatorC2Ec
-// CHECK: call void @_ZN9delegatorC2Eb
-// CHECK: call void @__cxa_throw
-delegator::delegator(char)
-  : delegator(true) {
-  throw 0;
-}

Modified: cfe/trunk/test/SemaCXX/cxx0x-delegating-ctors.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx0x-delegating-ctors.cpp?rev=130803&r1=130802&r2=130803&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/cxx0x-delegating-ctors.cpp (original)
+++ cfe/trunk/test/SemaCXX/cxx0x-delegating-ctors.cpp Tue May  3 18:05:34 2011
@@ -7,8 +7,9 @@
   foo(int, int);
   foo(bool);
   foo(char);
-  foo(float*);
-  foo(float&);
+  foo(const float*);
+  foo(const float&);
+  foo(void*);
 };
 
 // Good
@@ -25,12 +26,23 @@
 }
 
 // Good
-foo::foo (float* f) : foo(*f) {
+foo::foo (const float* f) : foo(*f) {
 }
 
 // FIXME: This should error
-foo::foo (float &f) : foo(&f) {
+foo::foo (const float &f) : foo(&f) {
 }
 
 foo::foo (char) : i(3), foo(3) { // expected-error{{must appear alone}}
 }
+
+// This should not cause an infinite loop
+foo::foo (void*) : foo(4.0f) {
+}
+
+struct deleted_dtor {
+  ~deleted_dtor() = delete; // expected-note{{function has been explicitly marked deleted here}}
+  deleted_dtor();
+  deleted_dtor(int) : deleted_dtor() // expected-error{{attempt to use a deleted function}}
+  {}
+};





More information about the cfe-commits mailing list