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

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

>From 4d1ede2fadba0aa3b8d5e0cbb93281e075310c34 Mon Sep 17 00:00:00 2001
From: Qiongsi Wu <[email protected]>
Date: Thu, 29 Jan 2026 15:50:25 -0800
Subject: [PATCH] Store absolute paths of the input PCH in a PCH file.

---
 clang/lib/Serialization/ASTWriter.cpp       | 13 +++++++++++--
 clang/test/PCH/pch-input-path-independent.c | 19 +++++++++++++++++++
 2 files changed, 30 insertions(+), 2 deletions(-)
 create mode 100644 clang/test/PCH/pch-input-path-independent.c

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(); }

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to