Bug 25071 - dummy argument larger than actual argument
Summary: dummy argument larger than actual argument
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 4.1.0
: P3 normal
Target Milestone: ---
Assignee: Dominique d'Humieres
URL:
Keywords: accepts-invalid
Depends on:
Blocks:
 
Reported: 2005-11-26 17:54 UTC by Joost VandeVondele
Modified: 2018-03-22 19:03 UTC (History)
4 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2006-02-26 19:49:01


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Joost VandeVondele 2005-11-26 17:54:59 UTC
using GNU Fortran 95 (GCC) 4.1.0 20051126 (prerelease)  with '-g -pedantic -std=f95', I get a bad / no diagnostic for the following invalid code:

INTEGER :: I(2,2)
CALL TST(I)
CONTAINS
 SUBROUTINE TST(I)
  INTEGER :: I(6)
 END SUBROUTINE TST
END
Comment 1 Francois-Xavier Coudert 2005-11-26 19:48:38 UTC
## g95 ##
In file foo.f90:2

CALL TST(I)
          1
Error: Array argument at (1) is smaller than the dummy size
## Intel ##
fortcom: Error: foo.f90, line 2: The storage extent of the dummy argument exceeds that of the actual argument.   [I]
CALL TST(I)
---------^
fortcom: Info: foo.f90, line 4: This variable has not been used.   [I]
 SUBROUTINE TST(I)
----------------^
compilation aborted for foo.f90 (code 1)
## Portland ##
## Sun ##

CALL TST(I)
         ^
"foo.f90", Line = 2, Column = 10: ERROR: The overall size of the dummy argument array is greater than the size of this actual argument.
Comment 2 Tobias Burnus 2007-04-19 16:16:42 UTC
Analogously for character lengths:

        program test
           character(len=10) :: x
           call foo(x)
           write(*,*) 'X=',x
        contains
        subroutine foo(y)
           character(len=20) :: y
           y = 'hello world'
        end subroutine
       end

Taken from: http://ftp.aset.psu.edu/pub/ger/fortran/test/ test17.f90 (slightly modified).

g95: Actual character argument at (1) is shorter in length than the formal argument

NAG f95: Character length too short for arg Y (no. 1) of FOO

ifort: Character length argument mismatch. [X]
Comment 3 patchapp@dberlin.org 2007-05-03 20:50:14 UTC
Subject: Bug number PR25071

A patch for this bug has been added to the patch tracker.
The mailing list url for the patch is http://gcc.gnu.org/ml/gcc-patches/2007-05/msg00186.html
Comment 4 Tobias Burnus 2007-05-04 08:54:19 UTC
Subject: Bug 25071

Author: burnus
Date: Fri May  4 07:54:06 2007
New Revision: 124411

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=124411
Log:
2007-05-04  Tobias Burnus  <burnus@net-b.de>

        PR fortran/25071
        * interface.c (compare_actual_formal): Check character length.

2007-05-04  Tobias Burnus  <burnus@net-b.de>

        PR fortran/25071
        * gfortran.dg/char_length_3.f90: New test.
        * gfortran.dg/char_result_2.f90: Fix test.


Added:
    trunk/gcc/testsuite/gfortran.dg/char_length_3.f90
Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/interface.c
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/testsuite/gfortran.dg/char_result_2.f90

Comment 5 Tobias Burnus 2007-05-04 08:55:16 UTC
Note: Only the string length problem is fixed; the array storage extend still needs to be fixed.
Comment 6 Tobias Burnus 2007-07-24 09:42:47 UTC
I believe this is fixed by PR30940.

The first example gives:
Warnung: Actual argument contains too few elements for dummy argument 'i' (4/6) at (1)

The second example:
Warnung: Character length of actual argument shorter than of dummy argument 'y' (10/20) at (1)

It currently gives only warnings since I failed to get any comments when an error and when only a warning should be given.

Missing is the check for array element designators: PR32616.
Comment 7 Janne Blomqvist 2011-01-25 12:01:17 UTC
Reopening..

