forked from OSchip/llvm-project
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:
parent
12d5ed8850
commit
20104048be
|
@ -980,6 +980,10 @@ void CodeGenFunction::EnterDtorCleanups(const CXXDestructorDecl *DD,
|
||||||
|
|
||||||
const CXXRecordDecl *ClassDecl = DD->getParent();
|
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.
|
// The complete-destructor phase just destructs all the virtual bases.
|
||||||
if (DtorType == Dtor_Complete) {
|
if (DtorType == Dtor_Complete) {
|
||||||
|
|
||||||
|
|
|
@ -2767,8 +2767,9 @@ void Sema::ActOnMemInitializers(Decl *ConstructorDecl,
|
||||||
void
|
void
|
||||||
Sema::MarkBaseAndMemberDestructorsReferenced(SourceLocation Location,
|
Sema::MarkBaseAndMemberDestructorsReferenced(SourceLocation Location,
|
||||||
CXXRecordDecl *ClassDecl) {
|
CXXRecordDecl *ClassDecl) {
|
||||||
// Ignore dependent contexts.
|
// Ignore dependent contexts. Also ignore unions, since their members never
|
||||||
if (ClassDecl->isDependentContext())
|
// have destructors implicitly called.
|
||||||
|
if (ClassDecl->isDependentContext() || ClassDecl->isUnion())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// FIXME: all the access-control diagnostics are positioned on the
|
// FIXME: all the access-control diagnostics are positioned on the
|
||||||
|
|
|
@ -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
|
Loading…
Reference in New Issue