[Mingw-w64-public] mingw-w64 and __attribute__((format(printf))) issue

Martin Storsjö martin@martin.st
Wed May 6 10:48:42 GMT 2020


On Wed, 6 May 2020, Liu Hao wrote:

> Due to a recent change in mingw-w64 master [1], libgomp ceases to build:
>
> ```
> ../../../gcc-git/libgomp/target.c:936:21: error: unknown conversion type
> character 'l' in format [-Werror=format=]
>  936 |         gomp_fatal ("present clause: !acc_is_present (%p, "
>      |                     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> ```
>
>
> On line 29 of 'libgomp/libgomp.h' from GCC 9 branch I found this declaration
>
> ```
> extern void gomp_fatal (const char *, ...)
>        __attribute__ ((noreturn, format (printf, 1, 2)));
> ```
>
> , which uses the `printf` attribute, but the `PRIu64` macro from
> <inttypes.h> expands to `%llu` because now GCC has `-std=gnu11` by
> default, which is only valid with `gnu_printf`.
>
> AFAICS there are three solutions:
>
> 1. Revert bfd33f6c0ec5e652cc9911857dd1492ece8d8383 in mingw-w64, or

This is generally the risk of this kind of commit - regardless of how 
right/wrong the status quo is, there's _a lot_ of code that relies on it 
behaving in a specific way, and changing that will certainly run into 
minor issues in a lot of places.

> 2. Make GCC treat `format(printf)` as `format(gnu_printf)` if C11 or
>   C++11 is selected, or

I'm not very keen on that. The compiler should ideally not assume to much 
about what the platform headers do in detail, because it limits what we 
can change. (If we'd make that change in the compiler, and then for 
another reason end up reverting the commit, we'd have the same issue in 
reverse.)

> 3. Replace `format(printf)` with `format(gnu_printf)` in libgomp source.

This also kind of hardcodes too much; libgomp in general can't and 
shouldn't assume too much about which format kind it uses, unless libgomp 
itself hardcodes __USE_MINGW_ANSI_STDIO. Also, the whole gnu_printf format 
is something that only GCC supports, not Clang, but I guess libgomp is 
rather GCC specific anyway.

However we do have a define that should expand to the right thing - just 
like inttypes.h PRIu64 follows __USE_MINGW_ANSI_STDIO - we have 
__MINGW_PRINTF_FORMAT.

So something like this should work:

#ifdef __MINGW32__
#define PRINTF_FORMAT __MINGW_PRINTF_FORMAT
#else
#define PRINTF_FORMAT printf
#endif

__attribute__((format(PRINTF_FORMAT)))

Not very pretty, but should work without hardcoding any assumptions about 
which format actually is used.


// Martin



More information about the Gcc-help mailing list