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

commit b44e7c167c3d05d175f84423707241ba7847bb77
Author: Thomas Koenig <tkoe...@gcc.gnu.org>
Date:   Sun Jul 28 14:29:42 2024 +0200

    Implement decimal list-directed I/O.

Diff:
---
 gcc/fortran/gfortran.h                   |  10 +-
 gcc/fortran/primary.cc                   |   3 +-
 gcc/fortran/simplify.cc                  |   4 +-
 gcc/fortran/trans-io.cc                  |  19 ++++
 gcc/testsuite/gfortran.dg/unsigned_1.f90 |   7 +-
 gcc/testsuite/gfortran.dg/unsigned_2.f90 |  20 ++++
 libgfortran/gfortran.map                 |   2 +
 libgfortran/io/io.h                      |   6 ++
 libgfortran/io/list_read.c               |  92 +++++++++++++++--
 libgfortran/io/read.c                    |  78 ++++++++++++++
 libgfortran/io/transfer.c                |  20 ++++
 libgfortran/io/write.c                   | 171 +++++++++++++++++++++++++++++++
 libgfortran/libgfortran.h                |  14 ++-
 libgfortran/mk-kinds-h.sh                |   1 +
 14 files changed, 426 insertions(+), 21 deletions(-)

diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h
index d7bbcf6cdcde..1e3262f97bf2 100644
--- a/gcc/fortran/gfortran.h
+++ b/gcc/fortran/gfortran.h
@@ -677,7 +677,6 @@ enum gfc_isym_id
   GFC_ISYM_STOPPED_IMAGES,
   GFC_ISYM_STORAGE_SIZE,
   GFC_ISYM_STRIDE,
-  GFC_ISYM_SU_KIND,
   GFC_ISYM_SUM,
   GFC_ISYM_SYMLINK,
   GFC_ISYM_SYMLNK,
@@ -706,7 +705,12 @@ enum gfc_isym_id
   GFC_ISYM_Y0,
   GFC_ISYM_Y1,
   GFC_ISYM_YN,
-  GFC_ISYM_YN2
+  GFC_ISYM_YN2,
+
+  /* Add this at the end, so maybe the module format
+     remains compatible.  */
+  GFC_ISYM_SU_KIND
+
 };
 
 enum init_local_logical
@@ -4108,7 +4112,7 @@ void gfc_convert_mpz_to_signed (mpz_t, int);
 gfc_expr *gfc_simplify_ieee_functions (gfc_expr *);
 bool gfc_is_constant_array_expr (gfc_expr *);
 bool gfc_is_size_zero_array (gfc_expr *);
-void gfc_convert_mpz_to_unsigned (mpz_t, int);
+void gfc_convert_mpz_to_unsigned (mpz_t, int, bool check = true);
 
 /* trans-array.cc  */
 
diff --git a/gcc/fortran/primary.cc b/gcc/fortran/primary.cc
index c1aa0bc77c91..63b0bcf6784d 100644
--- a/gcc/fortran/primary.cc
+++ b/gcc/fortran/primary.cc
@@ -229,7 +229,8 @@ convert_unsigned (const char *buffer, int kind, int radix, 
locus *where)
   mpz_set_str (e->value.integer, t, radix);
 
   k = gfc_validate_kind (BT_UNSIGNED, kind, false);
-  gfc_convert_mpz_to_unsigned (e->value.integer, 
gfc_unsigned_kinds[k].bit_size);
+  gfc_convert_mpz_to_unsigned (e->value.integer, 
gfc_unsigned_kinds[k].bit_size,
+                              false);
 
   return e;
 }
diff --git a/gcc/fortran/simplify.cc b/gcc/fortran/simplify.cc
index b96f5ee713e3..a8c9397edf97 100644
--- a/gcc/fortran/simplify.cc
+++ b/gcc/fortran/simplify.cc
@@ -148,7 +148,7 @@ get_kind (bt type, gfc_expr *k, const char *name, int 
default_kind)
    be accomplished by masking out the high bits.  */
 
 void
