DmitryPolukhin created this revision.
DmitryPolukhin added reviewers: kadircet, lh123, sammccall, hokein, 
ilya-biryukov.
DmitryPolukhin added projects: clang, clang-tools-extra.
Herald added a subscriber: usaxena95.
DmitryPolukhin requested review of this revision.

Compilation database might have empty string as a command line argument.
But ExpandResponseFilesDatabase::expand doesn't expect this and assumes
that string.front() can be used for any argument. It is undefined behaviour if
string is empty. With debug build mode it causes crash in clangd.

Test Plan: check-clang


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D105120

Files:
  clang/lib/Tooling/ExpandResponseFilesCompilationDatabase.cpp
  clang/unittests/Tooling/CompilationDatabaseTest.cpp


Index: clang/unittests/Tooling/CompilationDatabaseTest.cpp
===================================================================
--- clang/unittests/Tooling/CompilationDatabaseTest.cpp
+++ clang/unittests/Tooling/CompilationDatabaseTest.cpp
@@ -700,6 +700,10 @@
     SmallVector<StringRef, 8> Argv = {Clang, File, "-D", File};
     llvm::SplitString(Flags, Argv);
 
+    // Trim double quotation from the argumnets if any.
+    for (auto It = Argv.begin(); It != Argv.end(); ++It)
+      *It = It->trim("\"");
+
     SmallString<32> Dir;
     llvm::sys::path::system_temp_directory(false, Dir);
 
@@ -962,5 +966,12 @@
   EXPECT_EQ(getCommand("bar.cpp"), "clang bar.cpp -D bar.cpp -Dflag");
 }
 
+TEST_F(ExpandResponseFilesTest, ExpandResponseFilesEmptyArgument) {
+  addFile(path(StringRef("rsp1.rsp")), "-Dflag");
+
+  add("foo.cpp", "clang", "@rsp1.rsp \"\"");
+  EXPECT_EQ(getCommand("foo.cpp"), "clang foo.cpp -D foo.cpp -Dflag ");
+}
+
 } // end namespace tooling
 } // end namespace clang
Index: clang/lib/Tooling/ExpandResponseFilesCompilationDatabase.cpp
===================================================================
--- clang/lib/Tooling/ExpandResponseFilesCompilationDatabase.cpp
+++ clang/lib/Tooling/ExpandResponseFilesCompilationDatabase.cpp
@@ -54,7 +54,8 @@
       Argv.reserve(Cmd.CommandLine.size());
       for (auto &Arg : Cmd.CommandLine) {
         Argv.push_back(Arg.c_str());
-        SeenRSPFile |= Arg.front() == '@';
+        if (!Arg.empty())
+          SeenRSPFile |= Arg.front() == '@';
       }
       if (!SeenRSPFile)
         continue;


Index: clang/unittests/Tooling/CompilationDatabaseTest.cpp
===================================================================
--- clang/unittests/Tooling/CompilationDatabaseTest.cpp
+++ clang/unittests/Tooling/CompilationDatabaseTest.cpp
@@ -700,6 +700,10 @@
     SmallVector<StringRef, 8> Argv = {Clang, File, "-D", File};
     llvm::SplitString(Flags, Argv);
 
+    // Trim double quotation from the argumnets if any.
+    for (auto It = Argv.begin(); It != Argv.end(); ++It)
+      *It = It->trim("\"");
+
     SmallString<32> Dir;
     llvm::sys::path::system_temp_directory(false, Dir);
 
@@ -962,5 +966,12 @@
   EXPECT_EQ(getCommand("bar.cpp"), "clang bar.cpp -D bar.cpp -Dflag");
 }
 
+TEST_F(ExpandResponseFilesTest, ExpandResponseFilesEmptyArgument) {
+  addFile(path(StringRef("rsp1.rsp")), "-Dflag");
+
+  add("foo.cpp", "clang", "@rsp1.rsp \"\"");
+  EXPECT_EQ(getCommand("foo.cpp"), "clang foo.cpp -D foo.cpp -Dflag ");
+}
+
 } // end namespace tooling
 } // end namespace clang
Index: clang/lib/Tooling/ExpandResponseFilesCompilationDatabase.cpp
===================================================================
--- clang/lib/Tooling/ExpandResponseFilesCompilationDatabase.cpp
+++ clang/lib/Tooling/ExpandResponseFilesCompilationDatabase.cpp
@@ -54,7 +54,8 @@
       Argv.reserve(Cmd.CommandLine.size());
       for (auto &Arg : Cmd.CommandLine) {
         Argv.push_back(Arg.c_str());
-        SeenRSPFile |= Arg.front() == '@';
+        if (!Arg.empty())
+          SeenRSPFile |= Arg.front() == '@';
       }
       if (!SeenRSPFile)
         continue;
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to