[cfe-commits] r131385 - in /cfe/trunk: lib/CodeGen/CGClass.cpp test/CodeGenCXX/mangle-subst-std.cpp test/CodeGenCXX/skip-vtable-pointer-initialization.cpp
Anders Carlsson
andersca at mac.com
Sun May 15 10:36:21 PDT 2011
Author: andersca
Date: Sun May 15 12:36:21 2011
New Revision: 131385
URL: http://llvm.org/viewvc/llvm-project?rev=131385&view=rev
Log:
Re-enable the fix for PR9181 now that all the edge cases are handled.
Modified:
cfe/trunk/lib/CodeGen/CGClass.cpp
cfe/trunk/test/CodeGenCXX/mangle-subst-std.cpp
cfe/trunk/test/CodeGenCXX/skip-vtable-pointer-initialization.cpp
Modified: cfe/trunk/lib/CodeGen/CGClass.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGClass.cpp?rev=131385&r1=131384&r2=131385&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGClass.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGClass.cpp Sun May 15 12:36:21 2011
@@ -741,14 +741,78 @@
EmitMemberInitializer(*this, ClassDecl, MemberInitializers[I], CD, Args);
}
+static bool
+FieldHasTrivialDestructorBody(ASTContext &Context, const FieldDecl *Field);
+
+static bool
+HasTrivialDestructorBody(ASTContext &Context,
+ const CXXRecordDecl *BaseClassDecl,
+ const CXXRecordDecl *MostDerivedClassDecl)
+{
+ // If the destructor is trivial we don't have to check anything else.
+ if (BaseClassDecl->hasTrivialDestructor())
+ return true;
+
+ if (!BaseClassDecl->getDestructor()->hasTrivialBody())
+ return false;
+
+ // Check fields.
+ for (CXXRecordDecl::field_iterator I = BaseClassDecl->field_begin(),
+ E = BaseClassDecl->field_end(); I != E; ++I) {
+ const FieldDecl *Field = *I;
+
+ if (!FieldHasTrivialDestructorBody(Context, Field))
+ return false;
+ }
+
+ // Check non-virtual bases.
+ for (CXXRecordDecl::base_class_const_iterator I =
+ BaseClassDecl->bases_begin(), E = BaseClassDecl->bases_end();
+ I != E; ++I) {
+ if (I->isVirtual())
+ continue;
+
+ const CXXRecordDecl *NonVirtualBase =
+ cast<CXXRecordDecl>(I->getType()->castAs<RecordType>()->getDecl());
+ if (!HasTrivialDestructorBody(Context, NonVirtualBase,
+ MostDerivedClassDecl))
+ return false;
+ }
+
+ if (BaseClassDecl == MostDerivedClassDecl) {
+ // Check virtual bases.
+ for (CXXRecordDecl::base_class_const_iterator I =
+ BaseClassDecl->vbases_begin(), E = BaseClassDecl->vbases_end();
+ I != E; ++I) {
+ const CXXRecordDecl *VirtualBase =
+ cast<CXXRecordDecl>(I->getType()->castAs<RecordType>()->getDecl());
+ if (!HasTrivialDestructorBody(Context, VirtualBase,
+ MostDerivedClassDecl))
+ return false;
+ }
+ }
+
+ return true;
+}
+
+static bool
+FieldHasTrivialDestructorBody(ASTContext &Context,
+ const FieldDecl *Field)
+{
+ QualType FieldBaseElementType = Context.getBaseElementType(Field->getType());
+
+ const RecordType *RT = FieldBaseElementType->getAs<RecordType>();
+ if (!RT)
+ return true;
+
+ CXXRecordDecl *FieldClassDecl = cast<CXXRecordDecl>(RT->getDecl());
+ return HasTrivialDestructorBody(Context, FieldClassDecl, FieldClassDecl);
+}
+
/// CanSkipVTablePointerInitialization - Check whether we need to initialize
/// any vtable pointers before calling this destructor.
static bool CanSkipVTablePointerInitialization(ASTContext &Context,
const CXXDestructorDecl *Dtor) {
- // FIXME: We need to check dtors of bases of members too.
- // Re-enable once this has been fixed.
- return false;
-
if (!Dtor->hasTrivialBody())
return false;
@@ -757,21 +821,9 @@
for (CXXRecordDecl::field_iterator I = ClassDecl->field_begin(),
E = ClassDecl->field_end(); I != E; ++I) {
const FieldDecl *Field = *I;
-
- QualType FieldBaseElementType =
- Context.getBaseElementType(Field->getType());
- const RecordType *RT = FieldBaseElementType->getAs<RecordType>();
- if (!RT)
- continue;
-
- CXXRecordDecl *FieldClassDecl = cast<CXXRecordDecl>(RT->getDecl());
- if (FieldClassDecl->hasTrivialDestructor())
- continue;
- if (FieldClassDecl->getDestructor()->hasTrivialBody())
- continue;
-
- return false;
+ if (!FieldHasTrivialDestructorBody(Context, Field))
+ return false;
}
return true;
Modified: cfe/trunk/test/CodeGenCXX/mangle-subst-std.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/mangle-subst-std.cpp?rev=131385&r1=131384&r2=131385&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/mangle-subst-std.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/mangle-subst-std.cpp Sun May 15 12:36:21 2011
@@ -8,8 +8,8 @@
// CHECK: @_ZTCSd0_Si = linkonce_odr unnamed_addr constant
// CHECK: @_ZTCSd16_So = linkonce_odr unnamed_addr constant
// CHECK: @_ZTTSo = linkonce_odr unnamed_addr constant
-// CHECK: @_ZTVSo = linkonce_odr unnamed_addr constant
// CHECK: @_ZTTSi = linkonce_odr unnamed_addr constant
+// CHECK: @_ZTVSo = linkonce_odr unnamed_addr constant
// CHECK: @_ZTVSi = linkonce_odr unnamed_addr constant
namespace std {
struct A { A(); };
Modified: cfe/trunk/test/CodeGenCXX/skip-vtable-pointer-initialization.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/skip-vtable-pointer-initialization.cpp?rev=131385&r1=131384&r2=131385&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/skip-vtable-pointer-initialization.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/skip-vtable-pointer-initialization.cpp Sun May 15 12:36:21 2011
@@ -1,5 +1,4 @@
// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
-// XFAIL: *
namespace Test1 {
@@ -104,4 +103,84 @@
{
}
-}
\ No newline at end of file
+}
+
+namespace Test6 {
+
+// Check that we do initialize the vtable pointer in A::~A(), since Field has a member
+// variable with a non-trivial destructor body.
+
+struct NonTrivialDestructorBody {
+ ~NonTrivialDestructorBody();
+};
+
+struct Field {
+ NonTrivialDestructorBody nonTrivialDestructorBody;
+};
+
+struct A {
+ virtual void f();
+ ~A();
+
+ Field field;
+};
+
+// CHECK: define void @_ZN5Test61AD2Ev
+// CHECK: store i8** getelementptr inbounds ([3 x i8*]* @_ZTVN5Test61AE, i64 0, i64 2), i8***
+A::~A()
+{
+}
+
+}
+
+namespace Test7 {
+
+// Check that we do initialize the vtable pointer in A::~A(), since Field has a base
+// class with a non-trivial destructor body.
+
+struct NonTrivialDestructorBody {
+ ~NonTrivialDestructorBody();
+};
+
+struct Field : NonTrivialDestructorBody { };
+
+struct A {
+ virtual void f();
+ ~A();
+
+ Field field;
+};
+
+// CHECK: define void @_ZN5Test71AD2Ev
+// CHECK: store i8** getelementptr inbounds ([3 x i8*]* @_ZTVN5Test71AE, i64 0, i64 2), i8***
+A::~A()
+{
+}
+
+}
+
+namespace Test8 {
+
+// Check that we do initialize the vtable pointer in A::~A(), since Field has a virtual base
+// class with a non-trivial destructor body.
+
+struct NonTrivialDestructorBody {
+ ~NonTrivialDestructorBody();
+};
+
+struct Field : virtual NonTrivialDestructorBody { };
+
+struct A {
+ virtual void f();
+ ~A();
+
+ Field field;
+};
+
+// CHECK: define void @_ZN5Test81AD2Ev
+// CHECK: store i8** getelementptr inbounds ([3 x i8*]* @_ZTVN5Test81AE, i64 0, i64 2), i8***
+A::~A()
+{
+}
+
+}
More information about the cfe-commits
mailing list