aboutsummaryrefslogtreecommitdiff
path: root/test/CodeGenCXX/devirtualize-virtual-function-calls-final.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'test/CodeGenCXX/devirtualize-virtual-function-calls-final.cpp')
-rw-r--r--test/CodeGenCXX/devirtualize-virtual-function-calls-final.cpp46
1 files changed, 43 insertions, 3 deletions
diff --git a/test/CodeGenCXX/devirtualize-virtual-function-calls-final.cpp b/test/CodeGenCXX/devirtualize-virtual-function-calls-final.cpp
index 11026e8df3e7..193ee5f80406 100644
--- a/test/CodeGenCXX/devirtualize-virtual-function-calls-final.cpp
+++ b/test/CodeGenCXX/devirtualize-virtual-function-calls-final.cpp
@@ -53,26 +53,32 @@ namespace Test3 {
namespace Test4 {
struct A {
virtual void f();
+ virtual int operator-();
};
struct B final : A {
virtual void f();
+ virtual int operator-();
};
// CHECK-LABEL: define void @_ZN5Test41fEPNS_1BE
void f(B* d) {
// CHECK: call void @_ZN5Test41B1fEv
static_cast<A*>(d)->f();
+ // CHECK: call i32 @_ZN5Test41BngEv
+ -static_cast<A&>(*d);
}
}
namespace Test5 {
struct A {
virtual void f();
+ virtual int operator-();
};
struct B : A {
virtual void f();
+ virtual int operator-();
};
struct C final : B {
@@ -87,6 +93,15 @@ namespace Test5 {
// CHECK-NEXT: call void %[[FUNC]]
static_cast<A*>(d)->f();
}
+ // CHECK-LABEL: define void @_ZN5Test53fopEPNS_1CE
+ void fop(C* d) {
+ // FIXME: It should be possible to devirtualize this case, but that is
+ // not implemented yet.
+ // CHECK: getelementptr
+ // CHECK-NEXT: %[[FUNC:.*]] = load
+ // CHECK-NEXT: call i32 %[[FUNC]]
+ -static_cast<A&>(*d);
+ }
}
namespace Test6 {
@@ -165,6 +180,9 @@ namespace Test9 {
virtual A *f() {
return 0;
}
+ virtual A *operator-() {
+ return 0;
+ }
};
struct RC final : public RA {
virtual C *f() {
@@ -173,15 +191,37 @@ namespace Test9 {
x->b = 2;
return x;
}
+ virtual C *operator-() {
+ C *x = new C();
+ x->a = 1;
+ x->b = 2;
+ return x;
+ }
};
// CHECK: define {{.*}} @_ZN5Test91fEPNS_2RCE
A *f(RC *x) {
// FIXME: It should be possible to devirtualize this case, but that is
// not implemented yet.
- // CHECK: getelementptr
- // CHECK-NEXT: %[[FUNC:.*]] = load
- // CHECK-NEXT: bitcast
+ // CHECK: load
+ // CHECK: bitcast
+ // CHECK: [[F_PTR_RA:%.+]] = bitcast
+ // CHECK: [[VTABLE:%.+]] = load {{.+}} [[F_PTR_RA]]
+ // CHECK: [[VFN:%.+]] = getelementptr inbounds {{.+}} [[VTABLE]], i{{[0-9]+}} 0
+ // CHECK-NEXT: %[[FUNC:.*]] = load {{.+}} [[VFN]]
// CHECK-NEXT: = call {{.*}} %[[FUNC]]
return static_cast<RA*>(x)->f();
}
+ // CHECK: define {{.*}} @_ZN5Test93fopEPNS_2RCE
+ A *fop(RC *x) {
+ // FIXME: It should be possible to devirtualize this case, but that is
+ // not implemented yet.
+ // CHECK: load
+ // CHECK: bitcast
+ // CHECK: [[F_PTR_RA:%.+]] = bitcast
+ // CHECK: [[VTABLE:%.+]] = load {{.+}} [[F_PTR_RA]]
+ // CHECK: [[VFN:%.+]] = getelementptr inbounds {{.+}} [[VTABLE]], i{{[0-9]+}} 1
+ // CHECK-NEXT: %[[FUNC:.*]] = load {{.+}} [[VFN]]
+ // CHECK-NEXT: = call {{.*}} %[[FUNC]]
+ return -static_cast<RA&>(*x);
+ }
}