diff options
author | Rafael Espindola <rafael.espindola@gmail.com> | 2012-06-26 17:45:31 +0000 |
---|---|---|
committer | Rafael Espindola <rafael.espindola@gmail.com> | 2012-06-26 17:45:31 +0000 |
commit | 0b4fe503ef00d9f8ea330850d3e3b303e9c7c876 (patch) | |
tree | 4ea4cf2da2635676660fe4ed9c1ece8d0994a03d /test/CodeGenCXX/devirtualize-virtual-function-calls-final.cpp | |
parent | 7ed4f663287b087bc566d29d9febdfdeb8dd2776 (diff) |
During codegen of a virtual call we would extract any casts in the expression
to see if we had an underlying final class or method, but we would then
use the cast type to do the call, resulting in a direct call to the wrong
method.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@159212 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/CodeGenCXX/devirtualize-virtual-function-calls-final.cpp')
-rw-r--r-- | test/CodeGenCXX/devirtualize-virtual-function-calls-final.cpp | 60 |
1 files changed, 59 insertions, 1 deletions
diff --git a/test/CodeGenCXX/devirtualize-virtual-function-calls-final.cpp b/test/CodeGenCXX/devirtualize-virtual-function-calls-final.cpp index 3de75ed3db..f7b10f647b 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,61 @@ 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) { + // CHECK: call void @_ZN5Test51B1fEv + 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(); + } +} |