re PR fortran/78670 ([F03] Incorrect file position with namelist read under DTIO)
2017-03-29 Jerry DeLisle <jvdelisle@gcc.gnu.org> PR libgfortran/78670 * io/list_read.c (nml_get_obj_data): Delete code which calls the child read procedure. (nml_read_obj): Insert the code which calls the child procedure. Don't need to touch nodes if using dtio since parent will not be traversing the components. PR libgfortran/78670 * gfortran.dg/dtio_25.f90: Use 'a1' format when trying to read a character of length 1. Update test for success. * gfortran.dg/dtio_28.f03: New test. * gfortran.dg/dtio_4.f90: Update to open test file with status = 'scratch' to delete the file when done. From-SVN: r246576
This commit is contained in:
parent
533c0b6943
commit
fdc54f39c1
@ -1,3 +1,12 @@
|
|||||||
|
2017-03-29 Jerry DeLisle <jvdelisle@gcc.gnu.org>
|
||||||
|
|
||||||
|
PR libgfortran/78670
|
||||||
|
* gfortran.dg/dtio_25.f90: Use 'a1' format when trying to read
|
||||||
|
a character of length 1. Update test for success.
|
||||||
|
* gfortran.dg/dtio_28.f03: New test.
|
||||||
|
* gfortran.dg/dtio_4.f90: Update to open test file with status =
|
||||||
|
'scratch' to delete the file when done.
|
||||||
|
|
||||||
2017-03-29 Segher Boessenkool <segher@kernel.crashing.org>
|
2017-03-29 Segher Boessenkool <segher@kernel.crashing.org>
|
||||||
|
|
||||||
PR rtl-optimization/80233
|
PR rtl-optimization/80233
|
||||||
|
@ -20,7 +20,7 @@ contains
|
|||||||
integer, intent(out) :: iostat
|
integer, intent(out) :: iostat
|
||||||
character(*), intent(inout) :: iomsg
|
character(*), intent(inout) :: iomsg
|
||||||
if (iotype.eq."NAMELIST") then
|
if (iotype.eq."NAMELIST") then
|
||||||
write (unit, '(a3,a1,i3)') dtv%c,',', dtv%k
|
write (unit, '(a1,a1,i3)') dtv%c,',', dtv%k
|
||||||
else
|
else
|
||||||
write (unit,*) dtv%c, dtv%k
|
write (unit,*) dtv%c, dtv%k
|
||||||
end if
|
end if
|
||||||
@ -34,7 +34,7 @@ contains
|
|||||||
character(*), intent(inout) :: iomsg
|
character(*), intent(inout) :: iomsg
|
||||||
character :: comma
|
character :: comma
|
||||||
if (iotype.eq."NAMELIST") then
|
if (iotype.eq."NAMELIST") then
|
||||||
read (unit, '(a4,a1,i3)') dtv%c, comma, dtv%k ! FIXME: need a4 here, with a3 above
|
read (unit, '(a1,a1,i3)') dtv%c, comma, dtv%k
|
||||||
else
|
else
|
||||||
read (unit,*) dtv%c, comma, dtv%k
|
read (unit,*) dtv%c, comma, dtv%k
|
||||||
end if
|
end if
|
||||||
@ -50,7 +50,7 @@ program p
|
|||||||
namelist /nml/ x
|
namelist /nml/ x
|
||||||
x = t('a', 5)
|
x = t('a', 5)
|
||||||
write (buffer, nml)
|
write (buffer, nml)
|
||||||
if (buffer.ne.'&NML X= a, 5 /') call abort
|
if (buffer.ne.'&NML X=a, 5 /') call abort
|
||||||
x = t('x', 0)
|
x = t('x', 0)
|
||||||
read (buffer, nml)
|
read (buffer, nml)
|
||||||
if (x%c.ne.'a'.or. x%k.ne.5) call abort
|
if (x%c.ne.'a'.or. x%k.ne.5) call abort
|
||||||
|
74
gcc/testsuite/gfortran.dg/dtio_28.f03
Normal file
74
gcc/testsuite/gfortran.dg/dtio_28.f03
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
! { dg-do run }
|
||||||
|
! PR78670 Incorrect file position with namelist read under DTIO
|
||||||
|
MODULE m
|
||||||
|
IMPLICIT NONE
|
||||||
|
TYPE :: t
|
||||||
|
CHARACTER :: c
|
||||||
|
CONTAINS
|
||||||
|
PROCEDURE :: read_formatted
|
||||||
|
GENERIC :: READ(FORMATTED) => read_formatted
|
||||||
|
PROCEDURE :: write_formatted
|
||||||
|
GENERIC :: WRITE(FORMATTED) => write_formatted
|
||||||
|
END TYPE t
|
||||||
|
CONTAINS
|
||||||
|
SUBROUTINE write_formatted(dtv, unit, iotype, v_list, iostat, iomsg)
|
||||||
|
CLASS(t), INTENT(IN) :: dtv
|
||||||
|
INTEGER, INTENT(IN) :: unit
|
||||||
|
CHARACTER(*), INTENT(IN) :: iotype
|
||||||
|
INTEGER, INTENT(IN) :: v_list(:)
|
||||||
|
INTEGER, INTENT(OUT) :: iostat
|
||||||
|
CHARACTER(*), INTENT(INOUT) :: iomsg
|
||||||
|
write(unit,'(a)', iostat=iostat, iomsg=iomsg) dtv%c
|
||||||
|
END SUBROUTINE write_formatted
|
||||||
|
|
||||||
|
SUBROUTINE read_formatted(dtv, unit, iotype, v_list, iostat, iomsg)
|
||||||
|
CLASS(t), INTENT(INOUT) :: dtv
|
||||||
|
INTEGER, INTENT(IN) :: unit
|
||||||
|
CHARACTER(*), INTENT(IN) :: iotype
|
||||||
|
INTEGER, INTENT(IN) :: v_list(:)
|
||||||
|
INTEGER, INTENT(OUT) :: iostat
|
||||||
|
CHARACTER(*), INTENT(INOUT) :: iomsg
|
||||||
|
|
||||||
|
CHARACTER :: ch
|
||||||
|
dtv%c = ''
|
||||||
|
DO
|
||||||
|
READ (unit, "(A)", IOSTAT=iostat, IOMSG=iomsg) ch
|
||||||
|
IF (iostat /= 0) RETURN
|
||||||
|
! Store first non-blank
|
||||||
|
IF (ch /= ' ') THEN
|
||||||
|
dtv%c = ch
|
||||||
|
RETURN
|
||||||
|
END IF
|
||||||
|
END DO
|
||||||
|
END SUBROUTINE read_formatted
|
||||||
|
END MODULE m
|
||||||
|
|
||||||
|
PROGRAM p
|
||||||
|
USE m
|
||||||
|
IMPLICIT NONE
|
||||||
|
TYPE(t) :: x
|
||||||
|
TYPE(t) :: y
|
||||||
|
TYPE(t) :: z
|
||||||
|
integer :: j, k
|
||||||
|
NAMELIST /nml/ j, x, y, z, k
|
||||||
|
INTEGER :: unit, iostatus
|
||||||
|
|
||||||
|
OPEN(NEWUNIT=unit, STATUS='SCRATCH', ACTION='READWRITE')
|
||||||
|
|
||||||
|
x%c = 'a'
|
||||||
|
y%c = 'b'
|
||||||
|
z%c = 'c'
|
||||||
|
j=1
|
||||||
|
k=2
|
||||||
|
WRITE(unit, nml)
|
||||||
|
REWIND (unit)
|
||||||
|
x%c = 'x'
|
||||||
|
y%c = 'y'
|
||||||
|
z%c = 'x'
|
||||||
|
j=99
|
||||||
|
k=99
|
||||||
|
READ (unit, nml, iostat=iostatus)
|
||||||
|
if (iostatus.ne.0) call abort
|
||||||
|
if (j.ne.1 .or. k.ne.2 .or. x%c.ne.'a' .or. y%c.ne.'b' .or. z%c.ne.'c') call abort
|
||||||
|
!WRITE(*, nml)
|
||||||
|
END PROGRAM p
|
@ -96,7 +96,7 @@ program test1
|
|||||||
if (iomsg.ne.'SUCCESS') call abort
|
if (iomsg.ne.'SUCCESS') call abort
|
||||||
if (any(udt1%myarray.ne.result_array)) call abort
|
if (any(udt1%myarray.ne.result_array)) call abort
|
||||||
close(10)
|
close(10)
|
||||||
open (10, form='formatted')
|
open (10, form='formatted', status='scratch')
|
||||||
write (10, '(dt)') more1
|
write (10, '(dt)') more1
|
||||||
rewind(10)
|
rewind(10)
|
||||||
more1%myarray = 99
|
more1%myarray = 99
|
||||||
|
@ -1,3 +1,11 @@
|
|||||||
|
2017-03-29 Jerry DeLisle <jvdelisle@gcc.gnu.org>
|
||||||
|
|
||||||
|
PR libgfortran/78670
|
||||||
|
* io/list_read.c (nml_get_obj_data): Delete code which calls the
|
||||||
|
child read procedure. (nml_read_obj): Insert the code which
|
||||||
|
calls the child procedure. Don't need to touch nodes if using
|
||||||
|
dtio since parent will not be traversing the components.
|
||||||
|
|
||||||
2017-03-28 Janus Weil <janus@gcc.gnu.org>
|
2017-03-28 Janus Weil <janus@gcc.gnu.org>
|
||||||
|
|
||||||
PR fortran/78661
|
PR fortran/78661
|
||||||
|
@ -2958,6 +2958,61 @@ nml_read_obj (st_parameter_dt *dtp, namelist_info * nl, index_type offset,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case BT_DERIVED:
|
case BT_DERIVED:
|
||||||
|
/* If this object has a User Defined procedure, call it. */
|
||||||
|
if (nl->dtio_sub != NULL)
|
||||||
|
{
|
||||||
|
int unit = dtp->u.p.current_unit->unit_number;
|
||||||
|
char iotype[] = "NAMELIST";
|
||||||
|
gfc_charlen_type iotype_len = 8;
|
||||||
|
char tmp_iomsg[IOMSG_LEN] = "";
|
||||||
|
char *child_iomsg;
|
||||||
|
gfc_charlen_type child_iomsg_len;
|
||||||
|
int noiostat;
|
||||||
|
int *child_iostat = NULL;
|
||||||
|
gfc_array_i4 vlist;
|
||||||
|
gfc_class list_obj;
|
||||||
|
formatted_dtio dtio_ptr = (formatted_dtio)nl->dtio_sub;
|
||||||
|
|
||||||
|
GFC_DESCRIPTOR_DATA(&vlist) = NULL;
|
||||||
|
GFC_DIMENSION_SET(vlist.dim[0],1, 0, 0);
|
||||||
|
|
||||||
|
list_obj.data = (void *)nl->mem_pos;
|
||||||
|
list_obj.vptr = nl->vtable;
|
||||||
|
list_obj.len = 0;
|
||||||
|
|
||||||
|
/* Set iostat, intent(out). */
|
||||||
|
noiostat = 0;
|
||||||
|
child_iostat = (dtp->common.flags & IOPARM_HAS_IOSTAT) ?
|
||||||
|
dtp->common.iostat : &noiostat;
|
||||||
|
|
||||||
|
/* Set iomsg, intent(inout). */
|
||||||
|
if (dtp->common.flags & IOPARM_HAS_IOMSG)
|
||||||
|
{
|
||||||
|
child_iomsg = dtp->common.iomsg;
|
||||||
|
child_iomsg_len = dtp->common.iomsg_len;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
child_iomsg = tmp_iomsg;
|
||||||
|
child_iomsg_len = IOMSG_LEN;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If reading from an internal unit, stash it to allow
|
||||||
|
the child procedure to access it. */
|
||||||
|
if (is_internal_unit (dtp))
|
||||||
|
stash_internal_unit (dtp);
|
||||||
|
|
||||||
|
/* Call the user defined formatted READ procedure. */
|
||||||
|
dtp->u.p.current_unit->child_dtio++;
|
||||||
|
dtio_ptr ((void *)&list_obj, &unit, iotype, &vlist,
|
||||||
|
child_iostat, child_iomsg,
|
||||||
|
iotype_len, child_iomsg_len);
|
||||||
|
dtp->u.p.child_saved_iostat = *child_iostat;
|
||||||
|
dtp->u.p.current_unit->child_dtio--;
|
||||||
|
goto incr_idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Must be default derived type namelist read. */
|
||||||
obj_name_len = strlen (nl->var_name) + 1;
|
obj_name_len = strlen (nl->var_name) + 1;
|
||||||
obj_name = xmalloc (obj_name_len+1);
|
obj_name = xmalloc (obj_name_len+1);
|
||||||
memcpy (obj_name, nl->var_name, obj_name_len-1);
|
memcpy (obj_name, nl->var_name, obj_name_len-1);
|
||||||
@ -3268,58 +3323,6 @@ get_name:
|
|||||||
|
|
||||||
goto nml_err_ret;
|
goto nml_err_ret;
|
||||||
}
|
}
|
||||||
else if (nl->dtio_sub != NULL)
|
|
||||||
{
|
|
||||||
int unit = dtp->u.p.current_unit->unit_number;
|
|
||||||
char iotype[] = "NAMELIST";
|
|
||||||
gfc_charlen_type iotype_len = 8;
|
|
||||||
char tmp_iomsg[IOMSG_LEN] = "";
|
|
||||||
char *child_iomsg;
|
|
||||||
gfc_charlen_type child_iomsg_len;
|
|
||||||
int noiostat;
|
|
||||||
int *child_iostat = NULL;
|
|
||||||
gfc_array_i4 vlist;
|
|
||||||
gfc_class list_obj;
|
|
||||||
formatted_dtio dtio_ptr = (formatted_dtio)nl->dtio_sub;
|
|
||||||
|
|
||||||
GFC_DESCRIPTOR_DATA(&vlist) = NULL;
|
|
||||||
GFC_DIMENSION_SET(vlist.dim[0],1, 0, 0);
|
|
||||||
|
|
||||||
list_obj.data = (void *)nl->mem_pos;
|
|
||||||
list_obj.vptr = nl->vtable;
|
|
||||||
list_obj.len = 0;
|
|
||||||
|
|
||||||
/* Set iostat, intent(out). */
|
|
||||||
noiostat = 0;
|
|
||||||
child_iostat = (dtp->common.flags & IOPARM_HAS_IOSTAT) ?
|
|
||||||
dtp->common.iostat : &noiostat;
|
|
||||||
|
|
||||||
/* Set iomsg, intent(inout). */
|
|
||||||
if (dtp->common.flags & IOPARM_HAS_IOMSG)
|
|
||||||
{
|
|
||||||
child_iomsg = dtp->common.iomsg;
|
|
||||||
child_iomsg_len = dtp->common.iomsg_len;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
child_iomsg = tmp_iomsg;
|
|
||||||
child_iomsg_len = IOMSG_LEN;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If reading from an internal unit, stash it to allow
|
|
||||||
the child procedure to access it. */
|
|
||||||
if (is_internal_unit (dtp))
|
|
||||||
stash_internal_unit (dtp);
|
|
||||||
|
|
||||||
/* Call the user defined formatted READ procedure. */
|
|
||||||
dtp->u.p.current_unit->child_dtio++;
|
|
||||||
dtio_ptr ((void *)&list_obj, &unit, iotype, &vlist,
|
|
||||||
child_iostat, child_iomsg,
|
|
||||||
iotype_len, child_iomsg_len);
|
|
||||||
dtp->u.p.current_unit->child_dtio--;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get the length, data length, base pointer and rank of the variable.
|
/* Get the length, data length, base pointer and rank of the variable.
|
||||||
Set the default loop specification first. */
|
Set the default loop specification first. */
|
||||||
@ -3466,11 +3469,12 @@ get_name:
|
|||||||
nl->var_name);
|
nl->var_name);
|
||||||
goto nml_err_ret;
|
goto nml_err_ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If a derived type, touch its components and restore the root
|
/* If a derived type, touch its components and restore the root
|
||||||
namelist_info if we have parsed a qualified derived type
|
namelist_info if we have parsed a qualified derived type
|
||||||
component. */
|
component. */
|
||||||
|
|
||||||
if (nl->type == BT_DERIVED)
|
if (nl->type == BT_DERIVED && nl->dtio_sub == NULL)
|
||||||
nml_touch_nodes (nl);
|
nml_touch_nodes (nl);
|
||||||
|
|
||||||
if (first_nl)
|
if (first_nl)
|
||||||
|
Loading…
Reference in New Issue
Block a user