From: Reid Kleckner Date: Thu, 17 Apr 2014 22:47:52 +0000 (+0000) Subject: MS ABI: Don't append to vbtables that we shouldn't extend X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c911bf1a4ad6146dfb8c91410db219c582172c44;p=clang MS ABI: Don't append to vbtables that we shouldn't extend 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 --- diff --git a/lib/AST/VTableBuilder.cpp b/lib/AST/VTableBuilder.cpp index 3e8dd470df..c606450e1e 100644 --- a/lib/AST/VTableBuilder.cpp +++ b/lib/AST/VTableBuilder.cpp @@ -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()) diff --git a/test/CodeGenCXX/microsoft-abi-vbtables.cpp b/test/CodeGenCXX/microsoft-abi-vbtables.cpp index b950d0cbf0..8b86d6bd3c 100644 --- a/test/CodeGenCXX/microsoft-abi-vbtables.cpp +++ b/test/CodeGenCXX/microsoft-abi-vbtables.cpp @@ -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 +}