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