diff options
author | David Blaikie <dblaikie@gmail.com> | 2012-10-18 16:57:32 +0000 |
---|---|---|
committer | David Blaikie <dblaikie@gmail.com> | 2012-10-18 16:57:32 +0000 |
commit | 3d5cf5e0483f538c27016ef3e064536058d5605e (patch) | |
tree | 28fad1ff108358312f81b669731613d614aa75b3 /lib/Sema/SemaInit.cpp | |
parent | 7fd00b153c991fbe30f9fa76391d2ad9fa1d349d (diff) |
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.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@166188 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaInit.cpp')
-rw-r--r-- | lib/Sema/SemaInit.cpp | 10 |
1 files changed, 8 insertions, 2 deletions
diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp index ec25d53113..3596bbfc72 100644 --- a/lib/Sema/SemaInit.cpp +++ b/lib/Sema/SemaInit.cpp @@ -3700,8 +3700,14 @@ static void TryUserDefinedConversion(Sema &S, // Try to complete the type we're converting to. if (!S.RequireCompleteType(Kind.getLocation(), DestType, 0)) { - DeclContext::lookup_iterator Con, ConEnd; - for (llvm::tie(Con, ConEnd) = S.LookupConstructors(DestRecordDecl); + DeclContext::lookup_iterator ConOrig, ConEndOrig; + 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) { NamedDecl *D = *Con; DeclAccessPair FoundDecl = DeclAccessPair::make(D, D->getAccess()); |