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]
Other format: [Raw text]

[PATCH] avoid -Wmissing-format-attribute for functions that use literal formats


The attached patch refines the logic used to suggest the format
attribute to filter out functions that use string literals and
constants as formats.

This change has the effect of not suggesting the attribute for
functions like the one below (since the attribute couldn't very
be used with it):

  void g (char *d, __builtin_va_list va)
  {
    vsprintf (d, "%i", va);
  }

I started seeing the warnings after my recent changes to the
Wformat-length patch and couldn't find a good way to suppress
them other than via #pragma GCC diagnostic.

Martin
PR c/77336 -  -Wsuggest-attribute=format warning overly simplistic

gcc/c-family/ChangeLog:
2016-08-23  Martin Sebor  <msebor@redhat.com>

	PR c/77336
	* c-format.c (check_function_format): Avoid issuing warnings for
	functions unless they call format functions with non-constant
	format strings.

gcc/testsuite/ChangeLog:
2016-08-23  Martin Sebor  <msebor@redhat.com>

	PR c/77336
	* gcc.dg/format/miss-7.c: New test.

diff --git a/gcc/c-family/c-format.c b/gcc/c-family/c-format.c
index ad434f8..413962e 100644
--- a/gcc/c-family/c-format.c
+++ b/gcc/c-family/c-format.c
@@ -31,6 +31,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "c-format.h"
 #include "diagnostic.h"
 #include "selftest.h"
+#include "builtins.h"
 
 /* Handle attributes associated with format checking.  */
 
@@ -1212,9 +1213,17 @@ check_function_format (tree attrs, int nargs, tree *argarray)
 		params = tree_cons (NULL_TREE, argarray[i], params);
 	      check_format_info (&info, params);
 	    }
+
+	  /* Attempt to detect whether the current function might benefit
+	     from the format attribute if the called function is decorated
+	     with it.  Avoid using calls with string literal formats for
+	     guidance since those are unlikely to be viable candidates.  */
 	  if (warn_suggest_attribute_format && info.first_arg_num == 0
 	      && (format_types[info.format_type].flags
-		  & (int) FMT_FLAG_ARG_CONVERT))
+		  & (int) FMT_FLAG_ARG_CONVERT)
+	      /* c_strlen will fail for a function parameter but succeed
+		 for a literal or constant array.  */
+	      && !c_strlen (argarray[info.format_num - 1], 1))
 	    {
 	      tree c;
 	      for (c = TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl));
@@ -1242,8 +1251,9 @@ check_function_format (tree attrs, int nargs, tree *argarray)
 			break;
 		    }
 		  if (args != 0)
-		    warning (OPT_Wsuggest_attribute_format, "function might "
-			     "be possible candidate for %qs format attribute",
+		    warning (OPT_Wsuggest_attribute_format, "function %qD "
+			     "might be a candidate for %qs format attribute",
+			     current_function_decl,
 			     format_types[info.format_type].name);
 		}
 	    }
diff --git a/gcc/testsuite/gcc.dg/format/miss-7.c b/gcc/testsuite/gcc.dg/format/miss-7.c
new file mode 100644
index 0000000..828b781
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/format/miss-7.c
@@ -0,0 +1,36 @@
+/* PR77336 - -Wsuggest-attribute=format warning overly simplistic */
+/* { dg-do compile } */
+/* { dg-options "-Wsuggest-attribute=format" } */
+
+#include "format.h"
+
+const char format[] = "%i";
+
+void foo (char *d, unsigned n, va_list va)
+{
+  (void)&n;
+
+  /* The following calls don't imply that the enclosing function is
+     a candiate for the format attribute because it uses a string
+     constant as the format.  */
+  vsnprintf (d, n, "%i", va);
+
+  vsnprintf (d, n, format, va);
+
+  /* In theory this should not trigger the warning either but GCC
+     doesn't treat the local static constant the same way as the
+     global and issues a false positive.
+  const char fmt[] = "%i";
+  vsnprintf (d, n, fmt, va);
+  */
+}
+
+void bar (char *d, unsigned n, const char *f, va_list va)
+{
+  (void)&n;
+
+  /* The following call suggests that the enclosing function might
+     be a candiate for the format attribute because it doesn't use
+     a string literal as the format.  */
+  vsnprintf (d, n, f, va);   /* { dg-warning "function .bar. might be a candidate for .gnu_printf. format attribute" } */
+}

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