Author: Dmitry Polukhin
Date: 2023-07-12T00:57:41-07:00
New Revision: 6d9fcc2ad874e4ee9b94eef4b85ffece18e501b1

URL: 
https://github.com/llvm/llvm-project/commit/6d9fcc2ad874e4ee9b94eef4b85ffece18e501b1
DIFF: 
https://github.com/llvm/llvm-project/commit/6d9fcc2ad874e4ee9b94eef4b85ffece18e501b1.diff

LOG: [clang][clangd] Don't crash/assert on -gsplit-dwarf=single without output

The crash happens in clang::driver::tools::SplitDebugName when Output is
InputInfo::Nothing. It doesn't happen with standalone clang driver because
output is created in Driver::BuildJobsForActionNoCache.

Example backtrace:
```
* thread #1, name = 'clangd', stop reason = hit program assert
  * frame #0: 0x00007ffff5c4eacf libc.so.6`raise + 271
    frame #1: 0x00007ffff5c21ea5 libc.so.6`abort + 295
    frame #2: 0x00007ffff5c21d79 libc.so.6`__assert_fail_base.cold.0 + 15
    frame #3: 0x00007ffff5c47426 libc.so.6`__assert_fail + 70
    frame #4: 0x000055555dc0923c 
clangd`clang::driver::InputInfo::getFilename(this=0x00007fffffff9398) const at 
InputInfo.h:84:5
    frame #5: 0x000055555dcd0d8d 
clangd`clang::driver::tools::SplitDebugName(JA=0x000055555f6c6a50, 
Args=0x000055555f6d0b80, Input=0x00007fffffff9678, Output=0x00007fffffff9398) 
at CommonArgs.cpp:1275:40
    frame #6: 0x000055555dc955a5 
clangd`clang::driver::tools::Clang::ConstructJob(this=0x000055555f6c69d0, 
C=0x000055555f6c64a0, JA=0x000055555f6c6a50, Output=0x00007fffffff9398, 
Inputs=0x00007fffffff9668, Args=0x000055555f6d0b80, 
LinkingOutput=0x0000000000000000) const at Clang.cpp:5690:33
    frame #7: 0x000055555dbf6b54 
clangd`clang::driver::Driver::BuildJobsForActionNoCache(this=0x00007fffffffb5e0,
 C=0x000055555f6c64a0, A=0x000055555f6c6a50, TC=0x000055555f6c4be0, 
BoundArch=(Data = 0x0000000000000000, Length = 0), AtTopLevel=true, 
MultipleArchs=false, LinkingOutput=0x0000000000000000, CachedResults=size=1, 
TargetDeviceOffloadKind=OFK_None) const at Driver.cpp:5618:10
    frame #8: 0x000055555dbf4ef0 
clangd`clang::driver::Driver::BuildJobsForAction(this=0x00007fffffffb5e0, 
C=0x000055555f6c64a0, A=0x000055555f6c6a50, TC=0x000055555f6c4be0, 
BoundArch=(Data = 0x0000000000000000, Length = 0), AtTopLevel=true, 
MultipleArchs=false, LinkingOutput=0x0000000000000000, CachedResults=size=1, 
TargetDeviceOffloadKind=OFK_None) const at Driver.cpp:5306:26
    frame #9: 0x000055555dbeb590 
clangd`clang::driver::Driver::BuildJobs(this=0x00007fffffffb5e0, 
C=0x000055555f6c64a0) const at Driver.cpp:4844:5
    frame #10: 0x000055555dbe6b0f 
clangd`clang::driver::Driver::BuildCompilation(this=0x00007fffffffb5e0, 
ArgList=ArrayRef<const char *> @ 0x00007fffffffb268) at Driver.cpp:1496:3
    frame #11: 0x000055555b0cc0d9 
clangd`clang::createInvocation(ArgList=ArrayRef<const char *> @ 
0x00007fffffffbb38, Opts=CreateInvocationOptions @ 0x00007fffffffbb90) at 
CreateInvocationFromCommandLine.cpp:53:52
    frame #12: 0x000055555b378e7b 
clangd`clang::clangd::buildCompilerInvocation(Inputs=0x00007fffffffca58, 
D=0x00007fffffffc158, CC1Args=size=0) at Compiler.cpp:116:44
    frame #13: 0x000055555895a6c8 clangd`clang::clangd::(anonymous 
namespace)::Checker::buildInvocation(this=0x00007fffffffc760, 
TFS=0x00007fffffffe570, Contents= Has Value=false ) at Check.cpp:212:9
    frame #14: 0x0000555558959cec clangd`clang::clangd::check(File=(Data = 
"build/test.cpp", Length = 64), TFS=0x00007fffffffe570, 
Opts=0x00007fffffffe600) at Check.cpp:486:34
    frame #15: 0x000055555892164a clangd`main(argc=4, argv=0x00007fffffffecd8) 
at ClangdMain.cpp:993:12
    frame #16: 0x00007ffff5c3ad85 libc.so.6`__libc_start_main + 229
    frame #17: 0x00005555585bbe9e clangd`_start + 46
```

Test Plan: ninja ClangDriverTests && 
tools/clang/unittests/Driver/ClangDriverTests

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

Added: 
    

Modified: 
    clang/lib/Driver/ToolChains/CommonArgs.cpp
    clang/unittests/Driver/ToolChainTest.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp 
b/clang/lib/Driver/ToolChains/CommonArgs.cpp
index 3dcbd5b8deb8d7..649d7ddcf8997a 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -1274,7 +1274,7 @@ const char *tools::SplitDebugName(const JobAction &JA, 
const ArgList &Args,
     F += ".dwo";
   };
   if (Arg *A = Args.getLastArg(options::OPT_gsplit_dwarf_EQ))
-    if (StringRef(A->getValue()) == "single")
+    if (StringRef(A->getValue()) == "single" && Output.isFilename())
       return Args.MakeArgString(Output.getFilename());
 
   SmallString<128> T;

diff  --git a/clang/unittests/Driver/ToolChainTest.cpp 
b/clang/unittests/Driver/ToolChainTest.cpp
index 4ddeadac2103f4..8d3853a7b4a6de 100644
--- a/clang/unittests/Driver/ToolChainTest.cpp
+++ b/clang/unittests/Driver/ToolChainTest.cpp
@@ -367,6 +367,16 @@ TEST(ToolChainTest, PostCallback) {
   EXPECT_TRUE(CallbackHasCalled);
 }
 
+TEST(CompilerInvocation, SplitSwarfSingleCrash) {
+  static constexpr const char *Args[] = {
+      "clang",     "--target=arm-linux-gnueabi",
+      "-gdwarf-4", "-gsplit-dwarf=single",
+      "-c",        "foo.cpp"};
+  CreateInvocationOptions CIOpts;
+  std::unique_ptr<CompilerInvocation> CI = createInvocation(Args, CIOpts);
+  EXPECT_TRUE(CI); // no-crash
+}
+
 TEST(GetDriverMode, PrefersLastDriverMode) {
   static constexpr const char *Args[] = {"clang-cl", "--driver-mode=foo",
                                          "--driver-mode=bar", "foo.cpp"};


        
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to