xref: /aosp_15_r20/external/clang/test/CodeGenCXX/devirtualize-virtual-function-calls.cpp (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li // RUN: %clang_cc1 %s -triple armv7-none-eabi -emit-llvm -o - | FileCheck %s
2*67e74705SXin Li 
3*67e74705SXin Li struct A {
4*67e74705SXin Li   virtual void f();
5*67e74705SXin Li   virtual void f_const() const;
6*67e74705SXin Li 
7*67e74705SXin Li   A h();
8*67e74705SXin Li };
9*67e74705SXin Li 
10*67e74705SXin Li A g();
11*67e74705SXin Li 
f(A a,A * ap,A & ar)12*67e74705SXin Li void f(A a, A *ap, A& ar) {
13*67e74705SXin Li   // This should not be a virtual function call.
14*67e74705SXin Li 
15*67e74705SXin Li   // CHECK: call void @_ZN1A1fEv(%struct.A* %a)
16*67e74705SXin Li   a.f();
17*67e74705SXin Li 
18*67e74705SXin Li   // CHECK: call void %
19*67e74705SXin Li   ap->f();
20*67e74705SXin Li 
21*67e74705SXin Li   // CHECK: call void %
22*67e74705SXin Li   ar.f();
23*67e74705SXin Li 
24*67e74705SXin Li   // CHECK: call void @_ZN1A1fEv
25*67e74705SXin Li   A().f();
26*67e74705SXin Li 
27*67e74705SXin Li   // CHECK: call void @_ZN1A1fEv
28*67e74705SXin Li   g().f();
29*67e74705SXin Li 
30*67e74705SXin Li   // CHECK: call void @_ZN1A1fEv
31*67e74705SXin Li   a.h().f();
32*67e74705SXin Li 
33*67e74705SXin Li   // CHECK: call void @_ZNK1A7f_constEv
34*67e74705SXin Li   a.f_const();
35*67e74705SXin Li 
36*67e74705SXin Li   // CHECK: call void @_ZN1A1fEv
37*67e74705SXin Li   (a).f();
38*67e74705SXin Li }
39*67e74705SXin Li 
40*67e74705SXin Li struct B {
41*67e74705SXin Li   virtual void f();
42*67e74705SXin Li   ~B();
43*67e74705SXin Li 
44*67e74705SXin Li   B h();
45*67e74705SXin Li };
46*67e74705SXin Li 
47*67e74705SXin Li 
f()48*67e74705SXin Li void f() {
49*67e74705SXin Li   // CHECK: call void @_ZN1B1fEv
50*67e74705SXin Li   B().f();
51*67e74705SXin Li 
52*67e74705SXin Li   // CHECK: call void @_ZN1B1fEv
53*67e74705SXin Li   B().h().f();
54*67e74705SXin Li }
55*67e74705SXin Li 
56*67e74705SXin Li namespace test2 {
57*67e74705SXin Li   struct foo {
58*67e74705SXin Li     virtual void f();
59*67e74705SXin Li     virtual ~foo();
60*67e74705SXin Li   };
61*67e74705SXin Li 
62*67e74705SXin Li   struct bar : public foo {
63*67e74705SXin Li     virtual void f();
64*67e74705SXin Li     virtual ~bar();
65*67e74705SXin Li   };
66*67e74705SXin Li 
f(bar * b)67*67e74705SXin Li   void f(bar *b) {
68*67e74705SXin Li     // CHECK: call void @_ZN5test23foo1fEv
69*67e74705SXin Li     // CHECK: call %"struct.test2::foo"* @_ZN5test23fooD1Ev
70*67e74705SXin Li     b->foo::f();
71*67e74705SXin Li     b->foo::~foo();
72*67e74705SXin Li   }
73*67e74705SXin Li }
74*67e74705SXin Li 
75*67e74705SXin Li namespace test3 {
76*67e74705SXin Li   // Test that we don't crash in this case.
77*67e74705SXin Li   struct B {
78*67e74705SXin Li   };
79*67e74705SXin Li   struct D : public B {
80*67e74705SXin Li   };
f(D d)81*67e74705SXin Li   void f(D d) {
82*67e74705SXin Li     // CHECK-LABEL: define void @_ZN5test31fENS_1DE
83*67e74705SXin Li     d.B::~B();
84*67e74705SXin Li   }
85*67e74705SXin Li }
86*67e74705SXin Li 
87*67e74705SXin Li namespace test4 {
88*67e74705SXin Li   struct Animal {
89*67e74705SXin Li     virtual void eat();
90*67e74705SXin Li   };
91*67e74705SXin Li   struct Fish : Animal {
92*67e74705SXin Li     virtual void eat();
93*67e74705SXin Li   };
94*67e74705SXin Li   struct Wrapper {
95*67e74705SXin Li     Fish fish;
96*67e74705SXin Li   };
97*67e74705SXin Li   extern Wrapper *p;
test()98*67e74705SXin Li   void test() {
99*67e74705SXin Li     // CHECK: call void @_ZN5test44Fish3eatEv
100*67e74705SXin Li     p->fish.eat();
101*67e74705SXin Li   }
102*67e74705SXin Li }
103