[llvm-branch-commits] [clang] release/22.x: [clang-scan-deps] Fixes an assertion in clang-scan-deps (#193619) (PR #194118)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Fri Apr 24 23:27:01 PDT 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: llvmbot
<details>
<summary>Changes</summary>
Backport 1249cb6aea8893c3d2ba7221697b68b0ef4520e9
Requested by: @<!-- -->ChuanqiXu9
---
Full diff: https://github.com/llvm/llvm-project/pull/194118.diff
2 Files Affected:
- (added) clang/test/ClangScanDeps/p1689-mf-nested-dir.c (+34)
- (modified) clang/tools/clang-scan-deps/ClangScanDeps.cpp (+30-7)
``````````diff
diff --git a/clang/test/ClangScanDeps/p1689-mf-nested-dir.c b/clang/test/ClangScanDeps/p1689-mf-nested-dir.c
new file mode 100644
index 0000000000000..dca72727f4d6b
--- /dev/null
+++ b/clang/test/ClangScanDeps/p1689-mf-nested-dir.c
@@ -0,0 +1,34 @@
+// UNSUPPORTED: target={{.*}}-aix{{.*}}
+//
+// When using -format=p1689, clang-scan-deps writes make-style dependency output
+// to the path from -MF. The directory where the output file is written may not
+// exist yet. Ensure the tool creates missing directories instead of failing or
+// aborting.
+//
+// RUN: rm -rf %t
+// RUN: mkdir -p %t
+// RUN: split-file %s %t
+// RUN: sed "s|DIR|%/t|g" %t/cdb.json.in > %t/compile_commands.json
+// RUN: clang-scan-deps -compilation-database %t/compile_commands.json -format=p1689 \
+// RUN: -o %t/scan.json
+// RUN: cat %t/obj/nested/hello.o.d | sed 's:\\\\\?:/:g' | FileCheck %s --check-prefix=CHECK-DEP
+// RUN: cat %t/scan.json | FileCheck %s -DPREFIX=%/t --check-prefix=CHECK-JSON
+
+//--- hello.c
+int main(void) { return 0; }
+
+//--- cdb.json.in
+[
+ {
+ "directory": "DIR",
+ "command": "clang -c DIR/hello.c -o DIR/obj/nested/hello.o -MMD -MF DIR/obj/nested/hello.o.d",
+ "file": "DIR/hello.c",
+ "output": "DIR/obj/nested/hello.o"
+ }
+]
+
+// CHECK-DEP-DAG: hello.o
+// CHECK-DEP-DAG: hello.c
+
+// CHECK-JSON-DAG: "primary-output": "[[PREFIX]]/obj/nested/hello.o"
+// CHECK-JSON-DAG: "version": 1
diff --git a/clang/tools/clang-scan-deps/ClangScanDeps.cpp b/clang/tools/clang-scan-deps/ClangScanDeps.cpp
index 256a70568a3bf..a5f0db6976a43 100644
--- a/clang/tools/clang-scan-deps/ClangScanDeps.cpp
+++ b/clang/tools/clang-scan-deps/ClangScanDeps.cpp
@@ -19,6 +19,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/FileSystem.h"
#include "llvm/Support/FileUtilities.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/JSON.h"
@@ -1031,6 +1032,7 @@ int clang_scan_deps_main(int argc, char **argv, const llvm::ToolContext &) {
if (!MakeformatOutputPath.empty() && !MakeformatOutput.empty() &&
!HadErrors) {
+ llvm::SmallString<256> FullDepPath;
static std::mutex Lock;
// With compilation database, we may open different files
// concurrently or we may write the same file concurrently. So we
@@ -1039,16 +1041,37 @@ int clang_scan_deps_main(int argc, char **argv, const llvm::ToolContext &) {
static llvm::StringMap<llvm::raw_fd_ostream> OSs;
std::unique_lock<std::mutex> LockGuard(Lock);
- auto OSIter = OSs.find(MakeformatOutputPath);
+ if (llvm::sys::path::is_absolute(MakeformatOutputPath))
+ FullDepPath = MakeformatOutputPath;
+ else
+ llvm::sys::path::append(FullDepPath, CWD, MakeformatOutputPath);
+
+ if (llvm::StringRef Parent =
+ llvm::sys::path::parent_path(FullDepPath);
+ !Parent.empty()) {
+ if (std::error_code DirEC =
+ llvm::sys::fs::create_directories(Parent)) {
+ llvm::errs() << "Failed to create directory \"" << Parent
+ << "\" for P1689 make format output: "
+ << DirEC.message() << "\n";
+ HadErrors = true;
+ continue;
+ }
+ }
+
+ auto OSIter = OSs.find(FullDepPath);
if (OSIter == OSs.end()) {
std::error_code EC;
- OSIter = OSs.try_emplace(MakeformatOutputPath, MakeformatOutputPath,
- EC, llvm::sys::fs::OF_Text)
- .first;
- if (EC)
+ auto Emplaced = OSs.try_emplace(FullDepPath.str(), FullDepPath, EC,
+ llvm::sys::fs::OF_Text);
+ OSIter = Emplaced.first;
+ if (EC) {
+ OSs.erase(OSIter);
llvm::errs() << "Failed to open P1689 make format output file \""
- << MakeformatOutputPath << "\" for " << EC.message()
- << "\n";
+ << FullDepPath << "\" for " << EC.message() << "\n";
+ HadErrors = true;
+ continue;
+ }
}
SharedStream MakeformatOS(OSIter->second);
``````````
</details>
https://github.com/llvm/llvm-project/pull/194118
More information about the llvm-branch-commits
mailing list