diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2016-02-24 21:59:10 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2016-02-24 21:59:10 +0000 |
commit | 8ab0cfd5a7e5288f110800b495c968cb7f8eb26d (patch) | |
tree | 50153acd481e5d6cd48035c40ddf012ddb9d7f21 /clang/lib/Serialization/ASTWriterDecl.cpp | |
parent | f4ea6039698a9d07cf88bc959e79a83b05de5a82 (diff) | |
download | llvm-8ab0cfd5a7e5288f110800b495c968cb7f8eb26d.zip llvm-8ab0cfd5a7e5288f110800b495c968cb7f8eb26d.tar.gz llvm-8ab0cfd5a7e5288f110800b495c968cb7f8eb26d.tar.bz2 |
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!
llvm-svn: 261781
Diffstat (limited to 'clang/lib/Serialization/ASTWriterDecl.cpp')
-rw-r--r-- | clang/lib/Serialization/ASTWriterDecl.cpp | 22 |
1 files changed, 11 insertions, 11 deletions
diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp index f2f4a02..6ff3f95 100644 --- a/clang/lib/Serialization/ASTWriterDecl.cpp +++ b/clang/lib/Serialization/ASTWriterDecl.cpp @@ -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); } |