https://gcc.gnu.org/bugzilla/show_bug.cgi?id=122957

            Bug ID: 122957
           Summary: -fdefault-integer-8 is results in wrong v_list in user
                    defined IO
           Product: gcc
           Version: unknown
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: libfortran
          Assignee: unassigned at gcc dot gnu.org
          Reporter: martin.pleissa at web dot de
  Target Milestone: ---

Consider the following simplified user defined IO write operation:

module mymod 
  type :: my_type
    real :: value 
  end type 

  interface write(formatted)
        module procedure  write_formatted
  end interface
contains
  subroutine write_formatted(dtv, unit, iotype, v_list, iostat, iomsg)
        class(my_type), intent(in) :: dtv
        integer, intent(in) :: unit
        character(*), intent(in) :: iotype
        integer, intent(in) :: v_list(:)
        integer, intent(out) :: iostat
        character(*), intent(inout) :: iomsg

        ! local
        real :: xx
        xx = dtv % value

        write(*,*) "v_list = | ", v_list , " |"
        write(unit, *) xx 
 end subroutine write_formatted
end module 

and a main proram 

program test_dt_io
  use mymod
  implicit none

  type(my_type) :: x

  x%value = 3.14159265

  write (*, *) x
  write (*, '(DT(8,3))') x
  write (*, '(DT)')  x
  write (*, '(DT(5))') x

end program test_dt_io


If I compile the program using gfortran -o test_io test_io.f90 I get 

 v_list = |  |   3.14159274    
 v_list = |            8           3  |   3.14159274    
 v_list = |  |   3.14159274    
 v_list = |            5  |   3.14159274

which is the expected result. If I add -fdefault-integer-8 to the list of
compile options, I get 

 v_list = |  |   3.14159274    
 v_list = |           12884901896                    0  |   3.14159274    
 v_list = |  |   3.14159274    
 v_list = |                     5  |   3.14159274  

which give a v_list not matching the given specifications. With ugly type casts
like 

  integer(kind = 4), pointer, dimenion(:) :: v_list_4
  v_list_ptr = c_loc(v_list)
  call c_f_pointer(v_list_ptr, v_list_4, [ size(v_list) ]) 

I can get the correct values from the v_list. This leads to the idea, that
-fdefault-integer-8 is omitted in this case. By adding "integer *4" to the
v_list dummy argument, the compiler claims:

   17 |   subroutine write_formatted(dtv, unit, iotype, v_list, iostat, iomsg)
      |                                                      1
   Error: DTIO dummy argument at (1) must be of KIND = 8


Looking a libgfortran/io/write.c in function list_formatted_write_scalar  we
have the hardcoded integer sizes 

  2141           GFC_INTEGER_4 unit = dtp->u.p.current_unit->unit_number;
  2142           char iotype[] = "LISTDIRECTED";
  2143           gfc_charlen_type iotype_len = 12;
  2144           char tmp_iomsg[IOMSG_LEN] = "";
  2145           char *child_iomsg;
  2146           gfc_charlen_type child_iomsg_len;
  2147           GFC_INTEGER_4 noiostat;
  2148           GFC_INTEGER_4 *child_iostat = NULL;
  2149           gfc_full_array_i4 vlist;

Mostlikely, read is also effected by this, since in libgfortran/io/list_read.c 
list_formatted_read_scalar we have

  2378           GFC_INTEGER_4 unit = dtp->u.p.current_unit->unit_number;
  2379           char iotype[] = "LISTDIRECTED";
  2380           gfc_charlen_type iotype_len = 12;
  2381           char tmp_iomsg[IOMSG_LEN];
  2382           char *child_iomsg;
  2383           gfc_charlen_type child_iomsg_len;
  2384           GFC_INTEGER_4 noiostat;
  2385           GFC_INTEGER_4 *child_iostat = NULL;                           
                                                                               
                                    2386           gfc_full_array_i4 vlist;
  2387 
  2388           GFC_DESCRIPTOR_DATA(&vlist) = NULL;
  2389           GFC_DIMENSION_SET(vlist.dim[0],1, 0, 0);

where the integer sizes are hard coded as well

Reply via email to