]> granicus.if.org Git - clang/commitdiff
Fix a use-after-free found in libclang when doing code completion. The
authorChandler Carruth <chandlerc@gmail.com>
Sun, 18 Aug 2013 07:20:52 +0000 (07:20 +0000)
committerChandler Carruth <chandlerc@gmail.com>
Sun, 18 Aug 2013 07:20:52 +0000 (07:20 +0000)
loop processing the candidates can cause new declerations to be added to
the context, invalidating lookup_result. To avoid that, make a copy of
the list of declarations to iterate over.

I don't have a way to check in a test case for this as it involves
a giant pile of source code and a generated PCH file used to accelerate
code completion, all of this running under ASan.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@188623 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaLookup.cpp

index adda1b947910e077cbe79aa3a3b169603b72c719..07379d5100101e1d72317338e34bf645fdae9ce3 100644 (file)
@@ -2505,11 +2505,17 @@ Sema::SpecialMemberOverloadResult *Sema::LookupSpecialMember(CXXRecordDecl *RD,
   // will always be a (possibly implicit) declaration to shadow any others.
   OverloadCandidateSet OCS((SourceLocation()));
   DeclContext::lookup_result R = RD->lookup(Name);
-
   assert(!R.empty() &&
          "lookup for a constructor or assignment operator was empty");
-  for (DeclContext::lookup_iterator I = R.begin(), E = R.end(); I != E; ++I) {
-    Decl *Cand = *I;
+
+  // Copy the candidates as our processing of them may load new declarations
+  // from an external source and invalidate lookup_result.
+  SmallVector<NamedDecl *, 8> Candidates(R.begin(), R.end());
+
+  for (SmallVectorImpl<NamedDecl *>::iterator I = Candidates.begin(),
+                                         E = Candidates.end();
+       I != E; ++I) {
+    NamedDecl *Cand = *I;
 
     if (Cand->isInvalidDecl())
       continue;