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, update] PR25289 Large file IO


:REVIEWMAIL:

The attached patch is an update incorporating FX comments.

Bootstrapped and regression tested.

This patch defines a new type GFC_LARGE_IO_INT and uses that to define rec in st_parameter_dt. off_t is preserved as is for the definition of gfc_offset.

OK for trunk?

Regards,

Jerry

2006-07-22 Jerry DeLisle <jvdelisle@gcc.gnu.org>

	PR fortran/25289
	* gfortran.h: Declare gfc_large_io_int_kind.
	* trans-types.c (gfc_init_kinds): Set gfc_large_io_int_kind
	to size 8 or 4.
	* trans-io.c (enum iofield_type): Add large_io_int type.
	(gfc_build_st_parameter): Same.
	(gfc_build_io_library_fndecls): Same.
	* ioparm_def: Use large_io_int to define rec.

2006-07-22 Jerry DeLisle <jvdelisle@gcc.gnu.org>

	PR libgfortran/25289
	* libgfortran.h: Add conditional definition of GFC_LARGE_IO_INT type.
	* io/io.h (st_parameter_dt): Define rec as type GFC_LARGE_IO_INT.
Index: gcc/fortran/gfortran.h
===================================================================
*** gcc/fortran/gfortran.h	(revision 115683)
--- gcc/fortran/gfortran.h	(working copy)
*************** extern int gfc_default_character_kind;
*** 1806,1811 ****
--- 1806,1812 ----
  extern int gfc_default_logical_kind;
  extern int gfc_default_complex_kind;
  extern int gfc_c_int_kind;
+ extern int gfc_large_io_int_kind;
  
  /* symbol.c */
  void gfc_clear_new_implicit (void);
Index: gcc/fortran/trans-types.c
===================================================================
*** gcc/fortran/trans-types.c	(revision 115683)
--- gcc/fortran/trans-types.c	(working copy)
*************** int gfc_default_logical_kind;
*** 93,98 ****
--- 93,102 ----
  int gfc_default_complex_kind;
  int gfc_c_int_kind;
  
+ /* The kind size used for record offsets. If the target system supports
+    kind=8, this will be set to 8, otherwise it is set to 4.  */
+ int gfc_large_io_int_kind; 
+ 
  /* Query the target to determine which machine modes are available for
     computation.  Choose KIND numbers for them.  */
  
*************** gfc_init_kinds (void)
*** 140,145 ****
--- 144,157 ----
        i_index += 1;
      }
  
+   /* Set the kind used to match gfc_offset in libgfortran.  This is used for
+      large file access.  */
+ 
+   if (saw_i8)
+     gfc_large_io_int_kind = 8;
+   else
+     gfc_large_io_int_kind = 4;
+ 
    /* Set the maximum integer kind.  Used with at least BOZ constants.  */
    gfc_max_integer_kind = gfc_integer_kinds[i_index - 1].kind;
  
