GCC Bugzilla has been upgraded from version 4.4.9 to 5.0rc3. If you see any problem, please report it to bug 64968.
Bug 35831 - [F95] Shape mismatch check missing for dummy procedure argument
Summary: [F95] Shape mismatch check missing for dummy procedure argument
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 4.4.0
: P3 normal
Target Milestone: ---
Assignee: janus
URL:
Keywords: accepts-invalid
Depends on:
Blocks:
 
Reported: 2008-04-05 08:32 UTC by Tobias Burnus
Modified: 2013-12-10 21:53 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2008-04-09 18:49:31


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Tobias Burnus 2008-04-05 08:32:52 UTC
In the following program, the interface of the dummy procedure is explicit.

Fortran 2003's "12.4.1.3 Actual arguments associated with dummy procedure entities" has about this:

"If the interface of the dummy argument is explicit, the characteristics listed in 12.2 shall be the same for the associated actual argument and the corresponding dummy argument, except that a pure actual argument may be associated with a dummy argument that is not pure and an elemental intrinsic actual procedure may be associated with a dummy procedure (which is prohibited from being elemental)."

"If an external procedure name or a dummy procedure name is used as an actual argument, its interface shall be explicit or it shall be explicitly declared to have the EXTERNAL attribute."


gfortran does not seem to check whether the array arguments of dummy procedures match. One reason could be that passing a "a(2)" array ("call foo(a)") to an array "a(:)" is valid, but this does not apply here.

For some reason, gfortran checks this for
  PROCEDURE(<interface>) :: dummy
but not for
  INTERFACE; subroutine dummy() ...
in principle I had expected that both is handled identically. Remove the "!!" to test the PROCEDURE version.

Found at http://groups.google.com/group/comp.lang.fortran/browse_thread/thread/330df81363912681

Please also check the version given there (incl. the PROCEDURE version) when fixing this PR.

program test
  implicit none
  interface
    subroutine one(a)
      integer a(:)
    end subroutine one
    subroutine two(a)
      integer a(2)
    end subroutine two
  end interface
  ! PROCEDURE dummy, gives error:
  !! call foo(two)    ! OK: "Type/rank mismatch in argument 'f'"
  ! Interface dummy, is accepted:
  call bar(two)  ! Invalid, not diagnosed
contains
! Valid, but gives an ICE in trans-*.c, see PR 35830
!!  subroutine foo(f)
!!    procedure(one) :: f
!!  end subroutine foo

  subroutine bar(f)
    interface
      subroutine f(a)
        integer a(:)
      end subroutine f
    end interface
  end subroutine bar
end program test
Comment 1 Janus Weil 2008-04-08 20:58:41 UTC
Tobias,

I can confirm the behaviour you described for this test case, provided of course that "one" and "two" are implemented somewhere externally. Otherwise one gets

