https://github.com/Meinersbur updated https://github.com/llvm/llvm-project/pull/219181
>From 5571568b3d049283ab6672c297c34f5800cf69d4 Mon Sep 17 00:00:00 2001 From: Michael Kruse <[email protected]> Date: Wed, 26 Aug 2026 13:23:03 +0200 Subject: [PATCH 1/3] Implement -fmodule-mismatch-check flang_driver_module-mismatch-option Handle non-existing checksum as well Handle only checksum mismatch --- clang/include/clang/Options/FlangOptions.td | 2 + clang/lib/Driver/ToolChains/Flang.cpp | 1 + .../include/flang/Support/Fortran-features.h | 16 +++---- flang/include/flang/Support/LangOptions.def | 2 + flang/include/flang/Support/LangOptions.h | 14 ++++++ flang/lib/Frontend/CompilerInvocation.cpp | 20 ++++++++ flang/lib/Semantics/mod-file.cpp | 47 +++++++++++++++++-- flang/lib/Semantics/mod-file.h | 2 + flang/lib/Support/Fortran-features.cpp | 1 + .../Inputs/dir1/module_mismatch_check_a.mod | 6 +++ .../Inputs/dir2/module_mismatch_check_a.mod | 8 ++++ .../Inputs/module_mismatch_check_b.mod | 8 ++++ .../module-mismatch-check-intrinsic.f90 | 27 +++++++++++ .../Semantics/module-mismatch-check-user.f90 | 32 +++++++++++++ 14 files changed, 173 insertions(+), 13 deletions(-) create mode 100644 flang/test/Semantics/Inputs/dir1/module_mismatch_check_a.mod create mode 100644 flang/test/Semantics/Inputs/dir2/module_mismatch_check_a.mod create mode 100644 flang/test/Semantics/Inputs/module_mismatch_check_b.mod create mode 100644 flang/test/Semantics/module-mismatch-check-intrinsic.f90 create mode 100644 flang/test/Semantics/module-mismatch-check-user.f90 diff --git a/clang/include/clang/Options/FlangOptions.td b/clang/include/clang/Options/FlangOptions.td index 7a3dfd84fd4e7..980508ba98947 100644 --- a/clang/include/clang/Options/FlangOptions.td +++ b/clang/include/clang/Options/FlangOptions.td @@ -137,6 +137,8 @@ def module_dir : JoinedOrSeparate<["-"], "module-dir">, MetaVarName<"<dir>">, DocBrief<[{This option specifies where to put .mod files for compiled modules. It is also added to the list of directories to be searched by an USE statement. The default is the current directory.}]>; +def fmodule_mismatch_check_EQ : Joined<["-"], "fmodule-mismatch-check=">, Group<f_Group>, + HelpText<"Check consistency of used modules (option: on, non-intrinsic, warn)">; def ffixed_form : Flag<["-"], "ffixed-form">, Group<f_Group>, HelpText<"Process source files in fixed form">; diff --git a/clang/lib/Driver/ToolChains/Flang.cpp b/clang/lib/Driver/ToolChains/Flang.cpp index 7e7ac97b8b0e5..3404580ac1206 100644 --- a/clang/lib/Driver/ToolChains/Flang.cpp +++ b/clang/lib/Driver/ToolChains/Flang.cpp @@ -152,6 +152,7 @@ void Flang::addFortranDialectOptions(const ArgList &Args, options::OPT_fdefault_integer_8, options::OPT_fdefault_double_8, options::OPT_flarge_sizes, + options::OPT_fmodule_mismatch_check_EQ, options::OPT_fno_automatic, options::OPT_fhermetic_module_files, options::OPT_frealloc_lhs, diff --git a/flang/include/flang/Support/Fortran-features.h b/flang/include/flang/Support/Fortran-features.h index 4921496adee5c..1a646c8bfa789 100644 --- a/flang/include/flang/Support/Fortran-features.h +++ b/flang/include/flang/Support/Fortran-features.h @@ -81,14 +81,14 @@ ENUM_CLASS(UsageWarning, Portability, PointerToUndefinable, IndexVarRedefinition, IncompatibleImplicitInterfaces, VectorSubscriptFinalization, UndefinedFunctionResult, UselessIomsg, MismatchingDummyProcedure, SubscriptedEmptyArray, UnsignedLiteralTruncation, - CompatibleDeclarationsFromDistinctModules, ConstantIsContiguous, - NullActualForDefaultIntentAllocatable, UseAssociationIntoSameNameSubprogram, - HostAssociatedIntentOutInSpecExpr, NonVolatilePointerToVolatile, - RealConstantWidening, VolatileOrAsynchronousTemporary, UnusedVariable, - UsedUndefinedVariable, BadValueInDeadCode, AssumedTypeSizeDummy, - MisplacedIgnoreTKR, NamelistParameter, ImpureFinalInPure, - IgnoredNoReallocateLHS, ExperimentalOption, IoImpliedDoIndexConflict, - BOZLiteralTruncation) + CompatibleDeclarationsFromDistinctModules, ModuleFileMismatch, + ConstantIsContiguous, NullActualForDefaultIntentAllocatable, + UseAssociationIntoSameNameSubprogram, HostAssociatedIntentOutInSpecExpr, + NonVolatilePointerToVolatile, RealConstantWidening, + VolatileOrAsynchronousTemporary, UnusedVariable, UsedUndefinedVariable, + BadValueInDeadCode, AssumedTypeSizeDummy, MisplacedIgnoreTKR, + NamelistParameter, ImpureFinalInPure, IgnoredNoReallocateLHS, + ExperimentalOption, IoImpliedDoIndexConflict, BOZLiteralTruncation) using LanguageFeatures = EnumSet<LanguageFeature, LanguageFeature_enumSize>; using UsageWarnings = EnumSet<UsageWarning, UsageWarning_enumSize>; diff --git a/flang/include/flang/Support/LangOptions.def b/flang/include/flang/Support/LangOptions.def index 80d2302cc8c72..ed41f2b717e23 100644 --- a/flang/include/flang/Support/LangOptions.def +++ b/flang/include/flang/Support/LangOptions.def @@ -22,6 +22,8 @@ LANGOPT(Name, Bits, Default) ENUM_LANGOPT(FPContractMode, FPModeKind, 2, FPM_Fast) ///< FP Contract Mode (off/fast) /// signed integer overflow handling ENUM_LANGOPT(SignedOverflowBehavior, SignedOverflowBehaviorTy, 1, SOB_Undefined) +/// Module file checksum mismatch handling +ENUM_LANGOPT(ModuleMismatchCheck, ModuleMismatchCheckTy, 2, MMC_On) /// Indicate a build without the standard GPU libraries. LANGOPT(NoGPULib , 1, false) diff --git a/flang/include/flang/Support/LangOptions.h b/flang/include/flang/Support/LangOptions.h index 42b488c3d18a3..2e2196858cecd 100644 --- a/flang/include/flang/Support/LangOptions.h +++ b/flang/include/flang/Support/LangOptions.h @@ -43,6 +43,20 @@ class LangOptionsBase { FPM_Fast, }; + enum ModuleMismatchCheckTy { + // Verify checksums of all modules + MMC_On, + + // Reject checksum mismatches only in user modules. Intrinsic modules are + // shipped by the compiler, and their contents are defined by the language; + // a compiler update should not trigger an error when their APIs remain + // compatible. + MMC_NonIntrinsic, + + // Do not enforce module use consistency, just warn about them + MMC_Warn, + }; + /// Floating-point exception trap kinds for -ffpe-trap=. /// Bit values match the Fortran IEEE_FLAG_TYPE encoding used by /// the runtime's MapException(). diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp index 87a25f3101ddd..5b6a80c1d3635 100644 --- a/flang/lib/Frontend/CompilerInvocation.cpp +++ b/flang/lib/Frontend/CompilerInvocation.cpp @@ -1064,6 +1064,26 @@ static bool parseSemaArgs(CompilerInvocation &res, llvm::opt::ArgList &args, if (moduleDirList.size() == 1) res.setModuleDir(moduleDirList[0]); + // -fmodule-mismatch-check=<value> + if (const auto *arg = + args.getLastArg(clang::options::OPT_fmodule_mismatch_check_EQ)) { + using ModuleMismatchCheckTy = + Fortran::common::LangOptions::ModuleMismatchCheckTy; + auto check = llvm::StringSwitch<std::optional<ModuleMismatchCheckTy>>( + arg->getValue()) + .Case("on", Fortran::common::LangOptions::MMC_On) + .Case("warn", Fortran::common::LangOptions::MMC_Warn) + .Case("non-intrinsic", + Fortran::common::LangOptions::MMC_NonIntrinsic) + .Default(std::nullopt); + if (check) { + res.getLangOpts().setModuleMismatchCheck(*check); + } else { + diags.Report(clang::diag::err_drv_invalid_value) + << arg->getAsString(args) << arg->getValue(); + } + } + // -fdebug-module-writer option if (args.hasArg(clang::options::OPT_fdebug_module_writer)) { res.setDebugModuleDir(true); diff --git a/flang/lib/Semantics/mod-file.cpp b/flang/lib/Semantics/mod-file.cpp index e0fabd989bb45..5e9b1d1da00b1 100644 --- a/flang/lib/Semantics/mod-file.cpp +++ b/flang/lib/Semantics/mod-file.cpp @@ -1744,6 +1744,21 @@ Scope *ModFileReader::Read(SourceName name, std::optional<bool> isIntrinsic, return nullptr; } CHECK(sourceFile); + + bool mismatchIsError, mismatchIsWarning; + switch (context_.langOptions().getModuleMismatchCheck()) { + case common::LangOptions::MMC_On: + mismatchIsError = true; + mismatchIsWarning = true; + break; + case common::LangOptions::MMC_NonIntrinsic: + mismatchIsError = mismatchIsWarning = !isIntrinsic.value_or(false); + break; + case common::LangOptions::MMC_Warn: + mismatchIsError = false; + mismatchIsWarning = true; + break; + } std::optional<ModuleCheckSumType> checkSum{ VerifyHeader(sourceFile->content())}; if (!checkSum) { @@ -1758,12 +1773,20 @@ Scope *ModFileReader::Read(SourceName name, std::optional<bool> isIntrinsic, } return nullptr; } else if (requiredHash && *requiredHash != *checkSum) { - if (!silent) { - Say("use", name, ancestorName, - "File is not the right module file for %s"_err_en_US, - "'"s + name.ToString() + "': "s + sourceFile->path()); + if (mismatchIsError) { + if (!silent) { + Say("use", name, ancestorName, + "File is not the right module file for %s"_err_en_US, + "'"s + name.ToString() + "': "s + sourceFile->path()); + } + return nullptr; + } else { + if (!silent && mismatchIsWarning) { + Warn(name, common::UsageWarning::ModuleFileMismatch, ancestorName, + "File has a different checksum than expected for %s"_warn_en_US, + "'"s + name.ToString() + "': "s + sourceFile->path()); + } } - return nullptr; } llvm::raw_null_ostream NullStream; parsing.Parse(NullStream, context_.langOptions()); @@ -1893,6 +1916,20 @@ parser::Message &ModFileReader::Say(const char *verb, SourceName name, parser::MessageFormattedText{std::move(msg), arg}.MoveString()); } +parser::Message *ModFileReader::Warn(SourceName name, + common::UsageWarning warning, const std::string &ancestor, + parser::MessageFixedText &&msg, const std::string &arg) { + return context_.messages().Warn(/*isInModuleFile=*/false, + context_.languageFeatures(), warning, name, + "Module file for %s: %s"_warn_en_US, + parser::MessageFormattedText{ancestor.empty() + ? "module '%s'"_en_US + : "submodule '%s' of module '%s'"_en_US, + name, ancestor} + .MoveString(), + parser::MessageFormattedText{std::move(msg), arg}.MoveString()); +} + // program was read from a .mod file for a submodule; return the name of the // submodule's parent submodule, nullptr if none. static std::optional<SourceName> GetSubmoduleParent( diff --git a/flang/lib/Semantics/mod-file.h b/flang/lib/Semantics/mod-file.h index 83834671adac5..2ef012563f610 100644 --- a/flang/lib/Semantics/mod-file.h +++ b/flang/lib/Semantics/mod-file.h @@ -109,6 +109,8 @@ class ModFileReader { parser::Message &Say(const char *verb, SourceName, const std::string &, parser::MessageFixedText &&, const std::string &); + parser::Message *Warn(SourceName, common::UsageWarning, const std::string &, + parser::MessageFixedText &&, const std::string &); }; } // namespace Fortran::semantics diff --git a/flang/lib/Support/Fortran-features.cpp b/flang/lib/Support/Fortran-features.cpp index 533db242ac2d3..44e79e636cb16 100644 --- a/flang/lib/Support/Fortran-features.cpp +++ b/flang/lib/Support/Fortran-features.cpp @@ -223,6 +223,7 @@ LanguageFeatureControl::LanguageFeatureControl() { warnUsage_.set(UsageWarning::IgnoredNoReallocateLHS); warnUsage_.set(UsageWarning::IoImpliedDoIndexConflict); warnUsage_.set(UsageWarning::BOZLiteralTruncation); + warnUsage_.set(UsageWarning::ModuleFileMismatch); warnLanguage_.set(LanguageFeature::PreferIntrinsicModuleUseAssociation); warnLanguage_.set(LanguageFeature::OpenMPThreadprivateEquivalence); warnLanguage_.set(LanguageFeature::OpenAccDefaultNoneScalarsStrict); diff --git a/flang/test/Semantics/Inputs/dir1/module_mismatch_check_a.mod b/flang/test/Semantics/Inputs/dir1/module_mismatch_check_a.mod new file mode 100644 index 0000000000000..5690e5bb6775a --- /dev/null +++ b/flang/test/Semantics/Inputs/dir1/module_mismatch_check_a.mod @@ -0,0 +1,6 @@ +!mod$ v1 sum:4fcb3312b6234055 +module module_mismatch_check_a +contains +subroutine s1() +end +end diff --git a/flang/test/Semantics/Inputs/dir2/module_mismatch_check_a.mod b/flang/test/Semantics/Inputs/dir2/module_mismatch_check_a.mod new file mode 100644 index 0000000000000..f2fe3a7e1857d --- /dev/null +++ b/flang/test/Semantics/Inputs/dir2/module_mismatch_check_a.mod @@ -0,0 +1,8 @@ +!mod$ v1 sum:a14ba91f349f847c +module module_mismatch_check_a +contains +subroutine s1() +end +subroutine s1a() +end +end diff --git a/flang/test/Semantics/Inputs/module_mismatch_check_b.mod b/flang/test/Semantics/Inputs/module_mismatch_check_b.mod new file mode 100644 index 0000000000000..1907d34288d59 --- /dev/null +++ b/flang/test/Semantics/Inputs/module_mismatch_check_b.mod @@ -0,0 +1,8 @@ +!mod$ v1 sum:f3aa817a771c0caa +!need$ 4fcb3312b6234055 n module_mismatch_check_a +module module_mismatch_check_b +use module_mismatch_check_a,only:s1 +contains +subroutine s2() +end +end diff --git a/flang/test/Semantics/module-mismatch-check-intrinsic.f90 b/flang/test/Semantics/module-mismatch-check-intrinsic.f90 new file mode 100644 index 0000000000000..bf4f8ff79c30e --- /dev/null +++ b/flang/test/Semantics/module-mismatch-check-intrinsic.f90 @@ -0,0 +1,27 @@ + +! Reject unknown argument option +! RUN: not %flang -fmodule-mismatch-check=invalid %s 2>&1 | FileCheck --check-prefix=INVALID %s +! RUN: not %flang_fc1 -fmodule-mismatch-check=invalid %s 2>&1 | FileCheck --check-prefix=INVALID %s +! INVALID: error: invalid value 'invalid' in '-fmodule-mismatch-check=invalid' + + +! Test module dependency checksum mismatch handling for intrinsic modules +! Inputs/device-side-modules-a.mod records a deliberately wrong checksum for +! its dependency on iso_fortran_env. +! DEFINE: %{checksum_mismatch} = -fsyntax-only -I%S/Inputs + +! RUN: not %flang_fc1 %{checksum_mismatch} %s 2>&1 | FileCheck --check-prefix=REJECT %s +! RUN: not %flang_fc1 %{checksum_mismatch} -fmodule-mismatch-check=on %s 2>&1 | FileCheck --check-prefix=REJECT %s +! REJECT: Cannot use module file for module 'iso_fortran_env': File is not the right module file for 'iso_fortran_env' + +! RUN: %flang %{checksum_mismatch} -fmodule-mismatch-check=warn %s 2>&1 | FileCheck --check-prefix=WARNING %s +! WARNING: warning: Module file for module 'iso_fortran_env': File has a different checksum than expected for 'iso_fortran_env': + +! RUN: %flang %{checksum_mismatch} -fmodule-mismatch-check=non-intrinsic %s 2>&1 | FileCheck --allow-empty --check-prefix=NO-WARN %s +! RUN: %flang %{checksum_mismatch} -fmodule-mismatch-check=warn -Wno-module-file-mismatch %s 2>&1 | FileCheck --allow-empty --check-prefix=NO-WARN %s +! NO-WARN-NOT: warning + + +module module_mismatch_check_intrinsic + use device_modfile01_a, only: x +end module diff --git a/flang/test/Semantics/module-mismatch-check-user.f90 b/flang/test/Semantics/module-mismatch-check-user.f90 new file mode 100644 index 0000000000000..f1d7f893dd6b2 --- /dev/null +++ b/flang/test/Semantics/module-mismatch-check-user.f90 @@ -0,0 +1,32 @@ + +! Reject unknown argument option +! RUN: not %flang -fmodule-mismatch-check=invalid %s 2>&1 | FileCheck --check-prefix=INVALID %s +! RUN: not %flang_fc1 -fmodule-mismatch-check=invalid %s 2>&1 | FileCheck --check-prefix=INVALID %s +! INVALID: error: invalid value 'invalid' in '-fmodule-mismatch-check=invalid' + + +! Test module dependency checksum mismatch handling for user modules +! DEFINE: %{checksum_correct} = -fsyntax-only -I%S/Inputs -I%S/Inputs/dir1 +! DEFINE: %{checksum_mismatch} = -fsyntax-only -I%S/Inputs -I%S/Inputs/dir2 + +! Correct checksum in Inputs/dir1 +! RUN: %flang_fc1 %{checksum_correct} %s + +! Invalid checksum in Inputs/dir2 +! RUN: not %flang_fc1 %{checksum_mismatch} %s 2>&1 | FileCheck --check-prefix=REJECT %s +! RUN: not %flang_fc1 %{checksum_mismatch} -fmodule-mismatch-check=on %s 2>&1 | FileCheck --check-prefix=REJECT %s +! RUN: not %flang_fc1 %{checksum_mismatch} -fmodule-mismatch-check=non-intrinsic %s 2>&1 | FileCheck --check-prefix=REJECT %s +! REJECT: Cannot use module file for module 'module_mismatch_check_a': File is not the right module file for 'module_mismatch_check_a': + +! Convert checksum mismatch to warning +! RUN: %flang %{checksum_mismatch} -fmodule-mismatch-check=warn %s 2>&1 | FileCheck --check-prefix=WARNING %s +! WARNING: warning: Module file for module 'module_mismatch_check_a': File has a different checksum than expected for 'module_mismatch_check_a': + +! Silence warning using option +! RUN: %flang %{checksum_mismatch} -fmodule-mismatch-check=warn -Wno-module-file-mismatch %s 2>&1 | FileCheck --allow-empty --check-prefix=NO-WARNING %s +! NO-WARNING-NOT: warning + + +use module_mismatch_check_b +call s2 +end >From 7340933e1e308789073a4bd9bcaa323d9d668b64 Mon Sep 17 00:00:00 2001 From: Michael Kruse <[email protected]> Date: Thu, 27 Aug 2026 10:20:03 +0200 Subject: [PATCH 2/3] Consider files in -fintrinsic-modules-path as intrinsics unless overridden --- clang/include/clang/Options/FlangOptions.td | 14 ++++++++-- flang/docs/ReleaseNotes.md | 5 ++++ flang/lib/Semantics/mod-file.cpp | 28 +++++++++---------- .../Semantics/Inputs/device_modfile01_b.mod | 6 ++++ ...ule-mismatch-check-intrinsic-explicit.f90} | 7 +++-- ...dule-mismatch-check-intrinsic-implicit.f90 | 28 +++++++++++++++++++ 6 files changed, 68 insertions(+), 20 deletions(-) create mode 100644 flang/test/Semantics/Inputs/device_modfile01_b.mod rename flang/test/Semantics/{module-mismatch-check-intrinsic.f90 => module-mismatch-check-intrinsic-explicit.f90} (76%) create mode 100644 flang/test/Semantics/module-mismatch-check-intrinsic-implicit.f90 diff --git a/clang/include/clang/Options/FlangOptions.td b/clang/include/clang/Options/FlangOptions.td index 980508ba98947..47f707b0003cc 100644 --- a/clang/include/clang/Options/FlangOptions.td +++ b/clang/include/clang/Options/FlangOptions.td @@ -137,8 +137,18 @@ def module_dir : JoinedOrSeparate<["-"], "module-dir">, MetaVarName<"<dir>">, DocBrief<[{This option specifies where to put .mod files for compiled modules. It is also added to the list of directories to be searched by an USE statement. The default is the current directory.}]>; -def fmodule_mismatch_check_EQ : Joined<["-"], "fmodule-mismatch-check=">, Group<f_Group>, - HelpText<"Check consistency of used modules (option: on, non-intrinsic, warn)">; +def fmodule_mismatch_check_EQ : Joined<["-"], "fmodule-mismatch-check=">, + Group<f_Group>, + HelpText<"Check consistency of used modules (option: on, non-intrinsic, warn)">, + DocBrief<[{Normally, when loading a .mod file, Flang checks whether the +modules it itself depends on are the same modules from when the .mod file was +created. If there is a mismatch, compilation fails. The option converts this +error into a warning instead. The warning can be silenced using +-Wno-module-file-mismatch and thus mismatches are completely ignored. +-fmodule-mismatch-check=non-intrinsic still keeps the error for user modules +where mismatches hint towards a build dependency problem. Mismatches of +intrinsic modules are expected after a compiler upgrade. Upgraded intrinsic +modules are supposed to be backwards-compatible.}]>; def ffixed_form : Flag<["-"], "ffixed-form">, Group<f_Group>, HelpText<"Process source files in fixed form">; diff --git a/flang/docs/ReleaseNotes.md b/flang/docs/ReleaseNotes.md index bbc7084c4a757..5150854be051d 100644 --- a/flang/docs/ReleaseNotes.md +++ b/flang/docs/ReleaseNotes.md @@ -57,6 +57,11 @@ page](https://llvm.org/releases/). - Added `-gz` and `-gz=<format>` flags to enable compression of DWARF debug sections. Supported formats are `zlib`, `zstd`, and `none`. +- Added `-fmodule-mismatch-check=non-intrinsic` and + `-fmodule-mismatch-check=warn` to turn module USE checksum mismatches into a + warning instead of an error. `-Wno-module-file-mismatch` can be used to + silence even that warning. + ## Windows Support ## Fortran Language Changes in Flang diff --git a/flang/lib/Semantics/mod-file.cpp b/flang/lib/Semantics/mod-file.cpp index 5e9b1d1da00b1..d0df304910422 100644 --- a/flang/lib/Semantics/mod-file.cpp +++ b/flang/lib/Semantics/mod-file.cpp @@ -1745,18 +1745,25 @@ Scope *ModFileReader::Read(SourceName name, std::optional<bool> isIntrinsic, } CHECK(sourceFile); - bool mismatchIsError, mismatchIsWarning; + if (!isIntrinsic.has_value()) { + for (const auto &dir : context_.intrinsicModuleDirectories()) { + if (sourceFile->path().size() > dir.size() && + sourceFile->path().find(dir) == 0) { + isIntrinsic = true; + break; + } + } + } + bool mismatchIsError; switch (context_.langOptions().getModuleMismatchCheck()) { case common::LangOptions::MMC_On: mismatchIsError = true; - mismatchIsWarning = true; break; case common::LangOptions::MMC_NonIntrinsic: - mismatchIsError = mismatchIsWarning = !isIntrinsic.value_or(false); + mismatchIsError = !isIntrinsic.value_or(false); break; case common::LangOptions::MMC_Warn: mismatchIsError = false; - mismatchIsWarning = true; break; } std::optional<ModuleCheckSumType> checkSum{ @@ -1776,12 +1783,12 @@ Scope *ModFileReader::Read(SourceName name, std::optional<bool> isIntrinsic, if (mismatchIsError) { if (!silent) { Say("use", name, ancestorName, - "File is not the right module file for %s"_err_en_US, + "File is not the right module file for %s. Use -fmodule-mismatch-check=warn to turn this error into a warning."_err_en_US, "'"s + name.ToString() + "': "s + sourceFile->path()); } return nullptr; } else { - if (!silent && mismatchIsWarning) { + if (!silent) { Warn(name, common::UsageWarning::ModuleFileMismatch, ancestorName, "File has a different checksum than expected for %s"_warn_en_US, "'"s + name.ToString() + "': "s + sourceFile->path()); @@ -1801,15 +1808,6 @@ Scope *ModFileReader::Read(SourceName name, std::optional<bool> isIntrinsic, } parser::Program &parseTree{context_.SaveParseTree(std::move(*parsedProgram))}; Scope *parentScope; // the scope this module/submodule goes into - if (!isIntrinsic.has_value()) { - for (const auto &dir : context_.intrinsicModuleDirectories()) { - if (sourceFile->path().size() > dir.size() && - sourceFile->path().find(dir) == 0) { - isIntrinsic = true; - break; - } - } - } Scope &topScope{isIntrinsic.value_or(false) ? context_.intrinsicModulesScope() : context_.globalScope()}; Symbol *moduleSymbol{nullptr}; diff --git a/flang/test/Semantics/Inputs/device_modfile01_b.mod b/flang/test/Semantics/Inputs/device_modfile01_b.mod new file mode 100644 index 0000000000000..4253c7122b20d --- /dev/null +++ b/flang/test/Semantics/Inputs/device_modfile01_b.mod @@ -0,0 +1,6 @@ +!mod$ v1 sum:2280842c8e8a5ea7 +!need$ 0000000000000000 i iso_fortran_env +module device_modfile01_b +use::iso_fortran_env,only:int32 +integer(4)::x +end diff --git a/flang/test/Semantics/module-mismatch-check-intrinsic.f90 b/flang/test/Semantics/module-mismatch-check-intrinsic-explicit.f90 similarity index 76% rename from flang/test/Semantics/module-mismatch-check-intrinsic.f90 rename to flang/test/Semantics/module-mismatch-check-intrinsic-explicit.f90 index bf4f8ff79c30e..dfbaa97077bc7 100644 --- a/flang/test/Semantics/module-mismatch-check-intrinsic.f90 +++ b/flang/test/Semantics/module-mismatch-check-intrinsic-explicit.f90 @@ -14,10 +14,11 @@ ! RUN: not %flang_fc1 %{checksum_mismatch} -fmodule-mismatch-check=on %s 2>&1 | FileCheck --check-prefix=REJECT %s ! REJECT: Cannot use module file for module 'iso_fortran_env': File is not the right module file for 'iso_fortran_env' -! RUN: %flang %{checksum_mismatch} -fmodule-mismatch-check=warn %s 2>&1 | FileCheck --check-prefix=WARNING %s -! WARNING: warning: Module file for module 'iso_fortran_env': File has a different checksum than expected for 'iso_fortran_env': +! RUN: %flang %{checksum_mismatch} -fmodule-mismatch-check=non-intrinsic %s 2>&1 | FileCheck --allow-empty --check-prefix=WARN %s +! RUN: %flang %{checksum_mismatch} -fmodule-mismatch-check=warn %s 2>&1 | FileCheck --check-prefix=WARN %s +! WARN: warning: Module file for module 'iso_fortran_env': File has a different checksum than expected for 'iso_fortran_env': -! RUN: %flang %{checksum_mismatch} -fmodule-mismatch-check=non-intrinsic %s 2>&1 | FileCheck --allow-empty --check-prefix=NO-WARN %s +! RUN: %flang %{checksum_mismatch} -fmodule-mismatch-check=non-intrinsic -Wno-module-file-mismatch %s 2>&1 | FileCheck --allow-empty --check-prefix=NO-WARN %s ! RUN: %flang %{checksum_mismatch} -fmodule-mismatch-check=warn -Wno-module-file-mismatch %s 2>&1 | FileCheck --allow-empty --check-prefix=NO-WARN %s ! NO-WARN-NOT: warning diff --git a/flang/test/Semantics/module-mismatch-check-intrinsic-implicit.f90 b/flang/test/Semantics/module-mismatch-check-intrinsic-implicit.f90 new file mode 100644 index 0000000000000..5031a8bdf845d --- /dev/null +++ b/flang/test/Semantics/module-mismatch-check-intrinsic-implicit.f90 @@ -0,0 +1,28 @@ + +! Reject unknown argument option +! RUN: not %flang -fmodule-mismatch-check=invalid %s 2>&1 | FileCheck --check-prefix=INVALID %s +! RUN: not %flang_fc1 -fmodule-mismatch-check=invalid %s 2>&1 | FileCheck --check-prefix=INVALID %s +! INVALID: error: invalid value 'invalid' in '-fmodule-mismatch-check=invalid' + + +! Test module dependency checksum mismatch handling for intrinsic modules +! Inputs/device-side-modules-a.mod records a deliberately wrong checksum for +! its dependency on iso_fortran_env. +! DEFINE: %{checksum_mismatch} = -fsyntax-only -I%S/Inputs + +! RUN: not %flang_fc1 %{checksum_mismatch} %s 2>&1 | FileCheck --check-prefix=REJECT %s +! RUN: not %flang_fc1 %{checksum_mismatch} -fmodule-mismatch-check=on %s 2>&1 | FileCheck --check-prefix=REJECT %s +! REJECT: Cannot use module file for module 'iso_fortran_env': File is not the right module file for 'iso_fortran_env' + +! RUN: %flang %{checksum_mismatch} -fmodule-mismatch-check=non-intrinsic %s 2>&1 | FileCheck --allow-empty --check-prefix=WARN %s +! RUN: %flang %{checksum_mismatch} -fmodule-mismatch-check=warn %s 2>&1 | FileCheck --check-prefix=WARN %s +! WARN: warning: Module file for module 'iso_fortran_env': File has a different checksum than expected for 'iso_fortran_env': + +! RUN: %flang %{checksum_mismatch} -fmodule-mismatch-check=non-intrinsic -Wno-module-file-mismatch %s 2>&1 | FileCheck --allow-empty --check-prefix=NO-WARN %s +! RUN: %flang %{checksum_mismatch} -fmodule-mismatch-check=warn -Wno-module-file-mismatch %s 2>&1 | FileCheck --allow-empty --check-prefix=NO-WARN %s +! NO-WARN-NOT: warning + + +module module_mismatch_check_intrinsic + use device_modfile01_b, only: x +end module >From 80c870762b9f3b5a51686df11cfbf3e9bcb6d775 Mon Sep 17 00:00:00 2001 From: Michael Kruse <[email protected]> Date: Fri, 28 Aug 2026 14:01:25 +0200 Subject: [PATCH 3/3] Move warning option to the end --- flang/include/flang/Support/Fortran-features.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/flang/include/flang/Support/Fortran-features.h b/flang/include/flang/Support/Fortran-features.h index 1a646c8bfa789..416ee65cb73d7 100644 --- a/flang/include/flang/Support/Fortran-features.h +++ b/flang/include/flang/Support/Fortran-features.h @@ -81,14 +81,14 @@ ENUM_CLASS(UsageWarning, Portability, PointerToUndefinable, IndexVarRedefinition, IncompatibleImplicitInterfaces, VectorSubscriptFinalization, UndefinedFunctionResult, UselessIomsg, MismatchingDummyProcedure, SubscriptedEmptyArray, UnsignedLiteralTruncation, - CompatibleDeclarationsFromDistinctModules, ModuleFileMismatch, - ConstantIsContiguous, NullActualForDefaultIntentAllocatable, - UseAssociationIntoSameNameSubprogram, HostAssociatedIntentOutInSpecExpr, - NonVolatilePointerToVolatile, RealConstantWidening, - VolatileOrAsynchronousTemporary, UnusedVariable, UsedUndefinedVariable, - BadValueInDeadCode, AssumedTypeSizeDummy, MisplacedIgnoreTKR, - NamelistParameter, ImpureFinalInPure, IgnoredNoReallocateLHS, - ExperimentalOption, IoImpliedDoIndexConflict, BOZLiteralTruncation) + CompatibleDeclarationsFromDistinctModules, ConstantIsContiguous, + NullActualForDefaultIntentAllocatable, UseAssociationIntoSameNameSubprogram, + HostAssociatedIntentOutInSpecExpr, NonVolatilePointerToVolatile, + RealConstantWidening, VolatileOrAsynchronousTemporary, UnusedVariable, + UsedUndefinedVariable, BadValueInDeadCode, AssumedTypeSizeDummy, + MisplacedIgnoreTKR, NamelistParameter, ImpureFinalInPure, + IgnoredNoReallocateLHS, ExperimentalOption, IoImpliedDoIndexConflict, + BOZLiteralTruncation, ModuleFileMismatch) using LanguageFeatures = EnumSet<LanguageFeature, LanguageFeature_enumSize>; using UsageWarnings = EnumSet<UsageWarning, UsageWarning_enumSize>; _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
