[clang] [modules] Add diagnostic about performed input file validation when encounter unrecoverable changed input file. (PR #180899)
Volodymyr Sapsai via cfe-commits
cfe-commits at lists.llvm.org
Sat Feb 14 01:25:23 PST 2026
https://github.com/vsapsai updated https://github.com/llvm/llvm-project/pull/180899
>From ecc157d0da064e02ed4ebb14ef67a3b2c831f7e4 Mon Sep 17 00:00:00 2001
From: Volodymyr Sapsai <vsapsai at apple.com>
Date: Tue, 10 Feb 2026 22:32:14 -0800
Subject: [PATCH 1/6] [modules] Add diagnostic about performed input file
validation when encounter unrecoverable changed input file.
The expected behavior for implicitly built modules is to validate input
files and to rebuild a module if there are any input file changes. But if
for some reason a module hasn't been rebuilt, it is useful to know if
the validation has been done and what kind of validation.
The goal is to make investigations for fixes like
f2a3079a1b48033a92d0a7d9f03251ebeb4a0c30 and
ada79f4c2691ab6546d379a144377162fd4f5191 easier.
rdar://159857416
---
.../Basic/DiagnosticSerializationKinds.td | 4 ++++
.../include/clang/Serialization/ModuleFile.h | 23 +++++++++++++++++++
clang/lib/Serialization/ASTReader.cpp | 14 ++++++++++-
clang/test/Modules/module-file-modified.c | 1 +
4 files changed, 41 insertions(+), 1 deletion(-)
diff --git a/clang/include/clang/Basic/DiagnosticSerializationKinds.td b/clang/include/clang/Basic/DiagnosticSerializationKinds.td
index 229f0bacbd796..3edf5415809c0 100644
--- a/clang/include/clang/Basic/DiagnosticSerializationKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSerializationKinds.td
@@ -29,6 +29,10 @@ def note_ast_file_rebuild_required
: Note<"please rebuild precompiled file '%0'">;
def note_module_cache_path : Note<
"after modifying system headers, please delete the module cache at '%0'">;
+def note_ast_file_input_files_validation_status : Note<"input file validation "
+ "%select{has not been started|is disabled for this kind of module|"
+ "has already been done in the current build session|"
+ "has covered only user files|has covered all files}0">;
def err_ast_file_targetopt_mismatch : Error<
"precompiled file '%0' was compiled for the %1 '%2' but the current translation "
diff --git a/clang/include/clang/Serialization/ModuleFile.h b/clang/include/clang/Serialization/ModuleFile.h
index 783e2ba7a1f94..03015580217ef 100644
--- a/clang/include/clang/Serialization/ModuleFile.h
+++ b/clang/include/clang/Serialization/ModuleFile.h
@@ -120,6 +120,21 @@ class InputFile {
bool isNotFound() const { return Val.getInt() == NotFound; }
};
+/// Specifies the high-level result of validating input files.
+enum class InputFilesValidation {
+ /// Initial value, before the validation has been performed.
+ NotStarted = 0,
+ /// When the validation is disabled. For example, for a precompiled header.
+ Disabled,
+ /// When the validation is skipped because it was already done in the current
+ /// build session.
+ SkippedInBuildSession,
+ /// When the validation is done only for user files as an optimization.
+ UserFiles,
+ /// When the validation is done both for user files and system files.
+ AllFiles,
+};
+
/// Information about a module that has been loaded by the ASTReader.
///
/// Each instance of the Module class corresponds to a single AST file, which
@@ -276,6 +291,14 @@ class ModuleFile {
/// The time is specified in seconds since the start of the Epoch.
uint64_t InputFilesValidationTimestamp = 0;
+ /// Captures the high-level result of validating input files.
+ ///
+ /// Useful when encounter an invalid input file. This way can check what kind
+ /// of validation has been done already and can try to figure out why an
+ /// invalid file hasn't been discovered earlier.
+ InputFilesValidation InputFilesValidationStatus =
+ InputFilesValidation::NotStarted;
+
// === Source Locations ===
/// Cursor used to read source location entries.
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index f3902d57e3d1f..55efe355c433a 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -3000,6 +3000,8 @@ InputFile ASTReader::getInputFile(ModuleFile &F, unsigned ID, bool Complain) {
}
Diag(diag::note_ast_file_rebuild_required) << TopLevelASTFileName;
+ Diag(diag::note_ast_file_input_files_validation_status)
+ << F.InputFilesValidationStatus;
}
IsOutOfDate = true;
@@ -3228,10 +3230,18 @@ ASTReader::ReadControlBlock(ModuleFile &F,
// files.
unsigned N = ValidateSystemInputs ? NumInputs : NumUserInputs;
+ F.InputFilesValidationStatus = ValidateSystemInputs
+ ? InputFilesValidation::AllFiles
+ : InputFilesValidation::UserFiles;
if (HSOpts.ModulesValidateOncePerBuildSession &&
F.InputFilesValidationTimestamp > HSOpts.BuildSessionTimestamp &&
- F.Kind == MK_ImplicitModule)
+ F.Kind == MK_ImplicitModule) {
N = ForceValidateUserInputs ? NumUserInputs : 0;
+ F.InputFilesValidationStatus =
+ ForceValidateUserInputs
+ ? InputFilesValidation::UserFiles
+ : InputFilesValidation::SkippedInBuildSession;
+ }
if (N != 0)
Diag(diag::remark_module_validation)
@@ -3242,6 +3252,8 @@ ASTReader::ReadControlBlock(ModuleFile &F,
if (!IF.getFile() || IF.isOutOfDate())
return OutOfDate;
}
+ } else {
+ F.InputFilesValidationStatus = InputFilesValidation::Disabled;
}
if (Listener)
diff --git a/clang/test/Modules/module-file-modified.c b/clang/test/Modules/module-file-modified.c
index 1a02b3fa511b3..8ef574872b801 100644
--- a/clang/test/Modules/module-file-modified.c
+++ b/clang/test/Modules/module-file-modified.c
@@ -9,3 +9,4 @@
int foo = 0; // redefinition of 'foo'
// CHECK: fatal error: file {{.*}} has been modified since the module file {{.*}} was built
// CHECK: note: please rebuild precompiled file
+// CHECK: note: input file validation is disabled for this kind of module
>From 8332869c1db167c5b0b9bbdba3f1f157f5ff1848 Mon Sep 17 00:00:00 2001
From: Volodymyr Sapsai <vsapsai at gmail.com>
Date: Wed, 11 Feb 2026 12:56:37 -0800
Subject: [PATCH 2/6] Update clang/include/clang/Serialization/ModuleFile.h
Co-authored-by: Cyndy Ishida <cyndyishida at gmail.com>
---
clang/include/clang/Serialization/ModuleFile.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang/include/clang/Serialization/ModuleFile.h b/clang/include/clang/Serialization/ModuleFile.h
index 03015580217ef..767b17cb6df98 100644
--- a/clang/include/clang/Serialization/ModuleFile.h
+++ b/clang/include/clang/Serialization/ModuleFile.h
@@ -293,7 +293,7 @@ class ModuleFile {
/// Captures the high-level result of validating input files.
///
- /// Useful when encounter an invalid input file. This way can check what kind
+ /// Useful when encountering an invalid input file. This way, we can check what kind
/// of validation has been done already and can try to figure out why an
/// invalid file hasn't been discovered earlier.
InputFilesValidation InputFilesValidationStatus =
>From b2056bde8b639d2b6a95cb65cfaf46da9132c35d Mon Sep 17 00:00:00 2001
From: Volodymyr Sapsai <vsapsai at apple.com>
Date: Fri, 13 Feb 2026 21:47:48 -0800
Subject: [PATCH 3/6] Fix formatting and change /invalid/changed/ as it is more
correct and more specific.
---
clang/include/clang/Serialization/ModuleFile.h | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/clang/include/clang/Serialization/ModuleFile.h b/clang/include/clang/Serialization/ModuleFile.h
index 767b17cb6df98..519a74d920129 100644
--- a/clang/include/clang/Serialization/ModuleFile.h
+++ b/clang/include/clang/Serialization/ModuleFile.h
@@ -293,9 +293,9 @@ class ModuleFile {
/// Captures the high-level result of validating input files.
///
- /// Useful when encountering an invalid input file. This way, we can check what kind
- /// of validation has been done already and can try to figure out why an
- /// invalid file hasn't been discovered earlier.
+ /// Useful when encountering a changed input file. This way, we can check
+ /// what kind of validation has been done already and can try to figure out
+ /// why a changed file hasn't been discovered earlier.
InputFilesValidation InputFilesValidationStatus =
InputFilesValidation::NotStarted;
>From ffa2eb62c09eb28df1b847de01520232fe5ad4ad Mon Sep 17 00:00:00 2001
From: Volodymyr Sapsai <vsapsai at apple.com>
Date: Fri, 13 Feb 2026 21:48:40 -0800
Subject: [PATCH 4/6] s/module/precompiled file/
---
clang/include/clang/Basic/DiagnosticSerializationKinds.td | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang/include/clang/Basic/DiagnosticSerializationKinds.td b/clang/include/clang/Basic/DiagnosticSerializationKinds.td
index 3edf5415809c0..48872f1cef6d4 100644
--- a/clang/include/clang/Basic/DiagnosticSerializationKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSerializationKinds.td
@@ -30,7 +30,7 @@ def note_ast_file_rebuild_required
def note_module_cache_path : Note<
"after modifying system headers, please delete the module cache at '%0'">;
def note_ast_file_input_files_validation_status : Note<"input file validation "
- "%select{has not been started|is disabled for this kind of module|"
+ "%select{has not been started|was disabled for this kind of precompiled file|"
"has already been done in the current build session|"
"has covered only user files|has covered all files}0">;
>From a75e6b1efb9deb3f9d1d097541bc0e50a459776b Mon Sep 17 00:00:00 2001
From: Volodymyr Sapsai <vsapsai at apple.com>
Date: Fri, 13 Feb 2026 22:22:44 -0800
Subject: [PATCH 5/6] Introduce "earlier" in "earlier input file validation".
---
clang/include/clang/Basic/DiagnosticSerializationKinds.td | 6 +++---
clang/test/Modules/module-file-modified.c | 2 +-
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/clang/include/clang/Basic/DiagnosticSerializationKinds.td b/clang/include/clang/Basic/DiagnosticSerializationKinds.td
index 48872f1cef6d4..0029b5f0fd188 100644
--- a/clang/include/clang/Basic/DiagnosticSerializationKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSerializationKinds.td
@@ -29,9 +29,9 @@ def note_ast_file_rebuild_required
: Note<"please rebuild precompiled file '%0'">;
def note_module_cache_path : Note<
"after modifying system headers, please delete the module cache at '%0'">;
-def note_ast_file_input_files_validation_status : Note<"input file validation "
- "%select{has not been started|was disabled for this kind of precompiled file|"
- "has already been done in the current build session|"
+def note_ast_file_input_files_validation_status : Note<"earlier input file validation "
+ "%select{was not performed|was disabled for this kind of precompiled file|"
+ "was skipped for the current build session|"
"has covered only user files|has covered all files}0">;
def err_ast_file_targetopt_mismatch : Error<
diff --git a/clang/test/Modules/module-file-modified.c b/clang/test/Modules/module-file-modified.c
index 8ef574872b801..18d493a652eb5 100644
--- a/clang/test/Modules/module-file-modified.c
+++ b/clang/test/Modules/module-file-modified.c
@@ -9,4 +9,4 @@
int foo = 0; // redefinition of 'foo'
// CHECK: fatal error: file {{.*}} has been modified since the module file {{.*}} was built
// CHECK: note: please rebuild precompiled file
-// CHECK: note: input file validation is disabled for this kind of module
+// CHECK: note: earlier input file validation was disabled for this kind of precompiled file
>From 5616803dee6baeac5d3c1a98ccfccd534059adb1 Mon Sep 17 00:00:00 2001
From: Volodymyr Sapsai <vsapsai at apple.com>
Date: Fri, 13 Feb 2026 22:57:43 -0800
Subject: [PATCH 6/6] Change request to rebuild to use a passive voice, emit it
only when validation is disabled.
---
clang/include/clang/Basic/DiagnosticSerializationKinds.td | 2 +-
clang/lib/Serialization/ASTReader.cpp | 3 ++-
clang/test/Modules/module-file-modified.c | 2 +-
clang/test/Modules/validate-file-content.m | 2 +-
clang/test/PCH/modified-module-dependency.m | 2 +-
clang/test/PCH/validate-file-content.m | 2 +-
6 files changed, 7 insertions(+), 6 deletions(-)
diff --git a/clang/include/clang/Basic/DiagnosticSerializationKinds.td b/clang/include/clang/Basic/DiagnosticSerializationKinds.td
index 0029b5f0fd188..87d8cc5b48899 100644
--- a/clang/include/clang/Basic/DiagnosticSerializationKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSerializationKinds.td
@@ -26,7 +26,7 @@ def err_fe_pch_file_overridden : Error<
"file '%0' from the precompiled header has been overridden">;
def note_ast_file_required_by : Note<"'%0' required by '%1'">;
def note_ast_file_rebuild_required
- : Note<"please rebuild precompiled file '%0'">;
+ : Note<"precompiled file '%0' needs to be rebuilt">;
def note_module_cache_path : Note<
"after modifying system headers, please delete the module cache at '%0'">;
def note_ast_file_input_files_validation_status : Note<"earlier input file validation "
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index 55efe355c433a..d2bb99724dbf4 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -2999,7 +2999,8 @@ InputFile ASTReader::getInputFile(ModuleFile &F, unsigned ID, bool Complain) {
<< ImportStack[I - 1]->FileName << ImportStack[I]->FileName;
}
- Diag(diag::note_ast_file_rebuild_required) << TopLevelASTFileName;
+ if (F.InputFilesValidationStatus == InputFilesValidation::Disabled)
+ Diag(diag::note_ast_file_rebuild_required) << TopLevelASTFileName;
Diag(diag::note_ast_file_input_files_validation_status)
<< F.InputFilesValidationStatus;
}
diff --git a/clang/test/Modules/module-file-modified.c b/clang/test/Modules/module-file-modified.c
index 18d493a652eb5..c13fa0b3399e1 100644
--- a/clang/test/Modules/module-file-modified.c
+++ b/clang/test/Modules/module-file-modified.c
@@ -8,5 +8,5 @@
#include "a.h"
int foo = 0; // redefinition of 'foo'
// CHECK: fatal error: file {{.*}} has been modified since the module file {{.*}} was built
-// CHECK: note: please rebuild precompiled file
+// CHECK: note: precompiled file '{{.*}}m.pcm' needs to be rebuilt
// CHECK: note: earlier input file validation was disabled for this kind of precompiled file
diff --git a/clang/test/Modules/validate-file-content.m b/clang/test/Modules/validate-file-content.m
index 1eae7748165c1..6ea009139a026 100644
--- a/clang/test/Modules/validate-file-content.m
+++ b/clang/test/Modules/validate-file-content.m
@@ -27,5 +27,5 @@
// CHECK: file '[[M_H:.*[/\\]m\.h]]' has been modified since the precompiled header '[[A_PCH:.*[/\\]a\.pch]]' was built: content changed
// CHECK: '[[M_H]]' required by '[[M_PCM:.*[/\\]m.*\.pcm]]'
// CHECK: '[[M_PCM]]' required by '[[A_PCH]]'
-// CHECK: please rebuild precompiled file '[[A_PCH]]'
+// CHECK: earlier input file validation has covered only user files
// expected-no-diagnostics
diff --git a/clang/test/PCH/modified-module-dependency.m b/clang/test/PCH/modified-module-dependency.m
index bf93b53e2c152..6e52ac9cca0ec 100644
--- a/clang/test/PCH/modified-module-dependency.m
+++ b/clang/test/PCH/modified-module-dependency.m
@@ -17,4 +17,4 @@
// CHECK: file '[[TEST_H:.*[/\\]test\.h]]' has been modified since the precompiled header '[[PREFIX_PCH:.*[/\\]prefix\.pch]]' was built
// CHECK: '[[TEST_H]]' required by '[[TEST_PCM:.*[/\\]test\.pcm]]'
// CHECK: '[[TEST_PCM]]' required by '[[PREFIX_PCH]]'
-// CHECK: please rebuild precompiled file '[[PREFIX_PCH]]'
+// CHECK: earlier input file validation has covered only user files
diff --git a/clang/test/PCH/validate-file-content.m b/clang/test/PCH/validate-file-content.m
index 289dbff1a8c20..9624b65ca94ae 100644
--- a/clang/test/PCH/validate-file-content.m
+++ b/clang/test/PCH/validate-file-content.m
@@ -23,5 +23,5 @@
// RUN: FileCheck %s < %t/stderr
//
// CHECK: file '[[M_H:.*[/\\]m\.h]]' has been modified since the precompiled header '[[A_PCH:.*[/\\]a\.pch]]' was built: content changed
-// CHECK: please rebuild precompiled file '[[A_PCH]]'
+// CHECK: earlier input file validation has covered only user files
// expected-no-diagnostics
More information about the cfe-commits
mailing list