From: Anders Carlsson Date: Wed, 9 Mar 2011 05:09:32 +0000 (+0000) Subject: When deserializing CXXBaseSpecifiers (and offsets), make sure to walk the chain in... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f25330bd88f921b6e4cae965932681f213d9d544;p=clang When deserializing CXXBaseSpecifiers (and offsets), make sure to walk the chain in the correct order. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@127315 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp index 72637c1eb0..4717cd6268 100644 --- a/lib/Serialization/ASTReader.cpp +++ b/lib/Serialization/ASTReader.cpp @@ -3730,11 +3730,13 @@ ASTReader::GetCXXBaseSpecifiersOffset(serialization::CXXBaseSpecifiersID ID) { --ID; uint64_t Offset = 0; for (unsigned I = 0, N = Chain.size(); I != N; ++I) { - if (ID < Chain[I]->LocalNumCXXBaseSpecifiers) - return Offset + Chain[I]->CXXBaseSpecifiersOffsets[ID]; + PerFileData &F = *Chain[N - I - 1]; + + if (ID < F.LocalNumCXXBaseSpecifiers) + return Offset + F.CXXBaseSpecifiersOffsets[ID]; - ID -= Chain[I]->LocalNumCXXBaseSpecifiers; - Offset += Chain[I]->SizeInBits; + ID -= F.LocalNumCXXBaseSpecifiers; + Offset += F.SizeInBits; } assert(false && "CXXBaseSpecifiers not found"); @@ -3745,14 +3747,14 @@ CXXBaseSpecifier *ASTReader::GetExternalCXXBaseSpecifiers(uint64_t Offset) { // Figure out which AST file contains this offset. PerFileData *F = 0; for (unsigned I = 0, N = Chain.size(); I != N; ++I) { - if (Offset < Chain[I]->SizeInBits) { - F = Chain[I]; + if (Offset < Chain[N - I - 1]->SizeInBits) { + F = Chain[N - I - 1]; break; } - Offset -= Chain[I]->SizeInBits; + Offset -= Chain[N - I - 1]->SizeInBits; } - + if (!F) { Error("Malformed AST file: C++ base specifiers at impossible offset"); return 0; diff --git a/test/PCH/chain-cxx.cpp b/test/PCH/chain-cxx.cpp index 852af05d57..bf37acb298 100644 --- a/test/PCH/chain-cxx.cpp +++ b/test/PCH/chain-cxx.cpp @@ -34,6 +34,9 @@ struct S { typedef int H; }; template struct TS2; typedef TS2 TS2int; +template struct TestBaseSpecifiers { }; +template struct TestBaseSpecifiers2 : TestBaseSpecifiers { }; + //===----------------------------------------------------------------------===// #elif not defined(HEADER2) #define HEADER2 @@ -73,6 +76,9 @@ struct S { typedef int L; }; template struct TS2 { }; +struct TestBaseSpecifiers3 { }; +struct TestBaseSpecifiers4 : TestBaseSpecifiers3 { }; + struct A { }; struct B : A { };