On 1/13/2012 18:41, JonY wrote: > On 1/12/2012 04:30, Christian Franke wrote: >> JonY wrote: >>> On 1/6/2012 04:42, Kai Tietz wrote: >>>> 2012/1/5 Christian Franke<[email protected]>: >>>>> [Originally sent to Cygwin mailing list] >>>>> >>>>> When printf/scanf functions from MinGW runtime are selected via >>>>> __USE_MINGW_ANSI_STDIO, then format string checking is broken. This only >>>>> affects the C++ compiler: >>>>> >>>>> $ cygcheck -f /usr/bin/i686-w64-mingw32-g++ >>>>> mingw64-i686-gcc-g++-4.5.3-4 >>>>> >>>>> $ cat testfmt.c >>>>> #define __USE_MINGW_ANSI_STDIO 1 >>>>> #include<stdio.h> >>>>> >>>>> void myprintf(const char *, ...) >>>>> __attribute__((format(gnu_printf,1,2))); >>>>> >>>>> int main() >>>>> { >>>>> long long x = 42; >>>>> printf("%lld\n", x); // C++: Bogus warning >>>>> myprintf("%lld\n", x); // No warning (OK) >>>>> printf("%I64d\n", x); // Warning (OK) >>>>> return 0; >>>>> } >>>>> >>>>> $ i686-w64-mingw32-gcc -Wformat -c testfmt.c >>>>> testfmt.c: In function 'main': >>>>> testfmt.c:12:3: warning: format '%I64d' expects type 'int', but argument >>>>> 2 has type 'long long int' >>>>> >>>>> $ i686-w64-mingw32-g++ -Wformat -c testfmt.c >>>>> testfmt.c: In function 'int main()': >>>>> testfmt.c:10:21: warning: unknown conversion type character 'l' in format >>>>> testfmt.c:10:21: warning: too many arguments for format >>>>> testfmt.c:12:22: warning: format '%I64d' expects type 'int', but >>>>> argument 2 has type 'long long int' >>>>> >>>>> >>>>> Interestingly the bogus warning only occurs for standard functions like >>>>> printf(). These are replaced by inline functions in MinGW stdio.h if >>>>> __USE_MINGW_ANSI_STDIO is set. Probably a subtle bug in the handling of >>>>> functions known by the compiler. >>>> Issue is fixed on trunk. Version 2 branch still has those issues, as >>>> fixes to stdio.h and wchar.h were not merged back. >>>> >>> Looks like I need to do a new header/crt release soon. >> >> Thanks - but unfortunately the bug is still present after update to >> mingw64-i686-headers-3.0b_svn4725-1 >> >> The bug is likely in g++ itself. If __USE_MINGW_ANSI_STDIO is not set, >> format checking works, but interestingly the prototype does not provide >> a format attribute in this case: >> >> /usr/i686-w64-mingw32/sys-root/mingw/include/stdio.h: >> ... >> #if __USE_MINGW_ANSI_STDIO >> ... >> __mingw_ovr >> __attribute__((__format__ (gnu_printf, 1, 2))) ... >> int printf (const char *__format, ...) { ... } >> ... >> #else /* !__USE_MINGW_ANSI_STDIO */ >> ... >> int __cdecl printf(const char * __restrict__ _Format,...); >> // __attribute__((__format__(ms_printf, 1, 2))) <<--- MISSING! >> ... >> #endif /* __USE_MINGW_ANSI_STDIO */ >> >> So there is likely some special handling for printf() done by the compiler. >> (Another: gcc/g++ convert printf("Foo\n") to puts("Foo") regardless of >> -O level). >> >> Overriding the build in format attribute by the new printf() inline >> wrapper in MinGW stdio.h might not work properly. >> >> Christian >> >> > > Ping, Kai, any thing? > > I'll try to fix them in trunk soon, sorry for the long delay. >
Kai, should those new macros go into _mingw.h instead? It probably can be used for wide and multibyte functions too. If not, they should stay in stdio.h.
Index: trunk/mingw-w64-headers/crt/_mingw_mac.h =================================================================== --- trunk/mingw-w64-headers/crt/_mingw_mac.h (revision 4738) +++ trunk/mingw-w64-headers/crt/_mingw_mac.h (working copy) @@ -180,5 +180,10 @@ # define __MINGW_ATTRIB_DEPRECATED_SEC_WARN #endif +#define __MINGW_MS_PRINTF(__format,__args) __attribute__((__format__(ms_printf, __format,__args))) +#define __MINGW_MS_SCANF(__format,__args) __attribute__((__format__(ms_scanf, __format,__args))) +#define __MINGW_GNU_PRINTF(__format,__args) __attribute__((__format__(gnu_printf,__format,__args))) +#define __MINGW_GNU_SCANF(__format,__args) __attribute__((__format__(gnu_scanf, __format,__args))) + #endif /* _INC_CRTDEFS_MACRO */ Index: trunk/mingw-w64-headers/crt/stdio.h =================================================================== --- trunk/mingw-w64-headers/crt/stdio.h (revision 4738) +++ trunk/mingw-w64-headers/crt/stdio.h (working copy) @@ -363,21 +363,21 @@ /* * Default configuration: simply direct all calls to MSVCRT... */ - int __cdecl fprintf(FILE * __restrict__ _File,const char * __restrict__ _Format,...); - int __cdecl printf(const char * __restrict__ _Format,...); - int __cdecl sprintf(char * __restrict__ _Dest,const char * __restrict__ _Format,...) __MINGW_ATTRIB_DEPRECATED_SEC_WARN; + int __cdecl fprintf(FILE * __restrict__ _File,const char * __restrict__ _Format,...) __MINGW_MS_PRINTF(2,3); + int __cdecl printf(const char * __restrict__ _Format,...) __MINGW_MS_PRINTF(1,2); + int __cdecl sprintf(char * __restrict__ _Dest,const char * __restrict__ _Format,...) __MINGW_ATTRIB_DEPRECATED_SEC_WARN __MINGW_MS_PRINTF(2,3); - int __cdecl vfprintf(FILE * __restrict__ _File,const char * __restrict__ _Format,va_list _ArgList); - int __cdecl vprintf(const char * __restrict__ _Format,va_list _ArgList); - int __cdecl vsprintf(char * __restrict__ _Dest,const char * __restrict__ _Format,va_list _Args) __MINGW_ATTRIB_DEPRECATED_SEC_WARN; + int __cdecl vfprintf(FILE * __restrict__ _File,const char * __restrict__ _Format,va_list _ArgList) __MINGW_MS_PRINTF(2,0); + int __cdecl vprintf(const char * __restrict__ _Format,va_list _ArgList) __MINGW_MS_PRINTF(1,0); + int __cdecl vsprintf(char * __restrict__ _Dest,const char * __restrict__ _Format,va_list _Args) __MINGW_MS_PRINTF(2,0); - int __cdecl fscanf(FILE * __restrict__ _File,const char * __restrict__ _Format,...) __MINGW_ATTRIB_DEPRECATED_SEC_WARN; - int __cdecl scanf(const char * __restrict__ _Format,...) __MINGW_ATTRIB_DEPRECATED_SEC_WARN; - int __cdecl sscanf(const char * __restrict__ _Src,const char * __restrict__ _Format,...) __MINGW_ATTRIB_DEPRECATED_SEC_WARN; + int __cdecl fscanf(FILE * __restrict__ _File,const char * __restrict__ _Format,...) __MINGW_ATTRIB_DEPRECATED_SEC_WARN __MINGW_MS_SCANF(2,3); + int __cdecl scanf(const char * __restrict__ _Format,...) __MINGW_ATTRIB_DEPRECATED_SEC_WARN __MINGW_MS_SCANF(1,2); + int __cdecl sscanf(const char * __restrict__ _Src,const char * __restrict__ _Format,...) __MINGW_ATTRIB_DEPRECATED_SEC_WARN __MINGW_MS_SCANF(2,3); #ifndef __NO_ISOCEXT /* externs in libmingwex.a */ - int __cdecl __ms_vscanf(const char * __restrict__ Format, va_list argp); - int __cdecl __ms_vfscanf (FILE * __restrict__ fp, const char * __restrict__ Format,va_list argp); - int __cdecl __ms_vsscanf (const char * __restrict__ _Str,const char * __restrict__ Format,va_list argp); + int __cdecl __ms_vscanf(const char * __restrict__ Format, va_list argp) __MINGW_MS_SCANF(1,0); + int __cdecl __ms_vfscanf (FILE * __restrict__ fp, const char * __restrict__ Format,va_list argp) __MINGW_MS_SCANF(2,0); + int __cdecl __ms_vsscanf (const char * __restrict__ _Str,const char * __restrict__ Format,va_list argp) __MINGW_MS_SCANF(2,0); __mingw_ovr __MINGW_ATTRIB_NONNULL(2)
signature.asc
Description: OpenPGP digital signature
------------------------------------------------------------------------------ RSA(R) Conference 2012 Mar 27 - Feb 2 Save $400 by Jan. 27 Register now! http://p.sf.net/sfu/rsa-sfdev2dev2
_______________________________________________ Mingw-w64-public mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
