This is the mail archive of the
fortran@gcc.gnu.org
mailing list for the GNU Fortran project.
[patch, libgfortran] PR61640 KIND=4 Character Array Internal Unit Read Fail
- From: Jerry DeLisle <jvdelisle at charter dot net>
- To: gfortran <fortran at gcc dot gnu dot org>
- Cc: gcc patches <gcc-patches at gcc dot gnu dot org>
- Date: Sat, 28 Jun 2014 16:12:54 -0700
- Subject: [patch, libgfortran] PR61640 KIND=4 Character Array Internal Unit Read Fail
- Authentication-results: sourceware.org; auth=none
The attached patch is obvious and simple. I will commit to trunk soon.
There are two things obvious about this.
1) Using the wrong function for wide characters.
2) No one must be using this feature of Fortran since the bug exists at least
back to 4.5
;)
Regression tested on x86-64-linux-gnu.
Test case attached. I would suggest since it is a wrong code bug, we should at
least port to 4.9.1. I will wait a while before doing that and won't if anyone
feels strongly about not doing so. A portion of the patch in eat_spaces is a
correction to the fix for PR61499 for KIND=4.
Regards,
Jerry
2014-06-28 Jerry DeLisle <jvdelisle@gcc.gnu.org>
PR libgfortran/61640
* io/list_read.c (next_char_internal): Adjust the read length to
a single wide character. (eat_spaces): Add missing paren.
* io/unix.c (mem_read4): Use the correct mem_alloc function for
wide character internal reads.
Index: list_read.c
===================================================================
--- list_read.c (revision 212104)
+++ list_read.c (working copy)
@@ -273,7 +273,7 @@ next_char_internal (st_parameter_dt *dtp)
/* Get the next character and handle end-of-record conditions. */
if (dtp->common.unit) /* Check for kind=4 internal unit. */
- length = sread (dtp->u.p.current_unit->s, &c, sizeof (gfc_char4_t));
+ length = sread (dtp->u.p.current_unit->s, &c, 1);
else
{
char cc;
@@ -399,7 +399,7 @@ eat_spaces (st_parameter_dt *dtp)
{
for (i = 0; i < dtp->u.p.current_unit->bytes_left; i++)
{
- if (dtp->internal_unit[offset + i * sizeof (gfc_char4_t)]
+ if (dtp->internal_unit[(offset + i) * sizeof (gfc_char4_t)]
!= (gfc_char4_t)' ')
break;
}
Index: unix.c
===================================================================
--- unix.c (revision 212104)
+++ unix.c (working copy)
@@ -808,10 +808,10 @@ mem_read4 (stream * s, void * buf, ssize_t nbytes)
void *p;
int nb = nbytes;
- p = mem_alloc_r (s, &nb);
+ p = mem_alloc_r4 (s, &nb);
if (p)
{
- memcpy (buf, p, nb);
+ memcpy (buf, p, nb * 4);
return (ssize_t) nb;
}
else
! { dg-do run }
! PR61640 KIND=4 Character Array Internal Unit Read Fail
program read_internal
integer :: x(9),i
integer :: y(9)
character(kind=4,len=30), dimension(3) :: source
y = reshape ((/ 1,1,-1,1,-1,1,-1,1,1 /), shape(x))
source=[4_" 1 1 -1",4_" 1 -1 1",4_" -1 1 1"]
!print *, (trim(source(i)), i=1,3)
read(source,*) (x(i), i=1,9) ! This read fails for KIND=4 character
if (any(x /= y )) call abort
end program read_internal