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