[clang-tools-extra] 744b111 - [clangd] Bail gracefully if given an assembly or IR source file

Nathan Ridge via cfe-commits cfe-commits at lists.llvm.org
Fri Aug 18 20:26:45 PDT 2023


Author: Nathan Ridge
Date: 2023-08-18T23:26:32-04:00
New Revision: 744b111434b25b1259308050c59062dc4f38a589

URL: https://github.com/llvm/llvm-project/commit/744b111434b25b1259308050c59062dc4f38a589
DIFF: https://github.com/llvm/llvm-project/commit/744b111434b25b1259308050c59062dc4f38a589.diff

LOG: [clangd] Bail gracefully if given an assembly or IR source file

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 https://github.com/llvm/llvm-project/issues/62090

Differential Revision: https://reviews.llvm.org/D149236

Added: 
    

Modified: 
    clang-tools-extra/clangd/ParsedAST.cpp
    clang-tools-extra/clangd/unittests/ParsedASTTests.cpp

Removed: 
    


################################################################################
diff  --git a/clang-tools-extra/clangd/ParsedAST.cpp b/clang-tools-extra/clangd/ParsedAST.cpp
index 81cfe8bb60b3e0..3cf6671be9600e 100644
--- a/clang-tools-extra/clangd/ParsedAST.cpp
+++ b/clang-tools-extra/clangd/ParsedAST.cpp
@@ -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;

diff  --git a/clang-tools-extra/clangd/unittests/ParsedASTTests.cpp b/clang-tools-extra/clangd/unittests/ParsedASTTests.cpp
index b0d5bea1d3279e..ec8132645f81fb 100644
--- a/clang-tools-extra/clangd/unittests/ParsedASTTests.cpp
+++ b/clang-tools-extra/clangd/unittests/ParsedASTTests.cpp
@@ -13,6 +13,7 @@
 
 #include "../../clang-tidy/ClangTidyCheck.h"
 #include "AST.h"
+#include "CompileCommands.h"
 #include "Compiler.h"
 #include "Config.h"
 #include "Diagnostics.h"
@@ -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


        


More information about the cfe-commits mailing list