xref: /minix3/external/bsd/llvm/dist/clang/test/CodeGenCXX/devirtualize-virtual-function-calls-final.cpp (revision f4a2713ac843a11c696ec80c0a5e3e5d80b4d338)
1*f4a2713aSLionel Sambuc // RUN: %clang_cc1 -triple i386-unknown-unknown -std=c++11 %s -emit-llvm -o - | FileCheck %s
2*f4a2713aSLionel Sambuc 
3*f4a2713aSLionel Sambuc namespace Test1 {
4*f4a2713aSLionel Sambuc   struct A {
5*f4a2713aSLionel Sambuc     virtual int f() final;
6*f4a2713aSLionel Sambuc   };
7*f4a2713aSLionel Sambuc 
8*f4a2713aSLionel Sambuc   // CHECK-LABEL: define i32 @_ZN5Test11fEPNS_1AE
9*f4a2713aSLionel Sambuc   int f(A *a) {
10*f4a2713aSLionel Sambuc     // CHECK: call i32 @_ZN5Test11A1fEv
11*f4a2713aSLionel Sambuc     return a->f();
12*f4a2713aSLionel Sambuc   }
13*f4a2713aSLionel Sambuc }
14*f4a2713aSLionel Sambuc 
15*f4a2713aSLionel Sambuc namespace Test2 {
16*f4a2713aSLionel Sambuc   struct A final {
17*f4a2713aSLionel Sambuc     virtual int f();
18*f4a2713aSLionel Sambuc   };
19*f4a2713aSLionel Sambuc 
20*f4a2713aSLionel Sambuc   // CHECK-LABEL: define i32 @_ZN5Test21fEPNS_1AE
21*f4a2713aSLionel Sambuc   int f(A *a) {
22*f4a2713aSLionel Sambuc     // CHECK: call i32 @_ZN5Test21A1fEv
23*f4a2713aSLionel Sambuc     return a->f();
24*f4a2713aSLionel Sambuc   }
25*f4a2713aSLionel Sambuc }
26*f4a2713aSLionel Sambuc 
27*f4a2713aSLionel Sambuc namespace Test3 {
28*f4a2713aSLionel Sambuc   struct A {
29*f4a2713aSLionel Sambuc     virtual int f();
30*f4a2713aSLionel Sambuc   };
31*f4a2713aSLionel Sambuc 
32*f4a2713aSLionel Sambuc   struct B final : A { };
33*f4a2713aSLionel Sambuc 
34*f4a2713aSLionel Sambuc   // CHECK-LABEL: define i32 @_ZN5Test31fEPNS_1BE
35*f4a2713aSLionel Sambuc   int f(B *b) {
36*f4a2713aSLionel Sambuc     // CHECK: call i32 @_ZN5Test31A1fEv
37*f4a2713aSLionel Sambuc     return b->f();
38*f4a2713aSLionel Sambuc   }
39*f4a2713aSLionel Sambuc 
40*f4a2713aSLionel Sambuc   // CHECK-LABEL: define i32 @_ZN5Test31fERNS_1BE
41*f4a2713aSLionel Sambuc   int f(B &b) {
42*f4a2713aSLionel Sambuc     // CHECK: call i32 @_ZN5Test31A1fEv
43*f4a2713aSLionel Sambuc     return b.f();
44*f4a2713aSLionel Sambuc   }
45*f4a2713aSLionel Sambuc 
46*f4a2713aSLionel Sambuc   // CHECK-LABEL: define i32 @_ZN5Test31fEPv
47*f4a2713aSLionel Sambuc   int f(void *v) {
48*f4a2713aSLionel Sambuc     // CHECK: call i32 @_ZN5Test31A1fEv
49*f4a2713aSLionel Sambuc     return static_cast<B*>(v)->f();
50*f4a2713aSLionel Sambuc   }
51*f4a2713aSLionel Sambuc }
52*f4a2713aSLionel Sambuc 
53*f4a2713aSLionel Sambuc namespace Test4 {
54*f4a2713aSLionel Sambuc   struct A {
55*f4a2713aSLionel Sambuc     virtual void f();
56*f4a2713aSLionel Sambuc   };
57*f4a2713aSLionel Sambuc 
58*f4a2713aSLionel Sambuc   struct B final : A {
59*f4a2713aSLionel Sambuc     virtual void f();
60*f4a2713aSLionel Sambuc   };
61*f4a2713aSLionel Sambuc 
62*f4a2713aSLionel Sambuc   // CHECK-LABEL: define void @_ZN5Test41fEPNS_1BE
63*f4a2713aSLionel Sambuc   void f(B* d) {
64*f4a2713aSLionel Sambuc     // CHECK: call void @_ZN5Test41B1fEv
65*f4a2713aSLionel Sambuc     static_cast<A*>(d)->f();
66*f4a2713aSLionel Sambuc   }
67*f4a2713aSLionel Sambuc }
68*f4a2713aSLionel Sambuc 
69*f4a2713aSLionel Sambuc namespace Test5 {
70*f4a2713aSLionel Sambuc   struct A {
71*f4a2713aSLionel Sambuc     virtual void f();
72*f4a2713aSLionel Sambuc   };
73*f4a2713aSLionel Sambuc 
74*f4a2713aSLionel Sambuc   struct B : A {
75*f4a2713aSLionel Sambuc     virtual void f();
76*f4a2713aSLionel Sambuc   };
77*f4a2713aSLionel Sambuc 
78*f4a2713aSLionel Sambuc   struct C final : B {
79*f4a2713aSLionel Sambuc   };
80*f4a2713aSLionel Sambuc 
81*f4a2713aSLionel Sambuc   // CHECK-LABEL: define void @_ZN5Test51fEPNS_1CE
82*f4a2713aSLionel Sambuc   void f(C* d) {
83*f4a2713aSLionel Sambuc     // FIXME: It should be possible to devirtualize this case, but that is
84*f4a2713aSLionel Sambuc     // not implemented yet.
85*f4a2713aSLionel Sambuc     // CHECK: getelementptr
86*f4a2713aSLionel Sambuc     // CHECK-NEXT: %[[FUNC:.*]] = load
87*f4a2713aSLionel Sambuc     // CHECK-NEXT: call void %[[FUNC]]
88*f4a2713aSLionel Sambuc     static_cast<A*>(d)->f();
89*f4a2713aSLionel Sambuc   }
90*f4a2713aSLionel Sambuc }
91*f4a2713aSLionel Sambuc 
92*f4a2713aSLionel Sambuc namespace Test6 {
93*f4a2713aSLionel Sambuc   struct A {
94*f4a2713aSLionel Sambuc     virtual ~A();
95*f4a2713aSLionel Sambuc   };
96*f4a2713aSLionel Sambuc 
97*f4a2713aSLionel Sambuc   struct B : public A {
98*f4a2713aSLionel Sambuc     virtual ~B();
99*f4a2713aSLionel Sambuc   };
100*f4a2713aSLionel Sambuc 
101*f4a2713aSLionel Sambuc   struct C {
102*f4a2713aSLionel Sambuc     virtual ~C();
103*f4a2713aSLionel Sambuc   };
104*f4a2713aSLionel Sambuc 
105*f4a2713aSLionel Sambuc   struct D final : public C, public B {
106*f4a2713aSLionel Sambuc   };
107*f4a2713aSLionel Sambuc 
108*f4a2713aSLionel Sambuc   // CHECK-LABEL: define void @_ZN5Test61fEPNS_1DE
109*f4a2713aSLionel Sambuc   void f(D* d) {
110*f4a2713aSLionel Sambuc     // CHECK: call void @_ZN5Test61DD1Ev
111*f4a2713aSLionel Sambuc     static_cast<A*>(d)->~A();
112*f4a2713aSLionel Sambuc   }
113*f4a2713aSLionel Sambuc }
114*f4a2713aSLionel Sambuc 
115*f4a2713aSLionel Sambuc namespace Test7 {
116*f4a2713aSLionel Sambuc   struct foo {
117*f4a2713aSLionel Sambuc     virtual void g() {}
118*f4a2713aSLionel Sambuc   };
119*f4a2713aSLionel Sambuc 
120*f4a2713aSLionel Sambuc   struct bar {
121*f4a2713aSLionel Sambuc     virtual int f() { return 0; }
122*f4a2713aSLionel Sambuc   };
123*f4a2713aSLionel Sambuc 
124*f4a2713aSLionel Sambuc   struct zed final : public foo, public bar {
125*f4a2713aSLionel Sambuc     int z;
126*f4a2713aSLionel Sambuc     virtual int f() {return z;}
127*f4a2713aSLionel Sambuc   };
128*f4a2713aSLionel Sambuc 
129*f4a2713aSLionel Sambuc   // CHECK-LABEL: define i32 @_ZN5Test71fEPNS_3zedE
130*f4a2713aSLionel Sambuc   int f(zed *z) {
131*f4a2713aSLionel Sambuc     // CHECK: alloca
132*f4a2713aSLionel Sambuc     // CHECK-NEXT: store
133*f4a2713aSLionel Sambuc     // CHECK-NEXT: load
134*f4a2713aSLionel Sambuc     // CHECK-NEXT: call i32 @_ZN5Test73zed1fEv
135*f4a2713aSLionel Sambuc     // CHECK-NEXT: ret
136*f4a2713aSLionel Sambuc     return static_cast<bar*>(z)->f();
137*f4a2713aSLionel Sambuc   }
138*f4a2713aSLionel Sambuc }
139*f4a2713aSLionel Sambuc 
140*f4a2713aSLionel Sambuc namespace Test8 {
141*f4a2713aSLionel Sambuc   struct A { virtual ~A() {} };
142*f4a2713aSLionel Sambuc   struct B {
143*f4a2713aSLionel Sambuc     int b;
144*f4a2713aSLionel Sambuc     virtual int foo() { return b; }
145*f4a2713aSLionel Sambuc   };
146*f4a2713aSLionel Sambuc   struct C final : A, B {  };
147*f4a2713aSLionel Sambuc   // CHECK-LABEL: define i32 @_ZN5Test84testEPNS_1CE
148*f4a2713aSLionel Sambuc   int test(C *c) {
149*f4a2713aSLionel Sambuc     // CHECK: %[[THIS:.*]] = phi
150*f4a2713aSLionel Sambuc     // CHECK-NEXT: call i32 @_ZN5Test81B3fooEv(%"struct.Test8::B"* %[[THIS]])
151*f4a2713aSLionel Sambuc     return static_cast<B*>(c)->foo();
152*f4a2713aSLionel Sambuc   }
153*f4a2713aSLionel Sambuc }
154*f4a2713aSLionel Sambuc 
155*f4a2713aSLionel Sambuc namespace Test9 {
156*f4a2713aSLionel Sambuc   struct A {
157*f4a2713aSLionel Sambuc     int a;
158*f4a2713aSLionel Sambuc   };
159*f4a2713aSLionel Sambuc   struct B {
160*f4a2713aSLionel Sambuc     int b;
161*f4a2713aSLionel Sambuc   };
162*f4a2713aSLionel Sambuc   struct C : public B, public A {
163*f4a2713aSLionel Sambuc   };
164*f4a2713aSLionel Sambuc   struct RA {
165*f4a2713aSLionel Sambuc     virtual A *f() {
166*f4a2713aSLionel Sambuc       return 0;
167*f4a2713aSLionel Sambuc     }
168*f4a2713aSLionel Sambuc   };
169*f4a2713aSLionel Sambuc   struct RC final : public RA {
170*f4a2713aSLionel Sambuc     virtual C *f() {
171*f4a2713aSLionel Sambuc       C *x = new C();
172*f4a2713aSLionel Sambuc       x->a = 1;
173*f4a2713aSLionel Sambuc       x->b = 2;
174*f4a2713aSLionel Sambuc       return x;
175*f4a2713aSLionel Sambuc     }
176*f4a2713aSLionel Sambuc   };
177*f4a2713aSLionel Sambuc   // CHECK: define {{.*}} @_ZN5Test91fEPNS_2RCE
178*f4a2713aSLionel Sambuc   A *f(RC *x) {
179*f4a2713aSLionel Sambuc     // FIXME: It should be possible to devirtualize this case, but that is
180*f4a2713aSLionel Sambuc     // not implemented yet.
181*f4a2713aSLionel Sambuc     // CHECK: getelementptr
182*f4a2713aSLionel Sambuc     // CHECK-NEXT: %[[FUNC:.*]] = load
183*f4a2713aSLionel Sambuc     // CHECK-NEXT: bitcast
184*f4a2713aSLionel Sambuc     // CHECK-NEXT: = call {{.*}} %[[FUNC]]
185*f4a2713aSLionel Sambuc     return static_cast<RA*>(x)->f();
186*f4a2713aSLionel Sambuc   }
187*f4a2713aSLionel Sambuc }
188