(In reply to comment #6)
> I believe this is fixed by PR30940.
> 
> The first example gives:
> Warnung: Actual argument contains too few elements for dummy argument 'i' (4/6)
> at (1)
> 
> The second example:
> Warnung: Character length of actual argument shorter than of dummy argument 'y'
> (10/20) at (1)
> 
> It currently gives only warnings since I failed to get any comments when an
> error and when only a warning should be given.

Sorry for being 'a bit' late with comments, but IMHO this should be an error and not just a warning, because

1) The standard says so

2) Other compilers reject it (so we can't argue that we must support this common extension)

3) Not rejecting it makes it really easy to corrupt memory. Consider

program x
  character(len=10) :: a, b, c
  a = "1234567890"
  b = a
  c = a
  call xx2(b)
  print *, '::', a, '::', b, '::', c, '::'
contains
  subroutine xx2(name)
    character(len=20), intent(inout) :: name
    name = 'hi'
  end subroutine xx2
end program

This prints (gfortran 4.4, x86_64 Linux):

$ ./chardummy2
 ::    567890::hi        ::1234567890::

That is, blanking out the remaining 18 characters at the end of the character b passed to xx2 overwrites part of the character a (why are only 4 characters overwritten and not all 10? because they are allocated 4/8/16? byte aligned on the stack). Note that neither bounds checking nor valgrind detects this error.

> 
> Missing is the check for array element designators: PR32616.

