From f6e2b4cb4b4398229db55c63172705275313779a Mon Sep 17 00:00:00 2001 From: Ilya Biryukov Date: Tue, 9 Jan 2018 14:39:27 +0000 Subject: [PATCH] [clangd] Fix a bug in asynchronous code completion A StringRef that goes out of scope was copied and used in a handler running on a separate thread. We didn't catch it because clangd does not use the async completion API yet. llvm-svn: 322080 --- clang-tools-extra/clangd/ClangdServer.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/clang-tools-extra/clangd/ClangdServer.cpp b/clang-tools-extra/clangd/ClangdServer.cpp index e7c9c7a5148f..883ca35764ca 100644 --- a/clang-tools-extra/clangd/ClangdServer.cpp +++ b/clang-tools-extra/clangd/ClangdServer.cpp @@ -251,10 +251,17 @@ void ClangdServer::codeComplete( auto CodeCompleteOpts = Opts; if (FileIdx) CodeCompleteOpts.Index = FileIdx.get(); + + // Copy File, as it is a PathRef that will go out of scope before Task is + // executed. + Path FileStr = File; + // Copy PCHs to avoid accessing this->PCHs concurrently + std::shared_ptr PCHs = this->PCHs; // A task that will be run asynchronously. auto Task = // 'mutable' to reassign Preamble variable. - [=](Context Ctx, CallbackType Callback) mutable { + [FileStr, Preamble, Resources, Contents, Pos, CodeCompleteOpts, TaggedFS, + PCHs](Context Ctx, CallbackType Callback) mutable { if (!Preamble) { // Maybe we built some preamble before processing this request. Preamble = Resources->getPossiblyStalePreamble(); @@ -263,7 +270,7 @@ void ClangdServer::codeComplete( // both the old and the new version in case only one of them matches. CompletionList Result = clangd::codeComplete( - Ctx, File, Resources->getCompileCommand(), + Ctx, FileStr, Resources->getCompileCommand(), Preamble ? &Preamble->Preamble : nullptr, Contents, Pos, TaggedFS.Value, PCHs, CodeCompleteOpts);