On Wed, Oct 26, 2011 at 10:53 AM, Douglas Gregor <[email protected]> wrote: > Author: dgregor > Date: Wed Oct 26 12:53:41 2011 > New Revision: 143037 > > URL: http://llvm.org/viewvc/llvm-project?rev=143037&view=rev > Log: > Eliminate a hang while loading a sequence of redeclarable entities. In > essence, the redeclaration chain for a class could end up in an > inconsistent state while deserializing multiple declarations in that > chain, where the circular linked list was not, in fact, > circular. Since only two redeclarations of the same entity will get > loaded when we're in this state, restore circularity when both have > been loaded. Fixes <rdar://problem/10324940> / PR11195.
This appears to be causing a test failure on smooshlab on Windows. -Eli > > Added: > cfe/trunk/test/Index/Inputs/redeclarations.h (with props) > cfe/trunk/test/Index/redeclarations.cpp (with props) > Modified: > cfe/trunk/lib/Serialization/ASTReaderDecl.cpp > cfe/trunk/lib/Serialization/ASTWriterDecl.cpp > > Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=143037&r1=143036&r2=143037&view=diff > ============================================================================== > --- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original) > +++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Wed Oct 26 12:53:41 2011 > @@ -278,8 +278,8 @@ > } > > void ASTDeclReader::VisitTagDecl(TagDecl *TD) { > - VisitTypeDecl(TD); > VisitRedeclarable(TD); > + VisitTypeDecl(TD); > TD->IdentifierNamespace = Record[Idx++]; > TD->setTagKind((TagDecl::TagKind)Record[Idx++]); > TD->setCompleteDefinition(Record[Idx++]); > @@ -340,8 +340,8 @@ > } > > void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) { > - VisitDeclaratorDecl(FD); > VisitRedeclarable(FD); > + VisitDeclaratorDecl(FD); > > ReadDeclarationNameLoc(FD->DNLoc, FD->getDeclName(), Record, Idx); > FD->IdentifierNamespace = Record[Idx++]; > @@ -712,8 +712,8 @@ > } > > void ASTDeclReader::VisitVarDecl(VarDecl *VD) { > - VisitDeclaratorDecl(VD); > VisitRedeclarable(VD); > + VisitDeclaratorDecl(VD); > VD->VarDeclBits.SClass = (StorageClass)Record[Idx++]; > VD->VarDeclBits.SClassAsWritten = (StorageClass)Record[Idx++]; > VD->VarDeclBits.ThreadSpecified = Record[Idx++]; > @@ -1329,18 +1329,37 @@ > // We temporarily set the first (canonical) declaration as the previous > one > // which is the one that matters and mark the real previous DeclID to be > // loaded & attached later on. > - D->RedeclLink = typename Redeclarable<T>::PreviousDeclLink( > - > cast_or_null<T>(Reader.GetDecl(FirstDeclID))); > + T *FirstDecl = cast_or_null<T>(Reader.GetDecl(FirstDeclID)); > + D->RedeclLink = typename Redeclarable<T>::PreviousDeclLink(FirstDecl); > if (PreviousDeclID != FirstDeclID) > Reader.PendingPreviousDecls.push_back(std::make_pair(static_cast<T*>(D), > PreviousDeclID)); > + > + // If the first declaration in the chain is in an inconsistent > + // state where it thinks that it is the only declaration, fix its > + // redeclaration link now to point at this declaration, so that we have a > + // proper redeclaration chain. > + if (FirstDecl->RedeclLink.getPointer() == FirstDecl) { > + FirstDecl->RedeclLink > + = typename Redeclarable<T>::LatestDeclLink(static_cast<T*>(D)); > + } > break; > } > - case PointsToLatest: > - D->RedeclLink = typename Redeclarable<T>::LatestDeclLink( > - ReadDeclAs<T>(Record, > Idx)); > + case PointsToLatest: { > + T *LatestDecl = ReadDeclAs<T>(Record, Idx); > + D->RedeclLink = typename Redeclarable<T>::LatestDeclLink(LatestDecl); > + > + // If the latest declaration in the chain is in an inconsistent > + // state where it thinks that it is the only declaration, fix its > + // redeclaration link now to point at this declaration, so that we have a > + // proper redeclaration chain. > + if (LatestDecl->RedeclLink.getPointer() == LatestDecl) { > + LatestDecl->RedeclLink > + = typename Redeclarable<T>::PreviousDeclLink(static_cast<T*>(D)); > + } > break; > } > + } > > assert(!(Kind == PointsToPrevious && > Reader.FirstLatestDeclIDs.find(ThisDeclID) != > > Modified: cfe/trunk/lib/Serialization/ASTWriterDecl.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterDecl.cpp?rev=143037&r1=143036&r2=143037&view=diff > ============================================================================== > --- cfe/trunk/lib/Serialization/ASTWriterDecl.cpp (original) > +++ cfe/trunk/lib/Serialization/ASTWriterDecl.cpp Wed Oct 26 12:53:41 2011 > @@ -198,8 +198,8 @@ > } > > void ASTDeclWriter::VisitTagDecl(TagDecl *D) { > - VisitTypeDecl(D); > VisitRedeclarable(D); > + VisitTypeDecl(D); > Record.push_back(D->getIdentifierNamespace()); > Record.push_back((unsigned)D->getTagKind()); // FIXME: stable encoding > Record.push_back(D->isCompleteDefinition()); > @@ -289,8 +289,8 @@ > } > > void ASTDeclWriter::VisitFunctionDecl(FunctionDecl *D) { > - VisitDeclaratorDecl(D); > VisitRedeclarable(D); > + VisitDeclaratorDecl(D); > > Writer.AddDeclarationNameLoc(D->DNLoc, D->getDeclName(), Record); > Record.push_back(D->getIdentifierNamespace()); > @@ -651,8 +651,8 @@ > } > > void ASTDeclWriter::VisitVarDecl(VarDecl *D) { > - VisitDeclaratorDecl(D); > VisitRedeclarable(D); > + VisitDeclaratorDecl(D); > Record.push_back(D->getStorageClass()); // FIXME: stable encoding > Record.push_back(D->getStorageClassAsWritten()); > Record.push_back(D->isThreadSpecified()); > @@ -1336,6 +1336,8 @@ > // Abbreviation for DECL_ENUM > Abv = new BitCodeAbbrev(); > Abv->Add(BitCodeAbbrevOp(serialization::DECL_ENUM)); > + // Redeclarable > + Abv->Add(BitCodeAbbrevOp(0)); // No redeclaration > // Decl > Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext > Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LexicalDeclContext > @@ -1353,8 +1355,6 @@ > // TypeDecl > Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Source Location > Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type Ref > - // Redeclarable > - Abv->Add(BitCodeAbbrevOp(0)); // No redeclaration > // TagDecl > Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // IdentifierNamespace > Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // getTagKind > @@ -1382,6 +1382,8 @@ > // Abbreviation for DECL_RECORD > Abv = new BitCodeAbbrev(); > Abv->Add(BitCodeAbbrevOp(serialization::DECL_RECORD)); > + // Redeclarable > + Abv->Add(BitCodeAbbrevOp(0)); // No redeclaration > // Decl > Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext > Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LexicalDeclContext > @@ -1399,8 +1401,6 @@ > // TypeDecl > Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Source Location > Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type Ref > - // Redeclarable > - Abv->Add(BitCodeAbbrevOp(0)); // No redeclaration > // TagDecl > Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // IdentifierNamespace > Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // getTagKind > @@ -1422,6 +1422,8 @@ > // Abbreviation for DECL_PARM_VAR > Abv = new BitCodeAbbrev(); > Abv->Add(BitCodeAbbrevOp(serialization::DECL_PARM_VAR)); > + // Redeclarable > + Abv->Add(BitCodeAbbrevOp(0)); // No redeclaration > // Decl > Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext > Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LexicalDeclContext > @@ -1442,7 +1444,6 @@ > Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // InnerStartLoc > Abv->Add(BitCodeAbbrevOp(0)); // hasExtInfo > // VarDecl > - Abv->Add(BitCodeAbbrevOp(0)); // No redeclaration > Abv->Add(BitCodeAbbrevOp(0)); // StorageClass > Abv->Add(BitCodeAbbrevOp(0)); // StorageClassAsWritten > Abv->Add(BitCodeAbbrevOp(0)); // isThreadSpecified > @@ -1495,6 +1496,8 @@ > // Abbreviation for DECL_VAR > Abv = new BitCodeAbbrev(); > Abv->Add(BitCodeAbbrevOp(serialization::DECL_VAR)); > + // Redeclarable > + Abv->Add(BitCodeAbbrevOp(0)); // No redeclaration > // Decl > Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext > Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LexicalDeclContext > @@ -1515,7 +1518,6 @@ > Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // InnerStartLoc > Abv->Add(BitCodeAbbrevOp(0)); // hasExtInfo > // VarDecl > - Abv->Add(BitCodeAbbrevOp(0)); // No redeclaration > Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // StorageClass > Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // StorageClassAsWritten > Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isThreadSpecified > > Added: cfe/trunk/test/Index/Inputs/redeclarations.h > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/Inputs/redeclarations.h?rev=143037&view=auto > ============================================================================== > --- cfe/trunk/test/Index/Inputs/redeclarations.h (added) > +++ cfe/trunk/test/Index/Inputs/redeclarations.h Wed Oct 26 12:53:41 2011 > @@ -0,0 +1,21 @@ > +class X > +{ > + friend class A; > +}; > + > + > +template <typename T1, typename T2> > +class B > +{ > +}; > + > +template <class T> > +struct C > +{ > +}; > + > +class D > +{ > + B<D, class A> x; > + friend struct C<A>; > +}; > > Propchange: cfe/trunk/test/Index/Inputs/redeclarations.h > ------------------------------------------------------------------------------ > svn:eol-style = native > > Propchange: cfe/trunk/test/Index/Inputs/redeclarations.h > ------------------------------------------------------------------------------ > svn:keywords = Id > > Propchange: cfe/trunk/test/Index/Inputs/redeclarations.h > ------------------------------------------------------------------------------ > svn:mime-type = text/plain > > Added: cfe/trunk/test/Index/redeclarations.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/redeclarations.cpp?rev=143037&view=auto > ============================================================================== > --- cfe/trunk/test/Index/redeclarations.cpp (added) > +++ cfe/trunk/test/Index/redeclarations.cpp Wed Oct 26 12:53:41 2011 > @@ -0,0 +1,21 @@ > +#include "redeclarations.h" > + > +class A > +{ > +}; > + > +// RUN: env CINDEXTEST_EDITING=1 c-index-test -test-load-source-reparse 2 > all -I%S/Inputs %s | FileCheck %s > + > +// CHECK: redeclarations.h:1:7: ClassDecl=X:1:7 (Definition) Extent=[1:1 - > 4:2] > +// CHECK: redeclarations.h:8:7: ClassTemplate=B:8:7 (Definition) Extent=[7:1 > - 10:2] > +// CHECK: redeclarations.h:7:20: TemplateTypeParameter=T1:7:20 (Definition) > Extent=[7:11 - 7:22] > +// CHECK: redeclarations.h:7:33: TemplateTypeParameter=T2:7:33 (Definition) > Extent=[7:24 - 7:35] > +// CHECK: redeclarations.h:13:8: ClassTemplate=C:13:8 (Definition) > Extent=[12:1 - 15:2] > +// CHECK: redeclarations.h:12:17: TemplateTypeParameter=T:12:17 (Definition) > Extent=[12:11 - 12:18] > +// CHECK: redeclarations.h:17:7: ClassDecl=D:17:7 (Definition) Extent=[17:1 > - 21:2] > +// CHECK: redeclarations.h:19:16: ClassDecl=A:19:16 Extent=[19:10 - 19:17] > +// CHECK: redeclarations.h:19:19: FieldDecl=x:19:19 (Definition) > Extent=[19:5 - 19:20] > +// CHECK: redeclarations.h:19:5: TemplateRef=B:8:7 Extent=[19:5 - 19:6] > +// CHECK: redeclarations.h:19:7: TypeRef=class D:17:7 Extent=[19:7 - 19:8] > +// CHECK: redeclarations.h:19:16: TypeRef=class A:3:7 Extent=[19:16 - 19:17] > +// CHECK: redeclarations.cpp:3:7: ClassDecl=A:3:7 (Definition) Extent=[3:1 - > 5:2] > > Propchange: cfe/trunk/test/Index/redeclarations.cpp > ------------------------------------------------------------------------------ > svn:eol-style = native > > Propchange: cfe/trunk/test/Index/redeclarations.cpp > ------------------------------------------------------------------------------ > svn:keywords = Id > > Propchange: cfe/trunk/test/Index/redeclarations.cpp > ------------------------------------------------------------------------------ > svn:mime-type = text/plain > > > _______________________________________________ > cfe-commits mailing list > [email protected] > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits > _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
