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>
|
2000-12-07 Joseph S. Myers <jsm28@cam.ac.uk>
|
||||||
|
|
||||||
* invoke.texi (-Wformat): Document what format features are
|
* 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,
|
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,
|
"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,
|
"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
|
"i" for printf integer formats where the '0' flag is ignored with
|
||||||
precision, and "[" for the starting character of a scanf scanset. */
|
precision, and "[" for the starting character of a scanf scanset. */
|
||||||
const char *flags2;
|
const char *flags2;
|
||||||
@ -1521,6 +1522,9 @@ typedef struct format_wanted_type
|
|||||||
/* Whether the argument, dereferenced once, is written into and so the
|
/* Whether the argument, dereferenced once, is written into and so the
|
||||||
argument must not be a pointer to a const-qualified type. */
|
argument must not be a pointer to a const-qualified type. */
|
||||||
int writing_in_flag;
|
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",
|
/* If warnings should be of the form "field precision is not type int",
|
||||||
the name to use (in this case "field precision"), otherwise NULL,
|
the name to use (in this case "field precision"), otherwise NULL,
|
||||||
for "%s format, %s arg" type messages. If (in an extension), this
|
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[] =
|
static const format_char_info print_char_table[] =
|
||||||
{
|
{
|
||||||
/* C89 conversion specifiers. */
|
/* 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" },
|
{ "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" },
|
{ "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" },
|
{ "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 +#'", "" },
|
{ "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 +#", "" },
|
{ "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", "" },
|
{ "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" },
|
{ "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" },
|
{ "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" },
|
{ "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. */
|
/* C99 conversion specifiers. */
|
||||||
{ "F", 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 +#", "" },
|
{ "aA", 0, STD_C99, { T99_D, BADLEN, BADLEN, T99_D, BADLEN, T99_LD, BADLEN, BADLEN, BADLEN }, "-wp0 +#", "" },
|
||||||
/* X/Open conversion specifiers. */
|
/* X/Open conversion specifiers. */
|
||||||
{ "C", 0, STD_EXT, { TEX_WI, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "" },
|
{ "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", "" },
|
{ "S", 1, STD_EXT, { TEX_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "R" },
|
||||||
/* GNU conversion specifiers. */
|
/* 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 }
|
{ 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.pointer_count = 0;
|
||||||
width_wanted_type.char_lenient_flag = 0;
|
width_wanted_type.char_lenient_flag = 0;
|
||||||
width_wanted_type.writing_in_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.name = _("field width");
|
||||||
width_wanted_type.param = cur_param;
|
width_wanted_type.param = cur_param;
|
||||||
width_wanted_type.arg_num = arg_num;
|
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.pointer_count = 0;
|
||||||
precision_wanted_type.char_lenient_flag = 0;
|
precision_wanted_type.char_lenient_flag = 0;
|
||||||
precision_wanted_type.writing_in_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.name = _("field precision");
|
||||||
precision_wanted_type.param = cur_param;
|
precision_wanted_type.param = cur_param;
|
||||||
precision_wanted_type.arg_num = arg_num;
|
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)
|
if (strchr (fci->flags2, 'c') != 0)
|
||||||
main_wanted_type.char_lenient_flag = 1;
|
main_wanted_type.char_lenient_flag = 1;
|
||||||
main_wanted_type.writing_in_flag = 0;
|
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;
|
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.name = NULL;
|
||||||
main_wanted_type.param = cur_param;
|
main_wanted_type.param = cur_param;
|
||||||
main_wanted_type.arg_num = arg_num;
|
main_wanted_type.arg_num = arg_num;
|
||||||
@ -3208,6 +3222,15 @@ check_format_types (status, types)
|
|||||||
"writing through null pointer (arg %d)",
|
"writing through null pointer (arg %d)",
|
||||||
arg_num);
|
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)
|
if (cur_param != 0 && TREE_CODE (cur_param) == ADDR_EXPR)
|
||||||
cur_param = TREE_OPERAND (cur_param, 0);
|
cur_param = TREE_OPERAND (cur_param, 0);
|
||||||
else
|
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>
|
2000-12-06 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
|
||||||
|
|
||||||
* g++.old-deja/g++.oliva/partspec1.C: Remove XFAIL.
|
* 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 ("%n", cn); /* { dg-warning "constant" "%n with const" } */
|
||||||
printf ((const char *)L"foo"); /* { dg-warning "wide" "wide string" } */
|
printf ((const char *)L"foo"); /* { dg-warning "wide" "wide string" } */
|
||||||
printf ("%n", (int *)0); /* { dg-warning "null" "%n with NULL" } */
|
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