[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