[clang] [Modules] Enrich diags for out of date module dependencies (PR #190203)
Cyndy Ishida via cfe-commits
cfe-commits at lists.llvm.org
Thu Apr 2 09:01:25 PDT 2026
https://github.com/cyndyishida created https://github.com/llvm/llvm-project/pull/190203
Replace the opaque ErrorStr parameter in `ModuleManager::addModule` with a structured object that carries specific information for reporting. This allows the diagnostics to emit targeted notes instead of a single error string appended to the main diagnostic. Information that is relevant but is tied to implementation details of the compilation is reported as notes (e.g. signature mismatches)
>From dbba7298c0c2bd088dd956db7715cfd8e7844e66 Mon Sep 17 00:00:00 2001
From: Cyndy Ishida <cyndy_ishida at apple.com>
Date: Tue, 24 Mar 2026 08:14:56 -0700
Subject: [PATCH] [Modules] Enrich diags for out of date module deps
Replace the opaque std::string ErrorStr parameter in `ModuleManager::addModule` with a structured object that carries specific information for reporting.
This allows the diagnostics to emit targeted notes instead of a single error string appended to the main diagnostic. Information that is relevant but is tied to implementation details of the compilation is reported as notes (e.g. signature mismatches)
---
.../Basic/DiagnosticSerializationKinds.td | 8 +-
.../include/clang/Serialization/ModuleFile.h | 13 +++
.../clang/Serialization/ModuleManager.h | 82 +++++++++++-----
clang/lib/Serialization/ASTReader.cpp | 51 +++++-----
clang/lib/Serialization/ModuleManager.cpp | 98 +++++++++++--------
.../modules-pch-signature-mismatch.c | 62 ++++++++++++
clang/test/Modules/explicit-build.cpp | 6 +-
clang/test/Modules/invalid-module-dep.c | 2 +
8 files changed, 226 insertions(+), 96 deletions(-)
create mode 100644 clang/test/ClangScanDeps/modules-pch-signature-mismatch.c
diff --git a/clang/include/clang/Basic/DiagnosticSerializationKinds.td b/clang/include/clang/Basic/DiagnosticSerializationKinds.td
index 475c19957c4be..5c74caf010ad9 100644
--- a/clang/include/clang/Basic/DiagnosticSerializationKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSerializationKinds.td
@@ -78,10 +78,14 @@ def err_ast_file_with_compiler_errors : Error<
def err_module_file_conflict : Error<
"module '%0' is defined in both '%1' and '%2'">, DefaultFatal;
def err_ast_file_not_found : Error<
- "%select{PCH|module|precompiled}0 file '%1' not found%select{|: %3}2">, DefaultFatal;
+ "%select{PCH|module|precompiled}0 file '%1' not found">, DefaultFatal;
+def note_ast_file_buffer_failed : Note<
+ "unable to load buffer for precompiled file: %0">;
+def note_ast_file_signature_failed : Note<
+ "unable to verify precompiled file signature: %0">;
def err_ast_file_out_of_date : Error<
"%select{PCH|module|precompiled}0 file '%1' is out of date and "
- "needs to be rebuilt%select{|: %3}2">, DefaultFatal;
+ "needs to be rebuilt">, DefaultFatal;
def err_ast_file_invalid : Error<
"file '%1' is not a valid %select{PCH|module|precompiled}0 file: %2">, DefaultFatal;
def note_module_file_imported_by : Note<
diff --git a/clang/include/clang/Serialization/ModuleFile.h b/clang/include/clang/Serialization/ModuleFile.h
index 303bd65a8aad0..3dfbf4de96355 100644
--- a/clang/include/clang/Serialization/ModuleFile.h
+++ b/clang/include/clang/Serialization/ModuleFile.h
@@ -32,6 +32,7 @@
#include <cassert>
#include <cstdint>
#include <memory>
+#include <optional>
#include <string>
#include <vector>
@@ -120,6 +121,18 @@ class InputFile {
bool isNotFound() const { return Val.getInt() == NotFound; }
};
+/// Describes a single change detected in a module file or input file.
+struct Change {
+ enum ModificationKind {
+ Size,
+ ModTime,
+ Content,
+ None,
+ } Kind;
+ std::optional<int64_t> Old = std::nullopt;
+ std::optional<int64_t> New = std::nullopt;
+};
+
/// Specifies the high-level result of validating input files.
enum class InputFilesValidation {
/// Initial value, before the validation has been performed.
diff --git a/clang/include/clang/Serialization/ModuleManager.h b/clang/include/clang/Serialization/ModuleManager.h
index 1ef9aeee7e1fd..87aeafe61ee79 100644
--- a/clang/include/clang/Serialization/ModuleManager.h
+++ b/clang/include/clang/Serialization/ModuleManager.h
@@ -42,6 +42,53 @@ class PCHContainerReader;
namespace serialization {
+/// The result of attempting to add a new module.
+class AddModuleResult {
+public:
+ enum Kind {
+ /// The module file had already been loaded.
+ AlreadyLoaded,
+ /// The module file was just loaded in response to this call.
+ NewlyLoaded,
+ /// The module file is missing.
+ Missing,
+ /// The module file is out-of-date.
+ OutOfDate
+ };
+ Kind K;
+
+ ModuleFile *getModule() const { return Module; }
+
+ StringRef getBufferError() const {
+ assert(K == Missing && !Module);
+ return BufferError;
+ }
+
+ const SmallVector<Change, 2> &getChanges() const {
+ assert(K == OutOfDate && !Module);
+ return Changes;
+ }
+
+ InputFilesValidation getValidationStatus() const {
+ assert(K == OutOfDate && !Module);
+ return ValidationStatus;
+ }
+
+ StringRef getSignatureError() const {
+ assert(K == OutOfDate && !Module);
+ return SignatureError;
+ }
+
+private:
+ friend class ModuleManager;
+
+ ModuleFile *Module = nullptr;
+ SmallVector<Change, 2> Changes;
+ InputFilesValidation ValidationStatus = InputFilesValidation::NotStarted;
+ std::string BufferError;
+ std::string SignatureError;
+};
+
/// Manages the set of modules loaded by an AST reader.
class ModuleManager {
/// The chain of AST files, in the order in which we started to load
@@ -96,6 +143,13 @@ class ModuleManager {
/// just an non-owning pointer.
GlobalModuleIndex *GlobalIndex = nullptr;
+ bool isModuleFileOutOfDate(off_t Size, time_t ModTime, off_t ExpectedSize,
+ time_t ExpectedModTime, AddModuleResult &Result);
+
+ bool checkSignature(ASTFileSignature Signature,
+ ASTFileSignature ExpectedSignature,
+ AddModuleResult &Result);
+
/// State used by the "visit" operation to avoid malloc traffic in
/// calls to visit().
struct VisitState {
@@ -187,21 +241,6 @@ class ModuleManager {
/// Number of modules loaded
unsigned size() const { return Chain.size(); }
- /// The result of attempting to add a new module.
- enum AddModuleResult {
- /// The module file had already been loaded.
- AlreadyLoaded,
-
- /// The module file was just loaded in response to this call.
- NewlyLoaded,
-
- /// The module file is missing.
- Missing,
-
- /// The module file is out-of-date.
- OutOfDate
- };
-
using ASTFileSignatureReader = ASTFileSignature (*)(StringRef);
/// Attempts to create a new module and add it to the list of known
@@ -230,21 +269,14 @@ class ModuleManager {
/// \param ReadSignature Reads the signature from an AST file without actually
/// loading it.
///
- /// \param Module A pointer to the module file if the module was successfully
- /// loaded.
- ///
- /// \param ErrorStr Will be set to a non-empty string if any errors occurred
- /// while trying to load the module.
- ///
- /// \return A pointer to the module that corresponds to this file name,
- /// and a value indicating whether the module was loaded.
+ /// \return The result of attempting to add the module, including a pointer
+ /// to the module file if successfully loaded.
AddModuleResult addModule(ModuleFileName FileName, ModuleKind Type,
SourceLocation ImportLoc, ModuleFile *ImportedBy,
unsigned Generation, off_t ExpectedSize,
time_t ExpectedModTime,
ASTFileSignature ExpectedSignature,
- ASTFileSignatureReader ReadSignature,
- ModuleFile *&Module, std::string &ErrorStr);
+ ASTFileSignatureReader ReadSignature);
/// Remove the modules starting from First (to the end).
void removeModules(ModuleIterator First);
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index 4ecdb563a1de2..a41149658206f 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -2910,16 +2910,6 @@ InputFile ASTReader::getInputFile(ModuleFile &F, unsigned ID, bool Complain) {
}
}
- struct Change {
- enum ModificationKind {
- Size,
- ModTime,
- Content,
- None,
- } Kind;
- std::optional<int64_t> Old = std::nullopt;
- std::optional<int64_t> New = std::nullopt;
- };
auto HasInputContentChanged = [&](Change OriginalChange) {
assert(ValidateASTInputFilesContent &&
"We should only check the content of the inputs with "
@@ -5222,26 +5212,24 @@ ASTReader::ASTReadResult ASTReader::ReadASTCore(
ModuleFile *ImportedBy, SmallVectorImpl<ImportedModule> &Loaded,
off_t ExpectedSize, time_t ExpectedModTime,
ASTFileSignature ExpectedSignature, unsigned ClientLoadCapabilities) {
- ModuleFile *M;
- std::string ErrorStr;
- ModuleManager::AddModuleResult AddResult
- = ModuleMgr.addModule(FileName, Type, ImportLoc, ImportedBy,
- getGeneration(), ExpectedSize, ExpectedModTime,
- ExpectedSignature, readASTFileSignature,
- M, ErrorStr);
-
- switch (AddResult) {
- case ModuleManager::AlreadyLoaded:
+ auto Result = ModuleMgr.addModule(
+ FileName, Type, ImportLoc, ImportedBy, getGeneration(), ExpectedSize,
+ ExpectedModTime, ExpectedSignature, readASTFileSignature);
+ ModuleFile *M = Result.getModule();
+
+ switch (Result.K) {
+ case AddModuleResult::AlreadyLoaded: {
Diag(diag::remark_module_import)
<< M->ModuleName << M->FileName << (ImportedBy ? true : false)
<< (ImportedBy ? StringRef(ImportedBy->ModuleName) : StringRef());
return Success;
+ }
- case ModuleManager::NewlyLoaded:
+ case AddModuleResult::NewlyLoaded:
// Load module file below.
break;
- case ModuleManager::Missing:
+ case AddModuleResult::Missing:
// The module file was missing; if the client can handle that, return
// it.
if (ClientLoadCapabilities & ARR_Missing)
@@ -5249,11 +5237,12 @@ ASTReader::ASTReadResult ASTReader::ReadASTCore(
// Otherwise, return an error.
Diag(diag::err_ast_file_not_found)
- << moduleKindForDiagnostic(Type) << FileName << !ErrorStr.empty()
- << ErrorStr;
+ << moduleKindForDiagnostic(Type) << FileName;
+ if (!Result.getBufferError().empty())
+ Diag(diag::note_ast_file_buffer_failed) << Result.getBufferError();
return Failure;
- case ModuleManager::OutOfDate:
+ case AddModuleResult::OutOfDate:
// We couldn't load the module file because it is out-of-date. If the
// client can handle out-of-date, return it.
if (ClientLoadCapabilities & ARR_OutOfDate)
@@ -5261,8 +5250,16 @@ ASTReader::ASTReadResult ASTReader::ReadASTCore(
// Otherwise, return an error.
Diag(diag::err_ast_file_out_of_date)
- << moduleKindForDiagnostic(Type) << FileName << !ErrorStr.empty()
- << ErrorStr;
+ << moduleKindForDiagnostic(Type) << FileName;
+ for (const auto &C : Result.getChanges()) {
+ Diag(diag::note_fe_ast_file_modified)
+ << C.Kind << (C.Old && C.New) << llvm::itostr(C.Old.value_or(0))
+ << llvm::itostr(C.New.value_or(0));
+ }
+ Diag(diag::note_ast_file_input_files_validation_status)
+ << Result.getValidationStatus();
+ if (!Result.getSignatureError().empty())
+ Diag(diag::note_ast_file_signature_failed) << Result.getSignatureError();
return Failure;
}
diff --git a/clang/lib/Serialization/ModuleManager.cpp b/clang/lib/Serialization/ModuleManager.cpp
index ed7b6cf67674e..a284131857229 100644
--- a/clang/lib/Serialization/ModuleManager.cpp
+++ b/clang/lib/Serialization/ModuleManager.cpp
@@ -66,28 +66,30 @@ ModuleManager::lookupBuffer(StringRef Name) {
return std::move(InMemoryBuffers[*Entry]);
}
-static bool checkModuleFile(off_t Size, time_t ModTime, off_t ExpectedSize,
- time_t ExpectedModTime, std::string &ErrorStr) {
+bool ModuleManager::isModuleFileOutOfDate(off_t Size, time_t ModTime,
+ off_t ExpectedSize,
+ time_t ExpectedModTime,
+ AddModuleResult &Result) {
+ bool OutOfDate = false;
if (ExpectedSize && ExpectedSize != Size) {
- ErrorStr = "module file has a different size than expected";
- return true;
+ Result.Changes.push_back({Change::Size, ExpectedSize, Size});
+ OutOfDate = true;
}
if (ExpectedModTime && ExpectedModTime != ModTime) {
- ErrorStr = "module file has a different modification time than expected";
- return true;
+ Result.Changes.push_back({Change::ModTime, ExpectedModTime, ModTime});
+ OutOfDate = true;
}
- return false;
+ return OutOfDate;
}
-static bool checkSignature(ASTFileSignature Signature,
- ASTFileSignature ExpectedSignature,
- std::string &ErrorStr) {
+bool ModuleManager::checkSignature(ASTFileSignature Signature,
+ ASTFileSignature ExpectedSignature,
+ AddModuleResult &Result) {
if (!ExpectedSignature || Signature == ExpectedSignature)
return false;
-
- ErrorStr =
+ Result.SignatureError =
Signature ? "signature mismatch" : "could not read module signature";
return true;
}
@@ -105,13 +107,12 @@ static void updateModuleImports(ModuleFile &MF, ModuleFile *ImportedBy,
}
}
-ModuleManager::AddModuleResult ModuleManager::addModule(
+AddModuleResult ModuleManager::addModule(
ModuleFileName FileName, ModuleKind Type, SourceLocation ImportLoc,
ModuleFile *ImportedBy, unsigned Generation, off_t ExpectedSize,
time_t ExpectedModTime, ASTFileSignature ExpectedSignature,
- ASTFileSignatureReader ReadSignature, ModuleFile *&Module,
- std::string &ErrorStr) {
- Module = nullptr;
+ ASTFileSignatureReader ReadSignature) {
+ AddModuleResult Result;
uint64_t InputFilesValidationTimestamp = 0;
if (Type == MK_ImplicitModule)
@@ -131,24 +132,33 @@ ModuleManager::AddModuleResult ModuleManager::addModule(
std::optional<ModuleFileKey> FileKey = FileName.makeKey(FileMgr);
if (!FileKey) {
- ErrorStr = "module file not found";
- return Missing;
+ Result.K = AddModuleResult::Missing;
+ return Result;
}
- // Check whether we already loaded this module, before
+ // Check whether we already loaded this module before.
+ // Note: `isModuleFileOutOfDate` and `checkSignature` are mutally exclusive in
+ // practice. If a signature is stored, it means size/mtime values have been
+ // zeroed out. If size/mtime are non-NULL, the signature is empty.
if (ModuleFile *ModuleEntry = lookup(*FileKey)) {
- // Check file properties.
- if (checkModuleFile(ModuleEntry->Size, ModuleEntry->ModTime, ExpectedSize,
- ExpectedModTime, ErrorStr))
- return OutOfDate;
+ if (isModuleFileOutOfDate(ModuleEntry->Size, ModuleEntry->ModTime,
+ ExpectedSize, ExpectedModTime, Result)) {
+ Result.ValidationStatus = ModuleEntry->InputFilesValidationStatus;
+ Result.K = AddModuleResult::OutOfDate;
+ return Result;
+ }
// Check the stored signature.
- if (checkSignature(ModuleEntry->Signature, ExpectedSignature, ErrorStr))
- return OutOfDate;
+ if (checkSignature(ModuleEntry->Signature, ExpectedSignature, Result)) {
+ Result.ValidationStatus = ModuleEntry->InputFilesValidationStatus;
+ Result.K = AddModuleResult::OutOfDate;
+ return Result;
+ }
- Module = ModuleEntry;
+ Result.Module = ModuleEntry;
updateModuleImports(*ModuleEntry, ImportedBy, ImportLoc);
- return AlreadyLoaded;
+ Result.K = AddModuleResult::AlreadyLoaded;
+ return Result;
}
// Load the contents of the module
@@ -176,8 +186,8 @@ ModuleManager::AddModuleResult ModuleManager::addModule(
FileMgr.getOptionalFileRef(FileName, /*OpenFile=*/true,
/*CacheFailure=*/false);
if (!Entry) {
- ErrorStr = "module file not found";
- return Missing;
+ Result.K = AddModuleResult::Missing;
+ return Result;
}
ModTime = Entry->getModificationTime();
Size = Entry->getSize();
@@ -186,7 +196,8 @@ ModuleManager::AddModuleResult ModuleManager::addModule(
FileName)) {
// Report that the module is out of date, since we tried (and failed) to
// import it earlier.
- return OutOfDate;
+ Result.K = AddModuleResult::OutOfDate;
+ return Result;
} else {
OptionalFileEntryRef Entry =
expectedToOptional(FileName == StringRef("-")
@@ -194,8 +205,8 @@ ModuleManager::AddModuleResult ModuleManager::addModule(
: FileMgr.getFileRef(FileName, /*OpenFile=*/true,
/*CacheFailure=*/false));
if (!Entry) {
- ErrorStr = "module file not found";
- return Missing;
+ Result.K = AddModuleResult::Missing;
+ return Result;
}
// Get a buffer of the file and close the file descriptor when done.
@@ -209,8 +220,9 @@ ModuleManager::AddModuleResult ModuleManager::addModule(
/*RequiresNullTerminator=*/false);
if (!Buf) {
- ErrorStr = Buf.getError().message();
- return Missing;
+ Result.BufferError = Buf.getError().message();
+ Result.K = AddModuleResult::Missing;
+ return Result;
}
Size = Entry->getSize();
@@ -232,21 +244,26 @@ ModuleManager::AddModuleResult ModuleManager::addModule(
NewModule->Data = PCHContainerRdr.ExtractPCH(*NewModule->Buffer);
// Check file properties.
- if (checkModuleFile(Size, ModTime, ExpectedSize, ExpectedModTime, ErrorStr))
- return OutOfDate;
+ if (isModuleFileOutOfDate(Size, ModTime, ExpectedSize, ExpectedModTime,
+ Result)) {
+ Result.K = AddModuleResult::OutOfDate;
+ return Result;
+ }
// Read the signature eagerly now so that we can check it. Avoid calling
// ReadSignature unless there's something to check though.
if (ExpectedSignature && checkSignature(ReadSignature(NewModule->Data),
- ExpectedSignature, ErrorStr))
- return OutOfDate;
+ ExpectedSignature, Result)) {
+ Result.K = AddModuleResult::OutOfDate;
+ return Result;
+ }
if (NewFileBuffer)
getModuleCache().getInMemoryModuleCache().addPCM(FileName,
std::move(NewFileBuffer));
// We're keeping this module. Store it in the map.
- Module = Modules[*FileKey] = NewModule.get();
+ Result.Module = Modules[*FileKey] = NewModule.get();
updateModuleImports(*NewModule, ImportedBy, ImportLoc);
@@ -256,7 +273,8 @@ ModuleManager::AddModuleResult ModuleManager::addModule(
Roots.push_back(NewModule.get());
Chain.push_back(std::move(NewModule));
- return NewlyLoaded;
+ Result.K = AddModuleResult::NewlyLoaded;
+ return Result;
}
void ModuleManager::removeModules(ModuleIterator First) {
diff --git a/clang/test/ClangScanDeps/modules-pch-signature-mismatch.c b/clang/test/ClangScanDeps/modules-pch-signature-mismatch.c
new file mode 100644
index 0000000000000..ab8ca36666cf9
--- /dev/null
+++ b/clang/test/ClangScanDeps/modules-pch-signature-mismatch.c
@@ -0,0 +1,62 @@
+// UNSUPPORTED: target={{.*}}-aix{{.*}}
+
+/// Test that a signature mismatch on a PCH's module dependency is diagnosed
+/// during dependency scanning.
+///
+/// 1. Scan PCH dependencies with modules hash content encoded.
+/// 2. Explicitly build module A and the PCH.
+/// 3. Modify A's header, resulting in the same byte length and rebuild A for a new signature.
+/// 4. Scan a TU that uses the out of date PCH to detect signature mismatch.
+
+// RUN: rm -rf %t && mkdir %t
+// RUN: split-file %s %t
+
+// RUN: sed "s|DIR|%/t|g" %t/cdb_pch.json.in > %t/cdb_pch.json
+// RUN: clang-scan-deps -compilation-database %t/cdb_pch.json \
+// RUN: -format experimental-full -module-files-dir %t/build > %t/result_pch.json
+
+// RUN: %deps-to-rsp %t/result_pch.json --module-name=A > %t/A.rsp
+// RUN: %deps-to-rsp %t/result_pch.json --tu-index=0 > %t/pch.rsp
+// RUN: %clang @%t/A.rsp
+// RUN: %clang @%t/pch.rsp
+
+// RUN: cp %t/a_alt.h %t/a.h
+// RUN: %clang @%t/A.rsp
+
+// RUN: sed "s|DIR|%/t|g" %t/cdb_tu.json.in > %t/cdb_tu.json
+// RUN: not clang-scan-deps -compilation-database %t/cdb_tu.json \
+// RUN: -format experimental-full -module-files-dir %t/build 2>&1 \
+// RUN: | FileCheck %s
+
+// CHECK: error:{{.*}}is out of date and needs to be rebuilt
+// CHECK: note: unable to verify precompiled file signature: signature mismatch
+
+//--- module.modulemap
+module A {
+ header "a.h"
+}
+
+//--- a.h
+typedef int A_t;
+
+//--- a_alt.h
+typedef int A_u;
+
+//--- pch.h
+#include "a.h"
+
+//--- tu.c
+
+//--- cdb_pch.json.in
+[{
+ "directory": "DIR",
+ "command": "clang -x c-header DIR/pch.h -fmodules -fmodules-cache-path=DIR/cache -Xclang -fmodules-hash-content -I DIR -o DIR/pch.h.pch",
+ "file": "DIR/pch.h"
+}]
+
+//--- cdb_tu.json.in
+[{
+ "directory": "DIR",
+ "command": "clang -fsyntax-only DIR/tu.c -fmodules -fmodules-cache-path=DIR/cache -Xclang -fmodules-hash-content -I DIR -include DIR/pch.h -o DIR/tu.o",
+ "file": "DIR/tu.c"
+}]
diff --git a/clang/test/Modules/explicit-build.cpp b/clang/test/Modules/explicit-build.cpp
index c2fe2024a3629..020a1dceede8d 100644
--- a/clang/test/Modules/explicit-build.cpp
+++ b/clang/test/Modules/explicit-build.cpp
@@ -170,7 +170,7 @@
// RUN: -fmodule-file=%t/nonexistent.pcm \
// RUN: %s 2>&1 | FileCheck --check-prefix=CHECK-NO-FILE %s
//
-// CHECK-NO-FILE: fatal error: module file '{{.*}}nonexistent.pcm' not found: module file not found
+// CHECK-NO-FILE: fatal error: module file '{{.*}}nonexistent.pcm' not found
// RUN: mv %t/a.pcm %t/a-tmp.pcm
// RUN: not %clang_cc1 -triple=x86_64-linux-gnu -x c++ -std=c++11 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -Rmodule-build -fno-modules-error-recovery \
@@ -202,6 +202,8 @@
// RUN: -fmodule-file=%t/c.pcm \
// RUN: %s -DHAVE_A -DHAVE_B -DHAVE_C 2>&1 | FileCheck --check-prefix=CHECK-MISMATCHED-B %s
//
-// CHECK-MISMATCHED-B: fatal error: module file '{{.*}}b.pcm' is out of date and needs to be rebuilt: module file has a different size than expected
+// CHECK-MISMATCHED-B: fatal error: module file '{{.*}}b.pcm' is out of date and needs to be rebuilt
+// CHECK-MISMATCHED-B-NEXT: note: size changed from expected {{[0-9]+}} to {{[0-9]+}}
+// CHECK-MISMATCHED-B-NEXT: note: earlier input file validation was not performed
// CHECK-MISMATCHED-B-NEXT: note: imported by module 'c'
// CHECK-MISMATCHED-B-NOT: note:
diff --git a/clang/test/Modules/invalid-module-dep.c b/clang/test/Modules/invalid-module-dep.c
index 2bcda8be5f1b6..82aaa22743929 100644
--- a/clang/test/Modules/invalid-module-dep.c
+++ b/clang/test/Modules/invalid-module-dep.c
@@ -37,6 +37,8 @@
#include <A/A.h>
#include <B/B.h> // expected-warning {{conflicts with imported file}} \
// expected-note {{imported by module 'B'}} \
+ // expected-note {{size changed}} \
+ // expected-note {{earlier input file validation was disabled for this kind of precompiled file}} \
// expected-error {{out of date and needs to be rebuilt}}
//--- Sysroot/usr/include/A/module.modulemap
More information about the cfe-commits
mailing list