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 ();
(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. */
--- /dev/null
+/* 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;
+}
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)
{
{
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);
--- /dev/null
+
+/* 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;
+}