-gfc_convert_mpz_to_unsigned (mpz_t x, int bitsize)
+gfc_convert_mpz_to_unsigned (mpz_t x, int bitsize, bool check)
 {
   mpz_t mask;
 
@@ -171,7 +171,7 @@ gfc_convert_mpz_to_unsigned (mpz_t x, int bitsize)
     {
       /* Confirm that no bits above the signed range are set if we
         are doing range checking.  */
-      if (flag_range_check != 0)
+      if (check && flag_range_check != 0)
        gcc_assert (mpz_scan1 (x, bitsize-1) == ULONG_MAX);
     }
 }
diff --git a/gcc/fortran/trans-io.cc b/gcc/fortran/trans-io.cc
index 7ab82fa2f5b1..e9e67a0d6b81 100644
--- a/gcc/fortran/trans-io.cc
+++ b/gcc/fortran/trans-io.cc
@@ -117,6 +117,8 @@ enum iocall
   IOCALL_WRITE_DONE,
   IOCALL_X_INTEGER,
   IOCALL_X_INTEGER_WRITE,
+  IOCALL_X_UNSIGNED,
+  IOCALL_X_UNSIGNED_WRITE,
   IOCALL_X_LOGICAL,
   IOCALL_X_LOGICAL_WRITE,
   IOCALL_X_CHARACTER,
@@ -335,6 +337,14 @@ gfc_build_io_library_fndecls (void)
        get_identifier (PREFIX("transfer_integer_write")), ". w R . ",
        void_type_node, 3, dt_parm_type, pvoid_type_node, gfc_int4_type_node);
 
+  iocall[IOCALL_X_UNSIGNED] = gfc_build_library_function_decl_with_spec (
+       get_identifier (PREFIX("transfer_unsigned")), ". w W . ",
+       void_type_node, 3, dt_parm_type, pvoid_type_node, gfc_int4_type_node);
+
+  iocall[IOCALL_X_UNSIGNED_WRITE] = gfc_build_library_function_decl_with_spec (
+       get_identifier (PREFIX("transfer_unsigned_write")), ". w R . ",
+       void_type_node, 3, dt_parm_type, pvoid_type_node, gfc_int4_type_node);
+
   iocall[IOCALL_X_LOGICAL] = gfc_build_library_function_decl_with_spec (
        get_identifier (PREFIX("transfer_logical")), ". w W . ",
        void_type_node, 3, dt_parm_type, pvoid_type_node, gfc_int4_type_node);
