diff options
| author | Mike Stump <mrs@apple.com> | 2010-01-26 03:42:22 +0000 |
|---|---|---|
| committer | Mike Stump <mrs@apple.com> | 2010-01-26 03:42:22 +0000 |
| commit | 77537b136e2d281c842b4906f47aafa10b4e061c (patch) | |
| tree | 60731415dbd68230d6b9391a73c828522614cee4 /clang | |
| parent | 4c4c1dfc2b768486127dcea6e1505c5b21f12d4c (diff) | |
| download | bcm5719-llvm-77537b136e2d281c842b4906f47aafa10b4e061c.tar.gz bcm5719-llvm-77537b136e2d281c842b4906f47aafa10b4e061c.zip | |
Be sure to track the non-virtual part of the vcall offset in complex
multiple inheritance cases. WIP.
This fixes 20% of the outstanding problems found by the randomized
tester.
llvm-svn: 94499
Diffstat (limited to 'clang')
| -rw-r--r-- | clang/lib/CodeGen/CGVtable.cpp | 7 | ||||
| -rw-r--r-- | clang/test/CodeGenCXX/virt.cpp | 4 |
2 files changed, 7 insertions, 4 deletions
diff --git a/clang/lib/CodeGen/CGVtable.cpp b/clang/lib/CodeGen/CGVtable.cpp index 7c28f006c95..3d05b396058 100644 --- a/clang/lib/CodeGen/CGVtable.cpp +++ b/clang/lib/CodeGen/CGVtable.cpp @@ -59,6 +59,7 @@ private: llvm::DenseMap<const CXXMethodDecl *, Index_t> VCall; llvm::DenseMap<GlobalDecl, Index_t> VCallOffset; + llvm::DenseMap<GlobalDecl, Index_t> VCallOffsetForVCall; // This is the offset to the nearest virtual base llvm::DenseMap<const CXXMethodDecl *, Index_t> NonVirtualOffset; llvm::DenseMap<const CXXRecordDecl *, Index_t> VBIndex; @@ -632,6 +633,7 @@ public: Index_t &idx = VCall[UMD]; // Allocate the first one, after that, we reuse the previous one. if (idx == 0) { + VCallOffsetForVCall[UMD] = Offset/8; NonVirtualOffset[UMD] = -CurrentVBaseOffset/8 + Offset/8; idx = VCalls.size()+1; VCalls.push_back(Offset/8 - CurrentVBaseOffset/8); @@ -1077,14 +1079,15 @@ bool VtableBuilder::OverrideMethod(GlobalDecl GD, bool MorallyVirtual, if (idx == 0) { NonVirtualOffset[UMD] = CurrentVBaseOffset/8 - OverrideOffset/8; VCallOffset[GD] = OverrideOffset/8; + VCallOffsetForVCall[UMD] = OverrideOffset/8; idx = VCalls.size()+1; - VCalls.push_back(0); + VCalls.push_back(OverrideOffset/8 - CurrentVBaseOffset/8); D1(printf(" vcall for %s at %d with delta %d most derived %s\n", MD->getNameAsString().c_str(), (int)-idx-3, (int)VCalls[idx-1], MostDerivedClass->getNameAsCString())); } else { VCallOffset[GD] = VCallOffset[OGD]; - VCalls[idx-1] = -VCallOffset[OGD] + OverrideOffset/8; + VCalls[idx-1] = -VCallOffsetForVCall[UMD] + OverrideOffset/8; D1(printf(" vcall patch for %s at %d with delta %d most derived %s\n", MD->getNameAsString().c_str(), (int)-idx-3, (int)VCalls[idx-1], MostDerivedClass->getNameAsCString())); diff --git a/clang/test/CodeGenCXX/virt.cpp b/clang/test/CodeGenCXX/virt.cpp index 2d641dba5cb..e7fd911fb00 100644 --- a/clang/test/CodeGenCXX/virt.cpp +++ b/clang/test/CodeGenCXX/virt.cpp @@ -389,8 +389,8 @@ struct test16_D : test16_NV1, virtual test16_B2 { // CHECK-LP64-NEXT: .quad 0 // CHECK-LP64-NEXT: .quad 0 // CHECK-LP64-NEXT: .quad -16 -// CHECK-LP64-NEXT .quad -32 -// CHECK-LP64: .quad 0 +// CHECK-LP64-NEXT: .quad -32 +// CHECK-LP64-NEXT: .quad 0 // CHECK-LP64-NEXT: .quad 0 // CHECK-LP64-NEXT: .quad -32 // CHECK-LP64-NEXT: .quad __ZTI8test16_D |

