aboutsummaryrefslogtreecommitdiff
path: root/test/CodeGenCXX/skip-vtable-pointer-initialization.cpp
diff options
context:
space:
mode:
authorAnders Carlsson <andersca@mac.com>2011-05-14 23:26:09 +0000
committerAnders Carlsson <andersca@mac.com>2011-05-14 23:26:09 +0000
commitffb945ffb5d29b80fd93649c3572b6d87abce3fc (patch)
treeb2f9cf40b3b751972661f2b3763cbabc636c7fb0 /test/CodeGenCXX/skip-vtable-pointer-initialization.cpp
parenta83c17c28f4a570e18678f6031834487534f120d (diff)
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
Diffstat (limited to 'test/CodeGenCXX/skip-vtable-pointer-initialization.cpp')
-rw-r--r--test/CodeGenCXX/skip-vtable-pointer-initialization.cpp106
1 files changed, 106 insertions, 0 deletions
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