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, updated again


This patch is a revised version of my -Wformat=2 documentation and
enhancement patch; this version applies to the current code (after my
changes to check formats in conditional expressions affecting the same
code).  It documents the existing option -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 also adds a warning at
-Wformat=2 for strftime formats with non-constant format string, since
those are not vprintf-like but have first_arg_num == 0.

Bootstrapped with no regressions on i686-pc-linux-gnu (after applying
http://gcc.gnu.org/ml/gcc-patches/2000-10/msg00388.html).  OK to
commit?

gcc/ChangeLog:
2000-10-17  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.
	Also warn at -Wformat=2 for non-constant format strings with
	strftime formats.
	* 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-17  Joseph S. Myers  <jsm28@cam.ac.uk>

	* gcc.dg/format-nonlit-1.c: New test.

--- c-common.c.orig	Mon Oct 16 16:12:46 2000
+++ c-common.c	Mon Oct 16 18:31:34 2000
@@ -2202,6 +2202,7 @@ check_format_info (status, info, params)
   int arg_num;
   tree format_tree;
   format_check_results res;
+  int flags = format_types[info->format_type].flags;
   /* Skip to format argument.  If the argument isn't available, there's
      no work for us to do; prototype checking will catch the problem.  */
   for (arg_num = 1; ; ++arg_num)
@@ -2232,8 +2233,29 @@ 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)
-	status_warning (status, "format not a string literal, argument types not checked");
+      if (!(flags & FMT_FLAG_ARG_CONVERT))
+	{
+	  /* For strftime-like formats, warn for not checking the format
+	     string; but there are no arguments to check.  */
+	  if (warn_format > 1)
+	    status_warning (status, "format not a string literal, format string not checked");
+	}
+      else 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 (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");
+	}
     }
 
   /* If there were extra arguments to the format, normally warn.  However,
--- c-decl.c.orig	Tue Oct 10 15:16:37 2000
+++ c-decl.c	Tue Oct 10 15:17:11 2000
@@ -823,7 +823,8 @@ c_decode_option (argc, argv)
       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]