Patch a Source of Iterator Invalidation

getOpaqueResultTypeDecl() can wind up invoking lazy function body
parsing when it runs availability checking. If any of those function
bodies have opaque result types, they will be inserted. If that
insertion happens to resize the SetVector, iterators will be invalidated
and a non-deterministic crash results.

Instead, use SetVector::takeVector() for the iteration so we have
a temporary copy whose iterators cannot be invalidated in this
situation. This also elegantly handles clearing out the vector for us.

Resolves rdar://62976771
This commit is contained in:
Robert Widmann
2020-05-07 13:31:17 -07:00
parent 9a8b91edd1
commit 035cecaaa4

View File

@@ -2640,7 +2640,7 @@ SourceFile::getConfiguredReferencedNameTracker() const {
}
ArrayRef<OpaqueTypeDecl *> SourceFile::getOpaqueReturnTypeDecls() {
for (auto *vd : UnvalidatedDeclsWithOpaqueReturnTypes) {
for (auto *vd : UnvalidatedDeclsWithOpaqueReturnTypes.takeVector()) {
if (auto opaqueDecl = vd->getOpaqueResultTypeDecl()) {
auto inserted = ValidatedOpaqueReturnTypes.insert(
{opaqueDecl->getOpaqueReturnTypeIdentifier().str(),
@@ -2651,7 +2651,6 @@ ArrayRef<OpaqueTypeDecl *> SourceFile::getOpaqueReturnTypeDecls() {
}
}
UnvalidatedDeclsWithOpaqueReturnTypes.clear();
return OpaqueReturnTypes;
}