PR14021: Copy lookup results to ensure safe iteration.

Within the body of the loop the underlying map may be modified via

  Sema::AddOverloadCandidate
    -> Sema::CompareReferenceRelationship
    -> Sema::RequireCompleteType

to avoid the use of invalid iterators the sequence is copied first.

A reliable, though large, test case is available - it will be reduced and
committed shortly.

Patch by Robert Muth. Review by myself, Nico Weber, and Rafael Espindola.

llvm-svn: 166188
This commit is contained in:
David Blaikie 2012-10-18 16:57:32 +00:00
parent a0ca6601bc
commit 12be639dfc
1 changed files with 8 additions and 2 deletions

View File

@ -3700,8 +3700,14 @@ static void TryUserDefinedConversion(Sema &S,
// Try to complete the type we're converting to. // Try to complete the type we're converting to.
if (!S.RequireCompleteType(Kind.getLocation(), DestType, 0)) { if (!S.RequireCompleteType(Kind.getLocation(), DestType, 0)) {
DeclContext::lookup_iterator Con, ConEnd; DeclContext::lookup_iterator ConOrig, ConEndOrig;
for (llvm::tie(Con, ConEnd) = S.LookupConstructors(DestRecordDecl); llvm::tie(ConOrig, ConEndOrig) = S.LookupConstructors(DestRecordDecl);
// The container holding the constructors can under certain conditions
// be changed while iterating. To be safe we copy the lookup results
// to a new container.
SmallVector<NamedDecl*, 8> CopyOfCon(ConOrig, ConEndOrig);
for (SmallVector<NamedDecl*, 8>::iterator
Con = CopyOfCon.begin(), ConEnd = CopyOfCon.end();
Con != ConEnd; ++Con) { Con != ConEnd; ++Con) {
NamedDecl *D = *Con; NamedDecl *D = *Con;
DeclAccessPair FoundDecl = DeclAccessPair::make(D, D->getAccess()); DeclAccessPair FoundDecl = DeclAccessPair::make(D, D->getAccess());