From: Anders Carlsson Date: Sun, 10 Apr 2011 18:00:32 +0000 (+0000) Subject: Change CollectPrimaryBases to collect the bases in the right order. Fixes one half... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b8bced0b75fa4188c91753d5a1de6d164af45450;p=clang Change CollectPrimaryBases to collect the bases in the right order. Fixes one half of PR9660. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@129252 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGVTables.cpp b/lib/CodeGen/CGVTables.cpp index bc97b7463e..678b115753 100644 --- a/lib/CodeGen/CGVTables.cpp +++ b/lib/CodeGen/CGVTables.cpp @@ -2306,14 +2306,16 @@ void VTableBuilder::dumpLayout(llvm::raw_ostream& Out) { static void CollectPrimaryBases(const CXXRecordDecl *RD, ASTContext &Context, VTableBuilder::PrimaryBasesSetVectorTy &PrimaryBases) { - while (RD) { - const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); - const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase(); - if (PrimaryBase) - PrimaryBases.insert(PrimaryBase); + const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); + const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase(); - RD = PrimaryBase; - } + if (!PrimaryBase) + return; + + CollectPrimaryBases(PrimaryBase, Context, PrimaryBases); + + if (!PrimaryBases.insert(PrimaryBase)) + assert(false && "Found a duplicate primary base!"); } void CodeGenVTables::ComputeMethodVTableIndices(const CXXRecordDecl *RD) { diff --git a/test/CodeGenCXX/vtable-layout.cpp b/test/CodeGenCXX/vtable-layout.cpp index 1cf8a52d44..bd696813c8 100644 --- a/test/CodeGenCXX/vtable-layout.cpp +++ b/test/CodeGenCXX/vtable-layout.cpp @@ -41,6 +41,7 @@ // RUN: FileCheck --check-prefix=CHECK-40 %s < %t // RUN: FileCheck --check-prefix=CHECK-41 %s < %t // RUN: FileCheck --check-prefix=CHECK-42 %s < %t +// RUN: FileCheck --check-prefix=CHECK-43 %s < %t // For now, just verify this doesn't crash. namespace test0 { @@ -1679,3 +1680,24 @@ struct D : virtual B, C { void D::g() { } } + +namespace Test37 { + +// Test that we give C::f the right vtable index. (PR9660). +struct A { + virtual A* f() = 0; +}; + +struct B : virtual A { + virtual B* f(); +}; + +// CHECK-43: VTable indices for 'Test37::C' (1 entries). +// CHECK-43-NEXT: 1 | Test37::C *Test37::C::f() +struct C : B { + virtual C* f(); +}; + +C* C::f() { return 0; } + +}