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