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 43228 - fix reading of arrays with strides in NAMELISTs


Hi all,

gfortran supports as extension that using

&nml  a(1,1) = 1, 2, 3, 4 /

reads the values to a(1,1) and the next contiguously following array
elements. Additionally, it support according to the standard:

&nml a(:,:) = 1,2,3,4,5,6 /
&nml a(:,1) = 1,2,3 /

However, for a(1,:) gfortran was effectively using
a(1:ubound(a,dim=1),:), leading to wrong results. The problem was that
when encountering "a(1" everything was prepared for "a(1,n)" extended
reading and moving back to array section reading for "a(1,:)" did not
happen. For "a(:" that mode was set right away and thus "a(:,1)" was
handled correctly.

The attached patch now recovers the non-extended read as soon as ":" is
read. As the previous dimensions have to be an element (otherwise a ":"
would have been encountered before), setting "end = start" recovers the
required bonds. (The end-bound setting is needed as otherwise the bonds
are end == ubound.)

Build and regtested on x86-64-linux. OK for the trunk? Shall this be
also backported to the 4.4 branch?

Tobias
2010-03-11  Tobias Burnus  <burnus@net-b.de>

	PR fortran/43228
	* io/list_read.c (nml_parse_qualifier): Disable expanded_read
	for array sections.

2010-03-11  Tobias Burnus  <burnus@net-b.de>

	PR fortran/43228
	* gfortran.dg/namelist_61.f90: New test.

Index: libgfortran/io/list_read.c
===================================================================
--- libgfortran/io/list_read.c	(revision 157383)
+++ libgfortran/io/list_read.c	(working copy)
@@ -2091,6 +2091,14 @@ nml_parse_qualifier (st_parameter_dt *dt
 	    }
 	}
 
+      if (is_array_section == 1 && dtp->u.p.expanded_read == 1)
+     	{
+	  int i;
+	  dtp->u.p.expanded_read = 0;
+	  for (i = 0; i < dim; i++)
+	    ls[i].end = ls[i].start;
+      	}
+
       /* Check the values of the triplet indices.  */
       if ((ls[dim].start > (ssize_t) GFC_DIMENSION_UBOUND(ad[dim]))
 	   || (ls[dim].start < (ssize_t) GFC_DIMENSION_LBOUND(ad[dim]))
Index: gcc/testsuite/gfortran.dg/namelist_61.f90
===================================================================
--- gcc/testsuite/gfortran.dg/namelist_61.f90	(revision 0)
+++ gcc/testsuite/gfortran.dg/namelist_61.f90	(revision 0)
@@ -0,0 +1,35 @@
+! { dg-do run }
+!
+! PR fortran/43228
+!
+integer :: a(3,3)
+character(len=100) :: str
+namelist /nml/a
+
+a = -1
+str = '&nml a(1,:) = 1 2 3 /'
+read(str, nml=nml)
+if (any (a(1,:) /= [1, 2, 3])) call abort ()
+if (any (a([2,3],:) /= -1)) call abort ()
+
+a = -1
+str = '&nml a(1,1) = 1 2 3 4 /'
+read(str, nml=nml)
+if (any (a(:,1) /= [1, 2, 3])) call abort ()
+if (any (a(:,2) /= [4, -1, -1])) call abort ()
+if (any (a(:,3) /= -1)) call abort ()
+
+str = '&nml a(1,:) = 1 2 3 , &
+       &    a(2,:) = 4,5,6 &
+       &    a(3,:) = 7 8 9/'
+read(str, nml=nml)
+if (any (a(1,:) /= [1, 2, 3])) call abort ()
+if (any (a(2,:) /= [4, 5, 6])) call abort ()
+if (any (a(3,:) /= [7, 8, 9])) call abort ()
+
+!print *, a(:,1)
+!print *, a(:,2)
+!print *, a(:,3)
+end
+
+

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