@@ -2341,6 +2351,15 @@ transfer_expr (gfc_se * se, gfc_typespec * ts, tree 
addr_expr,
 
       break;
 
+    case BT_UNSIGNED:
+      arg2 = build_int_cst (unsigned_type_node, kind);
+      if (last_dt == READ)
+       function = iocall[IOCALL_X_UNSIGNED];
+      else
+       function = iocall[IOCALL_X_UNSIGNED_WRITE];
+
+      break;
+
     case BT_REAL:
       arg2 = build_int_cst (integer_type_node, kind);
       if (last_dt == READ)
diff --git a/gcc/testsuite/gfortran.dg/unsigned_1.f90 
b/gcc/testsuite/gfortran.dg/unsigned_1.f90
index a5f110aa0ab5..ed1a6eed937e 100644
--- a/gcc/testsuite/gfortran.dg/unsigned_1.f90
+++ b/gcc/testsuite/gfortran.dg/unsigned_1.f90
@@ -1,11 +1,16 @@
 ! { dg-do run }
 ! { dg-options "-funsigned" }
-! Test basic assignment, arithmetic and a condition.
+! Test some arithmetic ans selected_unsigned_kind.
 program memain
   unsigned :: u, v
+  integer, parameter :: u1 = selected_unsigned_kind(2), &
+       u2 = selected_unsigned_kind(4), &
+       u4 = selected_unsigned_kind(6), &
+       u8 = selected_unsigned_kind(10)
   u = 1u
   v = 42u
   if (u + v /= 43u) then
      stop 1
   end if
+  if (u1 /= 1 .or. u2 /= 2 .or. u4 /= 4 .or. u8 /= 8) stop 2
 end program memain
diff --git a/gcc/testsuite/gfortran.dg/unsigned_2.f90 
b/gcc/testsuite/gfortran.dg/unsigned_2.f90
new file mode 100644
index 000000000000..e55e0f51a6df
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/unsigned_2.f90
@@ -0,0 +1,20 @@
+! { dg-do run }
+! { dg-additional-options -funsigned }
+! Test some list-directed I/O
+program main
+  implicit none
+  unsigned :: uw, ur, vr
+  unsigned(kind=8) :: u8
+  uw = 10u
+  open (10, status="scratch")
+  write (10,*) uw,-1
+  rewind 10
+  read (10,*) ur,vr
+  if (ur /= 10u .or. vr /= 4294967295u) stop 1
+  rewind 10
+  write (10,*) 17179869184u_8
+  rewind 10
+  read (10,*) u8
+  if (u8 /= 17179869184u_8) stop 2
+end program main
+  
diff --git a/libgfortran/gfortran.map b/libgfortran/gfortran.map
index 82f8f3c5e9ca..e71cbcf23768 100644
--- a/libgfortran/gfortran.map
+++ b/libgfortran/gfortran.map
@@ -1775,4 +1775,6 @@ GFORTRAN_15 {
   global:
     _gfortran_internal_pack_class;
     _gfortran_internal_unpack_class;
+    _gfortran_transfer_unsigned;
+    _gfortran_transfer_unsigned_write;
 } GFORTRAN_14;
diff --git a/libgfortran/io/io.h b/libgfortran/io/io.h
index 1c23676cc4c1..32e2b825ed5b 100644
--- a/libgfortran/io/io.h
+++ b/libgfortran/io/io.h
@@ -861,9 +861,15 @@ internal_proto (transfer_array_inner);
 extern void set_integer (void *, GFC_INTEGER_LARGEST, int);
 internal_proto(set_integer);
 
+extern void set_unsigned (void *, GFC_UINTEGER_LARGEST, int);
+internal_proto(set_unsigned);
+
 extern GFC_UINTEGER_LARGEST si_max (int);
 internal_proto(si_max);
 
+extern GFC_UINTEGER_LARGEST us_max (int);
+internal_proto(us_max);
+
 extern int convert_real (st_parameter_dt *, void *, const char *, int);
 internal_proto(convert_real);
 
diff --git a/libgfortran/io/list_read.c b/libgfortran/io/list_read.c
index 96b2efe854f5..9e3fffe56143 100644
--- a/libgfortran/io/list_read.c
+++ b/libgfortran/io/list_read.c
@@ -722,6 +722,65 @@ convert_integer (st_parameter_dt *dtp, int length, int 
negative)
   return 1;
 }
 
+/* Same as above, but for unsigneds, where we do not need overflow checks,
+ except on the repeat count.  */
+
+static int
+convert_unsigned (st_parameter_dt *dtp, int length, int negative)
+{
+  char c, *buffer, message[IOMSG_LEN];
+  GFC_UINTEGER_LARGEST v, value;
+  GFC_UINTEGER_8 max;
+  int m;
+
+  buffer = dtp->u.p.saved_string;
+  max = length == -1 ? 0 : MAX_REPEAT;
+
+  for (;;)
+    {
+      c = *buffer++;
+      if (c == '\0')
+       break;
+      c -= '0';
+      v += c;
+      if (length == -1 && v > max)
+       goto overflow;
+    }
+
+  m = 0;
+
+  if (length == -1)
+    {
+      if (negative)
+       value = -v;
+      else
+       value = v;
+
+      value = value & us_max (length);
+      set_unsigned (dtp->u.p.value, value, length);
+    }
+  else
+    {
+      dtp->u.p.repeat_count = v;
+
+      if (dtp->u.p.repeat_count == 0)
+       {
+         snprintf (message, IOMSG_LEN, "Zero repeat count in item %d of list 
input",
+                  dtp->u.p.item_count);
+
+         generate_error (&dtp->common, LIBERROR_READ_VALUE, message);
+         m = 1;
+       }
+    }
+  free_saved (dtp);
+  return m;
+
+ overflow:
+  snprintf (message, IOMSG_LEN, "Repeat count overflow in item %d of list 
input",
+           dtp->u.p.item_count);
+
+  return 1;
+}
 
 /* Parse a repeat count for logical and complex values which cannot
    begin with a digit.  Returns nonzero if we are done, zero if we
@@ -990,7 +1049,7 @@ read_logical (st_parameter_dt *dtp, int length)
    used for repeat counts.  */
 
 static void
