c-common.c (format_wanted_type): Add reading_from_flag.
* c-common.c (format_wanted_type): Add reading_from_flag. (print_char_table): Mark %s and %S formats with flag "R". (check_format_info_main): Set up reading_from_flag appropriately. If aflag, always set writing_in_flag rather than relying on the format used being a scanf format and so having it set. (check_format_types): Check for formats reading through null pointers. testsuite: * gcc.dg/c90-printf-1.c: Add test for printf formats reading through a null pointer. From-SVN: r38104
This commit is contained in:
parent
8308e0b786
commit
014e7f1d30
@ -1,3 +1,13 @@
|
||||
2000-12-07 Joseph S. Myers <jsm28@cam.ac.uk>
|
||||
|
||||
* c-common.c (format_wanted_type): Add reading_from_flag.
|
||||
(print_char_table): Mark %s and %S formats with flag "R".
|
||||
(check_format_info_main): Set up reading_from_flag appropriately.
|
||||
If aflag, always set writing_in_flag rather than relying on the
|
||||
format used being a scanf format and so having it set.
|
||||
(check_format_types): Check for formats reading through null
|
||||
pointers.
|
||||
|
||||
2000-12-07 Joseph S. Myers <jsm28@cam.ac.uk>
|
||||
|
||||
* invoke.texi (-Wformat): Document what format features are
|
||||
|
@ -1416,6 +1416,7 @@ typedef struct
|
||||
years in some locales, "4" for "2" which becomes "3" with an "E" modifier,
|
||||
"o" if use of strftime "O" is a GNU extension beyond C99,
|
||||
"W" if the argument is a pointer which is dereferenced and written into,
|
||||
"R" if the argument is a pointer which is dereferenced and read from,
|
||||
"i" for printf integer formats where the '0' flag is ignored with
|
||||
precision, and "[" for the starting character of a scanf scanset. */
|
||||
const char *flags2;
|
||||
@ -1521,6 +1522,9 @@ typedef struct format_wanted_type
|
||||
/* Whether the argument, dereferenced once, is written into and so the
|
||||
argument must not be a pointer to a const-qualified type. */
|
||||
int writing_in_flag;
|
||||
/* Whether the argument, dereferenced once, is read from and so
|
||||
must not be a NULL pointer. */
|
||||
int reading_from_flag;
|
||||
/* If warnings should be of the form "field precision is not type int",
|
||||
the name to use (in this case "field precision"), otherwise NULL,
|
||||
for "%s format, %s arg" type messages. If (in an extension), this
|
||||
@ -1694,23 +1698,23 @@ static const format_flag_pair strftime_flag_pairs[] =
|
||||
static const format_char_info print_char_table[] =
|
||||
{
|
||||
/* C89 conversion specifiers. */
|
||||
{ "di", 0, STD_C89, { T89_I, T99_SC, T89_S, T89_L, T99_LL, TEX_LL, T99_SST, T99_PD, T99_IM }, "-wp0 +'I", "i" },
|
||||
{ "oxX", 0, STD_C89, { T89_UI, T99_UC, T89_US, T89_UL, T99_ULL, TEX_ULL, T99_ST, T99_UPD, T99_UIM }, "-wp0#", "i" },
|
||||
{ "u", 0, STD_C89, { T89_UI, T99_UC, T89_US, T89_UL, T99_ULL, TEX_ULL, T99_ST, T99_UPD, T99_UIM }, "-wp0'I", "i" },
|
||||
{ "fgG", 0, STD_C89, { T89_D, BADLEN, BADLEN, T99_D, BADLEN, T89_LD, BADLEN, BADLEN, BADLEN }, "-wp0 +#'", "" },
|
||||
{ "eE", 0, STD_C89, { T89_D, BADLEN, BADLEN, T99_D, BADLEN, T89_LD, BADLEN, BADLEN, BADLEN }, "-wp0 +#", "" },
|
||||
{ "c", 0, STD_C89, { T89_I, BADLEN, BADLEN, T94_WI, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "" },
|
||||
{ "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "c" },
|
||||
{ "p", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "c" },
|
||||
{ "n", 1, STD_C89, { T89_I, T99_SC, T89_S, T89_L, T99_LL, BADLEN, T99_SST, T99_PD, T99_IM }, "", "W" },
|
||||
{ "di", 0, STD_C89, { T89_I, T99_SC, T89_S, T89_L, T99_LL, TEX_LL, T99_SST, T99_PD, T99_IM }, "-wp0 +'I", "i" },
|
||||
{ "oxX", 0, STD_C89, { T89_UI, T99_UC, T89_US, T89_UL, T99_ULL, TEX_ULL, T99_ST, T99_UPD, T99_UIM }, "-wp0#", "i" },
|
||||
{ "u", 0, STD_C89, { T89_UI, T99_UC, T89_US, T89_UL, T99_ULL, TEX_ULL, T99_ST, T99_UPD, T99_UIM }, "-wp0'I", "i" },
|
||||
{ "fgG", 0, STD_C89, { T89_D, BADLEN, BADLEN, T99_D, BADLEN, T89_LD, BADLEN, BADLEN, BADLEN }, "-wp0 +#'", "" },
|
||||
{ "eE", 0, STD_C89, { T89_D, BADLEN, BADLEN, T99_D, BADLEN, T89_LD, BADLEN, BADLEN, BADLEN }, "-wp0 +#", "" },
|
||||
{ "c", 0, STD_C89, { T89_I, BADLEN, BADLEN, T94_WI, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "" },
|
||||
{ "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "cR" },
|
||||
{ "p", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "c" },
|
||||
{ "n", 1, STD_C89, { T89_I, T99_SC, T89_S, T89_L, T99_LL, BADLEN, T99_SST, T99_PD, T99_IM }, "", "W" },
|
||||
/* C99 conversion specifiers. */
|
||||
{ "F", 0, STD_C99, { T99_D, BADLEN, BADLEN, T99_D, BADLEN, T99_LD, BADLEN, BADLEN, BADLEN }, "-wp0 +#'", "" },
|
||||
{ "aA", 0, STD_C99, { T99_D, BADLEN, BADLEN, T99_D, BADLEN, T99_LD, BADLEN, BADLEN, BADLEN }, "-wp0 +#", "" },
|
||||
{ "F", 0, STD_C99, { T99_D, BADLEN, BADLEN, T99_D, BADLEN, T99_LD, BADLEN, BADLEN, BADLEN }, "-wp0 +#'", "" },
|
||||
{ "aA", 0, STD_C99, { T99_D, BADLEN, BADLEN, T99_D, BADLEN, T99_LD, BADLEN, BADLEN, BADLEN }, "-wp0 +#", "" },
|
||||
/* X/Open conversion specifiers. */
|
||||
{ "C", 0, STD_EXT, { TEX_WI, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "" },
|
||||
{ "S", 1, STD_EXT, { TEX_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "" },
|
||||
{ "C", 0, STD_EXT, { TEX_WI, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "" },
|
||||
{ "S", 1, STD_EXT, { TEX_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "R" },
|
||||
/* GNU conversion specifiers. */
|
||||
{ "m", 0, STD_EXT, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "" },
|
||||
{ "m", 0, STD_EXT, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "" },
|
||||
{ NULL, 0, 0, NOLENGTHS, NULL, NULL }
|
||||
};
|
||||
|
||||
@ -2718,6 +2722,7 @@ check_format_info_main (status, res, info, format_chars, format_length,
|
||||
width_wanted_type.pointer_count = 0;
|
||||
width_wanted_type.char_lenient_flag = 0;
|
||||
width_wanted_type.writing_in_flag = 0;
|
||||
width_wanted_type.reading_from_flag = 0;
|
||||
width_wanted_type.name = _("field width");
|
||||
width_wanted_type.param = cur_param;
|
||||
width_wanted_type.arg_num = arg_num;
|
||||
@ -2803,6 +2808,7 @@ check_format_info_main (status, res, info, format_chars, format_length,
|
||||
precision_wanted_type.pointer_count = 0;
|
||||
precision_wanted_type.char_lenient_flag = 0;
|
||||
precision_wanted_type.writing_in_flag = 0;
|
||||
precision_wanted_type.reading_from_flag = 0;
|
||||
precision_wanted_type.name = _("field precision");
|
||||
precision_wanted_type.param = cur_param;
|
||||
precision_wanted_type.arg_num = arg_num;
|
||||
@ -3129,8 +3135,16 @@ check_format_info_main (status, res, info, format_chars, format_length,
|
||||
if (strchr (fci->flags2, 'c') != 0)
|
||||
main_wanted_type.char_lenient_flag = 1;
|
||||
main_wanted_type.writing_in_flag = 0;
|
||||
if (strchr (fci->flags2, 'W') != 0)
|
||||
main_wanted_type.reading_from_flag = 0;
|
||||
if (aflag)
|
||||
main_wanted_type.writing_in_flag = 1;
|
||||
else
|
||||
{
|
||||
if (strchr (fci->flags2, 'W') != 0)
|
||||
main_wanted_type.writing_in_flag = 1;
|
||||
if (strchr (fci->flags2, 'R') != 0)
|
||||
main_wanted_type.reading_from_flag = 1;
|
||||
}
|
||||
main_wanted_type.name = NULL;
|
||||
main_wanted_type.param = cur_param;
|
||||
main_wanted_type.arg_num = arg_num;
|
||||
@ -3208,6 +3222,15 @@ check_format_types (status, types)
|
||||
"writing through null pointer (arg %d)",
|
||||
arg_num);
|
||||
|
||||
/* Check for reading through a NULL pointer. */
|
||||
if (types->reading_from_flag
|
||||
&& i == 0
|
||||
&& cur_param != 0
|
||||
&& integer_zerop (cur_param))
|
||||
status_warning (status,
|
||||
"reading through null pointer (arg %d)",
|
||||
arg_num);
|
||||
|
||||
if (cur_param != 0 && TREE_CODE (cur_param) == ADDR_EXPR)
|
||||
cur_param = TREE_OPERAND (cur_param, 0);
|
||||
else
|
||||
|
@ -1,3 +1,8 @@
|
||||
2000-12-07 Joseph S. Myers <jsm28@cam.ac.uk>
|
||||
|
||||
* gcc.dg/c90-printf-1.c: Add test for printf formats reading
|
||||
through a null pointer.
|
||||
|
||||
2000-12-06 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
|
||||
|
||||
* g++.old-deja/g++.oliva/partspec1.C: Remove XFAIL.
|
||||
|
@ -245,4 +245,5 @@ foo (int i, int i1, int i2, unsigned int u, double d, char *s, void *p,
|
||||
printf ("%n", cn); /* { dg-warning "constant" "%n with const" } */
|
||||
printf ((const char *)L"foo"); /* { dg-warning "wide" "wide string" } */
|
||||
printf ("%n", (int *)0); /* { dg-warning "null" "%n with NULL" } */
|
||||
printf ("%s", (char *)0); /* { dg-warning "null" "%s with NULL" } */
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user