]> granicus.if.org Git - clang/commitdiff
MS ABI: Don't append to vbtables that we shouldn't extend
authorReid Kleckner <reid@kleckner.net>
Thu, 17 Apr 2014 22:47:52 +0000 (22:47 +0000)
committerReid Kleckner <reid@kleckner.net>
Thu, 17 Apr 2014 22:47:52 +0000 (22:47 +0000)
This was probably a benign bug, since nobody would look at the vbtable
slots that we were filling in.

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

lib/AST/VTableBuilder.cpp
test/CodeGenCXX/microsoft-abi-vbtables.cpp

index 3e8dd470dfe474a1b58d71213688a81a51411a35..c606450e1e1d2175df8e7032359f25fcbe873651 100644 (file)
@@ -3180,11 +3180,7 @@ void MicrosoftVTableContext::computeVTablePaths(bool ForVBTables,
     const VPtrInfoVector &BasePaths =
         ForVBTables ? enumerateVBTables(Base) : getVFPtrOffsets(Base);
 
-    for (VPtrInfoVector::const_iterator II = BasePaths.begin(),
-                                        EE = BasePaths.end();
-         II != EE; ++II) {
-      VPtrInfo *BaseInfo = *II;
-
+    for (VPtrInfo *BaseInfo : BasePaths) {
       // Don't include the path if it goes through a virtual base that we've
       // already included.
       if (setsIntersect(VBasesSeen, BaseInfo->ContainingVBases))
@@ -3202,12 +3198,16 @@ void MicrosoftVTableContext::computeVTablePaths(bool ForVBTables,
       // FIXME: Why do we need this?
       P->PathToBaseWithVPtr.insert(P->PathToBaseWithVPtr.begin(), Base);
 
-      // Keep track of which derived class ultimately uses the vtable, and what
-      // the full adjustment is from the MDC to this vtable.  The adjustment is
-      // captured by an optional vbase and a non-virtual offset.
-      if (Base == (ForVBTables ? Layout.getBaseSharingVBPtr()
+      // Keep track of which vtable the derived class is going to extend with
+      // new methods or bases.  We append to either the vftable of our primary
+      // base, or the first non-virtual base that has a vbtable.
+      if (P->ReusingBase == Base &&
+          Base == (ForVBTables ? Layout.getBaseSharingVBPtr()
                                : Layout.getPrimaryBase()))
         P->ReusingBase = RD;
+
+      // Keep track of the full adjustment from the MDC to this vtable.  The
+      // adjustment is captured by an optional vbase and a non-virtual offset.
       if (B.isVirtual())
         P->ContainingVBases.push_back(Base);
       else if (P->ContainingVBases.empty())
index b950d0cbf0c64a79fb5a1c75e8f3b0c579d782b4..8b86d6bd3c8e99f9286413503c10e963f0727a46 100644 (file)
@@ -518,3 +518,13 @@ F x;
 // CHECK-DAG: @"\01??_8F@Test28@@7BD@1@@" =
 // CHECK-DAG: @"\01??_8F@Test28@@7BE@1@@" =
 }
+
+namespace Test29 {
+struct A {};
+struct B : virtual A {};
+struct C : virtual B {};
+struct D : C {};
+D d;
+
+// CHECK-DAG: @"\01??_8D@Test29@@7BB@1@@" = linkonce_odr unnamed_addr constant [2 x i32] zeroinitializer
+}