From 6794f93d5f1b260f35e9bef4f8ae1e1631667380 Mon Sep 17 00:00:00 2001 From: ktietz Date: Mon, 24 Aug 2009 06:17:33 +0000 Subject: [PATCH] Changelog gcc/ 2009-08-24 Kai Tietz 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 *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 | 17 +++++++ gcc/c-format.c | 78 +++++++++++++++++++------------- gcc/c-format.h | 4 ++ gcc/config/i386/msformat-c.c | 12 ++--- gcc/testsuite/ChangeLog | 7 +++ gcc/testsuite/gcc.dg/format/ms-format1.c | 8 +++- gcc/testsuite/gcc.dg/format/ms-format2.c | 23 ++++++++++ 7 files changed, 111 insertions(+), 38 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/format/ms-format2.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 10333a94ff2..890a3dce37a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,20 @@ +2009-08-24 Kai Tietz + + 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 PR target/40718 diff --git a/gcc/c-format.c b/gcc/c-format.c index 38a4b60a86f..6b14f4026c7 100644 --- a/gcc/c-format.c +++ b/gcc/c-format.c @@ -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, diff --git a/gcc/c-format.h b/gcc/c-format.h index 694d2f219ad..9d01f0af495 100644 --- a/gcc/c-format.h +++ b/gcc/c-format.h @@ -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; diff --git a/gcc/config/i386/msformat-c.c b/gcc/config/i386/msformat-c.c index d7eb42d9c3c..020cdb3c897 100644 --- a/gcc/config/i386/msformat-c.c +++ b/gcc/config/i386/msformat-c.c @@ -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[] = diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 58a563b9cb4..896c6819e57 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2009-08-24 Kai Tietz + + *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 * gfortran.dg/fmt_error_7.f: New test. diff --git a/gcc/testsuite/gcc.dg/format/ms-format1.c b/gcc/testsuite/gcc.dg/format/ms-format1.c index 81c21d911e5..e8f739dce35 100644 --- a/gcc/testsuite/gcc.dg/format/ms-format1.c +++ b/gcc/testsuite/gcc.dg/format/ms-format1.c @@ -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 index 00000000000..5c950522a7c --- /dev/null +++ b/gcc/testsuite/gcc.dg/format/ms-format2.c @@ -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 */ +/* { 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" } */ +} -- 2.11.0