https://gcc.gnu.org/g:f5a31b42af92e91cc94d1b0a6eea4fbea34c6dea

commit f5a31b42af92e91cc94d1b0a6eea4fbea34c6dea
Author: Mikael Morin <[email protected]>
Date:   Tue Oct 7 20:30:40 2025 +0200

    Correction partielle maxval_char_2.f90

Diff:
---
 libgfortran/io/transfer.c |  2 ++
 libgfortran/io/unix.c     | 36 ++++++++++++++++++++++++++++--------
 2 files changed, 30 insertions(+), 8 deletions(-)

diff --git a/libgfortran/io/transfer.c b/libgfortran/io/transfer.c
index a223c09dda88..1b163421a481 100644
--- a/libgfortran/io/transfer.c
+++ b/libgfortran/io/transfer.c
@@ -4240,6 +4240,8 @@ next_record_w (st_parameter_dt *dtp, int done)
              if (max_pos > m)
                {
                  length = (max_pos - m);
+                 if (unlikely (is_char4_unit (dtp)))
+                   length *= sizeof (gfc_char4_t);
                  if (sseek (dtp->u.p.current_unit->s,
                             length, SEEK_CUR) < 0)
                    {
diff --git a/libgfortran/io/unix.c b/libgfortran/io/unix.c
index a0b9f547000c..b44c2fdfd69b 100644
--- a/libgfortran/io/unix.c
+++ b/libgfortran/io/unix.c
@@ -833,17 +833,18 @@ mem_alloc_r4 (stream *strm, size_t *len)
   unix_stream *s = (unix_stream *) strm;
   gfc_offset n;
   gfc_offset where = s->logical_offset;
+  const gfc_offset unit_size = sizeof (gfc_char4_t);
 
   if (where < s->buffer_offset || where > s->buffer_offset + s->active)
     return NULL;
 
-  n = s->buffer_offset + s->active - where;
+  n = (s->buffer_offset + s->active - where) / unit_size;
   if ((gfc_offset) *len > n)
     *len = n;
 
-  s->logical_offset = where + *len;
+  s->logical_offset = where + *len * unit_size;
 
-  return s->buffer + (where - s->buffer_offset) * 4;
+  return s->buffer + (where - s->buffer_offset);
 }
 
 
@@ -874,9 +875,9 @@ mem_alloc_w4 (stream *strm, size_t *len)
   unix_stream *s = (unix_stream *)strm;
   gfc_offset m;
   gfc_offset where = s->logical_offset;
-  gfc_char4_t *result = (gfc_char4_t *) s->buffer;
+  const gfc_offset unit_size = sizeof (gfc_char4_t);
 
-  m = where + *len;
+  m = where + *len * unit_size;
 
   if (where < s->buffer_offset)
     return NULL;
@@ -885,7 +886,7 @@ mem_alloc_w4 (stream *strm, size_t *len)
     return NULL;
 
   s->logical_offset = m;
-  return &result[where - s->buffer_offset];
+  return (gfc_char4_t *) (s->buffer + (where - s->buffer_offset));
 }
 
 
@@ -908,6 +909,25 @@ mem_read (stream *s, void *buf, ssize_t nbytes)
 }
 
 
+/* Stream read function for chracter(kind=4) internal units.  */
+
+static ssize_t
+mem_read4 (stream *s, void *buf, ssize_t nbytes)
+{
+  void *p;
+  size_t nb = nbytes;
+
+  p = mem_alloc_r4 (s, &nb);
+  if (p)
+    {
+      memcpy (buf, p, nb * 4);
+      return (ssize_t) nb;
+    }
+  else
+    return 0;
+}
+
+
 /* Stream write function for character(kind=1) internal units.  */
 
 static ssize_t
@@ -1028,7 +1048,7 @@ static const struct stream_vtable mem_vtable = {
 };
 
 static const struct stream_vtable mem4_vtable = {
-  .read = (void *) mem_read,
+  .read = (void *) mem_read4,
   .write = (void *) mem_write4,
   .seek = (void *) mem_seek,
   .tell = (void *) mem_tell,
@@ -1079,7 +1099,7 @@ open_internal4 (char *base, size_t length, gfc_offset 
offset)
   s->buffer = base;
   s->buffer_offset = offset;
 
-  s->active = s->file_length = length * sizeof (gfc_char4_t);
+  s->active = s->file_length = length;
 
   s->st.vptr = &mem4_vtable;

Reply via email to