aboutsummaryrefslogtreecommitdiff
path: root/gcc/c/c-decl.c
diff options
context:
space:
mode:
authorMark Wielaard <mark@klomp.org>2020-05-28 02:55:36 +0200
committerMark Wielaard <mark@klomp.org>2020-06-05 20:21:17 +0200
commit1c7bcefbc95220cd74cee7c239f6d723f75a0ccc (patch)
tree135fe4efe728f939d0d86cb7ee7e4ca10292ed32 /gcc/c/c-decl.c
parent0cdc55f5ed881436c49d313b6cead244bdcf0654 (diff)
downloadgcc-1c7bcefbc95220cd74cee7c239f6d723f75a0ccc.zip
gcc-1c7bcefbc95220cd74cee7c239f6d723f75a0ccc.tar.gz
gcc-1c7bcefbc95220cd74cee7c239f6d723f75a0ccc.tar.bz2
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.
Diffstat (limited to 'gcc/c/c-decl.c')
-rw-r--r--gcc/c/c-decl.c30
1 files changed, 27 insertions, 3 deletions
diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c
index b3e05be..81bd2ee 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. */