Commit 4d808927 by Joseph Myers Committed by Joseph Myers

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
parent e78f4a97
2000-12-01 Joseph S. Myers <jsm28@cam.ac.uk> 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. * builtins.def (BUILT_IN_IMAXABS): Add.
* builtins.c (expand_builtin): Also abort on BUILT_IN_IMAXABS. * builtins.c (expand_builtin): Also abort on BUILT_IN_IMAXABS.
* c-common.c (c_common_nodes_and_builtins): Create builtin * c-common.c (c_common_nodes_and_builtins): Create builtin
......
...@@ -173,6 +173,22 @@ int flag_no_nonansi_builtin; ...@@ -173,6 +173,22 @@ int flag_no_nonansi_builtin;
const char *flag_dump_translation_unit; 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. */ /* Nonzero means warn about possible violations of sequence point rules. */
int warn_sequence_point; int warn_sequence_point;
...@@ -2321,7 +2337,7 @@ check_format_info (status, info, params) ...@@ -2321,7 +2337,7 @@ check_format_info (status, info, params)
/* Functions taking a va_list normally pass a non-literal format /* Functions taking a va_list normally pass a non-literal format
string. These functions typically are declared with string. These functions typically are declared with
first_arg_num == 0, so avoid warning in those cases. */ 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"); status_warning (status, "format not a string literal, argument types not checked");
} }
...@@ -2333,10 +2349,10 @@ check_format_info (status, info, params) ...@@ -2333,10 +2349,10 @@ check_format_info (status, info, params)
If the format is an empty string, this should be counted similarly to the If the format is an empty string, this should be counted similarly to the
case of extra format arguments. */ case of extra format arguments. */
if (res.number_extra_args > 0 && res.number_non_literal == 0 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"); status_warning (status, "too many arguments for format");
if (res.number_dollar_extra_args > 0 && res.number_non_literal == 0 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"); status_warning (status, "unused arguments in $-style format");
if (res.number_empty > 0 && res.number_non_literal == 0 if (res.number_empty > 0 && res.number_non_literal == 0
&& res.number_other == 0) && res.number_other == 0)
...@@ -2991,23 +3007,24 @@ check_format_info_main (status, res, info, format_chars, format_length, ...@@ -2991,23 +3007,24 @@ check_format_info_main (status, res, info, format_chars, format_length,
} }
/* Give Y2K warnings. */ /* Give Y2K warnings. */
{ if (warn_format_y2k)
int y2k_level = 0; {
if (strchr (fci->flags2, '4') != 0) int y2k_level = 0;
if (strchr (flag_chars, 'E') != 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; y2k_level = 3;
else else if (strchr (fci->flags2, '2') != 0)
y2k_level = 2; y2k_level = 2;
else if (strchr (fci->flags2, '3') != 0) if (y2k_level == 3)
y2k_level = 3; status_warning (status, "`%%%c' yields only last 2 digits of year in some locales",
else if (strchr (fci->flags2, '2') != 0) format_char);
y2k_level = 2; else if (y2k_level == 2)
if (y2k_level == 3) status_warning (status, "`%%%c' yields only last 2 digits of year", format_char);
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) if (strchr (fci->flags2, '[') != 0)
{ {
...@@ -3325,6 +3342,19 @@ check_format_types (status, types) ...@@ -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. /* Print a warning if a constant expression had overflow in folding.
Invoke this function on every expression that the language Invoke this function on every expression that the language
......
...@@ -349,6 +349,18 @@ extern int flag_const_strings; ...@@ -349,6 +349,18 @@ extern int flag_const_strings;
extern int warn_format; 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. */ /* Warn about possible violations of sequence point rules. */
extern int warn_sequence_point; extern int warn_sequence_point;
...@@ -441,6 +453,7 @@ extern void declare_function_name PARAMS ((void)); ...@@ -441,6 +453,7 @@ extern void declare_function_name PARAMS ((void));
extern void decl_attributes PARAMS ((tree, tree, tree)); extern void decl_attributes PARAMS ((tree, tree, tree));
extern void init_function_format_info PARAMS ((void)); extern void init_function_format_info PARAMS ((void));
extern void check_function_format PARAMS ((int *, tree, tree, tree)); 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)); extern void c_apply_type_quals_to_decl PARAMS ((int, tree));
/* Print an error message for invalid operands to arith operation CODE. /* Print an error message for invalid operands to arith operation CODE.
NOP_EXPR is used as a special case (see truthvalue_conversion). */ NOP_EXPR is used as a special case (see truthvalue_conversion). */
......
...@@ -421,10 +421,6 @@ int warn_redundant_decls = 0; ...@@ -421,10 +421,6 @@ int warn_redundant_decls = 0;
int warn_nested_externs = 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. */ /* Warn about a subscript that has type char. */
int warn_char_subscripts = 0; int warn_char_subscripts = 0;
...@@ -710,11 +706,23 @@ c_decode_option (argc, argv) ...@@ -710,11 +706,23 @@ c_decode_option (argc, argv)
else if (!strcmp (p, "-Wno-traditional")) else if (!strcmp (p, "-Wno-traditional"))
warn_traditional = 0; warn_traditional = 0;
else if (!strncmp (p, "-Wformat=", 9)) else if (!strncmp (p, "-Wformat=", 9))
warn_format = atol (p + 9); set_Wformat (atoi (p + 9));
else if (!strcmp (p, "-Wformat")) else if (!strcmp (p, "-Wformat"))
warn_format = 1; set_Wformat (1);
else if (!strcmp (p, "-Wno-format")) 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")) else if (!strcmp (p, "-Wchar-subscripts"))
warn_char_subscripts = 1; warn_char_subscripts = 1;
else if (!strcmp (p, "-Wno-char-subscripts")) else if (!strcmp (p, "-Wno-char-subscripts"))
...@@ -793,7 +801,7 @@ c_decode_option (argc, argv) ...@@ -793,7 +801,7 @@ c_decode_option (argc, argv)
warn_return_type = 1; warn_return_type = 1;
set_Wunused (1); set_Wunused (1);
warn_switch = 1; warn_switch = 1;
warn_format = 1; set_Wformat (1);
warn_char_subscripts = 1; warn_char_subscripts = 1;
warn_parentheses = 1; warn_parentheses = 1;
warn_sequence_point = 1; warn_sequence_point = 1;
......
2000-12-01 Joseph S. Myers <jsm28@cam.ac.uk> 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. * decl.c (WINT_TYPE, INTMAX_TYPE, UINTMAX_TYPE): Don't define.
(init_decl_processing): Don't create string_type_node, (init_decl_processing): Don't create string_type_node,
const_string_type_node, wint_type_node, intmax_type_node, const_string_type_node, wint_type_node, intmax_type_node,
......
...@@ -269,10 +269,6 @@ int warn_sign_compare; ...@@ -269,10 +269,6 @@ int warn_sign_compare;
int warn_float_equal = 0; 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. */ /* Warn about functions which might be candidates for format attributes. */
int warn_missing_format_attribute; int warn_missing_format_attribute;
...@@ -723,7 +719,13 @@ lang_decode_option (argc, argv) ...@@ -723,7 +719,13 @@ lang_decode_option (argc, argv)
else if (!strcmp (p, "float-equal")) else if (!strcmp (p, "float-equal"))
warn_float_equal = setting; warn_float_equal = setting;
else if (!strcmp (p, "format")) 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")) else if (!strcmp (p, "missing-format-attribute"))
warn_missing_format_attribute = setting; warn_missing_format_attribute = setting;
else if (!strcmp (p, "conversion")) else if (!strcmp (p, "conversion"))
...@@ -772,7 +774,7 @@ lang_decode_option (argc, argv) ...@@ -772,7 +774,7 @@ lang_decode_option (argc, argv)
set_Wunused (setting); set_Wunused (setting);
warn_implicit = setting; warn_implicit = setting;
warn_switch = setting; warn_switch = setting;
warn_format = setting; set_Wformat (setting);
warn_parentheses = setting; warn_parentheses = setting;
warn_missing_braces = setting; warn_missing_braces = setting;
warn_sign_compare = setting; warn_sign_compare = setting;
......
...@@ -143,7 +143,8 @@ in the following sections. ...@@ -143,7 +143,8 @@ in the following sections.
-w -W -Wall -Waggregate-return -w -W -Wall -Waggregate-return
-Wcast-align -Wcast-qual -Wchar-subscripts -Wcomment -Wcast-align -Wcast-qual -Wchar-subscripts -Wcomment
-Wconversion -Wdisabled-optimization -Werror -Wconversion -Wdisabled-optimization -Werror
-Wfloat-equal -Wformat -Wfloat-equal -Wformat -Wformat=2
-Wformat-nonliteral
-Wid-clash-@var{len} -Wimplicit -Wimplicit-int -Wid-clash-@var{len} -Wimplicit -Wimplicit-int
-Wimplicit-function-declaration -Wimplicit-function-declaration
-Werror-implicit-function-declaration -Werror-implicit-function-declaration
...@@ -151,7 +152,8 @@ in the following sections. ...@@ -151,7 +152,8 @@ in the following sections.
-Wlarger-than-@var{len} -Wlong-long -Wlarger-than-@var{len} -Wlong-long
-Wmain -Wmissing-declarations -Wmain -Wmissing-declarations
-Wmissing-format-attribute -Wmissing-noreturn -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 -Wparentheses -Wpointer-arith -Wredundant-decls
-Wreturn-type -Wsequence-point -Wshadow -Wreturn-type -Wsequence-point -Wshadow
-Wsign-compare -Wswitch -Wsystem-headers -Wsign-compare -Wswitch -Wsystem-headers
...@@ -1548,6 +1550,30 @@ Check calls to @code{printf} and @code{scanf}, etc., to make sure that ...@@ -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 the arguments supplied have types appropriate to the format string
specified. 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 @item -Wimplicit-int
Warn when a declaration does not specify a type. Warn when a declaration does not specify a type.
......
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> 2000-12-01 Neil Booth <neilb@earthling.net>
* gcc.dg/cpp/20000720-1.S: Remove duplicate testcase. * gcc.dg/cpp/20000720-1.S: Remove duplicate testcase.
......
/* 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);
}
/* 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);
}
/* 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" } */
}
/* 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" } */
}
...@@ -1226,8 +1226,16 @@ documented_lang_options[] = ...@@ -1226,8 +1226,16 @@ documented_lang_options[] =
{ "-Wno-comments", "" }, { "-Wno-comments", "" },
{ "-Wconversion", "Warn about possibly confusing type conversions" }, { "-Wconversion", "Warn about possibly confusing type conversions" },
{ "-Wno-conversion", "" }, { "-Wno-conversion", "" },
{ "-Wformat", "Warn about printf format anomalies" }, { "-Wformat", "Warn about printf/scanf/strftime format anomalies" },
{ "-Wno-format", "" }, { "-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", { "-Wimplicit-function-declaration",
"Warn about implicit function declarations" }, "Warn about implicit function declarations" },
{ "-Wno-implicit-function-declaration", "" }, { "-Wno-implicit-function-declaration", "" },
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment