This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
-Wformat=2 patch
- To: gcc-patches at gcc dot gnu dot org
- Subject: -Wformat=2 patch
- From: "Joseph S. Myers" <jsm28 at cam dot ac dot uk>
- Date: Sun, 1 Oct 2000 00:28:32 +0100 (BST)
This patch is the hopefully non-controversial part of my patch
<URL:http://gcc.gnu.org/ml/gcc-patches/2000-09/msg00854.html> with
warnings for printf (foo). It documents -Wformat=2, adds a testcase,
stops -Wall from overriding -Wformat=2, and adjusts the message
wording in the case of printf (foo), allowing the output from
compiling with that option to be grepped. It just omits the part
enabling the warning for printf (foo) at -Wall.
Bootstrapped with no regressions on i686-pc-linux-gnu. OK to commit?
Would a separate -Wsecurity option be acceptable for enabling the
printf (foo) warning, and any other security-related warnings for
problems GCC can detect which may be security holes but may also have
significant false positive rates?
gcc/ChangeLog:
2000-10-01 Joseph S. Myers <jsm28@cam.ac.uk>
* c-common.c (check_format_info): If the format is not a string
literal and there are no arguments to the format, give a different
warning message from the general non-string-literal case.
* c-decl.c (c_decode_option): If warn_format is nonzero, don't
change it in response to -Wall, so -Wall does not override
-Wformat=2.
* invoke.texi: Document -Wformat=2.
gcc/testsuite/ChangeLog:
2000-10-01 Joseph S. Myers <jsm28@cam.ac.uk>
* gcc.dg/format-nonlit-1.c: New test.
--- c-common.c.orig Fri Sep 29 22:42:19 2000
+++ c-common.c Sat Sep 30 19:20:43 2000
@@ -2029,8 +2029,23 @@
/* 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)
- status_warning (status, "format not a string literal, argument types not checked");
+ if (info->first_arg_num != 0)
+ {
+ /* If there are no arguments for the format at all, we may have
+ printf (foo) which is likely to be a security hole. */
+ while (arg_num + 1 < info->first_arg_num)
+ {
+ if (params == 0)
+ break;
+ params = TREE_CHAIN (params);
+ ++arg_num;
+ }
+ if (info->format_type != strftime_format_type && params == 0
+ && warn_format > 1)
+ status_warning (status, "format not a string literal and no format arguments");
+ else if (warn_format > 1)
+ status_warning (status, "format not a string literal, argument types not checked");
+ }
return;
}
format_tree = TREE_OPERAND (format_tree, 0);
@@ -2041,8 +2056,23 @@
/* 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)
- status_warning (status, "format not a string literal, argument types not checked");
+ if (info->first_arg_num != 0)
+ {
+ /* If there are no arguments for the format at all, we may have
+ printf (foo) which is likely to be a security hole. */
+ while (arg_num + 1 < info->first_arg_num)
+ {
+ if (params == 0)
+ break;
+ params = TREE_CHAIN (params);
+ ++arg_num;
+ }
+ if (info->format_type != strftime_format_type && params == 0
+ && warn_format > 1)
+ status_warning (status, "format not a string literal and no format arguments");
+ else if (warn_format > 1)
+ status_warning (status, "format not a string literal, argument types not checked");
+ }
return;
}
if (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (format_tree))) != char_type_node)
--- c-decl.c.orig Fri Sep 29 22:42:23 2000
+++ c-decl.c Sat Sep 30 19:19:47 2000
@@ -811,7 +811,8 @@
warn_return_type = 1;
set_Wunused (1);
warn_switch = 1;
- warn_format = 1;
+ if (warn_format == 0)
+ warn_format = 1;
warn_char_subscripts = 1;
warn_parentheses = 1;
warn_missing_braces = 1;
--- invoke.texi.orig Sat Sep 30 08:00:00 2000
+++ invoke.texi Sat Sep 30 19:21:16 2000
@@ -1494,7 +1494,9 @@
@item -Wformat
Check calls to @code{printf} and @code{scanf}, etc., to make sure that
the arguments supplied have types appropriate to the format string
-specified.
+specified. If @samp{-Wformat=2} 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 -Wimplicit-int
Warn when a declaration does not specify a type.
--- testsuite/gcc.dg/format-nonlit-1.c.orig Fri Sep 11 11:31:59 1998
+++ testsuite/gcc.dg/format-nonlit-1.c Tue Sep 19 22:45:58 2000
@@ -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" } */
+}
--
Joseph S. Myers
jsm28@cam.ac.uk