aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran
diff options
context:
space:
mode:
authorTobias Burnus <tobias@codesourcery.com>2021-08-20 15:43:32 +0200
committerTobias Burnus <tobias@codesourcery.com>2021-08-20 15:43:32 +0200
commit1b507b1e3c58c063b9cf803dff80c28d4626cb5d (patch)
tree3a61a7da692a0771377ad3b0b7e6209d49dac4c5 /gcc/fortran
parent12f22906d3c025e7edb60e3264dc9cd27a49e3e1 (diff)
downloadgcc-1b507b1e3c58c063b9cf803dff80c28d4626cb5d.zip
gcc-1b507b1e3c58c063b9cf803dff80c28d4626cb5d.tar.gz
gcc-1b507b1e3c58c063b9cf803dff80c28d4626cb5d.tar.bz2
c-format.c/Fortran: Support %wd / host-wide integer in gfc_error
This patch adds support for the 'll' (long double) and 'w' (HOST_WIDE_INT) length modifiers to the Fortran FE diagnostic function (gfc_error, gfc_warning, ...) gcc/c-family/ChangeLog: * c-format.c (gcc_gfc_length_specs): Add 'll' and 'w'. (gcc_gfc_char_table): Add T9L_LL and T9L_ULL to "di" and "u", respecitively; fill with BADLEN to match size of 'types'. (get_init_dynamic_hwi): Split off from ... (init_dynamic_diag_info): ... here. Call it. (init_dynamic_gfc_info): Call it. gcc/fortran/ChangeLog: * error.c (error_uinteger): Take 'long long unsigned' instead of 'long unsigned' as argumpent. (error_integer): Take 'long long' instead of 'long'. (error_hwuint, error_hwint): New. (error_print): Update to handle 'll' and 'w' length modifiers. * simplify.c (substring_has_constant_len): Use '%wd' in gfc_error.
Diffstat (limited to 'gcc/fortran')
-rw-r--r--gcc/fortran/error.c106
-rw-r--r--gcc/fortran/simplify.c11
2 files changed, 103 insertions, 14 deletions
diff --git a/gcc/fortran/error.c b/gcc/fortran/error.c
index 529d97f..5e6e873 100644
--- a/gcc/fortran/error.c
+++ b/gcc/fortran/error.c
@@ -136,7 +136,7 @@ error_string (const char *p)
#define IBUF_LEN 60
static void
-error_uinteger (unsigned long int i)
+error_uinteger (unsigned long long int i)
{
char *p, int_buf[IBUF_LEN];
@@ -156,13 +156,50 @@ error_uinteger (unsigned long int i)
}
static void
-error_integer (long int i)
+error_integer (long long int i)
{
- unsigned long int u;
+ unsigned long long int u;
if (i < 0)
{
- u = (unsigned long int) -i;
+ u = (unsigned long long int) -i;
+ error_char ('-');
+ }
+ else
+ u = i;
+
+ error_uinteger (u);
+}
+
+
+static void
+error_hwuint (unsigned HOST_WIDE_INT i)
+{
+ char *p, int_buf[IBUF_LEN];
+
+ p = int_buf + IBUF_LEN - 1;
+ *p-- = '\0';
+
+ if (i == 0)
+ *p-- = '0';
+
+ while (i > 0)
+ {
+ *p-- = i % 10 + '0';
+ i = i / 10;
+ }
+
+ error_string (p + 1);
+}
+
+static void
+error_hwint (HOST_WIDE_INT i)
+{
+ unsigned HOST_WIDE_INT u;
+
+ if (i < 0)
+ {
+ u = (unsigned HOST_WIDE_INT) -i;
error_char ('-');
}
else
@@ -482,8 +519,8 @@ static void ATTRIBUTE_GCC_GFC(2,0)
error_print (const char *type, const char *format0, va_list argp)
{
enum { TYPE_CURRENTLOC, TYPE_LOCUS, TYPE_INTEGER, TYPE_UINTEGER,
- TYPE_LONGINT, TYPE_ULONGINT, TYPE_CHAR, TYPE_STRING,
- NOTYPE };
+ TYPE_LONGINT, TYPE_ULONGINT, TYPE_LLONGINT, TYPE_ULLONGINT,
+ TYPE_HWINT, TYPE_HWUINT, TYPE_CHAR, TYPE_STRING, NOTYPE };
struct
{
int type;
@@ -494,6 +531,10 @@ error_print (const char *type, const char *format0, va_list argp)
unsigned int uintval;
long int longintval;
unsigned long int ulongintval;
+ long long int llongintval;
+ unsigned long long int ullongintval;
+ HOST_WIDE_INT hwintval;
+ unsigned HOST_WIDE_INT hwuintval;
char charval;
const char * stringval;
} u;
@@ -577,7 +618,17 @@ error_print (const char *type, const char *format0, va_list argp)
case 'l':
c = *format++;
- if (c == 'u')
+ if (c == 'l')
+ {
+ c = *format++;
+ if (c == 'u')
+ arg[pos].type = TYPE_ULLONGINT;
+ else if (c == 'i' || c == 'd')
+ arg[pos].type = TYPE_LLONGINT;
+ else
+ gcc_unreachable ();
+ }
+ else if (c == 'u')
arg[pos].type = TYPE_ULONGINT;
else if (c == 'i' || c == 'd')
arg[pos].type = TYPE_LONGINT;
@@ -585,6 +636,16 @@ error_print (const char *type, const char *format0, va_list argp)
gcc_unreachable ();
break;
+ case 'w':
+ c = *format++;
+ if (c == 'u')
+ arg[pos].type = TYPE_HWUINT;
+ else if (c == 'i' || c == 'd')
+ arg[pos].type = TYPE_HWINT;
+ else
+ gcc_unreachable ();
+ break;
+
case 'c':
arg[pos].type = TYPE_CHAR;
break;
@@ -649,6 +710,22 @@ error_print (const char *type, const char *format0, va_list argp)
arg[pos].u.ulongintval = va_arg (argp, unsigned long int);
break;
+ case TYPE_LLONGINT:
+ arg[pos].u.llongintval = va_arg (argp, long long int);
+ break;
+
+ case TYPE_ULLONGINT:
+ arg[pos].u.ullongintval = va_arg (argp, unsigned long long int);
+ break;
+
+ case TYPE_HWINT:
+ arg[pos].u.hwintval = va_arg (argp, HOST_WIDE_INT);
+ break;
+
+ case TYPE_HWUINT:
+ arg[pos].u.hwuintval = va_arg (argp, unsigned HOST_WIDE_INT);
+ break;
+
case TYPE_CHAR:
arg[pos].u.charval = (char) va_arg (argp, int);
break;
@@ -725,12 +802,27 @@ error_print (const char *type, const char *format0, va_list argp)
case 'l':
format++;
+ if (*format == 'l')
+ {
+ format++;
+ if (*format == 'u')
+ error_uinteger (spec[n++].u.ullongintval);
+ else
+ error_integer (spec[n++].u.llongintval);
+ }
if (*format == 'u')
error_uinteger (spec[n++].u.ulongintval);
else
error_integer (spec[n++].u.longintval);
break;
+ case 'w':
+ format++;
+ if (*format == 'u')
+ error_hwuint (spec[n++].u.hwintval);
+ else
+ error_hwint (spec[n++].u.hwuintval);
+ break;
}
}
diff --git a/gcc/fortran/simplify.c b/gcc/fortran/simplify.c
index eaabbff..4cb73e8 100644
--- a/gcc/fortran/simplify.c
+++ b/gcc/fortran/simplify.c
@@ -4552,12 +4552,10 @@ substring_has_constant_len (gfc_expr *e)
if (istart <= iend)
{
- char buffer[21];
if (istart < 1)
{
- sprintf (buffer, HOST_WIDE_INT_PRINT_DEC, istart);
- gfc_error ("Substring start index (%s) at %L below 1",
- buffer, &ref->u.ss.start->where);
+ gfc_error ("Substring start index (%wd) at %L below 1",
+ istart, &ref->u.ss.start->where);
return false;
}
@@ -4568,9 +4566,8 @@ substring_has_constant_len (gfc_expr *e)
length = gfc_mpz_get_hwi (ref->u.ss.length->length->value.integer);
if (iend > length)
{
- sprintf (buffer, HOST_WIDE_INT_PRINT_DEC, iend);
- gfc_error ("Substring end index (%s) at %L exceeds string length",
- buffer, &ref->u.ss.end->where);
+ gfc_error ("Substring end index (%wd) at %L exceeds string length",
+ iend, &ref->u.ss.end->where);
return false;
}
length = iend - istart + 1;