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