Author: d0k Date: Thu Oct 26 05:28:13 2017 New Revision: 316659 URL: http://llvm.org/viewvc/llvm-project?rev=316659&view=rev Log: [clangd] Report an error on findDefinitions/signatureHelp on an unopened file instead of crashing.
Found by clangd-fuzzer. Modified: clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp clang-tools-extra/trunk/clangd/ClangdServer.cpp clang-tools-extra/trunk/clangd/ClangdServer.h clang-tools-extra/trunk/test/clangd/definitions.test clang-tools-extra/trunk/test/clangd/signature-help.test clang-tools-extra/trunk/unittests/clangd/ClangdTests.cpp Modified: clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp?rev=316659&r1=316658&r2=316659&view=diff ============================================================================== --- clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp (original) +++ clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp Thu Oct 26 05:28:13 2017 @@ -160,24 +160,24 @@ void ClangdLSPServer::onCompletion(Ctx C void ClangdLSPServer::onSignatureHelp(Ctx C, TextDocumentPositionParams &Params) { - C.reply(SignatureHelp::unparse( - Server - .signatureHelp( - Params.textDocument.uri.file, - Position{Params.position.line, Params.position.character}) - .Value)); + auto SignatureHelp = Server.signatureHelp( + Params.textDocument.uri.file, + Position{Params.position.line, Params.position.character}); + if (!SignatureHelp) + return C.replyError(-32602, llvm::toString(SignatureHelp.takeError())); + C.reply(SignatureHelp::unparse(SignatureHelp->Value)); } void ClangdLSPServer::onGoToDefinition(Ctx C, TextDocumentPositionParams &Params) { - auto Items = Server - .findDefinitions(Params.textDocument.uri.file, - Position{Params.position.line, - Params.position.character}) - .Value; + auto Items = Server.findDefinitions( + Params.textDocument.uri.file, + Position{Params.position.line, Params.position.character}); + if (!Items) + return C.replyError(-32602, llvm::toString(Items.takeError())); std::string Locations; - for (const auto &Item : Items) { + for (const auto &Item : Items->Value) { Locations += Location::unparse(Item); Locations += ","; } Modified: clang-tools-extra/trunk/clangd/ClangdServer.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ClangdServer.cpp?rev=316659&r1=316658&r2=316659&view=diff ============================================================================== --- clang-tools-extra/trunk/clangd/ClangdServer.cpp (original) +++ clang-tools-extra/trunk/clangd/ClangdServer.cpp Thu Oct 26 05:28:13 2017 @@ -13,6 +13,7 @@ #include "clang/Frontend/CompilerInvocation.h" #include "clang/Tooling/CompilationDatabase.h" #include "llvm/ADT/ArrayRef.h" +#include "llvm/Support/Errc.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/Path.h" #include "llvm/Support/raw_ostream.h" @@ -266,15 +267,17 @@ void ClangdServer::codeComplete( WorkScheduler.addToFront(std::move(Task), std::move(Callback)); } -Tagged<SignatureHelp> +llvm::Expected<Tagged<SignatureHelp>> ClangdServer::signatureHelp(PathRef File, Position Pos, llvm::Optional<StringRef> OverridenContents, IntrusiveRefCntPtr<vfs::FileSystem> *UsedFS) { std::string DraftStorage; if (!OverridenContents) { auto FileContents = DraftMgr.getDraft(File); - assert(FileContents.Draft && - "signatureHelp is called for non-added document"); + if (!FileContents.Draft) + return llvm::make_error<llvm::StringError>( + "signatureHelp is called for non-added document", + llvm::errc::invalid_argument); DraftStorage = std::move(*FileContents.Draft); OverridenContents = DraftStorage; @@ -285,7 +288,10 @@ ClangdServer::signatureHelp(PathRef File *UsedFS = TaggedFS.Value; std::shared_ptr<CppFile> Resources = Units.getFile(File); - assert(Resources && "Calling signatureHelp on non-added file"); + if (!Resources) + return llvm::make_error<llvm::StringError>( + "signatureHelp is called for non-added document", + llvm::errc::invalid_argument); auto Preamble = Resources->getPossiblyStalePreamble(); auto Result = clangd::signatureHelp(File, Resources->getCompileCommand(), @@ -347,16 +353,15 @@ std::string ClangdServer::dumpAST(PathRe return Result; } -Tagged<std::vector<Location>> ClangdServer::findDefinitions(PathRef File, - Position Pos) { - auto FileContents = DraftMgr.getDraft(File); - assert(FileContents.Draft && - "findDefinitions is called for non-added document"); - +llvm::Expected<Tagged<std::vector<Location>>> +ClangdServer::findDefinitions(PathRef File, Position Pos) { auto TaggedFS = FSProvider.getTaggedFileSystem(File); std::shared_ptr<CppFile> Resources = Units.getFile(File); - assert(Resources && "Calling findDefinitions on non-added file"); + if (!Resources) + return llvm::make_error<llvm::StringError>( + "findDefinitions called on non-added file", + llvm::errc::invalid_argument); std::vector<Location> Result; Resources->getAST().get()->runUnderLock([Pos, &Result, this](ParsedAST *AST) { Modified: clang-tools-extra/trunk/clangd/ClangdServer.h URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ClangdServer.h?rev=316659&r1=316658&r2=316659&view=diff ============================================================================== --- clang-tools-extra/trunk/clangd/ClangdServer.h (original) +++ clang-tools-extra/trunk/clangd/ClangdServer.h Thu Oct 26 05:28:13 2017 @@ -271,13 +271,14 @@ public: /// will be used. If \p UsedFS is non-null, it will be overwritten by /// vfs::FileSystem used for signature help. This method should only be called /// for currently tracked files. - Tagged<SignatureHelp> + llvm::Expected<Tagged<SignatureHelp>> signatureHelp(PathRef File, Position Pos, llvm::Optional<StringRef> OverridenContents = llvm::None, IntrusiveRefCntPtr<vfs::FileSystem> *UsedFS = nullptr); /// Get definition of symbol at a specified \p Line and \p Column in \p File. - Tagged<std::vector<Location>> findDefinitions(PathRef File, Position Pos); + llvm::Expected<Tagged<std::vector<Location>>> findDefinitions(PathRef File, + Position Pos); /// Helper function that returns a path to the corresponding source file when /// given a header file and vice versa. Modified: clang-tools-extra/trunk/test/clangd/definitions.test URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clangd/definitions.test?rev=316659&r1=316658&r2=316659&view=diff ============================================================================== --- clang-tools-extra/trunk/test/clangd/definitions.test (original) +++ clang-tools-extra/trunk/test/clangd/definitions.test Thu Oct 26 05:28:13 2017 @@ -163,10 +163,15 @@ Content-Length: 148 # Go to macro, being undefined # CHECK: {"jsonrpc":"2.0","id":1,"result":[{"uri": "file:///main.cpp", "range": {"start": {"line": 2, "character": 8}, "end": {"line": 2, "character": 13}}}]} -Content-Length: 44 +Content-Length: 156 -{"jsonrpc":"2.0","id":3,"method":"shutdown"} -# CHECK: {"jsonrpc":"2.0","id":3,"result":null} +{"jsonrpc":"2.0","id":2,"method":"textDocument/definition","params":{"textDocument":{"uri":"file:///doesnotexist.cpp"},"position":{"line":4,"character":7}}} +# CHECK: {"jsonrpc":"2.0","id":2,"error":{"code":-32602,"message":"findDefinitions called on non-added file"}} + +Content-Length: 48 + +{"jsonrpc":"2.0","id":10000,"method":"shutdown"} +# CHECK: {"jsonrpc":"2.0","id":10000,"result":null} Content-Length: 33 {"jsonrpc":"2.0":"method":"exit"} Modified: clang-tools-extra/trunk/test/clangd/signature-help.test URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clangd/signature-help.test?rev=316659&r1=316658&r2=316659&view=diff ============================================================================== --- clang-tools-extra/trunk/test/clangd/signature-help.test (original) +++ clang-tools-extra/trunk/test/clangd/signature-help.test Thu Oct 26 05:28:13 2017 @@ -36,6 +36,11 @@ Content-Length: 151 # CHECK-DAG: {"label":"bar(float x = 0, int y = 42) -> void","parameters":[{"label":"float x = 0"},{"label":"int y = 42"}]} # CHECK: ]} +Content-Length: 159 + +{"jsonrpc":"2.0","id":3,"method":"textDocument/signatureHelp","params":{"textDocument":{"uri":"file:///doesnotexist.cpp"},"position":{"line":8,"character":9}}} +# CHECK: {"jsonrpc":"2.0","id":3,"error":{"code":-32602,"message":"signatureHelp is called for non-added document"}} + # Shutdown. Content-Length: 49 Modified: clang-tools-extra/trunk/unittests/clangd/ClangdTests.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clangd/ClangdTests.cpp?rev=316659&r1=316658&r2=316659&view=diff ============================================================================== --- clang-tools-extra/trunk/unittests/clangd/ClangdTests.cpp (original) +++ clang-tools-extra/trunk/unittests/clangd/ClangdTests.cpp Thu Oct 26 05:28:13 2017 @@ -1056,7 +1056,7 @@ int d; AddDocument(FileIndex); Position Pos{LineDist(RandGen), ColumnDist(RandGen)}; - Server.findDefinitions(FilePaths[FileIndex], Pos); + ASSERT_TRUE(!!Server.findDefinitions(FilePaths[FileIndex], Pos)); }; std::vector<std::function<void()>> AsyncRequests = { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits