OSDN Git Service

Changelog gcc/
authorktietz <ktietz@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 24 Aug 2009 06:17:33 +0000 (06:17 +0000)
committerktietz <ktietz@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 24 Aug 2009 06:17:33 +0000 (06:17 +0000)
2009-08-24  Kai Tietz  <kai.tietz@onevision.com>

PR/40786
* c-format.c (format_wanted_type):  Add new member scalar_identity_flag.
(check_format_info_main): Use scalar_identify_flag.
(check_format_types): Check for scalar size identity if
scalar_identify_flag is set.
(printf_length_specs): Extend by new field.
(asm_fprintf_length_specs): Likewise.
(gcc_diag_length_specs): Likewise.
(scanf_length_specs): Likewise.
(strfmon_length_specs): Likewise.
(gcc_gfc_length_specs): Likewise.
* config/i386/msformat-c.c (ms_printf_length_specs): Likewise.
(ms_printf_flag_specs): Likewise.
* c-format.h (format_length_info): Add new member scalar_identity_flag.

Changelog gcc/testsuite

2009-08-24  Kai Tietz  <kai.tietz@onevision.com>

*gcc.dg/format/ms-format1.c: Add new cases for I32
width specifier.
*gcc.dg/format/ms-format2.c: New test about illegal
use of I32/I64 width specifier.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@151047 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/c-format.c
gcc/c-format.h
gcc/config/i386/msformat-c.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/format/ms-format1.c
gcc/testsuite/gcc.dg/format/ms-format2.c [new file with mode: 0644]

index 10333a9..890a3dc 100644 (file)
@@ -1,3 +1,20 @@
+2009-08-24  Kai Tietz  <kai.tietz@onevision.com>
+
+       PR/40786
+       * c-format.c (format_wanted_type):  Add new member scalar_identity_flag.
+       (check_format_info_main): Use scalar_identify_flag.
+       (check_format_types): Check for scalar size identity if
+       scalar_identify_flag is set.
+       (printf_length_specs): Extend by new field.
+       (asm_fprintf_length_specs): Likewise.
+       (gcc_diag_length_specs): Likewise.
+       (scanf_length_specs): Likewise.
+       (strfmon_length_specs): Likewise.
+       (gcc_gfc_length_specs): Likewise.
+       * config/i386/msformat-c.c (ms_printf_length_specs): Likewise.
+       (ms_printf_flag_specs): Likewise.
+       * c-format.h (format_length_info): Add new member scalar_identity_flag.
+
 2009-08-23  Uros Bizjak  <ubizjak@gmail.com>
 
        PR target/40718
index 38a4b60..6b14f40 100644 (file)
@@ -259,6 +259,8 @@ typedef struct format_wanted_type
   tree wanted_type;
   /* The name of this type to use in diagnostics.  */
   const char *wanted_type_name;
+  /* Should be type checked just for scalar width identity.  */
+  int scalar_identity_flag;
   /* The level of indirection through pointers at which this type occurs.  */
   int pointer_count;
   /* Whether, when pointer_count is 1, to allow any character type when
@@ -288,33 +290,33 @@ typedef struct format_wanted_type
 
 static const format_length_info printf_length_specs[] =
 {
-  { "h", FMT_LEN_h, STD_C89, "hh", FMT_LEN_hh, STD_C99 },
-  { "l", FMT_LEN_l, STD_C89, "ll", FMT_LEN_ll, STD_C9L },
-  { "q", FMT_LEN_ll, STD_EXT, NO_FMT },
-  { "L", FMT_LEN_L, STD_C89, NO_FMT },
-  { "z", FMT_LEN_z, STD_C99, NO_FMT },
-  { "Z", FMT_LEN_z, STD_EXT, NO_FMT },
-  { "t", FMT_LEN_t, STD_C99, NO_FMT },
-  { "j", FMT_LEN_j, STD_C99, NO_FMT },
-  { "H", FMT_LEN_H, STD_EXT, NO_FMT },
-  { "D", FMT_LEN_D, STD_EXT, "DD", FMT_LEN_DD, STD_EXT },
-  { NO_FMT, NO_FMT }
+  { "h", FMT_LEN_h, STD_C89, "hh", FMT_LEN_hh, STD_C99, 0 },
+  { "l", FMT_LEN_l, STD_C89, "ll", FMT_LEN_ll, STD_C9L, 0 },
+  { "q", FMT_LEN_ll, STD_EXT, NO_FMT, 0 },
+  { "L", FMT_LEN_L, STD_C89, NO_FMT, 0 },
+  { "z", FMT_LEN_z, STD_C99, NO_FMT, 0 },
+  { "Z", FMT_LEN_z, STD_EXT, NO_FMT, 0 },
+  { "t", FMT_LEN_t, STD_C99, NO_FMT, 0 },
+  { "j", FMT_LEN_j, STD_C99, NO_FMT, 0 },
+  { "H", FMT_LEN_H, STD_EXT, NO_FMT, 0 },
+  { "D", FMT_LEN_D, STD_EXT, "DD", FMT_LEN_DD, STD_EXT, 0 },
+  { NO_FMT, NO_FMT, 0 }
 };
 
 /* Length specifiers valid for asm_fprintf.  */
 static const format_length_info asm_fprintf_length_specs[] =
 {
-  { "l", FMT_LEN_l, STD_C89, "ll", FMT_LEN_ll, STD_C89 },
-  { "w", FMT_LEN_none, STD_C89, NO_FMT },
-  { NO_FMT, NO_FMT }
+  { "l", FMT_LEN_l, STD_C89, "ll", FMT_LEN_ll, STD_C89, 0 },
+  { "w", FMT_LEN_none, STD_C89, NO_FMT, 0 },
+  { NO_FMT, NO_FMT, 0 }
 };
 
 /* Length specifiers valid for GCC diagnostics.  */
 static const format_length_info gcc_diag_length_specs[] =
 {
-  { "l", FMT_LEN_l, STD_C89, "ll", FMT_LEN_ll, STD_C89 },
-  { "w", FMT_LEN_none, STD_C89, NO_FMT },
-  { NO_FMT, NO_FMT }
+  { "l", FMT_LEN_l, STD_C89, "ll", FMT_LEN_ll, STD_C89, 0 },
+  { "w", FMT_LEN_none, STD_C89, NO_FMT, 0 },
+  { NO_FMT, NO_FMT, 0 }
 };
 
 /* The custom diagnostics all accept the same length specifiers.  */
@@ -325,16 +327,16 @@ static const format_length_info gcc_diag_length_specs[] =
 /* This differs from printf_length_specs only in that "Z" is not accepted.  */
 static const format_length_info scanf_length_specs[] =
 {
-  { "h", FMT_LEN_h, STD_C89, "hh", FMT_LEN_hh, STD_C99 },
-  { "l", FMT_LEN_l, STD_C89, "ll", FMT_LEN_ll, STD_C9L },
-  { "q", FMT_LEN_ll, STD_EXT, NO_FMT },
-  { "L", FMT_LEN_L, STD_C89, NO_FMT },
-  { "z", FMT_LEN_z, STD_C99, NO_FMT },
-  { "t", FMT_LEN_t, STD_C99, NO_FMT },
-  { "j", FMT_LEN_j, STD_C99, NO_FMT },
-  { "H", FMT_LEN_H, STD_EXT, NO_FMT },
-  { "D", FMT_LEN_D, STD_EXT, "DD", FMT_LEN_DD, STD_EXT },
-  { NO_FMT, NO_FMT }
+  { "h", FMT_LEN_h, STD_C89, "hh", FMT_LEN_hh, STD_C99, 0 },
+  { "l", FMT_LEN_l, STD_C89, "ll", FMT_LEN_ll, STD_C9L, 0 },
+  { "q", FMT_LEN_ll, STD_EXT, NO_FMT, 0 },
+  { "L", FMT_LEN_L, STD_C89, NO_FMT, 0 },
+  { "z", FMT_LEN_z, STD_C99, NO_FMT, 0 },
+  { "t", FMT_LEN_t, STD_C99, NO_FMT, 0 },
+  { "j", FMT_LEN_j, STD_C99, NO_FMT, 0 },
+  { "H", FMT_LEN_H, STD_EXT, NO_FMT, 0 },
+  { "D", FMT_LEN_D, STD_EXT, "DD", FMT_LEN_DD, STD_EXT, 0 },
+  { NO_FMT, NO_FMT, 0 }
 };
 
 
