diff options
author | Anders Carlsson <andersca@mac.com> | 2010-02-13 21:16:54 +0000 |
---|---|---|
committer | Anders Carlsson <andersca@mac.com> | 2010-02-13 21:16:54 +0000 |
commit | c1290adab780ce906a9d2ecb993014fae991bb33 (patch) | |
tree | 2c627838c4d565b947a8eb5c8eca17106c61b477 | |
parent | cf5a882da111d5aa006066180733b1bdef235fb4 (diff) | |
download | bcm5719-llvm-c1290adab780ce906a9d2ecb993014fae991bb33.tar.gz bcm5719-llvm-c1290adab780ce906a9d2ecb993014fae991bb33.zip |
Don't make return adjustments for pure virtual member functions.
llvm-svn: 96120
-rw-r--r-- | clang/lib/CodeGen/CGVtable.cpp | 13 | ||||
-rw-r--r-- | clang/test/CodeGenCXX/vtable-layout.cpp | 17 |
2 files changed, 25 insertions, 5 deletions
diff --git a/clang/lib/CodeGen/CGVtable.cpp b/clang/lib/CodeGen/CGVtable.cpp index 912f33c5d64..f16f66af2af 100644 --- a/clang/lib/CodeGen/CGVtable.cpp +++ b/clang/lib/CodeGen/CGVtable.cpp @@ -426,11 +426,14 @@ void FinalOverriders::PropagateOverrider(const CXXMethodDecl *OldMD, assert(Overrider.Method && "Did not find existing overrider!"); // Get the return adjustment base offset. - BaseOffset ReturnBaseOffset = - ComputeReturnTypeBaseOffset(Context, NewMD, OverriddenMD); - if (!ReturnBaseOffset.isEmpty()) { - // Store the return adjustment base offset. - ReturnAdjustments[SubobjectAndMethod] = ReturnBaseOffset; + // (We don't want to do this for pure virtual member functions). + if (!NewMD->isPure()) { + BaseOffset ReturnBaseOffset = + ComputeReturnTypeBaseOffset(Context, NewMD, OverriddenMD); + if (!ReturnBaseOffset.isEmpty()) { + // Store the return adjustment base offset. + ReturnAdjustments[SubobjectAndMethod] = ReturnBaseOffset; + } } // Set the new overrider. diff --git a/clang/test/CodeGenCXX/vtable-layout.cpp b/clang/test/CodeGenCXX/vtable-layout.cpp index 19ce8da4cfa..622983f7c8e 100644 --- a/clang/test/CodeGenCXX/vtable-layout.cpp +++ b/clang/test/CodeGenCXX/vtable-layout.cpp @@ -182,6 +182,23 @@ struct E : A { }; V3 *E::f() { return 0;} +// Test that a pure virtual member doesn't get a thunk. + +// CHECK: Vtable for 'Test4::F' (5 entries). +// CHECK-NEXT: 0 | offset_to_top (0) +// CHECK-NEXT: 1 | Test4::F RTTI +// CHECK-NEXT: -- (Test4::A, 0) vtable address -- +// CHECK-NEXT: -- (Test4::F, 0) vtable address -- +// CHECK-NEXT: 2 | Test4::R3 *Test4::F::f() [pure] +// CHECK-NEXT: 3 | void Test4::F::g() +// CHECK-NEXT: 4 | Test4::R3 *Test4::F::f() [pure] +struct F : A { + virtual void g(); + virtual R3 *f() = 0; +}; + +void F::g() { } + } // For now, just verify this doesn't crash. |