1 // RUN: %clang_cc1 %s -triple i686-linux -emit-llvm -o - -mconstructor-aliases -O1 -disable-llvm-optzns | FileCheck %s 2 // RUN: %clang_cc1 %s -triple i686-linux -emit-llvm -o - -mconstructor-aliases | FileCheck --check-prefix=NOOPT %s 3 4 // RUN: %clang_cc1 -triple x86_64--netbsd -emit-llvm \ 5 // RUN: -mconstructor-aliases -O2 %s -o - | FileCheck --check-prefix=CHECK-RAUW %s 6 7 namespace test1 { 8 // test that we don't produce an alias when the destructor is weak_odr. The 9 // reason to avoid it that another TU might have no explicit template 10 // instantiation definition or declaration, causing it to to output only 11 // one of the destructors as linkonce_odr, producing a different comdat. 12 13 // CHECK-DAG: define weak_odr void @_ZN5test16foobarIvEC2Ev 14 // CHECK-DAG: define weak_odr void @_ZN5test16foobarIvEC1Ev 15 16 template <typename T> struct foobar { 17 foobar() {} 18 }; 19 20 template struct foobar<void>; 21 } 22 23 namespace test2 { 24 // test that when the destrucor is linkonce_odr we just replace every use of 25 // C1 with C2. 26 27 // CHECK-DAG: define linkonce_odr void @_ZN5test26foobarIvEC2Ev( 28 // CHECK-DAG: call void @_ZN5test26foobarIvEC2Ev 29 void g(); 30 template <typename T> struct foobar { 31 foobar() { g(); } 32 }; 33 foobar<void> x; 34 } 35 36 namespace test3 { 37 // test that instead of an internal alias we just use the other destructor 38 // directly. 39 40 // CHECK-DAG: define internal void @_ZN5test312_GLOBAL__N_11AD2Ev( 41 // CHECK-DAG: call i32 @__cxa_atexit{{.*}}_ZN5test312_GLOBAL__N_11AD2Ev 42 namespace { 43 struct A { 44 ~A() {} 45 }; 46 47 struct B : public A {}; 48 } 49 50 B x; 51 } 52 53 namespace test4 { 54 // Test that we don't produce aliases from B to A. We cannot because we cannot 55 // guarantee that they will be present in every TU. Instead, we just call 56 // A's destructor directly. 57 58 // CHECK-DAG: define linkonce_odr void @_ZN5test41AD2Ev( 59 // CHECK-DAG: call i32 @__cxa_atexit{{.*}}_ZN5test41AD2Ev 60 61 // test that we don't do this optimization at -O0 so that the debugger can 62 // see both destructors. 63 // NOOPT-DAG: call i32 @__cxa_atexit{{.*}}@_ZN5test41BD2Ev 64 // NOOPT-DAG: define linkonce_odr void @_ZN5test41BD2Ev 65 struct A { 66 virtual ~A() {} 67 }; 68 struct B : public A{ 69 ~B() {} 70 }; 71 B X; 72 } 73 74 namespace test5 { 75 // similar to test4, but with an internal B. 76 77 // CHECK-DAG: define linkonce_odr void @_ZN5test51AD2Ev( 78 // CHECK-DAG: call i32 @__cxa_atexit{{.*}}_ZN5test51AD2Ev 79 struct A { 80 virtual ~A() {} 81 }; 82 namespace { 83 struct B : public A{ 84 ~B() {} 85 }; 86 } 87 B X; 88 } 89 90 namespace test6 { 91 // Test that we use ~A directly, even when ~A is not defined. The symbol for 92 // ~B would have been internal and still contain a reference to ~A. 93 struct A { 94 virtual ~A(); 95 }; 96 namespace { 97 struct B : public A { 98 ~B() {} 99 }; 100 } 101 B X; 102 // CHECK-DAG: call i32 @__cxa_atexit({{.*}}@_ZN5test61AD2Ev 103 } 104 105 namespace test7 { 106 // Test that we don't produce an alias from ~B to ~A<int> (or crash figuring 107 // out if we should). 108 // pr17875. 109 // CHECK-DAG: define void @_ZN5test71BD2Ev 110 template <typename> struct A { 111 ~A() {} 112 }; 113 class B : A<int> { 114 ~B(); 115 }; 116 template class A<int>; 117 B::~B() {} 118 } 119 120 namespace test8 { 121 // Test that we replace ~zed with ~bar which is an alias to ~foo. 122 // CHECK-DAG: call i32 @__cxa_atexit({{.*}}@_ZN5test83barD2Ev 123 // CHECK-DAG: @_ZN5test83barD2Ev = alias {{.*}} @_ZN5test83fooD2Ev 124 struct foo { 125 ~foo(); 126 }; 127 foo::~foo() {} 128 struct bar : public foo { 129 ~bar(); 130 }; 131 bar::~bar() {} 132 struct zed : public bar {}; 133 zed foo; 134 } 135 136 namespace test9 { 137 struct foo { 138 __attribute__((stdcall)) ~foo() { 139 } 140 }; 141 142 struct bar : public foo {}; 143 144 void zed() { 145 // Test that we produce a call to bar's destructor. We used to call foo's, but 146 // it has a different calling conversion. 147 // CHECK-DAG: call void @_ZN5test93barD2Ev 148 bar ptr; 149 } 150 } 151 152 // CHECK-RAUW: @_ZTV1C = linkonce_odr unnamed_addr constant [4 x i8*] [{{[^@]*}}@_ZTI1C {{[^@]*}}@_ZN1CD2Ev {{[^@]*}}@_ZN1CD0Ev {{[^@]*}}] 153 // r194296 replaced C::~C with B::~B without emitting the later. 154 155 class A { 156 public: 157 A(int); 158 virtual ~A(); 159 }; 160 161 template <class> 162 class B : A { 163 public: 164 B() 165 : A(0) { 166 } 167 __attribute__((always_inline)) ~B() { 168 } 169 }; 170 171 extern template class B<char>; 172 173 class C : B<char> { 174 }; 175 176 void 177 fn1() { 178 new C; 179 } 180