]> granicus.if.org Git - clang/commitdiff
Be sure to track the non-virtual part of the vcall offset in complex
authorMike Stump <mrs@apple.com>
Tue, 26 Jan 2010 03:42:22 +0000 (03:42 +0000)
committerMike Stump <mrs@apple.com>
Tue, 26 Jan 2010 03:42:22 +0000 (03:42 +0000)
multiple inheritance cases.  WIP.

This fixes 20% of the outstanding problems found by the randomized
tester.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@94499 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGVtable.cpp
test/CodeGenCXX/virt.cpp

index 7c28f006c9570a7662762d8fca1a2e41eb521777..3d05b396058174b1da14f6fa6575877dc0823b6a 100644 (file)
@@ -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()));
index 2d641dba5cb4400044a13e5c2e060f9dce79ac72..e7fd911fb002fd57fd5caff3c023103a564ade87 100644 (file)
@@ -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