aboutsummaryrefslogtreecommitdiff
path: root/gcc/c-format.c
diff options
context:
space:
mode:
authorKai Tietz <kai.tietz@onevision.com>2009-08-24 06:17:33 +0000
committerKai Tietz <ktietz@gcc.gnu.org>2009-08-24 08:17:33 +0200
commitb241b4757b4d31f85be90cbcd205ec92e21ee864 (patch)
treeced1677b66ea165e76b0af2c3bc13b58584e74b9 /gcc/c-format.c
parente523d8bcf768ba210681f90cc2983f03f1b4d983 (diff)
downloadgcc-b241b4757b4d31f85be90cbcd205ec92e21ee864.zip
gcc-b241b4757b4d31f85be90cbcd205ec92e21ee864.tar.gz
gcc-b241b4757b4d31f85be90cbcd205ec92e21ee864.tar.bz2
Changelog gcc/
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. From-SVN: r151047
Diffstat (limited to 'gcc/c-format.c')
-rw-r--r--gcc/c-format.c78
1 files changed, 47 insertions, 31 deletions
diff --git a/gcc/c-format.c b/gcc/c-format.c
index 38a4b60..6b14f40 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,