[flang-commits] [clang] [flang] [flang] Diagnose and optionally repair missing MODULE procedure prefixes (PR #220783)
Andre Kuhlenschmidt via flang-commits
flang-commits at lists.llvm.org
Thu Sep 17 11:16:09 PDT 2026
https://github.com/akuhlens updated https://github.com/llvm/llvm-project/pull/220783
>From e527fc8dffa7c96836f516569ea500a15fe65115 Mon Sep 17 00:00:00 2001
From: Andre Kuhlenschmidt <akuhlenschmi at nvidia.com>
Date: Mon, 31 Aug 2026 13:00:57 -0700
Subject: [PATCH 1/3] [flang] Diagnose missing MODULE procedure prefixes
---
clang/include/clang/Options/FlangOptions.td | 2 +
clang/lib/Driver/ToolChains/Flang.cpp | 2 +
flang/docs/Extensions.md | 7 +++
.../include/flang/Support/Fortran-features.h | 16 +++----
flang/lib/Frontend/CompilerInvocation.cpp | 6 +++
flang/lib/Semantics/resolve-names.cpp | 34 ++++++++++++--
flang/lib/Support/Fortran-features.cpp | 2 +
flang/test/Driver/implicit-module-prefix.f90 | 45 +++++++++++++++++++
.../Lower/implicit-module-prefix-shadow.f90 | 43 ++++++++++++++++++
flang/test/Lower/implicit-module-prefix.f90 | 25 +++++++++++
flang/test/Semantics/separate-mp07.f90 | 19 ++++++++
flang/test/Semantics/separate-mp08.f90 | 14 ++++++
flang/test/Semantics/separate-mp09.f90 | 20 +++++++++
flang/test/Semantics/separate-mp10.f90 | 15 +++++++
flang/test/Semantics/separate-mp11.f90 | 18 ++++++++
flang/test/Semantics/separate-mp12.f90 | 15 +++++++
16 files changed, 272 insertions(+), 11 deletions(-)
create mode 100644 flang/test/Driver/implicit-module-prefix.f90
create mode 100644 flang/test/Lower/implicit-module-prefix-shadow.f90
create mode 100644 flang/test/Lower/implicit-module-prefix.f90
create mode 100644 flang/test/Semantics/separate-mp07.f90
create mode 100644 flang/test/Semantics/separate-mp08.f90
create mode 100644 flang/test/Semantics/separate-mp09.f90
create mode 100644 flang/test/Semantics/separate-mp10.f90
create mode 100644 flang/test/Semantics/separate-mp11.f90
create mode 100644 flang/test/Semantics/separate-mp12.f90
diff --git a/clang/include/clang/Options/FlangOptions.td b/clang/include/clang/Options/FlangOptions.td
index 7a3dfd84fd4e7..a904aafc8fa97 100644
--- a/clang/include/clang/Options/FlangOptions.td
+++ b/clang/include/clang/Options/FlangOptions.td
@@ -184,6 +184,8 @@ defm xor_operator : OptInFC1FFlag<"xor-operator", "Enable .XOR. as a synonym of
defm logical_abbreviations : OptInFC1FFlag<"logical-abbreviations", "Enable logical abbreviations">;
defm implicit_none : OptInFC1FFlag<"implicit-none", "No implicit typing allowed unless overridden by IMPLICIT statements">;
defm implicit_none_ext : OptInFC1FFlag<"implicit-none-ext", "No implicit externals allowed">;
+defm implicit_module_prefix : OptInFC1FFlag<"implicit-module-prefix",
+ "Treat a submodule procedure as if it had a missing MODULE prefix when it matches an ancestor interface">;
defm underscoring : OptInFC1FFlag<"underscoring", "Appends one trailing underscore to external names">;
defm ppc_native_vec_elem_order: BoolOptionWithoutMarshalling<"f", "ppc-native-vector-element-order",
PosFlag<SetTrue, [], [ClangOption], "Specifies PowerPC native vector element order (default)">,
diff --git a/clang/lib/Driver/ToolChains/Flang.cpp b/clang/lib/Driver/ToolChains/Flang.cpp
index 7562206f93438..1c398abf7fe3a 100644
--- a/clang/lib/Driver/ToolChains/Flang.cpp
+++ b/clang/lib/Driver/ToolChains/Flang.cpp
@@ -138,7 +138,9 @@ void Flang::addFortranDialectOptions(const ArgList &Args,
options::OPT_finput_charset_EQ,
options::OPT_fimplicit_none,
options::OPT_fimplicit_none_ext,
+ options::OPT_fimplicit_module_prefix,
options::OPT_fno_implicit_none,
+ options::OPT_fno_implicit_module_prefix,
options::OPT_fbackslash,
options::OPT_fno_backslash,
options::OPT_flogical_abbreviations,
diff --git a/flang/docs/Extensions.md b/flang/docs/Extensions.md
index d00397ce2f227..57ac5b18ab2e3 100644
--- a/flang/docs/Extensions.md
+++ b/flang/docs/Extensions.md
@@ -579,6 +579,13 @@ end program
[-fimplicit-none-type-always]
* Ignore occurrences of `IMPLICIT NONE` and `IMPLICIT NONE(TYPE)`
[-fimplicit-none-type-never]
+* Treat a subprogram in a submodule as if it had a missing `MODULE` prefix
+ when its name matches a separate module procedure interface in an ancestor
+ module [-fimplicit-module-prefix]. This extension is disabled by default
+ because the unprefixed subprogram can instead be a conforming local
+ procedure. By default, that likely mistake is diagnosed with
+ `-Wmissing-module-prefix` without changing the program. When the extension
+ is enabled, `-Wimplicit-module-prefix` reports each repaired prefix.
* Old-style `PARAMETER pi=3.14` statement without parentheses
[-falternative-parameter-statement]
* `UNSIGNED` type (-funsigned)
diff --git a/flang/include/flang/Support/Fortran-features.h b/flang/include/flang/Support/Fortran-features.h
index 4921496adee5c..b1d08fe999d30 100644
--- a/flang/include/flang/Support/Fortran-features.h
+++ b/flang/include/flang/Support/Fortran-features.h
@@ -43,13 +43,13 @@ ENUM_CLASS(LanguageFeature, BackslashEscapes, OldDebugLines,
UseGenericIntrinsicWhenSpecificDoesntMatch, DataStmtExtensions,
RedundantContiguous, RedundantAttribute, InitBlankCommon,
EmptyBindCDerivedType, MiscSourceExtensions, AllocateToOtherLength,
- LongNames, IntrinsicAsSpecific, BenignNameClash, BenignRedundancy,
- NullMoldAllocatableComponentValue, NopassScalarBase, MiscUseExtensions,
- ImpliedDoIndexScope, DistinctCommonSizes, OddIndexVariableRestrictions,
- IndistinguishableSpecifics, SubroutineAndFunctionSpecifics,
- EmptySequenceType, NonSequenceCrayPointee, BranchIntoConstruct,
- BadBranchTarget, HollerithPolymorphic, ListDirectedSize,
- NonBindCInteroperability, CudaManaged, CudaUnified,
+ LongNames, IntrinsicAsSpecific, ImplicitModulePrefix, BenignNameClash,
+ BenignRedundancy, NullMoldAllocatableComponentValue, NopassScalarBase,
+ MiscUseExtensions, ImpliedDoIndexScope, DistinctCommonSizes,
+ OddIndexVariableRestrictions, IndistinguishableSpecifics,
+ SubroutineAndFunctionSpecifics, EmptySequenceType, NonSequenceCrayPointee,
+ BranchIntoConstruct, BadBranchTarget, HollerithPolymorphic,
+ ListDirectedSize, NonBindCInteroperability, CudaManaged, CudaUnified,
PolymorphicActualAllocatableOrPointerToMonomorphicDummy, RelaxedPureDummy,
UndefinableAsynchronousOrVolatileActual, AutomaticInMainProgram, PrintCptr,
SavedLocalInSpecExpr, PrintNamelist, AssumedRankPassedToNonAssumedRank,
@@ -88,7 +88,7 @@ ENUM_CLASS(UsageWarning, Portability, PointerToUndefinable,
UsedUndefinedVariable, BadValueInDeadCode, AssumedTypeSizeDummy,
MisplacedIgnoreTKR, NamelistParameter, ImpureFinalInPure,
IgnoredNoReallocateLHS, ExperimentalOption, IoImpliedDoIndexConflict,
- BOZLiteralTruncation)
+ BOZLiteralTruncation, MissingModulePrefix)
using LanguageFeatures = EnumSet<LanguageFeature, LanguageFeature_enumSize>;
using UsageWarnings = EnumSet<UsageWarning, UsageWarning_enumSize>;
diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp
index ff4c7f6a18624..2950975b61f46 100644
--- a/flang/lib/Frontend/CompilerInvocation.cpp
+++ b/flang/lib/Frontend/CompilerInvocation.cpp
@@ -903,6 +903,12 @@ static bool parseFrontendArgs(FrontendOptions &opts, llvm::opt::ArgList &args,
clang::options::OPT_fno_implicit_none_ext,
false));
+ // -f{no-}implicit-module-prefix
+ opts.features.Enable(
+ Fortran::common::LanguageFeature::ImplicitModulePrefix,
+ args.hasFlag(clang::options::OPT_fimplicit_module_prefix,
+ clang::options::OPT_fno_implicit_module_prefix, false));
+
// -f{no-}backslash
opts.features.Enable(Fortran::common::LanguageFeature::BackslashEscapes,
args.hasFlag(clang::options::OPT_fbackslash,
diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index 17abba65bdae5..17d8b6d491ff1 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -631,7 +631,8 @@ class ScopeHandler : public ImplicitRulesVisitor {
Symbol *FindInTypeOrParents(const Scope &, const parser::Name &);
Symbol *FindInTypeOrParents(const parser::Name &);
Symbol *FindInScopeOrBlockConstructs(const Scope &, SourceName);
- Symbol *FindSeparateModuleProcedureInterface(const parser::Name &);
+ Symbol *FindSeparateModuleProcedureInterface(
+ const parser::Name &, bool emitError = true);
void EraseSymbol(const parser::Name &);
void EraseSymbol(const Symbol &symbol) { currScope().erase(symbol.name()); }
// Make a new symbol with the name and attrs of an existing one
@@ -5515,6 +5516,11 @@ void SubprogramVisitor::Post(const parser::FunctionStmt &stmt) {
Symbol &SubprogramVisitor::PostSubprogramStmt() {
Symbol &symbol{*currScope().symbol()};
SetExplicitAttrs(symbol, EndAttrs());
+ if (symbol.get<SubprogramDetails>().moduleInterface()) {
+ // An omitted MODULE prefix accepted as an extension still defines the
+ // separate module procedure declared by the interface body.
+ SetExplicitAttr(symbol, Attr::MODULE);
+ }
if (symbol.attrs().test(Attr::MODULE)) {
symbol.attrs().set(Attr::EXTERNAL, false);
symbol.implicitAttrs().set(Attr::EXTERNAL, false);
@@ -5764,7 +5770,7 @@ void SubprogramVisitor::PostEntryStmt(const parser::EntryStmt &stmt) {
}
Symbol *ScopeHandler::FindSeparateModuleProcedureInterface(
- const parser::Name &name) {
+ const parser::Name &name, bool emitError) {
auto *symbol{FindSymbol(name)};
if (symbol && symbol->has<SubprogramNameDetails>()) {
const Scope *parent{nullptr};
@@ -5783,7 +5789,9 @@ Symbol *ScopeHandler::FindSeparateModuleProcedureInterface(
symbol = const_cast<Symbol *>(defnIface);
}
if (!IsSeparateModuleProcedureInterface(symbol)) {
- Say(name, "'%s' was not declared a separate module procedure"_err_en_US);
+ if (emitError) {
+ Say(name, "'%s' was not declared a separate module procedure"_err_en_US);
+ }
symbol = nullptr;
}
return symbol;
@@ -5849,6 +5857,26 @@ bool SubprogramVisitor::BeginSubprogram(const parser::Name &name,
EraseSymbol(name);
}
}
+ } else if (isValid && !inInterfaceBlock() && currScope().IsSubmodule() &&
+ (moduleInterface = FindSeparateModuleProcedureInterface(
+ name, /*emitError=*/false))) {
+ if (context().IsEnabled(common::LanguageFeature::ImplicitModulePrefix)) {
+ context().Warn(common::LanguageFeature::ImplicitModulePrefix, name.source,
+ "Assuming a missing MODULE prefix on '%s' to repair the separate module procedure interface '%s:%s'"_port_en_US,
+ name.source, moduleInterface->owner().GetName().value(),
+ moduleInterface->name());
+ } else {
+ context().Warn(common::UsageWarning::MissingModulePrefix, name.source,
+ "'%s' is a local procedure that hides the separate module procedure "
+ "interface '%s:%s'; "
+ "a call to that interface will fail to link with this local "
+ "procedure. "
+ "If this procedure is supposed to implement the interface, "
+ "add the MODULE keyword or enable -fimplicit-module-prefix."_warn_en_US,
+ name.source, moduleInterface->owner().GetName().value(),
+ moduleInterface->name());
+ moduleInterface = nullptr;
+ }
}
Symbol *newSymbol{
PushSubprogramScope(name, subpFlag, bindingSpec, hasModulePrefix)};
diff --git a/flang/lib/Support/Fortran-features.cpp b/flang/lib/Support/Fortran-features.cpp
index 533db242ac2d3..72ccd8140c843 100644
--- a/flang/lib/Support/Fortran-features.cpp
+++ b/flang/lib/Support/Fortran-features.cpp
@@ -152,6 +152,7 @@ LanguageFeatureControl::LanguageFeatureControl() {
disable_.set(LanguageFeature::LogicalAbbreviations);
disable_.set(LanguageFeature::XOROperator);
disable_.set(LanguageFeature::OldStyleParameter);
+ disable_.set(LanguageFeature::ImplicitModulePrefix);
// Possibly an accidental "feature" of nvfortran.
disable_.set(LanguageFeature::AssumedRankPassedToNonAssumedRank);
disable_.set(LanguageFeature::Coarray);
@@ -223,6 +224,7 @@ LanguageFeatureControl::LanguageFeatureControl() {
warnUsage_.set(UsageWarning::IgnoredNoReallocateLHS);
warnUsage_.set(UsageWarning::IoImpliedDoIndexConflict);
warnUsage_.set(UsageWarning::BOZLiteralTruncation);
+ warnUsage_.set(UsageWarning::MissingModulePrefix);
warnLanguage_.set(LanguageFeature::PreferIntrinsicModuleUseAssociation);
warnLanguage_.set(LanguageFeature::OpenMPThreadprivateEquivalence);
warnLanguage_.set(LanguageFeature::OpenAccDefaultNoneScalarsStrict);
diff --git a/flang/test/Driver/implicit-module-prefix.f90 b/flang/test/Driver/implicit-module-prefix.f90
new file mode 100644
index 0000000000000..a7af0727394f9
--- /dev/null
+++ b/flang/test/Driver/implicit-module-prefix.f90
@@ -0,0 +1,45 @@
+! REQUIRES: native
+! RUN: %flang -static-libflangrt -fimplicit-module-prefix %s -o %t-enabled
+! RUN: %t-enabled | FileCheck %s --check-prefix=REPAIRED
+! RUN: %flang -static-libflangrt -fno-implicit-module-prefix -fimplicit-module-prefix %s -o %t-reenabled
+! RUN: %t-reenabled | FileCheck %s --check-prefix=REPAIRED
+! RUN: %flang -c %s -o %t-default.o
+! RUN: not %flang %t-default.o -o %t-default
+! RUN: %flang -Wno-missing-module-prefix -c %s -o %t-suppressed.o
+! RUN: not %flang %t-suppressed.o -o %t-suppressed
+! RUN: %flang -Wimplicit-module-prefix -c %s -o %t-warning-only.o
+! RUN: not %flang %t-warning-only.o -o %t-warning-only
+! RUN: %flang -pedantic -c %s -o %t-pedantic.o
+! RUN: not %flang %t-pedantic.o -o %t-pedantic
+! RUN: %flang -fimplicit-module-prefix -fno-implicit-module-prefix -c %s -o %t-disabled.o
+! RUN: not %flang %t-disabled.o -o %t-disabled
+
+module alpha
+ interface
+ module integer function second()
+ end function second
+ module integer function third()
+ end function third
+ end interface
+end module alpha
+
+submodule(alpha) beta
+contains
+ integer function second()
+ second = 2
+ end function second
+end submodule beta
+
+submodule(alpha:beta) gamma
+contains
+ integer function third()
+ third = 3
+ end function third
+end submodule gamma
+
+program main
+ use alpha
+ print *, second(), third()
+end program main
+
+! REPAIRED: 2 3
diff --git a/flang/test/Lower/implicit-module-prefix-shadow.f90 b/flang/test/Lower/implicit-module-prefix-shadow.f90
new file mode 100644
index 0000000000000..d68cd611f0afc
--- /dev/null
+++ b/flang/test/Lower/implicit-module-prefix-shadow.f90
@@ -0,0 +1,43 @@
+! RUN: %flang_fc1 -Wno-missing-module-prefix -emit-hlfir %s -o - | FileCheck %s
+
+! A local procedure in beta hides alpha's interface only in beta and its
+! descendants. The sibling submodule may still implement alpha's public
+! second procedure.
+module alpha
+ interface
+ module subroutine second
+ end subroutine second
+ module subroutine third
+ end subroutine third
+ end interface
+end module alpha
+
+submodule(alpha) beta
+contains
+ ! CHECK-LABEL: func @_QMalphaSbetaPsecond()
+ subroutine second
+ end subroutine second
+end submodule beta
+
+submodule(alpha:beta) nested_gamma
+contains
+ ! CHECK-LABEL: func @_QMalphaPthird()
+ module subroutine third
+ end subroutine third
+end submodule nested_gamma
+
+submodule(alpha) sibling_gamma
+contains
+ ! CHECK-LABEL: func @_QMalphaPsecond()
+ module subroutine second
+ end subroutine second
+end submodule sibling_gamma
+
+! CHECK-LABEL: func @_QQmain()
+program main
+ use alpha
+ ! CHECK: fir.call @_QMalphaPsecond() {{.*}}
+ call second
+ ! CHECK: fir.call @_QMalphaPthird() {{.*}}
+ call third
+end program main
diff --git a/flang/test/Lower/implicit-module-prefix.f90 b/flang/test/Lower/implicit-module-prefix.f90
new file mode 100644
index 0000000000000..2a57fc73dc093
--- /dev/null
+++ b/flang/test/Lower/implicit-module-prefix.f90
@@ -0,0 +1,25 @@
+! RUN: %flang_fc1 -fimplicit-module-prefix -emit-hlfir %s -o - | FileCheck %s
+
+module alpha
+ interface
+ module subroutine implementation
+ end subroutine implementation
+ end interface
+end module alpha
+
+submodule(alpha) beta
+end submodule beta
+
+submodule(alpha:beta) gamma
+contains
+ ! CHECK-LABEL: func @_QMalphaPimplementation()
+ subroutine implementation
+ end subroutine implementation
+end submodule gamma
+
+! CHECK-LABEL: func @_QQmain()
+program main
+ use alpha
+ ! CHECK: fir.call @_QMalphaPimplementation() {{.*}}
+ call implementation
+end program main
diff --git a/flang/test/Semantics/separate-mp07.f90 b/flang/test/Semantics/separate-mp07.f90
new file mode 100644
index 0000000000000..896c3f87988ce
--- /dev/null
+++ b/flang/test/Semantics/separate-mp07.f90
@@ -0,0 +1,19 @@
+! RUN: %python %S/test_errors.py %s %flang_fc1 -Werror
+! A local subprogram hides an ancestor interface and leaves calls to the
+! ancestor's separate module procedure undefined at link time.
+module alpha
+ interface
+ module subroutine second
+ end subroutine second
+ end interface
+end module alpha
+
+submodule(alpha) beta
+end submodule beta
+
+submodule(alpha:beta) gamma
+contains
+ !WARNING: 'second' is a local procedure that hides the separate module procedure interface 'alpha:second'; a call to that interface will fail to link with this local procedure. If this procedure is supposed to implement the interface, add the MODULE keyword or enable -fimplicit-module-prefix. [-Wmissing-module-prefix]
+ subroutine second
+ end subroutine second
+end submodule gamma
diff --git a/flang/test/Semantics/separate-mp08.f90 b/flang/test/Semantics/separate-mp08.f90
new file mode 100644
index 0000000000000..70986c352386a
--- /dev/null
+++ b/flang/test/Semantics/separate-mp08.f90
@@ -0,0 +1,14 @@
+! RUN: %python %S/test_errors.py %s %flang_fc1 -Wno-missing-module-prefix
+! The default diagnostic may be suppressed without enabling the extension.
+module m
+ interface
+ module subroutine implementation
+ end subroutine implementation
+ end interface
+end module m
+
+submodule(m) sm
+contains
+ subroutine implementation
+ end subroutine implementation
+end submodule sm
diff --git a/flang/test/Semantics/separate-mp09.f90 b/flang/test/Semantics/separate-mp09.f90
new file mode 100644
index 0000000000000..ae26635a738e9
--- /dev/null
+++ b/flang/test/Semantics/separate-mp09.f90
@@ -0,0 +1,20 @@
+! RUN: %flang_fc1 -fimplicit-module-prefix -fdebug-dump-symbols %s 2>&1 | FileCheck %s
+! The enabled extension silently repairs a likely omitted MODULE prefix by
+! binding the definition to the separate module procedure interface.
+module m
+ interface
+ module subroutine implementation
+ end subroutine implementation
+ end interface
+end module m
+
+submodule(m) sm
+contains
+ subroutine implementation
+ end subroutine implementation
+end submodule sm
+
+! CHECK: Module scope: m
+! CHECK: implementation, MODULE, PUBLIC (Subroutine): Subprogram isInterface ()
+! CHECK: Module scope: sm
+! CHECK: implementation, MODULE, PUBLIC (Subroutine): Subprogram () moduleInterface: implementation, MODULE, PUBLIC (Subroutine): Subprogram isInterface ()
diff --git a/flang/test/Semantics/separate-mp10.f90 b/flang/test/Semantics/separate-mp10.f90
new file mode 100644
index 0000000000000..677af8f78963d
--- /dev/null
+++ b/flang/test/Semantics/separate-mp10.f90
@@ -0,0 +1,15 @@
+! RUN: %python %S/test_errors.py %s %flang_fc1 -fimplicit-module-prefix -pedantic -Werror
+! Pedantic mode reports the nonstandard repair.
+module m
+ interface
+ module subroutine implementation
+ end subroutine implementation
+ end interface
+end module m
+
+submodule(m) sm
+contains
+ !PORTABILITY: Assuming a missing MODULE prefix on 'implementation' to repair the separate module procedure interface 'm:implementation' [-Wimplicit-module-prefix]
+ subroutine implementation
+ end subroutine implementation
+end submodule sm
diff --git a/flang/test/Semantics/separate-mp11.f90 b/flang/test/Semantics/separate-mp11.f90
new file mode 100644
index 0000000000000..d66618d8e3533
--- /dev/null
+++ b/flang/test/Semantics/separate-mp11.f90
@@ -0,0 +1,18 @@
+! RUN: %python %S/test_errors.py %s %flang_fc1 -fimplicit-module-prefix -Wimplicit-module-prefix -Werror
+! The extension warning may be requested without enabling all pedantic warnings.
+module alpha
+ interface
+ module subroutine implementation
+ end subroutine implementation
+ end interface
+end module alpha
+
+submodule(alpha) beta
+end submodule beta
+
+submodule(alpha:beta) gamma
+contains
+ !PORTABILITY: Assuming a missing MODULE prefix on 'implementation' to repair the separate module procedure interface 'alpha:implementation' [-Wimplicit-module-prefix]
+ subroutine implementation
+ end subroutine implementation
+end submodule gamma
diff --git a/flang/test/Semantics/separate-mp12.f90 b/flang/test/Semantics/separate-mp12.f90
new file mode 100644
index 0000000000000..deccd90c18615
--- /dev/null
+++ b/flang/test/Semantics/separate-mp12.f90
@@ -0,0 +1,15 @@
+! RUN: %python %S/test_errors.py %s %flang_fc1 -pedantic -Werror
+! Pedantic mode widens diagnostics but does not enable the repair extension.
+module m
+ interface
+ module subroutine implementation
+ end subroutine implementation
+ end interface
+end module m
+
+submodule(m) sm
+contains
+ !WARNING: 'implementation' is a local procedure that hides the separate module procedure interface 'm:implementation'; a call to that interface will fail to link with this local procedure. If this procedure is supposed to implement the interface, add the MODULE keyword or enable -fimplicit-module-prefix. [-Wmissing-module-prefix]
+ subroutine implementation
+ end subroutine implementation
+end submodule sm
>From 06c801923d77af9e303c84edf9020af045c6115b Mon Sep 17 00:00:00 2001
From: Andre Kuhlenschmidt <akuhlenschmi at nvidia.com>
Date: Mon, 31 Aug 2026 14:07:02 -0700
Subject: [PATCH 2/3] [flang][test] Narrow dead SELECT CASE check
---
flang/test/Lower/select-case-statement.f90 | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/flang/test/Lower/select-case-statement.f90 b/flang/test/Lower/select-case-statement.f90
index b289024da2810..5ac05259bc27c 100644
--- a/flang/test/Lower/select-case-statement.f90
+++ b/flang/test/Lower/select-case-statement.f90
@@ -104,7 +104,7 @@ subroutine slogical(L)
! CHECK: cf.cond_br
case (.true.)
n8 = 2
- ! CHECK-NOT: 888
+ ! CHECK-NOT: arith.constant 888
case default ! dead
n8 = 888
end select
>From 418c887dbf306a5fe27988db58f6d68acb1e4717 Mon Sep 17 00:00:00 2001
From: Andre Kuhlenschmidt <akuhlenschmi at nvidia.com>
Date: Thu, 17 Sep 2026 11:15:05 -0700
Subject: [PATCH 3/3] [flang] Append ImplicitModulePrefix language feature
---
flang/include/flang/Support/Fortran-features.h | 17 +++++++++--------
1 file changed, 9 insertions(+), 8 deletions(-)
diff --git a/flang/include/flang/Support/Fortran-features.h b/flang/include/flang/Support/Fortran-features.h
index b1d08fe999d30..702b5352a5af4 100644
--- a/flang/include/flang/Support/Fortran-features.h
+++ b/flang/include/flang/Support/Fortran-features.h
@@ -43,13 +43,13 @@ ENUM_CLASS(LanguageFeature, BackslashEscapes, OldDebugLines,
UseGenericIntrinsicWhenSpecificDoesntMatch, DataStmtExtensions,
RedundantContiguous, RedundantAttribute, InitBlankCommon,
EmptyBindCDerivedType, MiscSourceExtensions, AllocateToOtherLength,
- LongNames, IntrinsicAsSpecific, ImplicitModulePrefix, BenignNameClash,
- BenignRedundancy, NullMoldAllocatableComponentValue, NopassScalarBase,
- MiscUseExtensions, ImpliedDoIndexScope, DistinctCommonSizes,
- OddIndexVariableRestrictions, IndistinguishableSpecifics,
- SubroutineAndFunctionSpecifics, EmptySequenceType, NonSequenceCrayPointee,
- BranchIntoConstruct, BadBranchTarget, HollerithPolymorphic,
- ListDirectedSize, NonBindCInteroperability, CudaManaged, CudaUnified,
+ LongNames, IntrinsicAsSpecific, BenignNameClash, BenignRedundancy,
+ NullMoldAllocatableComponentValue, NopassScalarBase, MiscUseExtensions,
+ ImpliedDoIndexScope, DistinctCommonSizes, OddIndexVariableRestrictions,
+ IndistinguishableSpecifics, SubroutineAndFunctionSpecifics,
+ EmptySequenceType, NonSequenceCrayPointee, BranchIntoConstruct,
+ BadBranchTarget, HollerithPolymorphic, ListDirectedSize,
+ NonBindCInteroperability, CudaManaged, CudaUnified,
PolymorphicActualAllocatableOrPointerToMonomorphicDummy, RelaxedPureDummy,
UndefinableAsynchronousOrVolatileActual, AutomaticInMainProgram, PrintCptr,
SavedLocalInSpecExpr, PrintNamelist, AssumedRankPassedToNonAssumedRank,
@@ -61,7 +61,8 @@ ENUM_CLASS(LanguageFeature, BackslashEscapes, OldDebugLines,
MultipleProgramUnitsOnSameLine, AllocatedForAssociated,
OpenMPThreadprivateEquivalence, RelaxedCLocChecks, CudaPinned,
OpenAccDefaultNoneScalarsStrict, OpenACCMultipleNamesInRoutine,
- EnumerationType, CUDAInit, PreferIntrinsicModuleUseAssociation)
+ EnumerationType, CUDAInit, PreferIntrinsicModuleUseAssociation,
+ ImplicitModulePrefix)
// Portability and suspicious usage warnings
ENUM_CLASS(UsageWarning, Portability, PointerToUndefinable,
More information about the flang-commits
mailing list