[gcc(refs/users/giulianob/heads/autopar_rebase2)] diagnostics: Consistently add fixit hint for implicit builtin declaration
Giuliano Belinassi
giulianob@gcc.gnu.org
Mon Aug 17 23:17:14 GMT 2020
https://gcc.gnu.org/g:5b084b6d1029e1ed240e7c0e445bcae1a717b01d
commit 5b084b6d1029e1ed240e7c0e445bcae1a717b01d
Author: Mark Wielaard <mark@klomp.org>
Date: Thu May 28 02:55:36 2020 +0200
diagnostics: Consistently add fixit hint for implicit builtin declaration
There are two warnings that might trigger when a builtin function is
used but not declared yet. Both called through implicitly_declare in
c-decl. The first in implicit_decl_warning does warn for builtins,
but does not add a fixit hint for them (only for non-builtins when
a header is suggested through lookup_name_fuzzy). This warning is
guarded by -Wimplicit-function-declaration. The second warning, which
does include a fixit hint if possible, is given when the implicit
builtin declaration has an incompatible signature. This second warning
cannot be disabled.
This setup means that you only get a fixit-hint for usage of builtin
functions where the implicit signature is different than the actual
signature of the builtin. No fixit hints with header suggestions
are ever generated for builtins like abs, isdigit or putchar.
It seems more consistent to always generate a fixit-hint if possible
for the -Wimplicit-function-declaration warning. And for the second
warning to make it depend on -Wbuiltin-declaration-mismatch like
other warnings about builtin declaration mismatches.
Include a new test to show we get fixit-hints for abs, isdigit and
putchar now. Some small tweaks to existing tests to show the
effect of -Wno-builtin-declaration-mismatch with this change. And
a testcase to show that #pragma GCC diagnostic ignored now works.
gcc/c/ChangeLog:
* c-decl.c (implicit_decl_warning): When warned and olddecl is
an undeclared builtin, then add a fixit header hint, if found.
(implicitly_declare): Add OPT_Wbuiltin_declaration_mismatch to
warning_at about implicit builtin declaration type mismatch.
gcc/testsuite/ChangeLog:
* gcc.dg/missing-header-fixit-3.c: Add
-Wno-implicit-function-declaration.
* gcc.dg/missing-header-fixit-4.c: Add new expected output.
* gcc.dg/missing-header-fixit-5.c: New testcase.
* gcc.dg/Wbuiltin-declaration-mismatch-ignore.c: Likewise.
Diff:
---
gcc/c/c-decl.c | 30 ++++++++++++++++--
.../gcc.dg/Wbuiltin-declaration-mismatch-ignore.c | 11 +++++++
gcc/testsuite/gcc.dg/missing-header-fixit-3.c | 2 +-
gcc/testsuite/gcc.dg/missing-header-fixit-4.c | 4 +++
gcc/testsuite/gcc.dg/missing-header-fixit-5.c | 36 ++++++++++++++++++++++
5 files changed, 79 insertions(+), 4 deletions(-)
diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c
index b3e05be0af8..81bd2ee94f0 100644
--- a/gcc/c/c-decl.c
+++ b/gcc/c/c-decl.c
@@ -3368,8 +3368,30 @@ implicit_decl_warning (location_t loc, tree id, tree olddecl)
warned = warning_at (loc, OPT_Wimplicit_function_declaration,
G_("implicit declaration of function %qE"), id);
- if (olddecl && warned)
- locate_old_decl (olddecl);
+ if (warned)
+ {
+ /* Whether the olddecl is an undeclared builtin function.
+ locate_old_decl will not generate a diagnostic for those,
+ so in that case we want to look elsewhere. */
+ bool undeclared_builtin = (olddecl
+ && TREE_CODE (olddecl) == FUNCTION_DECL
+ && fndecl_built_in_p (olddecl)
+ && !C_DECL_DECLARED_BUILTIN (olddecl));
+ if (undeclared_builtin)
+ {
+ const char *header = header_for_builtin_fn (olddecl);
+ if (header)
+ {
+ rich_location richloc (line_table, loc);
+ maybe_add_include_fixit (&richloc, header, true);
+ inform (&richloc,
+ "include %qs or provide a declaration of %qE",
+ header, id);
+ }
+ }
+ else if (olddecl)
+ locate_old_decl (olddecl);
+ }
if (!warned)
hint.suppress ();
@@ -3631,7 +3653,9 @@ implicitly_declare (location_t loc, tree functionid)
(TREE_TYPE (decl)));
if (!comptypes (newtype, TREE_TYPE (decl)))
{
- bool warned = warning_at (loc, 0, "incompatible implicit "
+ bool warned = warning_at (loc,
+ OPT_Wbuiltin_declaration_mismatch,
+ "incompatible implicit "
"declaration of built-in "
"function %qD", decl);
/* See if we can hint which header to include. */
diff --git a/gcc/testsuite/gcc.dg/Wbuiltin-declaration-mismatch-ignore.c b/gcc/testsuite/gcc.dg/Wbuiltin-declaration-mismatch-ignore.c
new file mode 100644
index 00000000000..732c23f91b1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wbuiltin-declaration-mismatch-ignore.c
@@ -0,0 +1,11 @@
+/* Check -Wbuiltin-declaration-mismatch can be ignored with pragma. */
+/* { dg-do compile }
+ { dg-options "-Wno-implicit-function-declaration -Wno-int-conversion -Wbuiltin-declaration-mismatch" } */
+
+#pragma GCC diagnostic ignored "-Wbuiltin-declaration-mismatch"
+int foo (const char *str)
+{
+ int i;
+ sscanf (str, "%d", &i);
+ return i;
+}
diff --git a/gcc/testsuite/gcc.dg/missing-header-fixit-3.c b/gcc/testsuite/gcc.dg/missing-header-fixit-3.c
index dd53bf65d3c..8394010c1ac 100644
--- a/gcc/testsuite/gcc.dg/missing-header-fixit-3.c
+++ b/gcc/testsuite/gcc.dg/missing-header-fixit-3.c
@@ -2,7 +2,7 @@
adding them to the top of the file, given that there is no
pre-existing #include. */
-/* { dg-options "-fdiagnostics-show-caret -fdiagnostics-show-line-numbers" } */
+/* { dg-options "-fdiagnostics-show-caret -fdiagnostics-show-line-numbers -Wno-implicit-function-declaration" } */
void test (int i, int j)
{
diff --git a/gcc/testsuite/gcc.dg/missing-header-fixit-4.c b/gcc/testsuite/gcc.dg/missing-header-fixit-4.c
index 942897d8c79..b6680563dc1 100644
--- a/gcc/testsuite/gcc.dg/missing-header-fixit-4.c
+++ b/gcc/testsuite/gcc.dg/missing-header-fixit-4.c
@@ -9,6 +9,10 @@ void test (int i, int j)
{
printf ("%i of %i\n", i, j); /* { dg-line printf } */
/* { dg-warning "implicit declaration of function" "" { target *-*-* } printf } */
+ /* { dg-begin-multiline-output "" }
+ 10 | printf ("%i of %i\n", i, j);
+ | ^~~~~~
+ { dg-end-multiline-output "" } */
/* { dg-warning "incompatible implicit declaration" "" { target *-*-* } printf } */
/* { dg-begin-multiline-output "" }
10 | printf ("%i of %i\n", i, j);
diff --git a/gcc/testsuite/gcc.dg/missing-header-fixit-5.c b/gcc/testsuite/gcc.dg/missing-header-fixit-5.c
new file mode 100644
index 00000000000..916033c689c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/missing-header-fixit-5.c
@@ -0,0 +1,36 @@
+
+/* Forget to include any standard headers, all for built-in functions.
+ Rely on -Wimplicit-function-declaration for fixit hints, not on
+ -Wbuiltin-declaration-mismatch (which misses abs, isdigit, putchar). */
+
+/* { dg-options "-fdiagnostics-show-caret -fdiagnostics-show-line-numbers -Wimplicit-function-declaration -Wno-builtin-declaration-mismatch" } */
+
+int
+foo (char *m, int i)
+{
+ if (isdigit (m[0])) /* { dg-warning "implicit declaration of function" } */
+ /* { dg-begin-multiline-output "" }
+ 11 | if (isdigit (m[0]))
+ | ^~~~~~~
+ +++ |+#include <ctype.h>
+ 1 |
+ { dg-end-multiline-output "" } */
+ {
+ return abs (i); /* { dg-warning "implicit declaration of function" } */
+ /* { dg-begin-multiline-output "" }
+ 19 | return abs (i);
+ | ^~~
+ +++ |+#include <stdlib.h>
+ 1 |
+ { dg-end-multiline-output "" } */
+ }
+ else
+ putchar (m[0]); /* { dg-warning "implicit declaration of function" } */
+ /* { dg-begin-multiline-output "" }
+ 28 | putchar (m[0]);
+ | ^~~~~~~
+ +++ |+#include <stdio.h>
+ 1 |
+ { dg-end-multiline-output "" } */
+ return i;
+}
More information about the Gcc-cvs
mailing list