]> granicus.if.org Git - clang/commitdiff
PR14021: Copy lookup results to ensure safe iteration.
authorDavid Blaikie <dblaikie@gmail.com>
Thu, 18 Oct 2012 16:57:32 +0000 (16:57 +0000)
committerDavid Blaikie <dblaikie@gmail.com>
Thu, 18 Oct 2012 16:57:32 +0000 (16:57 +0000)
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

lib/Sema/SemaInit.cpp

index ec25d531136f9de184ba065d9388450d12a4cb65..3596bbfc725ae4e89afbce85a0e574684ba7ca0a 100644 (file)
@@ -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());