Bug 37768 - bogus warnings on x86_64-mingw32 due to attribute((format(printf))) breakage
Summary: bogus warnings on x86_64-mingw32 due to attribute((format(printf))) breakage
Status: RESOLVED INVALID
Alias: None
Product: gcc
Classification: Unclassified
Component: c (show other bugs)
Version: 4.4.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2008-10-08 09:30 UTC by Mikael Pettersson
Modified: 2008-10-09 07:04 UTC (History)
1 user (show)

See Also:
Host:
Target: x86_64-pc-mingw32
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Mikael Pettersson 2008-10-08 09:30:01 UTC
When gcc is configured to generate code for x86_64-pc-mingw32, that is MinGW for 64-bit Windows, attribute((format(printf))) is redefined by the backend to be compatible with MSVC's runtime library, which differs significantly from C99.

This is fine for calls that link to MSVC's library, but it breaks code that uses private implementations of C99-compliant formatting routines, because the backend redefines ALL uses of attribute((format(printf))) to mean MSVC's printf not C99. The result is that C99-compliant code gets stray warnings and inadequate printf format checking on x86_64-pc-mingw32.

The program below illustrates the issue. It declares a private C99-compliant snprintf() implementation and invokes it with "%zu" and "%llx" formats. This
triggers the following bogus warnings on x86_64-pc-mingw32:

> x86_64-pc-mingw32-gcc -std=c99 -O -Wall -c badwarning.c
badwarning.c: In function 'main':
badwarning.c:16: warning: unknown conversion type character 'z' in format
badwarning.c:16: warning: unknown conversion type character 'l' in format
badwarning.c:16: warning: too many arguments for format

What I think the backend should do is to implement an "msprintf" format type, and then Mingw-w64 should declare printf() et al using that not plain "printf".

/* badwarning.c */
#include <stddef.h>
#include <stdarg.h>

int  __attribute__((format(printf, 3, 4)))
    my_snprintf(char *buf, size_t n, const char *fmt, ...)
{
    /* invoke C99 compliant private vsnprintf() here */
    return 0;
}

int main(void)
{
    char buf[64];
    return my_snprintf(buf, sizeof buf, "%zu %llx",
                       sizeof buf, 0ULL);
}
Comment 1 jsm-csl@polyomino.org.uk 2008-10-08 16:15:07 UTC
Subject: Re:   New: bogus warnings on x86_64-mingw32 due to
 attribute((format(printf))) breakage

On Wed, 8 Oct 2008, mikpe at it dot uu dot se wrote:

> When gcc is configured to generate code for x86_64-pc-mingw32, that is MinGW
> for 64-bit Windows, attribute((format(printf))) is redefined by the backend to
> be compatible with MSVC's runtime library, which differs significantly from
> C99.

Correct.  This is the conclusion we eventually reached, that "printf" 
would be for the system formats (e.g. for a function wrapping a call to a 
system function), that "gnu_printf" would be for the formats accepted by 
the GNU C Library (including GNU extensions) on all platforms and that 
"ms_printf" would be for the MSVC formats, on Windows platforms only.

> The program below illustrates the issue. It declares a private C99-compliant
> snprintf() implementation and invokes it with "%zu" and "%llx" formats. This
> triggers the following bogus warnings on x86_64-pc-mingw32:

Use gnu_printf for such an implementation.

Comment 2 Mikael Pettersson 2008-10-09 07:04:00 UTC
> > The program below illustrates the issue. It declares a private C99-compliant
> > snprintf() implementation and invokes it with "%zu" and "%llx" formats. This
> > triggers the following bogus warnings on x86_64-pc-mingw32:
> 
> Use gnu_printf for such an implementation.

Thanks. Using gnu_printf (new in 4.4) solves the issues I had.