aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Koenig <tkoenig@gcc.gnu.org>2024-07-28 14:29:42 +0200
committerThomas Koenig <tkoenig@gcc.gnu.org>2024-07-28 19:06:03 +0200
commitb44e7c167c3d05d175f84423707241ba7847bb77 (patch)
tree9b7e2f411103da08f8f7b1bb003eb152db5f5b68
parentb421a3b1a3809b0401a79ae8f4eac2ec0cca2e62 (diff)
downloadgcc-b44e7c167c3d05d175f84423707241ba7847bb77.zip
gcc-b44e7c167c3d05d175f84423707241ba7847bb77.tar.gz
gcc-b44e7c167c3d05d175f84423707241ba7847bb77.tar.bz2
Implement decimal list-directed I/O.
-rw-r--r--gcc/fortran/gfortran.h10
-rw-r--r--gcc/fortran/primary.cc3
-rw-r--r--gcc/fortran/simplify.cc4
-rw-r--r--gcc/fortran/trans-io.cc19
-rw-r--r--gcc/testsuite/gfortran.dg/unsigned_1.f907
-rw-r--r--gcc/testsuite/gfortran.dg/unsigned_2.f9020
-rw-r--r--libgfortran/gfortran.map2
-rw-r--r--libgfortran/io/io.h6
-rw-r--r--libgfortran/io/list_read.c92
-rw-r--r--libgfortran/io/read.c78
-rw-r--r--libgfortran/io/transfer.c20
-rw-r--r--libgfortran/io/write.c171
-rw-r--r--libgfortran/libgfortran.h14
-rwxr-xr-xlibgfortran/mk-kinds-h.sh1
14 files changed, 426 insertions, 21 deletions
diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h
index d7bbcf6..1e3262f 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 c1aa0bc..63b0bcf 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 b96f5ee..a8c9397 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 7ab82fa..e9e67a0 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 a5f110a..ed1a6ee 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 0000000..e55e0f5
--- /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 82f8f3c..e71cbcf 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 1c23676..32e2b82 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 96b2efe..9e3fffe 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 7a9e341..2fb3939 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 a86099d..741dbd9 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);
@@ -2609,6 +2617,18 @@ transfer_integer_write (st_parameter_dt *dtp, void *p, int 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)
{
size_t size;
diff --git a/libgfortran/io/write.c b/libgfortran/io/write.c
index 91d1da2..0f9600f 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 effa373..faf57a3 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 0e0ec19..647b3b6 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$$.*