From a42e7952b0af76c0c16d341d25eaad7f044b5dc4 Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Tue, 6 Sep 2016 19:23:25 +0000 Subject: [PATCH] PR c/77336 - -Wsuggest-attribute=format warning overly simplistic gcc/c-family/ChangeLog: 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: PR c/77336 * gcc.dg/format/miss-7.c: New test. From-SVN: r240013 --- gcc/c-family/ChangeLog | 7 ++++++ gcc/c-family/c-format.c | 16 ++++++++++--- gcc/testsuite/ChangeLog | 5 ++++ gcc/testsuite/gcc.dg/format/miss-7.c | 36 ++++++++++++++++++++++++++++ 4 files changed, 61 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/format/miss-7.c diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index 9d9344ffa9f..5d642d71ece 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,10 @@ +2016-09-06 Martin Sebor + + PR c/77336 + * c-format.c (check_function_format): Avoid issuing warnings for + functions unless they call format functions with non-constant + format strings. + 2016-09-06 Richard Biener PR c/77450 diff --git a/gcc/c-family/c-format.c b/gcc/c-family/c-format.c index ad434f810ce..413962eec21 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/ChangeLog b/gcc/testsuite/ChangeLog index acb0e201b5b..4e24658c993 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2016-09-06 Martin Sebor + + PR c/77336 + * gcc.dg/format/miss-7.c: New test. + 2016-09-06 Uros Bizjak * gfortran.dg/c_by_val_1.f: Correct the call to c_to_c and c_to_c8. 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 00000000000..828b781e0e6 --- /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" } */ +} -- 2.30.2