On 20.08.21 02:21, H.J. Lu wrote:
This may have broken bootstrap on 32-bit hosts: https://gcc.gnu.org/pipermail/gcc-regression/2021-August/075209.html
The latter has:
../../src-master/gcc/fortran/simplify.c:4557:22: error: unknown conversion type character ‘l’ in format [-Werror=format=] 4557 | gfc_error ("Substring start index (" HOST_WIDE_INT_PRINT_DEC | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
HOST_WIDE_INT_PRINT_DEC is: #define HOST_WIDE_INT_PRINT_DEC "%" PRId64 and the latter is something like: "ld" or "lld" I fail to see why that shouldn't work – and also building with: CC="gcc-10 -m32 -fno-lto -O2" CXX="g++-10 -m32 -fno-lto -O2" .../configure --prefix=... --disable-multilib --disable-libstdcxx-pch --enable-multiarch --enable-languages=c,c++,fortran --disable-lto did succeed. Looking at the format checking: gfortran.h:void gfc_error (const char *, ...) ATTRIBUTE_GCC_GFC(1,2); with gfortran.h:#define ATTRIBUTE_GCC_GFC(m, n) __attribute__ ((__format__ (__gcc_gfc__, m, n))) ATTRIBUTE_NONNULL(m) I do see that the C/C++ part (which also uses HOST_WIDE_INT_PRINT_DEC) have some special code for HWI, which is used for via init_dynamic_diag_info contains support for hwi not for gfc_{error,warning} via init_dynamic_gfc_info I did wonder whether that causes the differences (→ attached patch). On the other hand, %ld and %lld are pretty standard – and the comment in the function talks about %w – which is not used (except in spec files and in 'go'). Hence: No idea what's the problem or goes wrong. Maybe the patch is still useful – at least it gives an error when HWI is neither long nor long long ... (Build with and without that patch with the options shown aboved (and 'error:' in stage 1, 2, 3 plus the usual bootstrap on x86-64.) Comments? Tobias ----------------- Siemens Electronic Design Automation GmbH; Anschrift: Arnulfstraße 201, 80634 München; Gesellschaft mit beschränkter Haftung; Geschäftsführer: Thomas Heurung, Frank Thürauf; Sitz der Gesellschaft: München; Registergericht München, HRB 106955
c-family/c-format.c: Support HOST_WIDE_INT in __gcc_gfc__ This patch fixes x86 -m32 builds as gcc/fortran now uses HOST_WIDE_INT with gfc_error. gcc/c-family/ChangeLog: * c-format.c (init_dynamic_diag_hwi): New. Moved from ... (init_dynamic_diag_info): ... here; call it. (init_dynamic_gfc_info): Call it. gcc/c-family/c-format.c | 135 ++++++++++++++++++++++++++---------------------- 1 file changed, 74 insertions(+), 61 deletions(-) diff --git a/gcc/c-family/c-format.c b/gcc/c-family/c-format.c index 6fd0bb33d21..1db4fd33dbc 100644 --- a/gcc/c-family/c-format.c +++ b/gcc/c-family/c-format.c @@ -4843,12 +4843,85 @@ init_dynamic_asm_fprintf_info (void) } } +/* Called by init_dynamic_gfc_info and init_dynamic_diag_info. + Determine the type of "HOST_WIDE_INT" in the code being compiled for + use in GCC's diagnostic custom format attributes. You + must have set dynamic_format_types before calling this function. */ +static void +init_dynamic_diag_hwi (void) +{ + 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 (); + } + } +} + + /* 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) { + init_dynamic_diag_hwi (); + if (!locus) { static format_char_info *gfc_fci; @@ -4985,67 +5058,7 @@ 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 (); - } - } + init_dynamic_diag_hwi (); /* It's safe to "re-initialize these to the same values. */ dynamic_format_types[gcc_diag_format_type].conversion_specs =