@@ -343,16 +345,16 @@ static const format_length_info scanf_length_specs[] =
 static const format_length_info strfmon_length_specs[] =
 {
   /* A GNU extension.  */
-  { "L", FMT_LEN_L, STD_C89, NO_FMT },
-  { NO_FMT, NO_FMT }
+  { "L", FMT_LEN_L, STD_C89, NO_FMT, 0 },
+  { NO_FMT, NO_FMT, 0 }
 };
 
 
 /* For now, the Fortran front-end routines only use l as length modifier.  */
 static const format_length_info gcc_gfc_length_specs[] =
 {
-  { "l", FMT_LEN_l, STD_C89, NO_FMT },
-  { NO_FMT, NO_FMT }
+  { "l", FMT_LEN_l, STD_C89, NO_FMT, 0 },
+  { NO_FMT, NO_FMT, 0 }
 };
 
 
@@ -1479,6 +1481,7 @@ check_format_info_main (format_check_results *res,
       const format_char_info *fci = NULL;
       char flag_chars[256];
       int alloc_flag = 0;
+      int scalar_identity_flag = 0;
       const char *format_start = format_chars;
       if (*format_chars == 0)
        {
@@ -1612,6 +1615,7 @@ check_format_info_main (format_check_results *res,
                  width_wanted_type.wanted_type_name = NULL;
                  width_wanted_type.pointer_count = 0;
                  width_wanted_type.char_lenient_flag = 0;
+                 width_wanted_type.scalar_identity_flag = 0;
                  width_wanted_type.writing_in_flag = 0;
                  width_wanted_type.reading_from_flag = 0;
                  width_wanted_type.name = _("field width");
@@ -1714,6 +1718,7 @@ check_format_info_main (format_check_results *res,
                  precision_wanted_type.wanted_type_name = NULL;
                  precision_wanted_type.pointer_count = 0;
                  precision_wanted_type.char_lenient_flag = 0;
+                 precision_wanted_type.scalar_identity_flag = 0;
                  precision_wanted_type.writing_in_flag = 0;
                  precision_wanted_type.reading_from_flag = 0;
                  precision_wanted_type.name = _("field precision");
@@ -1767,6 +1772,7 @@ check_format_info_main (format_check_results *res,
       length_chars = NULL;
       length_chars_val = FMT_LEN_none;
       length_chars_std = STD_C89;
+      scalar_identity_flag = 0;
       if (fli)
        {
          while (fli->name != 0 
@@ -1787,6 +1793,7 @@ check_format_info_main (format_check_results *res,
                  length_chars = fli->name;
                  length_chars_val = fli->index;
                  length_chars_std = fli->std;
+                 scalar_identity_flag = fli->scalar_identity_flag;
                }
              i = strlen (flag_chars);
              flag_chars[i++] = fki->length_code_char;
@@ -2075,6 +2082,9 @@ check_format_info_main (format_check_results *res,
              wanted_type_ptr->char_lenient_flag = 0;
              if (strchr (fci->flags2, 'c') != 0)
                wanted_type_ptr->char_lenient_flag = 1;
+             wanted_type_ptr->scalar_identity_flag = 0;
+             if (scalar_identity_flag)
+               wanted_type_ptr->scalar_identity_flag = 1;
              wanted_type_ptr->writing_in_flag = 0;
              wanted_type_ptr->reading_from_flag = 0;
              if (alloc_flag)
@@ -2259,6 +2269,12 @@ check_format_types (format_wanted_type *types, const char *format_start,
          && (!pedantic || i < 2)
          && char_type_flag)
        continue;
+      if (types->scalar_identity_flag
+         && (TREE_CODE (cur_type) == TREE_CODE (wanted_type)
+             || (INTEGRAL_TYPE_P (cur_type)
+                 && INTEGRAL_TYPE_P (wanted_type)))
+         && TYPE_PRECISION (cur_type) == TYPE_PRECISION (wanted_type))
+       continue;
       /* Now we have a type mismatch.  */
       format_type_warning (types->name, format_start, format_length,
                           wanted_type, types->pointer_count,
index 694d2f2..9d01f0a 100644 (file)
@@ -96,6 +96,10 @@ typedef struct
   const char *double_name;
   enum format_lengths double_index;
   enum format_std_version double_std;
+
+  /* If this flag is set, just scalar width identity is checked, and
+     not the type identity itself.  */
+  int scalar_identity_flag;
 } format_length_info;
 
 
index d7eb42d..020cdb3 100644 (file)
@@ -36,12 +36,12 @@ along with GCC; see the file COPYING3.  If not see
 
 static format_length_info ms_printf_length_specs[] =
 {
-  { "h", FMT_LEN_h, STD_C89, NULL, FMT_LEN_none, STD_C89 },
-  { "l", FMT_LEN_l, STD_C89, NULL, FMT_LEN_none, STD_C89 },
-  { "I32", FMT_LEN_l, STD_EXT, NULL, FMT_LEN_none, STD_C89 },
-  { "I64", FMT_LEN_ll, STD_EXT, NULL, FMT_LEN_none, STD_C89 },
-  { "I", FMT_LEN_L, STD_EXT, NULL, FMT_LEN_none, STD_C89 },
-  { NULL, FMT_LEN_none, STD_C89, NULL, FMT_LEN_none, STD_C89 }
+  { "h", FMT_LEN_h, STD_C89, NULL, FMT_LEN_none, STD_C89, 0 },
+  { "l", FMT_LEN_l, STD_C89, NULL, FMT_LEN_none, STD_C89, 0 },
+  { "I32", FMT_LEN_l, STD_EXT, NULL, FMT_LEN_none, STD_C89, 1 },
+  { "I64", FMT_LEN_ll, STD_EXT, NULL, FMT_LEN_none, STD_C89, 1 },
+  { "I", FMT_LEN_L, STD_EXT, NULL, FMT_LEN_none, STD_C89, 0 },
+  { NULL, FMT_LEN_none, STD_C89, NULL, FMT_LEN_none, STD_C89, 0 }
 };
 
 static const format_flag_spec ms_printf_flag_specs[] =
index 58a563b..896c681 100644 (file)
@@ -1,3 +1,10 @@
+2009-08-24  Kai Tietz  <kai.tietz@onevision.com>
+
+       *gcc.dg/format/ms-format1.c: Add new cases for I32
+       width specifier.
+       *gcc.dg/format/ms-format2.c: New test about illegal
+       use of I32/I64 width specifier.
+
 2009-08-23  Jerry DeLisle   <jvdelisle@gcc.gnu.org>
 
        * gfortran.dg/fmt_error_7.f: New test.
index 81c21d9..e8f739d 100644 (file)
@@ -8,10 +8,16 @@
 #define USE_SYSTEM_FORMATS
 #include "format.h"
 
+enum en1 { A=0, B=1 };
+typedef enum { _A=0, _B=1 } en2;
+
 void
-foo (int i, long long ll, size_t z)
+foo (int i, long l, long long ll, size_t z, enum en1 e1, en2 e2)
 {
   printf ("%I32d", i);
+  printf ("%I32d", l);
+  printf ("%I32d", e1);
+  printf ("%I32d", e2);
   printf ("%I64x", ll);
   printf ("%Ix", z);
 }
diff --git a/gcc/testsuite/gcc.dg/format/ms-format2.c b/gcc/testsuite/gcc.dg/format/ms-format2.c
new file mode 100644 (file)
index 0000000..5c95052
--- /dev/null
@@ -0,0 +1,23 @@
+/* Test for printf formats.  Formats using extensions to the standard
+   should be rejected in strict pedantic mode. But allowed by -Wno-pedantic-ms-format.
+*/
+/* Origin: Kai Tietz <kai.tietz@onevision.com> */
+/* { dg-do compile { target { *-*-mingw* } } } */
+/* { dg-options "-std=iso9899:1999 -pedantic -Wformat -Wno-pedantic-ms-format" } */
+
+#define USE_SYSTEM_FORMATS
+#include "format.h"
+
+#ifdef _WIN64
+#define XXX "%I64x"
+#else
+#define XXX "%I32x"
+#endif
+
+void
+foo (float f, double d, void *p)
+{
+  printf (XXX, p); /* { dg-warning "format" "bad argument types" } */
+  printf ("%I32x", f); /* { dg-warning "format" "bad argument types" } */
+  printf ("%I64x", d); /* { dg-warning "format" "bad argument types" } */
+}