https://github.com/necto updated 
https://github.com/llvm/llvm-project/pull/196298

>From fc1e8b138b8f7a826eb2d79789cb44c518be727a Mon Sep 17 00:00:00 2001
From: Arseniy Zaostrovnykh <[email protected]>
Date: Thu, 7 May 2026 14:01:31 +0200
Subject: [PATCH 01/10] Demonstrate CTU import failure when mtime is advanced

---
 clang/test/Analysis/ctu/reusable-pch.c | 42 ++++++++++++++++++++++++++
 1 file changed, 42 insertions(+)
 create mode 100644 clang/test/Analysis/ctu/reusable-pch.c

diff --git a/clang/test/Analysis/ctu/reusable-pch.c 
b/clang/test/Analysis/ctu/reusable-pch.c
new file mode 100644
index 0000000000000..6f42cd3c90097
--- /dev/null
+++ b/clang/test/Analysis/ctu/reusable-pch.c
@@ -0,0 +1,42 @@
+// RUN: rm -rf %t
+// RUN: mkdir -p %t
+// RUN: split-file %s %t
+
+// Step 1: Build PCH and defmap.
+// RUN: %clang_cc1 -x c -emit-pch -o %t/other.c.ast %t/other.c
+// RUN: %clang_extdef_map %t/other.c -- -c -x c > %t/externalDefMap.tmp.txt
+// RUN: sed 's| .*other\.c| other.c.ast|' %t/externalDefMap.tmp.txt > 
%t/externalDefMap.txt
+
+// Step 2: Run CTU using the PCH - the division by zero is found via inlining.
+// RUN: %clang_cc1 -analyze \
+// RUN:   -analyzer-checker=core \
+// RUN:   -analyzer-config experimental-enable-naive-ctu-analysis=true \
+// RUN:   -analyzer-config ctu-dir=%t \
+// RUN:   -verify %t/main.c
+
+// Step 3: Advance mtime of the source from which PCH was built.
+// RUN: %python -c "import os, sys, time; os.utime(sys.argv[1], (time.time() + 
120, time.time() + 120))" %t/other.c
+
+// Step 4: Run CTU using the now-stale PCH - it breaks.
+// RUN: not %clang_cc1 -analyze \
+// RUN:   -analyzer-checker=core \
+// RUN:   -analyzer-config experimental-enable-naive-ctu-analysis=true \
+// RUN:   -analyzer-config ctu-dir=%t \
+// RUN:   %t/main.c 2>&1 | FileCheck --check-prefix=BREAKS %s
+
+// BREAKS: file '{{.*}}other.c' has been modified since the precompiled file 
'{{.*}}other.c.ast' was built
+
+//--- main.c
+// Without CTU, always_zero() has an unknown return value so no bug is found.
+// With CTU, always_zero() is inlined and its return value (0) is known,
+// exposing the division by zero.
+
+int always_zero(void);
+
+void f(void) {
+  int x = always_zero();
+  (void)(1 / x); // expected-warning{{Division by zero}}
+}
+
+//--- other.c
+int always_zero(void) { return 0; }

>From f7ddef412640dff8f054e8b786d0181a8699a6d6 Mon Sep 17 00:00:00 2001
From: Arseniy Zaostrovnykh <[email protected]>
Date: Thu, 7 May 2026 14:08:29 +0200
Subject: [PATCH 02/10] Forward ValidateASTInputFilesContent when importing AST
 dumps

---
 clang/lib/Frontend/ASTUnit.cpp         |  7 ++++++-
 clang/test/Analysis/ctu/reusable-pch.c | 12 ++++++------
 2 files changed, 12 insertions(+), 7 deletions(-)

