1 // RUN: %clang_cc1 -no-opaque-pointers -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(%"struct.Test8::B"* {{[^,]*}} %[[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.
220 // CHECK: [[F_PTR_RA:%.+]] = bitcast
221 // CHECK: [[VTABLE:%.+]] = load {{.+}} [[F_PTR_RA]]
222 // CHECK: [[VFN:%.+]] = getelementptr inbounds {{.+}} [[VTABLE]], i{{[0-9]+}} 0
223 // CHECK-NEXT: %[[FUNC:.*]] = load {{.+}} [[VFN]]
224 // CHECK-NEXT: = call {{.*}} %[[FUNC]]
225 return static_cast<RA
*>(x
)->f();
227 // CHECK: define {{.*}} @_ZN5Test93fopEPNS_2RCE
229 // FIXME: It should be possible to devirtualize this case, but that is
230 // not implemented yet.
233 // CHECK: [[F_PTR_RA:%.+]] = bitcast
234 // CHECK: [[VTABLE:%.+]] = load {{.+}} [[F_PTR_RA]]
235 // CHECK: [[VFN:%.+]] = getelementptr inbounds {{.+}} [[VTABLE]], i{{[0-9]+}} 1
236 // CHECK-NEXT: %[[FUNC:.*]] = load {{.+}} [[VFN]]
237 // CHECK-NEXT: = call {{.*}} %[[FUNC]]
238 return -static_cast<RA
&>(*x
);
251 // CHECK-LABEL: define{{.*}} i32 @_ZN6Test101fEPNS_1BE
253 // CHECK: call noundef i32 @_ZN6Test101B1fEv
254 return static_cast<A
*>(b
)->f();
258 namespace TestVBase
{
259 struct A
{ virtual void f(); };
260 struct B
: virtual A
{};
261 struct C
: virtual A
{ void f() override
; };
263 extern struct BC final
: B
, C
{} &bc
;
264 extern struct BCusingA final
: B
, C
{ using A::f
; } &bc_using_a
;
265 extern struct BCusingB final
: B
, C
{ using B::f
; } &bc_using_b
;
266 extern struct BCusingC final
: B
, C
{ using C::f
; } &bc_using_c
;
268 extern struct CB final
: C
, B
{} &cb
;
269 extern struct CBusingA final
: C
, B
{ using A::f
; } &cb_using_a
;
270 extern struct CBusingB final
: C
, B
{ using B::f
; } &cb_using_b
;
271 extern struct CBusingC final
: C
, B
{ using C::f
; } &cb_using_c
;
273 // CHECK-LABEL: @_ZN9TestVBase4testEv(
275 // FIXME: The 'using A' case can be devirtualized to call A's virtual
276 // adjustment thunk for C::f.
277 // FIXME: The 'using B' case can be devirtualized, but requires us to emit
278 // a derived-to-base or base-to-derived conversion as part of
281 // CHECK: call void @_ZN9TestVBase1C1fEv(
283 // CHECK: call void %
285 // CHECK: call void %
287 // CHECK: call void @_ZN9TestVBase1C1fEv(
290 // CHECK: call void @_ZN9TestVBase1C1fEv(
292 // CHECK: call void %
294 // CHECK: call void %
296 // CHECK: call void @_ZN9TestVBase1C1fEv(
302 // Check that the definitions of Derived's operators are emitted.
304 // CHECK-LABEL: define linkonce_odr void @_ZN6Test111SIiE4foo1Ev(
305 // CHECK: call void @_ZN6Test111SIiE7DerivedclEv(
306 // CHECK: call noundef zeroext i1 @_ZN6Test111SIiE7DerivedeqERKNS_4BaseE(
307 // CHECK: call noundef zeroext i1 @_ZN6Test111SIiE7DerivedntEv(
308 // CHECK: call noundef nonnull align 4 dereferenceable(4) %"class.Test11::Base"* @_ZN6Test111SIiE7DerivedixEi(
309 // CHECK: define linkonce_odr void @_ZN6Test111SIiE7DerivedclEv(
310 // CHECK: define linkonce_odr noundef zeroext i1 @_ZN6Test111SIiE7DerivedeqERKNS_4BaseE(
311 // CHECK: define linkonce_odr noundef zeroext i1 @_ZN6Test111SIiE7DerivedntEv(
312 // CHECK: define linkonce_odr noundef nonnull align 4 dereferenceable(4) %"class.Test11::Base"* @_ZN6Test111SIiE7DerivedixEi(
315 virtual void operator()() {}
316 virtual bool operator==(const Base
&other
) { return false; }
317 virtual bool operator!() { return false; }
318 virtual Base
&operator[](int i
) { return *this; }
323 class Derived final
: public Base
{
325 void operator()() override
{}
326 bool operator==(const Base
&other
) override
{ return true; }
327 bool operator!() override
{ return true; }
328 Base
&operator[](int i
) override
{ return *this; }
331 Derived
*ptr
= nullptr, *ptr2
= nullptr;
335 // These calls get devirtualized. Linkage fails if the definitions of
336 // the called functions are not emitted.
338 (void)(*ptr
== *ptr2
);
346 S
<int> *s
= new S
<int>;