* [PATCH][RFC] Make mingw-w64 printf/scanf attribute alias to ms_printf/ms_scanf only for C89 @ 2020-11-12 10:18 Jonathan Yong 2020-11-12 15:12 ` Liu Hao 0 siblings, 1 reply; 10+ messages in thread From: Jonathan Yong @ 2020-11-12 10:18 UTC (permalink / raw) To: Gcc Patch List; +Cc: Liu Hao, Kai Tietz, Jonathan Wakely [-- Attachment #1.1.1: Type: text/plain, Size: 1036 bytes --] libgomp build fails because of the false -Wformat error, even though: 1. Correct C99 inttypes.h macros are used. 2. __mingw_* C99 wrappers are used. 3. The printf attribute is used, but it was aliased to ms_printf The attached patch makes mingw-w64 printf attribute equivalent to other platforms on C99 or later. This allows libgomp to build again with -Werror on. This patch should not affect the original mingw.org distribution in any way. For C99 or later, the mingw-w64 headers already wrap printf/scanf properly, and inttypes.h also gives the correct C99 specifiers, so it makes sense to treat the printf attribute as C99 compliant. Under C89 mode, the headers would produce MS specific specifiers, so the printf attribute under C89 reverts to the old behavior of being aliased to ms_printf. This might break other code that assumes differently however. I don't think there is a solution to satisfy everyone, but at least this allows C99/C++11 compliant code to build again with -Werror. Comments? [-- Attachment #1.1.2: 0001-gcc-make-mingw-w64-printf-scanf-attribute-gnu-equiva.patch --] [-- Type: text/x-patch, Size: 6459 bytes --] From 397097aba5a098f18da92704e9ca7560adb4f29c Mon Sep 17 00:00:00 2001 From: Jonathan Yong <10walls@gmail.com> Date: Thu, 12 Nov 2020 06:45:00 +0000 Subject: [PATCH] gcc: make mingw-w64 printf/scanf attribute gnu equivalents in C99 Makes printf/scanf attribute equivalent to gnu_printf and gnu_scanf in C99 mode. Fixes false positive warnings for functions with printf attribute, even when correct C99 style printf specifiers are used. 12-11-2020 Jonathan Yong <10walls@gmail.com> gcc/ChangeLog: * c-family/c-format.c (convert_format_name_to_system_name): Turn TARGET_OVERRIDES_FORMAT_ATTRIBUTES into a callback that returns a list of attribute aliases. * config/i386/mingw-w64.h (TARGET_OVERRIDES_FORMAT_C89): Define. Tell GCC to use ms_printf and ms_scanf in C89. * config/i386/mingw32.h: (TARGET_OVERRIDES_FORMAT_ATTRIBUTES): Point to wrapper function and update description. (TARGET_OVERRIDES_FORMAT_ATTRIBUTES_COUNT): remove. * config/i386/msformat-c.c: (mingw_format_attribute_overrides): New callback. (mingw_format_attribute_overrides_table): make null terminated. --- gcc/c-family/c-format.c | 28 ++++++++++++++++------------ gcc/config/i386/mingw-w64.h | 4 ++++ gcc/config/i386/mingw32.h | 8 ++------ gcc/config/i386/msformat-c.c | 23 ++++++++++++++++++++--- 4 files changed, 42 insertions(+), 21 deletions(-) diff --git a/gcc/c-family/c-format.c b/gcc/c-family/c-format.c index 77d24ad94e4..4edf4c64f79 100644 --- a/gcc/c-family/c-format.c +++ b/gcc/c-family/c-format.c @@ -5077,7 +5077,7 @@ extern const format_kind_info TARGET_FORMAT_TYPES[]; #endif #ifdef TARGET_OVERRIDES_FORMAT_ATTRIBUTES -extern const target_ovr_attr TARGET_OVERRIDES_FORMAT_ATTRIBUTES[]; +extern const target_ovr_attr* TARGET_OVERRIDES_FORMAT_ATTRIBUTES (int format_std_version); #endif #ifdef TARGET_OVERRIDES_FORMAT_INIT extern void TARGET_OVERRIDES_FORMAT_INIT (void); @@ -5102,6 +5102,9 @@ static const char * convert_format_name_to_system_name (const char *attr_name) { int i; +#ifdef TARGET_OVERRIDES_FORMAT_ATTRIBUTES + const target_ovr_attr* override_attributes; +#endif if (attr_name == NULL || *attr_name == 0 || strncmp (attr_name, "gcc_", 4) == 0) @@ -5112,18 +5115,19 @@ convert_format_name_to_system_name (const char *attr_name) #ifdef TARGET_OVERRIDES_FORMAT_ATTRIBUTES /* Check if format attribute is overridden by target. */ - if (TARGET_OVERRIDES_FORMAT_ATTRIBUTES != NULL - && TARGET_OVERRIDES_FORMAT_ATTRIBUTES_COUNT > 0) + override_attributes = TARGET_OVERRIDES_FORMAT_ATTRIBUTES(C_STD_VER); + if (override_attributes != NULL) { - for (i = 0; i < TARGET_OVERRIDES_FORMAT_ATTRIBUTES_COUNT; ++i) - { - if (cmp_attribs (TARGET_OVERRIDES_FORMAT_ATTRIBUTES[i].named_attr_src, - attr_name)) - return attr_name; - if (cmp_attribs (TARGET_OVERRIDES_FORMAT_ATTRIBUTES[i].named_attr_dst, - attr_name)) - return TARGET_OVERRIDES_FORMAT_ATTRIBUTES[i].named_attr_src; - } + for (i = 0; + override_attributes[i].named_attr_src != NULL + && override_attributes[i].named_attr_dst != NULL; + ++i) + { + if (cmp_attribs (override_attributes[i].named_attr_src, attr_name)) + return attr_name; + if (cmp_attribs (override_attributes[i].named_attr_dst, attr_name)) + return override_attributes[i].named_attr_src; + } } #endif /* Otherwise default to gnu format. */ diff --git a/gcc/config/i386/mingw-w64.h b/gcc/config/i386/mingw-w64.h index 0d0aa939996..586d151a082 100644 --- a/gcc/config/i386/mingw-w64.h +++ b/gcc/config/i386/mingw-w64.h @@ -104,3 +104,7 @@ along with GCC; see the file COPYING3. If not see original mingw32. */ #undef TARGET_LIBC_HAS_FUNCTION #define TARGET_LIBC_HAS_FUNCTION gnu_libc_has_function + +/* alias printf/scanf attributes to MS variants when in C89 */ +#undef TARGET_OVERRIDES_FORMAT_C89 +#define TARGET_OVERRIDES_FORMAT_C89 diff --git a/gcc/config/i386/mingw32.h b/gcc/config/i386/mingw32.h index 321c30e41cc..8fa2008c1b6 100644 --- a/gcc/config/i386/mingw32.h +++ b/gcc/config/i386/mingw32.h @@ -241,16 +241,12 @@ do { \ to register C++ static destructors. */ #define TARGET_CXX_USE_ATEXIT_FOR_CXA_ATEXIT hook_bool_void_true -/* Contains a pointer to type target_ovr_attr defining the target specific +/* Returns a pointer to type target_ovr_attr defining the target specific overrides of format attributes. See c-format.h for structure - definition. */ + definition, null terminated */ #undef TARGET_OVERRIDES_FORMAT_ATTRIBUTES #define TARGET_OVERRIDES_FORMAT_ATTRIBUTES mingw_format_attribute_overrides -/* Specify the count of elements in TARGET_OVERRIDES_ATTRIBUTE. */ -#undef TARGET_OVERRIDES_FORMAT_ATTRIBUTES_COUNT -#define TARGET_OVERRIDES_FORMAT_ATTRIBUTES_COUNT 3 - /* Custom initialization for warning -Wpedantic-ms-format for c-format. */ #undef TARGET_OVERRIDES_FORMAT_INIT #define TARGET_OVERRIDES_FORMAT_INIT msformat_init diff --git a/gcc/config/i386/msformat-c.c b/gcc/config/i386/msformat-c.c index 4ceec633a6e..a75b24669a0 100644 --- a/gcc/config/i386/msformat-c.c +++ b/gcc/config/i386/msformat-c.c @@ -161,14 +161,31 @@ EXPORTED_CONST format_kind_info mingw_format_attributes[3] = } }; -/* Default overrides for printf, scanf and strftime. */ -EXPORTED_CONST target_ovr_attr mingw_format_attribute_overrides[4] = +/* Default overrides for printf, scanf and strftime in C89 */ +static const target_ovr_attr mingw_format_attribute_overrides_table[] = { { "ms_printf", "printf" }, { "ms_scanf", "scanf" }, - { "ms_strftime", "strftime" } + { "ms_strftime", "strftime" }, + { NULL, NULL} }; +/* For C99 and later, there are no strftime C99 wrappers yet */ +static const target_ovr_attr __attribute__ ((unused)) mingw_format_attribute_overrides_table_c99[] = +{ + { "ms_strftime", "strftime" }, + { NULL, NULL } +}; + +EXPORTED_CONST target_ovr_attr *mingw_format_attribute_overrides(int __attribute__ ((unused)) std) +{ +#ifdef TARGET_OVERRIDES_FORMAT_C89 + if(std >= STD_C9L) + return mingw_format_attribute_overrides_table_c99; +#endif + return mingw_format_attribute_overrides_table; +} + /* Setup for option Wpedantic-ms-format. */ #ifdef TARGET_OVERRIDES_FORMAT_INIT -- 2.29.2 [-- Attachment #1.1.3: OpenPGP_0x713B5FE29C145D45_and_old_rev.asc --] [-- Type: application/pgp-keys, Size: 8035 bytes --] [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 840 bytes --] ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH][RFC] Make mingw-w64 printf/scanf attribute alias to ms_printf/ms_scanf only for C89 2020-11-12 10:18 [PATCH][RFC] Make mingw-w64 printf/scanf attribute alias to ms_printf/ms_scanf only for C89 Jonathan Yong @ 2020-11-12 15:12 ` Liu Hao 2020-11-12 16:52 ` Liu Hao 0 siblings, 1 reply; 10+ messages in thread From: Liu Hao @ 2020-11-12 15:12 UTC (permalink / raw) To: Jonathan Yong, Gcc Patch List; +Cc: Kai Tietz, Jonathan Wakely [-- Attachment #1: Type: text/plain, Size: 2107 bytes --] 在 2020/11/12 18:18, Jonathan Yong 写道: > libgomp build fails because of the false -Wformat error, even though: > 1. Correct C99 inttypes.h macros are used. > 2. __mingw_* C99 wrappers are used. > 3. The printf attribute is used, but it was aliased to ms_printf > > The attached patch makes mingw-w64 printf attribute equivalent to other platforms on C99 or later. > This allows libgomp to build again with -Werror on. This patch should not affect the original > mingw.org distribution in any way. > According to the conversation on IRC, I personally consider this inappropriate. Although the `ll` modifier is specified by C99 for `long long`, there are many more that don't conform to C99 without UCRT: 1. The `z` modifier for `size_t` is unrecognized. 2. The `t` modifier for `ptrdiff_t` is unrecognized. 3. The `L` modifier for `long double` is accepted but ignored due to the fact that MSABI uses an 8-byte type. > For C99 or later, the mingw-w64 headers already wrap printf/scanf properly, and inttypes.h also > gives the correct C99 specifiers, so it makes sense to treat the printf attribute as C99 compliant. > Under C89 mode, the headers would produce MS specific specifiers, so the printf attribute under C89 > reverts to the old behavior of being aliased to ms_printf. > > This might break other code that assumes differently however. I don't think there is a solution to > satisfy everyone, but at least this allows C99/C++11 compliant code to build again with -Werror. > Comments? My humble opinion is that people should have gotten used to the `ll` specifier so I propose a different patch that enables it unconditionally. As Jonathan Yong pointed out, GCC is impossible to predict where the target executable will run. It may be reasonable to expect Vista+ instead of an ancient one. Users who still code for XP- should probably handle such differentiation themselves. In comparison, MSVC does not have such format checks at all. I started bootstrapping GCC a few minutes ago. It's not gonna finish very soon so I send this patch for your comments. -- Best regards, LH_Mouse [-- Attachment #2: 9999-gcc-Add-ll-and-L-length-modifiers-for-ms_printf.patch --] [-- Type: text/plain, Size: 9454 bytes --] From 1d61adae0695e7067e35f36e607a754a7cf12796 Mon Sep 17 00:00:00 2001 From: Liu Hao <lh_mouse@126.com> Date: Thu, 12 Nov 2020 22:20:29 +0800 Subject: [PATCH] gcc: Add `ll` and `L` length modifiers for `ms_printf` Previous code abuse `FMT_LEN_L` for the `I` modifier. As `L` is a valid modifier for `f`, `e`, `g`, etc. and `I` has the same semantics as the C99 `z` modifier, `FMT_LEN_z` is now used. First, in the Microsoft ABI, type `long double` has the same layout as type `double`, so `%Lg` behaves identically to `%g`. Users should pass in `double`s instead as `long double`s, as GCC uses the 10-byte format. Second, with a CRT that is recent enough (MSVCRT since Vista, MSVCR80, UCRT, or mingw-w64 8.0), `printf`-family functions can handle the `ll` length modifier correctly. This ability is assumed to be available universally. A lot of libraries (such as libgomp) that use the `format(printf, ...)` attribute used to suffer from warnings about unknown format specifiers. Reference: https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2008/tcxf1dw6(v=vs.90) Reference: https://docs.microsoft.com/en-us/cpp/porting/visual-cpp-what-s-new-2003-through-2015#new-crt-features Signed-off-by: Liu Hao <lh_mouse@126.com> gcc/: * config/i386/msformat-c.c: Add more length modifiers --- gcc/config/i386/msformat-c.c | 45 ++++++++++++++++++------------------ 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/gcc/config/i386/msformat-c.c b/gcc/config/i386/msformat-c.c index 4ceec633a6e..1629b866976 100644 --- a/gcc/config/i386/msformat-c.c +++ b/gcc/config/i386/msformat-c.c @@ -32,10 +32,11 @@ along with GCC; see the file COPYING3. If not see static format_length_info ms_printf_length_specs[] = { { "h", FMT_LEN_h, STD_C89, NULL, FMT_LEN_none, STD_C89, 0 }, - { "l", FMT_LEN_l, STD_C89, NULL, FMT_LEN_none, STD_C89, 0 }, + { "l", FMT_LEN_l, STD_C89, NULL, FMT_LEN_ll, STD_C9L, 0 }, + { "L", FMT_LEN_L, STD_C89, NULL, FMT_LEN_none, STD_C89, 1 }, { "I32", FMT_LEN_l, STD_EXT, NULL, FMT_LEN_none, STD_C89, 1 }, { "I64", FMT_LEN_ll, STD_EXT, NULL, FMT_LEN_none, STD_C89, 1 }, - { "I", FMT_LEN_L, STD_EXT, NULL, FMT_LEN_none, STD_C89, 1 }, + { "I", FMT_LEN_z, STD_EXT, NULL, FMT_LEN_none, STD_C89, 1 }, { NULL, FMT_LEN_none, STD_C89, NULL, FMT_LEN_none, STD_C89, 0 } }; @@ -90,33 +91,33 @@ static const format_flag_pair ms_strftime_flag_pairs[] = static const format_char_info ms_print_char_table[] = { /* C89 conversion specifiers. */ - { "di", 0, STD_C89, { T89_I, BADLEN, T89_S, T89_L, T9L_LL, T99_SST, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0 +'", "i", NULL }, - { "oxX", 0, STD_C89, { T89_UI, BADLEN, T89_US, T89_UL, T9L_ULL, T99_ST, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0#", "i", NULL }, - { "u", 0, STD_C89, { T89_UI, BADLEN, T89_US, T89_UL, T9L_ULL, T99_ST, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0'", "i", NULL }, - { "fgG", 0, STD_C89, { T89_D, BADLEN, BADLEN, T99_D, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0 +#'", "", NULL }, - { "eE", 0, STD_C89, { T89_D, BADLEN, BADLEN, T99_D, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0 +#", "", NULL }, - { "c", 0, STD_C89, { T89_I, BADLEN, T89_S, T94_WI, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "", NULL }, - { "s", 1, STD_C89, { T89_C, BADLEN, T89_S, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "cR", NULL }, - { "p", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "c", NULL }, - { "n", 1, STD_C89, { T89_I, BADLEN, T89_S, T89_L, T9L_LL, BADLEN, BADLEN, BADLEN, T99_IM, BADLEN, BADLEN, BADLEN }, "", "W", NULL }, + { "di", 0, STD_C89, { T89_I, BADLEN, T89_S, T89_L, T9L_LL, BADLEN, T99_SST, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0 +'", "i", NULL }, + { "oxX", 0, STD_C89, { T89_UI, BADLEN, T89_US, T89_UL, T9L_ULL, BADLEN, T99_ST, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0#", "i", NULL }, + { "u", 0, STD_C89, { T89_UI, BADLEN, T89_US, T89_UL, T9L_ULL, BADLEN, T99_ST, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0'", "i", NULL }, + { "fgG", 0, STD_C89, { T89_D, BADLEN, BADLEN, T99_D, BADLEN, T89_D, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0 +#'", "", NULL }, + { "eE", 0, STD_C89, { T89_D, BADLEN, BADLEN, T99_D, BADLEN, T89_D, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0 +#", "", NULL }, + { "c", 0, STD_C89, { T89_I, BADLEN, T89_S, T94_WI, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "", NULL }, + { "s", 1, STD_C89, { T89_C, BADLEN, T89_S, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "cR", NULL }, + { "p", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "c", NULL }, + { "n", 1, STD_C89, { T89_I, BADLEN, T89_S, T89_L, T9L_LL, BADLEN, BADLEN, BADLEN, T99_IM, BADLEN, BADLEN, BADLEN }, "", "W", NULL }, /* X/Open conversion specifiers. */ - { "C", 0, STD_EXT, { TEX_WI, BADLEN, T89_S, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "", NULL }, - { "S", 1, STD_EXT, { TEX_W, BADLEN, T89_S, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "R", NULL }, + { "C", 0, STD_EXT, { TEX_WI, BADLEN, T89_S, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "", NULL }, + { "S", 1, STD_EXT, { TEX_W, BADLEN, T89_S, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "R", NULL }, { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL } }; static const format_char_info ms_scan_char_table[] = { /* C89 conversion specifiers. */ - { "di", 1, STD_C89, { T89_I, BADLEN, T89_S, T89_L, T9L_LL, T99_SST, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w'", "W", NULL }, - { "u", 1, STD_C89, { T89_UI, BADLEN, T89_US, T89_UL, T9L_ULL, T99_ST, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w'", "W", NULL }, - { "oxX", 1, STD_C89, { T89_UI, BADLEN, T89_US, T89_UL, T9L_ULL, T99_ST, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w", "W", NULL }, - { "efgEG", 1, STD_C89, { T89_F, BADLEN, BADLEN, T89_D, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w'", "W", NULL }, - { "c", 1, STD_C89, { T89_C, BADLEN, T89_S, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w", "cW", NULL }, - { "s", 1, STD_C89, { T89_C, BADLEN, T89_S, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*aw", "cW", NULL }, - { "[", 1, STD_C89, { T89_C, BADLEN, BADLEN, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*aw", "cW[", NULL }, - { "p", 2, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w", "W", NULL }, - { "n", 1, STD_C89, { T89_I, BADLEN, T89_S, T89_L, T9L_LL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "W", NULL }, + { "di", 1, STD_C89, { T89_I, BADLEN, T89_S, T89_L, T9L_LL, BADLEN, T99_SST, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w'", "W", NULL }, + { "u", 1, STD_C89, { T89_UI, BADLEN, T89_US, T89_UL, T9L_ULL, BADLEN, T99_ST, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w'", "W", NULL }, + { "oxX", 1, STD_C89, { T89_UI, BADLEN, T89_US, T89_UL, T9L_ULL, BADLEN, T99_ST, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w", "W", NULL }, + { "efgEG", 1, STD_C89, { T89_F, BADLEN, BADLEN, T89_D, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w'", "W", NULL }, + { "c", 1, STD_C89, { T89_C, BADLEN, T89_S, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w", "cW", NULL }, + { "s", 1, STD_C89, { T89_C, BADLEN, T89_S, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*aw", "cW", NULL }, + { "[", 1, STD_C89, { T89_C, BADLEN, BADLEN, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*aw", "cW[", NULL }, + { "p", 2, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w", "W", NULL }, + { "n", 1, STD_C89, { T89_I, BADLEN, T89_S, T89_L, T9L_LL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "W", NULL }, /* X/Open conversion specifiers. */ { "C", 1, STD_EXT, { TEX_W, BADLEN, T89_S, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w", "W", NULL }, { "S", 1, STD_EXT, { TEX_W, BADLEN, T89_S, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*aw", "W", NULL }, -- 2.20.1 ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH][RFC] Make mingw-w64 printf/scanf attribute alias to ms_printf/ms_scanf only for C89 2020-11-12 15:12 ` Liu Hao @ 2020-11-12 16:52 ` Liu Hao 2020-11-12 18:46 ` Joseph Myers 0 siblings, 1 reply; 10+ messages in thread From: Liu Hao @ 2020-11-12 16:52 UTC (permalink / raw) To: Jonathan Yong, Gcc Patch List; +Cc: Kai Tietz, Jonathan Wakely [-- Attachment #1.1.1: Type: text/plain, Size: 368 bytes --] 在 2020/11/12 23:12, Liu Hao 写道: > > My humble opinion is that people should have gotten used to the `ll` specifier so I propose a > different patch that enables it unconditionally. As Jonathan Yong pointed out, GCC is impossible to The previous patch missed a `double_name` field. A revised version has been attached. -- Best regards, LH_Mouse [-- Attachment #1.1.2: 9999-gcc-Add-ll-and-L-length-modifiers-for-ms_printf.patch --] [-- Type: text/plain, Size: 9454 bytes --] From 1d61adae0695e7067e35f36e607a754a7cf12796 Mon Sep 17 00:00:00 2001 From: Liu Hao <lh_mouse@126.com> Date: Thu, 12 Nov 2020 22:20:29 +0800 Subject: [PATCH] gcc: Add `ll` and `L` length modifiers for `ms_printf` Previous code abuse `FMT_LEN_L` for the `I` modifier. As `L` is a valid modifier for `f`, `e`, `g`, etc. and `I` has the same semantics as the C99 `z` modifier, `FMT_LEN_z` is now used. First, in the Microsoft ABI, type `long double` has the same layout as type `double`, so `%Lg` behaves identically to `%g`. Users should pass in `double`s instead as `long double`s, as GCC uses the 10-byte format. Second, with a CRT that is recent enough (MSVCRT since Vista, MSVCR80, UCRT, or mingw-w64 8.0), `printf`-family functions can handle the `ll` length modifier correctly. This ability is assumed to be available universally. A lot of libraries (such as libgomp) that use the `format(printf, ...)` attribute used to suffer from warnings about unknown format specifiers. Reference: https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2008/tcxf1dw6(v=vs.90) Reference: https://docs.microsoft.com/en-us/cpp/porting/visual-cpp-what-s-new-2003-through-2015#new-crt-features Signed-off-by: Liu Hao <lh_mouse@126.com> gcc/: * config/i386/msformat-c.c: Add more length modifiers --- gcc/config/i386/msformat-c.c | 45 ++++++++++++++++++------------------ 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/gcc/config/i386/msformat-c.c b/gcc/config/i386/msformat-c.c index 4ceec633a6e..1629b866976 100644 --- a/gcc/config/i386/msformat-c.c +++ b/gcc/config/i386/msformat-c.c @@ -32,10 +32,11 @@ along with GCC; see the file COPYING3. If not see static format_length_info ms_printf_length_specs[] = { { "h", FMT_LEN_h, STD_C89, NULL, FMT_LEN_none, STD_C89, 0 }, - { "l", FMT_LEN_l, STD_C89, NULL, FMT_LEN_none, STD_C89, 0 }, + { "l", FMT_LEN_l, STD_C89, "ll", FMT_LEN_ll, STD_C89, 0 }, + { "L", FMT_LEN_L, STD_C89, NULL, FMT_LEN_none, STD_C89, 1 }, { "I32", FMT_LEN_l, STD_EXT, NULL, FMT_LEN_none, STD_C89, 1 }, { "I64", FMT_LEN_ll, STD_EXT, NULL, FMT_LEN_none, STD_C89, 1 }, - { "I", FMT_LEN_L, STD_EXT, NULL, FMT_LEN_none, STD_C89, 1 }, + { "I", FMT_LEN_z, STD_EXT, NULL, FMT_LEN_none, STD_C89, 1 }, { NULL, FMT_LEN_none, STD_C89, NULL, FMT_LEN_none, STD_C89, 0 } }; @@ -90,33 +91,33 @@ static const format_flag_pair ms_strftime_flag_pairs[] = static const format_char_info ms_print_char_table[] = { /* C89 conversion specifiers. */ - { "di", 0, STD_C89, { T89_I, BADLEN, T89_S, T89_L, T9L_LL, T99_SST, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0 +'", "i", NULL }, - { "oxX", 0, STD_C89, { T89_UI, BADLEN, T89_US, T89_UL, T9L_ULL, T99_ST, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0#", "i", NULL }, - { "u", 0, STD_C89, { T89_UI, BADLEN, T89_US, T89_UL, T9L_ULL, T99_ST, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0'", "i", NULL }, - { "fgG", 0, STD_C89, { T89_D, BADLEN, BADLEN, T99_D, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0 +#'", "", NULL }, - { "eE", 0, STD_C89, { T89_D, BADLEN, BADLEN, T99_D, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0 +#", "", NULL }, - { "c", 0, STD_C89, { T89_I, BADLEN, T89_S, T94_WI, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "", NULL }, - { "s", 1, STD_C89, { T89_C, BADLEN, T89_S, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "cR", NULL }, - { "p", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "c", NULL }, - { "n", 1, STD_C89, { T89_I, BADLEN, T89_S, T89_L, T9L_LL, BADLEN, BADLEN, BADLEN, T99_IM, BADLEN, BADLEN, BADLEN }, "", "W", NULL }, + { "di", 0, STD_C89, { T89_I, BADLEN, T89_S, T89_L, T9L_LL, BADLEN, T99_SST, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0 +'", "i", NULL }, + { "oxX", 0, STD_C89, { T89_UI, BADLEN, T89_US, T89_UL, T9L_ULL, BADLEN, T99_ST, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0#", "i", NULL }, + { "u", 0, STD_C89, { T89_UI, BADLEN, T89_US, T89_UL, T9L_ULL, BADLEN, T99_ST, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0'", "i", NULL }, + { "fgG", 0, STD_C89, { T89_D, BADLEN, BADLEN, T99_D, BADLEN, T89_D, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0 +#'", "", NULL }, + { "eE", 0, STD_C89, { T89_D, BADLEN, BADLEN, T99_D, BADLEN, T89_D, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0 +#", "", NULL }, + { "c", 0, STD_C89, { T89_I, BADLEN, T89_S, T94_WI, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "", NULL }, + { "s", 1, STD_C89, { T89_C, BADLEN, T89_S, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "cR", NULL }, + { "p", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "c", NULL }, + { "n", 1, STD_C89, { T89_I, BADLEN, T89_S, T89_L, T9L_LL, BADLEN, BADLEN, BADLEN, T99_IM, BADLEN, BADLEN, BADLEN }, "", "W", NULL }, /* X/Open conversion specifiers. */ - { "C", 0, STD_EXT, { TEX_WI, BADLEN, T89_S, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "", NULL }, - { "S", 1, STD_EXT, { TEX_W, BADLEN, T89_S, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "R", NULL }, + { "C", 0, STD_EXT, { TEX_WI, BADLEN, T89_S, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "", NULL }, + { "S", 1, STD_EXT, { TEX_W, BADLEN, T89_S, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "R", NULL }, { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL } }; static const format_char_info ms_scan_char_table[] = { /* C89 conversion specifiers. */ - { "di", 1, STD_C89, { T89_I, BADLEN, T89_S, T89_L, T9L_LL, T99_SST, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w'", "W", NULL }, - { "u", 1, STD_C89, { T89_UI, BADLEN, T89_US, T89_UL, T9L_ULL, T99_ST, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w'", "W", NULL }, - { "oxX", 1, STD_C89, { T89_UI, BADLEN, T89_US, T89_UL, T9L_ULL, T99_ST, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w", "W", NULL }, - { "efgEG", 1, STD_C89, { T89_F, BADLEN, BADLEN, T89_D, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w'", "W", NULL }, - { "c", 1, STD_C89, { T89_C, BADLEN, T89_S, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w", "cW", NULL }, - { "s", 1, STD_C89, { T89_C, BADLEN, T89_S, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*aw", "cW", NULL }, - { "[", 1, STD_C89, { T89_C, BADLEN, BADLEN, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*aw", "cW[", NULL }, - { "p", 2, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w", "W", NULL }, - { "n", 1, STD_C89, { T89_I, BADLEN, T89_S, T89_L, T9L_LL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "W", NULL }, + { "di", 1, STD_C89, { T89_I, BADLEN, T89_S, T89_L, T9L_LL, BADLEN, T99_SST, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w'", "W", NULL }, + { "u", 1, STD_C89, { T89_UI, BADLEN, T89_US, T89_UL, T9L_ULL, BADLEN, T99_ST, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w'", "W", NULL }, + { "oxX", 1, STD_C89, { T89_UI, BADLEN, T89_US, T89_UL, T9L_ULL, BADLEN, T99_ST, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w", "W", NULL }, + { "efgEG", 1, STD_C89, { T89_F, BADLEN, BADLEN, T89_D, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w'", "W", NULL }, + { "c", 1, STD_C89, { T89_C, BADLEN, T89_S, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w", "cW", NULL }, + { "s", 1, STD_C89, { T89_C, BADLEN, T89_S, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*aw", "cW", NULL }, + { "[", 1, STD_C89, { T89_C, BADLEN, BADLEN, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*aw", "cW[", NULL }, + { "p", 2, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w", "W", NULL }, + { "n", 1, STD_C89, { T89_I, BADLEN, T89_S, T89_L, T9L_LL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "W", NULL }, /* X/Open conversion specifiers. */ { "C", 1, STD_EXT, { TEX_W, BADLEN, T89_S, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w", "W", NULL }, { "S", 1, STD_EXT, { TEX_W, BADLEN, T89_S, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*aw", "W", NULL }, -- 2.20.1 [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 833 bytes --] ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH][RFC] Make mingw-w64 printf/scanf attribute alias to ms_printf/ms_scanf only for C89 2020-11-12 16:52 ` Liu Hao @ 2020-11-12 18:46 ` Joseph Myers 2020-11-13 2:37 ` Liu Hao 0 siblings, 1 reply; 10+ messages in thread From: Joseph Myers @ 2020-11-12 18:46 UTC (permalink / raw) To: Liu Hao; +Cc: Jonathan Yong, Gcc Patch List, Jonathan Wakely I'd expect these patches to include updates to the gcc.dg/format/ms_*.c tests to reflect the changed semantics (or new tests there if some of the changes don't result in any failures in the existing tests). -- Joseph S. Myers joseph@codesourcery.com ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH][RFC] Make mingw-w64 printf/scanf attribute alias to ms_printf/ms_scanf only for C89 2020-11-12 18:46 ` Joseph Myers @ 2020-11-13 2:37 ` Liu Hao 2020-11-14 0:12 ` Joseph Myers 0 siblings, 1 reply; 10+ messages in thread From: Liu Hao @ 2020-11-13 2:37 UTC (permalink / raw) To: Joseph Myers; +Cc: Jonathan Yong, Gcc Patch List, Jonathan Wakely [-- Attachment #1.1.1: Type: text/plain, Size: 563 bytes --] 在 2020/11/13 2:46, Joseph Myers 写道: > I'd expect these patches to include updates to the gcc.dg/format/ms_*.c > tests to reflect the changed semantics (or new tests there if some of the > changes don't result in any failures in the existing tests). > Does the attached patch suffice? I know very little about Deja GNU. I only tried compiling the function in that test and verified that lines without `dg-warning` didn't result in any warnings with my bootstrapped GCC last night, both on i686 and x86_64. -- Best regards, LH_Mouse [-- Attachment #1.1.2: 0001-gcc-Add-ll-and-L-length-modifiers-for-ms_printf.patch --] [-- Type: text/plain, Size: 11333 bytes --] From 3f58912fb369fd1f645d880a3d967e6523b87507 Mon Sep 17 00:00:00 2001 From: Liu Hao <lh_mouse@126.com> Date: Thu, 12 Nov 2020 22:20:29 +0800 Subject: [PATCH] gcc: Add `ll` and `L` length modifiers for `ms_printf` Previous code abuse `FMT_LEN_L` for the `I` modifier. As `L` is a valid modifier for `f`, `e`, `g`, etc. and `I` has the same semantics as the C99 `z` modifier, `FMT_LEN_z` is now used. First, in the Microsoft ABI, type `long double` has the same layout as type `double`, so `%Lg` behaves identically to `%g`. Users should pass in `double`s instead as `long double`s, as GCC uses the 10-byte format. Second, with a CRT that is recent enough (MSVCRT since Vista, MSVCR80, UCRT, or mingw-w64 8.0), `printf`-family functions can handle the `ll` length modifier correctly. This ability is assumed to be available universally. A lot of libraries (such as libgomp) that use the `format(printf, ...)` attribute used to suffer from warnings about unknown format specifiers. Reference: https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2008/tcxf1dw6(v=vs.90) Reference: https://docs.microsoft.com/en-us/cpp/porting/visual-cpp-what-s-new-2003-through-2015#new-crt-features Signed-off-by: Liu Hao <lh_mouse@126.com> gcc/: * config/i386/msformat-c.c: Add more length modifiers --- gcc/config/i386/msformat-c.c | 45 ++++++++++--------- gcc/testsuite/gcc.dg/format/ms_c99-printf-3.c | 22 ++++++++- 2 files changed, 44 insertions(+), 23 deletions(-) diff --git a/gcc/config/i386/msformat-c.c b/gcc/config/i386/msformat-c.c index 4ceec633a6e..1902b3c73d0 100644 --- a/gcc/config/i386/msformat-c.c +++ b/gcc/config/i386/msformat-c.c @@ -32,10 +32,11 @@ along with GCC; see the file COPYING3. If not see static format_length_info ms_printf_length_specs[] = { { "h", FMT_LEN_h, STD_C89, NULL, FMT_LEN_none, STD_C89, 0 }, - { "l", FMT_LEN_l, STD_C89, NULL, FMT_LEN_none, STD_C89, 0 }, + { "l", FMT_LEN_l, STD_C89, "ll", FMT_LEN_ll, STD_C89, 0 }, + { "L", FMT_LEN_L, STD_C89, NULL, FMT_LEN_none, STD_C89, 1 }, { "I32", FMT_LEN_l, STD_EXT, NULL, FMT_LEN_none, STD_C89, 1 }, { "I64", FMT_LEN_ll, STD_EXT, NULL, FMT_LEN_none, STD_C89, 1 }, - { "I", FMT_LEN_L, STD_EXT, NULL, FMT_LEN_none, STD_C89, 1 }, + { "I", FMT_LEN_z, STD_EXT, NULL, FMT_LEN_none, STD_C89, 1 }, { NULL, FMT_LEN_none, STD_C89, NULL, FMT_LEN_none, STD_C89, 0 } }; @@ -90,33 +91,33 @@ static const format_flag_pair ms_strftime_flag_pairs[] = static const format_char_info ms_print_char_table[] = { /* C89 conversion specifiers. */ - { "di", 0, STD_C89, { T89_I, BADLEN, T89_S, T89_L, T9L_LL, T99_SST, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0 +'", "i", NULL }, - { "oxX", 0, STD_C89, { T89_UI, BADLEN, T89_US, T89_UL, T9L_ULL, T99_ST, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0#", "i", NULL }, - { "u", 0, STD_C89, { T89_UI, BADLEN, T89_US, T89_UL, T9L_ULL, T99_ST, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0'", "i", NULL }, - { "fgG", 0, STD_C89, { T89_D, BADLEN, BADLEN, T99_D, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0 +#'", "", NULL }, - { "eE", 0, STD_C89, { T89_D, BADLEN, BADLEN, T99_D, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0 +#", "", NULL }, - { "c", 0, STD_C89, { T89_I, BADLEN, T89_S, T94_WI, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "", NULL }, - { "s", 1, STD_C89, { T89_C, BADLEN, T89_S, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "cR", NULL }, - { "p", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "c", NULL }, - { "n", 1, STD_C89, { T89_I, BADLEN, T89_S, T89_L, T9L_LL, BADLEN, BADLEN, BADLEN, T99_IM, BADLEN, BADLEN, BADLEN }, "", "W", NULL }, + { "di", 0, STD_C89, { T89_I, BADLEN, T89_S, T89_L, T9L_LL, BADLEN, T99_SST, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0 +'", "i", NULL }, + { "oxX", 0, STD_C89, { T89_UI, BADLEN, T89_US, T89_UL, T9L_ULL, BADLEN, T99_ST, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0#", "i", NULL }, + { "u", 0, STD_C89, { T89_UI, BADLEN, T89_US, T89_UL, T9L_ULL, BADLEN, T99_ST, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0'", "i", NULL }, + { "fgG", 0, STD_C89, { T89_D, BADLEN, BADLEN, T99_D, BADLEN, T89_D, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0 +#'", "", NULL }, + { "eE", 0, STD_C89, { T89_D, BADLEN, BADLEN, T99_D, BADLEN, T89_D, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0 +#", "", NULL }, + { "c", 0, STD_C89, { T89_I, BADLEN, T89_S, T94_WI, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "", NULL }, + { "s", 1, STD_C89, { T89_C, BADLEN, T89_S, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "cR", NULL }, + { "p", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "c", NULL }, + { "n", 1, STD_C89, { T89_I, BADLEN, T89_S, T89_L, T9L_LL, BADLEN, BADLEN, BADLEN, T99_IM, BADLEN, BADLEN, BADLEN }, "", "W", NULL }, /* X/Open conversion specifiers. */ - { "C", 0, STD_EXT, { TEX_WI, BADLEN, T89_S, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "", NULL }, - { "S", 1, STD_EXT, { TEX_W, BADLEN, T89_S, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "R", NULL }, + { "C", 0, STD_EXT, { TEX_WI, BADLEN, T89_S, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "", NULL }, + { "S", 1, STD_EXT, { TEX_W, BADLEN, T89_S, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "R", NULL }, { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL } }; static const format_char_info ms_scan_char_table[] = { /* C89 conversion specifiers. */ - { "di", 1, STD_C89, { T89_I, BADLEN, T89_S, T89_L, T9L_LL, T99_SST, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w'", "W", NULL }, - { "u", 1, STD_C89, { T89_UI, BADLEN, T89_US, T89_UL, T9L_ULL, T99_ST, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w'", "W", NULL }, - { "oxX", 1, STD_C89, { T89_UI, BADLEN, T89_US, T89_UL, T9L_ULL, T99_ST, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w", "W", NULL }, - { "efgEG", 1, STD_C89, { T89_F, BADLEN, BADLEN, T89_D, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w'", "W", NULL }, - { "c", 1, STD_C89, { T89_C, BADLEN, T89_S, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w", "cW", NULL }, - { "s", 1, STD_C89, { T89_C, BADLEN, T89_S, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*aw", "cW", NULL }, - { "[", 1, STD_C89, { T89_C, BADLEN, BADLEN, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*aw", "cW[", NULL }, - { "p", 2, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w", "W", NULL }, - { "n", 1, STD_C89, { T89_I, BADLEN, T89_S, T89_L, T9L_LL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "W", NULL }, + { "di", 1, STD_C89, { T89_I, BADLEN, T89_S, T89_L, T9L_LL, BADLEN, T99_SST, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w'", "W", NULL }, + { "u", 1, STD_C89, { T89_UI, BADLEN, T89_US, T89_UL, T9L_ULL, BADLEN, T99_ST, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w'", "W", NULL }, + { "oxX", 1, STD_C89, { T89_UI, BADLEN, T89_US, T89_UL, T9L_ULL, BADLEN, T99_ST, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w", "W", NULL }, + { "efgEG", 1, STD_C89, { T89_F, BADLEN, BADLEN, T89_D, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w'", "W", NULL }, + { "c", 1, STD_C89, { T89_C, BADLEN, T89_S, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w", "cW", NULL }, + { "s", 1, STD_C89, { T89_C, BADLEN, T89_S, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*aw", "cW", NULL }, + { "[", 1, STD_C89, { T89_C, BADLEN, BADLEN, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*aw", "cW[", NULL }, + { "p", 2, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w", "W", NULL }, + { "n", 1, STD_C89, { T89_I, BADLEN, T89_S, T89_L, T9L_LL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "W", NULL }, /* X/Open conversion specifiers. */ { "C", 1, STD_EXT, { TEX_W, BADLEN, T89_S, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w", "W", NULL }, { "S", 1, STD_EXT, { TEX_W, BADLEN, T89_S, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*aw", "W", NULL }, diff --git a/gcc/testsuite/gcc.dg/format/ms_c99-printf-3.c b/gcc/testsuite/gcc.dg/format/ms_c99-printf-3.c index d8c51eaa063..f46f155a0b1 100644 --- a/gcc/testsuite/gcc.dg/format/ms_c99-printf-3.c +++ b/gcc/testsuite/gcc.dg/format/ms_c99-printf-3.c @@ -9,13 +9,33 @@ #include "format.h" void -foo (int i, char *s, size_t n, va_list v0, va_list v1, va_list v2, va_list v3, +foo (int i, char *s, size_t n, long l, llong ll, double d, + long double ld, va_list v0, va_list v1, va_list v2, va_list v3, va_list v4, va_list v5, va_list v6, va_list v7) { fprintf (stdout, "%d", i); fprintf (stdout, "%ld", i); /* { dg-warning "format" "fprintf" } */ printf ("%d", i); printf ("%ld", i); /* { dg-warning "format" "printf" } */ + /* These are accepted since MSVCR80, MSVCRT from Vista, UCRT, + * and mingw-w64 8.0 with C99/C++11. */ + printf ("%lld", i); /* { dg-warning "format" "printf" } */ + printf ("%lld", l); /* { dg-warning "format" "printf" } */ + printf ("%lld", ll); + printf ("%llu", i); /* { dg-warning "format" "printf" } */ + printf ("%llu", l); /* { dg-warning "format" "printf" } */ + printf ("%llu", ll); + printf ("%llx", i); /* { dg-warning "format" "printf" } */ + printf ("%llx", l); /* { dg-warning "format" "printf" } */ + printf ("%llx", ll); + /* As MSABI uses an 8-byte `long double`, `%Lg` matches GCC's + * `double` instead of `long double` which takes 10 bytes. */ + printf ("%Lg", d); + printf ("%Lg", ld); /* { dg-warning "format" "printf" } */ + printf ("%Le", d); + printf ("%Le", ld); /* { dg-warning "format" "printf" } */ + printf ("%Lf", d); + printf ("%Lf", ld); /* { dg-warning "format" "printf" } */ /* The "unlocked" functions shouldn't warn in c99 mode. */ fprintf_unlocked (stdout, "%ld", i); printf_unlocked ("%ld", i); -- 2.29.2 [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 833 bytes --] ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH][RFC] Make mingw-w64 printf/scanf attribute alias to ms_printf/ms_scanf only for C89 2020-11-13 2:37 ` Liu Hao @ 2020-11-14 0:12 ` Joseph Myers 2020-11-14 2:14 ` Liu Hao 0 siblings, 1 reply; 10+ messages in thread From: Joseph Myers @ 2020-11-14 0:12 UTC (permalink / raw) To: Liu Hao; +Cc: Jonathan Wakely, Gcc Patch List On Fri, 13 Nov 2020, Liu Hao via Gcc-patches wrote: > 在 2020/11/13 2:46, Joseph Myers 写道: > > I'd expect these patches to include updates to the gcc.dg/format/ms_*.c > > tests to reflect the changed semantics (or new tests there if some of the > > changes don't result in any failures in the existing tests). > > > > Does the attached patch suffice? This is testing the sort of thing I'd expect tests for regarding 'L' and 'll'. What about the changes for 'I' - do those result in changes to how the compiler behaves, which should also have tests? -- Joseph S. Myers joseph@codesourcery.com ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH][RFC] Make mingw-w64 printf/scanf attribute alias to ms_printf/ms_scanf only for C89 2020-11-14 0:12 ` Joseph Myers @ 2020-11-14 2:14 ` Liu Hao 2020-11-14 12:29 ` Liu Hao 0 siblings, 1 reply; 10+ messages in thread From: Liu Hao @ 2020-11-14 2:14 UTC (permalink / raw) To: Joseph Myers; +Cc: Jonathan Wakely, Gcc Patch List [-- Attachment #1.1: Type: text/plain, Size: 828 bytes --] 在 2020/11/14 上午8:12, Joseph Myers 写道: > On Fri, 13 Nov 2020, Liu Hao via Gcc-patches wrote: > >> 在 2020/11/13 2:46, Joseph Myers 写道: >>> I'd expect these patches to include updates to the gcc.dg/format/ms_*.c >>> tests to reflect the changed semantics (or new tests there if some of the >>> changes don't result in any failures in the existing tests). >>> >> >> Does the attached patch suffice? > > This is testing the sort of thing I'd expect tests for regarding 'L' and > 'll'. What about the changes for 'I' - do those result in changes to how > the compiler behaves, which should also have tests? > There is already a test for `%Ix` in 'ms_c99-printf-2.c', but there is no test (in all 'ms_*printf*' files) which checks for absence of warnings. -- Best regards, LH_Mouse [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 833 bytes --] ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH][RFC] Make mingw-w64 printf/scanf attribute alias to ms_printf/ms_scanf only for C89 2020-11-14 2:14 ` Liu Hao @ 2020-11-14 12:29 ` Liu Hao 2020-11-16 5:40 ` Jonathan Yong 0 siblings, 1 reply; 10+ messages in thread From: Liu Hao @ 2020-11-14 12:29 UTC (permalink / raw) To: Joseph Myers; +Cc: Jonathan Wakely, Gcc Patch List [-- Attachment #1.1.1: Type: text/plain, Size: 430 bytes --] This is the third revision of my patch: 1. Two typos in the commit message have been fixed. 2. Support for `%a` and `%A` has been added. Documentation can be found on the same page in the commit message. 3. GCC will no longer warn about 'ISO C does not support the ‘L’ ms_printf length modifier'. This was caused by mistaken array indices in `TARGET_OVERRIDES_FORMAT_INIT`. -- Best regards, LH_Mouse [-- Attachment #1.1.2: 0001-gcc-Add-ll-and-L-length-modifiers-for-ms_printf.patch --] [-- Type: text/plain, Size: 12015 bytes --] From f73d5dcdc61a5da1a4265b144739067b4ec40ec2 Mon Sep 17 00:00:00 2001 From: Liu Hao <lh_mouse@126.com> Date: Thu, 12 Nov 2020 22:20:29 +0800 Subject: [PATCH] gcc: Add `ll` and `L` length modifiers for `ms_printf` Previous code abused `FMT_LEN_L` for the `I` modifier. As `L` is a valid modifier for `f`, `e`, `g`, etc. and `I` has the same semantics as the C99 `z` modifier, `FMT_LEN_z` is now used instead. First, in the Microsoft ABI, type `long double` has the same layout as type `double`, so `%Lg` behaves identically to `%g`. Users should pass in `double`s instead of `long double`s, as GCC uses the 10-byte format. Second, with a CRT that is recent enough (MSVCRT since Vista, MSVCR80, UCRT, or mingw-w64 8.0), `printf`-family functions can handle the `ll` length modifier correctly. This ability is assumed to be available universally. A lot of libraries (such as libgomp) that use the `format(printf, ...)` attribute used to suffer from warnings about unknown format specifiers. Reference: https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2008/tcxf1dw6(v=vs.90) Reference: https://docs.microsoft.com/en-us/cpp/porting/visual-cpp-what-s-new-2003-through-2015#new-crt-features Signed-off-by: Liu Hao <lh_mouse@126.com> gcc/: * config/i386/msformat-c.c: Add more length modifiers --- gcc/config/i386/msformat-c.c | 53 ++++++++++--------- gcc/testsuite/gcc.dg/format/ms_c99-printf-3.c | 22 +++++++- 2 files changed, 49 insertions(+), 26 deletions(-) diff --git a/gcc/config/i386/msformat-c.c b/gcc/config/i386/msformat-c.c index 4ceec633a6e..085ac88789a 100644 --- a/gcc/config/i386/msformat-c.c +++ b/gcc/config/i386/msformat-c.c @@ -32,10 +32,11 @@ along with GCC; see the file COPYING3. If not see static format_length_info ms_printf_length_specs[] = { { "h", FMT_LEN_h, STD_C89, NULL, FMT_LEN_none, STD_C89, 0 }, - { "l", FMT_LEN_l, STD_C89, NULL, FMT_LEN_none, STD_C89, 0 }, + { "l", FMT_LEN_l, STD_C89, "ll", FMT_LEN_ll, STD_C89, 0 }, + { "L", FMT_LEN_L, STD_C89, NULL, FMT_LEN_none, STD_C89, 1 }, { "I32", FMT_LEN_l, STD_EXT, NULL, FMT_LEN_none, STD_C89, 1 }, { "I64", FMT_LEN_ll, STD_EXT, NULL, FMT_LEN_none, STD_C89, 1 }, - { "I", FMT_LEN_L, STD_EXT, NULL, FMT_LEN_none, STD_C89, 1 }, + { "I", FMT_LEN_z, STD_EXT, NULL, FMT_LEN_none, STD_C89, 1 }, { NULL, FMT_LEN_none, STD_C89, NULL, FMT_LEN_none, STD_C89, 0 } }; @@ -90,33 +91,35 @@ static const format_flag_pair ms_strftime_flag_pairs[] = static const format_char_info ms_print_char_table[] = { /* C89 conversion specifiers. */ - { "di", 0, STD_C89, { T89_I, BADLEN, T89_S, T89_L, T9L_LL, T99_SST, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0 +'", "i", NULL }, - { "oxX", 0, STD_C89, { T89_UI, BADLEN, T89_US, T89_UL, T9L_ULL, T99_ST, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0#", "i", NULL }, - { "u", 0, STD_C89, { T89_UI, BADLEN, T89_US, T89_UL, T9L_ULL, T99_ST, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0'", "i", NULL }, - { "fgG", 0, STD_C89, { T89_D, BADLEN, BADLEN, T99_D, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0 +#'", "", NULL }, - { "eE", 0, STD_C89, { T89_D, BADLEN, BADLEN, T99_D, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0 +#", "", NULL }, - { "c", 0, STD_C89, { T89_I, BADLEN, T89_S, T94_WI, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "", NULL }, - { "s", 1, STD_C89, { T89_C, BADLEN, T89_S, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "cR", NULL }, - { "p", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "c", NULL }, - { "n", 1, STD_C89, { T89_I, BADLEN, T89_S, T89_L, T9L_LL, BADLEN, BADLEN, BADLEN, T99_IM, BADLEN, BADLEN, BADLEN }, "", "W", NULL }, + { "di", 0, STD_C89, { T89_I, BADLEN, T89_S, T89_L, T9L_LL, BADLEN, T99_SST, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0 +'", "i", NULL }, + { "oxX", 0, STD_C89, { T89_UI, BADLEN, T89_US, T89_UL, T9L_ULL, BADLEN, T99_ST, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0#", "i", NULL }, + { "u", 0, STD_C89, { T89_UI, BADLEN, T89_US, T89_UL, T9L_ULL, BADLEN, T99_ST, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0'", "i", NULL }, + { "fgG", 0, STD_C89, { T89_D, BADLEN, BADLEN, T99_D, BADLEN, T89_D, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0 +#'", "", NULL }, + { "eE", 0, STD_C89, { T89_D, BADLEN, BADLEN, T99_D, BADLEN, T89_D, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0 +#", "", NULL }, + { "c", 0, STD_C89, { T89_I, BADLEN, T89_S, T94_WI, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "", NULL }, + { "s", 1, STD_C89, { T89_C, BADLEN, T89_S, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "cR", NULL }, + { "p", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "c", NULL }, + { "n", 1, STD_C89, { T89_I, BADLEN, T89_S, T89_L, T9L_LL, BADLEN, BADLEN, BADLEN, T99_IM, BADLEN, BADLEN, BADLEN }, "", "W", NULL }, + /* C99 conversion specifiers. */ + { "aA", 0, STD_C99, { T99_D, BADLEN, BADLEN, T99_D, BADLEN, T99_D, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0 +#", "", NULL }, /* X/Open conversion specifiers. */ - { "C", 0, STD_EXT, { TEX_WI, BADLEN, T89_S, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "", NULL }, - { "S", 1, STD_EXT, { TEX_W, BADLEN, T89_S, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "R", NULL }, + { "C", 0, STD_EXT, { TEX_WI, BADLEN, T89_S, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "", NULL }, + { "S", 1, STD_EXT, { TEX_W, BADLEN, T89_S, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "R", NULL }, { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL } }; static const format_char_info ms_scan_char_table[] = { /* C89 conversion specifiers. */ - { "di", 1, STD_C89, { T89_I, BADLEN, T89_S, T89_L, T9L_LL, T99_SST, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w'", "W", NULL }, - { "u", 1, STD_C89, { T89_UI, BADLEN, T89_US, T89_UL, T9L_ULL, T99_ST, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w'", "W", NULL }, - { "oxX", 1, STD_C89, { T89_UI, BADLEN, T89_US, T89_UL, T9L_ULL, T99_ST, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w", "W", NULL }, - { "efgEG", 1, STD_C89, { T89_F, BADLEN, BADLEN, T89_D, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w'", "W", NULL }, - { "c", 1, STD_C89, { T89_C, BADLEN, T89_S, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w", "cW", NULL }, - { "s", 1, STD_C89, { T89_C, BADLEN, T89_S, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*aw", "cW", NULL }, - { "[", 1, STD_C89, { T89_C, BADLEN, BADLEN, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*aw", "cW[", NULL }, - { "p", 2, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w", "W", NULL }, - { "n", 1, STD_C89, { T89_I, BADLEN, T89_S, T89_L, T9L_LL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "W", NULL }, + { "di", 1, STD_C89, { T89_I, BADLEN, T89_S, T89_L, T9L_LL, BADLEN, T99_SST, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w'", "W", NULL }, + { "u", 1, STD_C89, { T89_UI, BADLEN, T89_US, T89_UL, T9L_ULL, BADLEN, T99_ST, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w'", "W", NULL }, + { "oxX", 1, STD_C89, { T89_UI, BADLEN, T89_US, T89_UL, T9L_ULL, BADLEN, T99_ST, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w", "W", NULL }, + { "efgEG", 1, STD_C89, { T89_F, BADLEN, BADLEN, T89_D, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w'", "W", NULL }, + { "c", 1, STD_C89, { T89_C, BADLEN, T89_S, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w", "cW", NULL }, + { "s", 1, STD_C89, { T89_C, BADLEN, T89_S, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*aw", "cW", NULL }, + { "[", 1, STD_C89, { T89_C, BADLEN, BADLEN, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*aw", "cW[", NULL }, + { "p", 2, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w", "W", NULL }, + { "n", 1, STD_C89, { T89_I, BADLEN, T89_S, T89_L, T9L_LL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "W", NULL }, /* X/Open conversion specifiers. */ { "C", 1, STD_EXT, { TEX_W, BADLEN, T89_S, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w", "W", NULL }, { "S", 1, STD_EXT, { TEX_W, BADLEN, T89_S, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*aw", "W", NULL }, @@ -182,9 +185,9 @@ extern void TARGET_OVERRIDES_FORMAT_INIT (void); void TARGET_OVERRIDES_FORMAT_INIT (void) { - ms_printf_length_specs[2].std = C89_OR_EXT; /* I32 */ - ms_printf_length_specs[3].std = C89_OR_EXT; /* I64 */ - ms_printf_length_specs[4].std = C89_OR_EXT; /* I */ + ms_printf_length_specs[3].std = C89_OR_EXT; /* I32 */ + ms_printf_length_specs[4].std = C89_OR_EXT; /* I64 */ + ms_printf_length_specs[5].std = C89_OR_EXT; /* I */ } #undef C89_OR_EXT diff --git a/gcc/testsuite/gcc.dg/format/ms_c99-printf-3.c b/gcc/testsuite/gcc.dg/format/ms_c99-printf-3.c index d8c51eaa063..f46f155a0b1 100644 --- a/gcc/testsuite/gcc.dg/format/ms_c99-printf-3.c +++ b/gcc/testsuite/gcc.dg/format/ms_c99-printf-3.c @@ -9,13 +9,33 @@ #include "format.h" void -foo (int i, char *s, size_t n, va_list v0, va_list v1, va_list v2, va_list v3, +foo (int i, char *s, size_t n, long l, llong ll, double d, + long double ld, va_list v0, va_list v1, va_list v2, va_list v3, va_list v4, va_list v5, va_list v6, va_list v7) { fprintf (stdout, "%d", i); fprintf (stdout, "%ld", i); /* { dg-warning "format" "fprintf" } */ printf ("%d", i); printf ("%ld", i); /* { dg-warning "format" "printf" } */ + /* These are accepted since MSVCR80, MSVCRT from Vista, UCRT, + * and mingw-w64 8.0 with C99/C++11. */ + printf ("%lld", i); /* { dg-warning "format" "printf" } */ + printf ("%lld", l); /* { dg-warning "format" "printf" } */ + printf ("%lld", ll); + printf ("%llu", i); /* { dg-warning "format" "printf" } */ + printf ("%llu", l); /* { dg-warning "format" "printf" } */ + printf ("%llu", ll); + printf ("%llx", i); /* { dg-warning "format" "printf" } */ + printf ("%llx", l); /* { dg-warning "format" "printf" } */ + printf ("%llx", ll); + /* As MSABI uses an 8-byte `long double`, `%Lg` matches GCC's + * `double` instead of `long double` which takes 10 bytes. */ + printf ("%Lg", d); + printf ("%Lg", ld); /* { dg-warning "format" "printf" } */ + printf ("%Le", d); + printf ("%Le", ld); /* { dg-warning "format" "printf" } */ + printf ("%Lf", d); + printf ("%Lf", ld); /* { dg-warning "format" "printf" } */ /* The "unlocked" functions shouldn't warn in c99 mode. */ fprintf_unlocked (stdout, "%ld", i); printf_unlocked ("%ld", i); -- 2.29.2 [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 833 bytes --] ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH][RFC] Make mingw-w64 printf/scanf attribute alias to ms_printf/ms_scanf only for C89 2020-11-14 12:29 ` Liu Hao @ 2020-11-16 5:40 ` Jonathan Yong 2020-11-17 10:35 ` Jonathan Yong 0 siblings, 1 reply; 10+ messages in thread From: Jonathan Yong @ 2020-11-16 5:40 UTC (permalink / raw) To: Liu Hao, Joseph Myers; +Cc: Jonathan Wakely, Gcc Patch List [-- Attachment #1.1.1: Type: text/plain, Size: 543 bytes --] On 11/14/20 12:29 PM, Liu Hao via Gcc-patches wrote: > This is the third revision of my patch: > > 1. Two typos in the commit message have been fixed. > 2. Support for `%a` and `%A` has been added. Documentation can be > found on the same page in the commit message. > 3. GCC will no longer warn about 'ISO C does not support the ‘L’ > ms_printf length modifier'. This was caused by mistaken array > indices in `TARGET_OVERRIDES_FORMAT_INIT`. > > I'll be pushing this soon if there aren't any more complaints. [-- Attachment #1.1.2: OpenPGP_0x713B5FE29C145D45_and_old_rev.asc --] [-- Type: application/pgp-keys, Size: 8035 bytes --] [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 840 bytes --] ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH][RFC] Make mingw-w64 printf/scanf attribute alias to ms_printf/ms_scanf only for C89 2020-11-16 5:40 ` Jonathan Yong @ 2020-11-17 10:35 ` Jonathan Yong 0 siblings, 0 replies; 10+ messages in thread From: Jonathan Yong @ 2020-11-17 10:35 UTC (permalink / raw) To: Liu Hao, Joseph Myers; +Cc: Jonathan Wakely, Gcc Patch List [-- Attachment #1.1.1: Type: text/plain, Size: 672 bytes --] On 11/16/20 5:40 AM, Jonathan Yong wrote: > On 11/14/20 12:29 PM, Liu Hao via Gcc-patches wrote: >> This is the third revision of my patch: >> >> 1. Two typos in the commit message have been fixed. >> 2. Support for `%a` and `%A` has been added. Documentation can be >> found on the same page in the commit message. >> 3. GCC will no longer warn about 'ISO C does not support the ‘L’ >> ms_printf length modifier'. This was caused by mistaken array >> indices in `TARGET_OVERRIDES_FORMAT_INIT`. >> >> > > I'll be pushing this soon if there aren't any more complaints. Pushed to master, thanks all for contributing and reviewing. [-- Attachment #1.1.2: OpenPGP_0x713B5FE29C145D45_and_old_rev.asc --] [-- Type: application/pgp-keys, Size: 8035 bytes --] [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 840 bytes --] ^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2020-11-17 10:35 UTC | newest] Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2020-11-12 10:18 [PATCH][RFC] Make mingw-w64 printf/scanf attribute alias to ms_printf/ms_scanf only for C89 Jonathan Yong 2020-11-12 15:12 ` Liu Hao 2020-11-12 16:52 ` Liu Hao 2020-11-12 18:46 ` Joseph Myers 2020-11-13 2:37 ` Liu Hao 2020-11-14 0:12 ` Joseph Myers 2020-11-14 2:14 ` Liu Hao 2020-11-14 12:29 ` Liu Hao 2020-11-16 5:40 ` Jonathan Yong 2020-11-17 10:35 ` Jonathan Yong
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).