Skip to content

[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

Merged
merged 1 commit into from
Oct 7, 2024

Conversation

klausler
Copy link
Contributor

@klausler klausler commented Oct 2, 2024

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.

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.
@klausler klausler requested a review from vdonaldson October 2, 2024 18:59
@llvmbot llvmbot added flang Flang issues not falling into any other category flang:semantics labels Oct 2, 2024
@llvmbot
Copy link
Member

llvmbot commented Oct 2, 2024

@llvm/pr-subscribers-flang-semantics

Author: Peter Klausler (klausler)

Changes

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.


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

3 Files Affected:

  • (modified) flang/include/flang/Common/Fortran-features.h (+2-1)
  • (modified) flang/lib/Semantics/check-declarations.cpp (+11-3)
  • (modified) flang/test/Semantics/separate-mp02.f90 (+18-2)
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

@klausler klausler merged commit ce5edfd into llvm:main Oct 7, 2024
11 checks passed
@klausler klausler deleted the bug110797 branch October 7, 2024 20:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
flang:semantics flang Flang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[flang][Semantics] Invalid semantic error with external dummy procedures
3 participants