-read_integer (st_parameter_dt *dtp, int length)
+read_integer (st_parameter_dt *dtp, int length, bt type)
 {
   char message[IOMSG_LEN];
   int c, negative;
@@ -1055,8 +1114,16 @@ read_integer (st_parameter_dt *dtp, int length)
     }
 
  repeat:
-  if (convert_integer (dtp, -1, 0))
-    return;
+  if (type == BT_INTEGER)
+    {
+      if (convert_integer (dtp, -1, 0))
+       return;
+    }
+  else
+    {
+      if (convert_unsigned (dtp, -1, 0))
+      return;
+    }
 
   /* Get the real integer.  */
 
@@ -1127,8 +1194,13 @@ read_integer (st_parameter_dt *dtp, int length)
   else if (c != '\n')
     eat_line (dtp);
 
-  snprintf (message, IOMSG_LEN, "Bad integer for item %d in list input",
+  if (type == BT_INTEGER)
+    snprintf (message, IOMSG_LEN, "Bad integer for item %d in list input",
              dtp->u.p.item_count);
+  else
+    snprintf (message, IOMSG_LEN, "Bad unsigned for item %d in list input",
+             dtp->u.p.item_count);
+
   free_line (dtp);
   generate_error (&dtp->common, LIBERROR_READ_VALUE, message);
 
@@ -1139,17 +1211,16 @@ read_integer (st_parameter_dt *dtp, int length)
   eat_separator (dtp);
 
   push_char (dtp, '\0');
-  if (convert_integer (dtp, length, negative))
+  if (convert_integer (dtp, length, negative)) /* XXX */
     {
        free_saved (dtp);
        return;
     }
 
   free_saved (dtp);
-  dtp->u.p.saved_type = BT_INTEGER;
+  dtp->u.p.saved_type = type;
 }
 
-
 /* Read a character variable.  */
 
 static void
