From 55e94561e97ed0bce4774aa1c6b5d5d82209a379 Mon Sep 17 00:00:00 2001
From: Florian Weimer <fweimer@redhat.com>
Date: Fri, 1 Dec 2023 08:10:13 +0100
Subject: [PATCH] c: Turn -Wimplicit-function-declaration into a permerror

In the future, it may make sense to avoid cascading errors from
the implicit declaration, especially its assumed int return type.
This change here only changes the kind of the diagnostic, not
its wording or consequences.

gcc/

	* doc/invoke.texi (Warning Options): Document changes.

gcc/c/

	PR c/91092
	PR c/96284
	* c-decl.cc (implicit_decl_permerror): Rename from
	implicit_decl_warning.  Call permerror_opt instead of
	pedwarn and warning_at.
	(implicitly_declare): Adjust callers.

gcc/testsuite/

	* gcc.dg/permerror-default.c (implicit_function_declaration):
	Expect the new permerror.
	* gcc.dg/permerror-system.c: Likewise.
	* c-c++-common/spellcheck-reserved.c (test, test_2): Expect
	error instead of warning.
	(f): Expect error instead of warning.
	* gcc.dg/Wimplicit-function-declaration-c99.c: Compile with
	-fpermissive due to expected warning.
	* gcc.dg/Wimplicit-function-declaration-c99-2.c: New test.
	Copied from gcc.dg/Wimplicit-function-declaration-c99.c.
	Expect error.
	* gcc.dg/missing-header-fixit-1.c: Compile with -fpermissive
	due to expect error.
	* gcc.dg/missing-header-fixit-1a.c: New test.  Copied from
	gcc.dg/missing-header-fixit-1.c, but expect error.
	* gcc.dg/missing-header-fixit-2.c: Compile with -fpermissive
	due to expect error.
	* gcc.dg/missing-header-fixit-2a.c: New test.  Copied from
	gcc.dg/missing-header-fixit-2.c, but expect error.
	* gcc.dg/missing-header-fixit-4.c: Compile with -fpermissive
	due to expect error.
	* gcc.dg/missing-header-fixit-4a.c: New test.  Copied from
	gcc.dg/missing-header-fixit-4.c, but expect error.
	* gcc.dg/missing-header-fixit-5.c: Compile with -fpermissive
	due to expect error.
	* gcc.dg/missing-header-fixit-5a.c: New test.  Copied from
	gcc.dg/missing-header-fixit-5.c, but expect error.
	* gcc.dg/pr61852.c: Expect implicit-function-declaration
	error instead of warning.
	* gcc.dg/spellcheck-identifiers-2.c: Compile with
	-fpermissive due to expected warnings.
	* gcc.dg/spellcheck-identifiers-2a.c: New test.  Copied
	from gcc.dg/spellcheck-identifiers-2a.c.  Expect errors.
	* gcc.dg/spellcheck-identifiers-3.c: Compile with
	-fpermissive due to expected warnings.
	* gcc.dg/spellcheck-identifiers-3a.c: New test.  Copied
	from gcc.dg/spellcheck-identifiers-2a.c.  Expect errors.
	* gcc.dg/spellcheck-identifiers-4.c: Compile with
	-fpermissive due to expected warnings.
	* gcc.dg/spellcheck-identifiers-4a.c: New test.  Copied
	from gcc.dg/spellcheck-identifiers-2a.c.  Expect error.
	* gcc.dg/spellcheck-identifiers.c: Compile with
	-fpermissive due to expected warnings.
	* gcc.dg/spellcheck-identifiers-1a.c: New test.  Copied
	from gcc.dg/spellcheck-identifiers.c.  Expect errors.
	* gcc.target/aarch64/sve/acle/general-c/ld1sh_gather_1.c (f1):
	Expect error.
	* gcc.target/aarch64/sve/acle/general-c/load_ext_gather_index_1.c:
	(f1): Likewise.
	* gcc.target/aarch64/sve/acle/general-c/load_ext_gather_index_restricted_1.c:
	(f1): Likewise.
	* gcc.target/aarch64/sve/acle/general-c/load_ext_gather_offset_1.c:
	(f1): Likewise.
	* gcc.target/aarch64/sve/acle/general-c/load_ext_gather_offset_2.c:
	(f1): Likewise.
	* gcc.target/aarch64/sve/acle/general-c/load_ext_gather_offset_3.c:
	(f1): Likewise.
	* gcc.target/aarch64/sve/acle/general-c/load_ext_gather_offset_4.c:
	(f1): Likewise.
	* gcc.target/aarch64/sve/acle/general-c/load_ext_gather_offset_5.c:
	(f1): Likewise.
	* gcc.target/aarch64/sve/acle/general-c/load_ext_gather_offset_restricted_1.c:
	(f1): Likewise.
	* gcc.target/aarch64/sve/acle/general-c/load_ext_gather_offset_restricted_2.c:
	(f1): Likewise.
	* gcc.target/aarch64/sve/acle/general-c/load_ext_gather_offset_restricted_3.c:
	(f1): Likewise.
	* gcc.target/aarch64/sve/acle/general-c/load_ext_gather_offset_restricted_4.c:
	(f1): Likewise.
---
 gcc/c/c-decl.cc                               |  20 +--
 gcc/doc/invoke.texi                           |   8 +-
 .../c-c++-common/spellcheck-reserved.c        |   4 +-
 .../Wimplicit-function-declaration-c99-2.c    |   7 +
 .../Wimplicit-function-declaration-c99.c      |   2 +-
 gcc/testsuite/gcc.dg/missing-header-fixit-1.c |   2 +-
 .../gcc.dg/missing-header-fixit-1a.c          |  37 +++++
 gcc/testsuite/gcc.dg/missing-header-fixit-2.c |   2 +-
 .../gcc.dg/missing-header-fixit-2a.c          |  31 ++++
 gcc/testsuite/gcc.dg/missing-header-fixit-4.c |   2 +-
 .../gcc.dg/missing-header-fixit-4a.c          |  27 ++++
 gcc/testsuite/gcc.dg/missing-header-fixit-5.c |   2 +-
 .../gcc.dg/missing-header-fixit-5a.c          |  42 ++++++
 gcc/testsuite/gcc.dg/permerror-default.c      |   2 +-
 gcc/testsuite/gcc.dg/permerror-system.c       |   2 +
 gcc/testsuite/gcc.dg/pr61852.c                |   4 +-
 .../gcc.dg/spellcheck-identifiers-1a.c        | 136 ++++++++++++++++++
 .../gcc.dg/spellcheck-identifiers-2.c         |   2 +-
 .../gcc.dg/spellcheck-identifiers-2a.c        |  33 +++++
 .../gcc.dg/spellcheck-identifiers-3.c         |   2 +-
 .../gcc.dg/spellcheck-identifiers-3a.c        |  45 ++++++
 .../gcc.dg/spellcheck-identifiers-4.c         |   2 +-
 .../gcc.dg/spellcheck-identifiers-4a.c        |  10 ++
 gcc/testsuite/gcc.dg/spellcheck-identifiers.c |   2 +-
 .../sve/acle/general-c/ld1sh_gather_1.c       |   2 +-
 .../acle/general-c/load_ext_gather_index_1.c  |   2 +-
 .../load_ext_gather_index_restricted_1.c      |   2 +-
 .../acle/general-c/load_ext_gather_offset_1.c |   2 +-
 .../acle/general-c/load_ext_gather_offset_2.c |   2 +-
 .../acle/general-c/load_ext_gather_offset_3.c |   2 +-
 .../acle/general-c/load_ext_gather_offset_4.c |   2 +-
 .../acle/general-c/load_ext_gather_offset_5.c |   2 +-
 .../load_ext_gather_offset_restricted_1.c     |   2 +-
 .../load_ext_gather_offset_restricted_2.c     |   2 +-
 .../load_ext_gather_offset_restricted_3.c     |   2 +-
 .../load_ext_gather_offset_restricted_4.c     |   2 +-
 36 files changed, 412 insertions(+), 38 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/Wimplicit-function-declaration-c99-2.c
 create mode 100644 gcc/testsuite/gcc.dg/missing-header-fixit-1a.c
 create mode 100644 gcc/testsuite/gcc.dg/missing-header-fixit-2a.c
 create mode 100644 gcc/testsuite/gcc.dg/missing-header-fixit-4a.c
 create mode 100644 gcc/testsuite/gcc.dg/missing-header-fixit-5a.c
 create mode 100644 gcc/testsuite/gcc.dg/spellcheck-identifiers-1a.c
 create mode 100644 gcc/testsuite/gcc.dg/spellcheck-identifiers-2a.c
 create mode 100644 gcc/testsuite/gcc.dg/spellcheck-identifiers-3a.c
 create mode 100644 gcc/testsuite/gcc.dg/spellcheck-identifiers-4a.c

diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc
index cf1df82c0f40..4d17f055604b 100644
--- a/gcc/c/c-decl.cc
+++ b/gcc/c/c-decl.cc
@@ -3493,12 +3493,12 @@ pushdecl (tree x)
 }
 
 
-/* Issue a warning about implicit function declaration.  ID is the function
+/* Issue a permerror about implicit function declaration.  ID is the function
    identifier, OLDDECL is a declaration of the function in a different scope,
    or NULL_TREE.  */
 
 static void
-implicit_decl_warning (location_t loc, tree id, tree olddecl)
+implicit_decl_permerror (location_t loc, tree id, tree olddecl)
 {
   if (!warn_implicit_function_declaration)
     return;
@@ -3515,14 +3515,14 @@ implicit_decl_warning (location_t loc, tree id, tree olddecl)
 	{
 	  gcc_rich_location richloc (loc);
 	  richloc.add_fixit_replace (suggestion);
-	  warned = pedwarn (&richloc, OPT_Wimplicit_function_declaration,
-			    "implicit declaration of function %qE;"
-			    " did you mean %qs?",
-			    id, suggestion);
+	  warned = permerror_opt (&richloc, OPT_Wimplicit_function_declaration,
+				  "implicit declaration of function %qE;"
+				  " did you mean %qs?",
+				  id, suggestion);
 	}
       else
-	warned = pedwarn (loc, OPT_Wimplicit_function_declaration,
-			  "implicit declaration of function %qE", id);
+	warned = permerror_opt (loc, OPT_Wimplicit_function_declaration,
+				"implicit declaration of function %qE", id);
     }
   else if (const char *suggestion = hint.suggestion ())
     {
@@ -3812,7 +3812,7 @@ implicitly_declare (location_t loc, tree functionid)
 	     then recycle the old declaration but with the new type.  */
 	  if (!C_DECL_IMPLICIT (decl))
 	    {
-	      implicit_decl_warning (loc, functionid, decl);
+	      implicit_decl_permerror (loc, functionid, decl);
 	      C_DECL_IMPLICIT (decl) = 1;
 	    }
 	  if (fndecl_built_in_p (decl))
@@ -3865,7 +3865,7 @@ implicitly_declare (location_t loc, tree functionid)
   DECL_EXTERNAL (decl) = 1;
   TREE_PUBLIC (decl) = 1;
   C_DECL_IMPLICIT (decl) = 1;
-  implicit_decl_warning (loc, functionid, 0);
+  implicit_decl_permerror (loc, functionid, 0);
   asmspec_tree = maybe_apply_renaming_pragma (decl, /*asmname=*/NULL);
   if (asmspec_tree)
     set_user_assembler_name (decl, TREE_STRING_POINTER (asmspec_tree));
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index cc8fb7a59c12..5244958f01d3 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -6184,6 +6184,7 @@ only by this flag, but it also downgrades some C and C++ diagnostics
 that have their own flag:
 
 @gccoptlist{
+-Wimplicit-function-declaration @r{(C and Objective-C only)}
 -Wint-conversion @r{(C and Objective-C only)}
 -Wnarrowing @r{(C++)}
 }
@@ -6864,8 +6865,11 @@ This warning is upgraded to an error by @option{-pedantic-errors}.
 @opindex Wno-implicit-function-declaration
 @item -Wno-implicit-function-declaration @r{(C and Objective-C only)}
 This option controls warnings when a function is used before being declared.
-This warning is enabled by default in C99 and later dialects of C,
-and also by @option{-Wall}.
+This warning is enabled by default, as an error, in C99 and later
+dialects of C, and also by @option{-Wall}.  The error can be downgraded
+to a warning using @option{-fpermissive} (along with certain other
+errors), or for this error alone, with
+@option{-Wno-error=implicit-function-declaration}.
 
 This warning is upgraded to an error by @option{-pedantic-errors}.
 
diff --git a/gcc/testsuite/c-c++-common/spellcheck-reserved.c b/gcc/testsuite/c-c++-common/spellcheck-reserved.c
index 56e59dcc00ac..0be35c56f52d 100644
--- a/gcc/testsuite/c-c++-common/spellcheck-reserved.c
+++ b/gcc/testsuite/c-c++-common/spellcheck-reserved.c
@@ -29,7 +29,7 @@ SOME_MACRO foo; /* { dg-bogus "__SOME_MACRO" } */
 void test (const char *buf, char ch)
 {
   __builtin_strtchr (buf, ch); /* { dg-line misspelled_reserved } */
-  /* { dg-warning "did you mean '__builtin_strchr'" "" { target c } misspelled_reserved } */
+  /* { dg-error "did you mean '__builtin_strchr'" "" { target c } misspelled_reserved } */
   /* { dg-error "'__builtin_strtchr' was not declared in this scope; did you mean '__builtin_strrchr'\\?" "" { target c++ } misspelled_reserved } */
 }
 
@@ -38,7 +38,7 @@ void test (const char *buf, char ch)
 void test_2 (const char *buf, char ch)
 {
   _builtin_strchr (buf, ch); /* { dg-line misspelled_one_underscore } */
-  /* { dg-warning "did you mean '__builtin_strchr'" "" { target c } misspelled_one_underscore } */
+  /* { dg-error "did you mean '__builtin_strchr'" "" { target c } misspelled_one_underscore } */
   /* { dg-error "'_builtin_strchr' was not declared in this scope; did you mean '__builtin_strchr'\\?" "" { target c++ } misspelled_one_underscore } */
 }
 
diff --git a/gcc/testsuite/gcc.dg/Wimplicit-function-declaration-c99-2.c b/gcc/testsuite/gcc.dg/Wimplicit-function-declaration-c99-2.c
new file mode 100644
index 000000000000..d65abc9670ce
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wimplicit-function-declaration-c99-2.c
@@ -0,0 +1,7 @@
+/* { dg-do compile } */
+/* { dg-options "-std=c99" } */
+
+void f(void) 
+{ 
+  puts("Hello"); /* { dg-error "implicit declaration of function" } */
+}
diff --git a/gcc/testsuite/gcc.dg/Wimplicit-function-declaration-c99.c b/gcc/testsuite/gcc.dg/Wimplicit-function-declaration-c99.c
index 254f7e70e657..abea8a5f3566 100644
--- a/gcc/testsuite/gcc.dg/Wimplicit-function-declaration-c99.c
+++ b/gcc/testsuite/gcc.dg/Wimplicit-function-declaration-c99.c
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-std=c99" } */
+/* { dg-options "-fpermissive -std=c99" } */
 
 void f(void) 
 { 
diff --git a/gcc/testsuite/gcc.dg/missing-header-fixit-1.c b/gcc/testsuite/gcc.dg/missing-header-fixit-1.c
index 2b28357e1db9..eb33d9b1f238 100644
--- a/gcc/testsuite/gcc.dg/missing-header-fixit-1.c
+++ b/gcc/testsuite/gcc.dg/missing-header-fixit-1.c
@@ -5,7 +5,7 @@
 /* This is padding (to avoid the generated patch containing DejaGnu
    directives).  */
 
-/* { dg-options "-fdiagnostics-generate-patch" } */
+/* { dg-options "-fpermissive -fdiagnostics-generate-patch" } */
 
 void test (int i, int j)
 {
diff --git a/gcc/testsuite/gcc.dg/missing-header-fixit-1a.c b/gcc/testsuite/gcc.dg/missing-header-fixit-1a.c
new file mode 100644
index 000000000000..e47236b955d2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/missing-header-fixit-1a.c
@@ -0,0 +1,37 @@
+/* Example of a fix-it hint that adds a #include directive,
+   adding them to the top of the file, given that there is no
+   pre-existing #include.  */
+
+/* This is padding (to avoid the generated patch containing DejaGnu
+   directives).  */
+
+/* { dg-options "-fdiagnostics-generate-patch" } */
+
+void test (int i, int j)
+{
+  printf ("%i of %i\n", i, j); /* { dg-error "implicit declaration" } */
+  /* { dg-message "include '<stdio.h>' or provide a declaration of 'printf'" "" { target *-*-* } .-1 } */
+  /* { dg-warning "incompatible implicit declaration of built-in function 'printf'" "" { target *-*-* } .-2 } */
+}
+
+/* Verify the output from -fdiagnostics-generate-patch.
+   We expect the patch to begin with a header, containing this
+   source filename, via an absolute path.
+   Given the path, we can only capture it via regexps.  */
+/* { dg-regexp "\\-\\-\\- .*" } */
+/* { dg-regexp "\\+\\+\\+ .*" } */
+/* Use #if 0/#endif rather than comments, to allow the text to contain
+   a comment.  */
+#if 0
+{ dg-begin-multiline-output "" }
+@@ -1,3 +1,4 @@
++#include <stdio.h>
+ /* Example of a fix-it hint that adds a #include directive,
+    adding them to the top of the file, given that there is no
+    pre-existing #include.  */
+{ dg-end-multiline-output "" }
+#endif
+
+/* FIXME: should we attempt to skip leading comments when determining the
+   insertion location?
+   Similarly, should we attempt to be within single-inclusion guards, etc?  */
diff --git a/gcc/testsuite/gcc.dg/missing-header-fixit-2.c b/gcc/testsuite/gcc.dg/missing-header-fixit-2.c
index 5d5f87488f57..38d36a66c461 100644
--- a/gcc/testsuite/gcc.dg/missing-header-fixit-2.c
+++ b/gcc/testsuite/gcc.dg/missing-header-fixit-2.c
@@ -9,7 +9,7 @@
 /* { dg-warning "implicit declaration of function 'printf'" "" { target *-*-* } 6 } */
 /* { dg-warning "incompatible implicit declaration of built-in function 'printf'" "" { target *-*-* } 6 } */
 
-/* { dg-options "-fdiagnostics-generate-patch" } */
+/* { dg-options "-fpermissive -fdiagnostics-generate-patch" } */
 
 /* Verify the output from -fdiagnostics-generate-patch.
    We expect the patch to begin with a header, containing the
diff --git a/gcc/testsuite/gcc.dg/missing-header-fixit-2a.c b/gcc/testsuite/gcc.dg/missing-header-fixit-2a.c
new file mode 100644
index 000000000000..4ae617bddbd4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/missing-header-fixit-2a.c
@@ -0,0 +1,31 @@
+/* Verify that when we suggest adding #include directives that they
+   are added to the affected file.  */
+
+/* The following header file is missing a "#include <stdio.h>".  */
+
+#include "missing-header-fixit-2.h"
+
+/* These directives actually apply to the header.  */
+/* { dg-error "implicit declaration of function 'printf'" "" { target *-*-* } 6 } */
+/* { dg-warning "incompatible implicit declaration of built-in function 'printf'" "" { target *-*-* } 6 } */
+
+/* { dg-options "-fdiagnostics-generate-patch" } */
+
+/* Verify the output from -fdiagnostics-generate-patch.
+   We expect the patch to begin with a header, containing the
+   filename of the header, via an absolute path.
+   Given the path, we can only capture it via regexps.  */
+/* { dg-regexp "\\-\\-\\- .*" } */
+/* { dg-regexp "\\+\\+\\+ .*" } */
+/* Use #if 0/#endif rather than comments, to allow the text to contain
+   a comment.
+   We expect the *header* to have been patched, adding the missing include.  */
+#if 0
+{ dg-begin-multiline-output "" }
+@@ -1,3 +1,4 @@
++#include <stdio.h>
+ /* This is missing-header-fixit-2.h, for use by
+    missing-header-fixit-2.c  */
+ 
+{ dg-end-multiline-output "" }
+#endif
diff --git a/gcc/testsuite/gcc.dg/missing-header-fixit-4.c b/gcc/testsuite/gcc.dg/missing-header-fixit-4.c
index b6680563dc13..8e4e48d2e43a 100644
--- a/gcc/testsuite/gcc.dg/missing-header-fixit-4.c
+++ b/gcc/testsuite/gcc.dg/missing-header-fixit-4.c
@@ -3,7 +3,7 @@
 #include "empty.h"
 int the_next_line;
 
-/* { dg-options "-fdiagnostics-show-caret -fdiagnostics-show-line-numbers" } */
+/* { dg-options "-fpermissive -fdiagnostics-show-caret -fdiagnostics-show-line-numbers" } */
 
 void test (int i, int j)
 {
diff --git a/gcc/testsuite/gcc.dg/missing-header-fixit-4a.c b/gcc/testsuite/gcc.dg/missing-header-fixit-4a.c
new file mode 100644
index 000000000000..b93061f287b7
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/missing-header-fixit-4a.c
@@ -0,0 +1,27 @@
+/* Example of a fix-it hint that adds a #include directive,
+   adding them after a pre-existing #include directive.  */
+#include "empty.h"
+int the_next_line;
+
+/* { dg-options "-fdiagnostics-show-caret -fdiagnostics-show-line-numbers" } */
+
+void test (int i, int j)
+{
+  printf ("%i of %i\n", i, j); /* { dg-line printf } */
+  /* { dg-error "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);
+      |   ^~~~~~
+   { dg-end-multiline-output "" } */
+  /* { dg-message "include '<stdio.h>' or provide a declaration of 'printf'" "" { target *-*-* } 4 } */
+  /* { dg-begin-multiline-output "" }
+    3 | #include "empty.h"
+  +++ |+#include <stdio.h>
+    4 | int the_next_line;
+   { dg-end-multiline-output "" } */
+}
diff --git a/gcc/testsuite/gcc.dg/missing-header-fixit-5.c b/gcc/testsuite/gcc.dg/missing-header-fixit-5.c
index bf44feb24a9f..c34a47dc286b 100644
--- a/gcc/testsuite/gcc.dg/missing-header-fixit-5.c
+++ b/gcc/testsuite/gcc.dg/missing-header-fixit-5.c
@@ -3,7 +3,7 @@
    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" } */
+/* { dg-options "-fpermissive -fdiagnostics-show-caret -fdiagnostics-show-line-numbers -Wimplicit-function-declaration -Wno-builtin-declaration-mismatch" } */
 
 int
 foo (char *m, int i)
diff --git a/gcc/testsuite/gcc.dg/missing-header-fixit-5a.c b/gcc/testsuite/gcc.dg/missing-header-fixit-5a.c
new file mode 100644
index 000000000000..420cbf7be407
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/missing-header-fixit-5a.c
@@ -0,0 +1,42 @@
+
+/* 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-error "implicit declaration of function" } */
+  /* { dg-begin-multiline-output "" }
+   11 |   if (isdigit (m[0]))
+      |       ^~~~~~~
+     { dg-end-multiline-output "" } */
+  /* { dg-begin-multiline-output "" }
+  +++ |+#include <ctype.h>
+    1 | 
+     { dg-end-multiline-output "" } */
+    {
+      return abs (i); /* { dg-error "implicit declaration of function" } */
+  /* { dg-begin-multiline-output "" }
+   21 |       return abs (i);
+      |              ^~~
+     { dg-end-multiline-output "" } */
+  /* { dg-begin-multiline-output "" }
+  +++ |+#include <stdlib.h>
+    1 | 
+     { dg-end-multiline-output "" } */
+    }
+  else
+    putchar (m[0]); /* { dg-error "implicit declaration of function" } */
+  /* { dg-begin-multiline-output "" }
+   32 |     putchar (m[0]);
+      |     ^~~~~~~
+     { dg-end-multiline-output "" } */
+  /* { dg-begin-multiline-output "" }
+  +++ |+#include <stdio.h>
+    1 | 
+     { dg-end-multiline-output "" } */
+  return i;
+}
diff --git a/gcc/testsuite/gcc.dg/permerror-default.c b/gcc/testsuite/gcc.dg/permerror-default.c
index 5235a4271757..f37f9189e41c 100644
--- a/gcc/testsuite/gcc.dg/permerror-default.c
+++ b/gcc/testsuite/gcc.dg/permerror-default.c
@@ -7,7 +7,7 @@
 void
 implicit_function_declaration (void)
 {
-  f1 (); /* { dg-warning "'f1' \\\[-Wimplicit-function-declaration\\\]" } */
+  f1 (); /* { dg-error "'f1' \\\[-Wimplicit-function-declaration\\\]" } */
 }
 
 extern implicit_int_1; /* { dg-warning "'implicit_int_1' \\\[-Wimplicit-int\\\]" } */
diff --git a/gcc/testsuite/gcc.dg/permerror-system.c b/gcc/testsuite/gcc.dg/permerror-system.c
index 75e08887ef1d..e4da4a99e9a9 100644
--- a/gcc/testsuite/gcc.dg/permerror-system.c
+++ b/gcc/testsuite/gcc.dg/permerror-system.c
@@ -8,6 +8,8 @@
 
 /* These errors come from permerror-default.c.  */
 
+/* { dg-error "'f1' \\\[-Wimplicit-function-declaration\\\]" "" { target *-*-* } 10 } */
+
 /* { dg-error "pointer/integer type mismatch in conditional expression \\\[-Wint-conversion\\\]" "" { target *-*-* } 29 } */
 /* { dg-error "pointer/integer type mismatch in conditional expression \\\[-Wint-conversion\\\]" "" { target *-*-* } 30 } */
 /* { dg-error "passing argument 1 of 'f2' makes pointer from integer without a cast \\\[-Wint-conversion\\\]" "" { target *-*-* } 31 } */
diff --git a/gcc/testsuite/gcc.dg/pr61852.c b/gcc/testsuite/gcc.dg/pr61852.c
index f488aca7ac2f..e669d3c4d397 100644
--- a/gcc/testsuite/gcc.dg/pr61852.c
+++ b/gcc/testsuite/gcc.dg/pr61852.c
@@ -1,10 +1,10 @@
 /* PR c/61852 */
 /* { dg-do compile } */
-/* { dg-options "-Wimplicit-function-declaration" } */
+/* { dg-options "" } */
 
 int
 f (int a)
 {
-  int b = a + a + a + ff (a); /* { dg-warning "23:implicit declaration of function" } */
+  int b = a + a + a + ff (a); /* { dg-error "23:implicit declaration of function" } */
   return b;
 }
diff --git a/gcc/testsuite/gcc.dg/spellcheck-identifiers-1a.c b/gcc/testsuite/gcc.dg/spellcheck-identifiers-1a.c
new file mode 100644
index 000000000000..f50c52b656c4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/spellcheck-identifiers-1a.c
@@ -0,0 +1,136 @@
+/* { dg-do compile } */
+/* { dg-options "-fdiagnostics-show-caret" } */
+
+typedef struct GtkWidget { int dummy; } GtkWidget;
+
+extern void gtk_widget_show_all (GtkWidget *w);
+
+void
+test_1 (GtkWidget *w)
+{
+  gtk_widget_showall (w); /* { dg-error "3: implicit declaration of function .gtk_widget_showall.; did you mean .gtk_widget_show_all.?" } */
+  /* { dg-begin-multiline-output "" }
+   gtk_widget_showall (w);
+   ^~~~~~~~~~~~~~~~~~
+   gtk_widget_show_all
+   { dg-end-multiline-output "" } */
+
+  /* Ensure we don't try to suggest "gtk_widget_showall" for subsequent
+     corrections.  */
+  gtk_widget_showall_ (w); /* { dg-error "3: implicit declaration of function .gtk_widget_showall_.; did you mean .gtk_widget_show_all.?" } */
+  /* { dg-begin-multiline-output "" }
+   gtk_widget_showall_ (w);
+   ^~~~~~~~~~~~~~~~~~~
+   gtk_widget_show_all
+   { dg-end-multiline-output "" } */
+
+  GtkWidgetShowAll (w); /* { dg-error "3: implicit declaration of function .GtkWidgetShowAll.; did you mean .gtk_widget_show_all.?" } */
+  /* { dg-begin-multiline-output "" }
+   GtkWidgetShowAll (w);
+   ^~~~~~~~~~~~~~~~
+   gtk_widget_show_all
+   { dg-end-multiline-output "" } */
+}
+
+int
+test_2 (int param)
+{
+  return parma * parma; /* { dg-error "10: .parma. undeclared .first use in this function.; did you mean .param." } */
+  /* { dg-begin-multiline-output "" }
+   return parma * parma;
+          ^~~~~
+          param
+   { dg-end-multiline-output "" } */
+}
+
+#define MACRO(X) ((X))
+
+int
+test_3 (int i)
+{
+  return MACRAME (i); /* { dg-error "10: implicit declaration of function .MACRAME.; did you mean .MACRO.?" } */
+  /* { dg-begin-multiline-output "" }
+   return MACRAME (i);
+          ^~~~~~~
+          MACRO
+   { dg-end-multiline-output "" } */
+}
+
+#define IDENTIFIER_POINTER(X) ((X))
+
+int
+test_4 (int node)
+{
+  return IDENTIFIER_PTR (node); /* { dg-error "10: implicit declaration of function .IDENTIFIER_PTR.; did you mean .IDENTIFIER_POINTER.?" } */
+  /* { dg-begin-multiline-output "" }
+   return IDENTIFIER_PTR (node);
+          ^~~~~~~~~~~~~~
+          IDENTIFIER_POINTER
+   { dg-end-multiline-output "" } */
+}
+
+
+int
+test_5 (void)
+{
+  return __LINE_; /* { dg-error "10: .__LINE_. undeclared .first use in this function.; did you mean .__LINE__." } */
+  /* { dg-begin-multiline-output "" }
+   return __LINE_;
+          ^~~~~~~
+          __LINE__
+   { dg-end-multiline-output "" } */
+}
+
+#define MAX_ITEMS 100
+int array[MAX_ITEM]; /* { dg-error "11: .MAX_ITEM. undeclared here .not in a function.; did you mean .MAX_ITEMS." } */
+  /* { dg-begin-multiline-output "" }
+ int array[MAX_ITEM];
+           ^~~~~~~~
+           MAX_ITEMS
+   { dg-end-multiline-output "" } */
+
+
+enum foo {
+  FOO_FIRST,
+  FOO_SECOND
+};
+
+int
+test_6 (enum foo f)
+{
+  switch (f)
+    {
+    case FOO_FURST: /* { dg-error "10: .FOO_FURST. undeclared .first use in this function.; did you mean .FOO_FIRST." } */
+      break;
+  /* { dg-begin-multiline-output "" }
+     case FOO_FURST:
+          ^~~~~~~~~
+          FOO_FIRST
+   { dg-end-multiline-output "" } */
+
+    case FOO_SECCOND: /* { dg-error "10: .FOO_SECCOND. undeclared .first use in this function.; did you mean .FOO_SECOND." } */
+      break;
+  /* { dg-begin-multiline-output "" }
+     case FOO_SECCOND:
+          ^~~~~~~~~~~
+          FOO_SECOND
+   { dg-end-multiline-output "" } */
+
+    default:
+      break;
+    }
+}
+
+int snprintf (char *, __SIZE_TYPE__, const char *, ...);
+
+void
+test_7 (int i, int j)
+{
+  int buffer[100];
+  snprint (buffer, 100, "%i of %i", i, j); /* { dg-error "3: implicit declaration of function .snprint.; did you mean .snprintf.." } */
+  /* { dg-begin-multiline-output "" }
+   snprint (buffer, 100, "%i of %i", i, j);
+   ^~~~~~~
+   snprintf
+   { dg-end-multiline-output "" } */
+}
diff --git a/gcc/testsuite/gcc.dg/spellcheck-identifiers-2.c b/gcc/testsuite/gcc.dg/spellcheck-identifiers-2.c
index ad6e9d3191d4..b49709dc528d 100644
--- a/gcc/testsuite/gcc.dg/spellcheck-identifiers-2.c
+++ b/gcc/testsuite/gcc.dg/spellcheck-identifiers-2.c
@@ -1,7 +1,7 @@
 /* PR c/71858 */
 /* Make sure anticipated builtins are not considered before they are declared.  */
 /* { dg-do compile } */
-/* { dg-options "-Wimplicit-function-declaration -fdiagnostics-show-caret" } */
+/* { dg-options "-fpermissive -Wimplicit-function-declaration -fdiagnostics-show-caret" } */
 
 int sscafn (const char *, const char *, ...);
 
diff --git a/gcc/testsuite/gcc.dg/spellcheck-identifiers-2a.c b/gcc/testsuite/gcc.dg/spellcheck-identifiers-2a.c
new file mode 100644
index 000000000000..1a3e68c703c4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/spellcheck-identifiers-2a.c
@@ -0,0 +1,33 @@
+/* PR c/71858 */
+/* Make sure anticipated builtins are not considered before they are declared.  */
+/* { dg-do compile } */
+/* { dg-options "-fdiagnostics-show-caret" } */
+
+int sscafn (const char *, const char *, ...);
+
+int
+test_1 (const char *p)
+{
+  int i;
+  return ssacnf (p, "%d", &i); /* { dg-error "10: implicit declaration of function .ssacnf.; did you mean .sscafn.?" } */
+  /* { dg-begin-multiline-output "" }
+   return ssacnf (p, "%d", &i);
+          ^~~~~~
+          sscafn
+   { dg-end-multiline-output "" } */
+}
+
+int scafn (const char *, ...);
+int scanf (const char *, ...);
+
+int
+test_2 (void)
+{
+  int i;
+  return sacnf ("%d", &i); /* { dg-error "10: implicit declaration of function .sacnf.; did you mean .scanf.?" } */
+  /* { dg-begin-multiline-output "" }
+   return sacnf ("%d", &i);
+          ^~~~~
+          scanf
+   { dg-end-multiline-output "" } */
+}
diff --git a/gcc/testsuite/gcc.dg/spellcheck-identifiers-3.c b/gcc/testsuite/gcc.dg/spellcheck-identifiers-3.c
index 94f4078d0e82..0b5982fa705a 100644
--- a/gcc/testsuite/gcc.dg/spellcheck-identifiers-3.c
+++ b/gcc/testsuite/gcc.dg/spellcheck-identifiers-3.c
@@ -1,7 +1,7 @@
 /* PR c/71858 */
 /* Only consider function names, function pointers and macros for implicit function declarations.  */
 /* { dg-do compile } */
-/* { dg-options "-Wimplicit-function-declaration -fdiagnostics-show-caret" } */
+/* { dg-options "-fpermissive -Wimplicit-function-declaration -fdiagnostics-show-caret" } */
 
 void fn1abcd (void);
 
diff --git a/gcc/testsuite/gcc.dg/spellcheck-identifiers-3a.c b/gcc/testsuite/gcc.dg/spellcheck-identifiers-3a.c
new file mode 100644
index 000000000000..0c0a19e547bf
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/spellcheck-identifiers-3a.c
@@ -0,0 +1,45 @@
+/* PR c/71858 */
+/* Only consider function names, function pointers and macros for implicit function declarations.  */
+/* { dg-do compile } */
+/* { dg-options "-fdiagnostics-show-caret" } */
+
+void fn1abcd (void);
+
+void
+test_1 (int fn1bacd)
+{
+  fn1badc (); /* { dg-error "3: implicit declaration of function .fn1badc.; did you mean .fn1abcd.?" } */
+  /* { dg-begin-multiline-output "" }
+   fn1badc ();
+   ^~~~~~~
+   fn1abcd
+   { dg-end-multiline-output "" } */
+}
+
+void fn2efgh (void);
+void (*fn2efhg) (void);
+
+void
+test_2 (void)
+{
+  fn2fehg (); /* { dg-error "3: implicit declaration of function .fn2fehg.; did you mean .fn2efhg.?" } */
+  /* { dg-begin-multiline-output "" }
+   fn2fehg ();
+   ^~~~~~~
+   fn2efhg
+   { dg-end-multiline-output "" } */
+}
+
+void fn3ijkl (void);
+typedef int fn3ijlk;
+
+void
+test_3 (void)
+{
+  fn3jilk (); /* { dg-error "3: implicit declaration of function .fn3jilk.; did you mean .fn3ijkl.?" } */
+  /* { dg-begin-multiline-output "" }
+   fn3jilk ();
+   ^~~~~~~
+   fn3ijkl
+   { dg-end-multiline-output "" } */
+}
diff --git a/gcc/testsuite/gcc.dg/spellcheck-identifiers-4.c b/gcc/testsuite/gcc.dg/spellcheck-identifiers-4.c
index f9b7d8d0cab8..f24d863a15c6 100644
--- a/gcc/testsuite/gcc.dg/spellcheck-identifiers-4.c
+++ b/gcc/testsuite/gcc.dg/spellcheck-identifiers-4.c
@@ -1,4 +1,4 @@
-/* { dg-options "-Wimplicit-function-declaration" } */
+/* { dg-options "-fpermissive -Wimplicit-function-declaration" } */
 
 extern double sqrt (double);
 
diff --git a/gcc/testsuite/gcc.dg/spellcheck-identifiers-4a.c b/gcc/testsuite/gcc.dg/spellcheck-identifiers-4a.c
new file mode 100644
index 000000000000..33a6b4220f49
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/spellcheck-identifiers-4a.c
@@ -0,0 +1,10 @@
+/* { dg-options "" } */
+
+extern double sqrt (double);
+
+void test (float pf, float inff)
+{
+  assert (pf == inff); /* { dg-bogus "sqrt" } */
+  /* { dg-error "implicit declaration of function 'assert'" "" { target *-*-* } .-1 } */
+  /* { dg-message "header '<assert.h>'" "" { target *-*-* } .-2 } */
+}
diff --git a/gcc/testsuite/gcc.dg/spellcheck-identifiers.c b/gcc/testsuite/gcc.dg/spellcheck-identifiers.c
index 063e3f9eda19..cd632c6a064f 100644
--- a/gcc/testsuite/gcc.dg/spellcheck-identifiers.c
+++ b/gcc/testsuite/gcc.dg/spellcheck-identifiers.c
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-Wimplicit-function-declaration -fdiagnostics-show-caret" } */
+/* { dg-options "-fpermissive -fdiagnostics-show-caret" } */
 
 typedef struct GtkWidget { int dummy; } GtkWidget;
 
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/ld1sh_gather_1.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/ld1sh_gather_1.c
index 91f37f6a53d7..c9f49b6e73da 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/ld1sh_gather_1.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/ld1sh_gather_1.c
@@ -11,7 +11,7 @@ f1 (svbool_t pg, short *s16_ptr, unsigned short *u16_ptr,
     svint32_t s32, svuint32_t u32, svfloat32_t f32,
     svint64_t s64, svuint64_t u64, svfloat64_t f64, struct s s)
 {
-  svld1sh_gather_index (pg, s16_ptr, s32); /* { dg-warning {implicit declaration of function 'svld1sh_gather_index'; did you mean 'svld1_gather_index'} } */
+  svld1sh_gather_index (pg, s16_ptr, s32); /* { dg-error {implicit declaration of function 'svld1sh_gather_index'; did you mean 'svld1_gather_index'} } */
   svld1sh_gather_index_u32 (pg, s16_ptr); /* { dg-error {too few arguments to function 'svld1sh_gather_index_u32'} } */
   svld1sh_gather_index_u32 (pg, s16_ptr, s32, 0); /* { dg-error {too many arguments to function 'svld1sh_gather_index_u32'} } */
   svld1sh_gather_index_u32 (pg, u16_ptr, s32); /* { dg-warning {pointer targets in passing argument 2 of 'svld1sh_gather_s32index_u32' differ in signedness} } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/load_ext_gather_index_1.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/load_ext_gather_index_1.c
index 91f37f6a53d7..c9f49b6e73da 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/load_ext_gather_index_1.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/load_ext_gather_index_1.c
@@ -11,7 +11,7 @@ f1 (svbool_t pg, short *s16_ptr, unsigned short *u16_ptr,
     svint32_t s32, svuint32_t u32, svfloat32_t f32,
     svint64_t s64, svuint64_t u64, svfloat64_t f64, struct s s)
 {
-  svld1sh_gather_index (pg, s16_ptr, s32); /* { dg-warning {implicit declaration of function 'svld1sh_gather_index'; did you mean 'svld1_gather_index'} } */
+  svld1sh_gather_index (pg, s16_ptr, s32); /* { dg-error {implicit declaration of function 'svld1sh_gather_index'; did you mean 'svld1_gather_index'} } */
   svld1sh_gather_index_u32 (pg, s16_ptr); /* { dg-error {too few arguments to function 'svld1sh_gather_index_u32'} } */
   svld1sh_gather_index_u32 (pg, s16_ptr, s32, 0); /* { dg-error {too many arguments to function 'svld1sh_gather_index_u32'} } */
   svld1sh_gather_index_u32 (pg, u16_ptr, s32); /* { dg-warning {pointer targets in passing argument 2 of 'svld1sh_gather_s32index_u32' differ in signedness} } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/load_ext_gather_index_restricted_1.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/load_ext_gather_index_restricted_1.c
index c47e5411c20c..a2dcf9a041bd 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/load_ext_gather_index_restricted_1.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/load_ext_gather_index_restricted_1.c
@@ -13,7 +13,7 @@ f1 (svbool_t pg, short *s16_ptr, unsigned short *u16_ptr,
     svint32_t s32, svuint32_t u32, svfloat32_t f32,
     svint64_t s64, svuint64_t u64, svfloat64_t f64, struct s s)
 {
-  svldnt1sh_gather_index (pg, s16_ptr, s64); /* { dg-warning {implicit declaration of function 'svldnt1sh_gather_index'; did you mean 'svldnt1_gather_index'} } */
+  svldnt1sh_gather_index (pg, s16_ptr, s64); /* { dg-error {implicit declaration of function 'svldnt1sh_gather_index'; did you mean 'svldnt1_gather_index'} } */
   svldnt1sh_gather_index_u64 (pg, s16_ptr); /* { dg-error {too few arguments to function 'svldnt1sh_gather_index_u64'} } */
   svldnt1sh_gather_index_u64 (pg, s16_ptr, s64, 0); /* { dg-error {too many arguments to function 'svldnt1sh_gather_index_u64'} } */
   svldnt1sh_gather_index_u64 (pg, u16_ptr, s64); /* { dg-warning {pointer targets in passing argument 2 of 'svldnt1sh_gather_s64index_u64' differ in signedness} } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/load_ext_gather_offset_1.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/load_ext_gather_offset_1.c
index dae4d0ce120a..cd849f899410 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/load_ext_gather_offset_1.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/load_ext_gather_offset_1.c
@@ -11,7 +11,7 @@ f1 (svbool_t pg, signed char *s8_ptr, short *s16_ptr,
     svint32_t s32, svuint32_t u32, svfloat32_t f32,
     svint64_t s64, svuint64_t u64, svfloat64_t f64, struct s s)
 {
-  svld1sb_gather_offset (pg, s8_ptr, s32); /* { dg-warning {implicit declaration of function 'svld1sb_gather_offset'; did you mean 'svld1_gather_offset'} } */
+  svld1sb_gather_offset (pg, s8_ptr, s32); /* { dg-error {implicit declaration of function 'svld1sb_gather_offset'; did you mean 'svld1_gather_offset'} } */
   svld1sb_gather_offset_s32 (pg, s8_ptr); /* { dg-error {too few arguments to function 'svld1sb_gather_offset_s32'} } */
   svld1sb_gather_offset_s32 (pg, s8_ptr, s32, 0); /* { dg-error {too many arguments to function 'svld1sb_gather_offset_s32'} } */
   svld1sb_gather_offset_s32 (pg, s16_ptr, s32); /* { dg-warning {passing argument 2 of 'svld1sb_gather_s32offset_s32' from incompatible pointer type} } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/load_ext_gather_offset_2.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/load_ext_gather_offset_2.c
index 1bc66977cdf9..850eecf99f61 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/load_ext_gather_offset_2.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/load_ext_gather_offset_2.c
@@ -11,7 +11,7 @@ f1 (svbool_t pg, signed char *s8_ptr, short *s16_ptr,
     svint32_t s32, svuint32_t u32, svfloat32_t f32,
     svint64_t s64, svuint64_t u64, svfloat64_t f64, struct s s)
 {
-  svld1sb_gather_offset (pg, s8_ptr, s32); /* { dg-warning {implicit declaration of function 'svld1sb_gather_offset'; did you mean 'svld1_gather_offset'} } */
+  svld1sb_gather_offset (pg, s8_ptr, s32); /* { dg-error {implicit declaration of function 'svld1sb_gather_offset'; did you mean 'svld1_gather_offset'} } */
   svld1sb_gather_offset_u32 (pg, s8_ptr); /* { dg-error {too few arguments to function 'svld1sb_gather_offset_u32'} } */
   svld1sb_gather_offset_u32 (pg, s8_ptr, s32, 0); /* { dg-error {too many arguments to function 'svld1sb_gather_offset_u32'} } */
   svld1sb_gather_offset_u32 (pg, s16_ptr, s32); /* { dg-warning {passing argument 2 of 'svld1sb_gather_s32offset_u32' from incompatible pointer type} } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/load_ext_gather_offset_3.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/load_ext_gather_offset_3.c
index 6522889dbe79..93a728593f9e 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/load_ext_gather_offset_3.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/load_ext_gather_offset_3.c
@@ -11,7 +11,7 @@ f1 (svbool_t pg, signed char *s8_ptr, short *s16_ptr,
     svint32_t s32, svuint32_t u32, svfloat32_t f32,
     svint64_t s64, svuint64_t u64, svfloat64_t f64, struct s s)
 {
-  svld1sb_gather_offset (pg, s8_ptr, s64); /* { dg-warning {implicit declaration of function 'svld1sb_gather_offset'; did you mean 'svld1_gather_offset'} } */
+  svld1sb_gather_offset (pg, s8_ptr, s64); /* { dg-error {implicit declaration of function 'svld1sb_gather_offset'; did you mean 'svld1_gather_offset'} } */
   svld1sb_gather_offset_s64 (pg, s8_ptr); /* { dg-error {too few arguments to function 'svld1sb_gather_offset_s64'} } */
   svld1sb_gather_offset_s64 (pg, s8_ptr, s64, 0); /* { dg-error {too many arguments to function 'svld1sb_gather_offset_s64'} } */
   svld1sb_gather_offset_s64 (pg, s16_ptr, s64); /* { dg-warning {passing argument 2 of 'svld1sb_gather_s64offset_s64' from incompatible pointer type} } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/load_ext_gather_offset_4.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/load_ext_gather_offset_4.c
index 025621989099..d54dc8eafab3 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/load_ext_gather_offset_4.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/load_ext_gather_offset_4.c
@@ -11,7 +11,7 @@ f1 (svbool_t pg, signed char *s8_ptr, short *s16_ptr,
     svint32_t s32, svuint32_t u32, svfloat32_t f32,
     svint64_t s64, svuint64_t u64, svfloat64_t f64, struct s s)
 {
-  svld1sb_gather_offset (pg, s8_ptr, s64); /* { dg-warning {implicit declaration of function 'svld1sb_gather_offset'; did you mean 'svld1_gather_offset'} } */
+  svld1sb_gather_offset (pg, s8_ptr, s64); /* { dg-error {implicit declaration of function 'svld1sb_gather_offset'; did you mean 'svld1_gather_offset'} } */
   svld1sb_gather_offset_u64 (pg, s8_ptr); /* { dg-error {too few arguments to function 'svld1sb_gather_offset_u64'} } */
   svld1sb_gather_offset_u64 (pg, s8_ptr, s64, 0); /* { dg-error {too many arguments to function 'svld1sb_gather_offset_u64'} } */
   svld1sb_gather_offset_u64 (pg, s16_ptr, s64); /* { dg-warning {passing argument 2 of 'svld1sb_gather_s64offset_u64' from incompatible pointer type} } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/load_ext_gather_offset_5.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/load_ext_gather_offset_5.c
index 8d57aa020ead..3b521d5c1416 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/load_ext_gather_offset_5.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/load_ext_gather_offset_5.c
@@ -11,7 +11,7 @@ f1 (svbool_t pg, unsigned char *s8_ptr, unsigned short *s16_ptr,
     svint32_t s32, svuint32_t u32, svfloat32_t f32,
     svint64_t s64, svuint64_t u64, svfloat64_t f64, struct s s)
 {
-  svld1ub_gather_offset (pg, s8_ptr, s32); /* { dg-warning {implicit declaration of function 'svld1ub_gather_offset'; did you mean 'svld1_gather_offset'} } */
+  svld1ub_gather_offset (pg, s8_ptr, s32); /* { dg-error {implicit declaration of function 'svld1ub_gather_offset'; did you mean 'svld1_gather_offset'} } */
   svld1ub_gather_offset_s32 (pg, s8_ptr); /* { dg-error {too few arguments to function 'svld1ub_gather_offset_s32'} } */
   svld1ub_gather_offset_s32 (pg, s8_ptr, s32, 0); /* { dg-error {too many arguments to function 'svld1ub_gather_offset_s32'} } */
   svld1ub_gather_offset_s32 (pg, s16_ptr, s32); /* { dg-warning {passing argument 2 of 'svld1ub_gather_s32offset_s32' from incompatible pointer type} } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/load_ext_gather_offset_restricted_1.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/load_ext_gather_offset_restricted_1.c
index 353fec2d39d0..96d8ad550743 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/load_ext_gather_offset_restricted_1.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/load_ext_gather_offset_restricted_1.c
@@ -13,7 +13,7 @@ f1 (svbool_t pg, signed char *s8_ptr, short *s16_ptr,
     svint32_t s32, svuint32_t u32, svfloat32_t f32,
     svint64_t s64, svuint64_t u64, svfloat64_t f64, struct s s)
 {
-  svldnt1sb_gather_offset (pg, s8_ptr, s32); /* { dg-warning {implicit declaration of function 'svldnt1sb_gather_offset'; did you mean 'svldnt1_gather_offset'} } */
+  svldnt1sb_gather_offset (pg, s8_ptr, s32); /* { dg-error {implicit declaration of function 'svldnt1sb_gather_offset'; did you mean 'svldnt1_gather_offset'} } */
   svldnt1sb_gather_offset_s32 (pg, s8_ptr); /* { dg-error {too few arguments to function 'svldnt1sb_gather_offset_s32'} } */
   svldnt1sb_gather_offset_s32 (pg, s8_ptr, u32, 0); /* { dg-error {too many arguments to function 'svldnt1sb_gather_offset_s32'} } */
   svldnt1sb_gather_offset_s32 (pg, s16_ptr, u32); /* { dg-warning {passing argument 2 of 'svldnt1sb_gather_u32offset_s32' from incompatible pointer type} } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/load_ext_gather_offset_restricted_2.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/load_ext_gather_offset_restricted_2.c
index e22b3dd8fea3..25ce7268a1e1 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/load_ext_gather_offset_restricted_2.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/load_ext_gather_offset_restricted_2.c
@@ -13,7 +13,7 @@ f1 (svbool_t pg, signed char *s8_ptr, short *s16_ptr,
     svint32_t s32, svuint32_t u32, svfloat32_t f32,
     svint64_t s64, svuint64_t u64, svfloat64_t f64, struct s s)
 {
-  svldnt1sb_gather_offset (pg, s8_ptr, s32); /* { dg-warning {implicit declaration of function 'svldnt1sb_gather_offset'; did you mean 'svldnt1_gather_offset'} } */
+  svldnt1sb_gather_offset (pg, s8_ptr, s32); /* { dg-error {implicit declaration of function 'svldnt1sb_gather_offset'; did you mean 'svldnt1_gather_offset'} } */
   svldnt1sb_gather_offset_u32 (pg, s8_ptr); /* { dg-error {too few arguments to function 'svldnt1sb_gather_offset_u32'} } */
   svldnt1sb_gather_offset_u32 (pg, s8_ptr, u32, 0); /* { dg-error {too many arguments to function 'svldnt1sb_gather_offset_u32'} } */
   svldnt1sb_gather_offset_u32 (pg, s16_ptr, u32); /* { dg-warning {passing argument 2 of 'svldnt1sb_gather_u32offset_u32' from incompatible pointer type} } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/load_ext_gather_offset_restricted_3.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/load_ext_gather_offset_restricted_3.c
index 73b5715c3685..04465f251b13 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/load_ext_gather_offset_restricted_3.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/load_ext_gather_offset_restricted_3.c
@@ -13,7 +13,7 @@ f1 (svbool_t pg, signed char *s8_ptr, short *s16_ptr,
     svint32_t s32, svuint32_t u32, svfloat32_t f32,
     svint64_t s64, svuint64_t u64, svfloat64_t f64, struct s s)
 {
-  svldnt1sb_gather_offset (pg, s8_ptr, s64); /* { dg-warning {implicit declaration of function 'svldnt1sb_gather_offset'; did you mean 'svldnt1_gather_offset'} } */
+  svldnt1sb_gather_offset (pg, s8_ptr, s64); /* { dg-error {implicit declaration of function 'svldnt1sb_gather_offset'; did you mean 'svldnt1_gather_offset'} } */
   svldnt1sb_gather_offset_s64 (pg, s8_ptr); /* { dg-error {too few arguments to function 'svldnt1sb_gather_offset_s64'} } */
   svldnt1sb_gather_offset_s64 (pg, s8_ptr, s64, 0); /* { dg-error {too many arguments to function 'svldnt1sb_gather_offset_s64'} } */
   svldnt1sb_gather_offset_s64 (pg, s16_ptr, s64); /* { dg-warning {passing argument 2 of 'svldnt1sb_gather_s64offset_s64' from incompatible pointer type} } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/load_ext_gather_offset_restricted_4.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/load_ext_gather_offset_restricted_4.c
index e2ceb18bc422..479be66996df 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/load_ext_gather_offset_restricted_4.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/load_ext_gather_offset_restricted_4.c
@@ -13,7 +13,7 @@ f1 (svbool_t pg, signed char *s8_ptr, short *s16_ptr,
     svint32_t s32, svuint32_t u32, svfloat32_t f32,
     svint64_t s64, svuint64_t u64, svfloat64_t f64, struct s s)
 {
-  svldnt1sb_gather_offset (pg, s8_ptr, s64); /* { dg-warning {implicit declaration of function 'svldnt1sb_gather_offset'; did you mean 'svldnt1_gather_offset'} } */
+  svldnt1sb_gather_offset (pg, s8_ptr, s64); /* { dg-error {implicit declaration of function 'svldnt1sb_gather_offset'; did you mean 'svldnt1_gather_offset'} } */
   svldnt1sb_gather_offset_u64 (pg, s8_ptr); /* { dg-error {too few arguments to function 'svldnt1sb_gather_offset_u64'} } */
   svldnt1sb_gather_offset_u64 (pg, s8_ptr, s64, 0); /* { dg-error {too many arguments to function 'svldnt1sb_gather_offset_u64'} } */
   svldnt1sb_gather_offset_u64 (pg, s16_ptr, s64); /* { dg-warning {passing argument 2 of 'svldnt1sb_gather_s64offset_u64' from incompatible pointer type} } */
-- 
GitLab