aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Serialization/ASTWriterDecl.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2016-02-24 21:59:10 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2016-02-24 21:59:10 +0000
commit8ab0cfd5a7e5288f110800b495c968cb7f8eb26d (patch)
tree50153acd481e5d6cd48035c40ddf012ddb9d7f21 /clang/lib/Serialization/ASTWriterDecl.cpp
parentf4ea6039698a9d07cf88bc959e79a83b05de5a82 (diff)
downloadllvm-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.cpp22
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);
}