Skip to content

Commit

Permalink
[clangd] Bail gracefully if given an assembly or IR source file
Browse files Browse the repository at this point in the history
The previous behaviour is to try to parse such files, and in some
cases assert or hang in components that don't expect these forms of
input, like TokenBuffer.

Fixes #62090

Differential Revision: https://reviews.llvm.org/D149236
  • Loading branch information
HighCommander4 committed Aug 19, 2023
1 parent 92464cc commit 744b111
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 0 deletions.
9 changes: 9 additions & 0 deletions clang-tools-extra/clangd/ParsedAST.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,15 @@ ParsedAST::build(llvm::StringRef Filename, const ParseInputs &Inputs,
VFS = Preamble->StatCache->getConsumingFS(std::move(VFS));

assert(CI);

if (CI->getFrontendOpts().Inputs.size() > 0) {
auto Lang = CI->getFrontendOpts().Inputs[0].getKind().getLanguage();
if (Lang == Language::Asm || Lang == Language::LLVM_IR) {
elog("Clangd does not support assembly or IR source files");
return std::nullopt;
}
}

// Command-line parsing sets DisableFree to true by default, but we don't want
// to leak memory in clangd.
CI->getFrontendOpts().DisableFree = false;
Expand Down
32 changes: 32 additions & 0 deletions clang-tools-extra/clangd/unittests/ParsedASTTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

#include "../../clang-tidy/ClangTidyCheck.h"
#include "AST.h"
#include "CompileCommands.h"
#include "Compiler.h"
#include "Config.h"
#include "Diagnostics.h"
Expand Down Expand Up @@ -731,6 +732,37 @@ TEST(ParsedASTTest, DiscoversPragmaMarks) {
pragmaTrivia(" End")));
}

TEST(ParsedASTTest, GracefulFailureOnAssemblyFile) {
std::string Filename = "TestTU.S";
std::string Code = R"S(
main:
# test comment
bx lr
)S";

// The rest is a simplified version of TestTU::build().
// Don't call TestTU::build() itself because it would assert on
// failure to build an AST.
MockFS FS;
std::string FullFilename = testPath(Filename);
FS.Files[FullFilename] = Code;
ParseInputs Inputs;
auto &Argv = Inputs.CompileCommand.CommandLine;
Argv = {"clang"};
Argv.push_back(FullFilename);
Inputs.CompileCommand.Filename = FullFilename;
Inputs.CompileCommand.Directory = testRoot();
Inputs.Contents = Code;
Inputs.TFS = &FS;
StoreDiags Diags;
auto CI = buildCompilerInvocation(Inputs, Diags);
assert(CI && "Failed to build compilation invocation.");
auto AST = ParsedAST::build(FullFilename, Inputs, std::move(CI), {}, nullptr);

EXPECT_FALSE(AST.has_value())
<< "Should not try to build AST for assembly source file";
}

} // namespace
} // namespace clangd
} // namespace clang

0 comments on commit 744b111

Please sign in to comment.