diff --git a/clang/lib/Frontend/ASTUnit.cpp b/clang/lib/Frontend/ASTUnit.cpp
index 05ae1f348f920..df6f85560227f 100644
--- a/clang/lib/Frontend/ASTUnit.cpp
+++ b/clang/lib/Frontend/ASTUnit.cpp
@@ -780,11 +780,16 @@ std::unique_ptr<ASTUnit> ASTUnit::LoadFromASTFile(
       DisableValidationForModuleKind::None;
   if (::getenv("LIBCLANG_DISABLE_PCH_VALIDATION"))
     disableValid = DisableValidationForModuleKind::All;
+  bool ValidateASTInputFilesContent = HSOpts.ValidateASTInputFilesContent;
+
   AST->Reader = llvm::makeIntrusiveRefCnt<ASTReader>(
       *AST->PP, *AST->ModCache, AST->Ctx.get(), PCHContainerRdr,
       *AST->CodeGenOpts, ArrayRef<std::shared_ptr<ModuleFileExtension>>(),
       /*isysroot=*/"",
-      /*DisableValidationKind=*/disableValid, AllowASTWithCompilerErrors);
+      /*DisableValidationKind=*/disableValid, AllowASTWithCompilerErrors,
+      /*AllowConfigurationMismatch=*/false,
+      /*ValidateSystemInputs=*/false,
+      /*ForceValidateUserInputs=*/true, ValidateASTInputFilesContent);
 
   // Attach the AST reader to the AST context as an external AST source, so 
that
   // declarations will be deserialized from the AST file as needed.
diff --git a/clang/test/Analysis/ctu/reusable-pch.c 
b/clang/test/Analysis/ctu/reusable-pch.c
index 6f42cd3c90097..1490894f061a1 100644
--- a/clang/test/Analysis/ctu/reusable-pch.c
+++ b/clang/test/Analysis/ctu/reusable-pch.c
@@ -3,12 +3,13 @@
 // RUN: split-file %s %t
 
 // Step 1: Build PCH and defmap.
-// RUN: %clang_cc1 -x c -emit-pch -o %t/other.c.ast %t/other.c
+// RUN: %clang_cc1 -x c -emit-pch -fvalidate-ast-input-files-content -o 
%t/other.c.ast %t/other.c
 // RUN: %clang_extdef_map %t/other.c -- -c -x c > %t/externalDefMap.tmp.txt
 // RUN: sed 's| .*other\.c| other.c.ast|' %t/externalDefMap.tmp.txt > 
%t/externalDefMap.txt
 
 // Step 2: Run CTU using the PCH - the division by zero is found via inlining.
 // RUN: %clang_cc1 -analyze \
+// RUN:   -fvalidate-ast-input-files-content \
 // RUN:   -analyzer-checker=core \
 // RUN:   -analyzer-config experimental-enable-naive-ctu-analysis=true \
 // RUN:   -analyzer-config ctu-dir=%t \
@@ -17,14 +18,13 @@
 // Step 3: Advance mtime of the source from which PCH was built.
 // RUN: %python -c "import os, sys, time; os.utime(sys.argv[1], (time.time() + 
120, time.time() + 120))" %t/other.c
 
-// Step 4: Run CTU using the now-stale PCH - it breaks.
-// RUN: not %clang_cc1 -analyze \
+// Step 4: Run CTU using the "stale" PCH
+// RUN: %clang_cc1 -analyze \
+// RUN:   -fvalidate-ast-input-files-content \
 // RUN:   -analyzer-checker=core \
 // RUN:   -analyzer-config experimental-enable-naive-ctu-analysis=true \
 // RUN:   -analyzer-config ctu-dir=%t \
-// RUN:   %t/main.c 2>&1 | FileCheck --check-prefix=BREAKS %s
-
-// BREAKS: file '{{.*}}other.c' has been modified since the precompiled file 
'{{.*}}other.c.ast' was built
+// RUN:   -verify %t/main.c
 
 //--- main.c
 // Without CTU, always_zero() has an unknown return value so no bug is found.

>From 2103ae99e36b37080a7a4ef3b70d1a4d2514c14d Mon Sep 17 00:00:00 2001
From: Arseniy Zaostrovnykh <[email protected]>
Date: Mon, 11 May 2026 12:26:53 +0200
Subject: [PATCH 03/10] Update clang/test/Analysis/ctu/reusable-pch.c
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Co-authored-by: Balázs Benics <[email protected]>
---
 clang/test/Analysis/ctu/reusable-pch.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/test/Analysis/ctu/reusable-pch.c 
