https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119684
Jakub Jelinek <jakub at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |bruno at clisp dot org, | |jsm28 at gcc dot gnu.org --- Comment #6 from Jakub Jelinek <jakub at gcc dot gnu.org> --- (In reply to Roland Illig from comment #1) > I wrote a little program to check these, and while doing this, I noticed the > ambiguity that %td could mean a target-sized integer and "%t must be reg + > const_int". So the "t" is used both as a modifier as well as a conversion > specification. This needs to be fixed as well. Could you share it, so that we can also check with it other translations? I thought it is the gettext utilities which are supposed to verify this kind of stuff, but maybe it hasn't been taught about some GCC format strings yet. (In reply to Roland Illig from comment #2) > The ambiguous %t sequences are: > > operands to %T/%t must be reg + const_int: fatal_insn ("operands to %T/%t must be reg + const_int:", x); in avr, that does error ("%s", _(msgid)); so %T/%t are indeed passed through unmodified there. > specs %%include syntax malformed after %td characters > specs %%rename syntax malformed after %td characters > specs unknown %% command after %td characters > specs file malformed after %td characters These are all fatal_error, so should be gcc-internal-format. > Substring start index (%td) at %L below 1 > Substring end index (%td) at %L exceeds string length > CHARACTER expression will be truncated in constructor (%td/%td) at %L These are gfc_error/gfc_warning_now, should be gfc-internal-format. > Or maybe this ambiguity is fine, assuming that no message will ever have a > %t conversion followed directly by the letter d, as that would contradict > the GCC diagnostics guidelines. For t/z modifiers, I think we need diff --git a/gettext-tools/src/format-gcc-internal.c b/gettext-tools/src/format-gcc-internal.c index 4e7335b1e..bcba79db6 100644 --- a/gettext-tools/src/format-gcc-internal.c +++ b/gettext-tools/src/format-gcc-internal.c @@ -49,7 +49,7 @@ - optionally 'm$' where m is a positive integer, - optionally any number of flags: 'q' (once only), - 'l' (up to twice) or 'w' (once only) (exclusive), + 'l' (up to twice) or 'w', 'z' or 't' (once only) (exclusive), '+' (once only), '#' (once only), - finished by a specifier @@ -107,18 +107,21 @@ enum format_arg_type FAT_SIZE_LONG = 1 << 5, FAT_SIZE_LONGLONG = 2 << 5, FAT_SIZE_WIDE = 3 << 5, - FAT_TREE_DECL = 1 << 7, - FAT_TREE_STATEMENT = 2 << 7, - FAT_TREE_FUNCDECL = 3 << 7, - FAT_TREE_TYPE = 4 << 7, - FAT_TREE_ARGUMENT = 5 << 7, - FAT_TREE_EXPRESSION = 6 << 7, - FAT_TREE_CV = 7 << 7, - FAT_TREE_CODE_BINOP = 1 << 10, - FAT_TREE_CODE_ASSOP = 2 << 10, - FAT_FUNCPARAM = 1 << 12, + FAT_SIZE_SIZE_T = 4 << 5, + FAT_SIZE_PTRDIFF_T = 5 << 5, + FAT_TREE_DECL = 1 << 8, + FAT_TREE_STATEMENT = 2 << 8, + FAT_TREE_FUNCDECL = 3 << 8, + FAT_TREE_TYPE = 4 << 8, + FAT_TREE_ARGUMENT = 5 << 8, + FAT_TREE_EXPRESSION = 6 << 8, + FAT_TREE_CV = 7 << 8, + FAT_TREE_CODE_BINOP = 1 << 11, + FAT_TREE_CODE_ASSOP = 2 << 11, + FAT_FUNCPARAM = 1 << 13, /* Bitmasks */ - FAT_SIZE_MASK = (FAT_SIZE_LONG | FAT_SIZE_LONGLONG | FAT_SIZE_WIDE) + FAT_SIZE_MASK = (FAT_SIZE_LONG | FAT_SIZE_LONGLONG | FAT_SIZE_WIDE + | FAT_SIZE_SIZE_T | FAT_SIZE_PTRDIFF_T) }; #ifdef __cplusplus typedef int format_arg_type_t; @@ -186,6 +189,8 @@ format_parse (const char *format, bool translated, char *fdi, unsigned int flag_q = 0; unsigned int flag_l = 0; unsigned int flag_w = 0; + unsigned int flag_z = 0; + unsigned int flag_t = 0; unsigned int flag_plus = 0; unsigned int flag_sharp = 0; format_arg_type_t size; @@ -227,15 +232,25 @@ format_parse (const char *format, bool translated, char *fdi, flag_q = 1; continue; case 'l': - if (flag_l > 1 || flag_w) + if (flag_l > 1 || flag_w || flag_z || flag_t) goto invalid_flags; flag_l++; continue; case 'w': - if (flag_w > 0 || flag_l) + if (flag_w > 0 || flag_l || flag_z || flag_t) goto invalid_flags; flag_w = 1; continue; + case 'z': + if (flag_z > 0 || flag_l || flag_w || flag_t) + goto invalid_flags; + flag_z = 1; + continue; + case 't': + if (flag_t > 0 || flag_l || flag_w || flag_z) + goto invalid_flags; + flag_t = 1; + continue; case '+': if (flag_plus > 0) goto invalid_flags; @@ -258,6 +273,8 @@ format_parse (const char *format, bool translated, char *fdi, size = (flag_l == 2 ? FAT_SIZE_LONGLONG : flag_l == 1 ? FAT_SIZE_LONG : flag_w ? FAT_SIZE_WIDE : + flag_z ? FAT_SIZE_SIZE_T : + flag_t ? FAT_SIZE_PTRDIFF_T : 0); if (*format == 'c') @@ -744,6 +761,12 @@ format_print (void *descr) case FAT_SIZE_WIDE: printf ("[host-wide]"); break; + case FAT_SIZE_SIZE_T: + printf ("[size_t]"); + break; + case FAT_SIZE_PTRDIFF_T: + printf ("[ptrdiff_t]"); + break; default: abort (); } or so (and likely something similar for format-gfc-internal.c, which apparently doesn't handle even the w modifier. What other gcc-internal-format changes are missing I have no idea.