1 // RUN: %clang_cc1 %s -triple x86_64-apple-darwin10 -emit-llvm -o %t.ll -O1 -disable-llvm-optzns -fms-extensions
2 // RUN: %clang_cc1 %s -triple i686-pc-win32 -emit-llvm -o %t.ms.ll -O1 -disable-llvm-optzns -fms-extensions
3 
4 // RUN: FileCheck --check-prefix=CHECK1 --input-file=%t.ll %s
5 // RUN: FileCheck --check-prefix=CHECK2 --input-file=%t.ll %s
6 // RUN: FileCheck --check-prefix=CHECK3 --input-file=%t.ll %s
7 // RUN: FileCheck --check-prefix=CHECK4 --input-file=%t.ll %s
8 // RUN: FileCheck --check-prefix=CHECK-MS --input-file=%t.ms.ll %s
9 // RUN: FileCheck --check-prefix=CHECK6 --input-file=%t.ll %s
10 // RUN: FileCheck --check-prefix=CHECK7 --input-file=%t.ll %s
11 // RUN: FileCheck --check-prefix=CHECK8 --input-file=%t.ll %s
12 // RUN: FileCheck --check-prefix=CHECK9 --input-file=%t.ll %s
13 namespace test1 {
14 
15 struct A {
16   A();
17   virtual void foo();
18 };
19 
20 struct B : A {
21   virtual void foo();
22 };
23 
24 void g(A *a) { a->foo(); }
25 
26 // CHECK1-LABEL: define void @_ZN5test14fooAEv()
27 // CHECK1: call void @_ZN5test11AC1Ev(%"struct.test1::A"*
28 // CHECK1: %[[VTABLE:.*]] = load i8**, i8*** %{{.*}}
29 // CHECK1: %[[CMP:.*]] = icmp eq i8** %[[VTABLE]], getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN5test11AE, i64 0, i64 2)
30 // CHECK1: call void @llvm.assume(i1 %[[CMP]])
31 // CHECK1-LABEL: }
32 
33 void fooA() {
34   A a;
35   g(&a);
36 }
37 
38 // CHECK1-LABEL: define void @_ZN5test14fooBEv()
39 // CHECK1: call void @_ZN5test11BC1Ev(%"struct.test1::B"* %{{.*}})
40 // CHECK1: %[[VTABLE:.*]] = load i8**, i8*** %{{.*}}
41 // CHECK1: %[[CMP:.*]] = icmp eq i8** %[[VTABLE]], getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN5test11BE, i64 0, i64 2)
42 // CHECK1: call void @llvm.assume(i1 %[[CMP]])
43 // CHECK1-LABEL: }
44 
45 void fooB() {
46   B b;
47   g(&b);
48 }
49 // there should not be any assumes in the ctor that calls base ctor
50 // CHECK1-LABEL: define linkonce_odr void @_ZN5test11BC2Ev(%"struct.test1::B"*
51 // CHECK1-NOT: @llvm.assume(
52 // CHECK1-LABEL: }
53 }
54 namespace test2 {
55 struct A {
56   A();
57   virtual void foo();
58 };
59 
60 struct B {
61   B();
62   virtual void bar();
63 };
64 
65 struct C : A, B {
66   C();
67   virtual void foo();
68 };
69 void g(A *a) { a->foo(); }
70 void h(B *b) { b->bar(); }
71 
72 // CHECK2-LABEL: define void @_ZN5test24testEv()
73 // CHECK2: call void @_ZN5test21CC1Ev(%"struct.test2::C"*
74 // CHECK2: %[[VTABLE:.*]] = load i8**, i8*** {{.*}}
75 // CHECK2: %[[CMP:.*]] = icmp eq i8** %[[VTABLE]], getelementptr inbounds ([6 x i8*], [6 x i8*]* @_ZTVN5test21CE, i64 0, i64 2)
76 // CHECK2: call void @llvm.assume(i1 %[[CMP]])
77 
78 // CHECK2: %[[V2:.*]] = bitcast %"struct.test2::C"* %{{.*}} to i8*
79 // CHECK2: %[[ADD_PTR:.*]] = getelementptr inbounds i8, i8* %[[V2]], i64 8
80 // CHECK2: %[[V3:.*]] = bitcast i8* %[[ADD_PTR]] to i8***
81 // CHECK2: %[[VTABLE2:.*]] = load i8**, i8*** %[[V3]]
82 // CHECK2: %[[CMP2:.*]] = icmp eq i8** %[[VTABLE2]], getelementptr inbounds ([6 x i8*], [6 x i8*]* @_ZTVN5test21CE, i64 0, i64 5)
83 // CHECK2: call void @llvm.assume(i1 %[[CMP2]])
84 
85 // CHECK2: call void @_ZN5test21gEPNS_1AE(
86 // CHECK2-LABEL: }
87 
88 void test() {
89   C c;
90   g(&c);
91   h(&c);
92 }
93 }
94 
95 namespace test3 {
96 struct A {
97   A();
98 };
99 
100 struct B : A {
101   B();
102   virtual void foo();
103 };
104 
105 struct C : virtual A, B {
106   C();
107   virtual void foo();
108 };
109 void g(B *a) { a->foo(); }
110 
111 // CHECK3-LABEL: define void @_ZN5test34testEv()
112 // CHECK3: call void @_ZN5test31CC1Ev(%"struct.test3::C"*
113 // CHECK3: %[[CMP:.*]] = icmp eq i8** %{{.*}}, getelementptr inbounds ([4 x i8*], [4 x i8*]* @_ZTVN5test31CE, i64 0, i64 3)
114 // CHECK3: call void @llvm.assume(i1 %[[CMP]])
115 // CHECK3-LABLEL: }
116 void test() {
117   C c;
118   g(&c);
119 }
120 } // test3
121 
122 namespace test4 {
123 struct A {
124   A();
125   virtual void foo();
126 };
127 
128 struct B : virtual A {
129   B();
130   virtual void foo();
131 };
132 struct C : B {
133   C();
134   virtual void foo();
135 };
136 
137 void g(C *c) { c->foo(); }
138 
139 // CHECK4-LABEL: define void @_ZN5test44testEv()
140 // CHECK4: call void @_ZN5test41CC1Ev(%"struct.test4::C"*
141 // CHECK4: %[[VTABLE:.*]] = load i8**, i8*** %{{.*}}
142 // CHECK4: %[[CMP:.*]] = icmp eq i8** %[[VTABLE]], getelementptr inbounds ([5 x i8*], [5 x i8*]* @_ZTVN5test41CE, i64 0, i64 4)
143 // CHECK4: call void @llvm.assume(i1 %[[CMP]]
144 
145 // CHECK4: %[[VTABLE2:.*]] = load i8**, i8*** %{{.*}}
146 // CHECK4: %[[CMP2:.*]] = icmp eq i8** %[[VTABLE2]], getelementptr inbounds ([5 x i8*], [5 x i8*]* @_ZTVN5test41CE, i64 0, i64 4)
147 // CHECK4: call void @llvm.assume(i1 %[[CMP2]])
148 // CHECK4-LABEL: }
149 
150 void test() {
151   C c;
152   g(&c);
153 }
154 } // test4
155 
156 namespace testMS {
157 
158 struct __declspec(novtable) S {
159   virtual void foo();
160 };
161 
162 void g(S &s) { s.foo(); }
163 
164 // if struct has novtable specifier, then we can't generate assumes
165 // CHECK-MS-LABEL: define void @"\01?test@testMS@@YAXXZ"()
166 // CHECK-MS: call x86_thiscallcc %"struct.testMS::S"* @"\01??0S@testMS@@QAE@XZ"(
167 // CHECK-MS-NOT: @llvm.assume
168 // CHECK-MS-LABEL: }
169 
170 void test() {
171   S s;
172   g(s);
173 }
174 
175 } // testMS
176 
177 namespace test6 {
178 struct A {
179   A();
180   virtual void foo();
181   virtual ~A() {}
182 };
183 struct B : A {
184   B();
185 };
186 // FIXME: Because A's vtable is external, and no virtual functions are hidden,
187 // it's safe to generate assumption loads.
188 // CHECK6-LABEL: define void @_ZN5test61gEv()
189 // CHECK6: call void @_ZN5test61AC1Ev(
190 // CHECK6-NOT: call void @llvm.assume(
191 
192 // We can't emit assumption loads for B, because if we would refer to vtable
193 // it would refer to functions that will not be able to find (like implicit
194 // inline destructor).
195 
196 // CHECK6-LABEL:   call void @_ZN5test61BC1Ev(
197 // CHECK6-NOT: call void @llvm.assume(
198 // CHECK6-LABEL: }
199 void g() {
200   A *a = new A;
201   B *b = new B;
202 }
203 }
204 
205 namespace test7 {
206 // Because A's key function is defined here, vtable is generated in this TU
207 // CHECK7: @_ZTVN5test71AE = unnamed_addr constant
208 struct A {
209   A();
210   virtual void foo();
211   virtual void bar();
212 };
213 void A::foo() {}
214 
215 // CHECK7-LABEL: define void @_ZN5test71gEv()
216 // CHECK7: call void @_ZN5test71AC1Ev(
217 // CHECK7: call void @llvm.assume(
218 // CHECK7-LABEL: }
219 void g() {
220   A *a = new A();
221   a->bar();
222 }
223 }
224 
225 namespace test8 {
226 
227 struct A {
228   virtual void foo();
229   virtual void bar();
230 };
231 
232 // CHECK8-DAG: @_ZTVN5test81BE = available_externally unnamed_addr constant
233 struct B : A {
234   B();
235   void foo();
236   void bar();
237 };
238 
239 // CHECK8-DAG: @_ZTVN5test81CE = linkonce_odr unnamed_addr constant
240 struct C : A {
241   C();
242   void bar();
243   void foo() {}
244 };
245 inline void C::bar() {}
246 
247 struct D : A {
248   D();
249   void foo();
250   void inline bar();
251 };
252 void D::bar() {}
253 
254 // CHECK8-DAG: @_ZTVN5test81EE = linkonce_odr unnamed_addr constant
255 struct E : A {
256   E();
257 };
258 
259 // CHECK8-LABEL: define void @_ZN5test81bEv()
260 // CHECK8: call void @llvm.assume(
261 // CHECK8-LABEL: }
262 void b() {
263   B b;
264   b.bar();
265 }
266 
267 // FIXME: C has inline virtual functions which prohibits as from generating
268 // assumption loads, but because vtable is generated in this TU (key function
269 // defined here) it would be correct to refer to it.
270 // CHECK8-LABEL: define void @_ZN5test81cEv()
271 // CHECK8-NOT: call void @llvm.assume(
272 // CHECK8-LABEL: }
273 void c() {
274   C c;
275   c.bar();
276 }
277 
278 // FIXME: We could generate assumption loads here.
279 // CHECK8-LABEL: define void @_ZN5test81dEv()
280 // CHECK8-NOT: call void @llvm.assume(
281 // CHECK8-LABEL: }
282 void d() {
283   D d;
284   d.bar();
285 }
286 
287 // CHECK8-LABEL: define void @_ZN5test81eEv()
288 // CHECK8: call void @llvm.assume(
289 // CHECK8-LABEL: }
290 void e() {
291   E e;
292   e.bar();
293 }
294 }
295 
296 namespace test9 {
297 
298 struct S {
299   S();
300   __attribute__((visibility("hidden"))) virtual void doStuff();
301 };
302 
303 // CHECK9-LABEL: define void @_ZN5test94testEv()
304 // CHECK9-NOT: @llvm.assume(
305 // CHECK9: }
306 void test() {
307   S *s = new S();
308   s->doStuff();
309   delete s;
310 }
311 }
312 
313