llvmorg-github-actions[bot] wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-flang-semantics

Author: Michael Kruse (Meinersbur)

<details>
<summary>Changes</summary>

Add `-fmodule-mismatch-check` option:

 * `-fmodule-mismatch-check=on`: Current behavior: error when a module mismatch 
is detected 

 * `-fmodule-mismatch-check=non-intrinsic`: Error when a user module 
mismatches, but ignore intrinsic module mismatches. Flang consideres a module 
being an intrinsic primarily by what modifier is on the `USE` statement, but if 
that is missing, uses in which search path it was found.

  * `-fmodule-mismatch-check=warn`: Only warn about mismatches, but continue 
compiling

 * `-fmodule-mismatch-check=warn -Wno-module-file-mismatch`: Complete silence 
on mismatch

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.

---
Full diff: https://github.com/llvm/llvm-project/pull/219181.diff


17 Files Affected:

- (modified) clang/include/clang/Options/FlangOptions.td (+12) 
- (modified) clang/lib/Driver/ToolChains/Flang.cpp (+1) 
- (modified) flang/docs/ReleaseNotes.md (+5) 
- (modified) flang/include/flang/Support/Fortran-features.h (+8-8) 
- (modified) flang/include/flang/Support/LangOptions.def (+2) 
- (modified) flang/include/flang/Support/LangOptions.h (+14) 
- (modified) flang/lib/Frontend/CompilerInvocation.cpp (+20) 
- (modified) flang/lib/Semantics/mod-file.cpp (+49-14) 
- (modified) flang/lib/Semantics/mod-file.h (+2) 
- (modified) flang/lib/Support/Fortran-features.cpp (+1) 
- (added) flang/test/Semantics/Inputs/device_modfile01_b.mod (+6) 
- (added) flang/test/Semantics/Inputs/dir1/module_mismatch_check_a.mod (+6) 
- (added) flang/test/Semantics/Inputs/dir2/module_mismatch_check_a.mod (+8) 
- (added) flang/test/Semantics/Inputs/module_mismatch_check_b.mod (+8) 
- (added) flang/test/Semantics/module-mismatch-check-intrinsic-explicit.f90 
(+28) 
- (added) flang/test/Semantics/module-mismatch-check-intrinsic-implicit.f90 
(+28) 
- (added) flang/test/Semantics/module-mismatch-check-user.f90 (+32) 


``````````diff
diff --git a/clang/include/clang/Options/FlangOptions.td 
b/clang/include/clang/Options/FlangOptions.td
index 7a3dfd84fd4e7..47f707b0003cc 100644
--- a/clang/include/clang/Options/FlangOptions.td
+++ b/clang/include/clang/Options/FlangOptions.td
@@ -137,6 +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)">,
+  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/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/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/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..d0df304910422 100644
--- a/flang/lib/Semantics/mod-file.cpp
+++ b/flang/lib/Semantics/mod-file.cpp
@@ -1744,6 +1744,28 @@ Scope *ModFileReader::Read(SourceName name, 
std::optional<bool> isIntrinsic,
     return nullptr;
   }
   CHECK(sourceFile);
+
+  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;
+    break;
+  case common::LangOptions::MMC_NonIntrinsic:
+    mismatchIsError = !isIntrinsic.value_or(false);
+    break;
+  case common::LangOptions::MMC_Warn:
+    mismatchIsError = false;
+    break;
+  }
   std::optional<ModuleCheckSumType> checkSum{
       VerifyHeader(sourceFile->content())};
   if (!checkSum) {
@@ -1758,12 +1780,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. 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) {
+        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());
@@ -1778,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};
@@ -1893,6 +1914,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/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/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-explicit.f90 
b/flang/test/Semantics/module-mismatch-check-intrinsic-explicit.f90
new file mode 100644
index 0000000000000..dfbaa97077bc7
--- /dev/null
+++ b/flang/test/Semantics/module-mismatch-check-intrinsic-explicit.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_a, only: x
+end module
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
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

``````````

</details>


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

Reply via email to