summaryrefslogtreecommitdiffstats
path: root/test/CodeGenCXX/devirtualize-virtual-function-calls.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2016-11-11 01:01:31 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2016-11-11 01:01:31 +0000
commit4f7770e365bd65e46393357538fbb886528a92c7 (patch)
treee287fb91250d32702dd00f8a90f1361e833dcc3a /test/CodeGenCXX/devirtualize-virtual-function-calls.cpp
parent534a7a7eedade86800c4cb6f8d0c347f500ec82c (diff)
PR30937: don't devirtualize if we find that the callee is a pure virtual
function. In that case, there is no requirement that the callee is actually defined, and the code may in fact be valid and have defined behavior if the virtual call is unreachable. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@286534 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/CodeGenCXX/devirtualize-virtual-function-calls.cpp')
-rw-r--r--test/CodeGenCXX/devirtualize-virtual-function-calls.cpp34
1 files changed, 34 insertions, 0 deletions
diff --git a/test/CodeGenCXX/devirtualize-virtual-function-calls.cpp b/test/CodeGenCXX/devirtualize-virtual-function-calls.cpp
index f2dc978972..b4c39f3fcf 100644
--- a/test/CodeGenCXX/devirtualize-virtual-function-calls.cpp
+++ b/test/CodeGenCXX/devirtualize-virtual-function-calls.cpp
@@ -161,3 +161,37 @@ namespace test4 {
p->fish.eat();
}
}
+
+// Do not devirtualize to pure virtual function calls.
+namespace test5 {
+ struct X {
+ virtual void f() = 0;
+ };
+ struct Y {};
+ // CHECK-LABEL: define {{.*}} @_ZN5test51f
+ void f(Y &y, X Y::*p) {
+ // CHECK-NOT: call {{.*}} @_ZN5test51X1fEv
+ // CHECK: call void %
+ (y.*p).f();
+ };
+
+ struct Z final {
+ virtual void f() = 0;
+ };
+ // CHECK-LABEL: define {{.*}} @_ZN5test51g
+ void g(Z &z) {
+ // CHECK-NOT: call {{.*}} @_ZN5test51Z1fEv
+ // CHECK: call void %
+ z.f();
+ }
+
+ struct Q {
+ virtual void f() final = 0;
+ };
+ // CHECK-LABEL: define {{.*}} @_ZN5test51h
+ void h(Q &q) {
+ // CHECK-NOT: call {{.*}} @_ZN5test51Q1fEv
+ // CHECK: call void %
+ q.f();
+ }
+}