1 // RUN: %clang_cc1 -triple i386-unknown-unknown -std=c++11 %s -emit-llvm -o - | FileCheck %s
8 // CHECK-LABEL: define{{.*}} i32 @_ZN5Test11fEPNS_1AE
10 // CHECK: call noundef i32 @_ZN5Test11A1fEv
20 // CHECK-LABEL: define{{.*}} i32 @_ZN5Test21fEPNS_1AE
22 // CHECK: call noundef i32 @_ZN5Test21A1fEv
33 // CHECK-LABEL: define{{.*}} i32 @_ZN6Test2a1fEPNS_1AE
35 // CHECK: call noundef i32 @_ZN6Test2a1A1fEv
45 struct B final
: A
{ };
47 // CHECK-LABEL: define{{.*}} i32 @_ZN5Test31fEPNS_1BE
49 // CHECK: call noundef i32 @_ZN5Test31A1fEv
53 // CHECK-LABEL: define{{.*}} i32 @_ZN5Test31fERNS_1BE
55 // CHECK: call noundef i32 @_ZN5Test31A1fEv
59 // CHECK-LABEL: define{{.*}} i32 @_ZN5Test31fEPv
61 // CHECK: call noundef i32 @_ZN5Test31A1fEv
62 return static_cast<B
*>(v
)->f();
69 virtual int operator-();
74 virtual int operator-();
77 // CHECK-LABEL: define{{.*}} void @_ZN5Test41fEPNS_1BE
79 // CHECK: call void @_ZN5Test41B1fEv
80 static_cast<A
*>(d
)->f();
81 // CHECK: call noundef i32 @_ZN5Test41BngEv
89 virtual int operator-();
94 virtual int operator-();
100 // CHECK-LABEL: define{{.*}} void @_ZN5Test51fEPNS_1CE
102 // FIXME: It should be possible to devirtualize this case, but that is
103 // not implemented yet.
104 // CHECK: getelementptr
105 // CHECK-NEXT: %[[FUNC:.*]] = load
106 // CHECK-NEXT: call void %[[FUNC]]
107 static_cast<A
*>(d
)->f();
109 // CHECK-LABEL: define{{.*}} void @_ZN5Test53fopEPNS_1CE
111 // FIXME: It should be possible to devirtualize this case, but that is
112 // not implemented yet.
113 // CHECK: getelementptr
114 // CHECK-NEXT: %[[FUNC:.*]] = load
115 // CHECK-NEXT: call noundef i32 %[[FUNC]]
116 -static_cast<A
&>(*d
);
125 struct B
: public A
{
133 struct D final
: public C
, public B
{
136 // CHECK-LABEL: define{{.*}} void @_ZN5Test61fEPNS_1DE
138 // CHECK: call void @_ZN5Test61DD1Ev
139 static_cast<A
*>(d
)->~A();
149 virtual int f() { return 0; }
152 struct zed final
: public foo
, public bar
{
154 virtual int f() {return z
;}
157 // CHECK-LABEL: define{{.*}} i32 @_ZN5Test71fEPNS_3zedE
162 // CHECK-NEXT: call noundef i32 @_ZN5Test73zed1fEv
164 return static_cast<bar
*>(z
)->f();
169 struct A
{ virtual ~A() {} };
172 virtual int foo() { return b
; }
174 struct C final
: A
, B
{ };
175 // CHECK-LABEL: define{{.*}} i32 @_ZN5Test84testEPNS_1CE
177 // CHECK: %[[THIS:.*]] = phi
178 // CHECK-NEXT: call noundef i32 @_ZN5Test81B3fooEv(ptr {{[^,]*}} %[[THIS]])
179 return static_cast<B
*>(c
)->foo();
190 struct C
: public B
, public A
{
196 virtual A
*operator-() {
200 struct RC final
: public RA
{
207 virtual C
*operator-() {
214 // CHECK: define {{.*}} @_ZN5Test91fEPNS_2RCE
216 // FIXME: It should be possible to devirtualize this case, but that is
217 // not implemented yet.
219 // CHECK: [[VTABLE:%.+]] = load {{.+}}
220 // CHECK: [[VFN:%.+]] = getelementptr inbounds {{.+}} [[VTABLE]], i{{[0-9]+}} 0
221 // CHECK-NEXT: %[[FUNC:.*]] = load {{.+}} [[VFN]]
222 // CHECK-NEXT: = call {{.*}} %[[FUNC]]
223 return static_cast<RA
*>(x
)->f();
225 // CHECK: define {{.*}} @_ZN5Test93fopEPNS_2RCE
227 // FIXME: It should be possible to devirtualize this case, but that is
228 // not implemented yet.
230 // CHECK: [[VTABLE:%.+]] = load {{.+}}
231 // CHECK: [[VFN:%.+]] = getelementptr inbounds {{.+}} [[VTABLE]], i{{[0-9]+}} 1
232 // CHECK-NEXT: %[[FUNC:.*]] = load {{.+}} [[VFN]]
233 // CHECK-NEXT: = call {{.*}} %[[FUNC]]
234 return -static_cast<RA
&>(*x
);
247 // CHECK-LABEL: define{{.*}} i32 @_ZN6Test101fEPNS_1BE
249 // CHECK: call noundef i32 @_ZN6Test101B1fEv
250 return static_cast<A
*>(b
)->f();
254 namespace TestVBase
{
255 struct A
{ virtual void f(); };
256 struct B
: virtual A
{};
257 struct C
: virtual A
{ void f() override
; };
259 extern struct BC final
: B
, C
{} &bc
;
260 extern struct BCusingA final
: B
, C
{ using A::f
; } &bc_using_a
;
261 extern struct BCusingB final
: B
, C
{ using B::f
; } &bc_using_b
;
262 extern struct BCusingC final
: B
, C
{ using C::f
; } &bc_using_c
;
264 extern struct CB final
: C
, B
{} &cb
;
265 extern struct CBusingA final
: C
, B
{ using A::f
; } &cb_using_a
;
266 extern struct CBusingB final
: C
, B
{ using B::f
; } &cb_using_b
;
267 extern struct CBusingC final
: C
, B
{ using C::f
; } &cb_using_c
;
269 // CHECK-LABEL: @_ZN9TestVBase4testEv(
271 // FIXME: The 'using A' case can be devirtualized to call A's virtual
272 // adjustment thunk for C::f.
273 // FIXME: The 'using B' case can be devirtualized, but requires us to emit
274 // a derived-to-base or base-to-derived conversion as part of
277 // CHECK: call void @_ZN9TestVBase1C1fEv(
279 // CHECK: call void %
281 // CHECK: call void %
283 // CHECK: call void @_ZN9TestVBase1C1fEv(
286 // CHECK: call void @_ZN9TestVBase1C1fEv(
288 // CHECK: call void %
290 // CHECK: call void %
292 // CHECK: call void @_ZN9TestVBase1C1fEv(
298 // Check that the definitions of Derived's operators are emitted.
300 // CHECK-LABEL: define linkonce_odr void @_ZN6Test111SIiE4foo1Ev(
301 // CHECK: call void @_ZN6Test111SIiE7DerivedclEv(
302 // CHECK: call noundef zeroext i1 @_ZN6Test111SIiE7DerivedeqERKNS_4BaseE(
303 // CHECK: call noundef zeroext i1 @_ZN6Test111SIiE7DerivedntEv(
304 // CHECK: call noundef nonnull align 4 dereferenceable(4) ptr @_ZN6Test111SIiE7DerivedixEi(
305 // CHECK: define linkonce_odr void @_ZN6Test111SIiE7DerivedclEv(
306 // CHECK: define linkonce_odr noundef zeroext i1 @_ZN6Test111SIiE7DerivedeqERKNS_4BaseE(
307 // CHECK: define linkonce_odr noundef zeroext i1 @_ZN6Test111SIiE7DerivedntEv(
308 // CHECK: define linkonce_odr noundef nonnull align 4 dereferenceable(4) ptr @_ZN6Test111SIiE7DerivedixEi(
311 virtual void operator()() {}
312 virtual bool operator==(const Base
&other
) { return false; }
313 virtual bool operator!() { return false; }
314 virtual Base
&operator[](int i
) { return *this; }
319 class Derived final
: public Base
{
321 void operator()() override
{}
322 bool operator==(const Base
&other
) override
{ return true; }
323 bool operator!() override
{ return true; }
324 Base
&operator[](int i
) override
{ return *this; }
327 Derived
*ptr
= nullptr, *ptr2
= nullptr;
331 // These calls get devirtualized. Linkage fails if the definitions of
332 // the called functions are not emitted.
334 (void)(*ptr
== *ptr2
);
342 S
<int> *s
= new S
<int>;