This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

-Wformat=2 patch


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]