-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[flang] Finer error detection in separate module procedure case #110912
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
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 llvm#110797.
@llvm/pr-subscribers-flang-semantics Author: Peter Klausler (klausler) ChangesWhen 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. Full diff: https://github.com/llvm/llvm-project/pull/110912.diff 3 Files Affected:
diff --git a/flang/include/flang/Common/Fortran-features.h b/flang/include/flang/Common/Fortran-features.h
index f813cbae40a57e..3942a792628645 100644
--- a/flang/include/flang/Common/Fortran-features.h
+++ b/flang/include/flang/Common/Fortran-features.h
@@ -72,7 +72,8 @@ ENUM_CLASS(UsageWarning, Portability, PointerToUndefinable,
IgnoredIntrinsicFunctionType, PreviousScalarUse,
RedeclaredInaccessibleComponent, ImplicitShared, IndexVarRedefinition,
IncompatibleImplicitInterfaces, BadTypeForTarget,
- VectorSubscriptFinalization, UndefinedFunctionResult, UselessIomsg)
+ VectorSubscriptFinalization, UndefinedFunctionResult, UselessIomsg,
+ MismatchingDummyProcedure)
using LanguageFeatures = EnumSet<LanguageFeature, LanguageFeature_enumSize>;
using UsageWarnings = EnumSet<UsageWarning, UsageWarning_enumSize>;
diff --git a/flang/lib/Semantics/check-declarations.cpp b/flang/lib/Semantics/check-declarations.cpp
index 7778561fb5bd33..f8e873008ceabc 100644
--- a/flang/lib/Semantics/check-declarations.cpp
+++ b/flang/lib/Semantics/check-declarations.cpp
@@ -3765,12 +3765,20 @@ void SubprogramMatchHelper::CheckDummyDataObject(const Symbol &symbol1,
void SubprogramMatchHelper::CheckDummyProcedure(const Symbol &symbol1,
const Symbol &symbol2, const DummyProcedure &proc1,
const DummyProcedure &proc2) {
+ std::string whyNot;
if (!CheckSameIntent(symbol1, symbol2, proc1.intent, proc2.intent)) {
} else if (!CheckSameAttrs(symbol1, symbol2, proc1.attrs, proc2.attrs)) {
- } else if (proc1 != proc2) {
+ } else if (!proc2.IsCompatibleWith(proc1, &whyNot)) {
Say(symbol1, symbol2,
- "Dummy procedure '%s' does not match the corresponding argument in"
- " the interface body"_err_en_US);
+ "Dummy procedure '%s' is not compatible with the corresponding argument in the interface body: %s"_err_en_US,
+ whyNot);
+ } else if (proc1 != proc2) {
+ evaluate::AttachDeclaration(
+ symbol1.owner().context().Warn(
+ common::UsageWarning::MismatchingDummyProcedure,
+ "Dummy procedure '%s' does not exactly match the corresponding argument in the interface body"_warn_en_US,
+ symbol1.name()),
+ symbol2);
}
}
diff --git a/flang/test/Semantics/separate-mp02.f90 b/flang/test/Semantics/separate-mp02.f90
index c63ab6f41a1326..cb1e2687bad736 100644
--- a/flang/test/Semantics/separate-mp02.f90
+++ b/flang/test/Semantics/separate-mp02.f90
@@ -1,4 +1,4 @@
-! RUN: %python %S/test_errors.py %s %flang_fc1
+! RUN: %python %S/test_errors.py %s %flang_fc1 -pedantic
! When a module subprogram has the MODULE prefix the following must match
! with the corresponding separate module procedure interface body:
@@ -238,7 +238,7 @@ module subroutine s1(x)
procedure(s_real2) :: x
end
module subroutine s2(x)
- !ERROR: Dummy procedure 'x' does not match the corresponding argument in the interface body
+ !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)
procedure(s_integer) :: x
end
end
@@ -357,3 +357,19 @@ module character(2) function f()
module character(3) function f()
end function
end submodule
+
+module m11
+ interface
+ module subroutine s(x)
+ ! The subroutine/function distinction is not known.
+ external x
+ end
+ end interface
+end
+submodule(m11) sm11
+ contains
+ !WARNING: Dummy procedure 'x' does not exactly match the corresponding argument in the interface body
+ module subroutine s(x)
+ call x ! no error
+ end
+end
|
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.