aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/CodeGen/CGVtable.cpp7
-rw-r--r--test/CodeGenCXX/virt.cpp4
2 files changed, 7 insertions, 4 deletions
diff --git a/lib/CodeGen/CGVtable.cpp b/lib/CodeGen/CGVtable.cpp
index 7c28f006c9..3d05b39605 100644
--- a/lib/CodeGen/CGVtable.cpp
+++ b/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/test/CodeGenCXX/virt.cpp b/test/CodeGenCXX/virt.cpp
index 2d641dba5c..e7fd911fb0 100644
--- a/test/CodeGenCXX/virt.cpp
+++ b/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