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
This commit is contained in:
Richard Smith 2016-02-24 21:59:10 +00:00
parent f4ea603969
commit 8ab0cfd5a7
1 changed files with 11 additions and 11 deletions

View File

@ -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);
}