Skip to content

Commit ce5edfd

Browse files
authored
[flang] Finer error detection in separate module procedure case (#110912)
When a separate module procedure has a dummy procedure argument that is simply declared EXTERNAL in its interface but is actually called as a subroutine or function in its definition, the compiler is emitting an error message. This is too strong; an error is appropriate only when the dummy procedure in the definition has an interface that is incompatible with the one in the interface definition. However, this is not a safe coding practice, and can lead to trouble during execution if a function is passed as an actual argument but called as a subroutine in the procedure (or the other way around), so add a warning message as well for this case (off by default). Fixes #110797.
1 parent 8882d59 commit ce5edfd

File tree

3 files changed

+31
-6
lines changed

3 files changed

+31
-6
lines changed

flang/include/flang/Common/Fortran-features.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,8 @@ ENUM_CLASS(UsageWarning, Portability, PointerToUndefinable,
7272
IgnoredIntrinsicFunctionType, PreviousScalarUse,
7373
RedeclaredInaccessibleComponent, ImplicitShared, IndexVarRedefinition,
7474
IncompatibleImplicitInterfaces, BadTypeForTarget,
75-
VectorSubscriptFinalization, UndefinedFunctionResult, UselessIomsg)
75+
VectorSubscriptFinalization, UndefinedFunctionResult, UselessIomsg,
76+
MismatchingDummyProcedure)
7677

7778
using LanguageFeatures = EnumSet<LanguageFeature, LanguageFeature_enumSize>;
7879
using UsageWarnings = EnumSet<UsageWarning, UsageWarning_enumSize>;

flang/lib/Semantics/check-declarations.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3765,12 +3765,20 @@ void SubprogramMatchHelper::CheckDummyDataObject(const Symbol &symbol1,
37653765
void SubprogramMatchHelper::CheckDummyProcedure(const Symbol &symbol1,
37663766
const Symbol &symbol2, const DummyProcedure &proc1,
37673767
const DummyProcedure &proc2) {
3768+
std::string whyNot;
37683769
if (!CheckSameIntent(symbol1, symbol2, proc1.intent, proc2.intent)) {
37693770
} else if (!CheckSameAttrs(symbol1, symbol2, proc1.attrs, proc2.attrs)) {
3770-
} else if (proc1 != proc2) {
3771+
} else if (!proc2.IsCompatibleWith(proc1, &whyNot)) {
37713772
Say(symbol1, symbol2,
3772-
"Dummy procedure '%s' does not match the corresponding argument in"
3773-
" the interface body"_err_en_US);
3773+
"Dummy procedure '%s' is not compatible with the corresponding argument in the interface body: %s"_err_en_US,
3774+
whyNot);
3775+
} else if (proc1 != proc2) {
3776+
evaluate::AttachDeclaration(
3777+
symbol1.owner().context().Warn(
3778+
common::UsageWarning::MismatchingDummyProcedure,
3779+
"Dummy procedure '%s' does not exactly match the corresponding argument in the interface body"_warn_en_US,
3780+
symbol1.name()),
3781+
symbol2);
37743782
}
37753783
}
37763784

flang/test/Semantics/separate-mp02.f90

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
! RUN: %python %S/test_errors.py %s %flang_fc1
1+
! RUN: %python %S/test_errors.py %s %flang_fc1 -pedantic
22

33
! When a module subprogram has the MODULE prefix the following must match
44
! with the corresponding separate module procedure interface body:
@@ -238,7 +238,7 @@ module subroutine s1(x)
238238
procedure(s_real2) :: x
239239
end
240240
module subroutine s2(x)
241-
!ERROR: Dummy procedure 'x' does not match the corresponding argument in the interface body
241+
!ERROR: Dummy procedure 'x' is not compatible with the corresponding argument in the interface body: incompatible dummy procedure interfaces: incompatible dummy argument #1: incompatible dummy data object types: INTEGER(4) vs REAL(4)
242242
procedure(s_integer) :: x
243243
end
244244
end
@@ -357,3 +357,19 @@ module character(2) function f()
357357
module character(3) function f()
358358
end function
359359
end submodule
360+
361+
module m11
362+
interface
363+
module subroutine s(x)
364+
! The subroutine/function distinction is not known.
365+
external x
366+
end
367+
end interface
368+
end
369+
submodule(m11) sm11
370+
contains
371+
!WARNING: Dummy procedure 'x' does not exactly match the corresponding argument in the interface body
372+
module subroutine s(x)
373+
call x ! no error
374+
end
375+
end

0 commit comments

Comments
 (0)