This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Patch,Fortran] PR 40452 Fix false positive with -fcheck=bounds


Hi all,

this is a follow up to yesterday's patch (PR 40383). (Which was approved
by Daniel (and is checked in), but for some reason Daniel's email only
appeared in gcc-patches@ but not in fortran@ although the header looks OK.)
(The issue below is quite independent from yesterday's patch, except that
 I found problem while looking at PR 40383.)


The problem with the original patch (PR 37746) was that it does not take
argument association fully into account. The following program is valid
but as the string lengths do not match, a bogus error is printed at run
time (with -fcheck=bounds) [compile-time diagnostics works as is should]

  program test
    implicit none
    call sub(["ab", "cd"])
  contains
    subroutine sub(a)
     character(len=4) :: a(1)
     print *, a(1)
    end subroutine sub
  end program test


The reason that the program is valid is due to the argument association,
which associates the storage of "ab" + "cd" with the dummy argument a(1).
As both have exactly 4 bytes, everything is OK.

Fortran 95 has (12.4.1.4 Sequence association)
"If the actual argument is of type default character and is an array
 expression, array element, or array element substring designator, the
 element sequence consists of the character storage units beginning with
 the first storage unit of the actual argument and continuing to the end
 of the array. The character storage units of an array element substring
 designator are viewed as array elements consisting of consecutive groups
 of character storage units having the character length of the dummy
 array."

(Note the: "dummy array" which is crucial for this patch.)

Fortran 2003 has in 12.4.1.5 the same (except of allowing C_CHAR) and
then continues with
"If the actual argument is of type default character or of type character
 with the C character kind, and is a scalar that is not an array element
 or array element substring designator, the element sequence consists of
 the storage units of the actual argument."

(The addition is not important for us, but it allows to pass "a string"
 to a BIND(C) procedure which has "character(len=1):: str(*)".)


The fix is simple: Don't do the checking if the dummy is an array, only
if it is a scalar. Fortunately, this is the normal use and thus the check
remains useful.


Bootstrapped and regtested on x86-64-linux.
OK for the trunk?

Tobias
2009-06-16  Tobias Burnus  <burnus@net-b.de>

	PR fortran/40452
	* trans-decl.c (add_argument_checking): Disable bounds check
	for allowed argument storage association.

2009-06-16  Tobias Burnus  <burnus@net-b.de>

	PR fortran/40452
	* gfortran.dg/bounds_check_strlen_9.f90: New test.

Index: gcc/fortran/trans-decl.c
===================================================================
--- gcc/fortran/trans-decl.c	(Revision 148544)
+++ gcc/fortran/trans-decl.c	(Arbeitskopie)
@@ -3835,7 +3835,11 @@ add_argument_checking (stmtblock_t *bloc
 
 	/* For POINTER, ALLOCATABLE and assumed-shape dummy arguments, the
 	   string lengths must match exactly.  Otherwise, it is only required
-	   that the actual string length is *at least* the expected one.  */
+	   that the actual string length is *at least* the expected one.
+	   Sequence association allows for a mismatch of the string length
+	   if the actual argument is (part of) an array, but only if the
+	   dummy argument is an array. (See "Sequence association" in
+	   Section 12.4.1.4 for F95 and 12.4.1.5 for F2003.)  */
 	if (fsym->attr.pointer || fsym->attr.allocatable
 	    || (fsym->as && fsym->as->type == AS_ASSUMED_SHAPE))
 	  {
@@ -3843,6 +3847,8 @@ add_argument_checking (stmtblock_t *bloc
 	    message = _("Actual string length does not match the declared one"
 			" for dummy argument '%s' (%ld/%ld)");
 	  }
+	else if (fsym->as && fsym->as->rank != 0)
+	  continue;
 	else
 	  {
 	    comparison = LT_EXPR;
Index: gcc/testsuite/gfortran.dg/bounds_check_strlen_9.f90
===================================================================
--- gcc/testsuite/gfortran.dg/bounds_check_strlen_9.f90	(Revision 0)
+++ gcc/testsuite/gfortran.dg/bounds_check_strlen_9.f90	(Revision 0)
@@ -0,0 +1,20 @@
+! { dg-do run }
+! { dg-options "-fbounds-check" }
+!
+! PR fortran/40452
+! The following program is valid Fortran 90 and later.
+! The storage-sequence association of the dummy argument
+! allows that the actual argument ["ab", "cd"] is mapped
+! to the dummy argument a(1) which perfectly fits.
+! (The dummy needs to be an array, however.)
+!
+
+program test
+  implicit none
+  call sub(["ab", "cd"])
+contains
+  subroutine sub(a)
+   character(len=4) :: a(1)
+   print *, a(1)
+  end subroutine sub
+end program test

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]