From: Jakub Jelinek <jakub@redhat.com>
To: Tobias Burnus <tobias@codesourcery.com>
Cc: Harald Anlauf <anlauf@gmx.de>, "H.J. Lu" <hjl.tools@gmail.com>,
Harald Anlauf via Gcc-patches <gcc-patches@gcc.gnu.org>,
fortran <fortran@gcc.gnu.org>
Subject: Re: [Patch] c-format.c/Fortran: Support %wd / host-wide integer in gfc_error (Re: [PATCH] PR fortran/100950 - ICE in output_constructor_regular_field, at varasm.c:5514)
Date: Fri, 20 Aug 2021 13:56:34 +0200 [thread overview]
Message-ID: <20210820115634.GH2380545@tucnak> (raw)
In-Reply-To: <a9778a8a-c257-4cd7-f40e-adabf9317754@codesourcery.com>
On Fri, Aug 20, 2021 at 01:50:00PM +0200, Tobias Burnus wrote:
> On 20.08.21 11:16, Jakub Jelinek wrote:
>
> > Now, the non-Fortran FE diagnostic code actually has %wd for this (w
> > modifier like l modifier), which takes HOST_WIDE_INT/unsigned HOST_WIDE_INT
> > argument and prints it.
> >
> > So, either you get through the hops to support that, unfortunately it isn't
> > just adding support for that in fortran/error.c (error_print) and some
> > helper functions, which wouldn't be that hard, just add 'w' next to 'l'
> > handling, TYPE_* for that and union member etc., but one needs to modify
> > c-family/c-format.c too to register the modifier so that gcc doesn't warn
> > about it and knows the proper argument type etc.
>
> That's what the attached patch does.
>
> Build on x86-64 GNU Linux; I tried to build it with -m32 (cf. my
> previous email) but as I did not run into the original issue, this does
> not proof much.
>
> Comments? OK?
LGTM (except that the last hunk won't apply anymore).
> 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): Replace
> HOST_WIDE_INT_PRINT_DEC by '%wd'.
>
> diff --git a/gcc/c-family/c-format.c b/gcc/c-family/c-format.c
> index 6fd0bb33d21..b4cb765a9d3 100644
> --- a/gcc/c-family/c-format.c
> +++ b/gcc/c-family/c-format.c
> @@ -546,10 +546,11 @@ static const format_length_info strfmon_length_specs[] =
> };
>
>
> -/* For now, the Fortran front-end routines only use l as length modifier. */
> +/* Length modifiers used by the fortran/error.c routines. */
> static const format_length_info gcc_gfc_length_specs[] =
> {
> - { "l", FMT_LEN_l, STD_C89, NO_FMT, 0 },
> + { "l", FMT_LEN_l, STD_C89, "ll", FMT_LEN_ll, STD_C89, 0 },
> + { "w", FMT_LEN_w, STD_C89, NO_FMT, 0 },
> { NO_FMT, NO_FMT, 0 }
> };
>
> @@ -821,10 +822,10 @@ static const format_char_info gcc_cxxdiag_char_table[] =
> static const format_char_info gcc_gfc_char_table[] =
> {
> /* C89 conversion specifiers. */
> - { "di", 0, STD_C89, { T89_I, BADLEN, BADLEN, T89_L, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
> - { "u", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
> - { "c", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
> - { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "cR", NULL },
> + { "di", 0, STD_C89, { T89_I, BADLEN, BADLEN, T89_L, T9L_LL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
> + { "u", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
> + { "c", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
> + { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "cR", NULL },
>
> /* gfc conversion specifiers. */
>
> @@ -4843,12 +4844,73 @@ init_dynamic_asm_fprintf_info (void)
> }
> }
>
> +static const format_length_info*
> +get_init_dynamic_hwi (void)
> +{
> + static tree hwi;
> + static format_length_info *diag_ls;
> +
> + if (!hwi)
> + {
> + unsigned int i;
> +
> + /* Find the underlying type for HOST_WIDE_INT. For the 'w'
> + length modifier to work, one must have issued: "typedef
> + HOST_WIDE_INT __gcc_host_wide_int__;" in one's source code
> + prior to using that modifier. */
> + if ((hwi = maybe_get_identifier ("__gcc_host_wide_int__")))
> + {
> + hwi = identifier_global_value (hwi);
> + if (hwi)
> + {
> + if (TREE_CODE (hwi) != TYPE_DECL)
> + {
> + error ("%<__gcc_host_wide_int__%> is not defined as a type");
> + hwi = 0;
> + }
> + else
> + {
> + hwi = DECL_ORIGINAL_TYPE (hwi);
> + gcc_assert (hwi);
> + if (hwi != long_integer_type_node
> + && hwi != long_long_integer_type_node)
> + {
> + error ("%<__gcc_host_wide_int__%> is not defined"
> + " as %<long%> or %<long long%>");
> + hwi = 0;
> + }
> + }
> + }
> + }
> + if (!diag_ls)
> + diag_ls = (format_length_info *)
> + xmemdup (gcc_diag_length_specs,
> + sizeof (gcc_diag_length_specs),
> + sizeof (gcc_diag_length_specs));
> + if (hwi)
> + {
> + /* HOST_WIDE_INT must be one of 'long' or 'long long'. */
> + i = find_length_info_modifier_index (diag_ls, 'w');
> + if (hwi == long_integer_type_node)
> + diag_ls[i].index = FMT_LEN_l;
> + else if (hwi == long_long_integer_type_node)
> + diag_ls[i].index = FMT_LEN_ll;
> + else
> + gcc_unreachable ();
> + }
> + }
> + return diag_ls;
> +}
> +
> /* Determine the type of a "locus" in the code being compiled for use
> in GCC's __gcc_gfc__ custom format attribute. You must have set
> dynamic_format_types before calling this function. */
> static void
> init_dynamic_gfc_info (void)
> {
> + dynamic_format_types[gcc_gfc_format_type].length_char_specs
> + = get_init_dynamic_hwi ();
> +
> if (!locus)
> {
> static format_char_info *gfc_fci;
> @@ -4985,67 +5047,13 @@ init_dynamic_diag_info (void)
> || local_event_ptr_node == void_type_node)
> local_event_ptr_node = get_named_type ("diagnostic_event_id_t");
>
> - static tree hwi;
> -
> - if (!hwi)
> - {
> - static format_length_info *diag_ls;
> - unsigned int i;
> -
> - /* Find the underlying type for HOST_WIDE_INT. For the 'w'
> - length modifier to work, one must have issued: "typedef
> - HOST_WIDE_INT __gcc_host_wide_int__;" in one's source code
> - prior to using that modifier. */
> - if ((hwi = maybe_get_identifier ("__gcc_host_wide_int__")))
> - {
> - hwi = identifier_global_value (hwi);
> - if (hwi)
> - {
> - if (TREE_CODE (hwi) != TYPE_DECL)
> - {
> - error ("%<__gcc_host_wide_int__%> is not defined as a type");
> - hwi = 0;
> - }
> - else
> - {
> - hwi = DECL_ORIGINAL_TYPE (hwi);
> - gcc_assert (hwi);
> - if (hwi != long_integer_type_node
> - && hwi != long_long_integer_type_node)
> - {
> - error ("%<__gcc_host_wide_int__%> is not defined"
> - " as %<long%> or %<long long%>");
> - hwi = 0;
> - }
> - }
> - }
> - }
> -
> - /* Assign the new data for use. */
> -
> - /* All the GCC diag formats use the same length specs. */
> - if (!diag_ls)
> - dynamic_format_types[gcc_diag_format_type].length_char_specs =
> - dynamic_format_types[gcc_tdiag_format_type].length_char_specs =
> - dynamic_format_types[gcc_cdiag_format_type].length_char_specs =
> - dynamic_format_types[gcc_cxxdiag_format_type].length_char_specs =
> - dynamic_format_types[gcc_dump_printf_format_type].length_char_specs =
> - diag_ls = (format_length_info *)
> - xmemdup (gcc_diag_length_specs,
> - sizeof (gcc_diag_length_specs),
> - sizeof (gcc_diag_length_specs));
> - if (hwi)
> - {
> - /* HOST_WIDE_INT must be one of 'long' or 'long long'. */
> - i = find_length_info_modifier_index (diag_ls, 'w');
> - if (hwi == long_integer_type_node)
> - diag_ls[i].index = FMT_LEN_l;
> - else if (hwi == long_long_integer_type_node)
> - diag_ls[i].index = FMT_LEN_ll;
> - else
> - gcc_unreachable ();
> - }
> - }
> + /* All the GCC diag formats use the same length specs. */
> + dynamic_format_types[gcc_diag_format_type].length_char_specs =
> + dynamic_format_types[gcc_tdiag_format_type].length_char_specs =
> + dynamic_format_types[gcc_cdiag_format_type].length_char_specs =
> + dynamic_format_types[gcc_cxxdiag_format_type].length_char_specs =
> + dynamic_format_types[gcc_dump_printf_format_type].length_char_specs
> + = get_init_dynamic_hwi ();
>
> /* It's safe to "re-initialize these to the same values. */
> dynamic_format_types[gcc_diag_format_type].conversion_specs =
> diff --git a/gcc/fortran/error.c b/gcc/fortran/error.c
> index 529d97fff8a..5e6e87316a6 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 492867e12cb..4cb73e836c7 100644
> --- a/gcc/fortran/simplify.c
> +++ b/gcc/fortran/simplify.c
> @@ -4554,8 +4554,7 @@ substring_has_constant_len (gfc_expr *e)
> {
> if (istart < 1)
> {
> - gfc_error ("Substring start index (" HOST_WIDE_INT_PRINT_DEC
> - ") at %L below 1",
> + gfc_error ("Substring start index (%wd) at %L below 1",
> istart, &ref->u.ss.start->where);
> return false;
> }
> @@ -4567,8 +4566,7 @@ substring_has_constant_len (gfc_expr *e)
> length = gfc_mpz_get_hwi (ref->u.ss.length->length->value.integer);
> if (iend > length)
> {
> - gfc_error ("Substring end index (" HOST_WIDE_INT_PRINT_DEC
> - ") at %L exceeds string length",
> + gfc_error ("Substring end index (%wd) at %L exceeds string length",
> iend, &ref->u.ss.end->where);
> return false;
> }
Jakub
next prev parent reply other threads:[~2021-08-20 11:56 UTC|newest]
Thread overview: 31+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-06-09 21:39 [PATCH] PR fortran/100950 - ICE in output_constructor_regular_field, at varasm.c:5514 Harald Anlauf
2021-06-10 10:24 ` Bernhard Reutner-Fischer
2021-06-10 12:47 ` Bernhard Reutner-Fischer
2021-06-10 18:52 ` Harald Anlauf
2021-06-11 6:02 ` Bernhard Reutner-Fischer
2021-06-21 12:12 ` Tobias Burnus
2021-07-12 21:23 ` Harald Anlauf
2021-08-03 21:17 ` Harald Anlauf
2021-08-11 19:28 ` *PING* " Harald Anlauf
2021-08-18 10:22 ` Tobias Burnus
2021-08-18 21:01 ` Harald Anlauf
2021-08-19 7:52 ` Tobias Burnus
2021-08-19 19:11 ` Harald Anlauf
2021-08-20 0:21 ` H.J. Lu
2021-08-20 6:48 ` Harald Anlauf
2021-08-20 9:16 ` Jakub Jelinek
2021-08-20 9:45 ` Aw: " Harald Anlauf
2021-08-20 10:12 ` Jakub Jelinek
2021-08-20 10:53 ` Aw: " Harald Anlauf
2021-08-20 10:59 ` Jakub Jelinek
2021-08-20 11:43 ` [PATCH, committed] Fix bootstrap breakage caused by r12-3033 (PR fortran/100950 - ICE in output_constructor_regular_field, at varasm.c:5514) Harald Anlauf
2021-08-20 12:01 ` Aw: Re: Re: [PATCH] PR fortran/100950 - ICE in output_constructor_regular_field, at varasm.c:5514 Tobias Burnus
2021-08-20 12:17 ` Aw: " Harald Anlauf
2021-08-20 14:19 ` Tobias Burnus
2021-08-20 19:43 ` Harald Anlauf
2021-08-20 11:50 ` [Patch] c-format.c/Fortran: Support %wd / host-wide integer in gfc_error (Re: [PATCH] PR fortran/100950 - ICE in output_constructor_regular_field, at varasm.c:5514) Tobias Burnus
2021-08-20 11:56 ` Jakub Jelinek [this message]
2021-08-20 13:47 ` Tobias Burnus
2021-08-20 13:53 ` Jakub Jelinek
2021-08-20 9:29 ` [PATCH] PR fortran/100950 - ICE in output_constructor_regular_field, at varasm.c:5514 Tobias Burnus
2021-06-18 20:47 ` PING " Harald Anlauf
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20210820115634.GH2380545@tucnak \
--to=jakub@redhat.com \
--cc=anlauf@gmx.de \
--cc=fortran@gcc.gnu.org \
--cc=gcc-patches@gcc.gnu.org \
--cc=hjl.tools@gmail.com \
--cc=tobias@codesourcery.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).