summaryrefslogtreecommitdiffstats
path: root/test/CodeGenCXX/devirtualize-virtual-function-calls-final.cpp
diff options
context:
space:
mode:
authordim <dim@FreeBSD.org>2012-08-15 20:02:54 +0000
committerdim <dim@FreeBSD.org>2012-08-15 20:02:54 +0000
commit554bcb69c2d785a011a30e7db87a36a87fe7db10 (patch)
tree9abb1a658a297776086f4e0dfa6ca533de02104e /test/CodeGenCXX/devirtualize-virtual-function-calls-final.cpp
parentbb67ca86b31f67faee50bd10c3b036d65751745a (diff)
downloadFreeBSD-src-554bcb69c2d785a011a30e7db87a36a87fe7db10.zip
FreeBSD-src-554bcb69c2d785a011a30e7db87a36a87fe7db10.tar.gz
Vendor import of clang trunk r161861:
http://llvm.org/svn/llvm-project/cfe/trunk@161861
Diffstat (limited to 'test/CodeGenCXX/devirtualize-virtual-function-calls-final.cpp')
-rw-r--r--test/CodeGenCXX/devirtualize-virtual-function-calls-final.cpp139
1 files changed, 138 insertions, 1 deletions
diff --git a/test/CodeGenCXX/devirtualize-virtual-function-calls-final.cpp b/test/CodeGenCXX/devirtualize-virtual-function-calls-final.cpp
index 3de75ed..634bf84 100644
--- a/test/CodeGenCXX/devirtualize-virtual-function-calls-final.cpp
+++ b/test/CodeGenCXX/devirtualize-virtual-function-calls-final.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -std=c++11 %s -emit-llvm -o - | FileCheck %s
namespace Test1 {
struct A {
@@ -49,3 +49,140 @@ namespace Test3 {
return static_cast<B*>(v)->f();
}
}
+
+namespace Test4 {
+ struct A {
+ virtual void f();
+ };
+
+ struct B final : A {
+ virtual void f();
+ };
+
+ // CHECK: define void @_ZN5Test41fEPNS_1BE
+ void f(B* d) {
+ // CHECK: call void @_ZN5Test41B1fEv
+ static_cast<A*>(d)->f();
+ }
+}
+
+namespace Test5 {
+ struct A {
+ virtual void f();
+ };
+
+ struct B : A {
+ virtual void f();
+ };
+
+ struct C final : B {
+ };
+
+ // CHECK: define void @_ZN5Test51fEPNS_1CE
+ void f(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 void %[[FUNC]]
+ static_cast<A*>(d)->f();
+ }
+}
+
+namespace Test6 {
+ struct A {
+ virtual ~A();
+ };
+
+ struct B : public A {
+ virtual ~B();
+ };
+
+ struct C {
+ virtual ~C();
+ };
+
+ struct D final : public C, public B {
+ };
+
+ // CHECK: define void @_ZN5Test61fEPNS_1DE
+ void f(D* d) {
+ // CHECK: call void @_ZN5Test61DD1Ev
+ static_cast<A*>(d)->~A();
+ }
+}
+
+namespace Test7 {
+ struct foo {
+ virtual void g() {}
+ };
+
+ struct bar {
+ virtual int f() { return 0; }
+ };
+
+ struct zed final : public foo, public bar {
+ int z;
+ virtual int f() {return z;}
+ };
+
+ // CHECK: define i32 @_ZN5Test71fEPNS_3zedE
+ int f(zed *z) {
+ // CHECK: alloca
+ // CHECK-NEXT: store
+ // CHECK-NEXT: load
+ // CHECK-NEXT: bitcast
+ // CHECK-NEXT: call {{.*}} @_ZN5Test73zed1fEv
+ // CHECK-NEXT: ret
+ return static_cast<bar*>(z)->f();
+ }
+}
+
+namespace Test8 {
+ struct A { virtual ~A() {} };
+ struct B {
+ int b;
+ virtual int foo() { return b; }
+ };
+ struct C final : A, B { };
+ // CHECK: define i32 @_ZN5Test84testEPNS_1CE
+ int test(C *c) {
+ // CHECK: %[[THIS:.*]] = phi
+ // CHECK-NEXT: call i32 @_ZN5Test81B3fooEv(%"struct.Test8::B"* %[[THIS]])
+ return static_cast<B*>(c)->foo();
+ }
+}
+
+namespace Test9 {
+ struct A {
+ int a;
+ };
+ struct B {
+ int b;
+ };
+ struct C : public B, public A {
+ };
+ struct RA {
+ virtual A *f() {
+ return 0;
+ }
+ };
+ struct RC final : public RA {
+ virtual C *f() {
+ 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-NEXT: = call {{.*}} %[[FUNC]]
+ return static_cast<RA*>(x)->f();
+ }
+}
OpenPOWER on IntegriCloud