Jakub Jelinek <ja...@redhat.com> 于2024年2月10日周六 17:41写道: > > Hi! > > In the previous patch I haven't touched the gcc diagnostic routines, > using HOST_SIZE_T_PRINT* for those is obviously undesirable because we > want the strings to be translatable. We already have %w[diox] for > HOST_WIDE_INT arguments, this patch adds t and z modifiers for those. > > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? > > 2024-02-10 Jakub Jelinek <ja...@redhat.com> > > gcc/ > * pretty-print.cc (pp_integer_with_precision): Handle precision 3 for > size_t and precision 4 for ptrdiff_t. Formatting fix. > (pp_format): Document %{t,z}{d,i,u,o,x}. Implement t and z modifiers. > Formatting fixes. > (test_pp_format): Test t and z modifiers. > * gcc.cc (read_specs): Use %td instead of %ld and casts to long. > gcc/c-family/ > * c-format.cc (gcc_diag_length_specs): Add t and z modifiers. > (PP_FORMAT_CHAR_TABLE, gcc_gfc_char_table): Add entries for t and > z modifiers. > gcc/fortran/ > * error.cc (error_print): Handle z and t modifiers on d, i and u. > * check.cc (gfc_check_transfer): Use %zd instead of %ld and casts to > long. > * primary.cc (gfc_convert_to_structure_constructor): Use %td instead > of %ld and casts to long. > > --- gcc/gcc.cc.jj 2024-02-09 14:54:09.141489744 +0100 > +++ gcc/gcc.cc 2024-02-09 22:04:37.655678742 +0100 > @@ -2410,8 +2410,7 @@ read_specs (const char *filename, bool m > if (*p1++ != '<' || p[-2] != '>') > fatal_error (input_location, > "specs %%include syntax malformed after " > - "%ld characters", > - (long) (p1 - buffer + 1)); > + "%td characters", p1 - buffer + 1); >
Should we use %td later for gcc itself? Since we may use older compiler to build gcc. My major workstation is Debian Bookworm, which has GCC 12, and then I get some warnings: ../../gcc/gcc.cc: In function ‘void read_specs(const char*, bool, bool)’: ../../gcc/gcc.cc:2417:32: warning: unknown conversion type character ‘t’ in format [-Wformat=] 2417 | "%td characters", p1 - buffer + 1); | ^ ../../gcc/gcc.cc:2416:30: warning: too many arguments for format [-Wformat-extra-args] 2416 | "specs %%include syntax malformed after " | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 2417 | "%td characters", p1 - buffer + 1); > p[-2] = '\0'; > new_filename = find_a_file (&startfile_prefixes, p1, R_OK, > true); > @@ -2431,8 +2430,7 @@ read_specs (const char *filename, bool m > if (*p1++ != '<' || p[-2] != '>') > fatal_error (input_location, > "specs %%include syntax malformed after " > - "%ld characters", > - (long) (p1 - buffer + 1)); > + "%td characters", p1 - buffer + 1); > > p[-2] = '\0'; > new_filename = find_a_file (&startfile_prefixes, p1, R_OK, > true); > @@ -2458,8 +2456,7 @@ read_specs (const char *filename, bool m > if (! ISALPHA ((unsigned char) *p1)) > fatal_error (input_location, > "specs %%rename syntax malformed after " > - "%ld characters", > - (long) (p1 - buffer)); > + "%td characters", p1 - buffer); > > p2 = p1; > while (*p2 && !ISSPACE ((unsigned char) *p2)) > @@ -2468,8 +2465,7 @@ read_specs (const char *filename, bool m > if (*p2 != ' ' && *p2 != '\t') > fatal_error (input_location, > "specs %%rename syntax malformed after " > - "%ld characters", > - (long) (p2 - buffer)); > + "%td characters", p2 - buffer); > > name_len = p2 - p1; > *p2++ = '\0'; > @@ -2479,8 +2475,7 @@ read_specs (const char *filename, bool m > if (! ISALPHA ((unsigned char) *p2)) > fatal_error (input_location, > "specs %%rename syntax malformed after " > - "%ld characters", > - (long) (p2 - buffer)); > + "%td characters", p2 - buffer); > > /* Get new spec name. */ > p3 = p2; > @@ -2490,8 +2485,7 @@ read_specs (const char *filename, bool m > if (p3 != p - 1) > fatal_error (input_location, > "specs %%rename syntax malformed after " > - "%ld characters", > - (long) (p3 - buffer)); > + "%td characters", p3 - buffer); > *p3 = '\0'; > > for (sl = specs; sl; sl = sl->next) > @@ -2530,8 +2524,8 @@ read_specs (const char *filename, bool m > } > else > fatal_error (input_location, > - "specs unknown %% command after %ld characters", > - (long) (p1 - buffer)); > + "specs unknown %% command after %td characters", > + p1 - buffer); > } > > /* Find the colon that should end the suffix. */ > @@ -2542,8 +2536,8 @@ read_specs (const char *filename, bool m > /* The colon shouldn't be missing. */ > if (*p1 != ':') > fatal_error (input_location, > - "specs file malformed after %ld characters", > - (long) (p1 - buffer)); > + "specs file malformed after %td characters", > + p1 - buffer); > > /* Skip back over trailing whitespace. */ > p2 = p1; > @@ -2556,8 +2550,8 @@ read_specs (const char *filename, bool m > p = skip_whitespace (p1 + 1); > if (p[1] == 0) > fatal_error (input_location, > - "specs file malformed after %ld characters", > - (long) (p - buffer)); > + "specs file malformed after %td characters", > + p - buffer); > > p1 = p; > /* Find next blank line or end of string. */ > --- gcc/c-family/c-format.cc.jj 2024-02-09 14:54:08.958492278 +0100 > +++ gcc/c-family/c-format.cc 2024-02-09 22:27:20.021113168 +0100 > @@ -512,6 +512,8 @@ static const format_length_info gcc_diag > { > { "l", FMT_LEN_l, STD_C89, "ll", FMT_LEN_ll, STD_C89, 0 }, > { "w", FMT_LEN_w, STD_C89, NO_FMT, 0 }, > + { "z", FMT_LEN_z, STD_C99, NO_FMT, 0 }, > + { "t", FMT_LEN_t, STD_C99, NO_FMT, 0 }, > { NO_FMT, NO_FMT, 0 } > }; > > @@ -758,9 +760,9 @@ static const format_char_info asm_fprint > by all pretty_printer instances within GCC. */ > > #define PP_FORMAT_CHAR_TABLE \ > - { "di", 0, STD_C89, { T89_I, BADLEN, BADLEN, T89_L, T9L_LL, > BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", > NULL }, \ > - { "ox", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, > 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 }, \ > + { "di", 0, STD_C89, { T89_I, BADLEN, BADLEN, T89_L, T9L_LL, > BADLEN, T99_SST, T99_PD, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", > NULL }, \ > + { "ox", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, > BADLEN, T99_ST, T99_UPD, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", > NULL }, \ > + { "u", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, > BADLEN, T99_ST, T99_UPD, 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 }, "pq", "cR", > NULL }, \ > { "p", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, > BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "c", > NULL }, \ > @@ -833,8 +835,8 @@ static const format_char_info gcc_cxxdia > static const format_char_info gcc_gfc_char_table[] = > { > /* C89 conversion specifiers. */ > - { "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 }, > + { "di", 0, STD_C89, { T89_I, BADLEN, BADLEN, T89_L, T9L_LL, > BADLEN, T99_SST, T99_PD, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL }, > + { "u", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, > BADLEN, T99_ST, T99_UPD, 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 > }, > > --- gcc/fortran/error.cc.jj 2024-01-03 12:07:06.006680415 +0100 > +++ gcc/fortran/error.cc 2024-02-09 22:40:33.054339955 +0100 > @@ -536,7 +536,8 @@ error_print (const char *type, const cha > { > enum { TYPE_CURRENTLOC, TYPE_LOCUS, TYPE_INTEGER, TYPE_UINTEGER, > TYPE_LONGINT, TYPE_ULONGINT, TYPE_LLONGINT, TYPE_ULLONGINT, > - TYPE_HWINT, TYPE_HWUINT, TYPE_CHAR, TYPE_STRING, NOTYPE }; > + TYPE_HWINT, TYPE_HWUINT, TYPE_CHAR, TYPE_STRING, TYPE_SIZE, > + TYPE_SSIZE, TYPE_PTRDIFF, NOTYPE }; > struct > { > int type; > @@ -553,6 +554,9 @@ error_print (const char *type, const cha > unsigned HOST_WIDE_INT hwuintval; > char charval; > const char * stringval; > + size_t sizeval; > + ssize_t ssizeval; > + ptrdiff_t ptrdiffval; > } u; > } arg[MAX_ARGS], spec[MAX_ARGS]; > /* spec is the array of specifiers, in the same order as they > @@ -662,6 +666,24 @@ error_print (const char *type, const cha > gcc_unreachable (); > break; > > + case 'z': > + c = *format++; > + if (c == 'u') > + arg[pos].type = TYPE_SIZE; > + else if (c == 'i' || c == 'd') > + arg[pos].type = TYPE_SSIZE; > + else > + gcc_unreachable (); > + break; > + > + case 't': > + c = *format++; > + if (c == 'u' || c == 'i' || c == 'd') > + arg[pos].type = TYPE_PTRDIFF; > + else > + gcc_unreachable (); > + break; > + > case 'c': > arg[pos].type = TYPE_CHAR; > break; > @@ -742,6 +764,18 @@ error_print (const char *type, const cha > arg[pos].u.hwuintval = va_arg (argp, unsigned HOST_WIDE_INT); > break; > > + case TYPE_SSIZE: > + arg[pos].u.ssizeval = va_arg (argp, ssize_t); > + break; > + > + case TYPE_SIZE: > + arg[pos].u.sizeval = va_arg (argp, size_t); > + break; > + > + case TYPE_PTRDIFF: > + arg[pos].u.ptrdiffval = va_arg (argp, ptrdiff_t); > + break; > + > case TYPE_CHAR: > arg[pos].u.charval = (char) va_arg (argp, int); > break; > @@ -839,6 +873,30 @@ error_print (const char *type, const cha > else > error_hwint (spec[n++].u.hwuintval); > break; > + > + case 'z': > + format++; > + if (*format == 'u') > + error_uinteger (spec[n++].u.sizeval); > + else > + error_integer (spec[n++].u.ssizeval); > + break; > + > + case 't': > + format++; > + if (*format == 'u') > + { > + ptrdiff_t ptrdiffval = spec[n++].u.ptrdiffval; > + if (sizeof (ptrdiff_t) == sizeof (int)) > + error_uinteger ((unsigned) ptrdiffval); > + else if (sizeof (ptrdiff_t) == sizeof (long)) > + error_uinteger ((unsigned long) ptrdiffval); > + else > + error_uinteger (ptrdiffval); > + } > + else > + error_integer (spec[n++].u.ptrdiffval); > + break; > } > } > > --- gcc/fortran/primary.cc.jj 2024-02-09 14:54:09.102490284 +0100 > +++ gcc/fortran/primary.cc 2024-02-09 22:04:37.654678756 +0100 > @@ -1190,14 +1190,14 @@ got_delim: > { > if (istart < 1) > { > - gfc_error ("Substring start index (%ld) at %L below 1", > - (long) istart, &e->ref->u.ss.start->where); > + gfc_error ("Substring start index (%td) at %L below 1", > + istart, &e->ref->u.ss.start->where); > return MATCH_ERROR; > } > if (iend > (ssize_t) length) > { > - gfc_error ("Substring end index (%ld) at %L exceeds string " > - "length", (long) iend, &e->ref->u.ss.end->where); > + gfc_error ("Substring end index (%td) at %L exceeds string " > + "length", iend, &e->ref->u.ss.end->where); > return MATCH_ERROR; > } > length = iend - istart + 1; > @@ -3240,8 +3240,8 @@ gfc_convert_to_structure_constructor (gf > if (warn_line_truncation && c < e1) > gfc_warning_now (OPT_Wcharacter_truncation, > "CHARACTER expression will be truncated " > - "in constructor (%ld/%ld) at %L", (long int) > c, > - (long int) e1, &actual->expr->where); > + "in constructor (%td/%td) at %L", c, > + e1, &actual->expr->where); > } > } > > --- gcc/fortran/check.cc.jj 2024-02-09 14:54:09.086490505 +0100 > +++ gcc/fortran/check.cc 2024-02-09 22:04:37.653678770 +0100 > @@ -6298,8 +6298,8 @@ gfc_check_transfer (gfc_expr *source, gf > if (source_size < result_size) > gfc_warning (OPT_Wsurprising, > "Intrinsic TRANSFER at %L has partly undefined result: " > - "source size %ld < result size %ld", &source->where, > - (long) source_size, (long) result_size); > + "source size %zd < result size %zd", &source->where, > + source_size, result_size); > > return true; > } > --- gcc/pretty-print.cc.jj 2024-02-09 14:54:09.225488581 +0100 > +++ gcc/pretty-print.cc 2024-02-09 22:04:37.652678783 +0100 > @@ -769,7 +769,30 @@ output_buffer::~output_buffer () > break; \ > \ > case 2: \ > - pp_scalar (PP, "%" HOST_LONG_LONG_FORMAT F, va_arg (ARG, long long > T)); \ > + pp_scalar (PP, "%" HOST_LONG_LONG_FORMAT F, \ > + va_arg (ARG, long long T)); \ > + break; \ > + \ > + case 3: \ > + if (T (-1) < T (0)) \ > + pp_scalar (PP, "%" GCC_PRISZ F, \ > + (fmt_size_t) va_arg (ARG, ssize_t)); \ > + else \ > + pp_scalar (PP, "%" GCC_PRISZ F, \ > + (fmt_size_t) va_arg (ARG, size_t)); \ > + break; \ > + \ > + case 4: \ > + if (sizeof (ptrdiff_t) <= sizeof (int)) \ > + pp_scalar (PP, "%" F, \ > + (int) va_arg (ARG, ptrdiff_t)); \ > + else if (sizeof (ptrdiff_t) <= sizeof (long)) \ > + pp_scalar (PP, "%l" F, \ > + (long int) va_arg (ARG, ptrdiff_t)); \ > + else \ > + pp_scalar (PP, "%" HOST_LONG_LONG_FORMAT F, \ > + (long long int) \ > + va_arg (ARG, ptrdiff_t)); \ > break; \ > \ > default: \ > @@ -1237,6 +1260,8 @@ on_end_quote (pretty_printer *pp, > %ld, %li, %lo, %lu, %lx: long versions of the above. > %lld, %lli, %llo, %llu, %llx: long long versions. > %wd, %wi, %wo, %wu, %wx: HOST_WIDE_INT versions. > + %zd, %zi, %zo, %zu, %zx: size_t versions. > + %td, %ti, %to, %tu, %tx: ptrdiff_t versions. > %f: double > %c: character. > %s: string. > @@ -1422,7 +1447,7 @@ pp_format (pretty_printer *pp, > obstack_1grow (&buffer->chunk_obstack, *p); > p++; > } > - while (strchr ("qwl+#", p[-1])); > + while (strchr ("qwlzt+#", p[-1])); > > if (p[-1] == '.') > { > @@ -1524,6 +1549,16 @@ pp_format (pretty_printer *pp, > wide = true; > continue; > > + case 'z': > + gcc_assert (!precision); > + precision = 3; > + continue; > + > + case 't': > + gcc_assert (!precision); > + precision = 4; > + continue; > + > case 'l': > /* We don't support precision beyond that of "long long". */ > gcc_assert (precision < 2); > @@ -1570,8 +1605,8 @@ pp_format (pretty_printer *pp, > if (wide) > pp_wide_integer (pp, va_arg (*text->m_args_ptr, HOST_WIDE_INT)); > else > - pp_integer_with_precision > - (pp, *text->m_args_ptr, precision, int, "d"); > + pp_integer_with_precision (pp, *text->m_args_ptr, precision, > + int, "d"); > break; > > case 'o': > @@ -1579,8 +1614,8 @@ pp_format (pretty_printer *pp, > pp_scalar (pp, "%" HOST_WIDE_INT_PRINT "o", > va_arg (*text->m_args_ptr, unsigned HOST_WIDE_INT)); > else > - pp_integer_with_precision > - (pp, *text->m_args_ptr, precision, unsigned, "o"); > + pp_integer_with_precision (pp, *text->m_args_ptr, precision, > + unsigned, "o"); > break; > > case 's': > @@ -1599,8 +1634,8 @@ pp_format (pretty_printer *pp, > pp_scalar (pp, HOST_WIDE_INT_PRINT_UNSIGNED, > va_arg (*text->m_args_ptr, unsigned HOST_WIDE_INT)); > else > - pp_integer_with_precision > - (pp, *text->m_args_ptr, precision, unsigned, "u"); > + pp_integer_with_precision (pp, *text->m_args_ptr, precision, > + unsigned, "u"); > break; > > case 'f': > @@ -1629,8 +1664,8 @@ pp_format (pretty_printer *pp, > pp_scalar (pp, HOST_WIDE_INT_PRINT_HEX, > va_arg (*text->m_args_ptr, unsigned HOST_WIDE_INT)); > else > - pp_integer_with_precision > - (pp, *text->m_args_ptr, precision, unsigned, "x"); > + pp_integer_with_precision (pp, *text->m_args_ptr, precision, > + unsigned, "x"); > break; > > case '.': > @@ -2774,6 +2809,18 @@ test_pp_format () > ASSERT_PP_FORMAT_2 ("17 12345678", "%wo %x", (HOST_WIDE_INT)15, > 0x12345678); > ASSERT_PP_FORMAT_2 ("0xcafebabe 12345678", "%wx %x", > (HOST_WIDE_INT)0xcafebabe, > 0x12345678); > + ASSERT_PP_FORMAT_2 ("-27 12345678", "%zd %x", (ssize_t)-27, 0x12345678); > + ASSERT_PP_FORMAT_2 ("-5 12345678", "%zi %x", (ssize_t)-5, 0x12345678); > + ASSERT_PP_FORMAT_2 ("10 12345678", "%zu %x", (size_t)10, 0x12345678); > + ASSERT_PP_FORMAT_2 ("17 12345678", "%zo %x", (size_t)15, 0x12345678); > + ASSERT_PP_FORMAT_2 ("cafebabe 12345678", "%zx %x", (size_t)0xcafebabe, > + 0x12345678); > + ASSERT_PP_FORMAT_2 ("-27 12345678", "%td %x", (ptrdiff_t)-27, 0x12345678); > + ASSERT_PP_FORMAT_2 ("-5 12345678", "%ti %x", (ptrdiff_t)-5, 0x12345678); > + ASSERT_PP_FORMAT_2 ("10 12345678", "%tu %x", (ptrdiff_t)10, 0x12345678); > + ASSERT_PP_FORMAT_2 ("17 12345678", "%to %x", (ptrdiff_t)15, 0x12345678); > + ASSERT_PP_FORMAT_2 ("1afebabe 12345678", "%tx %x", (ptrdiff_t)0x1afebabe, > + 0x12345678); > ASSERT_PP_FORMAT_2 ("1.000000 12345678", "%f %x", 1.0, 0x12345678); > ASSERT_PP_FORMAT_2 ("A 12345678", "%c %x", 'A', 0x12345678); > ASSERT_PP_FORMAT_2 ("hello world 12345678", "%s %x", "hello world", > > Jakub > -- YunQiang Su