From: Mike Stump Date: Fri, 6 Nov 2009 02:38:24 +0000 (+0000) Subject: Refine the vcall for a function that is defined in a virtual base X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=33c530e33a2232e8d6089f4a3028e6b8c3e2b746;p=clang Refine the vcall for a function that is defined in a virtual base class that is overridden in a base that isn't morally virtual. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@86217 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGVtable.cpp b/lib/CodeGen/CGVtable.cpp index e2e11478de..34012cafe5 100644 --- a/lib/CodeGen/CGVtable.cpp +++ b/lib/CodeGen/CGVtable.cpp @@ -242,15 +242,13 @@ public: idx = VCalls.size()+1; VCalls.push_back(0); D1(printf(" vcall for %s at %d with delta %d most derived %s\n", - MD->getNameAsCString(), - (int)-VCalls.size()-3, (int)VCallOffset[MD], + MD->getNameAsCString(), (int)-idx-3, (int)VCalls[idx-1], Class->getNameAsCString())); } else { VCallOffset[MD] = VCallOffset[OMD]; VCalls[idx-1] = -VCallOffset[OMD] + OverrideOffset/8; D1(printf(" vcall patch for %s at %d with delta %d most derived %s\n", - MD->getNameAsCString(), - (int)-VCalls.size()-3, (int)VCallOffset[MD], + MD->getNameAsCString(), (int)-idx-3, (int)VCalls[idx-1], Class->getNameAsCString())); } VCall[MD] = idx; @@ -271,6 +269,16 @@ public: // FIXME: finish off int64_t O = VCallOffset[OMD] - OverrideOffset/8; // int64_t O = CurrentVBaseOffset/8 - OverrideOffset/8; + + if (VCall.count(OMD)) { + VCallOffset[MD] = VCallOffset[OMD]; + Index_t idx = VCall[OMD]; + VCalls[idx-1] = -VCallOffset[OMD] + OverrideOffset/8; + D1(printf(" vcall patch for %s at %d with delta %d most derived %s\n", + MD->getNameAsCString(), (int)-idx-3, (int)VCalls[idx-1], + Class->getNameAsCString())); + VCall[MD] = idx; + } if (O || ReturnOffset.first || ReturnOffset.second) { CallOffset ThisOffset = std::make_pair(O, 0); @@ -374,8 +382,7 @@ public: idx = VCalls.size()+1; VCalls.push_back(0); D1(printf(" vcall for %s at %d with delta %d\n", - MD->getNameAsCString(), (int)-VCalls.size()-3, - (int)VCallOffset[MD])); + MD->getNameAsCString(), (int)-VCalls.size()-3, 0)); } } } diff --git a/test/CodeGenCXX/virt.cpp b/test/CodeGenCXX/virt.cpp index 5eeabfac16..0f239eef8c 100644 --- a/test/CodeGenCXX/virt.cpp +++ b/test/CodeGenCXX/virt.cpp @@ -895,7 +895,7 @@ class test20_B : virtual test20_V { class test20_B1 : virtual test20_V1 { }; class test20_D : public test20_B, public test20_B1 { -} d; +}; // CHECK-LP64: __ZTV8test20_D: // CHECK-LP64-NEXT: .quad 8 @@ -911,6 +911,34 @@ class test20_D : public test20_B, public test20_B1 { // CHECK-LP64-NEXT: .quad __ZN9test20_V14foo2Ev +class test21_V { + virtual void foo(); +}; +class test21_V1 { + virtual void foo(); +}; +class test21_B : virtual test21_V { +}; +class test21_B1 : virtual test21_V1 { +}; +class test21_D : public test21_B, public test21_B1 { + void foo() { } +}; + +// CHECK-LP64: __ZTV8test21_D: +// CHECK-LP64-NEXT: .quad 8 +// CHECK-LP64-NEXT: .space 8 +// CHECK-LP64-NEXT: .space 8 +// CHECK-LP64-NEXT: .space 8 +// CHECK-LP64-NEXT: .quad __ZTI8test21_D +// CHECK-LP64-NEXT: .quad __ZN8test21_D3fooEv +// CHECK-LP64-NEXT: .space 8 +// CHECK-LP64-NEXT: .quad 18446744073709551608 +// CHECK-LP64-NEXT: .quad 18446744073709551608 +// CHECK-LP64-NEXT: .quad __ZTI8test21_D +// CHECK-LP64-NEXT .quad __ZTv0_n24_N8test21_D3fooEv + + // CHECK-LP64: __ZTV1B: // CHECK-LP64-NEXT: .space 8 @@ -951,6 +979,8 @@ class test20_D : public test20_B, public test20_B1 { // CHECK-LP64-NEXT: .quad __ZN2D14bar4Ev // CHECK-LP64-NEXT: .quad __ZN2D14bar5Ev +test21_D d21; +test20_D d20; test19_D d19; test18_D d18; test17_D d17;