[clang] [clang] Store the Input PCH Path Using Absolute Paths in a PCH (PR #178781)
via cfe-commits
cfe-commits at lists.llvm.org
Thu Jan 29 15:55:19 PST 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang-modules
Author: Qiongsi Wu (qiongsiwu)
<details>
<summary>Changes</summary>
When a PCH file includes another PCH file, the ASTWriter did not normalize the input PCH's path. This leads to a situation where the final PCH can be different depending on whether the input PCH is passed using relative path or absolute path.
This PR corrects the ASTWriter, so it always normalize the input PCH's path to an absolute path.
rdar://168596546
---
Full diff: https://github.com/llvm/llvm-project/pull/178781.diff
2 Files Affected:
- (modified) clang/lib/Serialization/ASTWriter.cpp (+11-2)
- (added) clang/test/PCH/pch-input-path-independent.c (+19)
``````````diff
diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp
index 3e10bbfedfe65..ded22300954c3 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -1752,7 +1752,10 @@ void ASTWriter::WriteControlBlock(Preprocessor &PP, StringRef isysroot) {
Record.push_back(PPOpts.UsePredefines);
// Detailed record is important since it is used for the module cache hash.
Record.push_back(PPOpts.DetailedRecord);
- AddString(PPOpts.ImplicitPCHInclude, Record);
+ if (PPOpts.ImplicitPCHInclude.empty())
+ AddString(PPOpts.ImplicitPCHInclude, Record);
+ else
+ AddPath(PPOpts.ImplicitPCHInclude, Record);
Record.push_back(static_cast<unsigned>(PPOpts.ObjCXXARCStandardLibrary));
Stream.EmitRecord(PREPROCESSOR_OPTIONS, Record);
@@ -6115,7 +6118,13 @@ ASTFileSignature ASTWriter::WriteASTCore(Sema *SemaPtr, StringRef isysroot,
endian::Writer LE(Out, llvm::endianness::little);
LE.write<uint8_t>(static_cast<uint8_t>(M.Kind));
- StringRef Name = M.isModule() ? M.ModuleName : M.FileName;
+ SmallString<128> Name;
+ if (M.isModule())
+ Name = M.ModuleName;
+ else {
+ Name = M.FileName;
+ PreparePathForOutput(Name);
+ }
LE.write<uint16_t>(Name.size());
Out.write(Name.data(), Name.size());
diff --git a/clang/test/PCH/pch-input-path-independent.c b/clang/test/PCH/pch-input-path-independent.c
new file mode 100644
index 0000000000000..357e903efc170
--- /dev/null
+++ b/clang/test/PCH/pch-input-path-independent.c
@@ -0,0 +1,19 @@
+// Tests that when PCHs are chained, the dependent PCHs produced are identical
+// wheter the input PCH is specified through a relative path or an absolute path.
+
+// RUN: rm -rf %t
+// RUN: split-file %s %t
+// RUN: cd %t
+// RUN: %clang_cc1 -triple x86_64-apple-macos11 -emit-pch h1.h -o %t/h1.h.pch
+// RUN: %clang_cc1 -triple x86_64-apple-macos11 -emit-pch bridging.h \
+// RUN: -o %t/bridging1.h.pch -include-pch %t/h1.h.pch
+// RUN: %clang_cc1 -triple x86_64-apple-macos11 -emit-pch bridging.h \
+// RUN: -o %t/bridging2.h.pch -include-pch ./h1.h.pch
+
+// RUN: diff %t/bridging1.h.pch %t/bridging2.h.pch
+
+//--- h1.h
+int bar1() { return 42; }
+
+//--- bridging.h
+int bar() { return bar1(); }
``````````
</details>
https://github.com/llvm/llvm-project/pull/178781
More information about the cfe-commits
mailing list