From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from esa3.mentor.iphmx.com (esa3.mentor.iphmx.com [68.232.137.180]) by sourceware.org (Postfix) with ESMTPS id 0CAF3384601D; Fri, 20 Aug 2021 13:48:02 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 0CAF3384601D Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=codesourcery.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=mentor.com IronPort-SDR: GMPJFznJS+kzFnxRktSiGREJgNnHB/AtI2Kr8TtWRZqsqWugG+oGFxKsTioRgt4X8nEXw9CpKd +c6zsKzUHy/FI2HfOUs9/ZK6rtOFHiRXDJvuVmFuWE6wYp+cuM0bbkCrUgNNAshvYeqtBBFTn3 5RULBHDc5AKd0GIHww6DWF9+bT02Z8yfk7lIw/OFpOo0ma3L8GFTDU/n/ulVCXyuMX1X3RHGuW iVF0Y8mFfr0zV1wQaSc5lz/fQSAASl456hSGC+z43exBWQel5CZdSmNRllMBOZRr42Andn2onJ q/JSFtCyvdLCz5zx+++FO95z X-IronPort-AV: E=Sophos;i="5.84,337,1620720000"; d="diff'?scan'208";a="64925848" Received: from orw-gwy-01-in.mentorg.com ([192.94.38.165]) by esa3.mentor.iphmx.com with ESMTP; 20 Aug 2021 05:48:01 -0800 IronPort-SDR: fBlTLJAK6d5xyRwvRTJtfmUFQ6q7iYQ+XtRfTLseYg+WM0rWZp9Ea7kIlvTpRBzWEwSMSByeQi IJ50/2onE97LLHDuLC2ueOe4KGcmMnzvu0GhdhQgI0KMYKJZHgf+J43wf8lKF4u1OrrRnyYziV f7nWQMhOJzy2T0Yp6ie6IlP57Sz5SjlE0jBlJsSCIqwPoiOhyF5xE72+56mHLLue2jSukyX/Th 78joUSfLjuMRvg+7CoaK9oVC+NjcsMmgxt1NTRxQY4lqeezj8jfBhWvPPRNuBiooM9QX5dWfQ9 jJc= 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) To: Jakub Jelinek CC: Harald Anlauf , "H.J. Lu" , Harald Anlauf via Gcc-patches , fortran References: <8d25c317-74fa-d8a2-724f-de6944fa602e@codesourcery.com> <20210820091618.GB2380545@tucnak> <20210820115634.GH2380545@tucnak> From: Tobias Burnus Message-ID: <869d678e-5e89-3b14-01ba-f9252eb6bc2f@codesourcery.com> Date: Fri, 20 Aug 2021 15:47:54 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.13.0 MIME-Version: 1.0 In-Reply-To: <20210820115634.GH2380545@tucnak> Content-Type: multipart/mixed; boundary="------------3D4C3AC8E7D36AAA25FBE170" Content-Language: en-US X-Originating-IP: [137.202.0.90] X-ClientProxiedBy: SVR-IES-MBX-08.mgc.mentorg.com (139.181.222.8) To svr-ies-mbx-01.mgc.mentorg.com (139.181.222.1) X-Spam-Status: No, score=-12.4 required=5.0 tests=BAYES_00, GIT_PATCH_0, HEADER_FROM_DIFFERENT_DOMAINS, KAM_DMARC_STATUS, NICE_REPLY_A, SPF_HELO_PASS, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 20 Aug 2021 13:48:05 -0000 --------------3D4C3AC8E7D36AAA25FBE170 Content-Type: text/plain; charset="utf-8"; format=flowed Content-Transfer-Encoding: quoted-printable On 20.08.21 13:56, Jakub Jelinek wrote: > On Fri, Aug 20, 2021 at 01:50:00PM +0200, Tobias Burnus wrote: >> Comments? OK? > LGTM (except that the last hunk won't apply anymore). Now applied as r12-3044; I have now changed it to %wd ... ... but as discussed in another email in the thread, I think the gfc_error should be removed (as unused); possibly with some additional testcases running into the resolve errors for those (out of bound). Tobias ----------------- Siemens Electronic Design Automation GmbH; Anschrift: Arnulfstra=C3=9Fe 201= , 80634 M=C3=BCnchen; Gesellschaft mit beschr=C3=A4nkter Haftung; Gesch=C3= =A4ftsf=C3=BChrer: Thomas Heurung, Frank Th=C3=BCrauf; Sitz der Gesellschaf= t: M=C3=BCnchen; Registergericht M=C3=BCnchen, HRB 106955 --------------3D4C3AC8E7D36AAA25FBE170 Content-Type: text/x-patch; charset="UTF-8"; name="committed.diff" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="committed.diff" commit 1b507b1e3c58c063b9cf803dff80c28d4626cb5d Author: Tobias Burnus Date: Fri Aug 20 15:43:32 2021 +0200 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. --- gcc/c-family/c-format.c | 142 +++++++++++++++++++++++++----------------------- gcc/fortran/error.c | 106 +++++++++++++++++++++++++++++++++--- gcc/fortran/simplify.c | 11 ++-- 3 files changed, 178 insertions(+), 81 deletions(-) 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 % or %"); + 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 % or %"); - 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 eaabbffca4d..4cb73e836c7 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; --------------3D4C3AC8E7D36AAA25FBE170--