Index: gcc/fortran/trans-io.c
===================================================================
*** gcc/fortran/trans-io.c	(revision 115683)
--- gcc/fortran/trans-io.c	(working copy)
*************** enum ioparam_type
*** 52,57 ****
--- 52,58 ----
  enum iofield_type
  {
    IOPARM_type_int4,
+   IOPARM_type_large_io_int,
    IOPARM_type_pint4,
    IOPARM_type_pchar,
    IOPARM_type_parray,
*************** gfc_build_st_parameter (enum ioparam_typ
*** 168,173 ****
--- 169,175 ----
        switch (p->type)
  	{
  	case IOPARM_type_int4:
+ 	case IOPARM_type_large_io_int:
  	case IOPARM_type_pint4:
  	case IOPARM_type_parray:
  	case IOPARM_type_pchar:
*************** void
*** 214,225 ****
--- 216,230 ----
  gfc_build_io_library_fndecls (void)
  {
    tree types[IOPARM_type_num], pad_idx, gfc_int4_type_node;
+   tree gfc_large_io_int_type_node;
    tree parm_type, dt_parm_type;
    tree gfc_c_int_type_node;
    HOST_WIDE_INT pad_size;
    enum ioparam_type ptype;
  
    types[IOPARM_type_int4] = gfc_int4_type_node = gfc_get_int_type (4);
+   types[IOPARM_type_large_io_int] = gfc_large_io_int_type_node
+ 			    = gfc_get_int_type (gfc_large_io_int_kind);
    types[IOPARM_type_pint4] = build_pointer_type (gfc_int4_type_node);
    types[IOPARM_type_parray] = pchar_type_node;
    types[IOPARM_type_pchar] = pchar_type_node;
Index: gcc/fortran/ioparm.def
===================================================================
*** gcc/fortran/ioparm.def	(revision 115683)
--- gcc/fortran/ioparm.def	(working copy)
*************** IOPARM (inquire, convert,       1 << 29,
*** 58,64 ****
  #define IOPARM_dt_namelist_read_mode	(1 << 8)
  #endif
  IOPARM (dt,      common,	0,	 common)
! IOPARM (dt,      rec,		1 << 9,  int4)
  IOPARM (dt,      size,		1 << 10, pint4)
  IOPARM (dt,      iolength,	1 << 11, pint4)
  IOPARM (dt,      internal_unit_desc, 0,  parray)
--- 58,64 ----
  #define IOPARM_dt_namelist_read_mode	(1 << 8)
  #endif
  IOPARM (dt,      common,	0,	 common)
! IOPARM (dt,      rec,		1 << 9,  large_io_int)
  IOPARM (dt,      size,		1 << 10, pint4)
  IOPARM (dt,      iolength,	1 << 11, pint4)
  IOPARM (dt,      internal_unit_desc, 0,  parray)
Index: libgfortran/libgfortran.h
===================================================================
*** libgfortran/libgfortran.h	(revision 115683)
--- libgfortran/libgfortran.h	(working copy)
*************** typedef off_t gfc_offset;
*** 196,201 ****
--- 196,211 ----
  
  #include "kinds.h"
  
+ /* Define the type used for the current record number for large file I/O.
+    The size must be consistent with the size defined on the compiler side.  */
+ #ifdef HAVE_GFC_INTEGER_8
+ typedef GFC_INTEGER_8 GFC_LARGE_IO_INT;
+ #else
+ #ifdef HAVE_GFC_INTEGER_4
+ typedef GFC_INTEGER_4 GFC_LARGE_IO_INT;
+ #endif
+ #endif
+ 
  /* The following two definitions must be consistent with the types used
     by the compiler.  */
  /* The type used of array indices, amongst other things.  */
Index: libgfortran/io/io.h
===================================================================
*** libgfortran/io/io.h	(revision 115683)
--- libgfortran/io/io.h	(working copy)
*************** struct format_data;
*** 351,357 ****
  typedef struct st_parameter_dt
  {
    st_parameter_common common;
!   GFC_INTEGER_4 rec;
    GFC_INTEGER_4 *size, *iolength;
    gfc_array_char *internal_unit_desc;
    CHARACTER1 (format);
--- 351,357 ----
  typedef struct st_parameter_dt
  {
    st_parameter_common common;
!   GFC_LARGE_IO_INT rec;
    GFC_INTEGER_4 *size, *iolength;
    gfc_array_char *internal_unit_desc;
    CHARACTER1 (format);
!{ dg-do run }
!{ dg-options "-std=gnu" }
! PR25289 Cannot handle record numbers larger than huge(0_4).
! This test checks that very large record numbers can be used.
! Derived from example in PR.
! Submitted by Jerry DeLisle  <jvdelisle@gcc.gnu.org>
      integer*1 abyte
      integer*8 n
      n = huge(0_4)
      n = n * 256
      abyte = 105
      open(10,file="foo",recl=2,form='unformatted',access='direct')
      write(10,rec=n) abyte
      abyte = 0
      read(10,rec=n) abyte
      if (abyte.ne.105) call abort()
      write(10,rec=1) abyte
      abyte = 0
      read(10,rec=1) abyte
      if (abyte.ne.105) call abort()
      n=n/2
      write(10,rec=n) abyte
      abyte = 0
      read(10,rec=n) abyte
      if (abyte.ne.105) call abort()
      close(10, status="delete")
      end
      

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