https://github.com/qiongsiwu created 
https://github.com/llvm/llvm-project/pull/128446

This PR explicitly sets `DebugCompilationDir` to the system's root directory if 
it is safe to ignore the current working directory. 

This fixes a problem where a PCM file's embedded debug information can lead to 
compilation failure. The compiler may have decided it is indeed safe to ignore 
the current working directory. In this case, the PCM file's content is 
functionally correct regardless of the current working directory because no 
inputs use relative paths (see 
https://github.com/llvm/llvm-project/pull/124786). However, a PCM may contain 
debug info. If debug info is requested, the compiler uses the current working 
directory value to set `DW_AT_comp_dir`.  This may lead to the following 
situation: 
1. Two different compilations need the same PCM file. 
2. The PCM file is compiled assuming a working directory, which is embedded in 
the debug info, but otherwise has no effect. 
3. The second compilation assumes a different working directory, hence expects 
an identically-sized pcm file. However, it cannot find such a PCM, because the 
existing PCM file has been compiled assuming a different `DW_AT_comp_dir `, 
which is embedded in the debug info. 

This PR resets the  `DebugCompilationDir` if it is functionally safe to ignore 
the working directory so the above situation is avoided, since all debug 
information will share the same working directory.

>From c8eda8b9192cf4bdad4121063336beeb14cbe689 Mon Sep 17 00:00:00 2001
From: Qiongsi Wu <qiongsi...@apple.com>
Date: Sun, 23 Feb 2025 16:47:18 -0800
Subject: [PATCH] Initial commit

---
 .../DependencyScanning/ModuleDepCollector.cpp | 17 +++++++++++++-
 clang/test/ClangScanDeps/modules-debug-dir.c  | 22 +++++++++++++++++++
 2 files changed, 38 insertions(+), 1 deletion(-)
 create mode 100644 clang/test/ClangScanDeps/modules-debug-dir.c

diff --git a/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp 
b/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp
index 1c5f4c4b50ab6..8a94535d3806c 100644
--- a/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp
+++ b/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp
@@ -492,8 +492,23 @@ static std::string getModuleContextHash(const ModuleDeps 
&MD,
   auto &FSOpts = const_cast<FileSystemOptions &>(CI.getFileSystemOpts());
   if (CWD && !IgnoreCWD)
     HashBuilder.add(*CWD);
-  else
+  else {
     FSOpts.WorkingDir.clear();
+    auto &CGOpts = const_cast<CodeGenOptions &>(CI.getCodeGenOpts());
+    if (CGOpts.DwarfVersion && CWD) {
+      // It is necessary to explicitly set the DebugCompilationDir
+      // to a common directory (e.g. root) if IgnoreCWD is true.
+      // When IgnoreCWD is true, the module's content should not depend
+      // on the current working directory. However, if dwarf information
+      // is needed (when CGOpts.DwarfVersion is non-zero), and if
+      // CGOpts.DebugCompilationDir is not explicitly set,
+      // the current working directory will be automatically embedded
+      // in the dwarf information in the pcm, contradicting the assumption
+      // that it is safe to ignore the CWD. Thus in such cases,
+      // CGOpts.DebugCompilationDir is explicitly set to a common directory.
+      CGOpts.DebugCompilationDir = llvm::sys::path::root_path(*CWD);
+    }
+  }
 
   // Hash the BuildInvocation without any input files.
   SmallString<0> ArgVec;
diff --git a/clang/test/ClangScanDeps/modules-debug-dir.c 
b/clang/test/ClangScanDeps/modules-debug-dir.c
new file mode 100644
index 0000000000000..580f72205e68f
--- /dev/null
+++ b/clang/test/ClangScanDeps/modules-debug-dir.c
@@ -0,0 +1,22 @@
+// RUN: rm -rf %t
+// RUN: split-file %s %t
+// RUN: sed -e "s|DIR|%/t|g" %t/cdb.json.in > %t/cdb.json
+// RUN: clang-scan-deps -compilation-database %t/cdb.json -format \
+// RUN:   experimental-full > %t/result.json
+
+//--- cdb.json.in
+[{
+  "directory": "DIR",
+  "command": "clang -g -fdebug-info-for-profiling DIR/tu.c -fmodules 
-fmodules-cache-path=DIR/cache -IDIR/include/ -o DIR/tu.o",
+  "file": "DIR/tu.c"
+}]
+
+//--- include/module.modulemap
+module mod {
+  header "mod.h"
+}
+
+//--- include/mod.h
+
+//--- tu.c
+#include "mod.h"

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

Reply via email to