Bug 40276 - Matching GENERIC procedure: Wrong INTENT should give directly an error message
Summary: Matching GENERIC procedure: Wrong INTENT should give directly an error message
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 4.5.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: diagnostic
Depends on:
Blocks:
 
Reported: 2009-05-27 18:34 UTC by Tobias Burnus
Modified: 2019-01-23 06:52 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2009-12-18 14:37:36


Attachments
Very initial draft patch (1.78 KB, patch)
2009-05-27 21:40 UTC, Tobias Burnus
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Tobias Burnus 2009-05-27 18:34:24 UTC
Starting with PR 40039, gfortran checks the INTENT of procedures. This works - especially with the patch for PR 36947/PR 40039 - rather well if one calls a SPECIFIC procedure.

However, if one calls a GENERIC procedure the error message is just:

  Error: There is no specific subroutine for the generic 'gen' at (1)

The issue is: There is already a matching specific procedure, it just has the problem that the INTENT is wrong.

If one checks for GENERIC procedures, one should continue checking the interface and if everything except of the INTENT matches, one should print an error message. Otherwise one can search for ages for the problem.

NAG f95 prints for the example:

Error: line 14: Dummy proc A arg 1 has different INTENT from actual proc SUB arg
Error: line 14: Incompatible procedure argument for A (no. 1) of SPECIFIC

Example:
-----------------------------
module m
  implicit none
  interface gen
    subroutine specific(a)
      interface
        subroutine a(x)
          integer, intent(in) :: x
        end subroutine a
      end interface
    end subroutine specific
  end interface gen
contains
  subroutine test()
    call gen(sub)
  end subroutine test
  subroutine sub(a)
    integer, intent(inout) :: a
  end subroutine sub
end module m
-----------------------------

 * * *

Without NAG f95 I would not have easily found the problem for the real-world program (now fixed). To show bad the error message is, here the interface (from octopus, see http://www.tddft.org). The problem was that the actual argument to "f" had for "val" intent(inout) instead of "intent(out)".

  interface loct_minimize
    function oct_minimize(method, dim, x, step, tolgrad, toldr, maxiter, f, &
                          write_iter_info, minimum)
      integer :: oct_minimize
      integer, intent(in)    :: method
      integer, intent(in)    :: dim
      real(8), intent(inout) :: x
      real(8), intent(in)    :: step
      integer, intent(in)    :: maxiter
      real(8), intent(in)    :: tolgrad
      real(8), intent(in)    :: toldr
      real(8), intent(out)   :: minimum
      interface
        subroutine f(n, x, val, getgrad, grad)
          integer, intent(in) :: n
          real(8), intent(in) :: x(n)
          real(8), intent(out) :: val
          integer, intent(in)  :: getgrad
          real(8), intent(out) :: grad(n)
        end subroutine f
        subroutine write_iter_info(iter, n, val, maxdr, maxgrad, x)
          integer, intent(in) :: iter
          integer, intent(in) :: n
          real(8), intent(in) :: val
          real(8), intent(in) :: maxdr
          real(8), intent(in) :: maxgrad
          real(8), intent(in) :: x(n)
        end subroutine write_iter_info
      end interface
    end function oct_minimize
  end interface
Comment 1 Tobias Burnus 2009-05-27 21:40:22 UTC
Created attachment 17922 [details]
Very initial draft patch

Some patch; now it prints:

    call gen(sub)
             1
Error: Type/rank mismatch in argument 'a' at (1)

Maybe together with the patch which gives better error messages this will produce something useful. Currently it is better than before, but only marginally. I think it should state somewhere that the generic procedure matches a specific one (and only the INTENT goes wrong). I think it should print somewhere the procedure name of the specific function. With all the recursion, having a proper error message is not trivial.

I had to remove the intents_check() as it does not do recursive checks. And I could not easily do a a recursive call as then one has two formal arguments rather than a formal and an actual arguments.
Comment 2 Tobias Burnus 2009-06-15 22:40:33 UTC
Also for OPTIONAL a suitable error message would be useful. For finding a specific interface, the OPTIONAL attribute could be ignored similarly to INTENT; however, one needs to be careful as for ambiguity checks and if the actual argument is not present, the OPTIONAL is still relevant.

PURE is another item which should be checked, which is simpler, however.
Comment 3 Tobias Burnus 2013-07-16 06:21:59 UTC
Patch for PR57711 and this PR: http://gcc.gnu.org/ml/fortran/2013-06/msg00132.html (approved).

It fails for the test case http://gcc.gnu.org/ml/fortran/2013-07/msg00017.html (-> PR39290 and PR20896). In that test case, "s1" and "s2" are ambiguous in F2003/F2008.

However, I fear that the check in the patch above will give a bogus error for
  interface gen
    subroutine s1(x)
      real, external :: x
    end subroutine s1
    subroutine s1(x)
      integer, external :: x
    end subroutine s1
  end interface
which is valid since F2008 ("both data objects or known to be functions, and neither is TKR compatible with the other,", 12.4.3.4.5). The issue does not occur yet, as the feature is not yet implemented.