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]

[Patch] "%I64" printf format specifer foor mingw32


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]