xref: /llvm-project/clang/test/CodeGenCXX/vtable-available-externally.cpp (revision 6bb63002fca8a7cfa9ff8ffd86da4c2ca3d98a3b)
1 // RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -std=c++98 -emit-llvm -o %t
2 // RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -std=c++98 -O2 -disable-llvm-passes -emit-llvm -o %t.opt
3 // RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -std=c++98 -O2 -disable-llvm-passes -emit-llvm -o %t.vtable -fforce-emit-vtables -fstrict-vtable-pointers -mconstructor-aliases
4 // RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK-TEST1 %s < %t
5 // RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK-TEST2 %s < %t
6 // RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK-TEST5 %s < %t
7 // RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK-TEST8 %s < %t.opt
8 // RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK-TEST9 %s < %t.opt
9 // RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK-TEST10 %s < %t.opt
10 // RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK-TEST11 %s < %t.opt
11 // RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK-TEST12 %s < %t.opt
12 // RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK-TEST13 %s < %t.opt
13 // RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK-TEST14 %s < %t.opt
14 // RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK-TEST15 %s < %t.opt
15 // RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK-TEST16 %s < %t.opt
16 // RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK-TEST17 %s < %t.opt
17 // RUN: FileCheck -allow-deprecated-dag-overlap --check-prefix=CHECK-FORCE-EMIT %s < %t.vtable
18 
19 
20 #include <typeinfo>
21 
22 // CHECK-TEST1: @_ZTVN5Test11AE = external unnamed_addr constant
23 // CHECK-FORCE-EMIT-DAG: @_ZTVN5Test11AE = available_externally unnamed_addr constant
24 namespace Test1 {
25 
26 struct A {
27   A();
28   virtual void f();
29   virtual ~A() { }
30 };
31 
32 A::A() { }
33 
34 void f(A* a) {
35   a->f();
36 };
37 
38 // CHECK-LABEL: define{{.*}} void @_ZN5Test11gEv
39 // CHECK: call void @_ZN5Test11A1fEv
40 void g() {
41   A a;
42   f(&a);
43 }
44 
45 }
46 
47 // Test2::A's key function (f) is defined in this translation unit, but when
48 // we're doing codegen for the typeid(A) call, we don't know that yet.
49 // This tests mainly that the typeinfo and typename constants have their linkage
50 // updated correctly.
51 
52 // CHECK-TEST2: @_ZTIN5Test21AE ={{.*}} constant
53 // CHECK-TEST2: @_ZTSN5Test21AE ={{.*}} constant
54 // CHECK-TEST2: @_ZTVN5Test21AE ={{.*}} unnamed_addr constant
55 namespace Test2 {
56   struct A {
57     virtual void f();
58   };
59 
60   const std::type_info &g() {
61     return typeid(A);
62   };
63 
64   void A::f() { }
65 }
66 
67 // Test that we don't assert on this test.
68 namespace Test3 {
69 
70 struct A {
71   virtual void f();
72   virtual ~A() { }
73 };
74 
75 struct B : A {
76   B();
77   virtual void f();
78 };
79 
80 B::B() { }
81 
82 void g(A* a) {
83   a->f();
84 };
85 
86 }
87 
88 // PR9114, test that we don't try to instantiate RefPtr<Node>.
89 namespace Test4 {
90 
91 template <class T> struct RefPtr {
92   T* p;
93   ~RefPtr() {
94     p->deref();
95   }
96 };
97 
98 struct A {
99   virtual ~A();
100 };
101 
102 struct Node;
103 
104 struct B : A {
105   virtual void deref();
106   RefPtr<Node> m;
107 };
108 
109 void f() {
110   RefPtr<B> b;
111 }
112 
113 }
114 
115 // PR9130, test that we emit a definition of A::f.
116 // CHECK-TEST5-LABEL: define linkonce_odr void @_ZN5Test51A1fEv
117 namespace Test5 {
118 
119 struct A {
120   virtual void f() { }
121 };
122 
123 struct B : A {
124   virtual ~B();
125 };
126 
127 B::~B() { }
128 
129 }
130 
131 // Check that we don't assert on this test.
132 namespace Test6 {
133 
134 struct A {
135   virtual ~A();
136   int a;
137 };
138 
139 struct B {
140   virtual ~B();
141   int b;
142 };
143 
144 struct C : A, B {
145   C();
146 };
147 
148 struct D : C {
149   virtual void f();
150   D();
151 };
152 
153 D::D() { }
154 
155 }
156 
157 namespace Test7 {
158 
159 struct c1 {};
160 struct c10 : c1{
161   virtual void foo ();
162 };
163 struct c11 : c10, c1{
164   virtual void f6 ();
165 };
166 struct c28 : virtual c11{
167   void f6 ();
168 };
169 }
170 
171 namespace Test8 {
172 // CHECK-TEST8: @_ZTVN5Test81YE = available_externally unnamed_addr constant
173 // vtable for X is not generated because there are no stores here
174 struct X {
175   X();
176   virtual void foo();
177 };
178 struct Y : X {
179   void foo();
180 };
181 
182 void g(X* p) { p->foo(); }
183 void f() {
184   Y y;
185   g(&y);
186   X x;
187   g(&x);
188 }
189 
190 }  // Test8
191 
192 namespace Test9 {
193 // All virtual functions are outline, so we can assume that it will
194 // be generated in translation unit where foo is defined.
195 // CHECK-TEST9-DAG: @_ZTVN5Test91AE = available_externally unnamed_addr constant
196 // CHECK-TEST9-DAG: @_ZTVN5Test91BE = available_externally unnamed_addr constant
197 struct A {
198   virtual void foo();
199   virtual void bar();
200 };
201 void A::bar() {}
202 
203 struct B : A {
204   void foo();
205 };
206 
207 void g() {
208   A a;
209   a.foo();
210   B b;
211   b.foo();
212 }
213 
214 }  // Test9
215 
216 namespace Test10 {
217 
218 // because A's key function is defined here, vtable is generated in this TU
219 // CHECK-TEST10-DAG: @_ZTVN6Test101AE ={{.*}} unnamed_addr constant
220 // CHECK-FORCE-EMIT-DAG: @_ZTVN6Test101AE ={{.*}} unnamed_addr constant
221 struct A {
222   virtual void foo();
223   virtual void bar();
224 };
225 void A::foo() {}
226 
227 // Because key function is inline we will generate vtable as linkonce_odr.
228 // CHECK-TEST10-DAG: @_ZTVN6Test101DE = linkonce_odr unnamed_addr constant
229 // CHECK-FORCE-EMIT-DAG: @_ZTVN6Test101DE = linkonce_odr unnamed_addr constant
230 struct D : A {
231   void bar();
232 };
233 inline void D::bar() {}
234 
235 // Because B has outline all virtual functions, we can refer to them.
236 // CHECK-TEST10-DAG: @_ZTVN6Test101BE = available_externally unnamed_addr constant
237 struct B : A {
238   void foo();
239   void bar();
240 };
241 
242 // C's key function (car) is outline, but C has inline virtual function so we
243 // can't guarantee that we will be able to refer to bar from name
244 // so (at the moment) we can't emit vtable available_externally.
245 // CHECK-TEST10-DAG: @_ZTVN6Test101CE = external unnamed_addr constant
246 // CHECK-FORCE-EMIT-DAG: @_ZTVN6Test101CE = available_externally unnamed_addr constant
247 struct C : A {
248   void bar() {}               // defined in body - not key function
249   virtual inline void gar();  // inline in body - not key function
250   virtual void car();
251 };
252 
253 // Inline definition outside body, so we can't emit vtable available_externally
254 // (see previous).
255 // CHECK-TEST10-DAG: @_ZTVN6Test101FE = external unnamed_addr constant
256 struct F : A {
257   void foo();
258   virtual void cat();         // inline outside body
259 };
260 inline void F::cat() {}
261 
262 // no key function, vtable will be generated everywhere it will be used
263 // CHECK-TEST10-DAG: @_ZTVN6Test101EE = linkonce_odr unnamed_addr constant
264 // CHECK-FORCE-EMIT-DAG: @_ZTVN6Test101EE = linkonce_odr unnamed_addr constant
265 
266 struct E : A {};
267 
268 void h(A& a) {
269   a.foo();
270   a.bar();
271 }
272 
273 void g() {
274   A a;
275   h(a);
276   B b;
277   h(b);
278   C c;
279   h(c);
280   D d;
281   h(d);
282   E e;
283   h(e);
284   F f;
285   h(f);
286 }
287 
288 }  // Test10
289 
290 namespace Test11 {
291 struct D;
292 // Can emit C's vtable available_externally.
293 // CHECK-TEST11: @_ZTVN6Test111CE = available_externally unnamed_addr constant
294 struct C {
295   virtual D& operator=(const D&);
296 };
297 
298 // Can emit D's vtable available_externally.
299 // CHECK-TEST11: @_ZTVN6Test111DE = available_externally unnamed_addr constant
300 struct D : C {
301   virtual void key();
302 };
303 D f();
304 
305 void g(D& a) {
306   C c;
307   c = a;
308   a.key();
309   a.key();
310 }
311 void g() {
312   D d;
313   d = f();
314   g(d);
315 }
316 }  // Test 11
317 
318 namespace Test12 {
319 
320 // CHECK-TEST12: @_ZTVN6Test121AE = external unnamed_addr constant
321 // CHECK-FORCE-EMIT-DAG: @_ZTVN6Test121AE = available_externally unnamed_addr constant
322 struct A {
323   virtual void foo();
324   virtual ~A() {}
325 };
326 // CHECK-TEST12: @_ZTVN6Test121BE = external unnamed_addr constant
327 // CHECK-FORCE-EMIT-DAG: @_ZTVN6Test121BE = available_externally unnamed_addr constant
328 struct B : A {
329   void foo();
330 };
331 
332 void g() {
333   A a;
334   a.foo();
335   B b;
336   b.foo();
337 }
338 }
339 
340 namespace Test13 {
341 
342 // CHECK-TEST13-DAG: @_ZTVN6Test131AE = available_externally unnamed_addr constant
343 // CHECK-TEST13-DAG: @_ZTVN6Test131BE = external unnamed_addr constant
344 // CHECK-FORCE-EMIT-DAG: @_ZTVN6Test131AE = available_externally unnamed_addr constant
345 // CHECK-FORCE-EMIT-DAG: @_ZTVN6Test131BE = available_externally unnamed_addr constant
346 
347 struct A {
348   virtual ~A();
349 };
350 struct B : A {
351   virtual void f();
352   void operator delete(void *);
353   ~B() {}
354 };
355 
356 void g() {
357   A *b = new B;
358 }
359 }
360 
361 namespace Test14 {
362 
363 // CHECK-TEST14: @_ZTVN6Test141AE = available_externally unnamed_addr constant
364 struct A {
365   virtual void f();
366   void operator delete(void *);
367   ~A();
368 };
369 
370 void g() {
371   A *b = new A;
372   delete b;
373 }
374 }
375 
376 namespace Test15 {
377 // In this test D's vtable has two slots for function f(), but uses only one,
378 // so the second slot is set to null.
379 // CHECK-TEST15: @_ZTVN6Test151DE = available_externally unnamed_addr constant
380 struct A { virtual void f() {} };
381 struct B : virtual A {};
382 struct C : virtual A {};
383 struct D : B, C {
384   virtual void g();
385   void f();
386 };
387 
388 void test() {
389   D * d = new D;
390   d->f();
391 }
392 }
393 
394 namespace Test16 {
395 // S has virtual method that is hidden, because of it we can't
396 // generate available_externally vtable for it.
397 // CHECK-TEST16-DAG: @_ZTVN6Test161SE = external unnamed_addr constant
398 // CHECK-TEST16-DAG: @_ZTVN6Test162S2E = available_externally
399 // CHECK-FORCE-EMIT-DAG: @_ZTVN6Test161SE = external unnamed_addr constant
400 // CHECK-FORCE-EMIT-DAG: @_ZTVN6Test162S2E = available_externally
401 
402 struct S {
403   __attribute__((visibility("hidden"))) virtual void doStuff();
404 };
405 
406 struct S2 {
407   virtual void doStuff();
408   __attribute__((visibility("hidden"))) void unused();
409 
410 };
411 
412 void test() {
413   S *s = new S;
414   s->doStuff();
415 
416   S2 *s2 = new S2;
417   s2->doStuff();
418 }
419 }
420 
421 namespace Test17 {
422 // This test checks if we emit vtables opportunistically.
423 // CHECK-TEST17-DAG: @_ZTVN6Test171AE = available_externally
424 // CHECK-TEST17-DAG: @_ZTVN6Test171BE = external
425 // CHECK-FORCE-EMIT-DAG: @_ZTVN6Test171AE = available_externally
426 // CHECK-FORCE-EMIT-DAG: @_ZTVN6Test171BE = available_externally
427 // CHECK-FORCE-EMIT-DAG: define linkonce_odr void @_ZN6Test171BD2Ev(
428 // CHECK-FORCE-EMIT-DAG: define linkonce_odr void @_ZN6Test171BD0Ev(
429 
430 struct A {
431   virtual void key();
432   virtual void bar() {}
433 };
434 
435 // We won't gonna use deleting destructor for this type, which will disallow
436 // emitting vtable as available_externally
437 struct B {
438   virtual void key();
439   virtual ~B() {}
440 };
441 
442 void testcaseA() {
443   A a;
444   a.bar(); // this forces to emit definition of bar
445 }
446 
447 void testcaseB() {
448   B b; // This only forces emitting of complete object destructor
449 }
450 
451 } // namespace Test17
452 
453 namespace Test18 {
454 // Here vtable will be only emitted because it is referenced by assume-load
455 // after the Derived construction.
456 // CHECK-FORCE-EMIT-DAG: @_ZTVN6Test187DerivedE = linkonce_odr unnamed_addr constant {{.*}} @_ZTIN6Test187DerivedE, {{.*}} @_ZN6Test184Base3funEv, {{.*}} @_ZN6Test184BaseD2Ev, {{.*}} @_ZN6Test187DerivedD0Ev
457 // CHECK-FORCE-EMIT-DAG: define linkonce_odr void @_ZN6Test187DerivedD0Ev
458 // CHECK-FORCE-EMIT-DAG: define linkonce_odr void @_ZN6Test184BaseD2Ev
459 // CHECK-FORCE-EMIT-DAG: define linkonce_odr noundef i32 @_ZN6Test184Base3funEv
460 // CHECK-FORCE-EMIT-DAG: @_ZTIN6Test187DerivedE = linkonce_odr constant
461 
462 struct Base {
463   virtual int fun() { return 42; }
464   virtual ~Base() { }
465 };
466 
467 struct Derived : Base {
468   Derived();
469 };
470 
471 int foo() {
472   Derived *der = new Derived();
473   return der->fun();
474 }
475 }
476 
477 namespace TestTemplates {
478 
479 // CHECK-FORCE-EMIT-DAG: @_ZTVN13TestTemplates8TemplateIiEE = linkonce_odr unnamed_addr constant {{.*}} @_ZTIN13TestTemplates8TemplateIiEE, {{.*}} @_ZN13TestTemplates8TemplateIiE3fooEi, {{.*}}@_ZN13TestTemplates8TemplateIiE22thisShouldBeEmittedTooEi, {{.*}}@_ZN13TestTemplates8TemplateIiED1Ev, {{.*}}@_ZN13TestTemplates8TemplateIiED0Ev
480 // CHECK-FORCE-EMIT-DAG: define linkonce_odr noundef i32 @_ZN13TestTemplates8TemplateIiE22thisShouldBeEmittedTooEi
481 
482 template<class T>
483 struct Template {
484   Template();
485   virtual T foo(T val);
486   // CHECK-FORCE-EMIT-DAG: define linkonce_odr noundef i32 @_ZN13TestTemplates8TemplateIiE22thisShouldBeEmittedTooEi
487   virtual T thisShouldBeEmittedToo(T val) { return val; }
488   virtual ~Template();
489 };
490 
491 
492 struct NonTemplate {
493   typedef int T;
494   NonTemplate();
495   virtual T foo(T val);
496   // CHECK-FORCE-EMIT-DAG: define linkonce_odr noundef i32 @_ZN13TestTemplates11NonTemplate22thisShouldBeEmittedTooEi
497   virtual T thisShouldBeEmittedToo(T val) { return val; }
498   virtual ~NonTemplate();
499 };
500 
501 // CHECK-FORCE-EMIT-DAG: @_ZTVN13TestTemplates16OuterNonTemplate27NestedTemplateInNonTemplateIiEE = linkonce_odr {{.*}} @_ZTIN13TestTemplates16OuterNonTemplate27NestedTemplateInNonTemplateIiEE, {{.*}} @_ZN13TestTemplates16OuterNonTemplate27NestedTemplateInNonTemplateIiE3fooEi, {{.*}} @_ZN13TestTemplates16OuterNonTemplate27NestedTemplateInNonTemplateIiE22thisShouldBeEmittedTooEi, {{.*}} @_ZN13TestTemplates16OuterNonTemplate27NestedTemplateInNonTemplateIiED1Ev, {{.*}} @_ZN13TestTemplates16OuterNonTemplate27NestedTemplateInNonTemplateIiED0Ev
502 
503 struct OuterNonTemplate {
504   template<class T>
505   struct NestedTemplateInNonTemplate {
506     NestedTemplateInNonTemplate();
507     virtual T foo(T val);
508     // CHECK-FORCE-EMIT-DAG: define linkonce_odr noundef i32 @_ZN13TestTemplates16OuterNonTemplate27NestedTemplateInNonTemplateIiE22thisShouldBeEmittedTooEi
509     virtual T thisShouldBeEmittedToo(T val) { return val; }
510     virtual ~NestedTemplateInNonTemplate();
511   };
512 
513   struct NestedNonTemplateInNonTemplate {
514     typedef int T;
515     NestedNonTemplateInNonTemplate();
516     virtual T foo(T val);
517     // CHECK-FORCE-EMIT-DAG: define linkonce_odr noundef i32 @_ZN13TestTemplates16OuterNonTemplate30NestedNonTemplateInNonTemplate22thisShouldBeEmittedTooEi
518     virtual T thisShouldBeEmittedToo(T val) { return val; }
519     virtual ~NestedNonTemplateInNonTemplate();
520   };
521 };
522 
523 template<class>
524 struct OuterTemplate {
525   template<class T>
526   struct NestedTemplateInTemplate {
527     NestedTemplateInTemplate();
528     virtual T foo(T val);
529     // CHECK-FORCE-EMIT-DAG: define linkonce_odr noundef i32 @_ZN13TestTemplates13OuterTemplateIlE24NestedTemplateInTemplateIiE22thisShouldBeEmittedTooEi
530     virtual T thisShouldBeEmittedToo(T val) { return val; }
531     virtual ~NestedTemplateInTemplate();
532   };
533 
534   struct NestedNonTemplateInTemplate {
535     typedef int T;
536     NestedNonTemplateInTemplate();
537     virtual T foo(T val);
538     // CHECK-FORCE-EMIT-DAG: define linkonce_odr noundef i32 @_ZN13TestTemplates13OuterTemplateIlE27NestedNonTemplateInTemplate22thisShouldBeEmittedTooEi
539     virtual T thisShouldBeEmittedToo(T val) { return val; }
540     virtual ~NestedNonTemplateInTemplate();
541   };
542 };
543 
544 template<class T>
545 int use() {
546   T *ptr = new T();
547   return ptr->foo(42);
548 }
549 
550 void test() {
551   use<Template<int> >();
552   use<OuterTemplate<long>::NestedTemplateInTemplate<int> >();
553   use<OuterNonTemplate::NestedTemplateInNonTemplate<int> >();
554 
555   use<NonTemplate>();
556   use<OuterTemplate<long>::NestedNonTemplateInTemplate>();
557   use<OuterNonTemplate::NestedNonTemplateInNonTemplate>();
558 }
559 }
560