undefined reference to `two_'

because there is only an interface for "two" but no actual implementation.


Now, if I apply the fix for PR35830, i.e. adding the following line in "copy_formal_args":

formal_arg->sym->as = gfc_copy_array_spec (curr_arg->sym->as);

Then also the error message for "call foo(two)" goes away! So this "Type/rank mismatch in argument 'f'" you saw before was apparently due to that array-handling bug in "copy_formal_args"!
Comment 2 Janus Weil 2008-04-09 18:23:55 UTC
Here is a modified version of the original test case, which is also accepted by gfortran, while it is rejected by ifort:


module m

contains

    subroutine one(a)
      integer a(1:2)
    end subroutine one

    subroutine two(a)
      integer a(2:3)
    end subroutine two

end module

program test
  use m
  implicit none

  ! PROCEDURE dummy
  !call foo(two)

  ! Interface dummy
  call bar(two)

contains

!   subroutine foo(f)
!     procedure(one) :: f
!   end subroutine foo

  subroutine bar(f)
    interface
      subroutine f(a)
        integer a(1:2)
      end subroutine f
    end interface
  end subroutine bar

end program test


In this test case both arrays are explicit-sized, and even have the same size, but their upper and lower bounds are shifted. gfortran currently does not even check if both arrays have the same size, only their ranks are compared.
ifort gives the following error message:

fortcom: Error: test35831.f90, line 23: The characteristics of dummy argument 1 of the associated actual procedure differ from the characteristics of dummy argument 1 of the dummy procedure. (12.2)   [TWO]
  call bar(two)
-----------^

I would change this bug's status from UNCONFIRMED to NEW, but apparently I don't have the "canconfirm" permission.
Comment 3 Tobias Burnus 2008-04-09 18:49:31 UTC
> In this test case both arrays are explicit-sized, and even have the same size,
> but their upper and lower bounds are shifted. gfortran currently does not even
> check if both arrays have the same size, only their ranks are compared.

I think procedures with explicit-shape arguments with the same shape/size but only different bounds should be conformable.

The only real problem is assumed-shape vs. the rest (explict, assumed-size, ...). Ok, if an explicit size is given, the sizes should match, but arguments of the dummy/actual function like "integer :: foo(*)" and bar(1:2) and foobar(3000:3001) should all be conformable.
Similarly, I think, also foo(1:), bar(:) and foobar(-300:) should be conformable.

(I cannot really pinpoint it in the standard, but I'm convinced that this is the case; when I have time, I will re-read the standard and try to produce a proper reference.)
* I use "manner" as "kind" and "type" have a special Fortran meaning.
Comment 4 Janus Weil 2008-04-10 21:09:58 UTC
To me it's also not completely clear what the standard says on this, but the way to fix it would probably be to insert some additional check into operator_correspondence (interface.c), where currently only the type and rank of the arguments is checked.


To require full equality of all array borders (as suggested in my comment #2), one could simply add

      if (!gfc_compare_array_spec (f1->sym->as, f2->sym->as))
	return 1;

into the above mentioned routine. This would result in gfortran behaving the same way as ifort in this case, may it be standard-conforming or not.


If on the other hand Tobias is right in the assumption he made in comment #3, then one could something along the lines of

  if (f1->sym->as->type != f2->sym->as->type)
    return 1;

to require only the array types to be equal, or something similar to at least prevent assumed-shape arrays from being passed instead of eplicit-shape arrays.


My feeling is that at least the array size should match for explicit-shape arrays, but this is just a feeling and I couldn't find anything in the standard to confirm this.

I'm not sure if the changes I'm suggesting would interfere with any other case where 'operator_correspondence' is called, but at least they don't seem to trigger any regressions.
Comment 5 Tobias Burnus 2008-04-11 07:45:20 UTC
> If on the other hand Tobias is right in the assumption he made in comment #3,
> then one could something along the lines of
>   if (f1->sym->as->type != f2->sym->as->type)

I would not be surprised if foo(*) and foo(4) are allowed and then your test rejects too much.

> My feeling is that at least the array size should match for explicit-shape
> arrays,

I'm not sure about that part; one can create "valid" (i.e. working) programs which violate this (e.g.: array(5), array(10), but only accessing 1 to 5). We should check what the standard says about this. I think it is formally invalid to do so; if we decide to allow it, at least a warning should be printed.

(At the end one needs to carefully read the standard, unfortunately, I do not have much time the next two, three weeks. One could also ask at comp.lang.fortran.)
Comment 6 janus 2011-09-10 10:18:58 UTC
(In reply to comment #0)
> Fortran 2003's "12.4.1.3 Actual arguments associated with dummy procedure
> entities" has about this:
> 
> "If the interface of the dummy argument is explicit, the characteristics listed
> in 12.2 shall be the same for the associated actual argument and the
> corresponding dummy argument, except that a pure actual argument may be
> associated with a dummy argument that is not pure and an elemental intrinsic
> actual procedure may be associated with a dummy procedure (which is prohibited
> from being elemental)."


Note: The same restrictions are already listed in F95's chapter 12.4.1.2, as well as F08's chapter 12.5.2.9. At first sight there are no differences between the different versions of the standard in the quoted passage.
Comment 7 janus 2011-09-10 11:24:02 UTC
Some more F08 standard quotes:

"12.5.2.9 Actual arguments associated with dummy procedure entities
If the interface of a dummy procedure is explicit, its characteristics as a procedure (12.3.1) shall be the same as those of its effective argument, ..."

"12.3.1 Characteristics of procedures
The characteristics of a procedure are the classification of the procedure as a function or subroutine, whether it is pure, whether it is elemental, whether it has the BIND attribute, the characteristics of its dummy arguments, ..."

"12.3.2.2 Characteristics of dummy data objects
The characteristics of a dummy data object are its type, its type parameters (if any), its shape, ...
If a shape, size, or type parameter is assumed or deferred, it is a
characteristic."


Combining the three statements above, F08 clearly demands that the *shape* of the argument should be the same (meaning that the bounds themselves may differ).


"1.3.128 shape
array dimensionality of a data entity, represented as a rank-one array whose size is the rank of the data entity and whose elements are the extents of the data entity"


So I would conclude that:
 * comment #0 is invalid (as well as the original c.l.f. example)
 * comment #2 is valid (ifort's check seems to be too strict)
Comment 8 janus 2011-09-10 11:26:50 UTC
(In reply to comment #7)
> "12.3.1 Characteristics of procedures
> The characteristics of a procedure are the classification of the procedure as a
> function or subroutine, whether it is pure, whether it is elemental, whether it
> has the BIND attribute, the characteristics of its dummy arguments, ..."
> 
> "12.3.2.2 Characteristics of dummy data objects
> The characteristics of a dummy data object are its type, its type parameters
> (if any), its shape, ...
> If a shape, size, or type parameter is assumed or deferred, it is a
> characteristic."
> 
> 
> Combining the three statements above, F08 clearly demands that the *shape* of
> the argument should be the same (meaning that the bounds themselves may
> differ).

Note that the same restrictions on dummy characteristics also apply to other situations, like e.g. overriding type-bound procedures (cf. PR47978).
Comment 9 janus 2011-09-11 10:06:03 UTC
(In reply to comment #7)
> Combining the three statements above, F08 clearly demands that the *shape* of
> the argument should be the same (meaning that the bounds themselves may
> differ).

However, there is one more sentence which seems to restrict this further:

"If a type parameter of an object or a bound of an array is not a constant expression, the exact dependence on the entities in the expression is a characteristic."

Here, the standard talks explicitly about 'bounds of an array' and not just the 'shape'.

Depending on how one reads this, it might mean two things:
 1) for non-constant bounds, the bounds themselves have to match, not only the shape
 2) for non-constant bounds, the shape expression (i.e. "upper bound minus lower bound") has to match, including the exact dependence on entities in the expression
Comment 10 janus 2011-09-11 20:12:30 UTC
Author: janus
Date: Sun Sep 11 20:12:24 2011
New Revision: 178767

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=178767
Log:
2011-09-11  Janus Weil  <janus@gcc.gnu.org>

	PR fortran/35831
	PR fortran/47978
	* interface.c (check_dummy_characteristics): New function to check the
	characteristics of dummy arguments.
	(gfc_compare_interfaces,gfc_check_typebound_override): Call it here.


2011-09-11  Janus Weil  <janus@gcc.gnu.org>

	PR fortran/35831
	PR fortran/47978
	* gfortran.dg/dynamic_dispatch_5.f03: Fix invalid test case.
	* gfortran.dg/proc_decl_26.f90: New.
	* gfortran.dg/typebound_override_2.f90: New.
	* gfortran.dg/typebound_proc_6.f03: Changed wording in error message.

Added:
    trunk/gcc/testsuite/gfortran.dg/proc_decl_26.f90
    trunk/gcc/testsuite/gfortran.dg/typebound_override_2.f90
Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/interface.c
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/testsuite/gfortran.dg/dynamic_dispatch_5.f03
    trunk/gcc/testsuite/gfortran.dg/typebound_proc_6.f03
Comment 11 janus 2011-09-11 20:48:40 UTC
r178767 implements a check to reject the original c.l.f. test case as well as the one in comment #0.

At this point I would tend to say that comment #2 is valid, but we also still fail to reject things like "a(1:2)" vs "a(1:3)".
Comment 12 janus 2011-09-29 16:41:13 UTC
Here's a link to a c.l.f. thread where I asked about this:

http://groups.google.com/group/comp.lang.fortran/browse_thread/thread/ae6a44043a3b1a95
Comment 13 janus 2011-10-04 18:37:22 UTC
Author: janus
Date: Tue Oct  4 18:37:13 2011
New Revision: 179520

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=179520
Log:
2011-10-04  Janus Weil  <janus@gcc.gnu.org>

	PR fortran/35831
	* interface.c (check_dummy_characteristics): Check the array shape.


2011-10-04  Janus Weil  <janus@gcc.gnu.org>

	PR fortran/35831
	* gfortran.dg/dummy_procedure_6.f90: New.

Added:
    trunk/gcc/testsuite/gfortran.dg/dummy_procedure_6.f90
Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/interface.c
    trunk/gcc/testsuite/ChangeLog
Comment 14 janus 2011-10-04 18:52:37 UTC
r179520 should pretty much fix the shape checking for dummy arguments.

Related ToDos:
1) check shape of dummy function results (in 'gfc_compare_interfaces')
2) check shape of function results when overriding TBPs (in 'gfc_check_typebound_override')

I wonder if it would make sense to combine both tasks into a new function 'check_result_characteristics' or similar (together with the checks for type/rank, string length, attributes, etc), cf. F08 chapter 12.3.3.
Comment 15 janus 2011-10-05 20:06:33 UTC
(In reply to comment #14)
> Related ToDos:
> 1) check shape of dummy function results (in 'gfc_compare_interfaces')
> 2) check shape of function results when overriding TBPs (in
> 'gfc_check_typebound_override')

3) check string length of dummy function results (so far we only have a string length check when overriding)


Test case (adapted from one of the IRs):



call caller(c1)

contains

  FUNCTION C1(N)
    CHARACTER(N) C1
  END FUNCTION C1

  SUBROUTINE CALLER(c2)
    INTERFACE
      FUNCTION C2(N)
	CHARACTER(2) C2
      END FUNCTION
    END INTERFACE
  end subroutine

end
Comment 16 janus 2012-08-06 20:36:23 UTC
Author: janus
Date: Mon Aug  6 20:36:16 2012
New Revision: 190187

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=190187
Log:
2012-08-06  Janus Weil  <janus@gcc.gnu.org>

	PR fortran/35831
	* interface.c (check_result_characteristics): New function, which checks
	the characteristics of function results.
	(gfc_compare_interfaces,gfc_check_typebound_override): Call it.

2012-08-06  Janus Weil  <janus@gcc.gnu.org>

	PR fortran/35831
	* gfortran.dg/dummy_procedure_5.f90: Modified.
	* gfortran.dg/dummy_procedure_8.f90: New.
	* gfortran.dg/interface_26.f90: Modified.
	* gfortran.dg/proc_ptr_11.f90: Modified.
	* gfortran.dg/proc_ptr_15.f90: Modified.
	* gfortran.dg/proc_ptr_result_5.f90: Modified.
	* gfortran.dg/typebound_override_1.f90: Modified.
	* gfortran.dg/typebound_proc_6.f03: Modified.

Added:
    trunk/gcc/testsuite/gfortran.dg/dummy_procedure_8.f90
Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/interface.c
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/testsuite/gfortran.dg/dummy_procedure_5.f90
    trunk/gcc/testsuite/gfortran.dg/interface_26.f90
    trunk/gcc/testsuite/gfortran.dg/proc_ptr_11.f90
    trunk/gcc/testsuite/gfortran.dg/proc_ptr_15.f90
    trunk/gcc/testsuite/gfortran.dg/proc_ptr_result_5.f90
    trunk/gcc/testsuite/gfortran.dg/typebound_override_1.f90
    trunk/gcc/testsuite/gfortran.dg/typebound_proc_6.f03
Comment 17 janus 2012-08-06 21:03:01 UTC
(In reply to comment #15)
> (In reply to comment #14)
> > Related ToDos:
> > 1) check shape of dummy function results (in 'gfc_compare_interfaces')
> > 2) check shape of function results when overriding TBPs (in
> > 'gfc_check_typebound_override')
> 
> 3) check string length of dummy function results (so far we only have a string
> length check when overriding)

r190187 does all of this (and basically a complete check of the result characteristics).

Related TODOs:
 * improve gfc_dep_compare_expr to catch more cases (and/or enable the warnings in check_result_characteristics and check_dummy_characteristics, marked by FIXMEs)
 * check more attributes in check_dummy_characteristics (another FIXME)
 * Tobias' remarks at http://gcc.gnu.org/ml/fortran/2012-08/msg00034.html, e.g. PR54189 and PR54190
Comment 18 janus 2013-12-10 21:41:46 UTC
Author: janus
Date: Tue Dec 10 21:41:43 2013
New Revision: 205873

URL: http://gcc.gnu.org/viewcvs?rev=205873&root=gcc&view=rev
Log:
2013-12-10  Janus Weil  <janus@gcc.gnu.org>

	PR fortran/35831
	* interface.c (check_dummy_characteristics): Add checks for several
	attributes.


2013-12-10  Janus Weil  <janus@gcc.gnu.org>

	PR fortran/35831
	* gfortran.dg/c_by_val_5.f90: Modified.
	* gfortran.dg/dummy_procedure_10.f90: New.

Added:
    trunk/gcc/testsuite/gfortran.dg/dummy_procedure_10.f90
Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/interface.c
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/testsuite/gfortran.dg/c_by_val_5.f90
Comment 19 janus 2013-12-10 21:53:36 UTC
(In reply to janus from comment #17)
> Related TODOs:
>  * improve gfc_dep_compare_expr to catch more cases (and/or enable the
> warnings in check_result_characteristics and check_dummy_characteristics,
> marked by FIXMEs)

This point is still open, but can be tracked e.g. in PR 37222.

>  * check more attributes in check_dummy_characteristics (another FIXME)

This has been implemented in r205873.

>  * Tobias' remarks at http://gcc.gnu.org/ml/fortran/2012-08/msg00034.html,
> e.g. PR54189 and PR54190

I think all of these remarks have been fixed by now (or at least sorted into PRs).


All in all, I think this PR is ripe to get closed after more than five years with (almost) everything fixed.