]> granicus.if.org Git - clang/commitdiff
[Sema] Avoid iterator invalidation when code completing.
authorBenjamin Kramer <benny.kra@googlemail.com>
Fri, 13 Oct 2017 22:14:34 +0000 (22:14 +0000)
committerBenjamin Kramer <benny.kra@googlemail.com>
Fri, 13 Oct 2017 22:14:34 +0000 (22:14 +0000)
It's possible for the code completion consumer to add new decls to the
current scope while lookup happens on it. Avoid this by making a copy
first.

Sadly I wasn't able to get a self-contained test case for this as it
requires code completion + precompiled preamble + the stars aligning to
deserialize at exactly the right time.

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

lib/Sema/SemaLookup.cpp

index 8f3e93845bb802a06abdd5f2f10d1e414229d17a..827c7012bc3529965d67f4eef4cfd804ea4fcf29 100644 (file)
@@ -3677,8 +3677,10 @@ static void LookupVisibleDecls(Scope *S, LookupResult &Result,
        !Visited.alreadyVisitedContext(S->getEntity())) ||
       (S->getEntity())->isFunctionOrMethod()) {
     FindLocalExternScope FindLocals(Result);
-    // Walk through the declarations in this Scope.
-    for (auto *D : S->decls()) {
+    // Walk through the declarations in this Scope. The consumer might add new
+    // decls to the scope as part of deserialization, so make a copy first.
+    SmallVector<Decl *, 8> ScopeDecls(S->decls().begin(), S->decls().end());
+    for (Decl *D : ScopeDecls) {
       if (NamedDecl *ND = dyn_cast<NamedDecl>(D))
         if ((ND = Result.getAcceptableDecl(ND))) {
           Consumer.FoundDecl(ND, Visited.checkHidden(ND), nullptr, false);