c-common.c (warn_format, [...]): Define.
* c-common.c (warn_format, warn_format_y2k, warn_format_extra_args, warn_format_nonliteral): Define. (check_format_info): Check warn_format_nonliteral and warn_format_extra_args. (check_format_info_main): Check warn_format_y2k. (set_Wformat): New function. * c-common.h (warn_format_y2k, warn_format_extra_args, warn_format_nonliteral, set_Wformat): Declare. * c-decl.c (warn_format): Remove definition. (c_decode_option): Handle -Wformat-nonliteral, -Wno-format-extra-args and -Wno-format-y2k, and negated versions. Use set_Wformat. * invoke.texi: Document these new options and -Wformat=2. * toplev.c (documented_lang_options): Add these new options. cp: * decl2.c (warn_format): Remove definition. (lang_decode_option): Handle -Wformat-nonliteral, -Wno-format-extra-args and -Wno-format-y2k. Use set_Wformat. testsuite: * gcc.dg/format-no-exargs-1.c, gcc.dg/format-no-y2k-1.c, gcc.dg/format-nonlit-1.c, gcc.dg/format-nonlit-2.c: New tests. From-SVN: r37933
This commit is contained in:
parent
e78f4a977a
commit
4d80892796
|
@ -1,3 +1,20 @@
|
|||
2000-12-01 Joseph S. Myers <jsm28@cam.ac.uk>
|
||||
|
||||
* c-common.c (warn_format, warn_format_y2k,
|
||||
warn_format_extra_args, warn_format_nonliteral): Define.
|
||||
(check_format_info): Check warn_format_nonliteral and
|
||||
warn_format_extra_args.
|
||||
(check_format_info_main): Check warn_format_y2k.
|
||||
(set_Wformat): New function.
|
||||
* c-common.h (warn_format_y2k, warn_format_extra_args,
|
||||
warn_format_nonliteral, set_Wformat): Declare.
|
||||
* c-decl.c (warn_format): Remove definition.
|
||||
(c_decode_option): Handle -Wformat-nonliteral,
|
||||
-Wno-format-extra-args and -Wno-format-y2k, and negated versions.
|
||||
Use set_Wformat.
|
||||
* invoke.texi: Document these new options and -Wformat=2.
|
||||
* toplev.c (documented_lang_options): Add these new options.
|
||||
|
||||
2000-12-01 Joseph S. Myers <jsm28@cam.ac.uk>
|
||||
|
||||
* builtins.def (BUILT_IN_IMAXABS): Add.
|
||||
|
|
|
@ -173,6 +173,22 @@ int flag_no_nonansi_builtin;
|
|||
|
||||
const char *flag_dump_translation_unit;
|
||||
|
||||
/* Warn about *printf or *scanf format/argument anomalies. */
|
||||
|
||||
int warn_format;
|
||||
|
||||
/* Warn about Y2K problems with strftime formats. */
|
||||
|
||||
int warn_format_y2k;
|
||||
|
||||
/* Warn about excess arguments to formats. */
|
||||
|
||||
int warn_format_extra_args;
|
||||
|
||||
/* Warn about non-literal format arguments. */
|
||||
|
||||
int warn_format_nonliteral;
|
||||
|
||||
/* Nonzero means warn about possible violations of sequence point rules. */
|
||||
|
||||
int warn_sequence_point;
|
||||
|
@ -2321,7 +2337,7 @@ check_format_info (status, info, params)
|
|||
/* Functions taking a va_list normally pass a non-literal format
|
||||
string. These functions typically are declared with
|
||||
first_arg_num == 0, so avoid warning in those cases. */
|
||||
if (info->first_arg_num != 0 && warn_format > 1)
|
||||
if (info->first_arg_num != 0 && warn_format_nonliteral)
|
||||
status_warning (status, "format not a string literal, argument types not checked");
|
||||
}
|
||||
|
||||
|
@ -2333,10 +2349,10 @@ check_format_info (status, info, params)
|
|||
If the format is an empty string, this should be counted similarly to the
|
||||
case of extra format arguments. */
|
||||
if (res.number_extra_args > 0 && res.number_non_literal == 0
|
||||
&& res.number_other == 0)
|
||||
&& res.number_other == 0 && warn_format_extra_args)
|
||||
status_warning (status, "too many arguments for format");
|
||||
if (res.number_dollar_extra_args > 0 && res.number_non_literal == 0
|
||||
&& res.number_other == 0)
|
||||
&& res.number_other == 0 && warn_format_extra_args)
|
||||
status_warning (status, "unused arguments in $-style format");
|
||||
if (res.number_empty > 0 && res.number_non_literal == 0
|
||||
&& res.number_other == 0)
|
||||
|
@ -2991,23 +3007,24 @@ check_format_info_main (status, res, info, format_chars, format_length,
|
|||
}
|
||||
|
||||
/* Give Y2K warnings. */
|
||||
{
|
||||
int y2k_level = 0;
|
||||
if (strchr (fci->flags2, '4') != 0)
|
||||
if (strchr (flag_chars, 'E') != 0)
|
||||
if (warn_format_y2k)
|
||||
{
|
||||
int y2k_level = 0;
|
||||
if (strchr (fci->flags2, '4') != 0)
|
||||
if (strchr (flag_chars, 'E') != 0)
|
||||
y2k_level = 3;
|
||||
else
|
||||
y2k_level = 2;
|
||||
else if (strchr (fci->flags2, '3') != 0)
|
||||
y2k_level = 3;
|
||||
else
|
||||
else if (strchr (fci->flags2, '2') != 0)
|
||||
y2k_level = 2;
|
||||
else if (strchr (fci->flags2, '3') != 0)
|
||||
y2k_level = 3;
|
||||
else if (strchr (fci->flags2, '2') != 0)
|
||||
y2k_level = 2;
|
||||
if (y2k_level == 3)
|
||||
status_warning (status, "`%%%c' yields only last 2 digits of year in some locales",
|
||||
format_char);
|
||||
else if (y2k_level == 2)
|
||||
status_warning (status, "`%%%c' yields only last 2 digits of year", format_char);
|
||||
}
|
||||
if (y2k_level == 3)
|
||||
status_warning (status, "`%%%c' yields only last 2 digits of year in some locales",
|
||||
format_char);
|
||||
else if (y2k_level == 2)
|
||||
status_warning (status, "`%%%c' yields only last 2 digits of year", format_char);
|
||||
}
|
||||
|
||||
if (strchr (fci->flags2, '[') != 0)
|
||||
{
|
||||
|
@ -3325,6 +3342,19 @@ check_format_types (status, types)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Set format warning options according to a -Wformat=n option. */
|
||||
|
||||
void
|
||||
set_Wformat (setting)
|
||||
int setting;
|
||||
{
|
||||
warn_format = setting;
|
||||
warn_format_y2k = setting;
|
||||
warn_format_extra_args = setting;
|
||||
if (setting != 1)
|
||||
warn_format_nonliteral = setting;
|
||||
}
|
||||
|
||||
/* Print a warning if a constant expression had overflow in folding.
|
||||
Invoke this function on every expression that the language
|
||||
|
|
|
@ -349,6 +349,18 @@ extern int flag_const_strings;
|
|||
|
||||
extern int warn_format;
|
||||
|
||||
/* Warn about Y2K problems with strftime formats. */
|
||||
|
||||
extern int warn_format_y2k;
|
||||
|
||||
/* Warn about excess arguments to formats. */
|
||||
|
||||
extern int warn_format_extra_args;
|
||||
|
||||
/* Warn about non-literal format arguments. */
|
||||
|
||||
extern int warn_format_nonliteral;
|
||||
|
||||
/* Warn about possible violations of sequence point rules. */
|
||||
|
||||
extern int warn_sequence_point;
|
||||
|
@ -441,6 +453,7 @@ extern void declare_function_name PARAMS ((void));
|
|||
extern void decl_attributes PARAMS ((tree, tree, tree));
|
||||
extern void init_function_format_info PARAMS ((void));
|
||||
extern void check_function_format PARAMS ((int *, tree, tree, tree));
|
||||
extern void set_Wformat PARAMS ((int));
|
||||
extern void c_apply_type_quals_to_decl PARAMS ((int, tree));
|
||||
/* Print an error message for invalid operands to arith operation CODE.
|
||||
NOP_EXPR is used as a special case (see truthvalue_conversion). */
|
||||
|
|
24
gcc/c-decl.c
24
gcc/c-decl.c
|
@ -421,10 +421,6 @@ int warn_redundant_decls = 0;
|
|||
|
||||
int warn_nested_externs = 0;
|
||||
|
||||
/* Warn about *printf or *scanf format/argument anomalies. */
|
||||
|
||||
int warn_format;
|
||||
|
||||
/* Warn about a subscript that has type char. */
|
||||
|
||||
int warn_char_subscripts = 0;
|
||||
|
@ -710,11 +706,23 @@ c_decode_option (argc, argv)
|
|||
else if (!strcmp (p, "-Wno-traditional"))
|
||||
warn_traditional = 0;
|
||||
else if (!strncmp (p, "-Wformat=", 9))
|
||||
warn_format = atol (p + 9);
|
||||
set_Wformat (atoi (p + 9));
|
||||
else if (!strcmp (p, "-Wformat"))
|
||||
warn_format = 1;
|
||||
set_Wformat (1);
|
||||
else if (!strcmp (p, "-Wno-format"))
|
||||
warn_format = 0;
|
||||
set_Wformat (0);
|
||||
else if (!strcmp (p, "-Wformat-y2k"))
|
||||
warn_format_y2k = 1;
|
||||
else if (!strcmp (p, "-Wno-format-y2k"))
|
||||
warn_format_y2k = 0;
|
||||
else if (!strcmp (p, "-Wformat-extra-args"))
|
||||
warn_format_extra_args = 1;
|
||||
else if (!strcmp (p, "-Wno-format-extra-args"))
|
||||
warn_format_extra_args = 0;
|
||||
else if (!strcmp (p, "-Wformat-nonliteral"))
|
||||
warn_format_nonliteral = 1;
|
||||
else if (!strcmp (p, "-Wno-format-nonliteral"))
|
||||
warn_format_nonliteral = 0;
|
||||
else if (!strcmp (p, "-Wchar-subscripts"))
|
||||
warn_char_subscripts = 1;
|
||||
else if (!strcmp (p, "-Wno-char-subscripts"))
|
||||
|
@ -793,7 +801,7 @@ c_decode_option (argc, argv)
|
|||
warn_return_type = 1;
|
||||
set_Wunused (1);
|
||||
warn_switch = 1;
|
||||
warn_format = 1;
|
||||
set_Wformat (1);
|
||||
warn_char_subscripts = 1;
|
||||
warn_parentheses = 1;
|
||||
warn_sequence_point = 1;
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
2000-12-01 Joseph S. Myers <jsm28@cam.ac.uk>
|
||||
|
||||
* decl2.c (warn_format): Remove definition.
|
||||
(lang_decode_option): Handle -Wformat-nonliteral,
|
||||
-Wno-format-extra-args and -Wno-format-y2k. Use set_Wformat.
|
||||
|
||||
2000-12-01 Joseph S. Myers <jsm28@cam.ac.uk>
|
||||
|
||||
* decl.c (WINT_TYPE, INTMAX_TYPE, UINTMAX_TYPE): Don't define.
|
||||
|
|
|
@ -269,10 +269,6 @@ int warn_sign_compare;
|
|||
|
||||
int warn_float_equal = 0;
|
||||
|
||||
/* Warn about *printf or *scanf format/argument anomalies. */
|
||||
|
||||
int warn_format;
|
||||
|
||||
/* Warn about functions which might be candidates for format attributes. */
|
||||
|
||||
int warn_missing_format_attribute;
|
||||
|
@ -723,7 +719,13 @@ lang_decode_option (argc, argv)
|
|||
else if (!strcmp (p, "float-equal"))
|
||||
warn_float_equal = setting;
|
||||
else if (!strcmp (p, "format"))
|
||||
warn_format = setting;
|
||||
set_Wformat (setting);
|
||||
else if (!strcmp (p, "format-y2k"))
|
||||
warn_format_y2k = setting;
|
||||
else if (!strcmp (p, "format-extra-args"))
|
||||
warn_format_extra_args = setting;
|
||||
else if (!strcmp (p, "format-nonliteral"))
|
||||
warn_format_nonliteral = setting;
|
||||
else if (!strcmp (p, "missing-format-attribute"))
|
||||
warn_missing_format_attribute = setting;
|
||||
else if (!strcmp (p, "conversion"))
|
||||
|
@ -772,7 +774,7 @@ lang_decode_option (argc, argv)
|
|||
set_Wunused (setting);
|
||||
warn_implicit = setting;
|
||||
warn_switch = setting;
|
||||
warn_format = setting;
|
||||
set_Wformat (setting);
|
||||
warn_parentheses = setting;
|
||||
warn_missing_braces = setting;
|
||||
warn_sign_compare = setting;
|
||||
|
|
|
@ -143,7 +143,8 @@ in the following sections.
|
|||
-w -W -Wall -Waggregate-return
|
||||
-Wcast-align -Wcast-qual -Wchar-subscripts -Wcomment
|
||||
-Wconversion -Wdisabled-optimization -Werror
|
||||
-Wfloat-equal -Wformat
|
||||
-Wfloat-equal -Wformat -Wformat=2
|
||||
-Wformat-nonliteral
|
||||
-Wid-clash-@var{len} -Wimplicit -Wimplicit-int
|
||||
-Wimplicit-function-declaration
|
||||
-Werror-implicit-function-declaration
|
||||
|
@ -151,7 +152,8 @@ in the following sections.
|
|||
-Wlarger-than-@var{len} -Wlong-long
|
||||
-Wmain -Wmissing-declarations
|
||||
-Wmissing-format-attribute -Wmissing-noreturn
|
||||
-Wmultichar -Wno-import -Wpacked -Wpadded
|
||||
-Wmultichar -Wno-format-extra-args -Wno-format-y2k
|
||||
-Wno-import -Wpacked -Wpadded
|
||||
-Wparentheses -Wpointer-arith -Wredundant-decls
|
||||
-Wreturn-type -Wsequence-point -Wshadow
|
||||
-Wsign-compare -Wswitch -Wsystem-headers
|
||||
|
@ -1548,6 +1550,30 @@ Check calls to @code{printf} and @code{scanf}, etc., to make sure that
|
|||
the arguments supplied have types appropriate to the format string
|
||||
specified.
|
||||
|
||||
@samp{-Wformat} is included in @samp{-Wall}. For more control over some
|
||||
aspects of format checking, the options @samp{-Wno-format-y2k},
|
||||
@samp{-Wno-format-extra-args}, @samp{-Wformat-nonliteral} and
|
||||
@samp{-Wformat=2} are available, but are not included in @samp{-Wall}.
|
||||
|
||||
@item -Wno-format-y2k
|
||||
If @samp{-Wformat} is specified, do not warn about @code{strftime}
|
||||
formats which may yield only a two-digit year.
|
||||
|
||||
@item -Wno-format-extra-args
|
||||
If @samp{-Wformat} is specified, do not warn about excess arguments to a
|
||||
@code{printf} or @code{scanf} format function. The C standard specifies
|
||||
that such arguments are ignored.
|
||||
|
||||
@item -Wformat-nonliteral
|
||||
If @samp{-Wformat} is specified, also warn if the format string is not a
|
||||
string literal and so cannot be checked, unless the format function
|
||||
takes its format arguments as a @code{va_list}.
|
||||
|
||||
@item -Wformat=2
|
||||
Enable @samp{-Wformat} plus format checks not included in
|
||||
@samp{-Wformat}. Currently equivalent to @samp{-Wformat
|
||||
-Wformat-nonliteral}.
|
||||
|
||||
@item -Wimplicit-int
|
||||
Warn when a declaration does not specify a type.
|
||||
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2000-12-01 Joseph S. Myers <jsm28@cam.ac.uk>
|
||||
|
||||
* gcc.dg/format-no-exargs-1.c, gcc.dg/format-no-y2k-1.c,
|
||||
gcc.dg/format-nonlit-1.c, gcc.dg/format-nonlit-2.c: New tests.
|
||||
|
||||
2000-12-01 Neil Booth <neilb@earthling.net>
|
||||
|
||||
* gcc.dg/cpp/20000720-1.S: Remove duplicate testcase.
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
/* Test for warnings for extra format arguments being disabled by
|
||||
-Wno-format-extra-args. */
|
||||
/* Origin: Joseph Myers <jsm28@cam.ac.uk> */
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-std=gnu99 -Wformat -Wno-format-extra-args" } */
|
||||
|
||||
extern int printf (const char *, ...);
|
||||
|
||||
void
|
||||
foo (int i)
|
||||
{
|
||||
printf ("foo", i);
|
||||
printf ("%1$d", i, i);
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
/* Test for warnings for Y2K problems being disabled by -Wno-format-y2k. */
|
||||
/* Origin: Joseph Myers <jsm28@cam.ac.uk> */
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-std=gnu99 -Wformat -Wno-format-y2k" } */
|
||||
|
||||
typedef __SIZE_TYPE__ size_t;
|
||||
|
||||
struct tm;
|
||||
|
||||
extern size_t strftime (char *, size_t, const char *, const struct tm *);
|
||||
|
||||
void
|
||||
foo (char *s, size_t m, const struct tm *tp)
|
||||
{
|
||||
strftime (s, m, "%y%c%x", tp);
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
/* Test for warnings for non-string-literal formats. */
|
||||
/* Origin: Joseph Myers <jsm28@cam.ac.uk> */
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-std=gnu99 -Wformat -Wformat-nonliteral" } */
|
||||
|
||||
extern int printf (const char *, ...);
|
||||
|
||||
void
|
||||
foo (char *s, int i)
|
||||
{
|
||||
printf ((const char *)i, i); /* { dg-warning "argument types" "non-literal" } */
|
||||
printf (s, i); /* { dg-warning "argument types" "non-literal" } */
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
/* Test for warnings for non-string-literal formats. Test with -Wformat=2. */
|
||||
/* Origin: Joseph Myers <jsm28@cam.ac.uk> */
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-std=gnu99 -Wformat=2" } */
|
||||
|
||||
extern int printf (const char *, ...);
|
||||
|
||||
void
|
||||
foo (char *s, int i)
|
||||
{
|
||||
printf ((const char *)i, i); /* { dg-warning "argument types" "non-literal" } */
|
||||
printf (s, i); /* { dg-warning "argument types" "non-literal" } */
|
||||
}
|
10
gcc/toplev.c
10
gcc/toplev.c
|
@ -1226,8 +1226,16 @@ documented_lang_options[] =
|
|||
{ "-Wno-comments", "" },
|
||||
{ "-Wconversion", "Warn about possibly confusing type conversions" },
|
||||
{ "-Wno-conversion", "" },
|
||||
{ "-Wformat", "Warn about printf format anomalies" },
|
||||
{ "-Wformat", "Warn about printf/scanf/strftime format anomalies" },
|
||||
{ "-Wno-format", "" },
|
||||
{ "-Wformat-y2k", "" },
|
||||
{ "-Wno-format-y2k",
|
||||
"Don't warn about strftime formats yielding 2 digit years" },
|
||||
{ "-Wformat-extra-args", "" },
|
||||
{ "-Wno-format-extra-args",
|
||||
"Don't warn about too many arguments to format functions" },
|
||||
{ "-Wformat-nonliteral", "Warn about non-string-literal format strings" },
|
||||
{ "-Wno-format-nonliteral", "" },
|
||||
{ "-Wimplicit-function-declaration",
|
||||
"Warn about implicit function declarations" },
|
||||
{ "-Wno-implicit-function-declaration", "" },
|
||||
|
|
Loading…
Reference in New Issue