1 // RUN: %clang_cc1 -std=c++98 %s -triple armv7-none-eabi -emit-llvm -o - | FileCheck %s 2 // RUN: %clang_cc1 -std=c++11 %s -triple armv7-none-eabi -emit-llvm -o - | FileCheck %s 3 // RUN: %clang_cc1 -std=c++1z %s -triple armv7-none-eabi -emit-llvm -o - | FileCheck %s 4 5 struct A { 6 virtual void f(); 7 virtual void f_const() const; 8 virtual void g(); 9 10 A h(); 11 }; 12 13 A g(); 14 15 void f(A a, A *ap, A& ar) { 16 // This should not be a virtual function call. 17 18 // CHECK: call void @_ZN1A1fEv(%struct.A* %a) 19 a.f(); 20 21 // CHECK: call void % 22 ap->f(); 23 24 // CHECK: call void % 25 ar.f(); 26 27 // CHECK: call void @_ZN1A1fEv 28 A().f(); 29 30 // CHECK: call void @_ZN1A1fEv 31 g().f(); 32 33 // CHECK: call void @_ZN1A1fEv 34 a.h().f(); 35 36 // CHECK: call void @_ZNK1A7f_constEv 37 a.f_const(); 38 39 // CHECK: call void @_ZN1A1fEv 40 (a).f(); 41 } 42 43 struct D : A { virtual void g(); }; 44 struct XD { D d; }; 45 46 D gd(); 47 48 void fd(D d, XD xd, D *p) { 49 // CHECK: call void @_ZN1A1fEv(%struct.A* 50 d.f(); 51 52 // CHECK: call void @_ZN1D1gEv(%struct.D* 53 d.g(); 54 55 // CHECK: call void @_ZN1A1fEv 56 D().f(); 57 58 // CHECK: call void @_ZN1D1gEv 59 D().g(); 60 61 // CHECK: call void @_ZN1A1fEv 62 gd().f(); 63 64 // CHECK: call void @_ZNK1A7f_constEv 65 d.f_const(); 66 67 // CHECK: call void @_ZN1A1fEv 68 (d).f(); 69 70 // CHECK: call void @_ZN1A1fEv 71 (true, d).f(); 72 73 // CHECK: call void @_ZN1D1gEv 74 (true, d).g(); 75 76 // CHECK: call void @_ZN1A1fEv 77 xd.d.f(); 78 79 // CHECK: call void @_ZN1A1fEv 80 XD().d.f(); 81 82 // CHECK: call void @_ZN1A1fEv 83 D XD::*mp; 84 (xd.*mp).f(); 85 86 // CHECK: call void @_ZN1D1gEv 87 (xd.*mp).g(); 88 89 // Can't devirtualize this; we have no guarantee that p points to a D here, 90 // due to the "single object is considered to be an array of one element" 91 // rule. 92 // CHECK: call void % 93 p[0].f(); 94 95 // FIXME: We can devirtualize this, by C++1z [expr.add]/6 (if the array 96 // element type and the pointee type are not similar, behavior is undefined). 97 // CHECK: call void % 98 p[1].f(); 99 } 100 101 struct B { 102 virtual void f(); 103 ~B(); 104 105 B h(); 106 }; 107 108 109 void f() { 110 // CHECK: call void @_ZN1B1fEv 111 B().f(); 112 113 // CHECK: call void @_ZN1B1fEv 114 B().h().f(); 115 } 116 117 namespace test2 { 118 struct foo { 119 virtual void f(); 120 virtual ~foo(); 121 }; 122 123 struct bar : public foo { 124 virtual void f(); 125 virtual ~bar(); 126 }; 127 128 void f(bar *b) { 129 // CHECK: call void @_ZN5test23foo1fEv 130 // CHECK: call %"struct.test2::foo"* @_ZN5test23fooD1Ev 131 b->foo::f(); 132 b->foo::~foo(); 133 } 134 } 135 136 namespace test3 { 137 // Test that we don't crash in this case. 138 struct B { 139 }; 140 struct D : public B { 141 }; 142 void f(D d) { 143 // CHECK-LABEL: define void @_ZN5test31fENS_1DE 144 d.B::~B(); 145 } 146 } 147 148 namespace test4 { 149 struct Animal { 150 virtual void eat(); 151 }; 152 struct Fish : Animal { 153 virtual void eat(); 154 }; 155 struct Wrapper { 156 Fish fish; 157 }; 158 extern Wrapper *p; 159 void test() { 160 // CHECK: call void @_ZN5test44Fish3eatEv 161 p->fish.eat(); 162 } 163 } 164 165 // Do not devirtualize to pure virtual function calls. 166 namespace test5 { 167 struct X { 168 virtual void f() = 0; 169 }; 170 struct Y {}; 171 // CHECK-LABEL: define {{.*}} @_ZN5test51f 172 void f(Y &y, X Y::*p) { 173 // CHECK-NOT: call {{.*}} @_ZN5test51X1fEv 174 // CHECK: call void % 175 (y.*p).f(); 176 }; 177 178 struct Z final { 179 virtual void f() = 0; 180 }; 181 // CHECK-LABEL: define {{.*}} @_ZN5test51g 182 void g(Z &z) { 183 // CHECK-NOT: call {{.*}} @_ZN5test51Z1fEv 184 // CHECK: call void % 185 z.f(); 186 } 187 188 struct Q { 189 virtual void f() final = 0; 190 }; 191 // CHECK-LABEL: define {{.*}} @_ZN5test51h 192 void h(Q &q) { 193 // CHECK-NOT: call {{.*}} @_ZN5test51Q1fEv 194 // CHECK: call void % 195 q.f(); 196 } 197 } 198