This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Other format: | [Raw text] |
Hello. This is refresh of a 'Proto-patch for "%I64" on Microsoft" submitted by Mark Mitchell back in; http://gcc.gnu.org/ml/gcc-patches/2004-11/msg02296.html MS runtime printf/scanf do not accept "%ll" as long long length specifier, but uses "%I64" instead. It also allows "%I32" for int and "%I" for size_t and ptrdiff_t This removes -Wformat warnings on use of these length specifiers on mingw32, and adds warnings on mingw32 if "I" is used in places where it is allowed by glibc. ISO C warnings are still reported with --pedantic Changelog 2006-11-06 Mark Mitchell <mark@codesourcery.com> Danny Smith <dannysmith@users.sourceforge.net> * doc/tm.texi (TARGET_EXTRA_PRINTF_FLAG_CHARS, TARGET_SCANF_PRINTF_FLAG_CHARS, TARGET_EXTRA_PRINTF_LENGTH_SPECIFIERS, TARGET_EXTRA_SCANF_LENGTH_SPECIFIERS): Document. * defaults.h (TARGET_EXTRA_PRINTF_FLAG_CHARS, TARGET_SCANF_PRINTF_FLAG_CHARS) : Define default. * c-format.c (printf_length_specs): Conditionally add TARGET_EXTRA_PRINTF_LENGTH_SPECIFIERS. (scanf_length_specs): Conditionally add TARGET_EXTRA_SCANF_LENGTH_SPECIFIERS. (format_types_orig):Add TARGET_EXTRA_PRINTF_FLAG_CHARS, TARGET_SCANF_PRINTF_FLAG_CHARS. * config/i386/mingw32.h: (TARGET_EXTRA_PRINTF_FLAG_CHARS, TARGET_SCANF_PRINTF_FLAG_CHARS, TARGET_EXTRA_PRINTF_LENGTH_SPECIFIERS, TARGET_EXTRA_SCANF_LENGTH_SPECIFIERS): Add defines. testsuite * gcc.dg/format/ext-1.c: Exclude MSVCRT targets from "I" tests. * gcc.dg/format/ext-2.c: Likewise. * gcc.dg/format/ext-7.c: New test. Index: doc/tm.texi =================================================================== *** doc/tm.texi (revision 118371) --- doc/tm.texi (working copy) *************** SUPPORTS_WEAK and TARGET_HAVE_NAMED_SECT *** 9942,9944 **** --- 9942,9969 ---- This macro determines the size of the objective C jump buffer for the NeXT runtime. By default, OBJC_JBLEN is defined to an innocuous value. @end defmac + + @defmac TARGET_EXTRA_PRINTF_FLAG_CHARS + Define this macro to a C string containing a comma-separated list of + flag characters that are supported by the systems C runtime @code{printf} + function. By default it is defined to "I" since historically GCC has + accepted GLIBC's "I" flag on all systems. + @end defmac + + @defmac TARGET_SCANF_PRINTF_FLAG_CHARS + Define this macro to a C string containing a comma-separated list of + flag characters that are supported by the systems C runtime @code{scanf} + function. By default it is defined to TARGET_EXTRA_PRINTF_FLAG_CHARS. + @end defmac + + @defmac TARGET_EXTRA_PRINTF_LENGTH_SPECIFIERS + If defined, this macro lists the const format_length_info structures specifying + additional format length specifiers that the target's C runtime @code{printf} + function accepts as extensions to the ISO C standard. + @end defmac + + @defmac TARGET_EXTRA_SCANF_LENGTH_SPECIFIERS + If defined, this macro lists the const format_length_info structures specifying + additional format length specifiers that the target's C runtime @code{scanf} + function accepts as extensions to the ISO C standard. + @end defmac Index: defaults.h =================================================================== *** defaults.h (revision 118370) --- defaults.h (working copy) *************** Software Foundation, 51 Franklin Street, *** 895,898 **** --- 895,909 ---- #define INCOMING_FRAME_SP_OFFSET 0 #endif + /* This should, in the abstract, be the empty string. However, + historically, GCC has accepted GLIBC's "I" flag character on all + systems. */ + #ifndef TARGET_EXTRA_PRINTF_FLAG_CHARS + #define TARGET_EXTRA_PRINTF_FLAG_CHARS "I" + #endif + + #ifndef TARGET_EXTRA_SCANF_FLAG_CHARS + #define TARGET_EXTRA_SCANF_FLAG_CHARS "I" + #endif + #endif /* ! GCC_DEFAULTS_H */ Index: c-format.c =================================================================== *** c-format.c (revision 118370) --- c-format.c (working copy) *************** static const format_length_info printf_l *** 293,298 **** --- 293,301 ---- { "j", FMT_LEN_j, STD_C99, NULL, 0, 0 }, { "H", FMT_LEN_H, STD_EXT, NULL, 0, 0 }, { "D", FMT_LEN_D, STD_EXT, "DD", FMT_LEN_DD, STD_EXT }, + #ifdef TARGET_EXTRA_PRINTF_LENGTH_SPECIFIERS + TARGET_EXTRA_PRINTF_LENGTH_SPECIFIERS, + #endif /* TARGET_EXTRA_PRINTF_LENGTH_SPECIFIERS */ { NULL, 0, 0, NULL, 0, 0 } }; *************** static const format_length_info scanf_le *** 329,334 **** --- 332,340 ---- { "j", FMT_LEN_j, STD_C99, NULL, 0, 0 }, { "H", FMT_LEN_H, STD_EXT, NULL, 0, 0 }, { "D", FMT_LEN_D, STD_EXT, "DD", FMT_LEN_DD, STD_EXT }, + #ifdef TARGET_EXTRA_SCANF_LENGTH_SPECIFIERS + TARGET_EXTRA_SCANF_LENGTH_SPECIFIERS, + #endif /* TARGET_EXTRA_SCANF_LENGTH_SPECIFIERS */ { NULL, 0, 0, NULL, 0, 0 } }; *************** static const format_char_info monetary_c *** 702,708 **** /* This must be in the same order as enum format_type. */ static const format_kind_info format_types_orig[] = { ! { "printf", printf_length_specs, print_char_table, " +#0-'I", NULL, printf_flag_specs, printf_flag_pairs, FMT_FLAG_ARG_CONVERT|FMT_FLAG_DOLLAR_MULTIPLE|FMT_FLAG_USE_DOLLAR|FMT_FL AG_EMPTY_PREC_OK, 'w', 0, 'p', 0, 'L', --- 708,715 ---- /* This must be in the same order as enum format_type. */ static const format_kind_info format_types_orig[] = { ! { "printf", printf_length_specs, print_char_table, ! " +#0-'" TARGET_EXTRA_PRINTF_FLAG_CHARS, NULL, printf_flag_specs, printf_flag_pairs, FMT_FLAG_ARG_CONVERT|FMT_FLAG_DOLLAR_MULTIPLE|FMT_FLAG_USE_DOLLAR|FMT_FL AG_EMPTY_PREC_OK, 'w', 0, 'p', 0, 'L', *************** static const format_kind_info format_typ *** 744,750 **** 0, 0, 0, 0, 0, NULL, NULL }, ! { "scanf", scanf_length_specs, scan_char_table, "*'I", NULL, scanf_flag_specs, scanf_flag_pairs, FMT_FLAG_ARG_CONVERT|FMT_FLAG_SCANF_A_KLUDGE|FMT_FLAG_USE_DOLLAR|FMT_FLA G_ZERO_WIDTH_BAD|FMT_FLAG_DOLLAR_GAP_POINTER_OK, 'w', 0, 0, '*', 'L', --- 751,758 ---- 0, 0, 0, 0, 0, NULL, NULL }, ! { "scanf", scanf_length_specs, scan_char_table, ! "*'" TARGET_EXTRA_SCANF_FLAG_CHARS, NULL, scanf_flag_specs, scanf_flag_pairs, FMT_FLAG_ARG_CONVERT|FMT_FLAG_SCANF_A_KLUDGE|FMT_FLAG_USE_DOLLAR|FMT_FLA G_ZERO_WIDTH_BAD|FMT_FLAG_DOLLAR_GAP_POINTER_OK, 'w', 0, 0, '*', 'L', *************** check_format_info_main (format_check_res *** 1733,1743 **** length_chars_std = STD_C89; if (fli) { ! while (fli->name != 0 && fli->name[0] != *format_chars) fli++; if (fli->name != 0) { ! format_chars++; if (fli->double_name != 0 && fli->name[0] == *format_chars) { format_chars++; --- 1741,1752 ---- length_chars_std = STD_C89; if (fli) { ! while (fli->name != 0 ! && strncmp (fli->name, format_chars, strlen (fli->name))) fli++; if (fli->name != 0) { ! format_chars += strlen (fli->name); if (fli->double_name != 0 && fli->name[0] == *format_chars) { format_chars++; Index: config/i386/mingw32.h =================================================================== *** config/i386/mingw32.h (revision 118371) --- config/i386/mingw32.h (working copy) *************** do { \ *** 116,118 **** --- 116,139 ---- /* mingw32 atexit function is safe to use in shared libraries. Use it to register C++ static destructors. */ #define TARGET_CXX_USE_ATEXIT_FOR_CXA_ATEXIT hook_bool_void_true + + /* MSVCRT does not support the "I" flag provided by GLIBC. */ + #undef TARGET_EXTRA_PRINTF_FLAG_CHARS + #define TARGET_EXTRA_PRINTF_FLAG_CHARS "" + #undef TARGET_EXTRA_SCANF_FLAG_CHARS + #define TARGET_EXTRA_SCANF_FLAG_CHARS "" + + /* MSVCRT supports additional length specifiers for "printf". (In + fact, it does not support some of the C99 specifiers, like + "ll". However, we do not presently have a mechanism for disabling + a specifier). */ + #define TARGET_EXTRA_PRINTF_LENGTH_SPECIFIERS \ + /* 32-bit integer */ \ + { "I32", FMT_LEN_l, STD_EXT, NULL, 0, 0 }, \ + /* 64-bit integer */ \ + { "I64", FMT_LEN_ll, STD_EXT, NULL, 0, 0 }, \ + /* size_t */ \ + { "I", FMT_LEN_z, STD_EXT, NULL, 0, 0 } + + #define TARGET_EXTRA_SCANF_LENGTH_SPECIFIERS \ + TARGET_EXTRA_PRINTF_LENGTH_SPECIFIERS Index: testsuite/gcc.dg/format/ext-1.c =================================================================== *** testsuite/gcc.dg/format/ext-1.c (revision 118370) --- testsuite/gcc.dg/format/ext-1.c (working copy) *************** foo (quad_t q, u_quad_t uq, quad_t *qn, *** 97,102 **** --- 97,106 ---- In GCC, we require this to be in the standard place for flags, though glibc allows it also after width or precision. */ + + /* "I" is used as a format length specifier for size_t in the MS Windows + runtime and should give different "length" warnings. */ + #ifndef __MSVCRT__ printf ("%Id%Ii%Iu", i, i, u); printf ("%Io", u); /* { dg-warning "flag" "bad use of I flag" } */ printf ("%Ix", u); /* { dg-warning "flag" "bad use of I flag" } */ *************** foo (quad_t q, u_quad_t uq, quad_t *qn, *** 116,121 **** --- 120,126 ---- printf ("%IC", lc); /* { dg-warning "flag" "bad use of I flag" } */ printf ("%IS", ls); /* { dg-warning "flag" "bad use of I flag" } */ printf ("%Im"); /* { dg-warning "flag" "bad use of I flag" } */ + #endif /* __MSVCRT__ */ /* As an extension, GCC does format checking on "unlocked" i.e. thread unsafe versions of these functions. */ Index: testsuite/gcc.dg/format/ext-2.c =================================================================== *** testsuite/gcc.dg/format/ext-2.c (revision 118370) --- testsuite/gcc.dg/format/ext-2.c (working copy) *************** foo (quad_t *qp, u_quad_t *uqp, quad_t * *** 51,56 **** --- 51,60 ---- scanf ("%'p", pp); /* { dg-warning "flag" "bad use of ' flag" } */ scanf ("%'C", ls); /* { dg-warning "flag" "bad use of ' flag" } */ scanf ("%'S", ls); /* { dg-warning "flag" "bad use of ' flag" } */ + + /* "I" is used as a format length specifier for size_t in the MS Windows + runtime and should give different "length" warnings. */ + #ifndef __MSVCRT__ scanf ("%Id%Ii%Iu", ip, ip, up); scanf ("%Ia", fp); /* { dg-warning "flag" "bad use of I flag" } */ scanf ("%IA", fp); /* { dg-warning "flag" "bad use of I flag" } */ *************** foo (quad_t *qp, u_quad_t *uqp, quad_t * *** 70,73 **** --- 74,78 ---- scanf ("%Ip", pp); /* { dg-warning "flag" "bad use of I flag" } */ scanf ("%IC", ls); /* { dg-warning "flag" "bad use of I flag" } */ scanf ("%IS", ls); /* { dg-warning "flag" "bad use of I flag" } */ + #endif /* __MSVCRT__ */ } *** /dev/null Mon Nov 6 11:54:34 2006 --- testsuite/gcc.dg/format/ext-7.c Mon Nov 6 11:47:13 2006 *************** *** 0 **** --- 1,13 ---- + /* Test for MSVCRT-specific format extensions */ + /* { dg-do compile { target i?86-*-mingw* } } */ + /* { dg-options "-std=gnu99 -Wformat" } */ + + #include "format.h" + + int foo(long long ll, int i, float f) + { + printf ("%I64d", ll); + printf ("%Id", i); + printf ("%IF", f); /* { dg-warning "length" "bad use of %I" } */ + printf ("%Id", ll); /* { dg-warning "format" "mismatched type" } */ + }
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |