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:
Joseph Myers 2000-12-01 22:43:33 +00:00 committed by Joseph Myers
parent e78f4a977a
commit 4d80892796
13 changed files with 206 additions and 35 deletions

View File

@ -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.

View File

@ -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

View File

@ -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). */

View File

@ -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;

View File

@ -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.

View File

@ -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;

View File

@ -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.

View File

@ -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.

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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" } */
}

View File

@ -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" } */
}

View File

@ -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", "" },