Author: Carlos Galvez
Date: 2025-09-05T20:38:59+02:00
New Revision: 97086d6fdacf67327a65317826955bab377aafc0

URL: 
https://github.com/llvm/llvm-project/commit/97086d6fdacf67327a65317826955bab377aafc0
DIFF: 
https://github.com/llvm/llvm-project/commit/97086d6fdacf67327a65317826955bab377aafc0.diff

LOG: [clang-tidy] Do not crash when an empty directory is used in the comp… 
(#156873)

…ilation database

Currently a hard crash encourages people to report a bug upstream, but
this is not really a bug. Instead, print an error and use a reasonable
default (the current working directory).

Fixes #57264

Co-authored-by: Carlos Gálvez <carlos.gal...@zenseact.com>

Added: 
    
clang-tools-extra/test/clang-tidy/infrastructure/Inputs/invalid-database/compile_commands.json
    clang-tools-extra/test/clang-tidy/infrastructure/invalid-database.cpp

Modified: 
    clang-tools-extra/docs/ReleaseNotes.rst
    clang-tools-extra/test/clang-tidy/infrastructure/empty-database.cpp
    clang/lib/Tooling/Tooling.cpp

Removed: 
    


################################################################################
diff  --git a/clang-tools-extra/docs/ReleaseNotes.rst 
b/clang-tools-extra/docs/ReleaseNotes.rst
index 32e4dfb8aa329..0f230b8fbdebd 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -126,6 +126,10 @@ Improvements to clang-tidy
 - Improved :program:`clang-tidy` option `-quiet` by suppressing diagnostic
   count messages.
 
+- Improved :program:`clang-tidy` by not crashing when an empty `directory`
+  field is used in a compilation database; the current working directory
+  will be used instead, and an error message will be printed.
+
 New checks
 ^^^^^^^^^^
 

diff  --git 
a/clang-tools-extra/test/clang-tidy/infrastructure/Inputs/invalid-database/compile_commands.json
 
b/clang-tools-extra/test/clang-tidy/infrastructure/Inputs/invalid-database/compile_commands.json
new file mode 100644
index 0000000000000..5d0e145740dc6
--- /dev/null
+++ 
b/clang-tools-extra/test/clang-tidy/infrastructure/Inputs/invalid-database/compile_commands.json
@@ -0,0 +1,5 @@
+[{
+    "directory":"/invalid/",
+    "file":"/tmp/",
+    "arguments": []
+}]

diff  --git 
a/clang-tools-extra/test/clang-tidy/infrastructure/empty-database.cpp 
b/clang-tools-extra/test/clang-tidy/infrastructure/empty-database.cpp
index 54fe8910a9a91..c4c504c95d475 100644
--- a/clang-tools-extra/test/clang-tidy/infrastructure/empty-database.cpp
+++ b/clang-tools-extra/test/clang-tidy/infrastructure/empty-database.cpp
@@ -1,5 +1,5 @@
 // UNSUPPORTED: system-windows
 
-// RUN: not --crash clang-tidy -p %S/Inputs/empty-database %s 2>&1 | FileCheck 
%s
+// RUN: clang-tidy -p %S/Inputs/empty-database %s 2>&1 | FileCheck %s
 
-// CHECK: LLVM ERROR: Cannot chdir into ""!
+// CHECK: 'directory' field of compilation database is empty; using the 
current working directory instead.

diff  --git 
a/clang-tools-extra/test/clang-tidy/infrastructure/invalid-database.cpp 
b/clang-tools-extra/test/clang-tidy/infrastructure/invalid-database.cpp
new file mode 100644
index 0000000000000..7935385c1a35a
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/infrastructure/invalid-database.cpp
@@ -0,0 +1,5 @@
+// UNSUPPORTED: system-windows
+
+// RUN: not --crash clang-tidy -p %S/Inputs/invalid-database %s 2>&1 | 
FileCheck %s
+
+// CHECK: LLVM ERROR: Cannot chdir into "/invalid/"!

diff  --git a/clang/lib/Tooling/Tooling.cpp b/clang/lib/Tooling/Tooling.cpp
index 1120e33b1f0c3..0c179b852813d 100644
--- a/clang/lib/Tooling/Tooling.cpp
+++ b/clang/lib/Tooling/Tooling.cpp
@@ -574,6 +574,15 @@ int ClangTool::run(ToolAction *Action) {
       continue;
     }
     for (CompileCommand &CompileCommand : CompileCommandsForFile) {
+      // If the 'directory' field of the compilation database is empty, display
+      // an error and use the working directory instead.
+      StringRef Directory = CompileCommand.Directory;
+      if (Directory.empty()) {
+        llvm::errs() << "'directory' field of compilation database is empty; "
+                        "using the current working directory instead.\n";
+        Directory = InitialWorkingDir;
+      }
+
       // FIXME: chdir is thread hostile; on the other hand, creating the same
       // behavior as chdir is complex: chdir resolves the path once, thus
       // guaranteeing that all subsequent relative path operations work
@@ -581,15 +590,14 @@ int ClangTool::run(ToolAction *Action) {
       // 
diff erence for example on network filesystems, where symlinks might be
       // switched during runtime of the tool. Fixing this depends on having a
       // file system abstraction that allows openat() style interactions.
-      if (OverlayFileSystem->setCurrentWorkingDirectory(
-              CompileCommand.Directory))
-        llvm::report_fatal_error("Cannot chdir into \"" +
-                                 Twine(CompileCommand.Directory) + "\"!");
+      if (OverlayFileSystem->setCurrentWorkingDirectory(Directory))
+        llvm::report_fatal_error("Cannot chdir into \"" + Twine(Directory) +
+                                 "\"!");
 
       // Now fill the in-memory VFS with the relative file mappings so it will
       // have the correct relative paths. We never remove mappings but that
       // should be fine.
-      if (SeenWorkingDirectories.insert(CompileCommand.Directory).second)
+      if (SeenWorkingDirectories.insert(Directory).second)
         for (const auto &MappedFile : MappedFileContents)
           if (!llvm::sys::path::is_absolute(MappedFile.first))
             InMemoryFileSystem->addFile(


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

Reply via email to