b/clang/test/Analysis/ctu/reusable-pch.c
index 1490894f061a1..98d6f2c8129cc 100644
--- a/clang/test/Analysis/ctu/reusable-pch.c
+++ b/clang/test/Analysis/ctu/reusable-pch.c
@@ -18,7 +18,7 @@
 // Step 3: Advance mtime of the source from which PCH was built.
 // RUN: %python -c "import os, sys, time; os.utime(sys.argv[1], (time.time() + 
120, time.time() + 120))" %t/other.c
 
-// Step 4: Run CTU using the "stale" PCH
+// Step 4: Run CTU using the "stale" PCH, and it should still load it and find 
the division by zero bug.
 // RUN: %clang_cc1 -analyze \
 // RUN:   -fvalidate-ast-input-files-content \
 // RUN:   -analyzer-checker=core \

>From 50654dcfef54806eee91488bb14e4cc678f55562 Mon Sep 17 00:00:00 2001
From: Arseniy Zaostrovnykh <[email protected]>
Date: Mon, 11 May 2026 13:33:35 +0200
Subject: [PATCH 04/10] [NFC] Inline the option

---
 clang/lib/Frontend/ASTUnit.cpp | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/clang/lib/Frontend/ASTUnit.cpp b/clang/lib/Frontend/ASTUnit.cpp
index df6f85560227f..73f6319f324ee 100644
--- a/clang/lib/Frontend/ASTUnit.cpp
+++ b/clang/lib/Frontend/ASTUnit.cpp
@@ -780,7 +780,6 @@ std::unique_ptr<ASTUnit> ASTUnit::LoadFromASTFile(
       DisableValidationForModuleKind::None;
   if (::getenv("LIBCLANG_DISABLE_PCH_VALIDATION"))
     disableValid = DisableValidationForModuleKind::All;
-  bool ValidateASTInputFilesContent = HSOpts.ValidateASTInputFilesContent;
 
   AST->Reader = llvm::makeIntrusiveRefCnt<ASTReader>(
       *AST->PP, *AST->ModCache, AST->Ctx.get(), PCHContainerRdr,
@@ -789,7 +788,7 @@ std::unique_ptr<ASTUnit> ASTUnit::LoadFromASTFile(
       /*DisableValidationKind=*/disableValid, AllowASTWithCompilerErrors,
       /*AllowConfigurationMismatch=*/false,
       /*ValidateSystemInputs=*/false,
-      /*ForceValidateUserInputs=*/true, ValidateASTInputFilesContent);
+      /*ForceValidateUserInputs=*/true, HSOpts.ValidateASTInputFilesContent);
 
   // Attach the AST reader to the AST context as an external AST source, so 
that
   // declarations will be deserialized from the AST file as needed.

>From 67c7da349552c38cc2c5d69362d0f1c7bc4a4f17 Mon Sep 17 00:00:00 2001
From: Arseniy Zaostrovnykh <[email protected]>
Date: Mon, 11 May 2026 13:33:48 +0200
Subject: [PATCH 05/10] [NFC] Use clang_analyze_cc1

---
 clang/test/Analysis/ctu/reusable-pch.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/clang/test/Analysis/ctu/reusable-pch.c 
b/clang/test/Analysis/ctu/reusable-pch.c
index 98d6f2c8129cc..2d68cb1924ae7 100644
--- a/clang/test/Analysis/ctu/reusable-pch.c
+++ b/clang/test/Analysis/ctu/reusable-pch.c
@@ -8,7 +8,7 @@
 // RUN: sed 's| .*other\.c| other.c.ast|' %t/externalDefMap.tmp.txt > 
%t/externalDefMap.txt
 
 // Step 2: Run CTU using the PCH - the division by zero is found via inlining.
-// RUN: %clang_cc1 -analyze \
+// RUN: %clang_analyze_cc1 \
 // RUN:   -fvalidate-ast-input-files-content \
 // RUN:   -analyzer-checker=core \
 // RUN:   -analyzer-config experimental-enable-naive-ctu-analysis=true \
@@ -18,8 +18,9 @@
 // Step 3: Advance mtime of the source from which PCH was built.
 // RUN: %python -c "import os, sys, time; os.utime(sys.argv[1], (time.time() + 
120, time.time() + 120))" %t/other.c
 
+// Step 4: Run CTU using the "stale" PCH
 // Step 4: Run CTU using the "stale" PCH, and it should still load it and find 
the division by zero bug.
-// RUN: %clang_cc1 -analyze \
+// RUN: %clang_analyze_cc1 \
 // RUN:   -fvalidate-ast-input-files-content \
 // RUN:   -analyzer-checker=core \
 // RUN:   -analyzer-config experimental-enable-naive-ctu-analysis=true \

>From 932842760a1744a002cf32fe7e6e120c0276ec73 Mon Sep 17 00:00:00 2001
From: Arseniy Zaostrovnykh <[email protected]>
Date: Mon, 11 May 2026 13:42:01 +0200
Subject: [PATCH 06/10] Use touch instead of a python script

---
 clang/test/Analysis/ctu/reusable-pch.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/clang/test/Analysis/ctu/reusable-pch.c 
b/clang/test/Analysis/ctu/reusable-pch.c
index 2d68cb1924ae7..bad15a99887eb 100644
--- a/clang/test/Analysis/ctu/reusable-pch.c
+++ b/clang/test/Analysis/ctu/reusable-pch.c
@@ -15,8 +15,8 @@
 // RUN:   -analyzer-config ctu-dir=%t \
 // RUN:   -verify %t/main.c
 
-// Step 3: Advance mtime of the source from which PCH was built.
-// RUN: %python -c "import os, sys, time; os.utime(sys.argv[1], (time.time() + 
120, time.time() + 120))" %t/other.c
+// Step 3: Set mtime of the source from which PCH was built to the year 3000 
(way in the future).
+// RUN: touch -t 300001010000 %t/other.c
 
 // Step 4: Run CTU using the "stale" PCH
 // Step 4: Run CTU using the "stale" PCH, and it should still load it and find 
the division by zero bug.

>From 0da55dc73c71440272bea37436f2207e48082403 Mon Sep 17 00:00:00 2001
From: Arseniy Zaostrovnykh <[email protected]>
Date: Mon, 11 May 2026 13:48:22 +0200
Subject: [PATCH 07/10] [NFC] use `sed -e` explicitly

---
 clang/test/Analysis/ctu/reusable-pch.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/test/Analysis/ctu/reusable-pch.c 
b/clang/test/Analysis/ctu/reusable-pch.c
index bad15a99887eb..5a7aaeb69ff04 100644
--- a/clang/test/Analysis/ctu/reusable-pch.c
+++ b/clang/test/Analysis/ctu/reusable-pch.c
@@ -5,7 +5,7 @@
 // Step 1: Build PCH and defmap.
 // RUN: %clang_cc1 -x c -emit-pch -fvalidate-ast-input-files-content -o 
%t/other.c.ast %t/other.c
 // RUN: %clang_extdef_map %t/other.c -- -c -x c > %t/externalDefMap.tmp.txt
-// RUN: sed 's| .*other\.c| other.c.ast|' %t/externalDefMap.tmp.txt > 
%t/externalDefMap.txt
+// RUN: sed -e 's| .*other\.c| other.c.ast|' %t/externalDefMap.tmp.txt > 
%t/externalDefMap.txt
 
 // Step 2: Run CTU using the PCH - the division by zero is found via inlining.
 // RUN: %clang_analyze_cc1 \

>From 8dfb808ae52c7471f6a703d5c5b0374bfd203513 Mon Sep 17 00:00:00 2001
From: Arseniy Zaostrovnykh <[email protected]>
Date: Mon, 11 May 2026 13:53:02 +0200
Subject: [PATCH 08/10] Update clang/test/Analysis/ctu/reusable-pch.c
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Co-authored-by: Balázs Benics <[email protected]>
---
 clang/test/Analysis/ctu/reusable-pch.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/clang/test/Analysis/ctu/reusable-pch.c 
