skip-vtable-pointer-initialization.cpp revision adf5dc340db3ea99de5fe3f6c42cfee1807d445e
1// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s 2 3namespace Test1 { 4 5// Check that we don't initialize the vtable pointer in A::~A(), since the destructor body is trivial. 6struct A { 7 virtual void f(); 8 ~A(); 9}; 10 11// CHECK: define void @_ZN5Test11AD2Ev 12// CHECK-NOT: store i8** getelementptr inbounds ([3 x i8*]* @_ZTVN5Test11AE, i64 0, i64 2), i8*** 13A::~A() 14{ 15} 16 17} 18 19namespace Test2 { 20 21// Check that we do initialize the vtable pointer in A::~A() since the destructor body isn't trivial. 22struct A { 23 virtual void f(); 24 ~A(); 25}; 26 27// CHECK: define void @_ZN5Test21AD2Ev 28// CHECK: store i8** getelementptr inbounds ([3 x i8*]* @_ZTVN5Test21AE, i64 0, i64 2), i8*** 29A::~A() { 30 f(); 31} 32 33} 34 35namespace Test3 { 36 37// Check that we don't initialize the vtable pointer in A::~A(), since the destructor body is trivial 38// and Field's destructor body is also trivial. 39struct Field { 40 ~Field() { } 41}; 42 43struct A { 44 virtual void f(); 45 ~A(); 46 47 Field field; 48}; 49 50// CHECK: define void @_ZN5Test31AD2Ev 51// CHECK-NOT: store i8** getelementptr inbounds ([3 x i8*]* @_ZTVN5Test31AE, i64 0, i64 2), i8*** 52A::~A() { 53 54} 55 56} 57 58namespace Test4 { 59 60// Check that we do initialize the vtable pointer in A::~A(), since Field's destructor body 61// isn't trivial. 62 63void f(); 64 65struct Field { 66 ~Field() { f(); } 67}; 68 69struct A { 70 virtual void f(); 71 ~A(); 72 73 Field field; 74}; 75 76// CHECK: define void @_ZN5Test41AD2Ev 77// CHECK: store i8** getelementptr inbounds ([3 x i8*]* @_ZTVN5Test41AE, i64 0, i64 2), i8*** 78A::~A() 79{ 80} 81 82} 83 84namespace Test5 { 85 86// Check that we do initialize the vtable pointer in A::~A(), since Field's destructor isn't 87// available in this translation unit. 88 89struct Field { 90 ~Field(); 91}; 92 93struct A { 94 virtual void f(); 95 ~A(); 96 97 Field field; 98}; 99 100// CHECK: define void @_ZN5Test51AD2Ev 101// CHECK: store i8** getelementptr inbounds ([3 x i8*]* @_ZTVN5Test51AE, i64 0, i64 2), i8*** 102A::~A() 103{ 104} 105 106} 107 108namespace Test6 { 109 110// Check that we do initialize the vtable pointer in A::~A(), since Field has a member 111// variable with a non-trivial destructor body. 112 113struct NonTrivialDestructorBody { 114 ~NonTrivialDestructorBody(); 115}; 116 117struct Field { 118 NonTrivialDestructorBody nonTrivialDestructorBody; 119}; 120 121struct A { 122 virtual void f(); 123 ~A(); 124 125 Field field; 126}; 127 128// CHECK: define void @_ZN5Test61AD2Ev 129// CHECK: store i8** getelementptr inbounds ([3 x i8*]* @_ZTVN5Test61AE, i64 0, i64 2), i8*** 130A::~A() 131{ 132} 133 134} 135 136namespace Test7 { 137 138// Check that we do initialize the vtable pointer in A::~A(), since Field has a base 139// class with a non-trivial destructor body. 140 141struct NonTrivialDestructorBody { 142 ~NonTrivialDestructorBody(); 143}; 144 145struct Field : NonTrivialDestructorBody { }; 146 147struct A { 148 virtual void f(); 149 ~A(); 150 151 Field field; 152}; 153 154// CHECK: define void @_ZN5Test71AD2Ev 155// CHECK: store i8** getelementptr inbounds ([3 x i8*]* @_ZTVN5Test71AE, i64 0, i64 2), i8*** 156A::~A() 157{ 158} 159 160} 161 162namespace Test8 { 163 164// Check that we do initialize the vtable pointer in A::~A(), since Field has a virtual base 165// class with a non-trivial destructor body. 166 167struct NonTrivialDestructorBody { 168 ~NonTrivialDestructorBody(); 169}; 170 171struct Field : virtual NonTrivialDestructorBody { }; 172 173struct A { 174 virtual void f(); 175 ~A(); 176 177 Field field; 178}; 179 180// CHECK: define void @_ZN5Test81AD2Ev 181// CHECK: store i8** getelementptr inbounds ([3 x i8*]* @_ZTVN5Test81AE, i64 0, i64 2), i8*** 182A::~A() 183{ 184} 185 186} 187