From 20104048be328324112cc40c4b9df8145182e375 Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Sun, 18 Sep 2011 12:11:43 +0000 Subject: [PATCH] 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 --- clang/lib/CodeGen/CGClass.cpp | 4 +++ clang/lib/Sema/SemaDeclCXX.cpp | 5 ++-- clang/test/CodeGenCXX/union-dtor.cpp | 42 ++++++++++++++++++++++++++++ 3 files changed, 49 insertions(+), 2 deletions(-) create mode 100644 clang/test/CodeGenCXX/union-dtor.cpp diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp index 71cb13e9df3d..615a4daa8697 100644 --- a/clang/lib/CodeGen/CGClass.cpp +++ b/clang/lib/CodeGen/CGClass.cpp @@ -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) { diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index b408f7f0882f..e75b79c60956 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -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 diff --git a/clang/test/CodeGenCXX/union-dtor.cpp b/clang/test/CodeGenCXX/union-dtor.cpp new file mode 100644 index 000000000000..a9d1f8e9bd75 --- /dev/null +++ b/clang/test/CodeGenCXX/union-dtor.cpp @@ -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 +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