]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - test/CodeGenCXX/ctor-dtor-alias.cpp
Vendor import of clang release_34 branch r197841 (effectively, 3.4 RC3):
[FreeBSD/FreeBSD.git] / test / CodeGenCXX / ctor-dtor-alias.cpp
1 // RUN: %clang_cc1 %s -triple x86_64-linux -emit-llvm -o - -mconstructor-aliases -O1 -disable-llvm-optzns | FileCheck %s
2 // RUN: %clang_cc1 %s -triple x86_64-linux -emit-llvm -o - -mconstructor-aliases | FileCheck --check-prefix=NOOPT %s
3
4 // RUN: %clang_cc1 -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   // NOOOPT-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 // CHECK-RAUW: @_ZTV1C = linkonce_odr unnamed_addr constant [4 x i8*] [{{[^@]*}}@_ZTI1C {{[^@]*}}@_ZN1CD2Ev {{[^@]*}}@_ZN1CD0Ev {{[^@]*}}]
137 // r194296 replaced C::~C with B::~B without emitting the later.
138
139 class A {
140 public:
141   A(int);
142   virtual ~A();
143 };
144
145 template <class>
146 class B : A {
147 public:
148   B()
149       : A(0) {
150   }
151   __attribute__((always_inline)) ~B() {
152   }
153 };
154
155 extern template class B<char>;
156
157 class C : B<char> {
158 };
159
160 void
161 fn1() {
162   new C;
163 }