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] PR30014 INQUIRE (iolength = xx) limited to kind=4


:ADDPATCH fortran:

The attached patch allows iolength and size parameters to be kind=8. The restriction to default integer kind in F95 is lifted in F2003. The patch adds a check for the kind for iolength similar to the existing check for the size parameter (there was no previous check on iolength).

This allows using integers of kind=8 for large file and large record IO operations without getting overflow.

A compile error is generated with -std=f95 if an integer of kind=8 is specified with the SIZE= in a formatted READ or IOLENGTH= in an INQUIRE. No errors are given for -std=F2003 or -std=gnu, etc.

Modified two test cases and added a third, (in the patch). I have attached an illustrative example case to try if you have sufficient resources. (Its not too bad, but I don't want this in the test suite. It takes 6 minutes, 34 seconds to execute on my system).

Regression tested on x86-64.

OK for trunk, and then later 4.2?

Regards,

Jerry

2006-12-26 Jerry DeLisle <jvdelisle@gcc.gnu.org>

	PR fortran/30014
	*io.c (resolve_tag): Don't issue error for tag_size type not being
	default integer size for -std=F2003.  Add similar check for
	tag_iolength.
	*ioparm.def: Change size and iolength parameters to ioint pointer, which
	corresponds to GFC_IO_INT on the library side.

2006-12-26 Jerry DeLisle <jvdelisle@gcc.gnu.org>

	PR libgfortran/30014
	*io/io.h (st_parameter_dt): Change *size and *iolength type to
	GFC_IO_INT.
	*io/transfer.c (finalize_transfer): Cast dtp->u.p.size_used to
	GFC_IO_INT.  (iolength_transfer): Cast size * nelems to GFC_IO_INT.
	
	
Index: gcc/testsuite/gfortran.dg/io_constraints_2.f90
===================================================================
*** gcc/testsuite/gfortran.dg/io_constraints_2.f90	(revision 120117)
--- gcc/testsuite/gfortran.dg/io_constraints_2.f90	(working copy)
*************** end module global
*** 53,58 ****
--- 53,60 ----
  ! Not allowed with an ADVANCE=specifier
   READ(buffer, fmt='(i6)', advance='YES') a      ! { dg-error "internal file" }
   READ(1, NML=NL, advance='YES')                 ! { dg-error "NAMELIST IO is not allowed" }
+  
+  READ(1, fmt='(i6)', advance='NO', size = ierr) ! { dg-error "requires default INTEGER" }
  
   READ(1, advance='YES')                         ! { dg-error "must appear with an explicit format" }
  
Index: gcc/testsuite/gfortran.dg/inquire_iolength.f90
===================================================================
*** gcc/testsuite/gfortran.dg/inquire_iolength.f90	(revision 0)
--- gcc/testsuite/gfortran.dg/inquire_iolength.f90	(revision 0)
***************
*** 0 ****
--- 1,10 ----
+ ! { dg-do compile}
+ ! { dg-options "-std=f95" }
+ ! PR30014 IOLENGTH does not handle KIND=8.  This patch checks the constraints.
+ ! Submitted by Jerry DeLisle  <jvdelisle@gcc.gnu.org>
+ ! F95 Standard 9.6, R923
+ integer (kind=4) small, x
+ integer (kind=8) large
+ inquire (iolength=small) x
+ inquire (iolength=large) x ! { dg-error "requires default INTEGER" }
+ end
Index: gcc/testsuite/gfortran.dg/io_constraints_1.f90
===================================================================
*** gcc/testsuite/gfortran.dg/io_constraints_1.f90	(revision 120117)
--- gcc/testsuite/gfortran.dg/io_constraints_1.f90	(working copy)
*************** end module global
*** 54,60 ****
  ! R912
  !Was correctly picked up before patch.
   write(6, NML=NL, iostat = ierr)                ! { dg-warning "requires default INTEGER" }
-  READ(1, fmt='(i6)', advance='NO', size = ierr) ! { dg-warning "requires default INTEGER" }
  
  ! Constraints
  !Was correctly picked up before patch.
--- 54,59 ----
Index: gcc/fortran/io.c
===================================================================
*** gcc/fortran/io.c	(revision 120117)
--- gcc/fortran/io.c	(working copy)
*************** resolve_tag (const io_tag * tag, gfc_exp
*** 1122,1128 ****
  
        if (tag == &tag_size && e->ts.kind != gfc_default_integer_kind)
  	{
! 	  if (gfc_notify_std (GFC_STD_GNU, "Fortran 95 requires default "
  			      "INTEGER in SIZE tag at %L",
  			      &e->where) == FAILURE)
  	    return FAILURE;
--- 1122,1128 ----
  
        if (tag == &tag_size && e->ts.kind != gfc_default_integer_kind)
  	{
! 	  if (gfc_notify_std (GFC_STD_F2003, "Fortran 95 requires default "
  			      "INTEGER in SIZE tag at %L",
  			      &e->where) == FAILURE)
  	    return FAILURE;
*************** resolve_tag (const io_tag * tag, gfc_exp
*** 1134,1139 ****
--- 1134,1147 ----
  			      &e->where) == FAILURE)
  	    return FAILURE;
  	}
+     
+       if (tag == &tag_iolength && e->ts.kind != gfc_default_integer_kind)
+ 	{
+ 	  if (gfc_notify_std (GFC_STD_F2003, "Fortran 95 requires default "
+ 			      "INTEGER in IOLENGTH tag at %L",
+ 			      &e->where) == FAILURE)
+ 	    return FAILURE;
+ 	}
      }
  
    return SUCCESS;
Index: gcc/fortran/ioparm.def
===================================================================
*** gcc/fortran/ioparm.def	(revision 120117)
--- gcc/fortran/ioparm.def	(working copy)
*************** IOPARM (inquire, convert,       1 << 30,
*** 60,67 ****
  #endif
  IOPARM (dt,      common,	0,	 common)
  IOPARM (dt,      rec,		1 << 9,  intio)
! IOPARM (dt,      size,		1 << 10, pint4)
! IOPARM (dt,      iolength,	1 << 11, pint4)
  IOPARM (dt,      internal_unit_desc, 0,  parray)
  IOPARM (dt,      format,	1 << 12, char1)
  IOPARM (dt,      advance,	1 << 13, char2)
--- 60,67 ----
  #endif
  IOPARM (dt,      common,	0,	 common)
  IOPARM (dt,      rec,		1 << 9,  intio)
! IOPARM (dt,      size,		1 << 10, pintio)
! IOPARM (dt,      iolength,	1 << 11, pintio)
  IOPARM (dt,      internal_unit_desc, 0,  parray)
  IOPARM (dt,      format,	1 << 12, char1)
  IOPARM (dt,      advance,	1 << 13, char2)
Index: libgfortran/io/io.h
===================================================================
*** libgfortran/io/io.h	(revision 120117)
--- libgfortran/io/io.h	(working copy)
*************** typedef struct st_parameter_dt
*** 354,360 ****
  {
    st_parameter_common common;
    GFC_IO_INT rec;
!   GFC_INTEGER_4 *size, *iolength;
    gfc_array_char *internal_unit_desc;
    CHARACTER1 (format);
    CHARACTER2 (advance);
--- 354,360 ----
  {
    st_parameter_common common;
    GFC_IO_INT rec;
!   GFC_IO_INT *size, *iolength;
    gfc_array_char *internal_unit_desc;
    CHARACTER1 (format);
    CHARACTER2 (advance);
Index: libgfortran/io/transfer.c
===================================================================
*** libgfortran/io/transfer.c	(revision 120117)
--- libgfortran/io/transfer.c	(working copy)
*************** finalize_transfer (st_parameter_dt *dtp)
*** 2539,2545 ****
    GFC_INTEGER_4 cf = dtp->common.flags;
  
    if ((dtp->common.flags & IOPARM_DT_HAS_SIZE) != 0)
!     *dtp->size = (GFC_INTEGER_4) dtp->u.p.size_used;
  
    if (dtp->u.p.eor_condition)
      {
--- 2539,2545 ----
    GFC_INTEGER_4 cf = dtp->common.flags;
  
    if ((dtp->common.flags & IOPARM_DT_HAS_SIZE) != 0)
!     *dtp->size = (GFC_IO_INT) dtp->u.p.size_used;
  
    if (dtp->u.p.eor_condition)
      {
*************** iolength_transfer (st_parameter_dt *dtp,
*** 2615,2621 ****
  		   size_t size, size_t nelems)
  {
    if ((dtp->common.flags & IOPARM_DT_HAS_IOLENGTH) != 0)
!     *dtp->iolength += (GFC_INTEGER_4) size * nelems;
  }
  
  
--- 2615,2621 ----
  		   size_t size, size_t nelems)
  {
    if ((dtp->common.flags & IOPARM_DT_HAS_IOLENGTH) != 0)
!     *dtp->iolength += (GFC_IO_INT) size * nelems;
  }
  
  
program subrecord
  integer, parameter :: arraydim = huge(1_4)/16
  real, dimension(arraydim) :: array
  integer :: x
  integer(kind=8) :: nrecl
  integer(kind=8) :: nbytes
  
  array = 3.14159
  x = 42
  nrecl = 0
  nbytes = 0
  inquire (iolength = nrecl) array,x,array,x,array,x,array,x,x,x
  print *, "record size =", nrecl
  open(10,form="formatted")
  write(10,'(a)') array,x,array,x,array,x,array,x,x,x
  rewind(10)
  read(10, '(a)', advance="no", size=nbytes) array,x,array,x,array,x,array,x,x,x
  print *, "size = ", nbytes
end program subrecord

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