I haven't looked, but maybe PR30940 and PR32616 would need to be fixed as well?
Comment 8 Joost VandeVondele 2011-01-25 12:12:59 UTC
(In reply to comment #7)
> Reopening..

actually, I think this is a kind of error that should be caught at run-time with -fcheck=arguments (not to say bounds). I guess that's not so easy to implement, as it seem to imply that additional hidden subroutine arguments need to be passed around.
Comment 9 Tobias Burnus 2011-01-25 12:41:11 UTC
(In reply to comment #8)
> actually, I think this is a kind of error that should be caught at run-time
> with -fcheck=arguments (not to say bounds). I guess that's not so easy to
> implement, as it seem to imply that additional hidden subroutine arguments need
> to be passed around.

Well, that assumes that one compiles all files with the checking option. I like the idea better to have a global (static, SAVE) derived-type (struct) variable which contains the arguments and a function pointer. If loc(current function) == loc(function pointer) then the argument checking is done - else it is for a different function and no checking is done.
Comment 10 Tobias Burnus 2011-01-27 09:16:47 UTC
(In reply to comment #7)
> Sorry for being 'a bit' late with comments, but IMHO this should be an error
> and not just a warning, because
>
> 2) Other compilers reject it (so we can't argue that we must support this
> common extension)

Well, ifort and pathscale compile w/o warning and g95 with just a warning the example at:  gfortran.fortran-torture/execute/st_function.f90

Thus, for compare_actual_formal I would make a distinction between:

      /* Special case for character arguments.  For allocatable, pointer
         and assumed-shape dummies, the string length needs to match
         exactly.  */

where I agree that at least for pointer and allocatable an error should be printed - but probably also for assumed-shape dummies.

And to
      if (actual_size != 0
            && actual_size < formal_size
            && a->expr->ts.type != BT_PROCEDURE)

which can be less problematic and where a warning might be sufficient.
Comment 11 Joost VandeVondele 2011-01-27 13:22:49 UTC
I actually vaguely recall why this should be a warning, and not be checked for at runtime. This is for legacy codes using real :: a(1) instead of real :: a(*). Something like

SUBROUTINE S1(a)
  INTEGER :: a(10)
  a(10)=0
END SUBROUTINE

SUBROUTINE S2(a)
  INTEGER :: a(1)
  CALL S1(a)
END SUBROUTINE

INTEGER :: a(10)
CALL S2(a)
END

'works just fine'...
Comment 12 Dominique d'Humieres 2015-09-06 01:08:38 UTC
No activity for more than four years. AFAICT everything is fixed, but for comment 7 preferring an error instead of the warning. Since warnings can be turned into errors with -Werror, I don't think this PR should stay opened.
Comment 13 janus 2016-01-25 09:18:05 UTC
(In reply to Dominique d'Humieres from comment #12)
> AFAICT everything is fixed, but for
> comment 7 preferring an error instead of the warning. Since warnings can be
> turned into errors with -Werror, I don't think this PR should stay opened.

I disagree: Code like comment #0 should give an error by default. That's also what other compilers do (e.g. ifort & sunf95) and I don't see how this can be a useful 'extension'. It is certainly problematic code.
Comment 14 janus 2016-01-25 09:38:05 UTC
Legacy code like the one in comment #11 should be allowed with -std=legacy only (if at all).
Comment 15 Dominique d'Humieres 2016-01-25 10:52:33 UTC
> > AFAICT everything is fixed, but for
> > comment 7 preferring an error instead of the warning. Since warnings can be
> > turned into errors with -Werror, I don't think this PR should stay opened.
>
> I disagree: Code like comment #0 should give an error by default.
> That's also what other compilers do (e.g. ifort & sunf95) and I don't see
> how this can be a useful 'extension'. It is certainly problematic code.

The errors introduced at r124411 have been changed to warnings by Tobias Burnus at r126271, see the rationale at https://gcc.gnu.org/ml/fortran/2007-06/msg00519.html.

> Legacy code like the one in comment #11 should be allowed with -std=legacy
> only (if at all).

If there is an agreement about that, this is something that I can handle.

IMO this PR should be closed as FIXED and a new one should be opened for the warning->error conversion.
Comment 16 janus 2016-01-30 16:48:30 UTC
(In reply to Dominique d'Humieres from comment #15)
> The errors introduced at r124411 have been changed to warnings by Tobias
> Burnus at r126271

.. but only for the CHARACTER case. For non-character arrays there were never any errors, and a warning has been added only in the second commit you mention.


> > Legacy code like the one in comment #11 should be allowed with -std=legacy
> > only (if at all).
> 
> If there is an agreement about that, this is something that I can handle.

I'm not sure if there will be any agreement about it, but in any case here is a patch proposal:


Index: gcc/fortran/interface.c
===================================================================
--- gcc/fortran/interface.c	(Revision 233007)
+++ gcc/fortran/interface.c	(Arbeitskopie)
@@ -2787,10 +2787,10 @@
 			 f->sym->name, actual_size, formal_size,
 			 &a->expr->where);
           else if (where)
-	    gfc_warning (0, "Actual argument contains too few "
-			 "elements for dummy argument %qs (%lu/%lu) at %L",
-			 f->sym->name, actual_size, formal_size,
-			 &a->expr->where);
+	    gfc_notify_std (GFC_STD_LEGACY, "Actual argument contains too few "
+	                    "elements for dummy argument %qs (%lu/%lu) at %L",
+			    f->sym->name, actual_size, formal_size,
+			    &a->expr->where);
 	  return  0;
 	}
 

On comment 0 this gives a hard error with -std=f95/f2003/f2008, a warning (as before) with -std=gnu and no diagnostic at all with -std=legacy.

For comment 11 the behavior is almost unchanged, giving a warning for all -std levels except legacy.

The patch does not trigger any failures in the testsuite, which is certainly a good sign. It might still break some legacy codes, but they can just use -std=legacy (which they probably already do). Everyone else will rather benefit from the stricter diagnostics, I guess. It can catch some rather bad errors.

Any opinions on this?
Comment 17 Dominique d'Humieres 2016-01-30 16:54:40 UTC
> Any opinions on this?

It's fine for me.
Comment 18 Janne Blomqvist 2016-02-01 07:32:35 UTC
(In reply to janus from comment #16)
> Any opinions on this?

+1
Comment 19 Dominique d'Humieres 2016-11-11 17:23:50 UTC
> Any opinions on this?

So far 2 for, 0 against. May be the patch can be committed?
Comment 20 Jerry DeLisle 2016-11-11 22:25:38 UTC
(In reply to Dominique d'Humieres from comment #19)
> > Any opinions on this?
> 
> So far 2 for, 0 against. May be the patch can be committed?

Please do if you can, after testing on trunk.
Comment 21 Dominique d'Humieres 2017-09-18 10:15:36 UTC
> Please do if you can, after testing on trunk.

I can do it if Janus unassign himself.
Comment 22 janus 2017-09-19 18:18:23 UTC
On the current trunk, the patch produces one failure:

FAIL: gfortran.dg/warn_argument_mismatch_1.f90   -O  (test for excess errors)

Another problem is that it removes the warning for -std=legacy.

Do with it what you will ...
Comment 23 Dominique d'Humieres 2017-09-20 10:00:42 UTC
> On the current trunk, the patch produces one failure:
>
> FAIL: gfortran.dg/warn_argument_mismatch_1.f90   -O  (test for excess errors)
>
> Another problem is that it removes the warning for -std=legacy.
>
> Do with it what you will ...

Thanks for the pointers, they will save me some time. I think I can handle the problems myself.
Comment 24 Dominique d'Humieres 2017-09-24 15:09:31 UTC
Taking.
Comment 25 Dominique d'Humieres 2017-09-28 12:58:00 UTC
Patch at https://gcc.gnu.org/ml/fortran/2017-09/msg00126.html.
Comment 26 dominiq 2017-09-29 13:16:01 UTC
Author: dominiq
Date: Fri Sep 29 13:15:26 2017
New Revision: 253286

URL: https://gcc.gnu.org/viewcvs?rev=253286&root=gcc&view=rev
Log:
2017-09-29  Dominique d'Humieres  <dominiq@lps.ens.fr>

	PR fortran/25071
	* interface.c (compare_actual_formal): Change warnings to errors
	when "Actual argument contains too few elements for dummy
	argument", unless -std=legacy is used.


Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/interface.c
Comment 27 dominiq 2017-09-29 13:19:53 UTC
Author: dominiq
Date: Fri Sep 29 13:19:21 2017
New Revision: 253287

URL: https://gcc.gnu.org/viewcvs?rev=253287&root=gcc&view=rev
Log:
2017-09-29  Dominique d'Humieres  <dominiq@lps.ens.fr>

	PR fortran/25071
	* gfortran.dg/argument_checking_3.f90: Change warnings to errors.
	* gfortran.dg/argument_checking_4.f90: Likewise.
	* gfortran.dg/argument_checking_5.f90: Likewise.
	* gfortran.dg/argument_checking_6.f90: Likewise.
	* gfortran.dg/argument_checking_10.f90: Likewise.
	* gfortran.dg/argument_checking_13.f90: Likewise.
	* gfortran.dg/argument_checking_15.f90: Likewise.
	* gfortran.dg/argument_checking_18.f90: Likewise.
	* gfortran.dg/gomp/udr8.f90: Likewise.
	* gfortran.dg/warn_argument_mismatch_1.f90: Add -std=legacy to
	the dg-options.


Modified:
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/testsuite/gfortran.dg/argument_checking_10.f90
    trunk/gcc/testsuite/gfortran.dg/argument_checking_13.f90
    trunk/gcc/testsuite/gfortran.dg/argument_checking_15.f90
    trunk/gcc/testsuite/gfortran.dg/argument_checking_18.f90
    trunk/gcc/testsuite/gfortran.dg/argument_checking_3.f90
    trunk/gcc/testsuite/gfortran.dg/argument_checking_4.f90
    trunk/gcc/testsuite/gfortran.dg/argument_checking_5.f90
    trunk/gcc/testsuite/gfortran.dg/argument_checking_6.f90
    trunk/gcc/testsuite/gfortran.dg/gomp/udr8.f90
    trunk/gcc/testsuite/gfortran.dg/warn_argument_mismatch_1.f90
Comment 28 Dominique d'Humieres 2017-09-29 13:29:59 UTC
Closing.