Author: rsmith Date: Wed Feb 24 15:59:10 2016 New Revision: 261781 URL: http://llvm.org/viewvc/llvm-project?rev=261781&view=rev Log: PR26237: Fix iterator invalidation bug that occurs if serializing specializations of a template manages to trigger deserialization of more specializations of the same template.
No test case provided: this is hard to reliably test due to standard library differences. Patch by Vassil Vassilev! Modified: cfe/trunk/lib/Serialization/ASTWriterDecl.cpp Modified: cfe/trunk/lib/Serialization/ASTWriterDecl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterDecl.cpp?rev=261781&r1=261780&r2=261781&view=diff ============================================================================== --- cfe/trunk/lib/Serialization/ASTWriterDecl.cpp (original) +++ cfe/trunk/lib/Serialization/ASTWriterDecl.cpp Wed Feb 24 15:59:10 2016 @@ -192,8 +192,8 @@ namespace clang { return None; } - template<typename Decl> - void AddTemplateSpecializations(Decl *D) { + template<typename DeclTy> + void AddTemplateSpecializations(DeclTy *D) { auto *Common = D->getCommonPtr(); // If we have any lazy specializations, and the external AST source is @@ -205,8 +205,6 @@ namespace clang { assert(!Common->LazySpecializations); } - auto &Specializations = Common->Specializations; - auto &&PartialSpecializations = getPartialSpecializations(Common); ArrayRef<DeclID> LazySpecializations; if (auto *LS = Common->LazySpecializations) LazySpecializations = llvm::makeArrayRef(LS + 1, LS[0]); @@ -215,13 +213,15 @@ namespace clang { unsigned I = Record.size(); Record.push_back(0); - for (auto &Entry : Specializations) { - auto *D = getSpecializationDecl(Entry); - assert(D->isCanonicalDecl() && "non-canonical decl in set"); - AddFirstDeclFromEachModule(D, /*IncludeLocal*/true); - } - for (auto &Entry : PartialSpecializations) { - auto *D = getSpecializationDecl(Entry); + // AddFirstDeclFromEachModule might trigger deserialization, invalidating + // *Specializations iterators. + llvm::SmallVector<const Decl*, 16> Specs; + for (auto &Entry : Common->Specializations) + Specs.push_back(getSpecializationDecl(Entry)); + for (auto &Entry : getPartialSpecializations(Common)) + Specs.push_back(getSpecializationDecl(Entry)); + + for (auto *D : Specs) { assert(D->isCanonicalDecl() && "non-canonical decl in set"); AddFirstDeclFromEachModule(D, /*IncludeLocal*/true); } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits