[clang] [clang] Forward `-fvalidate-ast-input-files-content` when loading an AST dump (PR #196298)
Arseniy Zaostrovnykh via cfe-commits
cfe-commits at lists.llvm.org
Thu May 7 05:25:25 PDT 2026
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 <necto.ne at gmail.com>
Date: Thu, 7 May 2026 14:01:31 +0200
Subject: [PATCH 1/3] 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 83753d63db8230563f2203497b59b73c5a1782b1 Mon Sep 17 00:00:00 2001
From: Arseniy Zaostrovnykh <necto.ne at gmail.com>
Date: Thu, 7 May 2026 14:08:29 +0200
Subject: [PATCH 2/3] Forward ValidateASTInputFilesContent when importing AST
dumps
---
clang/lib/Frontend/ASTUnit.cpp | 8 +++++++-
clang/test/Analysis/ctu/reusable-pch.c | 10 +++++-----
2 files changed, 12 insertions(+), 6 deletions(-)
diff --git a/clang/lib/Frontend/ASTUnit.cpp b/clang/lib/Frontend/ASTUnit.cpp
index 05ae1f348f920..8003b72e0619d 100644
--- a/clang/lib/Frontend/ASTUnit.cpp
+++ b/clang/lib/Frontend/ASTUnit.cpp
@@ -780,11 +780,17 @@ 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=*/ false,
+ 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..92256b9f0156c 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 \
@@ -18,13 +19,12 @@
// 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: %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: %t/main.c
//--- main.c
// Without CTU, always_zero() has an unknown return value so no bug is found.
>From 6834caed3ec4e7a183fe6d489ed0f7b15fc8ff07 Mon Sep 17 00:00:00 2001
From: Arseniy Zaostrovnykh <necto.ne at gmail.com>
Date: Thu, 7 May 2026 14:24:34 +0200
Subject: [PATCH 3/3] [NFC] Fix the format
---
clang/lib/Frontend/ASTUnit.cpp | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/clang/lib/Frontend/ASTUnit.cpp b/clang/lib/Frontend/ASTUnit.cpp
index 8003b72e0619d..80e9af3ea3d89 100644
--- a/clang/lib/Frontend/ASTUnit.cpp
+++ b/clang/lib/Frontend/ASTUnit.cpp
@@ -787,10 +787,9 @@ std::unique_ptr<ASTUnit> ASTUnit::LoadFromASTFile(
*AST->CodeGenOpts, ArrayRef<std::shared_ptr<ModuleFileExtension>>(),
/*isysroot=*/"",
/*DisableValidationKind=*/disableValid, AllowASTWithCompilerErrors,
- /*AllowConfigurationMismatch=*/ false,
- /*ValidateSystemInputs=*/ false,
- /*ForceValidateUserInputs=*/ false,
- ValidateASTInputFilesContent);
+ /*AllowConfigurationMismatch=*/false,
+ /*ValidateSystemInputs=*/false,
+ /*ForceValidateUserInputs=*/false, 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.
More information about the cfe-commits
mailing list