PR10304: Do not call destructors for data members from union destructors. Prior to C++11, this

has no effect since any such destructors must be trivial, and in C++11 such destructors must not
be called.

llvm-svn: 139997
This commit is contained in:
Richard Smith 2011-09-18 12:11:43 +00:00
parent 12d5ed8850
commit 20104048be
3 changed files with 49 additions and 2 deletions

View File

@ -980,6 +980,10 @@ void CodeGenFunction::EnterDtorCleanups(const CXXDestructorDecl *DD,
const CXXRecordDecl *ClassDecl = DD->getParent();
// Unions have no bases and do not call field destructors.
if (ClassDecl->isUnion())
return;
// The complete-destructor phase just destructs all the virtual bases.
if (DtorType == Dtor_Complete) {

View File

@ -2767,8 +2767,9 @@ void Sema::ActOnMemInitializers(Decl *ConstructorDecl,
void
Sema::MarkBaseAndMemberDestructorsReferenced(SourceLocation Location,
CXXRecordDecl *ClassDecl) {
// Ignore dependent contexts.
if (ClassDecl->isDependentContext())
// Ignore dependent contexts. Also ignore unions, since their members never
// have destructors implicitly called.
if (ClassDecl->isDependentContext() || ClassDecl->isUnion())
return;
// FIXME: all the access-control diagnostics are positioned on the

View File

@ -0,0 +1,42 @@
// RUN: %clang_cc1 -std=c++0x %s -S -o - -emit-llvm | FileCheck %s
// PR10304: destructors should not call destructors for variant members.
template<bool b = false>
struct Foo {
Foo() { static_assert(b, "Foo::Foo used"); }
~Foo() { static_assert(b, "Foo::~Foo used"); }
};
struct Bar {
Bar();
~Bar();
};
union FooBar {
FooBar() {}
~FooBar() {}
Foo<> foo;
Bar bar;
};
struct Variant {
Variant() {}
~Variant() {}
union {
Foo<> foo;
Bar bar;
};
};
FooBar foobar;
Variant variant;
// The ctor and dtor of Foo<> and Bar should not be mentioned in the resulting
// code.
//
// CHECK-NOT: 3FooILb1EEC1
// CHECK-NOT: 3BarC1
//
// CHECK-NOT: 3FooILb1EED1
// CHECK-NOT: 3BarD1