From ffb945ffb5d29b80fd93649c3572b6d87abce3fc Mon Sep 17 00:00:00 2001 From: Anders Carlsson Date: Sat, 14 May 2011 23:26:09 +0000 Subject: When emitting the destructor for a class with a vtable, if we can determine that the destructor body is trivial and that all member variables also have either trivial destructors or trivial destructor bodies, we don't need to initialize the vtable pointers since no virtual member functions will be called on the destructor. Fixes PR9181. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@131368 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../skip-vtable-pointer-initialization.cpp | 106 +++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 test/CodeGenCXX/skip-vtable-pointer-initialization.cpp (limited to 'test/CodeGenCXX/skip-vtable-pointer-initialization.cpp') diff --git a/test/CodeGenCXX/skip-vtable-pointer-initialization.cpp b/test/CodeGenCXX/skip-vtable-pointer-initialization.cpp new file mode 100644 index 0000000000..f992bd339d --- /dev/null +++ b/test/CodeGenCXX/skip-vtable-pointer-initialization.cpp @@ -0,0 +1,106 @@ +// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s + +namespace Test1 { + +// Check that we don't initialize the vtable pointer in A::~A(), since the destructor body is trivial. +struct A { + virtual void f(); + ~A(); +}; + +// CHECK: define void @_ZN5Test11AD2Ev +// CHECK-NOT: store i8** getelementptr inbounds ([3 x i8*]* @_ZTVN5Test11AE, i64 0, i64 2), i8*** +A::~A() +{ +} + +} + +namespace Test2 { + +// Check that we do initialize the vtable pointer in A::~A() since the destructor body isn't trivial. +struct A { + virtual void f(); + ~A(); +}; + +// CHECK: define void @_ZN5Test21AD2Ev +// CHECK: store i8** getelementptr inbounds ([3 x i8*]* @_ZTVN5Test21AE, i64 0, i64 2), i8*** +A::~A() { + f(); +} + +} + +namespace Test3 { + +// Check that we don't initialize the vtable pointer in A::~A(), since the destructor body is trivial +// and Field's destructor body is also trivial. +struct Field { + ~Field() { } +}; + +struct A { + virtual void f(); + ~A(); + + Field field; +}; + +// CHECK: define void @_ZN5Test31AD2Ev +// CHECK-NOT: store i8** getelementptr inbounds ([3 x i8*]* @_ZTVN5Test31AE, i64 0, i64 2), i8*** +A::~A() { + +} + +} + +namespace Test4 { + +// Check that we do initialize the vtable pointer in A::~A(), since Field's destructor body +// isn't trivial. + +void f(); + +struct Field { + ~Field() { f(); } +}; + +struct A { + virtual void f(); + ~A(); + + Field field; +}; + +// CHECK: define void @_ZN5Test41AD2Ev +// CHECK: store i8** getelementptr inbounds ([3 x i8*]* @_ZTVN5Test41AE, i64 0, i64 2), i8*** +A::~A() +{ +} + +} + +namespace Test5 { + +// Check that we do initialize the vtable pointer in A::~A(), since Field's destructor isn't +// available in this translation unit. + +struct Field { + ~Field(); +}; + +struct A { + virtual void f(); + ~A(); + + Field field; +}; + +// CHECK: define void @_ZN5Test51AD2Ev +// CHECK: store i8** getelementptr inbounds ([3 x i8*]* @_ZTVN5Test51AE, i64 0, i64 2), i8*** +A::~A() +{ +} + +} \ No newline at end of file -- cgit v1.2.3-18-g5258