@@ -2224,7 +2295,8 @@ list_formatted_read_scalar (st_parameter_dt *dtp, bt 
type, void *p,
   switch (type)
     {
     case BT_INTEGER:
-      read_integer (dtp, kind);
+    case BT_UNSIGNED:
+      read_integer (dtp, kind, type);
       break;
     case BT_LOGICAL:
       read_logical (dtp, kind);
@@ -2318,6 +2390,7 @@ list_formatted_read_scalar (st_parameter_dt *dtp, bt 
type, void *p,
       break;
 
     case BT_INTEGER:
+    case BT_UNSIGNED:
     case BT_LOGICAL:
       memcpy (p, dtp->u.p.value, size);
       break;
@@ -3029,7 +3102,8 @@ nml_read_obj (st_parameter_dt *dtp, namelist_info *nl, 
index_type offset,
           switch (nl->type)
          {
          case BT_INTEGER:
-           read_integer (dtp, len);
+         case BT_UNSIGNED:
+           read_integer (dtp, len, nl->type);
             break;
 
          case BT_LOGICAL:
diff --git a/libgfortran/io/read.c b/libgfortran/io/read.c
index 7a9e341d7d80..2fb39392fc99 100644
--- a/libgfortran/io/read.c
+++ b/libgfortran/io/read.c
@@ -92,6 +92,62 @@ set_integer (void *dest, GFC_INTEGER_LARGEST value, int 
length)
     }
 }
 
+/* set_integer()-- All of the integer assignments come here to
+   actually place the value into memory.  */
+
+void
+set_unsigned (void *dest, GFC_UINTEGER_LARGEST value, int length)
+{
+  NOTE ("set_integer: %lld %p", (long long int) value, dest);
+  switch (length)
+    {
+#ifdef HAVE_GFC_UINTEGER_16
+#ifdef HAVE_GFC_REAL_17
+    case 17:
+      {
+       GFC_UINTEGER_16 tmp = value;
+       memcpy (dest, (void *) &tmp, 16);
+      }
+      break;
+#endif
+/* length=10 comes about for kind=10 real/complex BOZ, cf. PR41711. */
+    case 10:
+    case 16:
+      {
+       GFC_UINTEGER_16 tmp = value;
+       memcpy (dest, (void *) &tmp, length);
+      }
+      break;
+#endif
+    case 8:
+      {
+       GFC_UINTEGER_8 tmp = value;
+       memcpy (dest, (void *) &tmp, length);
+      }
+      break;
+    case 4:
+      {
+       GFC_UINTEGER_4 tmp = value;
+       memcpy (dest, (void *) &tmp, length);
+      }
+      break;
+    case 2:
+      {
+       GFC_UINTEGER_2 tmp = value;
+       memcpy (dest, (void *) &tmp, length);
+      }
+      break;
+    case 1:
+      {
+       GFC_UINTEGER_1 tmp = value;
+       memcpy (dest, (void *) &tmp, length);
+      }
+      break;
+    default:
+      internal_error (NULL, "Bad integer kind");
+    }
+}
+
 
 /* Max signed value of size give by length argument.  */
 
@@ -132,6 +188,28 @@ si_max (int length)
     }
 }
 
+GFC_UINTEGER_LARGEST
+us_max (int length)
+{
+  switch (length)
+    {
+#ifdef HAVE_GFC_UINTEGER_16
+    case 17:
+    case 16:
+      return GFC_UINTEGER_16_HUGE;
+#endif
+    case 8:
+      return GFC_UINTEGER_8_HUGE;
+    case 4:
+      return GFC_UINTEGER_4_HUGE;
+    case 2:
+      return GFC_UINTEGER_2_HUGE;
+    case 1:
+      return GFC_UINTEGER_1_HUGE;
+    default:
+      internal_error (NULL, "Bad unsigned kind");
+    }
+}
 
 /* convert_real()-- Convert a character representation of a floating
    point number to the machine number.  Returns nonzero if there is an
diff --git a/libgfortran/io/transfer.c b/libgfortran/io/transfer.c
index a86099d46f56..741dbd9cc981 100644
--- a/libgfortran/io/transfer.c
+++ b/libgfortran/io/transfer.c
@@ -56,6 +56,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If 
not, see
       transfer_complex
       transfer_real128
       transfer_complex128
+      transfer_unsigned
 
     and for WRITE
 
@@ -67,6 +68,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If 
not, see
       transfer_complex_write
       transfer_real128_write
       transfer_complex128_write
+      transfer_unsigned_write
 
     These subroutines do not return status. The *128 functions
     are in the file transfer128.c.
@@ -82,6 +84,12 @@ export_proto(transfer_integer);
 extern void transfer_integer_write (st_parameter_dt *, void *, int);
 export_proto(transfer_integer_write);
 
+extern void transfer_unsigned (st_parameter_dt *, void *, int);
+export_proto(transfer_unsigned);
+
+extern void transfer_unsigned_write (st_parameter_dt *, void *, int);
+export_proto(transfer_unsigned_write);
+
 extern void transfer_real (st_parameter_dt *, void *, int);
 export_proto(transfer_real);
 
@@ -2608,6 +2616,18 @@ transfer_integer_write (st_parameter_dt *dtp, void *p, 
int kind)
   transfer_integer (dtp, p, kind);
 }
 
+void
+transfer_unsigned (st_parameter_dt *dtp, void *p, int kind)
+{
+    wrap_scalar_transfer (dtp, BT_UNSIGNED, p, kind, kind, 1);
+}
+
+void
+transfer_unsigned_write (st_parameter_dt *dtp, void *p, int kind)
+{
+  transfer_unsigned (dtp, p, kind);
+}
+
 void
 transfer_real (st_parameter_dt *dtp, void *p, int kind)
 {
diff --git a/libgfortran/io/write.c b/libgfortran/io/write.c
index 91d1da2007ae..0f9600f5f1fe 100644
--- a/libgfortran/io/write.c
+++ b/libgfortran/io/write.c
@@ -949,7 +949,134 @@ write_decimal (st_parameter_dt *dtp, const fnode *f, 
const char *source,
   return;
 }
 
+/* Same as above, but somewhat simpler because we only treat unsigned
+   numbers.  */
 
+static void
+write_decimal_unsigned (st_parameter_dt *dtp, const fnode *f,
+                       const char *source, int len)
+{
+  GFC_UINTEGER_LARGEST n = 0;
+  int w, m, digits, nsign, nzero, nblank;
+  char *p;
+  const char *q;
+  sign_t sign;
+  char itoa_buf[GFC_BTOA_BUF_SIZE];
+
+  w = f->u.integer.w;
+  m = f->format == FMT_G ? -1 : f->u.integer.m;
+
+  n = extract_uint (source, len);
+
+  /* Special case:  */
+  if (m == 0 && n == 0)
+    {
+      if (w == 0)
+       w = 1;
+
+      p = write_block (dtp, w);
+      if (p == NULL)
+       return;
+
+      if (unlikely (is_char4_unit (dtp)))
+       {
+         gfc_char4_t *p4 = (gfc_char4_t *) p;
+         memset4 (p4, ' ', w);
+       }
+      else
+       memset (p, ' ', w);
+      goto done;
+    }
+
+  /* Just in case somebody wants a + sign.  */
+  sign = calculate_sign (dtp, false);
+  nsign = sign == S_NONE ? 0 : 1;
+
+  q = gfc_itoa (n, itoa_buf, sizeof (itoa_buf));
+  digits = strlen (q);
+
+  /* Select a width if none was specified.  The idea here is to always
+     print something.  */
+  if (w == DEFAULT_WIDTH)
+    w = default_width_for_integer (len);
+
+  if (w == 0)
+    w = ((digits < m) ? m : digits) + nsign;
+
+  p = write_block (dtp, w);
+  if (p == NULL)
+    return;
+
+  nzero = 0;
+  if (digits < m)
+    nzero = m - digits;
+
+  /* See if things will work.  */
+
+  nblank = w - (nsign + nzero + digits);
+
+  if (unlikely (is_char4_unit (dtp)))
+    {
+      gfc_char4_t *p4 = (gfc_char4_t *)p;
+      if (nblank < 0)
+       {
+         memset4 (p4, '*', w);
+         goto done;
+       }
+
+      if (!dtp->u.p.namelist_mode)
+       {
+         memset4 (p4, ' ', nblank);
+         p4 += nblank;
+       }
+
+      if (sign == S_PLUS)
+       *p4++ = '+';
+
+      memset4 (p4, '0', nzero);
+      p4 += nzero;
+
+      memcpy4 (p4, q, digits);
+
+      if (dtp->u.p.namelist_mode)
+       {
+         p4 += digits;
+         memset4 (p4, ' ', nblank);
+       }
+
+      return;
+    }
+
+  if (nblank < 0)
+    {
+      star_fill (p, w);
+      goto done;
+    }
+
+  if (!dtp->u.p.namelist_mode)
+    {
+      memset (p, ' ', nblank);
+      p += nblank;
+    }
+
+  if (sign == S_PLUS)
+    *p++ = '+';
+
+  memset (p, '0', nzero);
+  p += nzero;
+
+  memcpy (p, q, digits);
+
+  if (dtp->u.p.namelist_mode)
+    {
+      p += digits;
+      memset (p, ' ', nblank);
+    }
+
+ done:
+  return;
+
+}
 /* Convert hexadecimal to ASCII.  */
 
 static const char *
@@ -1404,6 +1531,47 @@ write_integer (st_parameter_dt *dtp, const char *source, 
int kind)
   write_decimal (dtp, &f, source, kind);
 }
 