b/clang/test/Analysis/ctu/reusable-pch.c
index 5a7aaeb69ff04..d01fb7df2b7cd 100644
--- a/clang/test/Analysis/ctu/reusable-pch.c
+++ b/clang/test/Analysis/ctu/reusable-pch.c
@@ -18,7 +18,6 @@
 // Step 3: Set mtime of the source from which PCH was built to the year 3000 
(way in the future).
 // RUN: touch -t 300001010000 %t/other.c
 
-// Step 4: Run CTU using the "stale" PCH
 // Step 4: Run CTU using the "stale" PCH, and it should still load it and find 
the division by zero bug.
 // RUN: %clang_analyze_cc1 \
 // RUN:   -fvalidate-ast-input-files-content \

>From 4abf54520d484131ad01216ee95074344527c8af Mon Sep 17 00:00:00 2001
From: Arseniy Zaostrovnykh <[email protected]>
Date: Mon, 11 May 2026 13:53:48 +0200
Subject: [PATCH 09/10] [NFC] Remove uncalled-for empty line

---
 clang/lib/Frontend/ASTUnit.cpp | 1 -
 1 file changed, 1 deletion(-)

diff --git a/clang/lib/Frontend/ASTUnit.cpp b/clang/lib/Frontend/ASTUnit.cpp
index 73f6319f324ee..83fe82365b008 100644
--- a/clang/lib/Frontend/ASTUnit.cpp
+++ b/clang/lib/Frontend/ASTUnit.cpp
@@ -780,7 +780,6 @@ std::unique_ptr<ASTUnit> ASTUnit::LoadFromASTFile(
       DisableValidationForModuleKind::None;
   if (::getenv("LIBCLANG_DISABLE_PCH_VALIDATION"))
     disableValid = DisableValidationForModuleKind::All;
-
   AST->Reader = llvm::makeIntrusiveRefCnt<ASTReader>(
       *AST->PP, *AST->ModCache, AST->Ctx.get(), PCHContainerRdr,
       *AST->CodeGenOpts, ArrayRef<std::shared_ptr<ModuleFileExtension>>(),

>From 191bb9fd03c3910de8ffae2a4537425cdeb3bb0c Mon Sep 17 00:00:00 2001
From: Arseniy Zaostrovnykh <[email protected]>
Date: Mon, 11 May 2026 14:06:37 +0200
Subject: [PATCH 10/10] Add a negative test case

---
 clang/test/Analysis/ctu/reusable-pch.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/clang/test/Analysis/ctu/reusable-pch.c 
b/clang/test/Analysis/ctu/reusable-pch.c
index d01fb7df2b7cd..87ad3845317af 100644
--- a/clang/test/Analysis/ctu/reusable-pch.c
+++ b/clang/test/Analysis/ctu/reusable-pch.c
@@ -26,11 +26,23 @@
 // RUN:   -analyzer-config ctu-dir=%t \
 // RUN:   -verify %t/main.c
 
+// Step 4': Run without content validation: CTU import failure
+// RUN: not %clang_analyze_cc1 \
+// RUN:   -analyzer-checker=core \
+// RUN:   -analyzer-config experimental-enable-naive-ctu-analysis=true \
+// RUN:   -analyzer-config ctu-dir=%t \
+// RUN:   -verify %t/main.c 2>&1 | FileCheck %s
+
 //--- main.c
 // Without CTU, always_zero() has an unknown return value so no bug is found.
 // With CTU, always_zero() is inlined and its return value (0) is known,
 // exposing the division by zero.
 
+// CHECK: fatal error: file '{{.*}}/other.c' has been modified since the 
precompiled file '{{.*}}/other.c.ast' was built
+// CHECK: note: mtime changed from expected
+// CHECK: note: earlier input file validation has covered only user files
+// CHECK: import of an external symbol for CTU failed: Failed to load external 
AST source.
+
 int always_zero(void);
 
 void f(void) {

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

Reply via email to