+/* Write a list-directed unsigned value.  We use the same formatting
+   as for integer.  */
+
+static void
+write_unsigned (st_parameter_dt *dtp, const char *source, int kind)
+{
+  int width;
+  fnode f;
+
+  switch (kind)
+    {
+    case 1:
+      width = 4;
+      break;
+
+    case 2:
+      width = 6;
+      break;
+
+    case 4:
+      width = 11;
+      break;
+
+    case 8:
+      width = 20;
+      break;
+
+    case 16:
+      width = 40;
+      break;
+
+    default:
+      width = 0;
+      break;
+    }
+  f.u.integer.w = width;
+  f.u.integer.m = -1;
+  f.format = FMT_NONE;
+  write_decimal_unsigned (dtp, &f, source, kind);
+}
+
 
 /* Write a list-directed string.  We have to worry about delimiting
    the strings if the file has been opened in that mode.  */
@@ -1942,6 +2110,9 @@ list_formatted_write_scalar (st_parameter_dt *dtp, bt 
type, void *p, int kind,
     case BT_INTEGER:
       write_integer (dtp, p, kind);
       break;
+    case BT_UNSIGNED:
+      write_unsigned (dtp, p, kind);
+      break;
     case BT_LOGICAL:
       write_logical (dtp, p, kind);
       break;
diff --git a/libgfortran/libgfortran.h b/libgfortran/libgfortran.h
index effa3732c185..faf57a33358c 100644
--- a/libgfortran/libgfortran.h
+++ b/libgfortran/libgfortran.h
@@ -307,6 +307,15 @@ typedef GFC_UINTEGER_4 gfc_char4_t;
   (GFC_INTEGER_16)((((GFC_UINTEGER_16)1) << 127) - 1)
 #endif
 
+#define GFC_UINTEGER_1_HUGE ((GFC_UINTEGER_1) -1)
+#define GFC_UINTEGER_2_HUGE ((GFC_UINTEGER_2) -1)
+#define GFC_UINTEGER_4_HUGE ((GFC_UINTEGER_4) -1)
+#define GFC_UINTEGER_8_HUGE ((GFC_UINTEGER_8) -1)
+#ifdef HAVE_GFC_UINTEGER_16
+#define GFC_UINTEGER_16_HUGE ((GFC_UINTEGER_16) -1)
+#endif
+
+
 /* M{IN,AX}{LOC,VAL} need also infinities and NaNs if supported.  */
 
 #if __FLT_HAS_INFINITY__
@@ -2042,9 +2051,4 @@ extern int __snprintfieee128 (char *, size_t, const char 
*, ...)
 
 #endif
 
-/* We always have these.  */
-
-#define HAVE_GFC_UINTEGER_1 1
-#define HAVE_GFC_UINTEGER_4 1
-
 #endif  /* LIBGFOR_H  */
diff --git a/libgfortran/mk-kinds-h.sh b/libgfortran/mk-kinds-h.sh
index 0e0ec195875a..647b3b6eadb5 100755
--- a/libgfortran/mk-kinds-h.sh
+++ b/libgfortran/mk-kinds-h.sh
@@ -38,6 +38,7 @@ for k in $possible_integer_kinds; do
     echo "typedef GFC_INTEGER_${k} GFC_LOGICAL_${k};"
     echo "#define HAVE_GFC_LOGICAL_${k}"
     echo "#define HAVE_GFC_INTEGER_${k}"
+    echo "#define HAVE_GFC_UINTEGER_${k}"
     echo ""
   fi
   rm -f tmp$$.*

Reply via email to