public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH v2 0/8] Turn some C warnings into errors by default
@ 2023-11-14 17:50 Florian Weimer
  2023-11-14 17:50 ` [PATCH v2 1/8] Add tests for validating future C permerrors Florian Weimer
                   ` (8 more replies)
  0 siblings, 9 replies; 17+ messages in thread
From: Florian Weimer @ 2023-11-14 17:50 UTC (permalink / raw)
  To: gcc-patches; +Cc: jason, jeffreyalaw, joseph, sam

This new series covers:

  -Wint-conversion
  -Wimplicit-function-declaration
  -Wimplicit-int
  -Wreturn-mismatch
  -Wincompatible-pointer-types
  -Wdeclaration-missing-parameter-type (new)

There are now gcc.dg/permerror-*.c tests which track the graduation of
warnings to errors.

It turns out that pedpermerror was indeed unnecessary, and I can use
permerror_opt directly (or DK_PERMERROR in case I call one of the
low-level functions).

While working on this I found out that -Wimplicit-int is mostly
ineffective in system headers, so I fixed that for consistency.  I also
added a new -Wdeclaration-missing-parameter-type warning because missing
types in parameter lists in function declarations (as opposed to
old-style function definitions) are not covered by -Wimplicit-int, and
probably shouldn't be because the omitted types are not necessarily int.

This still depends on a couple of unreviewed patches.  In particular, I
do not want to break the AArch64 bootstrap, so the first patch looks
like a blocker.

  [PATCH] aarch64: Avoid -Wincompatible-pointer-types warning in Linux unwinder
  <https://inbox.sourceware.org/gcc-patches/874jht5tsq.fsf@oldenburg.str.redhat.com/>

  [PATCH] aarch64: Call named function in gcc.target/aarch64/aapcs64/ice_1.c
  <https://inbox.sourceware.org/gcc-patches/87r0kx6eez.fsf@oldenburg.str.redhat.com/>

  [PATCH] gm2: Add missing declaration of m2pim_M2RTS_Terminate to test
  <https://inbox.sourceware.org/gcc-patches/874jhp3nwf.fsf@oldenburg.str.redhat.com/>

Thanks,
Florian


Florian Weimer (8):
  Add tests for validating future C permerrors
  c: Turn int-conversion warnings into permerrors
  c: Turn -Wimplicit-function-declaration into a permerror
  c: Turn -Wimplicit-int into a permerror
  c: Do not ignore some forms of -Wimplicit-int in system headers
  c: Turn -Wreturn-mismatch into a permerror
  c: Turn -Wincompatible-pointer-types into a permerror
  c: Add new -Wdeclaration-missing-parameter-type permerror

 gcc/c-family/c.opt                            |   4 +
 gcc/c/c-decl.cc                               |  71 +++----
 gcc/c/c-typeck.cc                             | 164 ++++++++-------
 gcc/doc/invoke.texi                           |  50 ++++-
 gcc/testsuite/c-c++-common/pr77624-1.c        |   4 +-
 .../c-c++-common/spellcheck-reserved.c        |   4 +-
 gcc/testsuite/gcc.dg/20030906-1.c             |   2 +-
 gcc/testsuite/gcc.dg/20030906-1a.c            |  21 ++
 gcc/testsuite/gcc.dg/20030906-2.c             |   2 +-
 gcc/testsuite/gcc.dg/20030906-2a.c            |  21 ++
 .../Wimplicit-function-declaration-c99-2.c    |   7 +
 .../Wimplicit-function-declaration-c99.c      |   2 +-
 gcc/testsuite/gcc.dg/Wimplicit-int-1.c        |   2 +-
 gcc/testsuite/gcc.dg/Wimplicit-int-1a.c       |  11 ++
 gcc/testsuite/gcc.dg/Wimplicit-int-4.c        |   2 +-
 gcc/testsuite/gcc.dg/Wimplicit-int-4a.c       |  11 ++
 .../gcc.dg/Wincompatible-pointer-types-2.c    |   2 +-
 .../gcc.dg/Wincompatible-pointer-types-5.c    |  10 +
 gcc/testsuite/gcc.dg/Wint-conversion-2.c      |   2 +-
 gcc/testsuite/gcc.dg/Wint-conversion-3.c      |   2 +-
 gcc/testsuite/gcc.dg/Wint-conversion-4.c      |  14 ++
 gcc/testsuite/gcc.dg/Wreturn-mismatch-1.c     |   2 +-
 gcc/testsuite/gcc.dg/Wreturn-mismatch-1a.c    |  40 ++++
 gcc/testsuite/gcc.dg/Wreturn-mismatch-2.c     |   2 +-
 gcc/testsuite/gcc.dg/Wreturn-mismatch-2a.c    |  41 ++++
 gcc/testsuite/gcc.dg/anon-struct-11.c         |   5 +-
 gcc/testsuite/gcc.dg/anon-struct-11a.c        | 111 +++++++++++
 gcc/testsuite/gcc.dg/anon-struct-13.c         |   2 +-
 gcc/testsuite/gcc.dg/anon-struct-13a.c        |  76 +++++++
 gcc/testsuite/gcc.dg/assign-warn-1.c          |   2 +-
 gcc/testsuite/gcc.dg/assign-warn-4.c          |  21 ++
 .../gcc.dg/builtin-arith-overflow-4.c         |   2 +-
 .../gcc.dg/builtin-arith-overflow-4a.c        |  43 ++++
 gcc/testsuite/gcc.dg/c23-qual-4.c             |   6 +-
 gcc/testsuite/gcc.dg/dfp/composite-type-2.c   |  58 ++++++
 gcc/testsuite/gcc.dg/dfp/composite-type.c     |   2 +-
 gcc/testsuite/gcc.dg/diag-aka-1.c             |   2 +-
 gcc/testsuite/gcc.dg/diag-aka-1a.c            |  29 +++
 .../gcc.dg/diagnostic-range-bad-return-2.c    |  52 +++++
 .../gcc.dg/diagnostic-range-bad-return.c      |   2 +-
 gcc/testsuite/gcc.dg/diagnostic-types-1.c     |   2 +-
 gcc/testsuite/gcc.dg/diagnostic-types-2.c     |  24 +++
 gcc/testsuite/gcc.dg/enum-compat-1.c          |   2 +-
 gcc/testsuite/gcc.dg/enum-compat-2.c          |  32 +++
 gcc/testsuite/gcc.dg/func-ptr-conv-1.c        |   2 +-
 gcc/testsuite/gcc.dg/func-ptr-conv-2.c        |  56 ++++++
 gcc/testsuite/gcc.dg/gnu23-attr-syntax-2.c    |   2 +-
 gcc/testsuite/gcc.dg/gnu23-attr-syntax-3.c    |  17 ++
 gcc/testsuite/gcc.dg/gomp/pr35738-2.c         |  18 ++
 gcc/testsuite/gcc.dg/gomp/pr35738.c           |   2 +-
 gcc/testsuite/gcc.dg/init-bad-7.c             |   2 +-
 gcc/testsuite/gcc.dg/init-bad-7a.c            |  12 ++
 gcc/testsuite/gcc.dg/init-excess-3.c          |   4 +-
 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.dg/noncompile/incomplete-3.c          |   2 +-
 gcc/testsuite/gcc.dg/noncompile/pr79758-2.c   |   6 +
 gcc/testsuite/gcc.dg/noncompile/pr79758.c     |   1 +
 gcc/testsuite/gcc.dg/overflow-warn-1.c        |   4 +-
 gcc/testsuite/gcc.dg/overflow-warn-3.c        |   4 +-
 gcc/testsuite/gcc.dg/param-type-mismatch-2.c  | 187 ++++++++++++++++++
 gcc/testsuite/gcc.dg/param-type-mismatch.c    |   2 +-
 gcc/testsuite/gcc.dg/permerror-default.c      |  85 ++++++++
 gcc/testsuite/gcc.dg/permerror-fpermissive.c  |  85 ++++++++
 .../gcc.dg/permerror-gnu89-pedantic.c         |  85 ++++++++
 gcc/testsuite/gcc.dg/permerror-gnu89.c        |  85 ++++++++
 gcc/testsuite/gcc.dg/permerror-noerror.c      |  85 ++++++++
 gcc/testsuite/gcc.dg/permerror-pedantic.c     |  85 ++++++++
 gcc/testsuite/gcc.dg/permerror-system.c       |  45 +++++
 gcc/testsuite/gcc.dg/pointer-array-atomic-2.c |  60 ++++++
 gcc/testsuite/gcc.dg/pointer-array-atomic.c   |   2 +-
 gcc/testsuite/gcc.dg/pointer-array-quals-1.c  |   6 +-
 gcc/testsuite/gcc.dg/pr105635-2.c             |  11 ++
 gcc/testsuite/gcc.dg/pr105635.c               |   2 +-
 gcc/testsuite/gcc.dg/pr23075-2.c              |  14 ++
 gcc/testsuite/gcc.dg/pr23075.c                |   2 +-
 gcc/testsuite/gcc.dg/pr29521-a.c              |  15 ++
 gcc/testsuite/gcc.dg/pr29521.c                |   2 +-
 gcc/testsuite/gcc.dg/pr61162-2.c              |   2 +-
 gcc/testsuite/gcc.dg/pr61162-3.c              |  13 ++
 gcc/testsuite/gcc.dg/pr61852.c                |   4 +-
 gcc/testsuite/gcc.dg/pr67730-a.c              |  11 ++
 gcc/testsuite/gcc.dg/pr67730.c                |   2 +-
 gcc/testsuite/gcc.dg/spec-barrier-3.c         |   2 +-
 gcc/testsuite/gcc.dg/spec-barrier-3a.c        |  13 ++
 .../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 +-
 gcc/testsuite/gcc.dg/transparent-union-1.c    |   2 +-
 gcc/testsuite/gcc.dg/transparent-union-1a.c   |  85 ++++++++
 .../gcc.target/aarch64/acle/memtag_2.c        |   4 +-
 .../gcc.target/aarch64/acle/memtag_2a.c       |  71 +++++++
 .../sve/acle/general-c/ld1sh_gather_1.c       |   2 +-
 .../aarch64/sve/acle/general-c/load_2.c       |   4 +-
 .../aarch64/sve/acle/general-c/load_3.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 |   4 +-
 .../acle/general-c/load_ext_gather_offset_2.c |   4 +-
 .../acle/general-c/load_ext_gather_offset_3.c |   4 +-
 .../acle/general-c/load_ext_gather_offset_4.c |   4 +-
 .../acle/general-c/load_ext_gather_offset_5.c |   4 +-
 .../load_ext_gather_offset_restricted_1.c     |   4 +-
 .../load_ext_gather_offset_restricted_2.c     |   4 +-
 .../load_ext_gather_offset_restricted_3.c     |   4 +-
 .../load_ext_gather_offset_restricted_4.c     |   4 +-
 .../aarch64/sve/acle/general-c/sizeless-1.c   |   8 +-
 .../aarch64/sve/acle/general-c/sizeless-2.c   |   8 +-
 .../aarch64/sve/acle/general-c/store_1.c      |   8 +-
 .../aarch64/sve/acle/general-c/store_2.c      |  10 +-
 .../acle/general-c/store_scatter_index_1.c    |   8 +-
 .../store_scatter_index_restricted_1.c        |   8 +-
 .../acle/general-c/store_scatter_offset_2.c   |   8 +-
 .../store_scatter_offset_restricted_1.c       |   8 +-
 .../aarch64/sve/acle/general/attributes_7.c   |  28 +--
 .../i386/sse2-bfloat16-scalar-typecheck.c     |   4 +-
 .../i386/vect-bfloat16-typecheck_1.c          |   4 +-
 .../i386/vect-bfloat16-typecheck_2.c          |   4 +-
 .../gcc.target/powerpc/conditional-return.c   |   2 +-
 130 files changed, 2441 insertions(+), 257 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/20030906-1a.c
 create mode 100644 gcc/testsuite/gcc.dg/20030906-2a.c
 create mode 100644 gcc/testsuite/gcc.dg/Wimplicit-function-declaration-c99-2.c
 create mode 100644 gcc/testsuite/gcc.dg/Wimplicit-int-1a.c
 create mode 100644 gcc/testsuite/gcc.dg/Wimplicit-int-4a.c
 create mode 100644 gcc/testsuite/gcc.dg/Wincompatible-pointer-types-5.c
 create mode 100644 gcc/testsuite/gcc.dg/Wint-conversion-4.c
 create mode 100644 gcc/testsuite/gcc.dg/Wreturn-mismatch-1a.c
 create mode 100644 gcc/testsuite/gcc.dg/Wreturn-mismatch-2a.c
 create mode 100644 gcc/testsuite/gcc.dg/anon-struct-11a.c
 create mode 100644 gcc/testsuite/gcc.dg/anon-struct-13a.c
 create mode 100644 gcc/testsuite/gcc.dg/assign-warn-4.c
 create mode 100644 gcc/testsuite/gcc.dg/builtin-arith-overflow-4a.c
 create mode 100644 gcc/testsuite/gcc.dg/dfp/composite-type-2.c
 create mode 100644 gcc/testsuite/gcc.dg/diag-aka-1a.c
 create mode 100644 gcc/testsuite/gcc.dg/diagnostic-range-bad-return-2.c
 create mode 100644 gcc/testsuite/gcc.dg/diagnostic-types-2.c
 create mode 100644 gcc/testsuite/gcc.dg/enum-compat-2.c
 create mode 100644 gcc/testsuite/gcc.dg/func-ptr-conv-2.c
 create mode 100644 gcc/testsuite/gcc.dg/gnu23-attr-syntax-3.c
 create mode 100644 gcc/testsuite/gcc.dg/gomp/pr35738-2.c
 create mode 100644 gcc/testsuite/gcc.dg/init-bad-7a.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/noncompile/pr79758-2.c
 create mode 100644 gcc/testsuite/gcc.dg/param-type-mismatch-2.c
 create mode 100644 gcc/testsuite/gcc.dg/permerror-default.c
 create mode 100644 gcc/testsuite/gcc.dg/permerror-fpermissive.c
 create mode 100644 gcc/testsuite/gcc.dg/permerror-gnu89-pedantic.c
 create mode 100644 gcc/testsuite/gcc.dg/permerror-gnu89.c
 create mode 100644 gcc/testsuite/gcc.dg/permerror-noerror.c
 create mode 100644 gcc/testsuite/gcc.dg/permerror-pedantic.c
 create mode 100644 gcc/testsuite/gcc.dg/permerror-system.c
 create mode 100644 gcc/testsuite/gcc.dg/pointer-array-atomic-2.c
 create mode 100644 gcc/testsuite/gcc.dg/pr105635-2.c
 create mode 100644 gcc/testsuite/gcc.dg/pr23075-2.c
 create mode 100644 gcc/testsuite/gcc.dg/pr29521-a.c
 create mode 100644 gcc/testsuite/gcc.dg/pr61162-3.c
 create mode 100644 gcc/testsuite/gcc.dg/pr67730-a.c
 create mode 100644 gcc/testsuite/gcc.dg/spec-barrier-3a.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
 create mode 100644 gcc/testsuite/gcc.dg/transparent-union-1a.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/acle/memtag_2a.c


base-commit: 69d69865a792a93cce2905617c53913769d0f260
prerequisite-patch-id: f46d6a56470ab459865ba2e45372d60e131b9ee2
prerequisite-patch-id: 7e0b407ec2bbd5e3b9c7ed1342b08d3677a65283
prerequisite-patch-id: 02e95117add6ada9d5cdb489399fb2e562db76e2
-- 
2.41.0


^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH v2 1/8] Add tests for validating future C permerrors
  2023-11-14 17:50 [PATCH v2 0/8] Turn some C warnings into errors by default Florian Weimer
@ 2023-11-14 17:50 ` Florian Weimer
  2023-11-14 17:50 ` [PATCH v2 2/8] c: Turn int-conversion warnings into permerrors Florian Weimer
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 17+ messages in thread
From: Florian Weimer @ 2023-11-14 17:50 UTC (permalink / raw)
  To: gcc-patches; +Cc: jason, jeffreyalaw, joseph, sam

The dg-error directives for gcc.dg/permerror-system.c can be generated
using (for the most part at least):

perl -ne 'print if s,.*(/\* \{ dg-error .*) } \*/$,$1 "" { target *-*-* } $. } */,' \
  < gcc/testsuite/gcc.dg/permerror-default.c

gcc/testsuite/

	* gcc.dg/permerror-default.c: New test.
	* gcc.dg/permerror-fpermissive.c: Likewise.
	* gcc.dg/permerror-gnu89-pedantic.c: Likewise.
	* gcc.dg/permerror-gnu89.c: Likewise.
	* gcc.dg/permerror-noerror.c: Likewise.
	* gcc.dg/permerror-pedantic.c: Likewise.
	* gcc.dg/permerror-system.c: Likewise.
---
 gcc/testsuite/gcc.dg/permerror-default.c      | 85 +++++++++++++++++++
 gcc/testsuite/gcc.dg/permerror-fpermissive.c  | 85 +++++++++++++++++++
 .../gcc.dg/permerror-gnu89-pedantic.c         | 85 +++++++++++++++++++
 gcc/testsuite/gcc.dg/permerror-gnu89.c        | 85 +++++++++++++++++++
 gcc/testsuite/gcc.dg/permerror-noerror.c      | 85 +++++++++++++++++++
 gcc/testsuite/gcc.dg/permerror-pedantic.c     | 85 +++++++++++++++++++
 gcc/testsuite/gcc.dg/permerror-system.c       |  9 ++
 7 files changed, 519 insertions(+)
 create mode 100644 gcc/testsuite/gcc.dg/permerror-default.c
 create mode 100644 gcc/testsuite/gcc.dg/permerror-fpermissive.c
 create mode 100644 gcc/testsuite/gcc.dg/permerror-gnu89-pedantic.c
 create mode 100644 gcc/testsuite/gcc.dg/permerror-gnu89.c
 create mode 100644 gcc/testsuite/gcc.dg/permerror-noerror.c
 create mode 100644 gcc/testsuite/gcc.dg/permerror-pedantic.c
 create mode 100644 gcc/testsuite/gcc.dg/permerror-system.c

diff --git a/gcc/testsuite/gcc.dg/permerror-default.c b/gcc/testsuite/gcc.dg/permerror-default.c
new file mode 100644
index 00000000000..ea0be1dc89f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/permerror-default.c
@@ -0,0 +1,85 @@
+/* { dg-options "" } */
+
+/* Overview test for C permerrors.  This test should be kept in sync with the
+   other permerror-* tests.  If new permerrors are added, test cases should be
+   added to this and the other files.  */
+
+void
+implicit_function_declaration (void)
+{
+  f1 (); /* { dg-warning "'f1' \\\[-Wimplicit-function-declaration\\\]" } */
+}
+
+extern implicit_int_1; /* { dg-warning "'implicit_int_1' \\\[-Wimplicit-int\\\]" } */
+typedef implicit_int_2; /* { dg-warning "'implicit_int_2' \\\[-Wimplicit-int\\\]" } */
+extern implicit_int_3 (void); /* { dg-warning "'implicit_int_3' \\\[-Wimplicit-int\\]" } */
+implicit_int_4 (i) /* { dg-warning "return type defaults to 'int' \\\[-Wimplicit-int\\\]" } */
+/* { dg-warning "type of 'i' defaults to 'int' \\\[-Wimplicit-int\\\]" "" { target *-*-*} .-1 } */
+{
+  (const) 0; /* { dg-warning "type defaults to 'int' in type name \\\[-Wimplicit-int\\\]" } */
+}
+
+extern int missing_parameter_type (i); /* { dg-warning "parameter names \\\(without types\\\) in function declaration\n" } */
+
+
+int *
+int_conversion_1 (int flag)
+{
+  void f2 (int *);
+  flag ? "1" : 1; /* { dg-warning "pointer/integer type mismatch in conditional expression \\\[-Wint-conversion\\\]" } */
+  flag ? 1 : "1"; /* { dg-warning "pointer/integer type mismatch in conditional expression \\\[-Wint-conversion\\\]" } */
+  f2 (flag); /* { dg-warning "passing argument 1 of 'f2' makes pointer from integer without a cast \\\[-Wint-conversion\\\]" } */
+  {
+    int i1 = &flag; /* { dg-warning "initialization of 'int' from 'int \\\*' makes integer from pointer without a cast \\\[-Wint-conversion\\\]" } */
+    i1 = &flag; /* { dg-warning "assignment to 'int' from 'int \\\*' makes integer from pointer without a cast \\\[-Wint-conversion\\\]" } */
+  }
+  return flag; /* { dg-warning "returning 'int' from a function with return type 'int \\\*' makes pointer from integer without a cast \\\[-Wint-conversion\\\]" } */
+}
+
+int
+int_conversion_2 (int flag)
+{
+  void f3 (int);
+  f3 (&flag); /* { dg-warning "passing argument 1 of 'f3' makes integer from pointer without a cast \\\[-Wint-conversion\\\]" } */
+  {
+    int *i1 = flag; /* { dg-warning "initialization of 'int \\\*' from 'int' makes pointer from integer without a cast \\\[-Wint-conversion\\\]" } */
+    i1 = flag; /* { dg-warning "assignment to 'int \\\*' from 'int' makes pointer from integer without a cast \\\[-Wint-conversion\\\]" } */
+  }
+  return &flag; /* { dg-warning "returning 'int \\\*' from a function with return type 'int' makes integer from pointer without a cast \\\[-Wint-conversion\\\]" } */
+}
+
+int *
+incompatible_pointer_types (int flag)
+{
+  void f4 (int *);
+  flag ? __builtin_abs : __builtin_labs; /* { dg-warning "pointer type mismatch in conditional expression \\\[-Wincompatible-pointer-types\\\]" } */
+  {
+    int *p1 = __builtin_abs; /* { dg-warning "initialization of 'int \\\*' from pointer to '__builtin_abs' with incompatible type 'int \\\(\\\*\\\)\\\(int\\\)' \\\[-Wincompatible-pointer-types\\\]" } */
+    p1 = __builtin_abs; /* { dg-warning "assignment to 'int \\\*' from pointer to '__builtin_abs' with incompatible type 'int \\\(\\\*\\\)\\\(int\\\)' \\\[-Wincompatible-pointer-types\\\]" } */
+  }
+  {
+    int *p2 = incompatible_pointer_types; /* { dg-warning "initialization of 'int \\\*' from incompatible pointer type 'int \\\* \\\(\\\*\\\)\\\(int\\\)' \\\[-Wincompatible-pointer-types\\\]" } */
+    p2 = incompatible_pointer_types; /* { dg-warning "assignment to 'int \\\*' from incompatible pointer type 'int \\\* \\\(\\\*\\\)\\\(int\\\)' \\\[-Wincompatible-pointer-types\\\]" } */
+    {
+      int *p3 = &p2; /* { dg-warning "initialization of 'int \\\*' from incompatible pointer type 'int \\\*\\\*' \\\[-Wincompatible-pointer-types\\\]" } */
+      p3 = &p2; /* { dg-warning "assignment to 'int \\\*' from incompatible pointer type 'int \\\*\\\*' \\\[-Wincompatible-pointer-types\\\]" } */
+    }
+    f4 (&p2); /* { dg-warning "passing argument 1 of 'f4' from incompatible pointer type \\\[-Wincompatible-pointer-types\\\]" } */
+  }
+  if (flag)
+    return __builtin_abs; /* { dg-warning "returning pointer to '__builtin_abs' of type 'int \\\(\\\*\\\)\\\(int\\\)' from a function with incompatible type 'int \\\*' \\\[-Wincompatible-pointer-types\\\]" } */
+  else
+    return incompatible_pointer_types; /* { dg-warning "returning 'int \\\* \\\(\\\*\\\)\\\(int\\\)' from a function with incompatible return type 'int \\\*' \\\[-Wincompatible-pointer-types\\\]" } */
+}
+
+void
+return_mismatch_1 (void)
+{
+  return 0; /* { dg-warning "'return' with a value, in function returning void \\\[-Wreturn-mismatch\\\]" } */
+}
+
+int
+return_mismatch_2 (void)
+{
+  return; /* { dg-warning "return' with no value, in function returning non-void \\\[-Wreturn-mismatch\\\]" } */
+}
diff --git a/gcc/testsuite/gcc.dg/permerror-fpermissive.c b/gcc/testsuite/gcc.dg/permerror-fpermissive.c
new file mode 100644
index 00000000000..139f35ad1c0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/permerror-fpermissive.c
@@ -0,0 +1,85 @@
+/* { dg-options "-fpermissive" } */
+
+/* Overview test for C permerrors.  This test should be kept in sync with the
+   other permerror-* tests.  If new permerrors are added, test cases should be
+   added to this and the other files.  */
+
+void
+implicit_function_declaration (void)
+{
+  f1 (); /* { dg-warning "'f1' \\\[-Wimplicit-function-declaration\\\]" } */
+}
+
+extern implicit_int_1; /* { dg-warning "'implicit_int_1' \\\[-Wimplicit-int\\\]" } */
+typedef implicit_int_2; /* { dg-warning "'implicit_int_2' \\\[-Wimplicit-int\\\]" } */
+extern implicit_int_3 (void); /* { dg-warning "'implicit_int_3' \\\[-Wimplicit-int\\]" } */
+implicit_int_4 (i) /* { dg-warning "return type defaults to 'int' \\\[-Wimplicit-int\\\]" } */
+/* { dg-warning "type of 'i' defaults to 'int' \\\[-Wimplicit-int\\\]" "" { target *-*-*} .-1 } */
+{
+  (const) 0; /* { dg-warning "type defaults to 'int' in type name \\\[-Wimplicit-int\\\]" } */
+}
+
+extern int missing_parameter_type (i); /* { dg-warning "parameter names \\\(without types\\\) in function declaration\n" } */
+
+
+int *
+int_conversion_1 (int flag)
+{
+  void f2 (int *);
+  flag ? "1" : 1; /* { dg-warning "pointer/integer type mismatch in conditional expression \\\[-Wint-conversion\\\]" } */
+  flag ? 1 : "1"; /* { dg-warning "pointer/integer type mismatch in conditional expression \\\[-Wint-conversion\\\]" } */
+  f2 (flag); /* { dg-warning "passing argument 1 of 'f2' makes pointer from integer without a cast \\\[-Wint-conversion\\\]" } */
+  {
+    int i1 = &flag; /* { dg-warning "initialization of 'int' from 'int \\\*' makes integer from pointer without a cast \\\[-Wint-conversion\\\]" } */
+    i1 = &flag; /* { dg-warning "assignment to 'int' from 'int \\\*' makes integer from pointer without a cast \\\[-Wint-conversion\\\]" } */
+  }
+  return flag; /* { dg-warning "returning 'int' from a function with return type 'int \\\*' makes pointer from integer without a cast \\\[-Wint-conversion\\\]" } */
+}
+
+int
+int_conversion_2 (int flag)
+{
+  void f3 (int);
+  f3 (&flag); /* { dg-warning "passing argument 1 of 'f3' makes integer from pointer without a cast \\\[-Wint-conversion\\\]" } */
+  {
+    int *i1 = flag; /* { dg-warning "initialization of 'int \\\*' from 'int' makes pointer from integer without a cast \\\[-Wint-conversion\\\]" } */
+    i1 = flag; /* { dg-warning "assignment to 'int \\\*' from 'int' makes pointer from integer without a cast \\\[-Wint-conversion\\\]" } */
+  }
+  return &flag; /* { dg-warning "returning 'int \\\*' from a function with return type 'int' makes integer from pointer without a cast \\\[-Wint-conversion\\\]" } */
+}
+
+int *
+incompatible_pointer_types (int flag)
+{
+  void f4 (int *);
+  flag ? __builtin_abs : __builtin_labs; /* { dg-warning "pointer type mismatch in conditional expression \\\[-Wincompatible-pointer-types\\\]" } */
+  {
+    int *p1 = __builtin_abs; /* { dg-warning "initialization of 'int \\\*' from pointer to '__builtin_abs' with incompatible type 'int \\\(\\\*\\\)\\\(int\\\)' \\\[-Wincompatible-pointer-types\\\]" } */
+    p1 = __builtin_abs; /* { dg-warning "assignment to 'int \\\*' from pointer to '__builtin_abs' with incompatible type 'int \\\(\\\*\\\)\\\(int\\\)' \\\[-Wincompatible-pointer-types\\\]" } */
+  }
+  {
+    int *p2 = incompatible_pointer_types; /* { dg-warning "initialization of 'int \\\*' from incompatible pointer type 'int \\\* \\\(\\\*\\\)\\\(int\\\)' \\\[-Wincompatible-pointer-types\\\]" } */
+    p2 = incompatible_pointer_types; /* { dg-warning "assignment to 'int \\\*' from incompatible pointer type 'int \\\* \\\(\\\*\\\)\\\(int\\\)' \\\[-Wincompatible-pointer-types\\\]" } */
+    {
+      int *p3 = &p2; /* { dg-warning "initialization of 'int \\\*' from incompatible pointer type 'int \\\*\\\*' \\\[-Wincompatible-pointer-types\\\]" } */
+      p3 = &p2; /* { dg-warning "assignment to 'int \\\*' from incompatible pointer type 'int \\\*\\\*' \\\[-Wincompatible-pointer-types\\\]" } */
+    }
+    f4 (&p2); /* { dg-warning "passing argument 1 of 'f4' from incompatible pointer type \\\[-Wincompatible-pointer-types\\\]" } */
+  }
+  if (flag)
+    return __builtin_abs; /* { dg-warning "returning pointer to '__builtin_abs' of type 'int \\\(\\\*\\\)\\\(int\\\)' from a function with incompatible type 'int \\\*' \\\[-Wincompatible-pointer-types\\\]" } */
+  else
+    return incompatible_pointer_types; /* { dg-warning "returning 'int \\\* \\\(\\\*\\\)\\\(int\\\)' from a function with incompatible return type 'int \\\*' \\\[-Wincompatible-pointer-types\\\]" } */
+}
+
+void
+return_mismatch_1 (void)
+{
+  return 0; /* { dg-warning "'return' with a value, in function returning void \\\[-Wreturn-mismatch\\\]" } */
+}
+
+int
+return_mismatch_2 (void)
+{
+  return; /* { dg-warning "return' with no value, in function returning non-void \\\[-Wreturn-mismatch\\\]" } */
+}
diff --git a/gcc/testsuite/gcc.dg/permerror-gnu89-pedantic.c b/gcc/testsuite/gcc.dg/permerror-gnu89-pedantic.c
new file mode 100644
index 00000000000..465a16f5f9a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/permerror-gnu89-pedantic.c
@@ -0,0 +1,85 @@
+/* { dg-options "-std=gnu89 -pedantic-errors" } */
+
+/* Overview test for C permerrors.  This test should be kept in sync with the
+   other permerror-* tests.  If new permerrors are added, test cases should be
+   added to this and the other files.  */
+
+void
+implicit_function_declaration (void)
+{
+  f1 (); /* { dg-bogus "-Wimplicit-function-declaration" } */
+}
+
+extern implicit_int_1; /* { dg-bogus "-Wimplicit-int" } */
+typedef implicit_int_2; /* { dg-bogus "-Wimplicit-int" } */
+extern implicit_int_3 (void); /* { dg-bogus "-Wimplicit-int" } */
+implicit_int_4 (i) /* { dg-bogus "-Wimplicit-int" } */
+/* Directive here in the other files.  */
+{
+  (const) 0; /* { dg-bogus "-Wimplicit-int" } */
+}
+
+extern int missing_parameter_type (i); /* { dg-error "parameter names \\\(without types\\\) in function declaration\n" } */
+
+
+int *
+int_conversion_1 (int flag)
+{
+  void f2 (int *);
+  flag ? "1" : 1; /* { dg-error "pointer/integer type mismatch in conditional expression \\\[-Wint-conversion\\\]" } */
+  flag ? 1 : "1"; /* { dg-error "pointer/integer type mismatch in conditional expression \\\[-Wint-conversion\\\]" } */
+  f2 (flag); /* { dg-error "passing argument 1 of 'f2' makes pointer from integer without a cast \\\[-Wint-conversion\\\]" } */
+  {
+    int i1 = &flag; /* { dg-error "initialization of 'int' from 'int \\\*' makes integer from pointer without a cast \\\[-Wint-conversion\\\]" } */
+    i1 = &flag; /* { dg-error "assignment to 'int' from 'int \\\*' makes integer from pointer without a cast \\\[-Wint-conversion\\\]" } */
+  }
+  return flag; /* { dg-error "returning 'int' from a function with return type 'int \\\*' makes pointer from integer without a cast \\\[-Wint-conversion\\\]" } */
+}
+
+int
+int_conversion_2 (int flag)
+{
+  void f3 (int);
+  f3 (&flag); /* { dg-error "passing argument 1 of 'f3' makes integer from pointer without a cast \\\[-Wint-conversion\\\]" } */
+  {
+    int *i1 = flag; /* { dg-error "initialization of 'int \\\*' from 'int' makes pointer from integer without a cast \\\[-Wint-conversion\\\]" } */
+    i1 = flag; /* { dg-error "assignment to 'int \\\*' from 'int' makes pointer from integer without a cast \\\[-Wint-conversion\\\]" } */
+  }
+  return &flag; /* { dg-error "returning 'int \\\*' from a function with return type 'int' makes integer from pointer without a cast \\\[-Wint-conversion\\\]" } */
+}
+
+int *
+incompatible_pointer_types (int flag)
+{
+  void f4 (int *);
+  flag ? __builtin_abs : __builtin_labs; /* { dg-warning "pointer type mismatch in conditional expression \\\[-Wincompatible-pointer-types\\\]" } */
+  {
+    int *p1 = __builtin_abs; /* { dg-error "initialization of 'int \\\*' from pointer to '__builtin_abs' with incompatible type 'int \\\(\\\*\\\)\\\(int\\\)' \\\[-Wincompatible-pointer-types\\\]" } */
+    p1 = __builtin_abs; /* { dg-error "assignment to 'int \\\*' from pointer to '__builtin_abs' with incompatible type 'int \\\(\\\*\\\)\\\(int\\\)' \\\[-Wincompatible-pointer-types\\\]" } */
+  }
+  {
+    int *p2 = incompatible_pointer_types; /* { dg-error "initialization of 'int \\\*' from incompatible pointer type 'int \\\* \\\(\\\*\\\)\\\(int\\\)' \\\[-Wincompatible-pointer-types\\\]" } */
+    p2 = incompatible_pointer_types; /* { dg-error "assignment to 'int \\\*' from incompatible pointer type 'int \\\* \\\(\\\*\\\)\\\(int\\\)' \\\[-Wincompatible-pointer-types\\\]" } */
+    {
+      int *p3 = &p2; /* { dg-error "initialization of 'int \\\*' from incompatible pointer type 'int \\\*\\\*' \\\[-Wincompatible-pointer-types\\\]" } */
+      p3 = &p2; /* { dg-error "assignment to 'int \\\*' from incompatible pointer type 'int \\\*\\\*' \\\[-Wincompatible-pointer-types\\\]" } */
+    }
+    f4 (&p2); /* { dg-error "passing argument 1 of 'f4' from incompatible pointer type \\\[-Wincompatible-pointer-types\\\]" } */
+  }
+  if (flag)
+    return __builtin_abs; /* { dg-error "returning pointer to '__builtin_abs' of type 'int \\\(\\\*\\\)\\\(int\\\)' from a function with incompatible type 'int \\\*' \\\[-Wincompatible-pointer-types\\\]" } */
+  else
+    return incompatible_pointer_types; /* { dg-error "returning 'int \\\* \\\(\\\*\\\)\\\(int\\\)' from a function with incompatible return type 'int \\\*' \\\[-Wincompatible-pointer-types\\\]" } */
+}
+
+void
+return_mismatch_1 (void)
+{
+  return 0; /* { dg-error "'return' with a value, in function returning void \\\[-Wreturn-mismatch\\\]" } */
+}
+
+int
+return_mismatch_2 (void)
+{
+  return; /* { dg-bogus "-Wreturn-mismatch" } */
+}
diff --git a/gcc/testsuite/gcc.dg/permerror-gnu89.c b/gcc/testsuite/gcc.dg/permerror-gnu89.c
new file mode 100644
index 00000000000..66f7789269f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/permerror-gnu89.c
@@ -0,0 +1,85 @@
+/* { dg-options "-std=gnu89" } */
+
+/* Overview test for C permerrors.  This test should be kept in sync with the
+   other permerror-* tests.  If new permerrors are added, test cases should be
+   added to this and the other files.  */
+
+void
+implicit_function_declaration (void)
+{
+  f1 (); /* { dg-bogus "-Wimplicit-function-declaration" } */
+}
+
+extern implicit_int_1; /* { dg-bogus "-Wimplicit-int" } */
+typedef implicit_int_2; /* { dg-bogus "-Wimplicit-int" } */
+extern implicit_int_3 (void); /* { dg-bogus "-Wimplicit-int" } */
+implicit_int_4 (i) /* { dg-bogus "-Wimplicit-int" } */
+/* Directive here in the other files.  */
+{
+  (const) 0; /* { dg-bogus "-Wimplicit-int" } */
+}
+
+extern int missing_parameter_type (i); /* { dg-warning "parameter names \\\(without types\\\) in function declaration\n" } */
+
+
+int *
+int_conversion_1 (int flag)
+{
+  void f2 (int *);
+  flag ? "1" : 1; /* { dg-warning "pointer/integer type mismatch in conditional expression \\\[-Wint-conversion\\\]" } */
+  flag ? 1 : "1"; /* { dg-warning "pointer/integer type mismatch in conditional expression \\\[-Wint-conversion\\\]" } */
+  f2 (flag); /* { dg-warning "passing argument 1 of 'f2' makes pointer from integer without a cast \\\[-Wint-conversion\\\]" } */
+  {
+    int i1 = &flag; /* { dg-warning "initialization of 'int' from 'int \\\*' makes integer from pointer without a cast \\\[-Wint-conversion\\\]" } */
+    i1 = &flag; /* { dg-warning "assignment to 'int' from 'int \\\*' makes integer from pointer without a cast \\\[-Wint-conversion\\\]" } */
+  }
+  return flag; /* { dg-warning "returning 'int' from a function with return type 'int \\\*' makes pointer from integer without a cast \\\[-Wint-conversion\\\]" } */
+}
+
+int
+int_conversion_2 (int flag)
+{
+  void f3 (int);
+  f3 (&flag); /* { dg-warning "passing argument 1 of 'f3' makes integer from pointer without a cast \\\[-Wint-conversion\\\]" } */
+  {
+    int *i1 = flag; /* { dg-warning "initialization of 'int \\\*' from 'int' makes pointer from integer without a cast \\\[-Wint-conversion\\\]" } */
+    i1 = flag; /* { dg-warning "assignment to 'int \\\*' from 'int' makes pointer from integer without a cast \\\[-Wint-conversion\\\]" } */
+  }
+  return &flag; /* { dg-warning "returning 'int \\\*' from a function with return type 'int' makes integer from pointer without a cast \\\[-Wint-conversion\\\]" } */
+}
+
+int *
+incompatible_pointer_types (int flag)
+{
+  void f4 (int *);
+  flag ? __builtin_abs : __builtin_labs; /* { dg-warning "pointer type mismatch in conditional expression \\\[-Wincompatible-pointer-types\\\]" } */
+  {
+    int *p1 = __builtin_abs; /* { dg-warning "initialization of 'int \\\*' from pointer to '__builtin_abs' with incompatible type 'int \\\(\\\*\\\)\\\(int\\\)' \\\[-Wincompatible-pointer-types\\\]" } */
+    p1 = __builtin_abs; /* { dg-warning "assignment to 'int \\\*' from pointer to '__builtin_abs' with incompatible type 'int \\\(\\\*\\\)\\\(int\\\)' \\\[-Wincompatible-pointer-types\\\]" } */
+  }
+  {
+    int *p2 = incompatible_pointer_types; /* { dg-warning "initialization of 'int \\\*' from incompatible pointer type 'int \\\* \\\(\\\*\\\)\\\(int\\\)' \\\[-Wincompatible-pointer-types\\\]" } */
+    p2 = incompatible_pointer_types; /* { dg-warning "assignment to 'int \\\*' from incompatible pointer type 'int \\\* \\\(\\\*\\\)\\\(int\\\)' \\\[-Wincompatible-pointer-types\\\]" } */
+    {
+      int *p3 = &p2; /* { dg-warning "initialization of 'int \\\*' from incompatible pointer type 'int \\\*\\\*' \\\[-Wincompatible-pointer-types\\\]" } */
+      p3 = &p2; /* { dg-warning "assignment to 'int \\\*' from incompatible pointer type 'int \\\*\\\*' \\\[-Wincompatible-pointer-types\\\]" } */
+    }
+    f4 (&p2); /* { dg-warning "passing argument 1 of 'f4' from incompatible pointer type \\\[-Wincompatible-pointer-types\\\]" } */
+  }
+  if (flag)
+    return __builtin_abs; /* { dg-warning "returning pointer to '__builtin_abs' of type 'int \\\(\\\*\\\)\\\(int\\\)' from a function with incompatible type 'int \\\*' \\\[-Wincompatible-pointer-types\\\]" } */
+  else
+    return incompatible_pointer_types; /* { dg-warning "returning 'int \\\* \\\(\\\*\\\)\\\(int\\\)' from a function with incompatible return type 'int \\\*' \\\[-Wincompatible-pointer-types\\\]" } */
+}
+
+void
+return_mismatch_1 (void)
+{
+  return 0; /* { dg-warning "'return' with a value, in function returning void \\\[-Wreturn-mismatch\\\]" } */
+}
+
+int
+return_mismatch_2 (void)
+{
+  return; /* { dg-bogus "-Wreturn-mismatch" } */
+}
diff --git a/gcc/testsuite/gcc.dg/permerror-noerror.c b/gcc/testsuite/gcc.dg/permerror-noerror.c
new file mode 100644
index 00000000000..cd1c2013cb5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/permerror-noerror.c
@@ -0,0 +1,85 @@
+/* { dg-options "-Wno-error=implicit-function-declaration -Wno-error=implicit-int -Wno-error=int-conversion -Wno-error=incompatible-pointer-types -Wno-error=return-mismatch" } */
+
+/* This test should emulate the effect of -fpermissive by adding all the
+   -Wno-error= options that are implied by -fpermissive.  It needs to be
+   kept in sync with the other permerror-* tests.  */
+
+void
+implicit_function_declaration (void)
+{
+  f1 (); /* { dg-warning "'f1' \\\[-Wimplicit-function-declaration\\\]" } */
+}
+
+extern implicit_int_1; /* { dg-warning "'implicit_int_1' \\\[-Wimplicit-int\\\]" } */
+typedef implicit_int_2; /* { dg-warning "'implicit_int_2' \\\[-Wimplicit-int\\\]" } */
+extern implicit_int_3 (void); /* { dg-warning "'implicit_int_3' \\\[-Wimplicit-int\\]" } */
+implicit_int_4 (i) /* { dg-warning "return type defaults to 'int' \\\[-Wimplicit-int\\\]" } */
+/* { dg-warning "type of 'i' defaults to 'int' \\\[-Wimplicit-int\\\]" "" { target *-*-*} .-1 } */
+{
+  (const) 0; /* { dg-warning "type defaults to 'int' in type name \\\[-Wimplicit-int\\\]" } */
+}
+
+extern int missing_parameter_type (i); /* { dg-warning "parameter names \\\(without types\\\) in function declaration\n" } */
+
+
+int *
+int_conversion_1 (int flag)
+{
+  void f2 (int *);
+  flag ? "1" : 1; /* { dg-warning "pointer/integer type mismatch in conditional expression \\\[-Wint-conversion\\\]" } */
+  flag ? 1 : "1"; /* { dg-warning "pointer/integer type mismatch in conditional expression \\\[-Wint-conversion\\\]" } */
+  f2 (flag); /* { dg-warning "passing argument 1 of 'f2' makes pointer from integer without a cast \\\[-Wint-conversion\\\]" } */
+  {
+    int i1 = &flag; /* { dg-warning "initialization of 'int' from 'int \\\*' makes integer from pointer without a cast \\\[-Wint-conversion\\\]" } */
+    i1 = &flag; /* { dg-warning "assignment to 'int' from 'int \\\*' makes integer from pointer without a cast \\\[-Wint-conversion\\\]" } */
+  }
+  return flag; /* { dg-warning "returning 'int' from a function with return type 'int \\\*' makes pointer from integer without a cast \\\[-Wint-conversion\\\]" } */
+}
+
+int
+int_conversion_2 (int flag)
+{
+  void f3 (int);
+  f3 (&flag); /* { dg-warning "passing argument 1 of 'f3' makes integer from pointer without a cast \\\[-Wint-conversion\\\]" } */
+  {
+    int *i1 = flag; /* { dg-warning "initialization of 'int \\\*' from 'int' makes pointer from integer without a cast \\\[-Wint-conversion\\\]" } */
+    i1 = flag; /* { dg-warning "assignment to 'int \\\*' from 'int' makes pointer from integer without a cast \\\[-Wint-conversion\\\]" } */
+  }
+  return &flag; /* { dg-warning "returning 'int \\\*' from a function with return type 'int' makes integer from pointer without a cast \\\[-Wint-conversion\\\]" } */
+}
+
+int *
+incompatible_pointer_types (int flag)
+{
+  void f4 (int *);
+  flag ? __builtin_abs : __builtin_labs; /* { dg-warning "pointer type mismatch in conditional expression \\\[-Wincompatible-pointer-types\\\]" } */
+  {
+    int *p1 = __builtin_abs; /* { dg-warning "initialization of 'int \\\*' from pointer to '__builtin_abs' with incompatible type 'int \\\(\\\*\\\)\\\(int\\\)' \\\[-Wincompatible-pointer-types\\\]" } */
+    p1 = __builtin_abs; /* { dg-warning "assignment to 'int \\\*' from pointer to '__builtin_abs' with incompatible type 'int \\\(\\\*\\\)\\\(int\\\)' \\\[-Wincompatible-pointer-types\\\]" } */
+  }
+  {
+    int *p2 = incompatible_pointer_types; /* { dg-warning "initialization of 'int \\\*' from incompatible pointer type 'int \\\* \\\(\\\*\\\)\\\(int\\\)' \\\[-Wincompatible-pointer-types\\\]" } */
+    p2 = incompatible_pointer_types; /* { dg-warning "assignment to 'int \\\*' from incompatible pointer type 'int \\\* \\\(\\\*\\\)\\\(int\\\)' \\\[-Wincompatible-pointer-types\\\]" } */
+    {
+      int *p3 = &p2; /* { dg-warning "initialization of 'int \\\*' from incompatible pointer type 'int \\\*\\\*' \\\[-Wincompatible-pointer-types\\\]" } */
+      p3 = &p2; /* { dg-warning "assignment to 'int \\\*' from incompatible pointer type 'int \\\*\\\*' \\\[-Wincompatible-pointer-types\\\]" } */
+    }
+    f4 (&p2); /* { dg-warning "passing argument 1 of 'f4' from incompatible pointer type \\\[-Wincompatible-pointer-types\\\]" } */
+  }
+  if (flag)
+    return __builtin_abs; /* { dg-warning "returning pointer to '__builtin_abs' of type 'int \\\(\\\*\\\)\\\(int\\\)' from a function with incompatible type 'int \\\*' \\\[-Wincompatible-pointer-types\\\]" } */
+  else
+    return incompatible_pointer_types; /* { dg-warning "returning 'int \\\* \\\(\\\*\\\)\\\(int\\\)' from a function with incompatible return type 'int \\\*' \\\[-Wincompatible-pointer-types\\\]" } */
+}
+
+void
+return_mismatch_1 (void)
+{
+  return 0; /* { dg-warning "'return' with a value, in function returning void \\\[-Wreturn-mismatch\\\]" } */
+}
+
+int
+return_mismatch_2 (void)
+{
+  return; /* { dg-warning "return' with no value, in function returning non-void \\\[-Wreturn-mismatch\\\]" } */
+}
diff --git a/gcc/testsuite/gcc.dg/permerror-pedantic.c b/gcc/testsuite/gcc.dg/permerror-pedantic.c
new file mode 100644
index 00000000000..852e7daa38d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/permerror-pedantic.c
@@ -0,0 +1,85 @@
+/* { dg-options "-pedantic-errors" } */
+
+/* Overview test for C permerrors.  This test should be kept in sync with the
+   other permerror-* tests.  If new permerrors are added, test cases should be
+   added to this and the other files.  */
+
+void
+implicit_function_declaration (void)
+{
+  f1 (); /* { dg-error "'f1' \\\[-Wimplicit-function-declaration\\\]" } */
+}
+
+extern implicit_int_1; /* { dg-error "'implicit_int_1' \\\[-Wimplicit-int\\\]" } */
+typedef implicit_int_2; /* { dg-error "'implicit_int_2' \\\[-Wimplicit-int\\\]" } */
+extern implicit_int_3 (void); /* { dg-error "'implicit_int_3' \\\[-Wimplicit-int\\]" } */
+implicit_int_4 (i) /* { dg-error "return type defaults to 'int' \\\[-Wimplicit-int\\\]" } */
+/* { dg-error "type of 'i' defaults to 'int' \\\[-Wimplicit-int\\\]" "" { target *-*-*} .-1 } */
+{
+  (const) 0; /* { dg-error "type defaults to 'int' in type name \\\[-Wimplicit-int\\\]" } */
+}
+
+extern int missing_parameter_type (i); /* { dg-error "parameter names \\\(without types\\\) in function declaration\n" } */
+
+
+int *
+int_conversion_1 (int flag)
+{
+  void f2 (int *);
+  flag ? "1" : 1; /* { dg-error "pointer/integer type mismatch in conditional expression \\\[-Wint-conversion\\\]" } */
+  flag ? 1 : "1"; /* { dg-error "pointer/integer type mismatch in conditional expression \\\[-Wint-conversion\\\]" } */
+  f2 (flag); /* { dg-error "passing argument 1 of 'f2' makes pointer from integer without a cast \\\[-Wint-conversion\\\]" } */
+  {
+    int i1 = &flag; /* { dg-error "initialization of 'int' from 'int \\\*' makes integer from pointer without a cast \\\[-Wint-conversion\\\]" } */
+    i1 = &flag; /* { dg-error "assignment to 'int' from 'int \\\*' makes integer from pointer without a cast \\\[-Wint-conversion\\\]" } */
+  }
+  return flag; /* { dg-error "returning 'int' from a function with return type 'int \\\*' makes pointer from integer without a cast \\\[-Wint-conversion\\\]" } */
+}
+
+int
+int_conversion_2 (int flag)
+{
+  void f3 (int);
+  f3 (&flag); /* { dg-error "passing argument 1 of 'f3' makes integer from pointer without a cast \\\[-Wint-conversion\\\]" } */
+  {
+    int *i1 = flag; /* { dg-error "initialization of 'int \\\*' from 'int' makes pointer from integer without a cast \\\[-Wint-conversion\\\]" } */
+    i1 = flag; /* { dg-error "assignment to 'int \\\*' from 'int' makes pointer from integer without a cast \\\[-Wint-conversion\\\]" } */
+  }
+  return &flag; /* { dg-error "returning 'int \\\*' from a function with return type 'int' makes integer from pointer without a cast \\\[-Wint-conversion\\\]" } */
+}
+
+int *
+incompatible_pointer_types (int flag)
+{
+  void f4 (int *);
+  flag ? __builtin_abs : __builtin_labs; /* { dg-warning "pointer type mismatch in conditional expression \\\[-Wincompatible-pointer-types\\\]" } */
+  {
+    int *p1 = __builtin_abs; /* { dg-error "initialization of 'int \\\*' from pointer to '__builtin_abs' with incompatible type 'int \\\(\\\*\\\)\\\(int\\\)' \\\[-Wincompatible-pointer-types\\\]" } */
+    p1 = __builtin_abs; /* { dg-error "assignment to 'int \\\*' from pointer to '__builtin_abs' with incompatible type 'int \\\(\\\*\\\)\\\(int\\\)' \\\[-Wincompatible-pointer-types\\\]" } */
+  }
+  {
+    int *p2 = incompatible_pointer_types; /* { dg-error "initialization of 'int \\\*' from incompatible pointer type 'int \\\* \\\(\\\*\\\)\\\(int\\\)' \\\[-Wincompatible-pointer-types\\\]" } */
+    p2 = incompatible_pointer_types; /* { dg-error "assignment to 'int \\\*' from incompatible pointer type 'int \\\* \\\(\\\*\\\)\\\(int\\\)' \\\[-Wincompatible-pointer-types\\\]" } */
+    {
+      int *p3 = &p2; /* { dg-error "initialization of 'int \\\*' from incompatible pointer type 'int \\\*\\\*' \\\[-Wincompatible-pointer-types\\\]" } */
+      p3 = &p2; /* { dg-error "assignment to 'int \\\*' from incompatible pointer type 'int \\\*\\\*' \\\[-Wincompatible-pointer-types\\\]" } */
+    }
+    f4 (&p2); /* { dg-error "passing argument 1 of 'f4' from incompatible pointer type \\\[-Wincompatible-pointer-types\\\]" } */
+  }
+  if (flag)
+    return __builtin_abs; /* { dg-error "returning pointer to '__builtin_abs' of type 'int \\\(\\\*\\\)\\\(int\\\)' from a function with incompatible type 'int \\\*' \\\[-Wincompatible-pointer-types\\\]" } */
+  else
+    return incompatible_pointer_types; /* { dg-error "returning 'int \\\* \\\(\\\*\\\)\\\(int\\\)' from a function with incompatible return type 'int \\\*' \\\[-Wincompatible-pointer-types\\\]" } */
+}
+
+void
+return_mismatch_1 (void)
+{
+  return 0; /* { dg-error "'return' with a value, in function returning void \\\[-Wreturn-mismatch\\\]" } */
+}
+
+int
+return_mismatch_2 (void)
+{
+  return; /* { dg-error "return' with no value, in function returning non-void \\\[-Wreturn-mismatch\\\]" } */
+}
diff --git a/gcc/testsuite/gcc.dg/permerror-system.c b/gcc/testsuite/gcc.dg/permerror-system.c
new file mode 100644
index 00000000000..e6a978e494d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/permerror-system.c
@@ -0,0 +1,9 @@
+/* { dg-options "-isystem ${srcdir}" } */
+
+/* Test that permerrors appear in system headers.  */
+
+/* The dg-* directives in the header file are ignored.  No warnings are
+   expected.  */
+#include <gcc.dg/permerror-default.c>
+
+/* These errors come from permerror-default.c.  No errors yet.  */
-- 
2.41.0



^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH v2 2/8] c: Turn int-conversion warnings into permerrors
  2023-11-14 17:50 [PATCH v2 0/8] Turn some C warnings into errors by default Florian Weimer
  2023-11-14 17:50 ` [PATCH v2 1/8] Add tests for validating future C permerrors Florian Weimer
@ 2023-11-14 17:50 ` Florian Weimer
  2023-11-14 17:50 ` [PATCH v2 3/8] c: Turn -Wimplicit-function-declaration into a permerror Florian Weimer
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 17+ messages in thread
From: Florian Weimer @ 2023-11-14 17:50 UTC (permalink / raw)
  To: gcc-patches; +Cc: jason, jeffreyalaw, joseph, sam

gcc/

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

gcc/c/

	PR c/96284
	PR c/106416
	* c-typeck.cc (build_conditional_expr): Use permerror_opt for
	pointer/integer type mismatches, based on -Wint-conversion.
	(pedwarn_permerror_init, permerror_init): New function.
	(pedwarn_init): Call pedwarn_permerror_init.
	(convert_for_assignment): Use permerror_opt and
	permerror_init for -Wint-conversion	warnings.

gcc/testsuite/

	* gcc.dg/permerror-default.c (int_conversion_1)
	(int_conversion_2): Expect the new permerrors.
	* gcc.dg/permerror-system.c: Likewise.
	* c-c++-common/pr77624-1.c (foo, bar): Expect
	error instead of warning.
	* gcc.dg/Wint-conversion-2.c: Compile with -fpermissive due
	to expected int-conversion warning.
	* gcc.dg/Wint-conversion-3.c: Likewise.
	* gcc.dg/Wint-conversion-4.c: New test.  Based on
	gcc.dg/Wint-conversion-3.c.  Expect int-conversion errors.
	* gcc.dg/assign-warn-1.c: Compile with -fpermissive.
	* gcc.dg/assign-warn-4.c: New file.  Extracted from
	assign-warn1.c.  Expect int-cnversion errors.
	* gcc.dg/diagnostic-types-1.c: compile with -fpermissive.
	* gcc.dg/diagnostic-types-2.c: New file.  Extracted from
	gcc.dg/diagnostic-types-1.c.  Expect some errors instead of
	warnings.
	* gcc.dg/gomp/pr35738.c: Compile with -fpermissive due to
	expected int-conversion error.
	* gcc.dg/gomp/pr35738-2.c: New test.  Based on
	gcc.dg/gomp/pr35738.c.  Expect int-converison errors.
	* gcc.dg/init-excess-3.c: Expect int-converison errors.
	* gcc.dg/overflow-warn-1.c: Likewise.
	* gcc.dg/overflow-warn-3.c: Likewise.
	* gcc.dg/param-type-mismatch.c: Compile with -fpermissive.
	* gcc.dg/param-type-mismatch-2.c: New test.  Copied from
	gcc.dg/param-type-mismatch.c.  Expect errors.
	* gcc.dg/pr61162-2.c: Compile with -fpermissive.
	* gcc.dg/pr61162-3.c: New test. Extracted from
	gcc.dg/pr61162-2.c.  Expect int-conversion errors.
	* gcc.dg/spec-barrier-3.c: Use -fpermissive due to expected
	int-conversion error.
	* gcc.dg/spec-barrier-3a.c: New test.  Based on
	gcc.dg/spec-barrier-3.c.  Expect int-conversion errors.
	* gcc.target/aarch64/acle/memtag_2.c: Use -fpermissive due to expected
	int-conversion error.
	* gcc.target/aarch64/acle/memtag_2a.c: New test.  Copied from
	gcc.target/aarch64/acle/memtag_2.c.  Expect error.
	* gcc.target/aarch64/sve/acle/general-c/load_3.c (f1): Expect
	error.
	* gcc.target/aarch64/sve/acle/general-c/store_2.c (f1): Likewise.
	* gcc.target/aarch64/sve/acle/general-c/store_scatter_index_1.c
	(f1): Likewise.
	* gcc.target/aarch64/sve/acle/general-c/store_scatter_index_restricted_1.c
	(f1): Likewise.
	* gcc.target/aarch64/sve/acle/general-c/store_scatter_offset_2.c
	(f1): Likewise.
	* gcc.target/aarch64/sve/acle/general-c/store_scatter_offset_restricted_1.c
	(f1): Likewise.
---
 gcc/c/c-typeck.cc                             |  97 +++++----
 gcc/doc/invoke.texi                           |   6 +
 gcc/testsuite/c-c++-common/pr77624-1.c        |   4 +-
 gcc/testsuite/gcc.dg/Wint-conversion-2.c      |   2 +-
 gcc/testsuite/gcc.dg/Wint-conversion-3.c      |   2 +-
 gcc/testsuite/gcc.dg/Wint-conversion-4.c      |  14 ++
 gcc/testsuite/gcc.dg/assign-warn-1.c          |   2 +-
 gcc/testsuite/gcc.dg/assign-warn-4.c          |  21 ++
 gcc/testsuite/gcc.dg/diagnostic-types-1.c     |   2 +-
 gcc/testsuite/gcc.dg/diagnostic-types-2.c     |  24 +++
 gcc/testsuite/gcc.dg/gomp/pr35738-2.c         |  18 ++
 gcc/testsuite/gcc.dg/gomp/pr35738.c           |   2 +-
 gcc/testsuite/gcc.dg/init-excess-3.c          |   4 +-
 gcc/testsuite/gcc.dg/overflow-warn-1.c        |   4 +-
 gcc/testsuite/gcc.dg/overflow-warn-3.c        |   4 +-
 gcc/testsuite/gcc.dg/param-type-mismatch-2.c  | 187 ++++++++++++++++++
 gcc/testsuite/gcc.dg/param-type-mismatch.c    |   2 +-
 gcc/testsuite/gcc.dg/permerror-default.c      |  20 +-
 gcc/testsuite/gcc.dg/permerror-system.c       |  13 +-
 gcc/testsuite/gcc.dg/pr61162-2.c              |   2 +-
 gcc/testsuite/gcc.dg/pr61162-3.c              |  13 ++
 gcc/testsuite/gcc.dg/spec-barrier-3.c         |   2 +-
 gcc/testsuite/gcc.dg/spec-barrier-3a.c        |  13 ++
 .../gcc.target/aarch64/acle/memtag_2.c        |   4 +-
 .../gcc.target/aarch64/acle/memtag_2a.c       |  71 +++++++
 .../aarch64/sve/acle/general-c/load_3.c       |   2 +-
 .../aarch64/sve/acle/general-c/store_2.c      |   2 +-
 .../acle/general-c/store_scatter_index_1.c    |   2 +-
 .../store_scatter_index_restricted_1.c        |   2 +-
 .../acle/general-c/store_scatter_offset_2.c   |   2 +-
 .../store_scatter_offset_restricted_1.c       |   2 +-
 31 files changed, 473 insertions(+), 72 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/Wint-conversion-4.c
 create mode 100644 gcc/testsuite/gcc.dg/assign-warn-4.c
 create mode 100644 gcc/testsuite/gcc.dg/diagnostic-types-2.c
 create mode 100644 gcc/testsuite/gcc.dg/gomp/pr35738-2.c
 create mode 100644 gcc/testsuite/gcc.dg/param-type-mismatch-2.c
 create mode 100644 gcc/testsuite/gcc.dg/pr61162-3.c
 create mode 100644 gcc/testsuite/gcc.dg/spec-barrier-3a.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/acle/memtag_2a.c

diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc
index 1dbb4471a88..c7b35a27e3f 100644
--- a/gcc/c/c-typeck.cc
+++ b/gcc/c/c-typeck.cc
@@ -5450,8 +5450,9 @@ build_conditional_expr (location_t colon_loc, tree ifexp, bool ifexp_bcp,
 	   && (code2 == INTEGER_TYPE || code2 == BITINT_TYPE))
     {
       if (!null_pointer_constant_p (orig_op2))
-	pedwarn (colon_loc, OPT_Wint_conversion,
-		 "pointer/integer type mismatch in conditional expression");
+	permerror_opt (colon_loc, OPT_Wint_conversion,
+		       "pointer/integer type mismatch "
+		       "in conditional expression");
       else
 	{
 	  op2 = null_pointer_node;
@@ -5462,8 +5463,9 @@ build_conditional_expr (location_t colon_loc, tree ifexp, bool ifexp_bcp,
 	   && (code1 == INTEGER_TYPE || code1 == BITINT_TYPE))
     {
       if (!null_pointer_constant_p (orig_op1))
-	pedwarn (colon_loc, OPT_Wint_conversion,
-		 "pointer/integer type mismatch in conditional expression");
+	permerror_opt (colon_loc, OPT_Wint_conversion,
+		       "pointer/integer type mismatch "
+		       "in conditional expression");
       else
 	{
 	  op1 = null_pointer_node;
@@ -6559,28 +6561,48 @@ error_init (location_t loc, const char *gmsgid, ...)
     inform (loc, "(near initialization for %qs)", ofwhat);
 }
 
-/* Issue a pedantic warning for a bad initializer component.  OPT is
-   the option OPT_* (from options.h) controlling this warning or 0 if
-   it is unconditionally given.  GMSGID identifies the message.  The
-   component name is taken from the spelling stack.  */
+/* Used to implement pedwarn_init and permerror_init.  */
 
 static void ATTRIBUTE_GCC_DIAG (3,0)
-pedwarn_init (location_t loc, int opt, const char *gmsgid, ...)
+pedwarn_permerror_init (location_t loc, int opt, const char *gmsgid,
+			va_list *ap, diagnostic_t kind)
 {
   /* Use the location where a macro was expanded rather than where
      it was defined to make sure macros defined in system headers
      but used incorrectly elsewhere are diagnosed.  */
   location_t exploc = expansion_point_location_if_in_system_header (loc);
   auto_diagnostic_group d;
-  va_list ap;
-  va_start (ap, gmsgid);
-  bool warned = emit_diagnostic_valist (DK_PEDWARN, exploc, opt, gmsgid, &ap);
-  va_end (ap);
+  bool warned = emit_diagnostic_valist (kind, exploc, opt, gmsgid, ap);
   char *ofwhat = print_spelling ((char *) alloca (spelling_length () + 1));
   if (*ofwhat && warned)
     inform (exploc, "(near initialization for %qs)", ofwhat);
 }
 
+/* Issue a pedantic warning for a bad initializer component.  OPT is
+   the option OPT_* (from options.h) controlling this warning or 0 if
+   it is unconditionally given.  GMSGID identifies the message.  The
+   component name is taken from the spelling stack.  */
+
+static void ATTRIBUTE_GCC_DIAG (3,0)
+pedwarn_init (location_t loc, int opt, const char *gmsgid, ...)
+{
+  va_list ap;
+  va_start (ap, gmsgid);
+  pedwarn_permerror_init (loc, opt, gmsgid, &ap, DK_PEDWARN);
+  va_end (ap);
+}
+
+/* Like pedwarn_init, but issue a permerror.  */
+
+static void ATTRIBUTE_GCC_DIAG (3,0)
+permerror_init (location_t loc, int opt, const char *gmsgid, ...)
+{
+  va_list ap;
+  va_start (ap, gmsgid);
+  pedwarn_permerror_init (loc, opt, gmsgid, &ap, DK_PERMERROR);
+  va_end (ap);
+}
+
 /* Issue a warning for a bad initializer component.
 
    OPT is the OPT_W* value corresponding to the warning option that
@@ -7630,27 +7652,28 @@ convert_for_assignment (location_t location, location_t expr_loc, tree type,
 	      auto_diagnostic_group d;
 	      range_label_for_type_mismatch rhs_label (rhstype, type);
 	      gcc_rich_location richloc (expr_loc, &rhs_label);
-	      if (pedwarn (&richloc, OPT_Wint_conversion,
-			   "passing argument %d of %qE makes pointer from "
-			   "integer without a cast", parmnum, rname))
+	      if (permerror_opt (&richloc, OPT_Wint_conversion,
+				 "passing argument %d of %qE makes pointer "
+				 "from integer without a cast", parmnum, rname))
 		inform_for_arg (fundecl, expr_loc, parmnum, type, rhstype);
 	    }
 	    break;
 	  case ic_assign:
-	    pedwarn (location, OPT_Wint_conversion,
-		     "assignment to %qT from %qT makes pointer from integer "
-		     "without a cast", type, rhstype);
+	    permerror_opt (location, OPT_Wint_conversion,
+			   "assignment to %qT from %qT makes pointer from "
+			   "integer without a cast", type, rhstype);
 	    break;
 	  case ic_init:
 	  case ic_init_const:
-	    pedwarn_init (location, OPT_Wint_conversion,
-			  "initialization of %qT from %qT makes pointer from "
-			  "integer without a cast", type, rhstype);
+	    permerror_init (location, OPT_Wint_conversion,
+			    "initialization of %qT from %qT makes pointer "
+			    "from integer without a cast", type, rhstype);
 	    break;
 	  case ic_return:
-	    pedwarn (location, OPT_Wint_conversion, "returning %qT from a "
-		     "function with return type %qT makes pointer from "
-		     "integer without a cast", rhstype, type);
+	    permerror_init (location, OPT_Wint_conversion,
+			    "returning %qT from a function with return type "
+			    "%qT makes pointer from integer without a cast",
+			    rhstype, type);
 	    break;
 	  default:
 	    gcc_unreachable ();
@@ -7668,27 +7691,27 @@ convert_for_assignment (location_t location, location_t expr_loc, tree type,
 	    auto_diagnostic_group d;
 	    range_label_for_type_mismatch rhs_label (rhstype, type);
 	    gcc_rich_location richloc (expr_loc, &rhs_label);
-	    if (pedwarn (&richloc, OPT_Wint_conversion,
-			 "passing argument %d of %qE makes integer from "
-			 "pointer without a cast", parmnum, rname))
+	    if (permerror_opt (&richloc, OPT_Wint_conversion,
+			       "passing argument %d of %qE makes integer from "
+			       "pointer without a cast", parmnum, rname))
 	      inform_for_arg (fundecl, expr_loc, parmnum, type, rhstype);
 	  }
 	  break;
 	case ic_assign:
-	  pedwarn (location, OPT_Wint_conversion,
-		   "assignment to %qT from %qT makes integer from pointer "
-		   "without a cast", type, rhstype);
+	  permerror_opt (location, OPT_Wint_conversion,
+			 "assignment to %qT from %qT makes integer from "
+			 "pointer without a cast", type, rhstype);
 	  break;
 	case ic_init:
 	case ic_init_const:
-	  pedwarn_init (location, OPT_Wint_conversion,
-			"initialization of %qT from %qT makes integer from "
-			"pointer without a cast", type, rhstype);
+	  permerror_init (location, OPT_Wint_conversion,
+			  "initialization of %qT from %qT makes integer "
+			  "from pointer without a cast", type, rhstype);
 	  break;
 	case ic_return:
-	  pedwarn (location, OPT_Wint_conversion, "returning %qT from a "
-		   "function with return type %qT makes integer from "
-		   "pointer without a cast", rhstype, type);
+	  permerror_opt (location, OPT_Wint_conversion, "returning %qT from a "
+			 "function with return type %qT makes integer from "
+			 "pointer without a cast", rhstype, type);
 	  break;
 	default:
 	  gcc_unreachable ();
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 2d30a5d4767..6f748c3efd2 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -6179,6 +6179,7 @@ only by this flag, but it also downgrades some C and C++ diagnostics
 that have their own flag:
 
 @gccoptlist{
+-Wint-conversion @r{(C)}
 -Wnarrowing @r{(C++)}
 }
 
@@ -8545,6 +8546,11 @@ conversions.  This warning is about implicit conversions; for explicit
 conversions the warnings @option{-Wno-int-to-pointer-cast} and
 @option{-Wno-pointer-to-int-cast} may be used.
 
+By default, in C99 and later dialects of C, GCC treats this issue as an
+error.  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=int-conversion}.
+
 This warning is upgraded to an error by @option{-pedantic-errors}.
 
 @opindex Wzero-length-bounds
diff --git a/gcc/testsuite/c-c++-common/pr77624-1.c b/gcc/testsuite/c-c++-common/pr77624-1.c
index 3567e9b866f..e25469ee2c1 100644
--- a/gcc/testsuite/c-c++-common/pr77624-1.c
+++ b/gcc/testsuite/c-c++-common/pr77624-1.c
@@ -4,11 +4,11 @@
 int
 foo (int a)
 {
-  return __atomic_is_lock_free (2, a);		/* { dg-warning "pointer from integer" "" { target c } } */
+  return __atomic_is_lock_free (2, a);		/* { dg-error "pointer from integer" "" { target c } } */
 }						/* { dg-error "invalid conversion" "" { target c++ } .-1 } */
 
 int
 bar (int a)
 {
-  return __atomic_always_lock_free (2, a);	/* { dg-warning "pointer from integer" "" { target c } } */
+  return __atomic_always_lock_free (2, a);	/* { dg-error "pointer from integer" "" { target c } } */
 }						/* { dg-error "invalid conversion" "" { target c++ } .-1 } */
diff --git a/gcc/testsuite/gcc.dg/Wint-conversion-2.c b/gcc/testsuite/gcc.dg/Wint-conversion-2.c
index bf590a7bcd7..101e792e5b6 100644
--- a/gcc/testsuite/gcc.dg/Wint-conversion-2.c
+++ b/gcc/testsuite/gcc.dg/Wint-conversion-2.c
@@ -1,7 +1,7 @@
 /* PR middle-end/86202 - ICE in get_range_info calling an invalid memcpy()
    declaration */
 /* { dg-do compile } */
-/* { dg-options "-Wint-conversion" } */
+/* { dg-options "-fpermissive -Wint-conversion" } */
 
 void *memcpy (void *, void *, __SIZE_TYPE__ *);   /* { dg-warning "conflicting types for built-in function .memcpy." } */
 void *a, *b;
diff --git a/gcc/testsuite/gcc.dg/Wint-conversion-3.c b/gcc/testsuite/gcc.dg/Wint-conversion-3.c
index 4e514769c01..4614c015db4 100644
--- a/gcc/testsuite/gcc.dg/Wint-conversion-3.c
+++ b/gcc/testsuite/gcc.dg/Wint-conversion-3.c
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "" } */
+/* { dg-options "-fpermissive" } */
 
 const char *
 f1 (int flag)
diff --git a/gcc/testsuite/gcc.dg/Wint-conversion-4.c b/gcc/testsuite/gcc.dg/Wint-conversion-4.c
new file mode 100644
index 00000000000..6ded61aed9c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wint-conversion-4.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+const char *
+f1 (int flag)
+{
+  return flag ? "" : 1; /* { dg-error "pointer/integer type mismatch in conditional expression \\\[-Wint-conversion\\\]" } */
+}
+
+const char *
+f2 (int flag)
+{
+  return flag ? 1 : ""; /* { dg-error "pointer/integer type mismatch in conditional expression \\\[-Wint-conversion\\\]" } */
+}
diff --git a/gcc/testsuite/gcc.dg/assign-warn-1.c b/gcc/testsuite/gcc.dg/assign-warn-1.c
index 365025724c4..c483276a913 100644
--- a/gcc/testsuite/gcc.dg/assign-warn-1.c
+++ b/gcc/testsuite/gcc.dg/assign-warn-1.c
@@ -1,7 +1,7 @@
 /* Test diagnostics for bad implicit type conversions.  */
 /* Origin: Joseph Myers <jsm@polyomino.org.uk> */
 /* { dg-do compile } */
-/* { dg-options "-pedantic -ftrack-macro-expansion=0" } */
+/* { dg-options "-pedantic -fpermissive -ftrack-macro-expansion=0" } */
 
 #define TESTARG(ID, TL, TR) void ID##F(TL); void ID##F2(TR x) { ID##F(x); } extern int dummy
 #define TESTARP(ID, TL, TR) struct { void (*x)(TL); } ID##Fp; void ID##F2(TR x) { ID##Fp.x(x); } extern int dummy
diff --git a/gcc/testsuite/gcc.dg/assign-warn-4.c b/gcc/testsuite/gcc.dg/assign-warn-4.c
new file mode 100644
index 00000000000..da834f7d29d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/assign-warn-4.c
@@ -0,0 +1,21 @@
+/* Test diagnostics for bad implicit type conversions.  Error variant.  */
+/* { dg-do compile } */
+/* { dg-options "-ftrack-macro-expansion=0" } */
+
+#define TESTARG(ID, TL, TR) void ID##F(TL); void ID##F2(TR x) { ID##F(x); } extern int dummy
+#define TESTARP(ID, TL, TR) struct { void (*x)(TL); } ID##Fp; void ID##F2(TR x) { ID##Fp.x(x); } extern int dummy
+#define TESTASS(ID, TL, TR) void ID##F(TR x) { TL y; y = x; } extern int dummy
+#define TESTINI(ID, TL, TR) void ID##F(TR x) { TL y = x; } extern int dummy
+#define TESTRET(ID, TL, TR) TR ID##V; TL ID##F(void) { return ID##V; } extern int dummy
+
+TESTARG(ciia, char *, int); /* { dg-error "passing argument 1 of 'ciiaF' makes pointer from integer without a cast" } */
+TESTARP(ciib, char *, int); /* { dg-error "passing argument 1 of 'ciibFp.x' makes pointer from integer without a cast" } */
+TESTASS(ciic, char *, int); /* { dg-error "assignment to 'char \\*' from 'int' makes pointer from integer without a cast" } */
+TESTINI(ciid, char *, int); /* { dg-error "initialization of 'char \\*' from 'int' makes pointer from integer without a cast" } */
+TESTRET(ciie, char *, int); /* { dg-error "returning 'int' from a function with return type 'char \\*' makes pointer from integer without a cast" } */
+
+TESTARG(iica, int, char *); /* { dg-error "passing argument 1 of 'iicaF' makes integer from pointer without a cast" } */
+TESTARP(iicb, int, char *); /* { dg-error "passing argument 1 of 'iicbFp.x' makes integer from pointer without a cast" } */
+TESTASS(iicc, int, char *); /* { dg-error "assignment to 'int' from 'char \\*' makes integer from pointer without a cast" } */
+TESTINI(iicd, int, char *); /* { dg-error "initialization of 'int' from 'char \\*' makes integer from pointer without a cast" } */
+TESTRET(iice, int, char *); /* { dg-error "returning 'char \\*' from a function with return type 'int' makes integer from pointer without a cast" } */
diff --git a/gcc/testsuite/gcc.dg/diagnostic-types-1.c b/gcc/testsuite/gcc.dg/diagnostic-types-1.c
index fc4b104df05..94b67c6ae8d 100644
--- a/gcc/testsuite/gcc.dg/diagnostic-types-1.c
+++ b/gcc/testsuite/gcc.dg/diagnostic-types-1.c
@@ -1,6 +1,6 @@
 /* PR c/81233 */
 /* { dg-do compile } */
-/* { dg-options "-Wc++-compat -Wpedantic" } */
+/* { dg-options "-fpermissive -Wc++-compat -Wpedantic" } */
 /* Test we're printing the types, like the good compiler we are.  */
 
 enum E1 { A } e;
diff --git a/gcc/testsuite/gcc.dg/diagnostic-types-2.c b/gcc/testsuite/gcc.dg/diagnostic-types-2.c
new file mode 100644
index 00000000000..e6d284d2c5f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/diagnostic-types-2.c
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-options "-Wpedantic" } */
+/* Test we're printing the types, like the good compiler we are.  */
+
+extern void foo2 (int *); /* { dg-message "expected 'int \\*' but argument is of type 'int'" } */
+extern void foo3 (int); /* { dg-message "expected 'int' but argument is of type 'int \\*'" } */
+
+int *
+fn1 (int *p)
+{
+  p = 1; /* { dg-error "assignment to 'int \\*' from 'int' makes pointer from integer without a cast" } */
+  int *q = 1; /* { dg-error "initialization of 'int \\*' from 'int' makes pointer from integer without a cast" } */
+  foo2 (1); /* { dg-error "passing argument 1 of 'foo2' makes pointer from integer without a cast" } */
+  return 1; /* { dg-error "returning 'int' from a function with return type 'int \\*' makes pointer from integer without a cast" } */
+}
+
+int
+fn2 (int i, int *p)
+{
+  i = p; /* { dg-error "assignment to 'int' from 'int \\*' makes integer from pointer without a cast" } */
+  int j = p; /* { dg-error "initialization of 'int' from 'int \\*' makes integer from pointer without a cast" } */
+  foo3 (p); /* { dg-error "passing argument 1 of 'foo3' makes integer from pointer without a cast" } */
+  return p; /* { dg-error "returning 'int \\*' from a function with return type 'int' makes integer from pointer without a cast" } */
+}
diff --git a/gcc/testsuite/gcc.dg/gomp/pr35738-2.c b/gcc/testsuite/gcc.dg/gomp/pr35738-2.c
new file mode 100644
index 00000000000..846afe7e778
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/gomp/pr35738-2.c
@@ -0,0 +1,18 @@
+/* PR c/35738 */
+/* { dg-do compile } */
+/* { dg-options "-fopenmp" } */
+
+void foo (void);
+
+void
+bar (void *p)
+{
+  int i = 0;
+  char q[10];
+#pragma omp atomic
+  i += q;		/* { dg-error "makes integer from pointer without a cast" } */
+#pragma omp atomic
+  i += foo;		/* { dg-error "makes integer from pointer without a cast" } */
+#pragma omp atomic
+  i += p;		/* { dg-error "makes integer from pointer without a cast" } */
+}
diff --git a/gcc/testsuite/gcc.dg/gomp/pr35738.c b/gcc/testsuite/gcc.dg/gomp/pr35738.c
index 0b3866eae3b..954cfa43ece 100644
--- a/gcc/testsuite/gcc.dg/gomp/pr35738.c
+++ b/gcc/testsuite/gcc.dg/gomp/pr35738.c
@@ -1,6 +1,6 @@
 /* PR c/35738 */
 /* { dg-do compile } */
-/* { dg-options "-fopenmp" } */
+/* { dg-options "-fpermissive -fopenmp" } */
 
 void foo (void);
 
diff --git a/gcc/testsuite/gcc.dg/init-excess-3.c b/gcc/testsuite/gcc.dg/init-excess-3.c
index c03a98487b4..6ea7858a1c9 100644
--- a/gcc/testsuite/gcc.dg/init-excess-3.c
+++ b/gcc/testsuite/gcc.dg/init-excess-3.c
@@ -7,9 +7,9 @@
 char s0[] = {"abc",1}; /* { dg-error "'char..' initializer|near init" } */
 char s1[] = {"abc","a"}; /* { dg-error "'char..' initializer|near init" } */
 char s2[] = {1,"abc"}; /* { dg-error "'char..' initializer|near init|computable at load time" } */
-/* { dg-warning "integer from pointer without a cast" "" { target *-*-* } .-1 } */
+/* { dg-error "integer from pointer without a cast" "" { target *-*-* } .-1 } */
 
 char s3[5] = {"abc",1}; /* { dg-error "'char.5.' initializer|near init" } */
 char s4[5] = {"abc","a"}; /* { dg-error "'char.5.' initializer|near init" } */
 char s5[5] = {1,"abc"}; /* { dg-error "'char.5.' initializer|near init|computable at load time" } */
-/* { dg-warning "integer from pointer without a cast" "" { target *-*-* } .-1 } */
+/* { dg-error "integer from pointer without a cast" "" { target *-*-* } .-1 } */
diff --git a/gcc/testsuite/gcc.dg/overflow-warn-1.c b/gcc/testsuite/gcc.dg/overflow-warn-1.c
index a9d9fbae148..90eb43b35e2 100644
--- a/gcc/testsuite/gcc.dg/overflow-warn-1.c
+++ b/gcc/testsuite/gcc.dg/overflow-warn-1.c
@@ -47,10 +47,10 @@ static int sc = INT_MAX + 1; /* { dg-warning "25:integer overflow in expression"
    constants.  The third has the overflow in an unevaluated
    subexpression, so is a null pointer constant.  */
 void *p = 0 * (INT_MAX + 1); /* { dg-warning "integer overflow in expression" } */
-/* { dg-warning "initialization of 'void \\*' from 'int' makes pointer from integer without a cast" "null" { target *-*-* } .-1 } */
+/* { dg-error "initialization of 'void \\*' from 'int' makes pointer from integer without a cast" "null" { target *-*-* } .-1 } */
 void *q = 0 * (1 / 0); /* { dg-warning "division by zero" } */
 /* { dg-error "initializer element is not constant" "constant" { target *-*-* } .-1 } */
-/* { dg-warning "initialization of 'void \\*' from 'int' makes pointer from integer without a cast" "null" { target *-*-* } .-2 } */
+/* { dg-error "initialization of 'void \\*' from 'int' makes pointer from integer without a cast" "null" { target *-*-* } .-2 } */
 void *r = (1 ? 0 : INT_MAX+1);
 
 void
diff --git a/gcc/testsuite/gcc.dg/overflow-warn-3.c b/gcc/testsuite/gcc.dg/overflow-warn-3.c
index f64047795c7..a2ead836964 100644
--- a/gcc/testsuite/gcc.dg/overflow-warn-3.c
+++ b/gcc/testsuite/gcc.dg/overflow-warn-3.c
@@ -53,10 +53,10 @@ static int sc = INT_MAX + 1; /* { dg-warning "integer overflow in expression" }
    subexpression, so is a null pointer constant.  */
 void *p = 0 * (INT_MAX + 1); /* { dg-warning "integer overflow in expression" } */
 /* { dg-warning "overflow in constant expression" "constant" { target *-*-* } .-1 } */
-/* { dg-warning "initialization of 'void \\*' from 'int' makes pointer from integer without a cast" "null" { target *-*-* } .-2 } */
+/* { dg-error "initialization of 'void \\*' from 'int' makes pointer from integer without a cast" "null" { target *-*-* } .-2 } */
 void *q = 0 * (1 / 0); /* { dg-warning "division by zero" } */
 /* { dg-error "initializer element is not constant" "constant" { target *-*-* } .-1 } */
-/* { dg-warning "initialization of 'void \\*' from 'int' makes pointer from integer without a cast" "null" { target *-*-* } .-2 } */
+/* { dg-error "initialization of 'void \\*' from 'int' makes pointer from integer without a cast" "null" { target *-*-* } .-2 } */
 void *r = (1 ? 0 : INT_MAX+1);
 
 void
diff --git a/gcc/testsuite/gcc.dg/param-type-mismatch-2.c b/gcc/testsuite/gcc.dg/param-type-mismatch-2.c
new file mode 100644
index 00000000000..91d998437d1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/param-type-mismatch-2.c
@@ -0,0 +1,187 @@
+/* { dg-options "-fdiagnostics-show-caret -Wpointer-sign" }  */
+
+/* A collection of calls where argument 2 is of the wrong type.
+   Like param-type-mismatch.c, but expecting errors.  */
+
+/* decl, with argname.  */
+
+extern int callee_1 (int one, const char *two, float three); /* { dg-line callee_1 } */
+
+int test_1 (int first, int second, float third)
+{
+  return callee_1 (first, second, third); /* { dg-error "passing argument 2 of 'callee_1' makes pointer from integer without a cast" }  */
+  /* { dg-begin-multiline-output "" }
+   return callee_1 (first, second, third);
+                           ^~~~~~
+                           |
+                           int
+     { dg-end-multiline-output "" } */
+  /* { dg-message "expected 'const char \\*' but argument is of type 'int'" "" { target *-*-* } callee_1 } */
+  /* { dg-begin-multiline-output "" }
+ extern int callee_1 (int one, const char *two, float three);
+                               ~~~~~~~~~~~~^~~
+     { dg-end-multiline-output "" } */
+}
+
+/* decl, without argname.  */
+
+extern int callee_2 (int, const char *, float); /* { dg-line callee_2 } */
+
+int test_2 (int first, int second, float third)
+{
+  return callee_2 (first, second, third); /* { dg-error "passing argument 2 of 'callee_2' makes pointer from integer without a cast" } */
+  /* { dg-begin-multiline-output "" }
+   return callee_2 (first, second, third);
+                           ^~~~~~
+                           |
+                           int
+     { dg-end-multiline-output "" } */
+  /* { dg-message "expected 'const char \\*' but argument is of type 'int'" "" { target *-*-* } callee_2 } */
+  /* { dg-begin-multiline-output "" }
+ extern int callee_2 (int, const char *, float);
+                           ^~~~~~~~~~~~
+     { dg-end-multiline-output "" } */
+}
+
+/* defn, with argname.  */
+
+static int callee_3 (int one, const char *two, float three) /* { dg-line callee_3 } */
+{
+  return callee_2 (one, two, three);
+}
+
+int test_3 (int first, int second, float third)
+{
+  return callee_3 (first, second, third); // { dg-error "passing argument 2 of 'callee_3' makes pointer from integer without a cast" }
+  /* { dg-begin-multiline-output "" }
+   return callee_3 (first, second, third);
+                           ^~~~~~
+                           |
+                           int
+     { dg-end-multiline-output "" } */
+  /* { dg-message "expected 'const char \\*' but argument is of type 'int'" "" { target *-*-* } callee_3 } */
+  /* { dg-begin-multiline-output "" }
+ static int callee_3 (int one, const char *two, float three)
+                               ~~~~~~~~~~~~^~~
+     { dg-end-multiline-output "" } */
+}
+
+/* Trivial decl, with argname.  */
+
+extern int callee_4 (int one, float two, float three); /* { dg-line callee_4 } */
+
+int test_4 (int first, const char *second, float third)
+{
+  return callee_4 (first, second, third); /* { dg-error "incompatible type for argument 2 of 'callee_4'" }  */
+  /* { dg-begin-multiline-output "" }
+   return callee_4 (first, second, third);
+                           ^~~~~~
+                           |
+                           const char *
+     { dg-end-multiline-output "" } */
+  /* { dg-message "expected 'float' but argument is of type 'const char \\*'" "" { target *-*-* } callee_4 } */
+  /* { dg-begin-multiline-output "" }
+ extern int callee_4 (int one, float two, float three);
+                               ~~~~~~^~~
+     { dg-end-multiline-output "" } */
+}
+
+/* Trivial decl, without argname.  */
+
+extern int callee_5 (int, float, float); /* { dg-line callee_5 } */
+
+int test_5 (int first, const char *second, float third)
+{
+  return callee_5 (first, second, third); /* { dg-error "incompatible type for argument 2 of 'callee_5'" }  */
+  /* { dg-begin-multiline-output "" }
+   return callee_5 (first, second, third);
+                           ^~~~~~
+                           |
+                           const char *
+     { dg-end-multiline-output "" } */
+  /* { dg-message "expected 'float' but argument is of type 'const char \\*'" "" { target *-*-* } callee_5 } */
+  /* { dg-begin-multiline-output "" }
+ extern int callee_5 (int, float, float);
+                           ^~~~~
+     { dg-end-multiline-output "" } */
+}
+
+/* Callback with name.  */
+
+extern int callee_6 (int one, int (*two)(int, int), float three); /* { dg-line callee_6 } */
+
+int test_6 (int first, int second, float third)
+{
+  return callee_6 (first, second, third); /* { dg-error "passing argument 2 of 'callee_6' makes pointer from integer without a cast" } */
+  /* { dg-begin-multiline-output "" }
+   return callee_6 (first, second, third);
+                           ^~~~~~
+                           |
+                           int
+     { dg-end-multiline-output "" } */
+  /* { dg-message " expected 'int \\(\\*\\)\\(int,  int\\)' but argument is of type 'int'" "" { target *-*-* } callee_6 } */
+  /* { dg-begin-multiline-output "" }
+ extern int callee_6 (int one, int (*two)(int, int), float three);
+                               ~~~~~~^~~~~~~~~~~~~~
+     { dg-end-multiline-output "" } */
+}
+
+/* Callback without name.  */
+
+extern int callee_7 (int one, int (*)(int, int), float three); /* { dg-line callee_7 } */
+
+int test_7 (int first, int second, float third)
+{
+  return callee_7 (first, second, third); /* { dg-error "passing argument 2 of 'callee_7' makes pointer from integer without a cast" } */
+  /* { dg-begin-multiline-output "" }
+   return callee_7 (first, second, third);
+                           ^~~~~~
+                           |
+                           int
+     { dg-end-multiline-output "" } */
+  /* { dg-message " expected 'int \\(\\*\\)\\(int,  int\\)' but argument is of type 'int'" "" { target *-*-* } callee_7 } */
+  /* { dg-begin-multiline-output "" }
+ extern int callee_7 (int one, int (*)(int, int), float three);
+                               ^~~~~~~~~~~~~~~~~
+     { dg-end-multiline-output "" } */
+}
+
+/* -Wincompatible-pointer-types for a parameter.  */
+
+extern int callee_8 (int one, float *two, float (three)); /* { dg-line callee_8 } */
+
+int test_8 (int first, int *second, float third)
+{
+  return callee_8 (first, second, third); /* { dg-warning "passing argument 2 of 'callee_8' from incompatible pointer type" } */
+  /* { dg-begin-multiline-output "" }
+   return callee_8 (first, second, third);
+                           ^~~~~~
+                           |
+                           int *
+     { dg-end-multiline-output "" } */
+  /* { dg-message "expected 'float \\*' but argument is of type 'int \\*'" "" { target *-*-* } callee_8 } */
+  /* { dg-begin-multiline-output "" }
+ extern int callee_8 (int one, float *two, float (three));
+                               ~~~~~~~^~~
+     { dg-end-multiline-output "" } */
+}
+
+/* -Wpointer-sign for a parameter.  */
+
+extern int callee_9 (int one, int *two, float (three)); /* { dg-line callee_9 } */
+
+int test_9 (int first, unsigned int *second, float third)
+{
+  return callee_9 (first, second, third); /* { dg-warning "pointer targets in passing argument 2 of 'callee_9' differ in signedness" } */
+  /* { dg-begin-multiline-output "" }
+   return callee_9 (first, second, third);
+                           ^~~~~~
+                           |
+                           unsigned int *
+     { dg-end-multiline-output "" } */
+  /* { dg-message "expected 'int \\*' but argument is of type 'unsigned int \\*'" "" { target *-*-* } callee_9 } */
+  /* { dg-begin-multiline-output "" }
+ extern int callee_9 (int one, int *two, float (three));
+                               ~~~~~^~~
+     { dg-end-multiline-output "" } */
+}
diff --git a/gcc/testsuite/gcc.dg/param-type-mismatch.c b/gcc/testsuite/gcc.dg/param-type-mismatch.c
index 9e654a9e9c6..f6d68749cd8 100644
--- a/gcc/testsuite/gcc.dg/param-type-mismatch.c
+++ b/gcc/testsuite/gcc.dg/param-type-mismatch.c
@@ -1,4 +1,4 @@
-/* { dg-options "-fdiagnostics-show-caret -Wpointer-sign" }  */
+/* { dg-options "-fpermissive -fdiagnostics-show-caret -Wpointer-sign" }  */
 
 /* A collection of calls where argument 2 is of the wrong type.  */
 
diff --git a/gcc/testsuite/gcc.dg/permerror-default.c b/gcc/testsuite/gcc.dg/permerror-default.c
index ea0be1dc89f..5235a427175 100644
--- a/gcc/testsuite/gcc.dg/permerror-default.c
+++ b/gcc/testsuite/gcc.dg/permerror-default.c
@@ -26,26 +26,26 @@ int *
 int_conversion_1 (int flag)
 {
   void f2 (int *);
-  flag ? "1" : 1; /* { dg-warning "pointer/integer type mismatch in conditional expression \\\[-Wint-conversion\\\]" } */
-  flag ? 1 : "1"; /* { dg-warning "pointer/integer type mismatch in conditional expression \\\[-Wint-conversion\\\]" } */
-  f2 (flag); /* { dg-warning "passing argument 1 of 'f2' makes pointer from integer without a cast \\\[-Wint-conversion\\\]" } */
+  flag ? "1" : 1; /* { dg-error "pointer/integer type mismatch in conditional expression \\\[-Wint-conversion\\\]" } */
+  flag ? 1 : "1"; /* { dg-error "pointer/integer type mismatch in conditional expression \\\[-Wint-conversion\\\]" } */
+  f2 (flag); /* { dg-error "passing argument 1 of 'f2' makes pointer from integer without a cast \\\[-Wint-conversion\\\]" } */
   {
-    int i1 = &flag; /* { dg-warning "initialization of 'int' from 'int \\\*' makes integer from pointer without a cast \\\[-Wint-conversion\\\]" } */
-    i1 = &flag; /* { dg-warning "assignment to 'int' from 'int \\\*' makes integer from pointer without a cast \\\[-Wint-conversion\\\]" } */
+    int i1 = &flag; /* { dg-error "initialization of 'int' from 'int \\\*' makes integer from pointer without a cast \\\[-Wint-conversion\\\]" } */
+    i1 = &flag; /* { dg-error "assignment to 'int' from 'int \\\*' makes integer from pointer without a cast \\\[-Wint-conversion\\\]" } */
   }
-  return flag; /* { dg-warning "returning 'int' from a function with return type 'int \\\*' makes pointer from integer without a cast \\\[-Wint-conversion\\\]" } */
+  return flag; /* { dg-error "returning 'int' from a function with return type 'int \\\*' makes pointer from integer without a cast \\\[-Wint-conversion\\\]" } */
 }
 
 int
 int_conversion_2 (int flag)
 {
   void f3 (int);
-  f3 (&flag); /* { dg-warning "passing argument 1 of 'f3' makes integer from pointer without a cast \\\[-Wint-conversion\\\]" } */
+  f3 (&flag); /* { dg-error "passing argument 1 of 'f3' makes integer from pointer without a cast \\\[-Wint-conversion\\\]" } */
   {
-    int *i1 = flag; /* { dg-warning "initialization of 'int \\\*' from 'int' makes pointer from integer without a cast \\\[-Wint-conversion\\\]" } */
-    i1 = flag; /* { dg-warning "assignment to 'int \\\*' from 'int' makes pointer from integer without a cast \\\[-Wint-conversion\\\]" } */
+    int *i1 = flag; /* { dg-error "initialization of 'int \\\*' from 'int' makes pointer from integer without a cast \\\[-Wint-conversion\\\]" } */
+    i1 = flag; /* { dg-error "assignment to 'int \\\*' from 'int' makes pointer from integer without a cast \\\[-Wint-conversion\\\]" } */
   }
-  return &flag; /* { dg-warning "returning 'int \\\*' from a function with return type 'int' makes integer from pointer without a cast \\\[-Wint-conversion\\\]" } */
+  return &flag; /* { dg-error "returning 'int \\\*' from a function with return type 'int' makes integer from pointer without a cast \\\[-Wint-conversion\\\]" } */
 }
 
 int *
diff --git a/gcc/testsuite/gcc.dg/permerror-system.c b/gcc/testsuite/gcc.dg/permerror-system.c
index e6a978e494d..75e08887ef1 100644
--- a/gcc/testsuite/gcc.dg/permerror-system.c
+++ b/gcc/testsuite/gcc.dg/permerror-system.c
@@ -6,4 +6,15 @@
    expected.  */
 #include <gcc.dg/permerror-default.c>
 
-/* These errors come from permerror-default.c.  No errors yet.  */
+/* These errors come from permerror-default.c.  */
+
+/* { 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 } */
+/* { dg-error "initialization of 'int' from 'int \\\*' makes integer from pointer without a cast \\\[-Wint-conversion\\\]" "" { target *-*-* } 33 } */
+/* { dg-error "assignment to 'int' from 'int \\\*' makes integer from pointer without a cast \\\[-Wint-conversion\\\]" "" { target *-*-* } 34 } */
+/* { dg-error "returning 'int' from a function with return type 'int \\\*' makes pointer from integer without a cast \\\[-Wint-conversion\\\]" "" { target *-*-* } 36 } */
+/* { dg-error "passing argument 1 of 'f3' makes integer from pointer without a cast \\\[-Wint-conversion\\\]" "" { target *-*-* } 43 } */
+/* { dg-error "initialization of 'int \\\*' from 'int' makes pointer from integer without a cast \\\[-Wint-conversion\\\]" "" { target *-*-* } 45 } */
+/* { dg-error "assignment to 'int \\\*' from 'int' makes pointer from integer without a cast \\\[-Wint-conversion\\\]" "" { target *-*-* } 46 } */
+/* { dg-error "returning 'int \\\*' from a function with return type 'int' makes integer from pointer without a cast \\\[-Wint-conversion\\\]" "" { target *-*-* } 48 } */
diff --git a/gcc/testsuite/gcc.dg/pr61162-2.c b/gcc/testsuite/gcc.dg/pr61162-2.c
index 4aa8493d1a3..a7d0b45a310 100644
--- a/gcc/testsuite/gcc.dg/pr61162-2.c
+++ b/gcc/testsuite/gcc.dg/pr61162-2.c
@@ -1,6 +1,6 @@
 /* PR c/61162 */
 /* { dg-do compile } */
-/* { dg-options "-Wc++-compat -Wpointer-sign -Wpedantic" } */
+/* { dg-options "-fpermissive -Wc++-compat -Wpointer-sign -Wpedantic" } */
 
 enum e { A };
 struct s { int a; };
diff --git a/gcc/testsuite/gcc.dg/pr61162-3.c b/gcc/testsuite/gcc.dg/pr61162-3.c
new file mode 100644
index 00000000000..c48625797d8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr61162-3.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+
+int
+fn4 (int *a)
+{
+  return a; /* { dg-error "10:returning 'int \\*' from a function with return type 'int' makes integer from pointer without a cast" } */
+}
+
+int *
+fn5 (int a)
+{
+  return a; /* { dg-error "10:returning 'int' from a function with return type 'int \\*' makes pointer from integer without a cast" } */
+}
diff --git a/gcc/testsuite/gcc.dg/spec-barrier-3.c b/gcc/testsuite/gcc.dg/spec-barrier-3.c
index 3ed4d39061a..0940a2105c6 100644
--- a/gcc/testsuite/gcc.dg/spec-barrier-3.c
+++ b/gcc/testsuite/gcc.dg/spec-barrier-3.c
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-Wpedantic" } */
+/* { dg-options "-fpermissive -Wpedantic" } */
 
 /* __builtin_speculation_safe_value returns a value with the same type
    as its first argument.  There should be a warning if that isn't
diff --git a/gcc/testsuite/gcc.dg/spec-barrier-3a.c b/gcc/testsuite/gcc.dg/spec-barrier-3a.c
new file mode 100644
index 00000000000..ee98ad0ca50
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/spec-barrier-3a.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-Wpedantic" } */
+
+/* __builtin_speculation_safe_value returns a value with the same type
+   as its first argument.  There should be an error if that isn't
+   type-compatible with the use.  */
+int *
+f (int x)
+{
+  return __builtin_speculation_safe_value (x);  /* { dg-error "returning 'int' from a function with return type 'int \\*' makes pointer from integer without a cast" } */
+}
+
+/* { dg-prune-output "this target does not define a speculation barrier;" } */
diff --git a/gcc/testsuite/gcc.target/aarch64/acle/memtag_2.c b/gcc/testsuite/gcc.target/aarch64/acle/memtag_2.c
index fcab05b7abe..806e0750fd1 100644
--- a/gcc/testsuite/gcc.target/aarch64/acle/memtag_2.c
+++ b/gcc/testsuite/gcc.target/aarch64/acle/memtag_2.c
@@ -2,7 +2,7 @@
 
 /* { dg-do compile } */
 /* { dg-require-effective-target lp64 } */
-/* { dg-options "-O3 -march=armv8.5-a+memtag" } */
+/* { dg-options "-fpermissive -O3 -march=armv8.5-a+memtag" } */
 
 #include "arm_acle.h"
 
@@ -67,4 +67,4 @@ test_memtag_error_argument (void)
   __arm_mte_ptrdiff(no_decl2, 0);	/* { dg-error {} } */
   __arm_mte_ptrdiff(0);			/* { dg-error {} } */
   __arm_mte_ptrdiff();			/* { dg-error {} } */
-}
\ No newline at end of file
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/acle/memtag_2a.c b/gcc/testsuite/gcc.target/aarch64/acle/memtag_2a.c
new file mode 100644
index 00000000000..16db40df663
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/acle/memtag_2a.c
@@ -0,0 +1,71 @@
+/* Test the MEMTAG intrinsic qualifier warnings and argument errors.  */
+
+/* { dg-do compile } */
+/* { dg-require-effective-target lp64 } */
+/* { dg-options "-O3 -march=armv8.5-a+memtag" } */
+
+#include "arm_acle.h"
+
+void
+test_memtag_warning_return_qualifier (void)
+{
+  const char *c;
+  volatile char *v;
+  char *n;
+  int *i;
+  int64_t d;
+
+  v = __arm_mte_get_tag(c);		  /* { dg-warning {assignment} } */
+  n = __arm_mte_get_tag(c);		  /* { dg-warning {assignment} } */
+  i = __arm_mte_get_tag(c);		  /* { dg-warning {assignment} } */
+  c = __arm_mte_get_tag(v);		  /* { dg-warning {assignment} } */
+  n = __arm_mte_get_tag(v);		  /* { dg-warning {assignment} } */
+
+  i = __arm_mte_create_random_tag (c, 0); /* { dg-warning {assignment} } */
+  i = __arm_mte_increment_tag (c, 0);	  /* { dg-warning {assignment} } */
+
+  c = __arm_mte_get_tag(n);		  /* No warning.  */
+  d = __arm_mte_ptrdiff(c, i);		  /* No warning.  */
+}
+
+void
+test_memtag_warning_argument (void)
+{
+  const char *c;
+  __arm_mte_exclude_tag(0, 0);		/* No warning.  */
+  __arm_mte_create_random_tag (0, 0);	/* No warning.  */
+  __arm_mte_set_tag(0);			/* No warning.  */
+  __arm_mte_get_tag(0);			/* No warning.  */
+  __arm_mte_increment_tag (0, 15);	/* No warning.  */
+  __arm_mte_ptrdiff(c, 0);		/* No warning.  */
+  __arm_mte_ptrdiff(0, c);		/* No warning.  */
+}
+
+void
+test_memtag_error_argument (void)
+{
+  /* Produce errors properly for invalid arguments.  */
+  __arm_mte_exclude_tag(no_decl, 0);	/* { dg-error {} } */
+  __arm_mte_exclude_tag();		/* { dg-error {} } */
+  __arm_mte_ptrdiff(no_decl2, 0);	/* { dg-error {} } */
+  __arm_mte_ptrdiff(0);			/* { dg-error {} } */
+  __arm_mte_ptrdiff();			/* { dg-error {} } */
+
+  const char *c;
+  uint64_t i;
+  __arm_mte_exclude_tag(i, 0);		/* { dg-error {argument} } */
+  __arm_mte_create_random_tag (i, 0);	/* { dg-error {argument} } */
+  __arm_mte_set_tag(i);			/* { dg-error {argument} } */
+  __arm_mte_get_tag(i);			/* { dg-error {argument} } */
+  __arm_mte_increment_tag (i, 15);	/* { dg-error {argument} } */
+  __arm_mte_ptrdiff(c, i);		/* { dg-error {argument} } */
+  __arm_mte_ptrdiff(i, c);		/* { dg-error {argument} } */
+
+  __arm_mte_exclude_tag(1, 0);		/* { dg-error {argument} } */
+  __arm_mte_create_random_tag (1, 0);	/* { dg-error {argument} } */
+  __arm_mte_set_tag(1);			/* { dg-error {argument} } */
+  __arm_mte_get_tag(1);			/* { dg-error {argument} } */
+  __arm_mte_increment_tag (1, 15);	/* { dg-error {argument} } */
+  __arm_mte_ptrdiff(c, 1);		/* { dg-error {argument} } */
+  __arm_mte_ptrdiff(1, c);		/* { dg-error {argument} } */
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/load_3.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/load_3.c
index 770203f64c8..34166395ecc 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/load_3.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/load_3.c
@@ -13,6 +13,6 @@ f1 (svbool_t pg, signed char *s8_ptr, svint8_t s8)
   svld1_vnum (pg, s8_ptr, 0, 0); /* { dg-error {too many arguments to function 'svld1_vnum'} } */
   svld1_vnum (0, s8_ptr, 0); /* { dg-error {passing 'int' to argument 1 of 'svld1_vnum', which expects 'svbool_t'} } */
   svld1_vnum (pg, 0, 0); /* { dg-error {passing 'int' to argument 2 of 'svld1_vnum', which expects a pointer type} } */
-  svld1_vnum (pg, s8_ptr, s8_ptr); /* { dg-warning "passing argument 3 of 'svld1_vnum_s8' makes integer from pointer without a cast" } */
+  svld1_vnum (pg, s8_ptr, s8_ptr); /* { dg-error "passing argument 3 of 'svld1_vnum_s8' makes integer from pointer without a cast" } */
   svld1_vnum (pg, s8_ptr, s8); /* { dg-error {passing 'svint8_t' to argument 3 of 'svld1_vnum', which expects 'int64_t'} } */
 }
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/store_2.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/store_2.c
index c718b3ee04e..669f8844bc1 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/store_2.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/store_2.c
@@ -14,7 +14,7 @@ f1 (svbool_t pg, signed char *s8_ptr, void *void_ptr, struct s *s_ptr,
   svst1_vnum (0, s8_ptr, 0, s8); /* { dg-error {passing 'int' to argument 1 of 'svst1_vnum', which expects 'svbool_t'} } */
   svst1_vnum (pg, s8_ptr, pg, s8); /* { dg-error {passing 'svbool_t' to argument 3 of 'svst1_vnum', which expects 'int64_t'} } */
   svst1_vnum (pg, s8_ptr, s8, s8); /* { dg-error {passing 'svint8_t' to argument 3 of 'svst1_vnum', which expects 'int64_t'} } */
-  svst1_vnum (pg, s8_ptr, void_ptr, s8); /* { dg-warning "passing argument 3 of 'svst1_vnum_s8' makes integer from pointer without a cast" } */
+  svst1_vnum (pg, s8_ptr, void_ptr, s8); /* { dg-error "passing argument 3 of 'svst1_vnum_s8' makes integer from pointer without a cast" } */
   svst1_vnum (pg, void_ptr, 0, 0); /* { dg-error {passing 'int' to argument 4 of 'svst1_vnum', which expects an SVE vector type} } */
   svst1_vnum (pg, void_ptr, 0, pg); /* { dg-error {'svst1_vnum' has no form that takes 'svbool_t' arguments} } */
   svst1_vnum (pg, 0, 0, s8);
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/store_scatter_index_1.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/store_scatter_index_1.c
index 89528237522..29f4510c49b 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/store_scatter_index_1.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/store_scatter_index_1.c
@@ -26,7 +26,7 @@ f1 (svbool_t pg, signed char *s8_ptr, short *s16_ptr,
   svst1_scatter_index (pg, cf32_ptr, s32, f32); /* { dg-warning "passing argument 2 of 'svst1_scatter_s32index_f32' from incompatible pointer type" } */
   svst1_scatter_index (pg, s, s32, s32); /* { dg-error {passing 'struct s' to argument 2 of 'svst1_scatter_index', which expects a vector or pointer base address} } */
 
-  svst1_scatter_index (pg, u32, void_ptr, s32); /* { dg-warning "passing argument 3 of 'svst1_scatter_u32base_index_s32' makes integer from pointer without a cast" } */
+  svst1_scatter_index (pg, u32, void_ptr, s32); /* { dg-error "passing argument 3 of 'svst1_scatter_u32base_index_s32' makes integer from pointer without a cast" } */
   svst1_scatter_index (pg, u32, pg, s32); /* { dg-error {passing 'svbool_t' to argument 3 of 'svst1_scatter_index', which expects 'int64_t'} } */
   svst1_scatter_index (pg, u32, s32, s32); /* { dg-error {passing 'svint32_t' to argument 3 of 'svst1_scatter_index', which expects 'int64_t'} } */
 
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/store_scatter_index_restricted_1.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/store_scatter_index_restricted_1.c
index 5e31362c412..ab718b5eeee 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/store_scatter_index_restricted_1.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/store_scatter_index_restricted_1.c
@@ -28,7 +28,7 @@ f1 (svbool_t pg, signed char *s8_ptr, short *s16_ptr,
   svstnt1_scatter_index (pg, cf64_ptr, s64, f64); /* { dg-warning "passing argument 2 of 'svstnt1_scatter_s64index_f64' from incompatible pointer type" } */
   svstnt1_scatter_index (pg, s, s64, s64); /* { dg-error {passing 'struct s' to argument 2 of 'svstnt1_scatter_index', which expects a vector or pointer base address} } */
 
-  svstnt1_scatter_index (pg, u32, void_ptr, s32); /* { dg-warning "passing argument 3 of 'svstnt1_scatter_u32base_index_s32' makes integer from pointer without a cast" } */
+  svstnt1_scatter_index (pg, u32, void_ptr, s32); /* { dg-error "passing argument 3 of 'svstnt1_scatter_u32base_index_s32' makes integer from pointer without a cast" } */
   svstnt1_scatter_index (pg, u32, pg, s32); /* { dg-error {passing 'svbool_t' to argument 3 of 'svstnt1_scatter_index', which expects 'int64_t'} } */
   svstnt1_scatter_index (pg, u32, s32, s32); /* { dg-error {passing 'svint32_t' to argument 3 of 'svstnt1_scatter_index', which expects 'int64_t'} } */
 
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/store_scatter_offset_2.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/store_scatter_offset_2.c
index 4854818cae6..311b1744c91 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/store_scatter_offset_2.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/store_scatter_offset_2.c
@@ -26,7 +26,7 @@ f1 (svbool_t pg, signed char *s8_ptr, short *s16_ptr,
   svst1_scatter_offset (pg, cf32_ptr, s32, f32); /* { dg-warning "passing argument 2 of 'svst1_scatter_s32offset_f32' from incompatible pointer type" } */
   svst1_scatter_offset (pg, s, s32, s32); /* { dg-error {passing 'struct s' to argument 2 of 'svst1_scatter_offset', which expects a vector or pointer base address} } */
 
-  svst1_scatter_offset (pg, u32, void_ptr, s32); /* { dg-warning "passing argument 3 of 'svst1_scatter_u32base_offset_s32' makes integer from pointer without a cast" } */
+  svst1_scatter_offset (pg, u32, void_ptr, s32); /* { dg-error "passing argument 3 of 'svst1_scatter_u32base_offset_s32' makes integer from pointer without a cast" } */
   svst1_scatter_offset (pg, u32, pg, s32); /* { dg-error {passing 'svbool_t' to argument 3 of 'svst1_scatter_offset', which expects 'int64_t'} } */
   svst1_scatter_offset (pg, u32, s32, s32); /* { dg-error {passing 'svint32_t' to argument 3 of 'svst1_scatter_offset', which expects 'int64_t'} } */
 
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/store_scatter_offset_restricted_1.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/store_scatter_offset_restricted_1.c
index 100624b7b03..5b251127a47 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/store_scatter_offset_restricted_1.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/store_scatter_offset_restricted_1.c
@@ -28,7 +28,7 @@ f1 (svbool_t pg, signed char *s8_ptr, short *s16_ptr,
   svstnt1_scatter_offset (pg, cf32_ptr, u32, f32); /* { dg-warning "passing argument 2 of 'svstnt1_scatter_u32offset_f32' from incompatible pointer type" } */
   svstnt1_scatter_offset (pg, s, u32, s32); /* { dg-error {passing 'struct s' to argument 2 of 'svstnt1_scatter_offset', which expects a vector or pointer base address} } */
 
-  svstnt1_scatter_offset (pg, u32, void_ptr, s32); /* { dg-warning "passing argument 3 of 'svstnt1_scatter_u32base_offset_s32' makes integer from pointer without a cast" } */
+  svstnt1_scatter_offset (pg, u32, void_ptr, s32); /* { dg-error "passing argument 3 of 'svstnt1_scatter_u32base_offset_s32' makes integer from pointer without a cast" } */
   svstnt1_scatter_offset (pg, u32, pg, s32); /* { dg-error {passing 'svbool_t' to argument 3 of 'svstnt1_scatter_offset', which expects 'int64_t'} } */
   svstnt1_scatter_offset (pg, u32, s32, s32); /* { dg-error {passing 'svint32_t' to argument 3 of 'svstnt1_scatter_offset', which expects 'int64_t'} } */
 
-- 
2.41.0



^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH v2 3/8] c: Turn -Wimplicit-function-declaration into a permerror
  2023-11-14 17:50 [PATCH v2 0/8] Turn some C warnings into errors by default Florian Weimer
  2023-11-14 17:50 ` [PATCH v2 1/8] Add tests for validating future C permerrors Florian Weimer
  2023-11-14 17:50 ` [PATCH v2 2/8] c: Turn int-conversion warnings into permerrors Florian Weimer
@ 2023-11-14 17:50 ` Florian Weimer
  2023-11-14 17:50 ` [PATCH v2 4/8] c: Turn -Wimplicit-int " Florian Weimer
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 17+ messages in thread
From: Florian Weimer @ 2023-11-14 17:50 UTC (permalink / raw)
  To: gcc-patches; +Cc: jason, jeffreyalaw, joseph, sam

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 64d3a941cb9..011f0bf0a69 100644
--- a/gcc/c/c-decl.cc
+++ b/gcc/c/c-decl.cc
@@ -3493,12 +3493,12 @@ pushdecl (tree x)
 }
 \f
 
-/* 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 6f748c3efd2..a12b8e63c79 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -6179,6 +6179,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)}
 -Wint-conversion @r{(C)}
 -Wnarrowing @r{(C++)}
 }
@@ -6859,8 +6860,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 56e59dcc00a..0be35c56f52 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 00000000000..d65abc9670c
--- /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 254f7e70e65..abea8a5f356 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 2b28357e1db..eb33d9b1f23 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 00000000000..e47236b955d
--- /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 5d5f87488f5..38d36a66c46 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 00000000000..4ae617bddbd
--- /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 b6680563dc1..8e4e48d2e43 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 00000000000..b93061f287b
--- /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 bf44feb24a9..c34a47dc286 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 00000000000..420cbf7be40
--- /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 5235a427175..f37f9189e41 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 75e08887ef1..e4da4a99e9a 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 f488aca7ac2..e669d3c4d39 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 00000000000..f50c52b656c
--- /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 ad6e9d3191d..b49709dc528 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 00000000000..1a3e68c703c
--- /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 94f4078d0e8..0b5982fa705 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 00000000000..0c0a19e547b
--- /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 f9b7d8d0cab..f24d863a15c 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 00000000000..33a6b4220f4
--- /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 063e3f9eda1..cd632c6a064 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 91f37f6a53d..c9f49b6e73d 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 91f37f6a53d..c9f49b6e73d 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 c47e5411c20..a2dcf9a041b 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 dae4d0ce120..cd849f89941 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 1bc66977cdf..850eecf99f6 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 6522889dbe7..93a728593f9 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 02562198909..d54dc8eafab 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 8d57aa020ea..3b521d5c141 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 353fec2d39d..96d8ad55074 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 e22b3dd8fea..25ce7268a1e 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 73b5715c368..04465f251b1 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 e2ceb18bc42..479be66996d 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} } */
-- 
2.41.0



^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH v2 4/8] c: Turn -Wimplicit-int into a permerror
  2023-11-14 17:50 [PATCH v2 0/8] Turn some C warnings into errors by default Florian Weimer
                   ` (2 preceding siblings ...)
  2023-11-14 17:50 ` [PATCH v2 3/8] c: Turn -Wimplicit-function-declaration into a permerror Florian Weimer
@ 2023-11-14 17:50 ` Florian Weimer
  2023-11-14 17:50 ` [PATCH v2 5/8] c: Do not ignore some forms of -Wimplicit-int in system headers Florian Weimer
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 17+ messages in thread
From: Florian Weimer @ 2023-11-14 17:50 UTC (permalink / raw)
  To: gcc-patches; +Cc: jason, jeffreyalaw, joseph, sam

Most of these new permerrors are currently not diagnosed in system
headers.

gcc/

	PR c/91093
	PR c/96284
	* doc/invoke.texi (Warning Options): Document changes.

gcc/c/

	* c-decl.cc (warn_defaults_to): Remove.
	(grok_declarator, start_function): Call permerror_opt
	instead of warn_defaults_to.
	(store_parm_decls_oldstyle): Call permerror_opt for
	OPT_Wimplicit_int.

gcc/testsuite/

	* gcc.dg/permerror-default.c (implicit_int_1, implicit_int_2)
	(implicit_int_3, implicit_int_4): Expect new permerror.
	* gcc.dg/permerror-system.c: Expect a single new permerror.
	* gcc.dg/Wimplicit-int-1.c: Compile with -fpermissive due to
	expected warning.
	* gcc.dg/Wimplicit-int-4.c: Likewise.
	* gcc.dg/Wimplicit-int-1a.c: New test.  Copied from
	gcc.dg/Wimplicit-int-1.c, but expect errors.
	* gcc.dg/Wimplicit-int-4a.c: New test.  Copied from
	gcc.dg/Wimplicit-int-4.c, but expect errors.
	* gcc.dg/gnu23-attr-syntax-2.c: Compile with -fpermissive
	due to expected implicit-int error.
	* gcc.dg/gnu23-attr-syntax-3.c: New test.  Copied from
	gcc.dg/gnu23-attr-syntax-2.c, but expect an error.
	* gcc.dg/pr105635.c: Build with -fpermissive due to implicit
	int.
	* gcc.dg/pr105635-2.c: New test.  Copied from
	gcc.dg/pr105635.c.  Expect implicit int error.
	* gcc.dg/noncompile/pr79758.c: Build with -fpermissive due to
	implicit	int.
	* gcc.dg/noncompile/pr79758-2.c: New test.  Copied from
	gcc.dg/noncompile/pr79758.c.  Expect implicit int error.
---
 gcc/c/c-decl.cc                             | 43 ++++++---------------
 gcc/doc/invoke.texi                         |  7 +++-
 gcc/testsuite/gcc.dg/Wimplicit-int-1.c      |  2 +-
 gcc/testsuite/gcc.dg/Wimplicit-int-1a.c     | 11 ++++++
 gcc/testsuite/gcc.dg/Wimplicit-int-4.c      |  2 +-
 gcc/testsuite/gcc.dg/Wimplicit-int-4a.c     | 11 ++++++
 gcc/testsuite/gcc.dg/gnu23-attr-syntax-2.c  |  2 +-
 gcc/testsuite/gcc.dg/gnu23-attr-syntax-3.c  | 17 ++++++++
 gcc/testsuite/gcc.dg/noncompile/pr79758-2.c |  6 +++
 gcc/testsuite/gcc.dg/noncompile/pr79758.c   |  1 +
 gcc/testsuite/gcc.dg/permerror-default.c    | 12 +++---
 gcc/testsuite/gcc.dg/permerror-system.c     |  2 +
 gcc/testsuite/gcc.dg/pr105635-2.c           | 11 ++++++
 gcc/testsuite/gcc.dg/pr105635.c             |  2 +-
 14 files changed, 86 insertions(+), 43 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/Wimplicit-int-1a.c
 create mode 100644 gcc/testsuite/gcc.dg/Wimplicit-int-4a.c
 create mode 100644 gcc/testsuite/gcc.dg/gnu23-attr-syntax-3.c
 create mode 100644 gcc/testsuite/gcc.dg/noncompile/pr79758-2.c
 create mode 100644 gcc/testsuite/gcc.dg/pr105635-2.c

diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc
index 011f0bf0a69..893e24f7dc6 100644
--- a/gcc/c/c-decl.cc
+++ b/gcc/c/c-decl.cc
@@ -647,8 +647,6 @@ static tree grokdeclarator (const struct c_declarator *,
 			    bool *, enum deprecated_states);
 static tree grokparms (struct c_arg_info *, bool);
 static void layout_array_type (tree);
-static void warn_defaults_to (location_t, int, const char *, ...)
-    ATTRIBUTE_GCC_DIAG(3,4);
 static const char *header_for_builtin_fn (tree);
 \f
 /* T is a statement.  Add it to the statement-tree.  This is the
@@ -6570,23 +6568,6 @@ warn_variable_length_array (tree name, tree size)
     }
 }
 
-/* Print warning about defaulting to int if necessary.  */
-
-static void
-warn_defaults_to (location_t location, int opt, const char *gmsgid, ...)
-{
-  diagnostic_info diagnostic;
-  va_list ap;
-  rich_location richloc (line_table, location);
-
-  va_start (ap, gmsgid);
-  diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc,
-                       flag_isoc99 ? DK_PEDWARN : DK_WARNING);
-  diagnostic.option_index = opt;
-  diagnostic_report_diagnostic (global_dc, &diagnostic);
-  va_end (ap);
-}
-
 /* Returns the smallest location != UNKNOWN_LOCATION in LOCATIONS,
    considering only those c_declspec_words found in LIST, which
    must be terminated by cdw_number_of_elements.  */
@@ -6875,12 +6856,12 @@ grokdeclarator (const struct c_declarator *declarator,
       else
 	{
 	  if (name)
-	    warn_defaults_to (loc, OPT_Wimplicit_int,
-			      "type defaults to %<int%> in declaration "
-			      "of %qE", name);
+	    permerror_opt (loc, OPT_Wimplicit_int,
+			   "type defaults to %<int%> in declaration "
+			   "of %qE", name);
 	  else
-	    warn_defaults_to (loc, OPT_Wimplicit_int,
-			      "type defaults to %<int%> in type name");
+	    permerror_opt (loc, OPT_Wimplicit_int,
+			   "type defaults to %<int%> in type name");
 	}
     }
 
@@ -10290,10 +10271,10 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator,
     }
 
   if (warn_about_return_type)
-    warn_defaults_to (loc, flag_isoc99 ? OPT_Wimplicit_int
-			   : (warn_return_type > 0 ? OPT_Wreturn_type
-			      : OPT_Wimplicit_int),
-		      "return type defaults to %<int%>");
+    permerror_opt (loc, flag_isoc99 ? OPT_Wimplicit_int
+		   : (warn_return_type > 0 ? OPT_Wreturn_type
+		      : OPT_Wimplicit_int),
+		   "return type defaults to %<int%>");
 
   /* Make the init_value nonzero so pushdecl knows this is not tentative.
      error_mark_node is replaced below (in pop_scope) with the BLOCK.  */
@@ -10635,9 +10616,9 @@ store_parm_decls_oldstyle (tree fndecl, const struct c_arg_info *arg_info)
 	  warn_if_shadowing (decl);
 
 	  if (flag_isoc99)
-	    pedwarn (DECL_SOURCE_LOCATION (decl),
-		     OPT_Wimplicit_int, "type of %qD defaults to %<int%>",
-		     decl);
+	    permerror_opt (DECL_SOURCE_LOCATION (decl),
+			   OPT_Wimplicit_int, "type of %qD defaults to %<int%>",
+			   decl);
 	  else
 	    warning_at (DECL_SOURCE_LOCATION (decl),
 			OPT_Wmissing_parameter_type,
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index a12b8e63c79..3743ca4fb82 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -6180,6 +6180,7 @@ that have their own flag:
 
 @gccoptlist{
 -Wimplicit-function-declaration @r{(C)}
+-Wimplicit-int @r{(C)}
 -Wint-conversion @r{(C)}
 -Wnarrowing @r{(C++)}
 }
@@ -6851,8 +6852,10 @@ This warning is enabled by @option{-Wall} in C++.
 @opindex Wno-implicit-int
 @item -Wno-implicit-int @r{(C and Objective-C only)}
 This option controls warnings when a declaration does not specify a type.
-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-int}.
 
 This warning is upgraded to an error by @option{-pedantic-errors}.
 
diff --git a/gcc/testsuite/gcc.dg/Wimplicit-int-1.c b/gcc/testsuite/gcc.dg/Wimplicit-int-1.c
index 4a96e8f505d..fc7726c517e 100644
--- a/gcc/testsuite/gcc.dg/Wimplicit-int-1.c
+++ b/gcc/testsuite/gcc.dg/Wimplicit-int-1.c
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "" } */
+/* { dg-options "-fpermissive" } */
 
 static l; /* { dg-warning "type defaults to" } */
 
diff --git a/gcc/testsuite/gcc.dg/Wimplicit-int-1a.c b/gcc/testsuite/gcc.dg/Wimplicit-int-1a.c
new file mode 100644
index 00000000000..ef1835e2d3a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wimplicit-int-1a.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+static l; /* { dg-error "type defaults to" } */
+
+foo (a) /* { dg-error "return type defaults to" } */
+/* { dg-error "type of .a. defaults to .int." "type" { target *-*-* } .-1 } */
+{
+  auto p; /* { dg-error "type defaults to" } */
+  typedef bar; /* { dg-error "type defaults to" } */
+}
diff --git a/gcc/testsuite/gcc.dg/Wimplicit-int-4.c b/gcc/testsuite/gcc.dg/Wimplicit-int-4.c
index c9c6e8e5e95..99c61a76ecf 100644
--- a/gcc/testsuite/gcc.dg/Wimplicit-int-4.c
+++ b/gcc/testsuite/gcc.dg/Wimplicit-int-4.c
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-Wno-implicit -Wimplicit-int" } */
+/* { dg-options "-fpermissive -Wno-implicit -Wimplicit-int" } */
 
 static l; /* { dg-warning "type defaults to" } */
 
diff --git a/gcc/testsuite/gcc.dg/Wimplicit-int-4a.c b/gcc/testsuite/gcc.dg/Wimplicit-int-4a.c
new file mode 100644
index 00000000000..920a088f02b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wimplicit-int-4a.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-Wno-implicit -Wimplicit-int" } */
+
+static l; /* { dg-error "type defaults to" } */
+
+foo (a) /* { dg-error "return type defaults to" } */
+/* { dg-error "type of .a. defaults to .int." "type" { target *-*-* } .-1 } */
+{
+  auto p; /* { dg-error "type defaults to" } */
+  typedef bar; /* { dg-error "type defaults to" } */
+}
diff --git a/gcc/testsuite/gcc.dg/gnu23-attr-syntax-2.c b/gcc/testsuite/gcc.dg/gnu23-attr-syntax-2.c
index ba60f7a095a..8943534f2b2 100644
--- a/gcc/testsuite/gcc.dg/gnu23-attr-syntax-2.c
+++ b/gcc/testsuite/gcc.dg/gnu23-attr-syntax-2.c
@@ -1,7 +1,7 @@
 /* Test C23 attribute syntax.  Invalid uses of attributes with GNU C
    features.  */
 /* { dg-do compile } */
-/* { dg-options "-std=gnu23 -w" } */
+/* { dg-options "-fpermissive -std=gnu23 -w" } */
 
 /* Attributes cannot be used as prefix attributes on old-style
    parameter declarations or on function declarators with identifier
diff --git a/gcc/testsuite/gcc.dg/gnu23-attr-syntax-3.c b/gcc/testsuite/gcc.dg/gnu23-attr-syntax-3.c
new file mode 100644
index 00000000000..d73d6a3cfa8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/gnu23-attr-syntax-3.c
@@ -0,0 +1,17 @@
+/* Test C23 attribute syntax.  Invalid uses of attributes with GNU C
+   features.  Non-permissive variant.  */
+/* { dg-do compile } */
+/* { dg-options "-std=gnu23 -w" } */
+
+/* Attributes cannot be used as prefix attributes on old-style
+   parameter declarations or on function declarators with identifier
+   lists (removed from C23).  */
+
+void (*f(a, b) [[]])() int a, b; { } /* { dg-error "expected" } */
+
+void f(x, y) int x; [[]] int y; { } /* { dg-error "expected" } */
+/* { dg-error "type of 'y' defaults to 'int'" "" { target *-*-* } .-1 } */
+
+/* Nonempty attributes cannot be used as postfix attributes with
+   __auto_type.  */
+__auto_type [[gnu::no_such_attr]] x = 1; /* { dg-error "'__auto_type' followed by" } */
diff --git a/gcc/testsuite/gcc.dg/noncompile/pr79758-2.c b/gcc/testsuite/gcc.dg/noncompile/pr79758-2.c
new file mode 100644
index 00000000000..e6a27f952ef
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/noncompile/pr79758-2.c
@@ -0,0 +1,6 @@
+/* PR c/79758 */
+/* { dg-do compile } */
+
+void fn1 (int[a]) { }; /* { dg-error "undeclared here" } */
+void fn1 (b) { }; /* { dg-error "redefinition" } */
+/* { dg-error "defaults to 'int'" "" { target *-*-* } .-1 } */
diff --git a/gcc/testsuite/gcc.dg/noncompile/pr79758.c b/gcc/testsuite/gcc.dg/noncompile/pr79758.c
index a31216068f0..e42a44380fa 100644
--- a/gcc/testsuite/gcc.dg/noncompile/pr79758.c
+++ b/gcc/testsuite/gcc.dg/noncompile/pr79758.c
@@ -1,5 +1,6 @@
 /* PR c/79758 */
 /* { dg-do compile } */
+/* { dg-additional-options "-fpermissive" } */
 
 void fn1 (int[a]) { }; /* { dg-error "undeclared here" } */
 void fn1 (b) { }; /* { dg-error "redefinition" } */
diff --git a/gcc/testsuite/gcc.dg/permerror-default.c b/gcc/testsuite/gcc.dg/permerror-default.c
index f37f9189e41..90f2220037c 100644
--- a/gcc/testsuite/gcc.dg/permerror-default.c
+++ b/gcc/testsuite/gcc.dg/permerror-default.c
@@ -10,13 +10,13 @@ implicit_function_declaration (void)
   f1 (); /* { dg-error "'f1' \\\[-Wimplicit-function-declaration\\\]" } */
 }
 
-extern implicit_int_1; /* { dg-warning "'implicit_int_1' \\\[-Wimplicit-int\\\]" } */
-typedef implicit_int_2; /* { dg-warning "'implicit_int_2' \\\[-Wimplicit-int\\\]" } */
-extern implicit_int_3 (void); /* { dg-warning "'implicit_int_3' \\\[-Wimplicit-int\\]" } */
-implicit_int_4 (i) /* { dg-warning "return type defaults to 'int' \\\[-Wimplicit-int\\\]" } */
-/* { dg-warning "type of 'i' defaults to 'int' \\\[-Wimplicit-int\\\]" "" { target *-*-*} .-1 } */
+extern implicit_int_1; /* { dg-error "'implicit_int_1' \\\[-Wimplicit-int\\\]" } */
+typedef implicit_int_2; /* { dg-error "'implicit_int_2' \\\[-Wimplicit-int\\\]" } */
+extern implicit_int_3 (void); /* { dg-error "'implicit_int_3' \\\[-Wimplicit-int\\]" } */
+implicit_int_4 (i) /* { dg-error "return type defaults to 'int' \\\[-Wimplicit-int\\\]" } */
+/* { dg-error "type of 'i' defaults to 'int' \\\[-Wimplicit-int\\\]" "" { target *-*-*} .-1 } */
 {
-  (const) 0; /* { dg-warning "type defaults to 'int' in type name \\\[-Wimplicit-int\\\]" } */
+  (const) 0; /* { dg-error "type defaults to 'int' in type name \\\[-Wimplicit-int\\\]" } */
 }
 
 extern int missing_parameter_type (i); /* { dg-warning "parameter names \\\(without types\\\) in function declaration\n" } */
diff --git a/gcc/testsuite/gcc.dg/permerror-system.c b/gcc/testsuite/gcc.dg/permerror-system.c
index e4da4a99e9a..60c65ffc1d4 100644
--- a/gcc/testsuite/gcc.dg/permerror-system.c
+++ b/gcc/testsuite/gcc.dg/permerror-system.c
@@ -10,6 +10,8 @@
 
 /* { dg-error "'f1' \\\[-Wimplicit-function-declaration\\\]" "" { target *-*-* } 10 } */
 
+/* { dg-error "type of 'i' defaults to 'int' \\\[-Wimplicit-int\\\]" "" { target *-*-*} 16 } */
+
 /* { 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/pr105635-2.c b/gcc/testsuite/gcc.dg/pr105635-2.c
new file mode 100644
index 00000000000..807eef0b7cd
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr105635-2.c
@@ -0,0 +1,11 @@
+/* PR c/105635 */
+/* { dg-do compile } */
+/* { dg-options "-Wall" } */
+
+void foo (int, int[*]);	/* { dg-message "previous declaration of 'foo' with type" } */
+
+foo (int x, int y)	/* { dg-error "return type defaults to 'int'" } */
+{			/* { dg-warning "conflicting types for 'foo'" "" { target *-*-* } .-1 } */
+			/* { dg-message "declared here" "" { target *-*-* } .-2 } */
+  return (x >= 0) != (y < 0);	/* { dg-warning "'return' with a value, in function returning void" } */
+}
diff --git a/gcc/testsuite/gcc.dg/pr105635.c b/gcc/testsuite/gcc.dg/pr105635.c
index aa02f593bfa..b98ea1b3c3b 100644
--- a/gcc/testsuite/gcc.dg/pr105635.c
+++ b/gcc/testsuite/gcc.dg/pr105635.c
@@ -1,6 +1,6 @@
 /* PR c/105635 */
 /* { dg-do compile } */
-/* { dg-options "-Wall" } */
+/* { dg-options "-fpermissive -Wall" } */
 
 void foo (int, int[*]);	/* { dg-message "previous declaration of 'foo' with type" } */
 
-- 
2.41.0



^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH v2 5/8] c: Do not ignore some forms of -Wimplicit-int in system headers
  2023-11-14 17:50 [PATCH v2 0/8] Turn some C warnings into errors by default Florian Weimer
                   ` (3 preceding siblings ...)
  2023-11-14 17:50 ` [PATCH v2 4/8] c: Turn -Wimplicit-int " Florian Weimer
@ 2023-11-14 17:50 ` Florian Weimer
  2023-11-15  5:03   ` Sam James
  2023-11-14 17:50 ` [PATCH v2 6/8] c: Turn -Wreturn-mismatch into a permerror Florian Weimer
                   ` (3 subsequent siblings)
  8 siblings, 1 reply; 17+ messages in thread
From: Florian Weimer @ 2023-11-14 17:50 UTC (permalink / raw)
  To: gcc-patches; +Cc: jason, jeffreyalaw, joseph, sam

Most -Wimplicit-int warnings were unconditionally disabled for system
headers.  Only missing types for parameters in old-style function
definitions resulted in warnings.  This is inconsistent with the
treatment of other permerrors, which are active in system headers.

gcc/c/

	* c-decl.cc (grokdeclarator): Do not skip -Wimplicit-int
	warnings or errors in system headers.

gcc/testsuite/

	* gcc.dg/permerror-system.c: Expect all -Wimplicit-int
	permerrors.
---
 gcc/c/c-decl.cc                         | 2 +-
 gcc/testsuite/gcc.dg/permerror-system.c | 5 +++++
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc
index 893e24f7dc6..d16958113a8 100644
--- a/gcc/c/c-decl.cc
+++ b/gcc/c/c-decl.cc
@@ -6845,7 +6845,7 @@ grokdeclarator (const struct c_declarator *declarator,
 
   /* Diagnose defaulting to "int".  */
 
-  if (declspecs->default_int_p && !in_system_header_at (input_location))
+  if (declspecs->default_int_p)
     {
       /* Issue a warning if this is an ISO C 99 program or if
 	 -Wreturn-type and this is a function, or if -Wimplicit;
diff --git a/gcc/testsuite/gcc.dg/permerror-system.c b/gcc/testsuite/gcc.dg/permerror-system.c
index 60c65ffc1d4..cad48c93f90 100644
--- a/gcc/testsuite/gcc.dg/permerror-system.c
+++ b/gcc/testsuite/gcc.dg/permerror-system.c
@@ -10,7 +10,12 @@
 
 /* { dg-error "'f1' \\\[-Wimplicit-function-declaration\\\]" "" { target *-*-* } 10 } */
 
+/* { dg-error "'implicit_int_1' \\\[-Wimplicit-int\\\]" "" { target *-*-* } 13 } */
+/* { dg-error "'implicit_int_2' \\\[-Wimplicit-int\\\]" "" { target *-*-* } 14 } */
+/* { dg-error "'implicit_int_3' \\\[-Wimplicit-int\\]" "" { target *-*-* } 15 } */
+/* { dg-error "return type defaults to 'int' \\\[-Wimplicit-int\\\]" "" { target *-*-* } 16 } */
 /* { dg-error "type of 'i' defaults to 'int' \\\[-Wimplicit-int\\\]" "" { target *-*-*} 16 } */
+/* { dg-error "type defaults to 'int' in type name \\\[-Wimplicit-int\\\]" "" { target *-*-* } 19 } */
 
 /* { 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 } */
-- 
2.41.0



^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH v2 6/8] c: Turn -Wreturn-mismatch into a permerror
  2023-11-14 17:50 [PATCH v2 0/8] Turn some C warnings into errors by default Florian Weimer
                   ` (4 preceding siblings ...)
  2023-11-14 17:50 ` [PATCH v2 5/8] c: Do not ignore some forms of -Wimplicit-int in system headers Florian Weimer
@ 2023-11-14 17:50 ` Florian Weimer
  2023-11-14 17:50 ` [PATCH v2 7/8] c: Turn -Wincompatible-pointer-types " Florian Weimer
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 17+ messages in thread
From: Florian Weimer @ 2023-11-14 17:50 UTC (permalink / raw)
  To: gcc-patches; +Cc: jason, jeffreyalaw, joseph, sam

gcc/

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

gcc/c/

	PR c/96284
	* c-typeck.cc (c_finish_return): Use permerrors
	for OPT_Wreturn_mismatch diagnostics.

gcc/testsuite/

	* gcc.dg/permerror-default.c (return_mismatch_1)
	(return_mismatch_2): Expect new permerror.
	* gcc.dg/permerror-system.c: Likewise.
	* gcc.dg/20030906-1.c: Compile with -fpermissive due to
	expected -Wreturn-mismatch error.
	* gcc.dg/20030906-1a.c: New test.  Copied from
	gcc.dg/20030906-1.c.  Expect the error.
	* gcc.dg/20030906-2.c: Compile with -fpermissive due to
	expected -Wreturn-mismatch error.
	* gcc.dg/20030906-2a.c: New test.  Copied from
	gcc.dg/20030906-2.c.  Expect the error.
	* gcc.dg/Wreturn-mismatch-1.c: Compile with -fpermissive due to
	expected -Wreturn-mismatch error.
	* gcc.dg/Wreturn-mismatch-1a.c: New test.  Copied from
	gcc.dg/Wreturn-mismatch-1.c.  Expect the error.
	* gcc.dg/Wreturn-mismatch-2.c: Compile with -fpermissive due to
	expected -Wreturn-mismatch error.
	* gcc.dg/Wreturn-mismatch-2a.c: New test.  Copied from
	gcc.dg/Wreturn-mismatch-2.c.  Expect the error.
	* gcc.dg/diagnostic-range-bad-return.c: Compile with
	-fpermissive due to expected -Wreturn-mismatch error.
	* gcc.dg/diagnostic-range-bad-return-2.c: New test.
	Copied from gcc.dg/diagnostic-range-bad-return.c.  Expect the
	error.
	* gcc.dg/pr105635-2.c: Expect -Wreturn-mismatch error.
	* gcc.dg/pr23075.c: Build with -fpermissive due to
	expected -Wreturn-mismatch error.
	* gcc.dg/pr23075-2.c: New test.  Copied from gcc.dg/pr23075.c.
	Expect the error.
	* gcc.dg/pr29521.c: Compile with -fpermissive due to expected
	-Wreturn-mismatch error.
	* gcc.dg/pr29521-a.c: New test. Copied from gcc.dg/pr29521.c.
	Expect error.
	* gcc.dg/pr67730.c: Compile with -fpermissive due to expected
	-Wreturn-mismatch error.
	* gcc.dg/pr67730-a.c: New test.  Copied from
	gcc.dg/pr67730-a.c.  Expect error.
	* gcc.target/powerpc/conditional-return.c: Compile with
	-fpermissive due to expected	-Wreturn-mismatch error.
---
 gcc/c/c-typeck.cc                             |  4 +-
 gcc/doc/invoke.texi                           |  6 ++-
 gcc/testsuite/gcc.dg/20030906-1.c             |  2 +-
 gcc/testsuite/gcc.dg/20030906-1a.c            | 21 ++++++++
 gcc/testsuite/gcc.dg/20030906-2.c             |  2 +-
 gcc/testsuite/gcc.dg/20030906-2a.c            | 21 ++++++++
 gcc/testsuite/gcc.dg/Wreturn-mismatch-1.c     |  2 +-
 gcc/testsuite/gcc.dg/Wreturn-mismatch-1a.c    | 40 ++++++++++++++
 gcc/testsuite/gcc.dg/Wreturn-mismatch-2.c     |  2 +-
 gcc/testsuite/gcc.dg/Wreturn-mismatch-2a.c    | 41 +++++++++++++++
 .../gcc.dg/diagnostic-range-bad-return-2.c    | 52 +++++++++++++++++++
 .../gcc.dg/diagnostic-range-bad-return.c      |  2 +-
 gcc/testsuite/gcc.dg/permerror-default.c      |  4 +-
 gcc/testsuite/gcc.dg/permerror-system.c       |  3 ++
 gcc/testsuite/gcc.dg/pr105635-2.c             |  2 +-
 gcc/testsuite/gcc.dg/pr23075-2.c              | 14 +++++
 gcc/testsuite/gcc.dg/pr23075.c                |  2 +-
 gcc/testsuite/gcc.dg/pr29521-a.c              | 15 ++++++
 gcc/testsuite/gcc.dg/pr29521.c                |  2 +-
 gcc/testsuite/gcc.dg/pr67730-a.c              | 11 ++++
 gcc/testsuite/gcc.dg/pr67730.c                |  2 +-
 .../gcc.target/powerpc/conditional-return.c   |  2 +-
 22 files changed, 237 insertions(+), 15 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/20030906-1a.c
 create mode 100644 gcc/testsuite/gcc.dg/20030906-2a.c
 create mode 100644 gcc/testsuite/gcc.dg/Wreturn-mismatch-1a.c
 create mode 100644 gcc/testsuite/gcc.dg/Wreturn-mismatch-2a.c
 create mode 100644 gcc/testsuite/gcc.dg/diagnostic-range-bad-return-2.c
 create mode 100644 gcc/testsuite/gcc.dg/pr23075-2.c
 create mode 100644 gcc/testsuite/gcc.dg/pr29521-a.c
 create mode 100644 gcc/testsuite/gcc.dg/pr67730-a.c

diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc
index c7b35a27e3f..f4b700117ff 100644
--- a/gcc/c/c-typeck.cc
+++ b/gcc/c/c-typeck.cc
@@ -11205,7 +11205,7 @@ c_finish_return (location_t loc, tree retval, tree origtype)
 	  && valtype != NULL_TREE && TREE_CODE (valtype) != VOID_TYPE)
 	{
 	  no_warning = true;
-	  if (emit_diagnostic (flag_isoc99 ? DK_PEDWARN : DK_WARNING,
+	  if (emit_diagnostic (flag_isoc99 ? DK_PERMERROR : DK_WARNING,
 			       loc, OPT_Wreturn_mismatch,
 			       "%<return%> with no value,"
 			       " in function returning non-void"))
@@ -11218,7 +11218,7 @@ c_finish_return (location_t loc, tree retval, tree origtype)
       current_function_returns_null = 1;
       bool warned_here;
       if (TREE_CODE (TREE_TYPE (retval)) != VOID_TYPE)
-	warned_here = pedwarn
+	warned_here = permerror_opt
 	  (xloc, OPT_Wreturn_mismatch,
 	   "%<return%> with a value, in function returning void");
       else
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 3743ca4fb82..7edc142f787 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -6183,6 +6183,7 @@ that have their own flag:
 -Wimplicit-int @r{(C)}
 -Wint-conversion @r{(C)}
 -Wnarrowing @r{(C++)}
+-Wreturn-mismatch @r{(C)}
 }
 
 The @option{-fpermissive} option is the default for historic C language
@@ -7373,7 +7374,10 @@ Attempting to use the return value of a non-@code{void} function other
 than @code{main} that flows off the end by reaching the closing curly
 brace that terminates the function is undefined.
 
-This warning is specific to C and enabled by default.
+This warning is specific to C and enabled by default.  In C99 and later
+language dialects, it is treated as an error.  It an be downgraded
+to a warning using @option{-fpermissive} (along with other warnings),
+or for just this warning, with @option{-Wno-error=return-mismatch}.
 
 @opindex Wreturn-type
 @opindex Wno-return-type
diff --git a/gcc/testsuite/gcc.dg/20030906-1.c b/gcc/testsuite/gcc.dg/20030906-1.c
index c416f55ee75..6ba5b3d770a 100644
--- a/gcc/testsuite/gcc.dg/20030906-1.c
+++ b/gcc/testsuite/gcc.dg/20030906-1.c
@@ -2,7 +2,7 @@
    Copyright (C) 2003 Free Software Foundation Inc.  */
 
 /* { dg-do compile } */
-/* { dg-options "-O -finline-functions -Wreturn-type" } */
+/* { dg-options "-fpermissive -O -finline-functions -Wreturn-type" } */
 
 extern int i;
 extern int foo (void);
diff --git a/gcc/testsuite/gcc.dg/20030906-1a.c b/gcc/testsuite/gcc.dg/20030906-1a.c
new file mode 100644
index 00000000000..46ca1771a4d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/20030906-1a.c
@@ -0,0 +1,21 @@
+/* Bug 9862 -- Spurious warnings with -finline-functions.
+   Copyright (C) 2003 Free Software Foundation Inc.  */
+
+/* { dg-do compile } */
+/* { dg-options "-O -finline-functions -Wreturn-type" } */
+
+extern int i;
+extern int foo (void);
+extern int bar (void);
+
+int foo (void)
+{
+  if( i ) return 0;
+  else    return 1;
+}
+
+int bar (void)
+{
+  if( i ) return; /* { dg-error "'return' with no value, in function returning non-void" } */
+  else    return 1;
+}		
diff --git a/gcc/testsuite/gcc.dg/20030906-2.c b/gcc/testsuite/gcc.dg/20030906-2.c
index 1191133e6a0..a85d91f46f3 100644
--- a/gcc/testsuite/gcc.dg/20030906-2.c
+++ b/gcc/testsuite/gcc.dg/20030906-2.c
@@ -2,7 +2,7 @@
    Copyright (C) 2003 Free Software Foundation Inc.  */
 
 /* { dg-do compile } */
-/* { dg-options "-O -finline-functions -Wreturn-type" } */
+/* { dg-options "-fpermissive -O -finline-functions -Wreturn-type" } */
 
 extern int i;
 extern int foo (void);
diff --git a/gcc/testsuite/gcc.dg/20030906-2a.c b/gcc/testsuite/gcc.dg/20030906-2a.c
new file mode 100644
index 00000000000..a6ffbacb46d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/20030906-2a.c
@@ -0,0 +1,21 @@
+/* Bug 9862 -- Spurious warnings with -finline-functions.
+   Copyright (C) 2003 Free Software Foundation Inc.  */
+
+/* { dg-do compile } */
+/* { dg-options "-O -finline-functions -Wreturn-type" } */
+
+extern int i;
+extern int foo (void);
+extern int bar (void);
+
+int foo (void)
+{
+  if( i ) return; /* { dg-error "'return' with no value, in function returning non-void" } */
+  else    return 1;
+}
+
+int bar (void)
+{
+  if( i ) return 0;
+  else    return 1;
+}
diff --git a/gcc/testsuite/gcc.dg/Wreturn-mismatch-1.c b/gcc/testsuite/gcc.dg/Wreturn-mismatch-1.c
index 3bad847ecf7..aef6782cbeb 100644
--- a/gcc/testsuite/gcc.dg/Wreturn-mismatch-1.c
+++ b/gcc/testsuite/gcc.dg/Wreturn-mismatch-1.c
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "" } */
+/* { dg-options "-fpermissive" } */
 
 void f1 (void);
 
diff --git a/gcc/testsuite/gcc.dg/Wreturn-mismatch-1a.c b/gcc/testsuite/gcc.dg/Wreturn-mismatch-1a.c
new file mode 100644
index 00000000000..70c7c9ddb86
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wreturn-mismatch-1a.c
@@ -0,0 +1,40 @@
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+void f1 (void);
+
+int
+f2 (void)
+{
+  f1 ();
+}
+
+static inline int
+f3 (void)
+{
+  f1 ();
+}
+
+void
+f4 (void)
+{
+  return 1; /* { dg-error "'return' with a value\[^\n\r\]*-Wreturn-mismatch" } */
+}
+
+void
+f5 (void)
+{
+  return f1 (); /* { dg-bogus "ISO C" } */
+}
+
+int
+f6 (void)
+{
+  return; /* { dg-error "'return' with no value\[^\n\r\]*-Wreturn-mismatch" } */
+}
+
+int
+f7 (void)
+{
+  return f1 (); /* { dg-error "void value not ignored as it ought to be" } */
+}
diff --git a/gcc/testsuite/gcc.dg/Wreturn-mismatch-2.c b/gcc/testsuite/gcc.dg/Wreturn-mismatch-2.c
index 49eb5a5a95c..08811024b7e 100644
--- a/gcc/testsuite/gcc.dg/Wreturn-mismatch-2.c
+++ b/gcc/testsuite/gcc.dg/Wreturn-mismatch-2.c
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-Wall" } */
+/* { dg-options "-fpermissive -Wall" } */
 
 void f1 (void);
 
diff --git a/gcc/testsuite/gcc.dg/Wreturn-mismatch-2a.c b/gcc/testsuite/gcc.dg/Wreturn-mismatch-2a.c
new file mode 100644
index 00000000000..836651ed925
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wreturn-mismatch-2a.c
@@ -0,0 +1,41 @@
+/* { dg-do compile } */
+/* { dg-options "-Wall" } */
+
+void f1 (void);
+
+int
+f2 (void)
+{
+  f1 ();
+} /* { dg-warning "control reaches end of non-void\[^\n\r\]*-Wreturn-type" } */
+
+static inline int
+f3 (void)
+{
+  f1 ();
+} /* { dg-warning "no return statement in function\[^\n\r\]*-Wreturn-type" } */
+
+void
+f4 (void)
+{
+  return 1; /* { dg-error "with a value,\[^\n\r\]*-Wreturn-mismatch" } */
+}
+
+void
+f5 (void)
+{
+  return f1 ();
+}
+
+int
+f6 (void)
+{
+  return; /* { dg-error "with no value,\[^\n\r\]*Wreturn-mismatch" } */
+}
+
+int
+f7 (void)
+{
+  return f1 (); /* { dg-error "void value not ignored as it ought to be" } */
+} /* { dg-warning "control reaches end of non-void\[^\n\r\]*-Wreturn-type" } */
+
diff --git a/gcc/testsuite/gcc.dg/diagnostic-range-bad-return-2.c b/gcc/testsuite/gcc.dg/diagnostic-range-bad-return-2.c
new file mode 100644
index 00000000000..2fe8d341dba
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/diagnostic-range-bad-return-2.c
@@ -0,0 +1,52 @@
+/* { dg-options "-fdiagnostics-show-caret -Wreturn-local-addr" } */
+
+int *address_of_local (void)
+{
+  int some_local;
+  return &some_local; /* { dg-warning "function returns address of local variable" } */
+/* { dg-begin-multiline-output "" }
+   return &some_local;
+          ^~~~~~~~~~~
+   { dg-end-multiline-output "" } */
+}
+
+void surplus_return_when_void_1 (void)
+{
+  return 500; /* { dg-error "'return' with a value, in function returning void" } */
+/* { dg-begin-multiline-output "" }
+   return 500;
+          ^~~
+   { dg-end-multiline-output "" } */
+/* { dg-begin-multiline-output "" }
+ void surplus_return_when_void_1 (void)
+      ^~~~~~~~~~~~~~~~~~~~~~~~~~
+   { dg-end-multiline-output "" } */
+}
+
+void surplus_return_when_void_2 (int i, int j)
+{
+  return i * j; /* { dg-error "'return' with a value, in function returning void" } */
+/* { dg-begin-multiline-output "" }
+   return i * j;
+          ~~^~~
+   { dg-end-multiline-output "" } */
+/* { dg-begin-multiline-output "" }
+ void surplus_return_when_void_2 (int i, int j)
+      ^~~~~~~~~~~~~~~~~~~~~~~~~~
+   { dg-end-multiline-output "" } */
+}
+
+int missing_return_value (void)
+{
+  return; /* { dg-error "'return' with no value, in function returning non-void" } */
+/* { dg-begin-multiline-output "" }
+   return;
+   ^~~~~~
+   { dg-end-multiline-output "" } */
+/* { dg-begin-multiline-output "" }
+ int missing_return_value (void)
+     ^~~~~~~~~~~~~~~~~~~~
+   { dg-end-multiline-output "" } */
+/* TODO: ideally we'd underline the return type i.e. "int", but that
+   location isn't captured.  */
+}
diff --git a/gcc/testsuite/gcc.dg/diagnostic-range-bad-return.c b/gcc/testsuite/gcc.dg/diagnostic-range-bad-return.c
index 063fdf1f636..b74481b870c 100644
--- a/gcc/testsuite/gcc.dg/diagnostic-range-bad-return.c
+++ b/gcc/testsuite/gcc.dg/diagnostic-range-bad-return.c
@@ -1,4 +1,4 @@
-/* { dg-options "-fdiagnostics-show-caret -Wreturn-local-addr" } */
+/* { dg-options "-fpermissive -fdiagnostics-show-caret -Wreturn-local-addr" } */
 
 int *address_of_local (void)
 {
diff --git a/gcc/testsuite/gcc.dg/permerror-default.c b/gcc/testsuite/gcc.dg/permerror-default.c
index 90f2220037c..9ed9814d69e 100644
--- a/gcc/testsuite/gcc.dg/permerror-default.c
+++ b/gcc/testsuite/gcc.dg/permerror-default.c
@@ -75,11 +75,11 @@ incompatible_pointer_types (int flag)
 void
 return_mismatch_1 (void)
 {
-  return 0; /* { dg-warning "'return' with a value, in function returning void \\\[-Wreturn-mismatch\\\]" } */
+  return 0; /* { dg-error "'return' with a value, in function returning void \\\[-Wreturn-mismatch\\\]" } */
 }
 
 int
 return_mismatch_2 (void)
 {
-  return; /* { dg-warning "return' with no value, in function returning non-void \\\[-Wreturn-mismatch\\\]" } */
+  return; /* { dg-error "return' with no value, in function returning non-void \\\[-Wreturn-mismatch\\\]" } */
 }
diff --git a/gcc/testsuite/gcc.dg/permerror-system.c b/gcc/testsuite/gcc.dg/permerror-system.c
index cad48c93f90..f00420358d9 100644
--- a/gcc/testsuite/gcc.dg/permerror-system.c
+++ b/gcc/testsuite/gcc.dg/permerror-system.c
@@ -27,3 +27,6 @@
 /* { dg-error "initialization of 'int \\\*' from 'int' makes pointer from integer without a cast \\\[-Wint-conversion\\\]" "" { target *-*-* } 45 } */
 /* { dg-error "assignment to 'int \\\*' from 'int' makes pointer from integer without a cast \\\[-Wint-conversion\\\]" "" { target *-*-* } 46 } */
 /* { dg-error "returning 'int \\\*' from a function with return type 'int' makes integer from pointer without a cast \\\[-Wint-conversion\\\]" "" { target *-*-* } 48 } */
+
+/* { dg-error "'return' with a value, in function returning void \\\[-Wreturn-mismatch\\\]" "" { target *-*-* } 78 } */
+/* { dg-error "return' with no value, in function returning non-void \\\[-Wreturn-mismatch\\\]" "" { target *-*-* } 84 } */
diff --git a/gcc/testsuite/gcc.dg/pr105635-2.c b/gcc/testsuite/gcc.dg/pr105635-2.c
index 807eef0b7cd..019dbc7e557 100644
--- a/gcc/testsuite/gcc.dg/pr105635-2.c
+++ b/gcc/testsuite/gcc.dg/pr105635-2.c
@@ -7,5 +7,5 @@ void foo (int, int[*]);	/* { dg-message "previous declaration of 'foo' with type
 foo (int x, int y)	/* { dg-error "return type defaults to 'int'" } */
 {			/* { dg-warning "conflicting types for 'foo'" "" { target *-*-* } .-1 } */
 			/* { dg-message "declared here" "" { target *-*-* } .-2 } */
-  return (x >= 0) != (y < 0);	/* { dg-warning "'return' with a value, in function returning void" } */
+  return (x >= 0) != (y < 0);	/* { dg-error "'return' with a value, in function returning void" } */
 }
diff --git a/gcc/testsuite/gcc.dg/pr23075-2.c b/gcc/testsuite/gcc.dg/pr23075-2.c
new file mode 100644
index 00000000000..0702ddf1a66
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr23075-2.c
@@ -0,0 +1,14 @@
+/* PR c/23075 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -Wreturn-type" } */
+
+int
+foo (void)
+{
+  return;	/* { dg-error "with no value" } */
+}		/* { dg-bogus "control reaches end" } */
+
+int
+bar (void)
+{
+}		/* { dg-warning "control reaches end" } */
diff --git a/gcc/testsuite/gcc.dg/pr23075.c b/gcc/testsuite/gcc.dg/pr23075.c
index 2d85fb0650f..28baf41006a 100644
--- a/gcc/testsuite/gcc.dg/pr23075.c
+++ b/gcc/testsuite/gcc.dg/pr23075.c
@@ -1,6 +1,6 @@
 /* PR c/23075 */
 /* { dg-do compile } */
-/* { dg-options "-O2 -Wreturn-type" } */
+/* { dg-options "-O2 -fpermissive -Wreturn-type" } */
 
 int
 foo (void)
diff --git a/gcc/testsuite/gcc.dg/pr29521-a.c b/gcc/testsuite/gcc.dg/pr29521-a.c
new file mode 100644
index 00000000000..2c6a48b7e30
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr29521-a.c
@@ -0,0 +1,15 @@
+/* PR 29521 : warning for return with expression in function returning void */
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+void func (void) { }
+
+void func2 (void)
+{
+  return func ();
+}
+
+void func3 (void)
+{
+  return 1;  /* { dg-error "'return' with a value" } */
+}
diff --git a/gcc/testsuite/gcc.dg/pr29521.c b/gcc/testsuite/gcc.dg/pr29521.c
index b6fb535fab7..cd431514ed2 100644
--- a/gcc/testsuite/gcc.dg/pr29521.c
+++ b/gcc/testsuite/gcc.dg/pr29521.c
@@ -1,6 +1,6 @@
 /* PR 29521 : warning for return with expression in function returning void */
 /* { dg-do compile } */
-/* { dg-options "" } */
+/* { dg-options "-fpermissive" } */
 
 void func (void) { }
 
diff --git a/gcc/testsuite/gcc.dg/pr67730-a.c b/gcc/testsuite/gcc.dg/pr67730-a.c
new file mode 100644
index 00000000000..08737cc9811
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr67730-a.c
@@ -0,0 +1,11 @@
+/* PR c/67730 */
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+#include <stddef.h>
+
+void
+fn1 (void)
+{
+  return NULL; /* { dg-error "10:.return. with a value" } */
+}
diff --git a/gcc/testsuite/gcc.dg/pr67730.c b/gcc/testsuite/gcc.dg/pr67730.c
index 54d73a62cf8..cc51858c531 100644
--- a/gcc/testsuite/gcc.dg/pr67730.c
+++ b/gcc/testsuite/gcc.dg/pr67730.c
@@ -1,6 +1,6 @@
 /* PR c/67730 */
 /* { dg-do compile } */
-/* { dg-options "" } */
+/* { dg-options "-fpermissive" } */
 
 #include <stddef.h>
 
diff --git a/gcc/testsuite/gcc.target/powerpc/conditional-return.c b/gcc/testsuite/gcc.target/powerpc/conditional-return.c
index 6b3ef5f52ca..c6491216752 100644
--- a/gcc/testsuite/gcc.target/powerpc/conditional-return.c
+++ b/gcc/testsuite/gcc.target/powerpc/conditional-return.c
@@ -1,7 +1,7 @@
 /* Check that a conditional return is used.  */
 
 /* { dg-do compile } */
-/* { dg-options "-O2 -w" } */
+/* { dg-options "-O2 -fpermissive -w" } */
 
 /* { dg-final { scan-assembler {\mbeqlr\M} } } */
 
-- 
2.41.0



^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH v2 7/8] c: Turn -Wincompatible-pointer-types into a permerror
  2023-11-14 17:50 [PATCH v2 0/8] Turn some C warnings into errors by default Florian Weimer
                   ` (5 preceding siblings ...)
  2023-11-14 17:50 ` [PATCH v2 6/8] c: Turn -Wreturn-mismatch into a permerror Florian Weimer
@ 2023-11-14 17:50 ` Florian Weimer
  2023-11-14 17:50 ` [PATCH v2 8/8] c: Add new -Wdeclaration-missing-parameter-type permerror Florian Weimer
  2023-11-15  5:16 ` [PATCH v2 0/8] Turn some C warnings into errors by default Sam James
  8 siblings, 0 replies; 17+ messages in thread
From: Florian Weimer @ 2023-11-14 17:50 UTC (permalink / raw)
  To: gcc-patches; +Cc: jason, jeffreyalaw, joseph, sam

The change to build_conditional_expr drops the downgrade
from a pedwarn to warning for builtins.

gcc/

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

gcc/c/

	PR c/96284
	* c-typeck.cc (build_conditional_expr): Upgrade most pointer
	type mismatches to a permerror.
	(convert_for_assignment): Use permerror_opt and
	permerror_init for OPT_Wincompatible_pointer_types warnings.

gcc/testsuite/

	* gcc.dg/permerror-default.c (incompatible_pointer_types):
	Expect new permerror.
	* gcc.dg/permerror-pedantic.c (incompatible_pointer_types):
	Likewise.
	* gcc.dg/permerror-system.c: Likewise.
	* gcc.dg/Wincompatible-pointer-types-2.c: Compile with
	-fpermissive	due to expected errors.
	* gcc.dg/Wincompatible-pointer-types-5.c: New test.  Copied
	from gcc.dg/Wincompatible-pointer-types-2.c.  Expect errors.
	* gcc.dg/anon-struct-11.c: Compile with -fpermissive
	due to expected errors.
	* gcc.dg/anon-struct-11a.c: New test.  Copied from
	gcc.dg/anon-struct-11.c.  Expect errors.
	* gcc.dg/anon-struct-13.c: Compile with -fpermissive
	due to expected errors.
	* gcc.dg/anon-struct-13a.c: New test.  Copied from
	gcc.dg/anon-struct-13.c.  Expect errors.
	* gcc.dg/builtin-arith-overflow-4.c: Compile with -fpermissive
	due to expected errors.
	* gcc.dg/builtin-arith-overflow-4a.c: New test.  Copied from
	gcc.dg/builtin-arith-overflow-4.c.  Expect errors.
	* gcc.dg/c23-qual-4.c: Expect -Wincompatible-pointer-types errors.
	* gcc.dg/dfp/composite-type.c: Compile with -fpermissive
	due to expected errors.
	* gcc.dg/dfp/composite-type-2.c: New test.  Copied from
	gcc.dg/dfp/composite-type.c.  Expect errors.
	* gcc.dg/diag-aka-1.c: Compile with -fpermissive
	due to expected errors.
	* gcc.dg/diag-aka-1a.c: New test.  Copied from gcc.dg/diag-aka-1a.c.
	Expect errors.
	* gcc.dg/enum-compat-1.c: Compile with -fpermissive
	due to expected errors.
	* gcc.dg/enum-compat-2.c: New test.  Copied from
	gcc.dg/enum-compat-1.c.  Expect errors.
	* gcc.dg/func-ptr-conv-1.c: Compile with -fpermissive
	due to expected errors.
	* gcc.dg/func-ptr-conv-2.c: New test.  Copied from
	gcc.dg/func-ptr-conv-1.c.  Expect errors.
	* gcc.dg/init-bad-7.c: Compile with -fpermissive
	due to expected errors.
	* gcc.dg/init-bad-7a.c: New test.  Copied from gcc.dg/init-bad-7.c.
	Expect errors.
	* gcc.dg/noncompile/incomplete-3.c (foo): Expect
	-Wincompatible-pointer-types error.
	* gcc.dg/param-type-mismatch-2.c (test8): Likewise.
	* gcc.dg/pointer-array-atomic.c: Compile with -fpermissive
	due to expected errors.
	* gcc.dg/pointer-array-atomic-2.c: New test.  Copied from
	gcc.dg/pointer-array-atomic.c.  Expect errors.
	* gcc.dg/pointer-array-quals-1.c (test): Expect
	-Wincompatible-pointer-types errors.
	* gcc.dg/transparent-union-1.c: Compile with -fpermissive
	due to expected errors.
	* gcc.dg/transparent-union-1a.c: New test.  Copied from
	gcc.dg/transparent-union-1.c.  Expect errors.
	* gcc.target/aarch64/acle/memtag_2a.c
	(test_memtag_warning_return_qualifier): Expect additional
	errors.
	* gcc.target/aarch64/sve/acle/general-c/load_2.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.target/aarch64/sve/acle/general-c/sizeless-1.c (f1): Likewise.
	* gcc.target/aarch64/sve/acle/general-c/sizeless-2.c (f1): Likewise.
	* gcc.target/aarch64/sve/acle/general-c/store_1.c (f1): Likewise.
	* gcc.target/aarch64/sve/acle/general-c/store_2.c (f1): Likewise.
	* gcc.target/aarch64/sve/acle/general-c/store_scatter_index_1.c
	(f1): Likewise.
	* gcc.target/aarch64/sve/acle/general-c/store_scatter_index_restricted_1.c
	(f1): Likewise.
	* gcc.target/aarch64/sve/acle/general-c/store_scatter_offset_2.c
	(f1): Likewise.
	* gcc.target/aarch64/sve/acle/general-c/store_scatter_offset_restricted_1.c
	(f1): Likewise.
	* gcc.target/aarch64/sve/acle/general/attributes_7.c
	(f1): Likewise.
	* gcc.target/i386/sse2-bfloat16-scalar-typecheck.c (footest):
	Expect -Wincompatible-pointer-types errors.
	* gcc.target/i386/vect-bfloat16-typecheck_1.c (footest): Likewise.
	* gcc.target/i386/vect-bfloat16-typecheck_2.c (footest): Likewise.
---
 gcc/c/c-typeck.cc                             |  63 +++++-----
 gcc/doc/invoke.texi                           |   6 +
 .../gcc.dg/Wincompatible-pointer-types-2.c    |   2 +-
 .../gcc.dg/Wincompatible-pointer-types-5.c    |  10 ++
 gcc/testsuite/gcc.dg/anon-struct-11.c         |   5 +-
 gcc/testsuite/gcc.dg/anon-struct-11a.c        | 111 ++++++++++++++++++
 gcc/testsuite/gcc.dg/anon-struct-13.c         |   2 +-
 gcc/testsuite/gcc.dg/anon-struct-13a.c        |  76 ++++++++++++
 .../gcc.dg/builtin-arith-overflow-4.c         |   2 +-
 .../gcc.dg/builtin-arith-overflow-4a.c        |  43 +++++++
 gcc/testsuite/gcc.dg/c23-qual-4.c             |   6 +-
 gcc/testsuite/gcc.dg/dfp/composite-type-2.c   |  58 +++++++++
 gcc/testsuite/gcc.dg/dfp/composite-type.c     |   2 +-
 gcc/testsuite/gcc.dg/diag-aka-1.c             |   2 +-
 gcc/testsuite/gcc.dg/diag-aka-1a.c            |  29 +++++
 gcc/testsuite/gcc.dg/enum-compat-1.c          |   2 +-
 gcc/testsuite/gcc.dg/enum-compat-2.c          |  32 +++++
 gcc/testsuite/gcc.dg/func-ptr-conv-1.c        |   2 +-
 gcc/testsuite/gcc.dg/func-ptr-conv-2.c        |  56 +++++++++
 gcc/testsuite/gcc.dg/init-bad-7.c             |   2 +-
 gcc/testsuite/gcc.dg/init-bad-7a.c            |  12 ++
 .../gcc.dg/noncompile/incomplete-3.c          |   2 +-
 gcc/testsuite/gcc.dg/param-type-mismatch-2.c  |   2 +-
 gcc/testsuite/gcc.dg/permerror-default.c      |  20 ++--
 gcc/testsuite/gcc.dg/permerror-pedantic.c     |   2 +-
 gcc/testsuite/gcc.dg/permerror-system.c       |  11 ++
 gcc/testsuite/gcc.dg/pointer-array-atomic-2.c |  60 ++++++++++
 gcc/testsuite/gcc.dg/pointer-array-atomic.c   |   2 +-
 gcc/testsuite/gcc.dg/pointer-array-quals-1.c  |   6 +-
 gcc/testsuite/gcc.dg/transparent-union-1.c    |   2 +-
 gcc/testsuite/gcc.dg/transparent-union-1a.c   |  85 ++++++++++++++
 .../gcc.target/aarch64/acle/memtag_2a.c       |   6 +-
 .../aarch64/sve/acle/general-c/load_2.c       |   4 +-
 .../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 +-
 .../aarch64/sve/acle/general-c/sizeless-1.c   |   8 +-
 .../aarch64/sve/acle/general-c/sizeless-2.c   |   8 +-
 .../aarch64/sve/acle/general-c/store_1.c      |   8 +-
 .../aarch64/sve/acle/general-c/store_2.c      |   8 +-
 .../acle/general-c/store_scatter_index_1.c    |   6 +-
 .../store_scatter_index_restricted_1.c        |   6 +-
 .../acle/general-c/store_scatter_offset_2.c   |   6 +-
 .../store_scatter_offset_restricted_1.c       |   6 +-
 .../aarch64/sve/acle/general/attributes_7.c   |  28 ++---
 .../i386/sse2-bfloat16-scalar-typecheck.c     |   4 +-
 .../i386/vect-bfloat16-typecheck_1.c          |   4 +-
 .../i386/vect-bfloat16-typecheck_2.c          |   4 +-
 54 files changed, 718 insertions(+), 121 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/Wincompatible-pointer-types-5.c
 create mode 100644 gcc/testsuite/gcc.dg/anon-struct-11a.c
 create mode 100644 gcc/testsuite/gcc.dg/anon-struct-13a.c
 create mode 100644 gcc/testsuite/gcc.dg/builtin-arith-overflow-4a.c
 create mode 100644 gcc/testsuite/gcc.dg/dfp/composite-type-2.c
 create mode 100644 gcc/testsuite/gcc.dg/diag-aka-1a.c
 create mode 100644 gcc/testsuite/gcc.dg/enum-compat-2.c
 create mode 100644 gcc/testsuite/gcc.dg/func-ptr-conv-2.c
 create mode 100644 gcc/testsuite/gcc.dg/init-bad-7a.c
 create mode 100644 gcc/testsuite/gcc.dg/pointer-array-atomic-2.c
 create mode 100644 gcc/testsuite/gcc.dg/transparent-union-1a.c

diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc
index f4b700117ff..39efb518835 100644
--- a/gcc/c/c-typeck.cc
+++ b/gcc/c/c-typeck.cc
@@ -5434,8 +5434,15 @@ build_conditional_expr (location_t colon_loc, tree ifexp, bool ifexp_bcp,
       else
 	{
 	  int qual = ENCODE_QUAL_ADDR_SPACE (as_common);
-	  if (emit_diagnostic (bltin1 && bltin2 ? DK_WARNING : DK_PEDWARN,
-			       colon_loc, OPT_Wincompatible_pointer_types,
+	  diagnostic_t kind = DK_PERMERROR;
+	  if (!flag_isoc99)
+	    /* This downgrade to a warning ensures that -std=gnu89
+	       -pedantic-errors does not flag these mismatches between
+	       builtins as errors (as DK_PERMERROR would).  ISO C99
+	       and later do not have implicit function declarations,
+	       so the mismatch cannot occur naturally there.  */
+	    kind = bltin1 && bltin2 ? DK_WARNING : DK_PEDWARN;
+	  if (emit_diagnostic (kind, colon_loc, OPT_Wincompatible_pointer_types,
 			       "pointer type mismatch "
 			       "in conditional expression"))
 	    {
@@ -7573,46 +7580,48 @@ convert_for_assignment (location_t location, location_t expr_loc, tree type,
 		auto_diagnostic_group d;
 		range_label_for_type_mismatch rhs_label (rhstype, type);
 		gcc_rich_location richloc (expr_loc, &rhs_label);
-		if (pedwarn (&richloc, OPT_Wincompatible_pointer_types,
-			     "passing argument %d of %qE from incompatible "
-			     "pointer type", parmnum, rname))
+		if (permerror_opt (&richloc, OPT_Wincompatible_pointer_types,
+				   "passing argument %d of %qE from "
+				   "incompatible pointer type",
+				   parmnum, rname))
 		  inform_for_arg (fundecl, expr_loc, parmnum, type, rhstype);
 	      }
 	      break;
 	    case ic_assign:
 	      if (bltin)
-		pedwarn (location, OPT_Wincompatible_pointer_types,
-			 "assignment to %qT from pointer to "
-			 "%qD with incompatible type %qT",
-			 type, bltin, rhstype);
+		permerror_opt (location, OPT_Wincompatible_pointer_types,
+			       "assignment to %qT from pointer to "
+			       "%qD with incompatible type %qT",
+			       type, bltin, rhstype);
 	      else
-		pedwarn (location, OPT_Wincompatible_pointer_types,
-			 "assignment to %qT from incompatible pointer type %qT",
-			 type, rhstype);
+		permerror_opt (location, OPT_Wincompatible_pointer_types,
+			       "assignment to %qT from incompatible pointer "
+			       "type %qT",
+			       type, rhstype);
 	      break;
 	    case ic_init:
 	    case ic_init_const:
 	      if (bltin)
-		pedwarn_init (location, OPT_Wincompatible_pointer_types,
-			      "initialization of %qT from pointer to "
-			      "%qD with incompatible type %qT",
-			      type, bltin, rhstype);
+		permerror_init (location, OPT_Wincompatible_pointer_types,
+				"initialization of %qT from pointer to "
+				"%qD with incompatible type %qT",
+				type, bltin, rhstype);
 	      else
-		pedwarn_init (location, OPT_Wincompatible_pointer_types,
-			      "initialization of %qT from incompatible "
-			      "pointer type %qT",
-			      type, rhstype);
+		permerror_init (location, OPT_Wincompatible_pointer_types,
+				"initialization of %qT from incompatible "
+				"pointer type %qT",
+				type, rhstype);
 	      break;
 	    case ic_return:
 	      if (bltin)
-		pedwarn (location, OPT_Wincompatible_pointer_types,
-			 "returning pointer to %qD of type %qT from "
-			 "a function with incompatible type %qT",
-			 bltin, rhstype, type);
+		permerror_opt (location, OPT_Wincompatible_pointer_types,
+			       "returning pointer to %qD of type %qT from "
+			       "a function with incompatible type %qT",
+			       bltin, rhstype, type);
 	      else
-		pedwarn (location, OPT_Wincompatible_pointer_types,
-			 "returning %qT from a function with incompatible "
-			 "return type %qT", rhstype, type);
+		permerror_opt (location, OPT_Wincompatible_pointer_types,
+			       "returning %qT from a function with "
+			       "incompatible return type %qT", rhstype, type);
 	      break;
 	    default:
 	      gcc_unreachable ();
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 7edc142f787..c492ef7ba0c 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -6181,6 +6181,7 @@ that have their own flag:
 @gccoptlist{
 -Wimplicit-function-declaration @r{(C)}
 -Wimplicit-int @r{(C)}
+-Wincompatible-pointer-types @r{(C)}
 -Wint-conversion @r{(C)}
 -Wnarrowing @r{(C++)}
 -Wreturn-mismatch @r{(C)}
@@ -8547,6 +8548,11 @@ types.  This warning is for cases not covered by @option{-Wno-pointer-sign},
 which warns for pointer argument passing or assignment with different
 signedness.
 
+By default, in C99 and later dialects of C, GCC treats this issue as an
+error.  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=incompatible-pointer-types}.
+
 This warning is upgraded to an error by @option{-pedantic-errors}.
 
 @opindex Wno-int-conversion
diff --git a/gcc/testsuite/gcc.dg/Wincompatible-pointer-types-2.c b/gcc/testsuite/gcc.dg/Wincompatible-pointer-types-2.c
index 19276bbcfba..bbf983c1536 100644
--- a/gcc/testsuite/gcc.dg/Wincompatible-pointer-types-2.c
+++ b/gcc/testsuite/gcc.dg/Wincompatible-pointer-types-2.c
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "" } */
+/* { dg-options "-fpermissive" } */
 
 void *
 f1 (int flag, int *a, long *b)
diff --git a/gcc/testsuite/gcc.dg/Wincompatible-pointer-types-5.c b/gcc/testsuite/gcc.dg/Wincompatible-pointer-types-5.c
new file mode 100644
index 00000000000..dcbfa4767de
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wincompatible-pointer-types-5.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+void *
+f1 (int flag, int *a, long *b)
+{
+  return flag ? a : b; /* { dg-error "pointer type mismatch in conditional expression \\\[-Wincompatible-pointer-types\\\]" } */
+  /* { dg-note "first expression has type 'int \\*'" "" { target *-*-* } .-1 } */
+  /* { dg-note "second expression has type 'long int \\*'" "" { target *-*-* } .-2 } */
+}
diff --git a/gcc/testsuite/gcc.dg/anon-struct-11.c b/gcc/testsuite/gcc.dg/anon-struct-11.c
index c2f85fc24e4..622fb7cacc6 100644
--- a/gcc/testsuite/gcc.dg/anon-struct-11.c
+++ b/gcc/testsuite/gcc.dg/anon-struct-11.c
@@ -1,8 +1,7 @@
 /* { dg-do compile } */
 
-/* No special options--in particular, turn off the default
-   -pedantic-errors option.  */
-/* { dg-options "" } */
+/* Also turn off the default -pedantic-errors option.  */
+/* { dg-options "-fpermissive" } */
 
 /* When not using -fplan9-extensions, we don't support automatic
    conversion of pointer types, and we don't support referring to a
diff --git a/gcc/testsuite/gcc.dg/anon-struct-11a.c b/gcc/testsuite/gcc.dg/anon-struct-11a.c
new file mode 100644
index 00000000000..9ee3bb63ebf
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/anon-struct-11a.c
@@ -0,0 +1,111 @@
+/* { dg-do compile } */
+
+/* No special options--in particular, turn off the default
+   -pedantic-errors option.  */
+/* { dg-options "" } */
+
+/* When not using -fplan9-extensions, we don't support automatic
+   conversion of pointer types, and we don't support referring to a
+   typedef name directly.  */
+
+extern void exit (int);
+extern void abort (void);
+
+struct A { char a; };
+
+struct B {
+  char b;
+  struct A;		/* { dg-warning "does not declare anything" } */
+  char c;
+};
+
+void
+f1 (struct A *p)	/* { dg-message "expected" } */
+{
+  p->a = 1;
+}
+
+void
+test1 (void)
+{
+  struct B b;
+  struct A *p;
+
+  b.b = 2;
+  b.c = 3;
+  f1 (&b);		/* { dg-error "incompatible pointer type" } */
+  if (b.a != 1)		/* { dg-error "no member" } */
+    abort ();
+  if (b.b != 2 || b.c != 3)
+    abort ();
+  p = &b;		/* { dg-error "incompatible pointer type" } */
+  if (p->a != 1)
+    abort ();
+}
+
+typedef struct { char d; } D;
+
+struct E {
+  char b;
+  struct F { char f; };	/* { dg-warning "does not declare anything" } */
+  char c;
+  union {
+    D;			/* { dg-warning "does not declare anything" } */
+  };
+  char e;
+};
+
+void
+f2 (struct F *p)	/* { dg-message "expected" } */
+{
+  p->f = 6;
+}
+
+void
+f3 (D *p)		/* { dg-message "expected" } */
+{
+  p->d = 4;
+}
+
+void
+f4 (D d)
+{
+}
+
+void
+test2 (void)
+{
+  struct E e;
+  struct F *pf;
+  D *pd;
+  D d;
+
+  e.b = 2;
+  e.c = 3;
+  e.e = 5;
+  f2 (&e);		/* { dg-error "incompatible pointer type" } */
+  f3 (&e);		/* { dg-error "incompatible pointer type" } */
+  if (e.d != 4)		/* { dg-error "no member" } */
+    abort ();
+  if (e.f != 6)		/* { dg-error "no member" } */
+    abort ();
+  if (e.b != 2 || e.c != 3 || e.e != 5)
+    abort ();
+  pf = &e;		/* { dg-error "incompatible pointer type" } */
+  if (pf->f != 6)
+    abort ();
+  pd = &e;		/* { dg-error "incompatible pointer type" } */
+  if (pd->d != 4)
+    abort ();
+  d = e.D;		/* { dg-error "no member" } */
+  f3 (&e.D);		/* { dg-error "no member" } */
+  f4 (e.D);		/* { dg-error "no member" } */
+}
+
+int
+main ()
+{
+  test1 ();
+  test2 ();
+  exit (0);
+}
diff --git a/gcc/testsuite/gcc.dg/anon-struct-13.c b/gcc/testsuite/gcc.dg/anon-struct-13.c
index 6a508141bac..de478b9684b 100644
--- a/gcc/testsuite/gcc.dg/anon-struct-13.c
+++ b/gcc/testsuite/gcc.dg/anon-struct-13.c
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-fplan9-extensions" } */
+/* { dg-options "-fpermissive -fplan9-extensions" } */
 
 /* Test for ambiguity when using the Plan 9 extensions.  */
 
diff --git a/gcc/testsuite/gcc.dg/anon-struct-13a.c b/gcc/testsuite/gcc.dg/anon-struct-13a.c
new file mode 100644
index 00000000000..9e6c5d96595
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/anon-struct-13a.c
@@ -0,0 +1,76 @@
+/* { dg-do compile } */
+/* { dg-options "-fplan9-extensions" } */
+
+/* Test for ambiguity when using the Plan 9 extensions.  */
+
+struct A {
+  char a;		/* { dg-error "duplicate member" } */
+};
+
+struct B
+{
+  struct A;
+  struct A;
+};
+
+char
+f1 (struct B *p)
+{
+  return p->a;		/* { dg-error "no member" } */
+}
+
+void
+f2 (struct A *p)	/* { dg-message "expected" } */
+{
+}
+
+void
+f3 (struct B *p)
+{
+  f2 (p);		/* { dg-error "incompatible pointer type" } */
+}
+
+struct C
+{
+  char c;		/* { dg-error "duplicate member" } */
+};
+
+struct D
+{
+  struct C;
+};
+
+struct E
+{
+  struct C;
+  struct D;
+};
+
+char
+f4 (struct E *p)
+{
+  return p->c;		/* { dg-error "no member" } */
+}
+
+void
+f6 (struct C *p)	/* { dg-message "expected" } */
+{
+}
+
+void
+f7 (struct E *p)
+{
+  f6 (p);		/* { dg-error "incompatible pointer type" } */
+}
+
+struct A
+f8 (struct B *p)
+{
+  return p->A;		/* { dg-error "no member" } */
+}
+
+struct C
+f9 (struct E *p)
+{
+  return p->C;		/* { dg-error "no member" } */
+}
diff --git a/gcc/testsuite/gcc.dg/builtin-arith-overflow-4.c b/gcc/testsuite/gcc.dg/builtin-arith-overflow-4.c
index ab7d82a8d83..4c2c89ff616 100644
--- a/gcc/testsuite/gcc.dg/builtin-arith-overflow-4.c
+++ b/gcc/testsuite/gcc.dg/builtin-arith-overflow-4.c
@@ -1,6 +1,6 @@
 /* PR c/90628 */
 /* { dg-do compile } */
-/* { dg-options "" } */
+/* { dg-options "-fpermissive" } */
 
 _Atomic int a = 1, b = 2, c = 3;
 _Atomic long d = 4, e = 5, f = 6;
diff --git a/gcc/testsuite/gcc.dg/builtin-arith-overflow-4a.c b/gcc/testsuite/gcc.dg/builtin-arith-overflow-4a.c
new file mode 100644
index 00000000000..c021cabdc24
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/builtin-arith-overflow-4a.c
@@ -0,0 +1,43 @@
+/* PR c/90628 */
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+_Atomic int a = 1, b = 2, c = 3;
+_Atomic long d = 4, e = 5, f = 6;
+_Atomic long long g = 7, h = 8, i = 9;
+
+void
+f1 ()
+{
+  __builtin_add_overflow (a, b, &c);	/* { dg-error "argument 3 in call to function '__builtin_add_overflow' has pointer to '_Atomic' type" } */
+}
+
+void
+f2 ()
+{
+  __builtin_sub_overflow (d, e, &f);	/* { dg-error "argument 3 in call to function '__builtin_sub_overflow' has pointer to '_Atomic' type" } */
+}
+
+void
+f3 ()
+{
+  __builtin_mul_overflow (g, h, &i);	/* { dg-error "argument 3 in call to function '__builtin_mul_overflow' has pointer to '_Atomic' type" } */
+}
+
+void
+f4 ()
+{
+  __builtin_sadd_overflow (a, b, &c);	/* { dg-error "passing argument 3 of '__builtin_sadd_overflow' from incompatible pointer type" } */
+}
+
+void
+f5 ()
+{
+  __builtin_ssubl_overflow (d, e, &f);	/* { dg-error "passing argument 3 of '__builtin_ssubl_overflow' from incompatible pointer type" } */
+}
+
+void
+f6 ()
+{
+  __builtin_smulll_overflow (g, h, &i);	/* { dg-error "passing argument 3 of '__builtin_smulll_overflow' from incompatible pointer type" } */
+}
diff --git a/gcc/testsuite/gcc.dg/c23-qual-4.c b/gcc/testsuite/gcc.dg/c23-qual-4.c
index 8a7a9f2be35..a8538de74e8 100644
--- a/gcc/testsuite/gcc.dg/c23-qual-4.c
+++ b/gcc/testsuite/gcc.dg/c23-qual-4.c
@@ -83,9 +83,9 @@ void test(void)
 	(void)(1 ? x0 : z0);
 	(void)(1 ? x1 : z1);
 	(void)(1 ? x2 : z2);
-	(void)(1 ? x0 : x1); /* { dg-warning "pointer type mismatch in conditional expression" } */
-	(void)(1 ? x1 : x2); /* { dg-warning "pointer type mismatch in conditional expression" } */
-	(void)(1 ? x2 : x0); /* { dg-warning "pointer type mismatch in conditional expression" } */
+	(void)(1 ? x0 : x1); /* { dg-error "pointer type mismatch in conditional expression" } */
+	(void)(1 ? x1 : x2); /* { dg-error "pointer type mismatch in conditional expression" } */
+	(void)(1 ? x2 : x0); /* { dg-error "pointer type mismatch in conditional expression" } */
 	v0p = (1 ? z0 : v0p); /* { dg-warning "assignment discards 'const' qualifier from pointer target type" } */
 	v1p = (1 ? z1 : v1p); /* { dg-warning "assignment discards 'const' qualifier from pointer target type" } */
 	v2p = (1 ? z2 : v2p); /* { dg-warning "assignment discards 'const' qualifier from pointer target type" } */
diff --git a/gcc/testsuite/gcc.dg/dfp/composite-type-2.c b/gcc/testsuite/gcc.dg/dfp/composite-type-2.c
new file mode 100644
index 00000000000..5c6d95cc200
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/dfp/composite-type-2.c
@@ -0,0 +1,58 @@
+/* { dg-do compile } */
+/* { dg-options "-O -Wall -ftrack-macro-expansion=0" } */
+
+/* C99 6.2.7: Compatible type and composite type.  */
+
+#define DECIMAL_COMPOSITE_DECL(TYPE) \
+  _Decimal##TYPE g1_##TYPE(); \
+  _Decimal##TYPE g2_##TYPE(); \
+  _Decimal##TYPE (*h1_##TYPE)[2]; \
+  _Decimal##TYPE (*h2_##TYPE)[3]; \
+  _Decimal##TYPE (*h3_##TYPE)[4]; \
+  _Decimal##TYPE f1_##TYPE(_Decimal##TYPE(*)()); \
+  _Decimal##TYPE f1_##TYPE(_Decimal##TYPE(*)(_Decimal##TYPE*)); \
+  _Decimal##TYPE f1_##TYPE (_Decimal##TYPE(*g)(_Decimal##TYPE*)) \
+   { \
+     _Decimal##TYPE d##TYPE; \
+     d##TYPE = ((_Decimal##TYPE (*) (_Decimal##TYPE*)) g)(&d##TYPE); \
+     d##TYPE = ((_Decimal##TYPE (*) ()) g); \
+     return d##TYPE; \
+   } \
+   _Decimal##TYPE f2_##TYPE(_Decimal##TYPE(*)[]); \
+   _Decimal##TYPE f2_##TYPE(_Decimal##TYPE(*)[3]);
+
+#define DECIMAL_COMPOSITE_TEST(TYPE) \
+do \
+{ \
+ _Decimal##TYPE d##TYPE; \
+ d##TYPE = f1_##TYPE(g1_##TYPE); \
+ d##TYPE = f1_##TYPE(g2_##TYPE); \
+ d##TYPE = f2_##TYPE(h1_##TYPE); \
+ d##TYPE = f2_##TYPE(h2_##TYPE); \
+ d##TYPE = f2_##TYPE(h3_##TYPE); \
+ (void) d##TYPE; \
+} while(0)
+ 
+DECIMAL_COMPOSITE_DECL(32);  /* { dg-error "incompatible types when assigning to type '\[^\n\]*' from type '\[^\n\]*'" } */
+/* { dg-message "note: expected '\[^'\n\]*' but argument is of type '\[^'\n\]*'" "note: expected" { target *-*-* } .-1 } */
+
+
+DECIMAL_COMPOSITE_DECL(64);  /* { dg-error "incompatible types when assigning to type '\[^\n\]*' from type '\[^\n\]*'" } */
+/* { dg-message "note: expected '\[^'\n\]*' but argument is of type '\[^'\n\]*'" "note: expected" { target *-*-* } .-1 } */
+
+
+DECIMAL_COMPOSITE_DECL(128); /* { dg-error "incompatible types when assigning to type '\[^\n\]*' from type '\[^\n\]*'" } */
+/* { dg-message "note: expected '\[^'\n\]*' but argument is of type '\[^'\n\]*'" "note: expected" { target *-*-* } .-1 } */
+
+
+int main()
+{
+  DECIMAL_COMPOSITE_TEST(32);  /* { dg-error "incompatible pointer type" } */
+  DECIMAL_COMPOSITE_TEST(64);  /* { dg-error "incompatible pointer type" } */
+  DECIMAL_COMPOSITE_TEST(128); /* { dg-error "incompatible pointer type" } */
+
+  return 0;
+}
+
+/* The invalid function redeclarations might also trigger:
+   { dg-prune-output "-Warray-parameter" } */
diff --git a/gcc/testsuite/gcc.dg/dfp/composite-type.c b/gcc/testsuite/gcc.dg/dfp/composite-type.c
index ce7d5c1a0a0..2eb601400b5 100644
--- a/gcc/testsuite/gcc.dg/dfp/composite-type.c
+++ b/gcc/testsuite/gcc.dg/dfp/composite-type.c
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O -Wall -ftrack-macro-expansion=0" } */
+/* { dg-options "-fpermissive -O -Wall -ftrack-macro-expansion=0" } */
 
 /* C99 6.2.7: Compatible type and composite type.  */
 
diff --git a/gcc/testsuite/gcc.dg/diag-aka-1.c b/gcc/testsuite/gcc.dg/diag-aka-1.c
index 3383c1c263b..485a8a5f85d 100644
--- a/gcc/testsuite/gcc.dg/diag-aka-1.c
+++ b/gcc/testsuite/gcc.dg/diag-aka-1.c
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-Wc++-compat" } */
+/* { dg-options "-fpermissive -Wc++-compat" } */
 
 typedef struct A { int i; } B;
 typedef struct T { int i; } *T; /* { dg-warning "using 'T' as both a typedef and a tag is invalid" } */
diff --git a/gcc/testsuite/gcc.dg/diag-aka-1a.c b/gcc/testsuite/gcc.dg/diag-aka-1a.c
new file mode 100644
index 00000000000..d161b785e7d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/diag-aka-1a.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-options "-Wc++-compat" } */
+
+typedef struct A { int i; } B;
+typedef struct T { int i; } *T; /* { dg-warning "using 'T' as both a typedef and a tag is invalid" } */
+typedef const float TFA;
+typedef TFA TFB;
+typedef TFB TFC;
+typedef int IA[];
+typedef IA *IAP;
+extern IAP arr[];
+
+void fn1 (B *); /* { dg-message "expected 'B \\*' {aka 'struct A \\*'} but argument is of type 'struct B \\*'" } */
+void fn2 (TFC *);
+
+void 
+bar (B *b, int *i)
+{
+  fn1 ((struct B *) b); /* { dg-error "passing argument" } */
+  fn2 (i); /* { dg-error "passing argument" } */
+  sizeof (arr); /* { dg-error "invalid application of .sizeof. to incomplete type .int \\(\\*\\\[\\\]\\)\\\[\\\]." } */
+}
+
+int
+foo (void *a)
+{
+  T t = a; /* { dg-warning "request for implicit conversion from 'void \\*' to 'T' {aka 'struct T \\*'} not" } */
+  return t->i;
+}
diff --git a/gcc/testsuite/gcc.dg/enum-compat-1.c b/gcc/testsuite/gcc.dg/enum-compat-1.c
index 5fb150cee79..b7352f6ddc3 100644
--- a/gcc/testsuite/gcc.dg/enum-compat-1.c
+++ b/gcc/testsuite/gcc.dg/enum-compat-1.c
@@ -3,7 +3,7 @@
 /* Origin: Joseph Myers <jsm@polyomino.org.uk>, based on
    PR c/6024 from Richard Earnshaw <rearnsha@arm.com> */
 /* { dg-do compile } */
-/* { dg-options "" } */
+/* { dg-options "-fpermissive" } */
 
 /* Original test from PR c/6024.  */
 enum e1 {a, b};
diff --git a/gcc/testsuite/gcc.dg/enum-compat-2.c b/gcc/testsuite/gcc.dg/enum-compat-2.c
new file mode 100644
index 00000000000..69509012480
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/enum-compat-2.c
@@ -0,0 +1,32 @@
+/* Test that enumerated types are only considered compatible when they
+   are the same type.  PR c/6024.  */
+/* Origin: Joseph Myers <jsm@polyomino.org.uk>, based on
+   PR c/6024 from Richard Earnshaw <rearnsha@arm.com> */
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+/* Original test from PR c/6024.  */
+enum e1 {a, b};
+enum e2 {c, d};
+
+void f(enum e1); /* { dg-error "prototype" "error at decl" } */
+
+void f(x)
+     enum e2 x; /* { dg-error "doesn't match prototype" } */
+{
+  return;
+}
+
+/* Other compatibility tests.  */
+enum e3 { A };
+enum e4 { B };
+
+enum e3 v3;
+enum e4 *p = &v3; /* { dg-error "incompatible" "incompatible pointer" } */
+enum e3 *q = &v3;
+
+void g(enum e3); /* { dg-message "note: previous declaration" "error at first decl" } */
+void g(enum e4); /* { dg-error "conflicting types" "error at second decl" } */
+
+void h(enum e3);
+void h(enum e3);
diff --git a/gcc/testsuite/gcc.dg/func-ptr-conv-1.c b/gcc/testsuite/gcc.dg/func-ptr-conv-1.c
index 5c8a101343e..7c2876cc998 100644
--- a/gcc/testsuite/gcc.dg/func-ptr-conv-1.c
+++ b/gcc/testsuite/gcc.dg/func-ptr-conv-1.c
@@ -5,7 +5,7 @@
    are not permitted.  PR c/11234.  */
 /* Origin: Joseph Myers <jsm@polyomino.org.uk> */
 /* { dg-do compile } */
-/* { dg-options "-pedantic" } */
+/* { dg-options "-fpermissive -pedantic" } */
 
 void f(void);
 
diff --git a/gcc/testsuite/gcc.dg/func-ptr-conv-2.c b/gcc/testsuite/gcc.dg/func-ptr-conv-2.c
new file mode 100644
index 00000000000..a9884a6c919
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/func-ptr-conv-2.c
@@ -0,0 +1,56 @@
+/* Conversions between function and object pointers are not permitted
+   in any version of ISO C, even with casts, except for the special
+   case of converting a null pointer constant to function pointer
+   type.  Likewise, comparisons between function and object pointers
+   are not permitted.  PR c/11234.  */
+/* Origin: Joseph Myers <jsm@polyomino.org.uk> */
+/* { dg-do compile } */
+/* { dg-options "-pedantic" } */
+
+void f(void);
+
+void *v1 = f; /* { dg-warning "12:pointer" "bad conversion" } */
+void *v2 = &f; /* { dg-warning "12:pointer" "bad conversion" } */
+void *v3 = (void *)f; /* { dg-warning "12:pointer" "bad conversion" } */
+void *v4 = (void *)&f; /* { dg-warning "12:pointer" "bad conversion" } */
+void *v5;
+char *c1 = f; /* { dg-error "12:pointer" "bad conversion" } */
+char *c2 = &f; /* { dg-error "12:pointer" "bad conversion" } */
+char *c3 = (char *)f; /* { dg-warning "12:pointer" "bad conversion" } */
+char *c4 = (char *)&f; /* { dg-warning "12:pointer" "bad conversion" } */
+char *c5;
+void (*fp)(void);
+int a;
+
+void
+g(void)
+{
+  v5 = f; /* { dg-warning "6:pointer" "bad conversion" } */
+  v5 = &f; /* { dg-warning "6:pointer" "bad conversion" } */
+  v5 = (void *)f; /* { dg-warning "8:pointer" "bad conversion" } */
+  v5 = (void *)&f; /* { dg-warning "8:pointer" "bad conversion" } */
+  c5 = f; /* { dg-error "6:pointer" "bad conversion" } */
+  c5 = &f; /* { dg-error "6:pointer" "bad conversion" } */
+  c5 = (char *)f; /* { dg-warning "8:pointer" "bad conversion" } */
+  c5 = (char *)&f; /* { dg-warning "8:pointer" "bad conversion" } */
+  fp = v5; /* { dg-warning "6:pointer" "bad conversion" } */
+  fp = c5; /* { dg-error "6:pointer" "bad conversion" } */
+  fp = (void (*)(void))v5; /* { dg-warning "8:pointer" "bad conversion" } */
+  fp = (void (*)(void))c5; /* { dg-warning "8:pointer" "bad conversion" } */
+  (a ? f : v3); /* { dg-warning "10:pointer" "bad conversion" } */
+  (a ? v2 : fp); /* { dg-warning "11:pointer" "bad conversion" } */
+  /* The following are OK.  */
+  fp = 0;
+  fp = (void *)0;
+  fp = 0L;
+  fp = (void (*)(void))0;
+  fp = (void (*)(void))(void *)0;
+  (a ? f : 0);
+  (a ? f : (void *)0);
+  (a ? (void *)0 : fp);
+  (a ? 0 : fp);
+}
+
+/* The following are OK.  */
+void (*fp2)(void) = 0;
+void (*fp3)(void) = (void *)0;
diff --git a/gcc/testsuite/gcc.dg/init-bad-7.c b/gcc/testsuite/gcc.dg/init-bad-7.c
index de5e570978c..caa8c783d65 100644
--- a/gcc/testsuite/gcc.dg/init-bad-7.c
+++ b/gcc/testsuite/gcc.dg/init-bad-7.c
@@ -1,6 +1,6 @@
 /* PR c/37724 */
 /* { dg-do compile } */
-/* { dg-options "-std=gnu99 -pedantic" } */
+/* { dg-options "-fpermissive -std=gnu99 -pedantic" } */
 
 struct f
 {
diff --git a/gcc/testsuite/gcc.dg/init-bad-7a.c b/gcc/testsuite/gcc.dg/init-bad-7a.c
new file mode 100644
index 00000000000..9ead2901c4c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/init-bad-7a.c
@@ -0,0 +1,12 @@
+/* PR c/37724 */
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+struct f
+{
+  int *a;
+};
+
+char b[10];
+struct f g = {b}; /* { dg-error "initialization of 'int \\*' from incompatible pointer type" } */
+/* { dg-note "near initialization for" "" { target *-*-* } .-1 } */
diff --git a/gcc/testsuite/gcc.dg/noncompile/incomplete-3.c b/gcc/testsuite/gcc.dg/noncompile/incomplete-3.c
index 0618b4d8170..b783052d145 100644
--- a/gcc/testsuite/gcc.dg/noncompile/incomplete-3.c
+++ b/gcc/testsuite/gcc.dg/noncompile/incomplete-3.c
@@ -4,6 +4,6 @@ typedef struct { int a; } b_t;
 int foo (void)
 {
   b_t d;
-  struct b_t *c = &d;	/* { dg-warning "incompatible pointer type" } */
+  struct b_t *c = &d;	/* { dg-error "incompatible pointer type" } */
   c->a;			/* { dg-error "invalid use of undefined type" } */
 }
diff --git a/gcc/testsuite/gcc.dg/param-type-mismatch-2.c b/gcc/testsuite/gcc.dg/param-type-mismatch-2.c
index 91d998437d1..83bc360fbc9 100644
--- a/gcc/testsuite/gcc.dg/param-type-mismatch-2.c
+++ b/gcc/testsuite/gcc.dg/param-type-mismatch-2.c
@@ -152,7 +152,7 @@ extern int callee_8 (int one, float *two, float (three)); /* { dg-line callee_8
 
 int test_8 (int first, int *second, float third)
 {
-  return callee_8 (first, second, third); /* { dg-warning "passing argument 2 of 'callee_8' from incompatible pointer type" } */
+  return callee_8 (first, second, third); /* { dg-error "passing argument 2 of 'callee_8' from incompatible pointer type" } */
   /* { dg-begin-multiline-output "" }
    return callee_8 (first, second, third);
                            ^~~~~~
diff --git a/gcc/testsuite/gcc.dg/permerror-default.c b/gcc/testsuite/gcc.dg/permerror-default.c
index 9ed9814d69e..45b58b0131d 100644
--- a/gcc/testsuite/gcc.dg/permerror-default.c
+++ b/gcc/testsuite/gcc.dg/permerror-default.c
@@ -52,24 +52,24 @@ int *
 incompatible_pointer_types (int flag)
 {
   void f4 (int *);
-  flag ? __builtin_abs : __builtin_labs; /* { dg-warning "pointer type mismatch in conditional expression \\\[-Wincompatible-pointer-types\\\]" } */
+  flag ? __builtin_abs : __builtin_labs; /* { dg-error "pointer type mismatch in conditional expression \\\[-Wincompatible-pointer-types\\\]" } */
   {
-    int *p1 = __builtin_abs; /* { dg-warning "initialization of 'int \\\*' from pointer to '__builtin_abs' with incompatible type 'int \\\(\\\*\\\)\\\(int\\\)' \\\[-Wincompatible-pointer-types\\\]" } */
-    p1 = __builtin_abs; /* { dg-warning "assignment to 'int \\\*' from pointer to '__builtin_abs' with incompatible type 'int \\\(\\\*\\\)\\\(int\\\)' \\\[-Wincompatible-pointer-types\\\]" } */
+    int *p1 = __builtin_abs; /* { dg-error "initialization of 'int \\\*' from pointer to '__builtin_abs' with incompatible type 'int \\\(\\\*\\\)\\\(int\\\)' \\\[-Wincompatible-pointer-types\\\]" } */
+    p1 = __builtin_abs; /* { dg-error "assignment to 'int \\\*' from pointer to '__builtin_abs' with incompatible type 'int \\\(\\\*\\\)\\\(int\\\)' \\\[-Wincompatible-pointer-types\\\]" } */
   }
   {
-    int *p2 = incompatible_pointer_types; /* { dg-warning "initialization of 'int \\\*' from incompatible pointer type 'int \\\* \\\(\\\*\\\)\\\(int\\\)' \\\[-Wincompatible-pointer-types\\\]" } */
-    p2 = incompatible_pointer_types; /* { dg-warning "assignment to 'int \\\*' from incompatible pointer type 'int \\\* \\\(\\\*\\\)\\\(int\\\)' \\\[-Wincompatible-pointer-types\\\]" } */
+    int *p2 = incompatible_pointer_types; /* { dg-error "initialization of 'int \\\*' from incompatible pointer type 'int \\\* \\\(\\\*\\\)\\\(int\\\)' \\\[-Wincompatible-pointer-types\\\]" } */
+    p2 = incompatible_pointer_types; /* { dg-error "assignment to 'int \\\*' from incompatible pointer type 'int \\\* \\\(\\\*\\\)\\\(int\\\)' \\\[-Wincompatible-pointer-types\\\]" } */
     {
-      int *p3 = &p2; /* { dg-warning "initialization of 'int \\\*' from incompatible pointer type 'int \\\*\\\*' \\\[-Wincompatible-pointer-types\\\]" } */
-      p3 = &p2; /* { dg-warning "assignment to 'int \\\*' from incompatible pointer type 'int \\\*\\\*' \\\[-Wincompatible-pointer-types\\\]" } */
+      int *p3 = &p2; /* { dg-error "initialization of 'int \\\*' from incompatible pointer type 'int \\\*\\\*' \\\[-Wincompatible-pointer-types\\\]" } */
+      p3 = &p2; /* { dg-error "assignment to 'int \\\*' from incompatible pointer type 'int \\\*\\\*' \\\[-Wincompatible-pointer-types\\\]" } */
     }
-    f4 (&p2); /* { dg-warning "passing argument 1 of 'f4' from incompatible pointer type \\\[-Wincompatible-pointer-types\\\]" } */
+    f4 (&p2); /* { dg-error "passing argument 1 of 'f4' from incompatible pointer type \\\[-Wincompatible-pointer-types\\\]" } */
   }
   if (flag)
-    return __builtin_abs; /* { dg-warning "returning pointer to '__builtin_abs' of type 'int \\\(\\\*\\\)\\\(int\\\)' from a function with incompatible type 'int \\\*' \\\[-Wincompatible-pointer-types\\\]" } */
+    return __builtin_abs; /* { dg-error "returning pointer to '__builtin_abs' of type 'int \\\(\\\*\\\)\\\(int\\\)' from a function with incompatible type 'int \\\*' \\\[-Wincompatible-pointer-types\\\]" } */
   else
-    return incompatible_pointer_types; /* { dg-warning "returning 'int \\\* \\\(\\\*\\\)\\\(int\\\)' from a function with incompatible return type 'int \\\*' \\\[-Wincompatible-pointer-types\\\]" } */
+    return incompatible_pointer_types; /* { dg-error "returning 'int \\\* \\\(\\\*\\\)\\\(int\\\)' from a function with incompatible return type 'int \\\*' \\\[-Wincompatible-pointer-types\\\]" } */
 }
 
 void
diff --git a/gcc/testsuite/gcc.dg/permerror-pedantic.c b/gcc/testsuite/gcc.dg/permerror-pedantic.c
index 852e7daa38d..95dda18acd4 100644
--- a/gcc/testsuite/gcc.dg/permerror-pedantic.c
+++ b/gcc/testsuite/gcc.dg/permerror-pedantic.c
@@ -52,7 +52,7 @@ int *
 incompatible_pointer_types (int flag)
 {
   void f4 (int *);
-  flag ? __builtin_abs : __builtin_labs; /* { dg-warning "pointer type mismatch in conditional expression \\\[-Wincompatible-pointer-types\\\]" } */
+  flag ? __builtin_abs : __builtin_labs; /* { dg-error "pointer type mismatch in conditional expression \\\[-Wincompatible-pointer-types\\\]" } */
   {
     int *p1 = __builtin_abs; /* { dg-error "initialization of 'int \\\*' from pointer to '__builtin_abs' with incompatible type 'int \\\(\\\*\\\)\\\(int\\\)' \\\[-Wincompatible-pointer-types\\\]" } */
     p1 = __builtin_abs; /* { dg-error "assignment to 'int \\\*' from pointer to '__builtin_abs' with incompatible type 'int \\\(\\\*\\\)\\\(int\\\)' \\\[-Wincompatible-pointer-types\\\]" } */
diff --git a/gcc/testsuite/gcc.dg/permerror-system.c b/gcc/testsuite/gcc.dg/permerror-system.c
index f00420358d9..bd923138461 100644
--- a/gcc/testsuite/gcc.dg/permerror-system.c
+++ b/gcc/testsuite/gcc.dg/permerror-system.c
@@ -28,5 +28,16 @@
 /* { dg-error "assignment to 'int \\\*' from 'int' makes pointer from integer without a cast \\\[-Wint-conversion\\\]" "" { target *-*-* } 46 } */
 /* { dg-error "returning 'int \\\*' from a function with return type 'int' makes integer from pointer without a cast \\\[-Wint-conversion\\\]" "" { target *-*-* } 48 } */
 
+/* { dg-error "pointer type mismatch in conditional expression \\\[-Wincompatible-pointer-types\\\]" "" { target *-*-* } 55 } */
+/* { dg-error "initialization of 'int \\\*' from pointer to '__builtin_abs' with incompatible type 'int \\\(\\\*\\\)\\\(int\\\)' \\\[-Wincompatible-pointer-types\\\]" "" { target *-*-* } 57 } */
+/* { dg-error "assignment to 'int \\\*' from pointer to '__builtin_abs' with incompatible type 'int \\\(\\\*\\\)\\\(int\\\)' \\\[-Wincompatible-pointer-types\\\]" "" { target *-*-* } 58 } */
+/* { dg-error "initialization of 'int \\\*' from incompatible pointer type 'int \\\* \\\(\\\*\\\)\\\(int\\\)' \\\[-Wincompatible-pointer-types\\\]" "" { target *-*-* } 61 } */
+/* { dg-error "assignment to 'int \\\*' from incompatible pointer type 'int \\\* \\\(\\\*\\\)\\\(int\\\)' \\\[-Wincompatible-pointer-types\\\]" "" { target *-*-* } 62 } */
+/* { dg-error "initialization of 'int \\\*' from incompatible pointer type 'int \\\*\\\*' \\\[-Wincompatible-pointer-types\\\]" "" { target *-*-* } 64 } */
+/* { dg-error "assignment to 'int \\\*' from incompatible pointer type 'int \\\*\\\*' \\\[-Wincompatible-pointer-types\\\]" "" { target *-*-* } 65 } */
+/* { dg-error "passing argument 1 of 'f4' from incompatible pointer type \\\[-Wincompatible-pointer-types\\\]" "" { target *-*-* } 67 } */
+/* { dg-error "returning pointer to '__builtin_abs' of type 'int \\\(\\\*\\\)\\\(int\\\)' from a function with incompatible type 'int \\\*' \\\[-Wincompatible-pointer-types\\\]" "" { target *-*-* } 70 } */
+/* { dg-error "returning 'int \\\* \\\(\\\*\\\)\\\(int\\\)' from a function with incompatible return type 'int \\\*' \\\[-Wincompatible-pointer-types\\\]" "" { target *-*-* } 72 } */
+
 /* { dg-error "'return' with a value, in function returning void \\\[-Wreturn-mismatch\\\]" "" { target *-*-* } 78 } */
 /* { dg-error "return' with no value, in function returning non-void \\\[-Wreturn-mismatch\\\]" "" { target *-*-* } 84 } */
diff --git a/gcc/testsuite/gcc.dg/pointer-array-atomic-2.c b/gcc/testsuite/gcc.dg/pointer-array-atomic-2.c
new file mode 100644
index 00000000000..de63ff141a3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pointer-array-atomic-2.c
@@ -0,0 +1,60 @@
+/* { dg-do compile } */
+/* { dg-options "-std=c11" } */
+/* Origin: Martin Uecker <uecker@eecs.berkeley.edu> */
+void tvoid(void* x);
+void transpose0(double* out, _Atomic double* in) { }
+void transpose1(double out[2][2], _Atomic double in[2][2]) { }
+void transpose2(double out[2][2][2], _Atomic double in[2][2][2]) { }
+// return
+int (*x2(_Atomic int x[3][3]))[3] { return x; } /* { dg-error "returning '_Atomic int \\(\\*\\)\\\[3\\\]' from a function with incompatible return type" } */
+_Atomic int (*x3(int x[3][3]))[3] { return x; } /* { dg-error "returning 'int \\(\\*\\)\\\[3\\\]' from a function with incompatible return type" } */
+void test(void)
+{
+	double x0[2];
+	double y0[2];
+	_Atomic double z0[4];
+	double x1[2][2];
+	double y1[2][2];
+	double o1[2][3];
+	_Atomic double z1[2][2];
+	double x2[2][2][2];
+	double y2[2][2][2];
+	double o2[2][2][3];
+	_Atomic double z2[2][2][2];
+	tvoid(z0);
+	tvoid(z1);
+	tvoid(z2);
+	// passing as arguments
+	transpose0(y0, x0); /* { dg-error "passing argument 2 of 'transpose0' from incompatible pointer type" } */
+	transpose1(y1, o1); /* { dg-error "passing argument 2 of 'transpose1' from incompatible pointer type" } */
+	transpose1(y1, x1); /* { dg-error "passing argument 2 of 'transpose1' from incompatible pointer type" } */
+	transpose2(y2, o2); /* { dg-error "passing argument 2 of 'transpose2' from incompatible pointer type" } */
+	transpose2(y2, x2); /* { dg-error "passing argument 2 of 'transpose2' from incompatible pointer type" } */
+	// initialization
+	_Atomic double (*x0p) = x0; /* { dg-error "initialization of '_Atomic double \\*' from incompatible pointer type" } */
+	_Atomic double (*x1p)[2] = x1; /* { dg-error "initialization of '_Atomic double \\(\\*\\)\\\[2\\\]' from incompatible pointer type" } */
+	_Atomic double (*x2p)[2][2] = x2; /* { dg-error "initialization of '_Atomic double \\(\\*\\)\\\[2\\\]\\\[2\\\]' from incompatible pointer type" } */
+	// assignment
+	x0p = x0; /* { dg-error "assignment to '_Atomic double \\*' from incompatible pointer type" } */
+	x1p = x1; /* { dg-error "assignment to '_Atomic double \\(\\*\\)\\\[2\\\]' from incompatible pointer type" } */
+	x2p = x2; /* { dg-error "assignment to '_Atomic double \\(\\*\\)\\\[2\\\]\\\[2\\\]' from incompatible pointer type" } */
+	// subtraction
+	&(x0[1]) - &(z0[0]); /* { dg-error "invalid operands to binary" } */
+	&(x1[1]) - &(z1[0]); /* { dg-error "invalid operands to binary" } */
+	&(x2[1]) - &(z2[0]); /* { dg-error "invalid operands to binary" } */
+	// comparison
+	x0 == z0; /* { dg-warning "comparison of distinct pointer types lacks a cast" } */
+	x1 == z1; /* { dg-warning "comparison of distinct pointer types lacks a cast" } */
+	x2 == z2; /* { dg-warning "comparison of distinct pointer types lacks a cast" } */
+	x0 > z0; /* { dg-warning "comparison of distinct pointer types lacks a cast" } */
+	x1 > z1; /* { dg-warning "comparison of distinct pointer types lacks a cast" } */
+	x2 > z2; /* { dg-warning "comparison of distinct pointer types lacks a cast" } */
+	x0 < z0; /* { dg-warning "comparison of distinct pointer types lacks a cast" } */
+	x1 < z1; /* { dg-warning "comparison of distinct pointer types lacks a cast" } */
+	x2 < z2; /* { dg-warning "comparison of distinct pointer types lacks a cast" } */
+	// conditional expressions
+	(void)(1 ? x0 : z0); /* { dg-error "pointer type mismatch in conditional expression" } */
+	(void)(1 ? x1 : z1); /* { dg-error "pointer type mismatch in conditional expression" } */
+	(void)(1 ? x2 : z2); /* { dg-error "pointer type mismatch in conditional expression" } */
+}
+
diff --git a/gcc/testsuite/gcc.dg/pointer-array-atomic.c b/gcc/testsuite/gcc.dg/pointer-array-atomic.c
index bb63797b237..87d177a71a4 100644
--- a/gcc/testsuite/gcc.dg/pointer-array-atomic.c
+++ b/gcc/testsuite/gcc.dg/pointer-array-atomic.c
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-std=c11" } */
+/* { dg-options "-fpermissive -std=c11" } */
 /* Origin: Martin Uecker <uecker@eecs.berkeley.edu> */
 void tvoid(void* x);
 void transpose0(double* out, _Atomic double* in) { }
diff --git a/gcc/testsuite/gcc.dg/pointer-array-quals-1.c b/gcc/testsuite/gcc.dg/pointer-array-quals-1.c
index 498ab223162..be80912723a 100644
--- a/gcc/testsuite/gcc.dg/pointer-array-quals-1.c
+++ b/gcc/testsuite/gcc.dg/pointer-array-quals-1.c
@@ -84,9 +84,9 @@ void test(void)
 	(void)(1 ? x0 : z0);
 	(void)(1 ? x1 : z1);
 	(void)(1 ? x2 : z2);
-	(void)(1 ? x0 : x1); /* { dg-warning "pointer type mismatch in conditional expression" } */
-	(void)(1 ? x1 : x2); /* { dg-warning "pointer type mismatch in conditional expression" } */
-	(void)(1 ? x2 : x0); /* { dg-warning "pointer type mismatch in conditional expression" } */
+	(void)(1 ? x0 : x1); /* { dg-error "pointer type mismatch in conditional expression" } */
+	(void)(1 ? x1 : x2); /* { dg-error "pointer type mismatch in conditional expression" } */
+	(void)(1 ? x2 : x0); /* { dg-error "pointer type mismatch in conditional expression" } */
 	v0p = (1 ? z0 : v0p); /* { dg-warning "assignment discards 'const' qualifier from pointer target type" } */
 	v1p = (1 ? z1 : v1p); /* { dg-warning "assignment discards 'const' qualifier from pointer target type" } */
 	v2p = (1 ? z2 : v2p); /* { dg-warning "assignment discards 'const' qualifier from pointer target type" } */
diff --git a/gcc/testsuite/gcc.dg/transparent-union-1.c b/gcc/testsuite/gcc.dg/transparent-union-1.c
index 3f0c260c906..518adfb6ce0 100644
--- a/gcc/testsuite/gcc.dg/transparent-union-1.c
+++ b/gcc/testsuite/gcc.dg/transparent-union-1.c
@@ -1,6 +1,6 @@
 /* PR c/20043 */
 /* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
+/* { dg-options "-fpermissive -std=gnu99" } */
 
 extern void f0 (int *);
 extern void f0 (int *__restrict);
diff --git a/gcc/testsuite/gcc.dg/transparent-union-1a.c b/gcc/testsuite/gcc.dg/transparent-union-1a.c
new file mode 100644
index 00000000000..9796ceab490
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/transparent-union-1a.c
@@ -0,0 +1,85 @@
+/* PR c/20043 */
+/* { dg-do compile } */
+/* { dg-options "-std=gnu99" } */
+
+extern void f0 (int *);
+extern void f0 (int *__restrict);
+
+extern void f1 (int *__restrict);
+extern void f1 (int *);
+
+typedef union { int *i; long *l; } U2
+  __attribute__((transparent_union));
+extern void f2 (U2);
+extern void f2 (int *);
+
+typedef union { int *__restrict i; long *__restrict l; } U3
+  __attribute__((transparent_union));
+extern void f3 (U3);
+extern void f3 (int *__restrict);
+
+extern void f4 (U3);
+extern void f4 (int *);
+
+extern void f5 (U2);
+extern void f5 (int *__restrict);
+
+typedef union { long *l; int *i; } U6
+  __attribute__((transparent_union));
+extern void f6 (U6);
+extern void f6 (int *);
+
+typedef union { long *__restrict l; int *__restrict i; } U7
+  __attribute__((transparent_union));
+extern void f7 (U7);
+extern void f7 (int *__restrict);
+
+extern void f8 (U7);
+extern void f8 (int *);
+
+extern void f9 (U6);
+extern void f9 (int *__restrict);
+
+extern void f10 (U2);
+extern void f11 (U3);
+extern void f12 (U6);
+extern void f13 (U7);
+
+int i;
+long l;
+
+int
+main (void)
+{
+  f0 (&i);
+  f0 (&l);	/* { dg-error "passing argument 1 of 'f0' from incompatible pointer type" } */
+  f1 (&i);
+  f1 (&l);	/* { dg-error "passing argument 1 of 'f1' from incompatible pointer type" } */
+  f2 (&i);
+  f2 (&l);	/* { dg-error "passing argument 1 of 'f2' from incompatible pointer type" } */
+  f3 (&i);
+  f3 (&l);	/* { dg-error "passing argument 1 of 'f3' from incompatible pointer type" } */
+  f4 (&i);
+  f4 (&l);	/* { dg-error "passing argument 1 of 'f4' from incompatible pointer type" } */
+  f5 (&i);
+  f5 (&l);	/* { dg-error "passing argument 1 of 'f5' from incompatible pointer type" } */
+  f6 (&i);
+  f6 (&l);	/* { dg-error "passing argument 1 of 'f6' from incompatible pointer type" } */
+  f7 (&i);
+  f7 (&l);	/* { dg-error "passing argument 1 of 'f7' from incompatible pointer type" } */
+  f8 (&i);
+  f8 (&l);	/* { dg-error "passing argument 1 of 'f8' from incompatible pointer type" } */
+  f9 (&i);
+  f9 (&l);	/* { dg-error "passing argument 1 of 'f9' from incompatible pointer type" } */
+  f10 (&i);
+  f10 (&l);
+  f11 (&i);
+  f11 (&l);
+  f12 (&i);
+  f12 (&l);
+  f13 (&i);
+  f13 (&l);
+  return 0;
+}
+
+/* { dg-message "note: expected '\[^\n'\]*' but argument is of type '\[^\n'\]*'" "note: expected" { target *-*-* } 0 } */
diff --git a/gcc/testsuite/gcc.target/aarch64/acle/memtag_2a.c b/gcc/testsuite/gcc.target/aarch64/acle/memtag_2a.c
index 16db40df663..9ae371d8867 100644
--- a/gcc/testsuite/gcc.target/aarch64/acle/memtag_2a.c
+++ b/gcc/testsuite/gcc.target/aarch64/acle/memtag_2a.c
@@ -17,12 +17,12 @@ test_memtag_warning_return_qualifier (void)
 
   v = __arm_mte_get_tag(c);		  /* { dg-warning {assignment} } */
   n = __arm_mte_get_tag(c);		  /* { dg-warning {assignment} } */
-  i = __arm_mte_get_tag(c);		  /* { dg-warning {assignment} } */
+  i = __arm_mte_get_tag(c);		  /* { dg-error {assignment} } */
   c = __arm_mte_get_tag(v);		  /* { dg-warning {assignment} } */
   n = __arm_mte_get_tag(v);		  /* { dg-warning {assignment} } */
 
-  i = __arm_mte_create_random_tag (c, 0); /* { dg-warning {assignment} } */
-  i = __arm_mte_increment_tag (c, 0);	  /* { dg-warning {assignment} } */
+  i = __arm_mte_create_random_tag (c, 0); /* { dg-error {assignment} } */
+  i = __arm_mte_increment_tag (c, 0);	  /* { dg-error {assignment} } */
 
   c = __arm_mte_get_tag(n);		  /* No warning.  */
   d = __arm_mte_ptrdiff(c, i);		  /* No warning.  */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/load_2.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/load_2.c
index a8288762695..5f4cbeaea2e 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/load_2.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/load_2.c
@@ -15,8 +15,8 @@ f1 (svbool_t pg, signed char *s8_ptr, void *void_ptr, struct s *s_ptr,
   svld1_s8 (pg, 0);
   svld1_s32 (pg, (int32_t *) 0);
   svld1_s8 (pg, void_ptr);
-  svld1_s8 (pg, s_ptr); /* { dg-warning {passing argument 2 of 'svld1_s8' from incompatible pointer type} } */
+  svld1_s8 (pg, s_ptr); /* { dg-error {passing argument 2 of 'svld1_s8' from incompatible pointer type} } */
   svld1_f32 (pg, f32_ptr);
-  svld1_f32 (pg, cf32_ptr); /* { dg-warning {passing argument 2 of 'svld1_f32' from incompatible pointer type} } */
+  svld1_f32 (pg, cf32_ptr); /* { dg-error {passing argument 2 of 'svld1_f32' from incompatible pointer type} } */
   return svld1_s8 (pg, s8_ptr); /* { dg-error {incompatible types when returning type 'svint8_t' but 'svuint8_t' was expected} } */
 }
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 cd849f89941..41bf2da0fab 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
@@ -14,7 +14,7 @@ f1 (svbool_t pg, signed char *s8_ptr, short *s16_ptr,
   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} } */
+  svld1sb_gather_offset_s32 (pg, s16_ptr, s32); /* { dg-error {passing argument 2 of 'svld1sb_gather_s32offset_s32' from incompatible pointer type} } */
   svld1sb_gather_offset_s32 (pg, s8_ptr, pg); /* { dg-error {passing 'svbool_t' to argument 3 of 'svld1sb_gather_offset_s32', which expects a vector of 32-bit integers} } */
   svld1sb_gather_offset_s32 (pg, s8_ptr, s8); /* { dg-error {passing 'svint8_t' to argument 3 of 'svld1sb_gather_offset_s32', which expects a vector of 32-bit integers} } */
   svld1sb_gather_offset_s32 (pg, s8_ptr, s16); /* { dg-error {passing 'svint16_t' to argument 3 of 'svld1sb_gather_offset_s32', which expects a vector of 32-bit integers} } */
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 850eecf99f6..1261b49d487 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
@@ -14,7 +14,7 @@ f1 (svbool_t pg, signed char *s8_ptr, short *s16_ptr,
   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} } */
+  svld1sb_gather_offset_u32 (pg, s16_ptr, s32); /* { dg-error {passing argument 2 of 'svld1sb_gather_s32offset_u32' from incompatible pointer type} } */
   svld1sb_gather_offset_u32 (pg, s8_ptr, pg); /* { dg-error {passing 'svbool_t' to argument 3 of 'svld1sb_gather_offset_u32', which expects a vector of 32-bit integers} } */
   svld1sb_gather_offset_u32 (pg, s8_ptr, s8); /* { dg-error {passing 'svint8_t' to argument 3 of 'svld1sb_gather_offset_u32', which expects a vector of 32-bit integers} } */
   svld1sb_gather_offset_u32 (pg, s8_ptr, s16); /* { dg-error {passing 'svint16_t' to argument 3 of 'svld1sb_gather_offset_u32', which expects a vector of 32-bit integers} } */
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 93a728593f9..518348d1146 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
@@ -14,7 +14,7 @@ f1 (svbool_t pg, signed char *s8_ptr, short *s16_ptr,
   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} } */
+  svld1sb_gather_offset_s64 (pg, s16_ptr, s64); /* { dg-error {passing argument 2 of 'svld1sb_gather_s64offset_s64' from incompatible pointer type} } */
   svld1sb_gather_offset_s64 (pg, s8_ptr, pg); /* { dg-error {passing 'svbool_t' to argument 3 of 'svld1sb_gather_offset_s64', which expects a vector of 64-bit integers} } */
   svld1sb_gather_offset_s64 (pg, s8_ptr, s8); /* { dg-error {passing 'svint8_t' to argument 3 of 'svld1sb_gather_offset_s64', which expects a vector of 64-bit integers} } */
   svld1sb_gather_offset_s64 (pg, s8_ptr, s16); /* { dg-error {passing 'svint16_t' to argument 3 of 'svld1sb_gather_offset_s64', which expects a vector of 64-bit integers} } */
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 d54dc8eafab..6086911fd5d 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
@@ -14,7 +14,7 @@ f1 (svbool_t pg, signed char *s8_ptr, short *s16_ptr,
   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} } */
+  svld1sb_gather_offset_u64 (pg, s16_ptr, s64); /* { dg-error {passing argument 2 of 'svld1sb_gather_s64offset_u64' from incompatible pointer type} } */
   svld1sb_gather_offset_u64 (pg, s8_ptr, pg); /* { dg-error {passing 'svbool_t' to argument 3 of 'svld1sb_gather_offset_u64', which expects a vector of 64-bit integers} } */
   svld1sb_gather_offset_u64 (pg, s8_ptr, s8); /* { dg-error {passing 'svint8_t' to argument 3 of 'svld1sb_gather_offset_u64', which expects a vector of 64-bit integers} } */
   svld1sb_gather_offset_u64 (pg, s8_ptr, s16); /* { dg-error {passing 'svint16_t' to argument 3 of 'svld1sb_gather_offset_u64', which expects a vector of 64-bit integers} } */
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 3b521d5c141..9e2cceec2e9 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
@@ -14,7 +14,7 @@ f1 (svbool_t pg, unsigned char *s8_ptr, unsigned short *s16_ptr,
   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} } */
+  svld1ub_gather_offset_s32 (pg, s16_ptr, s32); /* { dg-error {passing argument 2 of 'svld1ub_gather_s32offset_s32' from incompatible pointer type} } */
   svld1ub_gather_offset_s32 (pg, s8_ptr, pg); /* { dg-error {passing 'svbool_t' to argument 3 of 'svld1ub_gather_offset_s32', which expects a vector of 32-bit integers} } */
   svld1ub_gather_offset_s32 (pg, s8_ptr, s8); /* { dg-error {passing 'svint8_t' to argument 3 of 'svld1ub_gather_offset_s32', which expects a vector of 32-bit integers} } */
   svld1ub_gather_offset_s32 (pg, s8_ptr, s16); /* { dg-error {passing 'svint16_t' to argument 3 of 'svld1ub_gather_offset_s32', which expects a vector of 32-bit integers} } */
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 96d8ad55074..18e16630944 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
@@ -16,7 +16,7 @@ f1 (svbool_t pg, signed char *s8_ptr, short *s16_ptr,
   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} } */
+  svldnt1sb_gather_offset_s32 (pg, s16_ptr, u32); /* { dg-error {passing argument 2 of 'svldnt1sb_gather_u32offset_s32' from incompatible pointer type} } */
   svldnt1sb_gather_offset_s32 (pg, s8_ptr, pg); /* { dg-error {passing 'svbool_t' to argument 3 of 'svldnt1sb_gather_offset_s32', which expects a vector of 32-bit integers} } */
   svldnt1sb_gather_offset_s32 (pg, s8_ptr, s8); /* { dg-error {passing 'svint8_t' to argument 3 of 'svldnt1sb_gather_offset_s32', which expects a vector of 32-bit integers} } */
   svldnt1sb_gather_offset_s32 (pg, s8_ptr, s16); /* { dg-error {passing 'svint16_t' to argument 3 of 'svldnt1sb_gather_offset_s32', which expects a vector of 32-bit integers} } */
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 25ce7268a1e..6bb9998bff5 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
@@ -16,7 +16,7 @@ f1 (svbool_t pg, signed char *s8_ptr, short *s16_ptr,
   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} } */
+  svldnt1sb_gather_offset_u32 (pg, s16_ptr, u32); /* { dg-error {passing argument 2 of 'svldnt1sb_gather_u32offset_u32' from incompatible pointer type} } */
   svldnt1sb_gather_offset_u32 (pg, s8_ptr, pg); /* { dg-error {passing 'svbool_t' to argument 3 of 'svldnt1sb_gather_offset_u32', which expects a vector of 32-bit integers} } */
   svldnt1sb_gather_offset_u32 (pg, s8_ptr, s8); /* { dg-error {passing 'svint8_t' to argument 3 of 'svldnt1sb_gather_offset_u32', which expects a vector of 32-bit integers} } */
   svldnt1sb_gather_offset_u32 (pg, s8_ptr, s16); /* { dg-error {passing 'svint16_t' to argument 3 of 'svldnt1sb_gather_offset_u32', which expects a vector of 32-bit integers} } */
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 04465f251b1..8dc160ce9c3 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
@@ -16,7 +16,7 @@ f1 (svbool_t pg, signed char *s8_ptr, short *s16_ptr,
   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} } */
+  svldnt1sb_gather_offset_s64 (pg, s16_ptr, s64); /* { dg-error {passing argument 2 of 'svldnt1sb_gather_s64offset_s64' from incompatible pointer type} } */
   svldnt1sb_gather_offset_s64 (pg, s8_ptr, pg); /* { dg-error {passing 'svbool_t' to argument 3 of 'svldnt1sb_gather_offset_s64', which expects a vector of 64-bit integers} } */
   svldnt1sb_gather_offset_s64 (pg, s8_ptr, s8); /* { dg-error {passing 'svint8_t' to argument 3 of 'svldnt1sb_gather_offset_s64', which expects a vector of 64-bit integers} } */
   svldnt1sb_gather_offset_s64 (pg, s8_ptr, s16); /* { dg-error {passing 'svint16_t' to argument 3 of 'svldnt1sb_gather_offset_s64', which expects a vector of 64-bit integers} } */
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 479be66996d..9a418f28089 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
@@ -16,7 +16,7 @@ f1 (svbool_t pg, signed char *s8_ptr, short *s16_ptr,
   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} } */
+  svldnt1sb_gather_offset_u64 (pg, s16_ptr, s64); /* { dg-error {passing argument 2 of 'svldnt1sb_gather_s64offset_u64' from incompatible pointer type} } */
   svldnt1sb_gather_offset_u64 (pg, s8_ptr, pg); /* { dg-error {passing 'svbool_t' to argument 3 of 'svldnt1sb_gather_offset_u64', which expects a vector of 64-bit integers} } */
   svldnt1sb_gather_offset_u64 (pg, s8_ptr, s8); /* { dg-error {passing 'svint8_t' to argument 3 of 'svldnt1sb_gather_offset_u64', which expects a vector of 64-bit integers} } */
   svldnt1sb_gather_offset_u64 (pg, s8_ptr, s16); /* { dg-error {passing 'svint16_t' to argument 3 of 'svldnt1sb_gather_offset_u64', which expects a vector of 64-bit integers} } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/sizeless-1.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/sizeless-1.c
index 01cfd14f873..b0389fa00a8 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/sizeless-1.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/sizeless-1.c
@@ -105,8 +105,8 @@ statements (int n)
 
   /* Pointer assignment.  */
 
-  gnu_sc_ptr = sve_sc_ptr; /* { dg-warning {assignment to [^\n]* from incompatible pointer type} } */
-  sve_sc_ptr = gnu_sc_ptr; /* { dg-warning {assignment to [^\n]* from incompatible pointer type} } */
+  gnu_sc_ptr = sve_sc_ptr; /* { dg-error {assignment to [^\n]* from incompatible pointer type} } */
+  sve_sc_ptr = gnu_sc_ptr; /* { dg-error {assignment to [^\n]* from incompatible pointer type} } */
 
   /* Pointer arithmetic.  */
 
@@ -153,8 +153,8 @@ statements (int n)
   0 ? 0 : sve_sc1; /* { dg-error {type mismatch in conditional expression} } */
   0 ?: sve_sc1; /* { dg-error {type mismatch in conditional expression} } */
   0 ? sve_sc_ptr : sve_sc_ptr;
-  0 ? sve_sc_ptr : gnu_sc_ptr; /* { dg-warning {pointer type mismatch in conditional expression} } */
-  0 ? gnu_sc_ptr : sve_sc_ptr; /* { dg-warning {pointer type mismatch in conditional expression} } */
+  0 ? sve_sc_ptr : gnu_sc_ptr; /* { dg-error {pointer type mismatch in conditional expression} } */
+  0 ? gnu_sc_ptr : sve_sc_ptr; /* { dg-error {pointer type mismatch in conditional expression} } */
 
   /* Generic associations.  */
 
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/sizeless-2.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/sizeless-2.c
index 613b9c47878..d16f40b5f2a 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/sizeless-2.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/sizeless-2.c
@@ -105,8 +105,8 @@ statements (int n)
 
   /* Pointer assignment.  */
 
-  gnu_sc_ptr = sve_sc_ptr; /* { dg-warning {incompatible pointer type} } */
-  sve_sc_ptr = gnu_sc_ptr; /* { dg-warning {incompatible pointer type} } */
+  gnu_sc_ptr = sve_sc_ptr; /* { dg-error {incompatible pointer type} } */
+  sve_sc_ptr = gnu_sc_ptr; /* { dg-error {incompatible pointer type} } */
 
   /* Pointer arithmetic.  */
 
@@ -153,8 +153,8 @@ statements (int n)
   0 ? 0 : sve_sc1; /* { dg-error {type mismatch in conditional expression} } */
   0 ?: sve_sc1; /* { dg-error {type mismatch in conditional expression} } */
   0 ? sve_sc_ptr : sve_sc_ptr;
-  0 ? sve_sc_ptr : gnu_sc_ptr; /* { dg-warning {pointer type mismatch} } */
-  0 ? gnu_sc_ptr : sve_sc_ptr; /* { dg-warning {pointer type mismatch} } */
+  0 ? sve_sc_ptr : gnu_sc_ptr; /* { dg-error {pointer type mismatch} } */
+  0 ? gnu_sc_ptr : sve_sc_ptr; /* { dg-error {pointer type mismatch} } */
 
   /* Generic associations.  */
 
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/store_1.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/store_1.c
index 625f059af44..3669b3088a7 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/store_1.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/store_1.c
@@ -16,11 +16,11 @@ f1 (svbool_t pg, signed char *s8_ptr, void *void_ptr, struct s *s_ptr,
   svst1 (pg, void_ptr, 0); /* { dg-error {passing 'int' to argument 3 of 'svst1', which expects an SVE vector type} } */
   svst1 (pg, void_ptr, pg); /* { dg-error {'svst1' has no form that takes 'svbool_t' arguments} } */
   svst1 (pg, 0, s8);
-  svst1 (pg, (int32_t *) 0, s8); /* { dg-warning "passing argument 2 of 'svst1_s8' from incompatible pointer type" } */
+  svst1 (pg, (int32_t *) 0, s8); /* { dg-error "passing argument 2 of 'svst1_s8' from incompatible pointer type" } */
   svst1 (pg, void_ptr, s8);
-  svst1 (pg, s_ptr, s8); /* { dg-warning "passing argument 2 of 'svst1_s8' from incompatible pointer type" } */
-  svst1 (pg, f32_ptr, s8); /* { dg-warning "passing argument 2 of 'svst1_s8' from incompatible pointer type" } */
+  svst1 (pg, s_ptr, s8); /* { dg-error "passing argument 2 of 'svst1_s8' from incompatible pointer type" } */
+  svst1 (pg, f32_ptr, s8); /* { dg-error "passing argument 2 of 'svst1_s8' from incompatible pointer type" } */
   svst1 (pg, f32_ptr, f32);
-  svst1 (pg, cf32_ptr, f32); /* { dg-warning "passing argument 2 of 'svst1_f32' from incompatible pointer type" } */
+  svst1 (pg, cf32_ptr, f32); /* { dg-error "passing argument 2 of 'svst1_f32' from incompatible pointer type" } */
   svst1 (pg, s, s8); /* { dg-error {passing 'struct s' to argument 2 of 'svst1', which expects a scalar pointer} } */
 }
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/store_2.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/store_2.c
index 669f8844bc1..30a0a4c8586 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/store_2.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/store_2.c
@@ -18,10 +18,10 @@ f1 (svbool_t pg, signed char *s8_ptr, void *void_ptr, struct s *s_ptr,
   svst1_vnum (pg, void_ptr, 0, 0); /* { dg-error {passing 'int' to argument 4 of 'svst1_vnum', which expects an SVE vector type} } */
   svst1_vnum (pg, void_ptr, 0, pg); /* { dg-error {'svst1_vnum' has no form that takes 'svbool_t' arguments} } */
   svst1_vnum (pg, 0, 0, s8);
-  svst1_vnum (pg, (int32_t *) 0, 0, s8); /* { dg-warning "passing argument 2 of 'svst1_vnum_s8' from incompatible pointer type" } */
+  svst1_vnum (pg, (int32_t *) 0, 0, s8); /* { dg-error "passing argument 2 of 'svst1_vnum_s8' from incompatible pointer type" } */
   svst1_vnum (pg, void_ptr, 0, s8);
-  svst1_vnum (pg, s_ptr, 0, s8); /* { dg-warning "passing argument 2 of 'svst1_vnum_s8' from incompatible pointer type" } */
-  svst1_vnum (pg, f32_ptr, 0, s8); /* { dg-warning "passing argument 2 of 'svst1_vnum_s8' from incompatible pointer type" } */
+  svst1_vnum (pg, s_ptr, 0, s8); /* { dg-error "passing argument 2 of 'svst1_vnum_s8' from incompatible pointer type" } */
+  svst1_vnum (pg, f32_ptr, 0, s8); /* { dg-error "passing argument 2 of 'svst1_vnum_s8' from incompatible pointer type" } */
   svst1_vnum (pg, f32_ptr, 0, f32);
-  svst1_vnum (pg, cf32_ptr, 0, f32); /* { dg-warning "passing argument 2 of 'svst1_vnum_f32' from incompatible pointer type" } */
+  svst1_vnum (pg, cf32_ptr, 0, f32); /* { dg-error "passing argument 2 of 'svst1_vnum_f32' from incompatible pointer type" } */
 }
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/store_scatter_index_1.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/store_scatter_index_1.c
index 29f4510c49b..21bd93afb3f 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/store_scatter_index_1.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/store_scatter_index_1.c
@@ -20,10 +20,10 @@ f1 (svbool_t pg, signed char *s8_ptr, short *s16_ptr,
   svst1_scatter_index (pg, 0, s32, s32);
   svst1_scatter_index (pg, (int32_t *) 0, s32, s32);
   svst1_scatter_index (pg, void_ptr, s32, s32);
-  svst1_scatter_index (pg, s_ptr, s32, s32); /* { dg-warning "passing argument 2 of 'svst1_scatter_s32index_s32' from incompatible pointer type" } */
-  svst1_scatter_index (pg, f32_ptr, s32, s32); /* { dg-warning "passing argument 2 of 'svst1_scatter_s32index_s32' from incompatible pointer type" } */
+  svst1_scatter_index (pg, s_ptr, s32, s32); /* { dg-error "passing argument 2 of 'svst1_scatter_s32index_s32' from incompatible pointer type" } */
+  svst1_scatter_index (pg, f32_ptr, s32, s32); /* { dg-error "passing argument 2 of 'svst1_scatter_s32index_s32' from incompatible pointer type" } */
   svst1_scatter_index (pg, f32_ptr, s32, f32);
-  svst1_scatter_index (pg, cf32_ptr, s32, f32); /* { dg-warning "passing argument 2 of 'svst1_scatter_s32index_f32' from incompatible pointer type" } */
+  svst1_scatter_index (pg, cf32_ptr, s32, f32); /* { dg-error "passing argument 2 of 'svst1_scatter_s32index_f32' from incompatible pointer type" } */
   svst1_scatter_index (pg, s, s32, s32); /* { dg-error {passing 'struct s' to argument 2 of 'svst1_scatter_index', which expects a vector or pointer base address} } */
 
   svst1_scatter_index (pg, u32, void_ptr, s32); /* { dg-error "passing argument 3 of 'svst1_scatter_u32base_index_s32' makes integer from pointer without a cast" } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/store_scatter_index_restricted_1.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/store_scatter_index_restricted_1.c
index ab718b5eeee..ec99f8af23e 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/store_scatter_index_restricted_1.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/store_scatter_index_restricted_1.c
@@ -22,10 +22,10 @@ f1 (svbool_t pg, signed char *s8_ptr, short *s16_ptr,
   svstnt1_scatter_index (pg, 0, s64, s64);
   svstnt1_scatter_index (pg, (int64_t *) 0, s64, s64);
   svstnt1_scatter_index (pg, void_ptr, s64, s64);
-  svstnt1_scatter_index (pg, s_ptr, s64, s64); /* { dg-warning "passing argument 2 of 'svstnt1_scatter_s64index_s64' from incompatible pointer type" } */
-  svstnt1_scatter_index (pg, f32_ptr, s64, s64); /* { dg-warning "passing argument 2 of 'svstnt1_scatter_s64index_s64' from incompatible pointer type" } */
+  svstnt1_scatter_index (pg, s_ptr, s64, s64); /* { dg-error "passing argument 2 of 'svstnt1_scatter_s64index_s64' from incompatible pointer type" } */
+  svstnt1_scatter_index (pg, f32_ptr, s64, s64); /* { dg-error "passing argument 2 of 'svstnt1_scatter_s64index_s64' from incompatible pointer type" } */
   svstnt1_scatter_index (pg, f64_ptr, s64, f64);
-  svstnt1_scatter_index (pg, cf64_ptr, s64, f64); /* { dg-warning "passing argument 2 of 'svstnt1_scatter_s64index_f64' from incompatible pointer type" } */
+  svstnt1_scatter_index (pg, cf64_ptr, s64, f64); /* { dg-error "passing argument 2 of 'svstnt1_scatter_s64index_f64' from incompatible pointer type" } */
   svstnt1_scatter_index (pg, s, s64, s64); /* { dg-error {passing 'struct s' to argument 2 of 'svstnt1_scatter_index', which expects a vector or pointer base address} } */
 
   svstnt1_scatter_index (pg, u32, void_ptr, s32); /* { dg-error "passing argument 3 of 'svstnt1_scatter_u32base_index_s32' makes integer from pointer without a cast" } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/store_scatter_offset_2.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/store_scatter_offset_2.c
index 311b1744c91..318f0dddfb1 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/store_scatter_offset_2.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/store_scatter_offset_2.c
@@ -20,10 +20,10 @@ f1 (svbool_t pg, signed char *s8_ptr, short *s16_ptr,
   svst1_scatter_offset (pg, 0, s32, s32);
   svst1_scatter_offset (pg, (int32_t *) 0, s32, s32);
   svst1_scatter_offset (pg, void_ptr, s32, s32);
-  svst1_scatter_offset (pg, s_ptr, s32, s32); /* { dg-warning "passing argument 2 of 'svst1_scatter_s32offset_s32' from incompatible pointer type" } */
-  svst1_scatter_offset (pg, f32_ptr, s32, s32); /* { dg-warning "passing argument 2 of 'svst1_scatter_s32offset_s32' from incompatible pointer type" } */
+  svst1_scatter_offset (pg, s_ptr, s32, s32); /* { dg-error "passing argument 2 of 'svst1_scatter_s32offset_s32' from incompatible pointer type" } */
+  svst1_scatter_offset (pg, f32_ptr, s32, s32); /* { dg-error "passing argument 2 of 'svst1_scatter_s32offset_s32' from incompatible pointer type" } */
   svst1_scatter_offset (pg, f32_ptr, s32, f32);
-  svst1_scatter_offset (pg, cf32_ptr, s32, f32); /* { dg-warning "passing argument 2 of 'svst1_scatter_s32offset_f32' from incompatible pointer type" } */
+  svst1_scatter_offset (pg, cf32_ptr, s32, f32); /* { dg-error "passing argument 2 of 'svst1_scatter_s32offset_f32' from incompatible pointer type" } */
   svst1_scatter_offset (pg, s, s32, s32); /* { dg-error {passing 'struct s' to argument 2 of 'svst1_scatter_offset', which expects a vector or pointer base address} } */
 
   svst1_scatter_offset (pg, u32, void_ptr, s32); /* { dg-error "passing argument 3 of 'svst1_scatter_u32base_offset_s32' makes integer from pointer without a cast" } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/store_scatter_offset_restricted_1.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/store_scatter_offset_restricted_1.c
index 5b251127a47..74bd7aefd70 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/store_scatter_offset_restricted_1.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/store_scatter_offset_restricted_1.c
@@ -22,10 +22,10 @@ f1 (svbool_t pg, signed char *s8_ptr, short *s16_ptr,
   svstnt1_scatter_offset (pg, 0, u32, s32);
   svstnt1_scatter_offset (pg, (int32_t *) 0, u32, s32);
   svstnt1_scatter_offset (pg, void_ptr, u32, s32);
-  svstnt1_scatter_offset (pg, s_ptr, u32, s32); /* { dg-warning "passing argument 2 of 'svstnt1_scatter_u32offset_s32' from incompatible pointer type" } */
-  svstnt1_scatter_offset (pg, f32_ptr, u32, s32); /* { dg-warning "passing argument 2 of 'svstnt1_scatter_u32offset_s32' from incompatible pointer type" } */
+  svstnt1_scatter_offset (pg, s_ptr, u32, s32); /* { dg-error "passing argument 2 of 'svstnt1_scatter_u32offset_s32' from incompatible pointer type" } */
+  svstnt1_scatter_offset (pg, f32_ptr, u32, s32); /* { dg-error "passing argument 2 of 'svstnt1_scatter_u32offset_s32' from incompatible pointer type" } */
   svstnt1_scatter_offset (pg, f32_ptr, u32, f32);
-  svstnt1_scatter_offset (pg, cf32_ptr, u32, f32); /* { dg-warning "passing argument 2 of 'svstnt1_scatter_u32offset_f32' from incompatible pointer type" } */
+  svstnt1_scatter_offset (pg, cf32_ptr, u32, f32); /* { dg-error "passing argument 2 of 'svstnt1_scatter_u32offset_f32' from incompatible pointer type" } */
   svstnt1_scatter_offset (pg, s, u32, s32); /* { dg-error {passing 'struct s' to argument 2 of 'svstnt1_scatter_offset', which expects a vector or pointer base address} } */
 
   svstnt1_scatter_offset (pg, u32, void_ptr, s32); /* { dg-error "passing argument 3 of 'svstnt1_scatter_u32base_offset_s32' makes integer from pointer without a cast" } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general/attributes_7.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/attributes_7.c
index 95be60591fb..5658a206fa3 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/general/attributes_7.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/attributes_7.c
@@ -135,41 +135,41 @@ g (int c)
   diff = gs8 - gs8;
 
   fs8 = ss8; // { dg-error {invalid conversion} "" { target c++ } }
-	     // { dg-warning {incompatible pointer type} "c" { target c } .-1 }
+	     // { dg-error {incompatible pointer type} "c" { target c } .-1 }
   fs8 = fs8;
   fs8 = gs8; // { dg-error {invalid conversion} "" { target c++ } }
-	     // { dg-warning {incompatible pointer type} "c" { target c } .-1 }
+	     // { dg-error {incompatible pointer type} "c" { target c } .-1 }
 
   fs8 = su8; // { dg-error {cannot convert} "c++" { target c++ } }
-	     // { dg-warning {incompatible pointer type} "c" { target c } .-1 }
+	     // { dg-error {incompatible pointer type} "c" { target c } .-1 }
   fs8 = fu8; // { dg-error {cannot convert} "c++" { target c++ } }
-	     // { dg-warning {incompatible pointer type} "c" { target c } .-1 }
+	     // { dg-error {incompatible pointer type} "c" { target c } .-1 }
   fs8 = gu8; // { dg-error {cannot convert} "c++" { target c++ } }
-	     // { dg-warning {incompatible pointer type} "c" { target c } .-1 }
+	     // { dg-error {incompatible pointer type} "c" { target c } .-1 }
 
   fs8 = ss16; // { dg-error {cannot convert} "c++" { target c++ } }
-	      // { dg-warning {incompatible pointer type} "c" { target c } .-1 }
+	      // { dg-error {incompatible pointer type} "c" { target c } .-1 }
   fs8 = fs16; // { dg-error {cannot convert} "c++" { target c++ } }
-	      // { dg-warning {incompatible pointer type} "c" { target c } .-1 }
+	      // { dg-error {incompatible pointer type} "c" { target c } .-1 }
   fs8 = gs16; // { dg-error {cannot convert} "c++" { target c++ } }
-	      // { dg-warning {incompatible pointer type} "c" { target c } .-1 }
+	      // { dg-error {incompatible pointer type} "c" { target c } .-1 }
 
   select = c ? ss8 : ss8;
   select = c ? ss8 : fs8; // { dg-error {distinct pointer types} "" { target c++ } }
-			  // { dg-warning {pointer type mismatch} "c" { target c } .-1 }
+			  // { dg-error {pointer type mismatch} "c" { target c } .-1 }
   select = c ? ss8 : gs8; // { dg-error {distinct pointer types} "" { target c++ } }
-			  // { dg-warning {pointer type mismatch} "c" { target c } .-1 }
+			  // { dg-error {pointer type mismatch} "c" { target c } .-1 }
 
   select = c ? fs8 : ss8; // { dg-error {distinct pointer types} "" { target c++ } }
-			  // { dg-warning {pointer type mismatch} "c" { target c } .-1 }
+			  // { dg-error {pointer type mismatch} "c" { target c } .-1 }
   select = c ? fs8 : fs8;
   select = c ? fs8 : gs8; // { dg-error {distinct pointer types} "" { target c++ } }
-			  // { dg-warning {pointer type mismatch} "c" { target c } .-1 }
+			  // { dg-error {pointer type mismatch} "c" { target c } .-1 }
 
   select = c ? gs8 : ss8; // { dg-error {distinct pointer types} "" { target c++ } }
-			  // { dg-warning {pointer type mismatch} "c" { target c } .-1 }
+			  // { dg-error {pointer type mismatch} "c" { target c } .-1 }
   select = c ? gs8 : fs8; // { dg-error {distinct pointer types} "" { target c++ } }
-			  // { dg-warning {pointer type mismatch} "c" { target c } .-1 }
+			  // { dg-error {pointer type mismatch} "c" { target c } .-1 }
   select = c ? gs8 : gs8;
 
   diff = sb - sb; // { dg-error {arithmetic on pointer to SVE type 'svbool_t'} }
diff --git a/gcc/testsuite/gcc.target/i386/sse2-bfloat16-scalar-typecheck.c b/gcc/testsuite/gcc.target/i386/sse2-bfloat16-scalar-typecheck.c
index d1a76db25e9..599b02632fd 100644
--- a/gcc/testsuite/gcc.target/i386/sse2-bfloat16-scalar-typecheck.c
+++ b/gcc/testsuite/gcc.target/i386/sse2-bfloat16-scalar-typecheck.c
@@ -181,8 +181,8 @@ __bf16 footest (__bf16 scalar0)
   0 ? 0.1 : scalar0;
   0 ? scalar0 : 0.1;
   0 ? bfloat_ptr : bfloat_ptr2;
-  0 ? bfloat_ptr : float_ptr; /* { dg-warning {pointer type mismatch in conditional expression} } */
-  0 ? float_ptr : bfloat_ptr; /* { dg-warning {pointer type mismatch in conditional expression} } */
+  0 ? bfloat_ptr : float_ptr; /* { dg-error {pointer type mismatch in conditional expression} } */
+  0 ? float_ptr : bfloat_ptr; /* { dg-error {pointer type mismatch in conditional expression} } */
 
   scalar0 ? scalar0 : scalar0;
   scalar0 ? is_a_float : scalar0;
diff --git a/gcc/testsuite/gcc.target/i386/vect-bfloat16-typecheck_1.c b/gcc/testsuite/gcc.target/i386/vect-bfloat16-typecheck_1.c
index 8bc3f4a7b8f..f8bdf2e71fd 100644
--- a/gcc/testsuite/gcc.target/i386/vect-bfloat16-typecheck_1.c
+++ b/gcc/testsuite/gcc.target/i386/vect-bfloat16-typecheck_1.c
@@ -224,8 +224,8 @@ __m128bf16 footest (__m128bf16 vector0)
   0 ? 0.1 : vector0; /* { dg-error {type mismatch in conditional expression} } */
   0 ? vector0 : 0.1; /* { dg-error {type mismatch in conditional expression} } */
   0 ? bfloat_ptr : bfloat_ptr2;
-  0 ? bfloat_ptr : float_ptr; /* { dg-warning {pointer type mismatch in conditional expression} } */
-  0 ? float_ptr : bfloat_ptr; /* { dg-warning {pointer type mismatch in conditional expression} } */
+  0 ? bfloat_ptr : float_ptr; /* { dg-error {pointer type mismatch in conditional expression} } */
+  0 ? float_ptr : bfloat_ptr; /* { dg-error {pointer type mismatch in conditional expression} } */
 
   vector0 ? vector0 : vector0; /* { dg-error {used vector type where scalar is required} } */
   vector0 ? is_a_float16_vec : vector0; /* { dg-error {used vector type where scalar is required} } */
diff --git a/gcc/testsuite/gcc.target/i386/vect-bfloat16-typecheck_2.c b/gcc/testsuite/gcc.target/i386/vect-bfloat16-typecheck_2.c
index 2a8a535daae..b6b7a430efa 100644
--- a/gcc/testsuite/gcc.target/i386/vect-bfloat16-typecheck_2.c
+++ b/gcc/testsuite/gcc.target/i386/vect-bfloat16-typecheck_2.c
@@ -214,8 +214,8 @@ __m256bf16 footest (__m256bf16 vector0)
   0 ? 0.1 : vector0; /* { dg-error {type mismatch in conditional expression} } */
   0 ? vector0 : 0.1; /* { dg-error {type mismatch in conditional expression} } */
   0 ? bfloat_ptr : bfloat_ptr2;
-  0 ? bfloat_ptr : float_ptr; /* { dg-warning {pointer type mismatch in conditional expression} } */
-  0 ? float_ptr : bfloat_ptr; /* { dg-warning {pointer type mismatch in conditional expression} } */
+  0 ? bfloat_ptr : float_ptr; /* { dg-error {pointer type mismatch in conditional expression} } */
+  0 ? float_ptr : bfloat_ptr; /* { dg-error {pointer type mismatch in conditional expression} } */
 
   vector0 ? vector0 : vector0; /* { dg-error {used vector type where scalar is required} } */
   vector0 ? is_a_float16_vec : vector0; /* { dg-error {used vector type where scalar is required} } */
-- 
2.41.0



^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH v2 8/8] c: Add new -Wdeclaration-missing-parameter-type permerror
  2023-11-14 17:50 [PATCH v2 0/8] Turn some C warnings into errors by default Florian Weimer
                   ` (6 preceding siblings ...)
  2023-11-14 17:50 ` [PATCH v2 7/8] c: Turn -Wincompatible-pointer-types " Florian Weimer
@ 2023-11-14 17:50 ` Florian Weimer
  2023-11-14 20:26   ` Marek Polacek
  2023-11-15  5:16 ` [PATCH v2 0/8] Turn some C warnings into errors by default Sam James
  8 siblings, 1 reply; 17+ messages in thread
From: Florian Weimer @ 2023-11-14 17:50 UTC (permalink / raw)
  To: gcc-patches; +Cc: jason, jeffreyalaw, joseph, sam

This used to be a warning, enabled by default, without its own option.

A subsequent change could improve diagnostics and provide spelling
hints for declarations like “void function (int32t);”.

gcc/c-family/

	* c.opt (Wdeclaration-missing-parameter-type): New.

gcc/c/ChangeLog:

	PR other/44209
	* c-decl.cc (grokparms): Issue permerror for
	OPT_Wdeclaration_missing_parameter_type instead of a pedwarn.

gcc/ChangeLog:

	* doc/invoke.texi (Warning Options): Document
	-Wdeclaration-missing-parameter-type

gcc/testsuite/ChangeLog:

	* gcc.dg/permerror-default.c (missing_parameter_type):
	Expect error.
	* gcc.dg/permerror-fpermissive.c (missing_parameter_type):
	Expect -Wdeclaration-missing-parameter-type warning.
	* gcc.dg/permerror-gnu89-pedantic.c (missing_parameter_type):
	Expect -Wdeclaration-missing-parameter-type error.
	* gcc.dg/permerror-gnu89.c (missing_parameter_type):
	Expect -Wdeclaration-missing-parameter-type warning.
	* gcc.dg/permerror-noerror.c: Add
	-Wno-error=declaration-missing-parameter-type to build flags.
	(missing_parameter_type): Expect
	-Wdeclaration-missing-parameter-type warning.
	* gcc.dg/permerror-pedantic.c (missing_parameter_type):
	Expect -Wdeclaration-missing-parameter-type error.
---
 gcc/c-family/c.opt                              |  4 ++++
 gcc/c/c-decl.cc                                 |  6 ++++--
 gcc/doc/invoke.texi                             | 17 ++++++++++++++++-
 gcc/testsuite/gcc.dg/permerror-default.c        |  2 +-
 gcc/testsuite/gcc.dg/permerror-fpermissive.c    |  2 +-
 gcc/testsuite/gcc.dg/permerror-gnu89-pedantic.c |  2 +-
 gcc/testsuite/gcc.dg/permerror-gnu89.c          |  2 +-
 gcc/testsuite/gcc.dg/permerror-noerror.c        |  4 ++--
 gcc/testsuite/gcc.dg/permerror-pedantic.c       |  2 +-
 gcc/testsuite/gcc.dg/permerror-system.c         |  2 ++
 10 files changed, 33 insertions(+), 10 deletions(-)

diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
index b10c6057cd1..723985ec5d0 100644
--- a/gcc/c-family/c.opt
+++ b/gcc/c-family/c.opt
@@ -591,6 +591,10 @@ Wdeclaration-after-statement
 C ObjC Var(warn_declaration_after_statement) Init(-1) Warning
 Warn when a declaration is found after a statement.
 
+Wdeclaration-missing-parameter-type
+C ObjC Warning
+Warn for missing parameter types in function declarations.
+
 Wdelete-incomplete
 C++ ObjC++ Var(warn_delete_incomplete) Init(1) Warning
 Warn when deleting a pointer to incomplete type.
diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc
index d16958113a8..3d9bee54259 100644
--- a/gcc/c/c-decl.cc
+++ b/gcc/c/c-decl.cc
@@ -8337,8 +8337,10 @@ grokparms (struct c_arg_info *arg_info, bool funcdef_flag)
     {
       if (!funcdef_flag)
 	{
-	  pedwarn (input_location, 0, "parameter names (without types) in "
-		   "function declaration");
+	  permerror_opt (input_location,
+			 OPT_Wdeclaration_missing_parameter_type,
+			 "parameter names (without types) in "
+			 "function declaration");
 	  arg_info->parms = NULL_TREE;
 	}
       else
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index c492ef7ba0c..66804bfe120 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -502,7 +502,8 @@ Objective-C and Objective-C++ Dialects}.
 
 @item C and Objective-C-only Warning Options
 @gccoptlist{-Wbad-function-cast  -Wmissing-declarations
--Wmissing-parameter-type -Wmissing-prototypes -Wmissing-variable-declarations
+-Wmissing-parameter-type -Wdeclaration-missing-parameter-type
+-Wmissing-prototypes -Wmissing-variable-declarations
 -Wnested-externs -Wold-style-declaration  -Wold-style-definition
 -Wstrict-prototypes  -Wtraditional  -Wtraditional-conversion
 -Wdeclaration-after-statement  -Wpointer-sign}
@@ -9732,6 +9733,20 @@ void foo(bar) @{ @}
 
 This warning is also enabled by @option{-Wextra}.
 
+@opindex Wno-declaration-missing-parameter-type
+@opindex Wdeclaration-missing-parameter-type
+@item -Wno-declaration-missing-parameter-type @r{(C and Objective-C only)}
+Do not warn if a function declaration contains a parameter name without
+a type.  Such function declarations do not provide a function prototype
+and prevent most type checking in function calls.
+
+This warning is enabled by default.  In C99 and later dialects of C, it
+is treated as an error.  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=declaration-missing-parameter-type}.
+
+This warning is upgraded to an error by @option{-pedantic-errors}.
+
 @opindex Wmissing-prototypes
 @opindex Wno-missing-prototypes
 @item -Wmissing-prototypes @r{(C and Objective-C only)}
diff --git a/gcc/testsuite/gcc.dg/permerror-default.c b/gcc/testsuite/gcc.dg/permerror-default.c
index 45b58b0131d..c674d689081 100644
--- a/gcc/testsuite/gcc.dg/permerror-default.c
+++ b/gcc/testsuite/gcc.dg/permerror-default.c
@@ -19,7 +19,7 @@ implicit_int_4 (i) /* { dg-error "return type defaults to 'int' \\\[-Wimplicit-i
   (const) 0; /* { dg-error "type defaults to 'int' in type name \\\[-Wimplicit-int\\\]" } */
 }
 
-extern int missing_parameter_type (i); /* { dg-warning "parameter names \\\(without types\\\) in function declaration\n" } */
+extern int missing_parameter_type (i); /* { dg-error "parameter names \\\(without types\\\) in function declaration \\\[-Wdeclaration-missing-parameter-type\\\]" } */
 
 
 int *
diff --git a/gcc/testsuite/gcc.dg/permerror-fpermissive.c b/gcc/testsuite/gcc.dg/permerror-fpermissive.c
index 139f35ad1c0..fd3020d75ee 100644
--- a/gcc/testsuite/gcc.dg/permerror-fpermissive.c
+++ b/gcc/testsuite/gcc.dg/permerror-fpermissive.c
@@ -19,7 +19,7 @@ implicit_int_4 (i) /* { dg-warning "return type defaults to 'int' \\\[-Wimplicit
   (const) 0; /* { dg-warning "type defaults to 'int' in type name \\\[-Wimplicit-int\\\]" } */
 }
 
-extern int missing_parameter_type (i); /* { dg-warning "parameter names \\\(without types\\\) in function declaration\n" } */
+extern int missing_parameter_type (i); /* { dg-warning "parameter names \\\(without types\\\) in function declaration \\\[-Wdeclaration-missing-parameter-type\\\]" } */
 
 
 int *
diff --git a/gcc/testsuite/gcc.dg/permerror-gnu89-pedantic.c b/gcc/testsuite/gcc.dg/permerror-gnu89-pedantic.c
index 465a16f5f9a..ef4dbfc86c5 100644
--- a/gcc/testsuite/gcc.dg/permerror-gnu89-pedantic.c
+++ b/gcc/testsuite/gcc.dg/permerror-gnu89-pedantic.c
@@ -19,7 +19,7 @@ implicit_int_4 (i) /* { dg-bogus "-Wimplicit-int" } */
   (const) 0; /* { dg-bogus "-Wimplicit-int" } */
 }
 
-extern int missing_parameter_type (i); /* { dg-error "parameter names \\\(without types\\\) in function declaration\n" } */
+extern int missing_parameter_type (i); /* { dg-error "parameter names \\\(without types\\\) in function declaration \\\[-Wdeclaration-missing-parameter-type\\\]" } */
 
 
 int *
diff --git a/gcc/testsuite/gcc.dg/permerror-gnu89.c b/gcc/testsuite/gcc.dg/permerror-gnu89.c
index 66f7789269f..83792ecfaac 100644
--- a/gcc/testsuite/gcc.dg/permerror-gnu89.c
+++ b/gcc/testsuite/gcc.dg/permerror-gnu89.c
@@ -19,7 +19,7 @@ implicit_int_4 (i) /* { dg-bogus "-Wimplicit-int" } */
   (const) 0; /* { dg-bogus "-Wimplicit-int" } */
 }
 
-extern int missing_parameter_type (i); /* { dg-warning "parameter names \\\(without types\\\) in function declaration\n" } */
+extern int missing_parameter_type (i); /* { dg-warning "parameter names \\\(without types\\\) in function declaration \\\[-Wdeclaration-missing-parameter-type\\\]" } */
 
 
 int *
diff --git a/gcc/testsuite/gcc.dg/permerror-noerror.c b/gcc/testsuite/gcc.dg/permerror-noerror.c
index cd1c2013cb5..fc68dfa8bb9 100644
--- a/gcc/testsuite/gcc.dg/permerror-noerror.c
+++ b/gcc/testsuite/gcc.dg/permerror-noerror.c
@@ -1,4 +1,4 @@
-/* { dg-options "-Wno-error=implicit-function-declaration -Wno-error=implicit-int -Wno-error=int-conversion -Wno-error=incompatible-pointer-types -Wno-error=return-mismatch" } */
+/* { dg-options "-Wno-error=implicit-function-declaration -Wno-error=implicit-int -Wno-error=int-conversion -Wno-error=incompatible-pointer-types -Wno-error=return-mismatch -Wno-error=declaration-missing-parameter-type" } */
 
 /* This test should emulate the effect of -fpermissive by adding all the
    -Wno-error= options that are implied by -fpermissive.  It needs to be
@@ -19,7 +19,7 @@ implicit_int_4 (i) /* { dg-warning "return type defaults to 'int' \\\[-Wimplicit
   (const) 0; /* { dg-warning "type defaults to 'int' in type name \\\[-Wimplicit-int\\\]" } */
 }
 
-extern int missing_parameter_type (i); /* { dg-warning "parameter names \\\(without types\\\) in function declaration\n" } */
+extern int missing_parameter_type (i); /* { dg-warning "parameter names \\\(without types\\\) in function declaration \\\[-Wdeclaration-missing-parameter-type\\\]" } */
 
 
 int *
diff --git a/gcc/testsuite/gcc.dg/permerror-pedantic.c b/gcc/testsuite/gcc.dg/permerror-pedantic.c
index 95dda18acd4..2380bb2583c 100644
--- a/gcc/testsuite/gcc.dg/permerror-pedantic.c
+++ b/gcc/testsuite/gcc.dg/permerror-pedantic.c
@@ -19,7 +19,7 @@ implicit_int_4 (i) /* { dg-error "return type defaults to 'int' \\\[-Wimplicit-i
   (const) 0; /* { dg-error "type defaults to 'int' in type name \\\[-Wimplicit-int\\\]" } */
 }
 
-extern int missing_parameter_type (i); /* { dg-error "parameter names \\\(without types\\\) in function declaration\n" } */
+extern int missing_parameter_type (i); /* { dg-error "parameter names \\\(without types\\\) in function declaration \\\[-Wdeclaration-missing-parameter-type\\\]" } */
 
 
 int *
diff --git a/gcc/testsuite/gcc.dg/permerror-system.c b/gcc/testsuite/gcc.dg/permerror-system.c
index bd923138461..790e4f03d66 100644
--- a/gcc/testsuite/gcc.dg/permerror-system.c
+++ b/gcc/testsuite/gcc.dg/permerror-system.c
@@ -17,6 +17,8 @@
 /* { dg-error "type of 'i' defaults to 'int' \\\[-Wimplicit-int\\\]" "" { target *-*-*} 16 } */
 /* { dg-error "type defaults to 'int' in type name \\\[-Wimplicit-int\\\]" "" { target *-*-* } 19 } */
 
+/* { dg-error "parameter names \\\(without types\\\) in function declaration \\\[-Wdeclaration-missing-parameter-type\\\]" "" { target *-*-* } 22 } */
+
 /* { 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 } */
-- 
2.41.0


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v2 8/8] c: Add new -Wdeclaration-missing-parameter-type permerror
  2023-11-14 17:50 ` [PATCH v2 8/8] c: Add new -Wdeclaration-missing-parameter-type permerror Florian Weimer
@ 2023-11-14 20:26   ` Marek Polacek
  2023-11-14 22:27     ` Florian Weimer
  0 siblings, 1 reply; 17+ messages in thread
From: Marek Polacek @ 2023-11-14 20:26 UTC (permalink / raw)
  To: Florian Weimer; +Cc: gcc-patches, jason, jeffreyalaw, joseph, sam

On Tue, Nov 14, 2023 at 06:50:58PM +0100, Florian Weimer wrote:
> --- a/gcc/c-family/c.opt
> +++ b/gcc/c-family/c.opt
> @@ -591,6 +591,10 @@ Wdeclaration-after-statement
>  C ObjC Var(warn_declaration_after_statement) Init(-1) Warning
>  Warn when a declaration is found after a statement.
>  
> +Wdeclaration-missing-parameter-type
> +C ObjC Warning
> +Warn for missing parameter types in function declarations.
> +

This doesn't have Var(warn_declaration_missing_parameter), so
-fpermissive -Wno-declaration-missing-parameter-type still warns
for

  void foo (i);

where I think the warning should be suppressed.  Is that expected?
It would be nice to have a test for that combination.

Marek


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v2 8/8] c: Add new -Wdeclaration-missing-parameter-type permerror
  2023-11-14 20:26   ` Marek Polacek
@ 2023-11-14 22:27     ` Florian Weimer
  0 siblings, 0 replies; 17+ messages in thread
From: Florian Weimer @ 2023-11-14 22:27 UTC (permalink / raw)
  To: Marek Polacek; +Cc: gcc-patches, jason, jeffreyalaw, joseph, sam

* Marek Polacek:

> On Tue, Nov 14, 2023 at 06:50:58PM +0100, Florian Weimer wrote:
>> --- a/gcc/c-family/c.opt
>> +++ b/gcc/c-family/c.opt
>> @@ -591,6 +591,10 @@ Wdeclaration-after-statement
>>  C ObjC Var(warn_declaration_after_statement) Init(-1) Warning
>>  Warn when a declaration is found after a statement.
>>  
>> +Wdeclaration-missing-parameter-type
>> +C ObjC Warning
>> +Warn for missing parameter types in function declarations.
>> +
>
> This doesn't have Var(warn_declaration_missing_parameter), so
> -fpermissive -Wno-declaration-missing-parameter-type still warns
> for
>
>   void foo (i);
>
> where I think the warning should be suppressed.  Is that expected?
> It would be nice to have a test for that combination.

Okay, I'll send a v3 tomorrow with this change and a test.  I had no
idea that this was necessary. 8-/

Thanks,
Florian


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v2 5/8] c: Do not ignore some forms of -Wimplicit-int in system headers
  2023-11-14 17:50 ` [PATCH v2 5/8] c: Do not ignore some forms of -Wimplicit-int in system headers Florian Weimer
@ 2023-11-15  5:03   ` Sam James
  2023-11-15  5:12     ` Florian Weimer
  0 siblings, 1 reply; 17+ messages in thread
From: Sam James @ 2023-11-15  5:03 UTC (permalink / raw)
  To: Florian Weimer; +Cc: gcc-patches, jason, jeffreyalaw, joseph, sam


Florian Weimer <fweimer@redhat.com> writes:

> Most -Wimplicit-int warnings were unconditionally disabled for system
> headers.  Only missing types for parameters in old-style function
> definitions resulted in warnings.  This is inconsistent with the
> treatment of other permerrors, which are active in system headers.

The situation with system headers is kind of a mess still. I went
looking for a bug for the -Wimplicit-int behaviour but I only found
PR78000 for -Wimplicit-function-declaration. But in the bug, Joseph
makes the same observation.

I don't suppose he'll want to block on that at this late point though.

Do you know offhand what Clang's behaviour is wrt warnings in system headers?

>
> gcc/c/
>
> 	* c-decl.cc (grokdeclarator): Do not skip -Wimplicit-int
> 	warnings or errors in system headers.
>
> gcc/testsuite/
>
> 	* gcc.dg/permerror-system.c: Expect all -Wimplicit-int
> 	permerrors.
> ---
>  gcc/c/c-decl.cc                         | 2 +-
>  gcc/testsuite/gcc.dg/permerror-system.c | 5 +++++
>  2 files changed, 6 insertions(+), 1 deletion(-)
>
> diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc
> index 893e24f7dc6..d16958113a8 100644
> --- a/gcc/c/c-decl.cc
> +++ b/gcc/c/c-decl.cc
> @@ -6845,7 +6845,7 @@ grokdeclarator (const struct c_declarator *declarator,
>  
>    /* Diagnose defaulting to "int".  */
>  
> -  if (declspecs->default_int_p && !in_system_header_at (input_location))
> +  if (declspecs->default_int_p)
>      {
>        /* Issue a warning if this is an ISO C 99 program or if
>  	 -Wreturn-type and this is a function, or if -Wimplicit;
> diff --git a/gcc/testsuite/gcc.dg/permerror-system.c b/gcc/testsuite/gcc.dg/permerror-system.c
> index 60c65ffc1d4..cad48c93f90 100644
> --- a/gcc/testsuite/gcc.dg/permerror-system.c
> +++ b/gcc/testsuite/gcc.dg/permerror-system.c
> @@ -10,7 +10,12 @@
>  
>  /* { dg-error "'f1' \\\[-Wimplicit-function-declaration\\\]" "" { target *-*-* } 10 } */
>  
> +/* { dg-error "'implicit_int_1' \\\[-Wimplicit-int\\\]" "" { target *-*-* } 13 } */
> +/* { dg-error "'implicit_int_2' \\\[-Wimplicit-int\\\]" "" { target *-*-* } 14 } */
> +/* { dg-error "'implicit_int_3' \\\[-Wimplicit-int\\]" "" { target *-*-* } 15 } */
> +/* { dg-error "return type defaults to 'int' \\\[-Wimplicit-int\\\]" "" { target *-*-* } 16 } */
>  /* { dg-error "type of 'i' defaults to 'int' \\\[-Wimplicit-int\\\]" "" { target *-*-*} 16 } */
> +/* { dg-error "type defaults to 'int' in type name \\\[-Wimplicit-int\\\]" "" { target *-*-* } 19 } */
>  
>  /* { 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 } */


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v2 5/8] c: Do not ignore some forms of -Wimplicit-int in system headers
  2023-11-15  5:03   ` Sam James
@ 2023-11-15  5:12     ` Florian Weimer
  2023-11-15  5:13       ` Sam James
  0 siblings, 1 reply; 17+ messages in thread
From: Florian Weimer @ 2023-11-15  5:12 UTC (permalink / raw)
  To: Sam James; +Cc: gcc-patches, jason, jeffreyalaw, joseph

* Sam James:

> Florian Weimer <fweimer@redhat.com> writes:
>
>> Most -Wimplicit-int warnings were unconditionally disabled for system
>> headers.  Only missing types for parameters in old-style function
>> definitions resulted in warnings.  This is inconsistent with the
>> treatment of other permerrors, which are active in system headers.
>
> The situation with system headers is kind of a mess still. I went
> looking for a bug for the -Wimplicit-int behaviour but I only found
> PR78000 for -Wimplicit-function-declaration. But in the bug, Joseph
> makes the same observation.
>
> I don't suppose he'll want to block on that at this late point though.
>
> Do you know offhand what Clang's behaviour is wrt warnings in system
> headers?

Clang ignores these new errors in system headers by default.  I don't
know if that's deliberate or a bug.  Our permerrors are deliberately
active in system headers.  As the test shows, -Wimplicit-int really was
the outlier here because of that check outside the permerror machinery.

I expect system headers are quite clean actually because they have to be
for C++ compatibility.  Some things have improved in the last 25 years.

Thanks,
Florian


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v2 5/8] c: Do not ignore some forms of -Wimplicit-int in system headers
  2023-11-15  5:12     ` Florian Weimer
@ 2023-11-15  5:13       ` Sam James
  2023-11-21 21:18         ` Jason Merrill
  0 siblings, 1 reply; 17+ messages in thread
From: Sam James @ 2023-11-15  5:13 UTC (permalink / raw)
  To: Florian Weimer; +Cc: Sam James, gcc-patches, jason, jeffreyalaw, joseph


Florian Weimer <fweimer@redhat.com> writes:

> * Sam James:
>
>> Florian Weimer <fweimer@redhat.com> writes:
>>
>>> Most -Wimplicit-int warnings were unconditionally disabled for system
>>> headers.  Only missing types for parameters in old-style function
>>> definitions resulted in warnings.  This is inconsistent with the
>>> treatment of other permerrors, which are active in system headers.
>>
>> The situation with system headers is kind of a mess still. I went
>> looking for a bug for the -Wimplicit-int behaviour but I only found
>> PR78000 for -Wimplicit-function-declaration. But in the bug, Joseph
>> makes the same observation.
>>
>> I don't suppose he'll want to block on that at this late point though.
>>
>> Do you know offhand what Clang's behaviour is wrt warnings in system
>> headers?
>
> Clang ignores these new errors in system headers by default.  I don't
> know if that's deliberate or a bug.  Our permerrors are deliberately
> active in system headers.  As the test shows, -Wimplicit-int really was
> the outlier here because of that check outside the permerror machinery.

Thanks - my assumption was that it was more widespread because of a few
lingering bugs I've seen a few projects complain about, but maybe they
were using old versions or similar.

>
> I expect system headers are quite clean actually because they have to be
> for C++ compatibility.  Some things have improved in the last 25 years.
>

Oh, duh. Thank you!



^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v2 0/8] Turn some C warnings into errors by default
  2023-11-14 17:50 [PATCH v2 0/8] Turn some C warnings into errors by default Florian Weimer
                   ` (7 preceding siblings ...)
  2023-11-14 17:50 ` [PATCH v2 8/8] c: Add new -Wdeclaration-missing-parameter-type permerror Florian Weimer
@ 2023-11-15  5:16 ` Sam James
  2023-11-15  6:37   ` Florian Weimer
  8 siblings, 1 reply; 17+ messages in thread
From: Sam James @ 2023-11-15  5:16 UTC (permalink / raw)
  To: Florian Weimer; +Cc: gcc-patches, jason, jeffreyalaw, joseph, sam


Florian Weimer <fweimer@redhat.com> writes:

> This new series covers:
>
>   -Wint-conversion
>   -Wimplicit-function-declaration
>   -Wimplicit-int
>   -Wreturn-mismatch
>   -Wincompatible-pointer-types
>   -Wdeclaration-missing-parameter-type (new)
>
> There are now gcc.dg/permerror-*.c tests which track the graduation of
> warnings to errors.
>
> It turns out that pedpermerror was indeed unnecessary, and I can use
> permerror_opt directly (or DK_PERMERROR in case I call one of the
> low-level functions).
>
> While working on this I found out that -Wimplicit-int is mostly
> ineffective in system headers, so I fixed that for consistency.  I also
> added a new -Wdeclaration-missing-parameter-type warning because missing
> types in parameter lists in function declarations (as opposed to
> old-style function definitions) are not covered by -Wimplicit-int, and
> probably shouldn't be because the omitted types are not necessarily int.
>
> This still depends on a couple of unreviewed patches.  In particular, I
> do not want to break the AArch64 bootstrap, so the first patch looks
> like a blocker.
>
>   [PATCH] aarch64: Avoid -Wincompatible-pointer-types warning in Linux unwinder
>   <https://inbox.sourceware.org/gcc-patches/874jht5tsq.fsf@oldenburg.str.redhat.com/>
>
>   [PATCH] aarch64: Call named function in gcc.target/aarch64/aapcs64/ice_1.c
>   <https://inbox.sourceware.org/gcc-patches/87r0kx6eez.fsf@oldenburg.str.redhat.com/>
>
>   [PATCH] gm2: Add missing declaration of m2pim_M2RTS_Terminate to test
>   <https://inbox.sourceware.org/gcc-patches/874jhp3nwf.fsf@oldenburg.str.redhat.com/>

When posting v3, I guess consider CCing the aarch64 maintainers (or just
pinging them separately)?

I'm not really sure how approval of (an earlier version of) this series
interacts with stage 3 ending on Friday.

>
> Thanks,
> Florian
>
>
> Florian Weimer (8):
>   Add tests for validating future C permerrors
>   c: Turn int-conversion warnings into permerrors
>   c: Turn -Wimplicit-function-declaration into a permerror
>   c: Turn -Wimplicit-int into a permerror
>   c: Do not ignore some forms of -Wimplicit-int in system headers
>   c: Turn -Wreturn-mismatch into a permerror
>   c: Turn -Wincompatible-pointer-types into a permerror
>   c: Add new -Wdeclaration-missing-parameter-type permerror
>
>  gcc/c-family/c.opt                            |   4 +
>  gcc/c/c-decl.cc                               |  71 +++----
>  gcc/c/c-typeck.cc                             | 164 ++++++++-------
>  gcc/doc/invoke.texi                           |  50 ++++-
>  gcc/testsuite/c-c++-common/pr77624-1.c        |   4 +-
>  .../c-c++-common/spellcheck-reserved.c        |   4 +-
>  gcc/testsuite/gcc.dg/20030906-1.c             |   2 +-
>  gcc/testsuite/gcc.dg/20030906-1a.c            |  21 ++
>  gcc/testsuite/gcc.dg/20030906-2.c             |   2 +-
>  gcc/testsuite/gcc.dg/20030906-2a.c            |  21 ++
>  .../Wimplicit-function-declaration-c99-2.c    |   7 +
>  .../Wimplicit-function-declaration-c99.c      |   2 +-
>  gcc/testsuite/gcc.dg/Wimplicit-int-1.c        |   2 +-
>  gcc/testsuite/gcc.dg/Wimplicit-int-1a.c       |  11 ++
>  gcc/testsuite/gcc.dg/Wimplicit-int-4.c        |   2 +-
>  gcc/testsuite/gcc.dg/Wimplicit-int-4a.c       |  11 ++
>  .../gcc.dg/Wincompatible-pointer-types-2.c    |   2 +-
>  .../gcc.dg/Wincompatible-pointer-types-5.c    |  10 +
>  gcc/testsuite/gcc.dg/Wint-conversion-2.c      |   2 +-
>  gcc/testsuite/gcc.dg/Wint-conversion-3.c      |   2 +-
>  gcc/testsuite/gcc.dg/Wint-conversion-4.c      |  14 ++
>  gcc/testsuite/gcc.dg/Wreturn-mismatch-1.c     |   2 +-
>  gcc/testsuite/gcc.dg/Wreturn-mismatch-1a.c    |  40 ++++
>  gcc/testsuite/gcc.dg/Wreturn-mismatch-2.c     |   2 +-
>  gcc/testsuite/gcc.dg/Wreturn-mismatch-2a.c    |  41 ++++
>  gcc/testsuite/gcc.dg/anon-struct-11.c         |   5 +-
>  gcc/testsuite/gcc.dg/anon-struct-11a.c        | 111 +++++++++++
>  gcc/testsuite/gcc.dg/anon-struct-13.c         |   2 +-
>  gcc/testsuite/gcc.dg/anon-struct-13a.c        |  76 +++++++
>  gcc/testsuite/gcc.dg/assign-warn-1.c          |   2 +-
>  gcc/testsuite/gcc.dg/assign-warn-4.c          |  21 ++
>  .../gcc.dg/builtin-arith-overflow-4.c         |   2 +-
>  .../gcc.dg/builtin-arith-overflow-4a.c        |  43 ++++
>  gcc/testsuite/gcc.dg/c23-qual-4.c             |   6 +-
>  gcc/testsuite/gcc.dg/dfp/composite-type-2.c   |  58 ++++++
>  gcc/testsuite/gcc.dg/dfp/composite-type.c     |   2 +-
>  gcc/testsuite/gcc.dg/diag-aka-1.c             |   2 +-
>  gcc/testsuite/gcc.dg/diag-aka-1a.c            |  29 +++
>  .../gcc.dg/diagnostic-range-bad-return-2.c    |  52 +++++
>  .../gcc.dg/diagnostic-range-bad-return.c      |   2 +-
>  gcc/testsuite/gcc.dg/diagnostic-types-1.c     |   2 +-
>  gcc/testsuite/gcc.dg/diagnostic-types-2.c     |  24 +++
>  gcc/testsuite/gcc.dg/enum-compat-1.c          |   2 +-
>  gcc/testsuite/gcc.dg/enum-compat-2.c          |  32 +++
>  gcc/testsuite/gcc.dg/func-ptr-conv-1.c        |   2 +-
>  gcc/testsuite/gcc.dg/func-ptr-conv-2.c        |  56 ++++++
>  gcc/testsuite/gcc.dg/gnu23-attr-syntax-2.c    |   2 +-
>  gcc/testsuite/gcc.dg/gnu23-attr-syntax-3.c    |  17 ++
>  gcc/testsuite/gcc.dg/gomp/pr35738-2.c         |  18 ++
>  gcc/testsuite/gcc.dg/gomp/pr35738.c           |   2 +-
>  gcc/testsuite/gcc.dg/init-bad-7.c             |   2 +-
>  gcc/testsuite/gcc.dg/init-bad-7a.c            |  12 ++
>  gcc/testsuite/gcc.dg/init-excess-3.c          |   4 +-
>  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.dg/noncompile/incomplete-3.c          |   2 +-
>  gcc/testsuite/gcc.dg/noncompile/pr79758-2.c   |   6 +
>  gcc/testsuite/gcc.dg/noncompile/pr79758.c     |   1 +
>  gcc/testsuite/gcc.dg/overflow-warn-1.c        |   4 +-
>  gcc/testsuite/gcc.dg/overflow-warn-3.c        |   4 +-
>  gcc/testsuite/gcc.dg/param-type-mismatch-2.c  | 187 ++++++++++++++++++
>  gcc/testsuite/gcc.dg/param-type-mismatch.c    |   2 +-
>  gcc/testsuite/gcc.dg/permerror-default.c      |  85 ++++++++
>  gcc/testsuite/gcc.dg/permerror-fpermissive.c  |  85 ++++++++
>  .../gcc.dg/permerror-gnu89-pedantic.c         |  85 ++++++++
>  gcc/testsuite/gcc.dg/permerror-gnu89.c        |  85 ++++++++
>  gcc/testsuite/gcc.dg/permerror-noerror.c      |  85 ++++++++
>  gcc/testsuite/gcc.dg/permerror-pedantic.c     |  85 ++++++++
>  gcc/testsuite/gcc.dg/permerror-system.c       |  45 +++++
>  gcc/testsuite/gcc.dg/pointer-array-atomic-2.c |  60 ++++++
>  gcc/testsuite/gcc.dg/pointer-array-atomic.c   |   2 +-
>  gcc/testsuite/gcc.dg/pointer-array-quals-1.c  |   6 +-
>  gcc/testsuite/gcc.dg/pr105635-2.c             |  11 ++
>  gcc/testsuite/gcc.dg/pr105635.c               |   2 +-
>  gcc/testsuite/gcc.dg/pr23075-2.c              |  14 ++
>  gcc/testsuite/gcc.dg/pr23075.c                |   2 +-
>  gcc/testsuite/gcc.dg/pr29521-a.c              |  15 ++
>  gcc/testsuite/gcc.dg/pr29521.c                |   2 +-
>  gcc/testsuite/gcc.dg/pr61162-2.c              |   2 +-
>  gcc/testsuite/gcc.dg/pr61162-3.c              |  13 ++
>  gcc/testsuite/gcc.dg/pr61852.c                |   4 +-
>  gcc/testsuite/gcc.dg/pr67730-a.c              |  11 ++
>  gcc/testsuite/gcc.dg/pr67730.c                |   2 +-
>  gcc/testsuite/gcc.dg/spec-barrier-3.c         |   2 +-
>  gcc/testsuite/gcc.dg/spec-barrier-3a.c        |  13 ++
>  .../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 +-
>  gcc/testsuite/gcc.dg/transparent-union-1.c    |   2 +-
>  gcc/testsuite/gcc.dg/transparent-union-1a.c   |  85 ++++++++
>  .../gcc.target/aarch64/acle/memtag_2.c        |   4 +-
>  .../gcc.target/aarch64/acle/memtag_2a.c       |  71 +++++++
>  .../sve/acle/general-c/ld1sh_gather_1.c       |   2 +-
>  .../aarch64/sve/acle/general-c/load_2.c       |   4 +-
>  .../aarch64/sve/acle/general-c/load_3.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 |   4 +-
>  .../acle/general-c/load_ext_gather_offset_2.c |   4 +-
>  .../acle/general-c/load_ext_gather_offset_3.c |   4 +-
>  .../acle/general-c/load_ext_gather_offset_4.c |   4 +-
>  .../acle/general-c/load_ext_gather_offset_5.c |   4 +-
>  .../load_ext_gather_offset_restricted_1.c     |   4 +-
>  .../load_ext_gather_offset_restricted_2.c     |   4 +-
>  .../load_ext_gather_offset_restricted_3.c     |   4 +-
>  .../load_ext_gather_offset_restricted_4.c     |   4 +-
>  .../aarch64/sve/acle/general-c/sizeless-1.c   |   8 +-
>  .../aarch64/sve/acle/general-c/sizeless-2.c   |   8 +-
>  .../aarch64/sve/acle/general-c/store_1.c      |   8 +-
>  .../aarch64/sve/acle/general-c/store_2.c      |  10 +-
>  .../acle/general-c/store_scatter_index_1.c    |   8 +-
>  .../store_scatter_index_restricted_1.c        |   8 +-
>  .../acle/general-c/store_scatter_offset_2.c   |   8 +-
>  .../store_scatter_offset_restricted_1.c       |   8 +-
>  .../aarch64/sve/acle/general/attributes_7.c   |  28 +--
>  .../i386/sse2-bfloat16-scalar-typecheck.c     |   4 +-
>  .../i386/vect-bfloat16-typecheck_1.c          |   4 +-
>  .../i386/vect-bfloat16-typecheck_2.c          |   4 +-
>  .../gcc.target/powerpc/conditional-return.c   |   2 +-
>  130 files changed, 2441 insertions(+), 257 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.dg/20030906-1a.c
>  create mode 100644 gcc/testsuite/gcc.dg/20030906-2a.c
>  create mode 100644 gcc/testsuite/gcc.dg/Wimplicit-function-declaration-c99-2.c
>  create mode 100644 gcc/testsuite/gcc.dg/Wimplicit-int-1a.c
>  create mode 100644 gcc/testsuite/gcc.dg/Wimplicit-int-4a.c
>  create mode 100644 gcc/testsuite/gcc.dg/Wincompatible-pointer-types-5.c
>  create mode 100644 gcc/testsuite/gcc.dg/Wint-conversion-4.c
>  create mode 100644 gcc/testsuite/gcc.dg/Wreturn-mismatch-1a.c
>  create mode 100644 gcc/testsuite/gcc.dg/Wreturn-mismatch-2a.c
>  create mode 100644 gcc/testsuite/gcc.dg/anon-struct-11a.c
>  create mode 100644 gcc/testsuite/gcc.dg/anon-struct-13a.c
>  create mode 100644 gcc/testsuite/gcc.dg/assign-warn-4.c
>  create mode 100644 gcc/testsuite/gcc.dg/builtin-arith-overflow-4a.c
>  create mode 100644 gcc/testsuite/gcc.dg/dfp/composite-type-2.c
>  create mode 100644 gcc/testsuite/gcc.dg/diag-aka-1a.c
>  create mode 100644 gcc/testsuite/gcc.dg/diagnostic-range-bad-return-2.c
>  create mode 100644 gcc/testsuite/gcc.dg/diagnostic-types-2.c
>  create mode 100644 gcc/testsuite/gcc.dg/enum-compat-2.c
>  create mode 100644 gcc/testsuite/gcc.dg/func-ptr-conv-2.c
>  create mode 100644 gcc/testsuite/gcc.dg/gnu23-attr-syntax-3.c
>  create mode 100644 gcc/testsuite/gcc.dg/gomp/pr35738-2.c
>  create mode 100644 gcc/testsuite/gcc.dg/init-bad-7a.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/noncompile/pr79758-2.c
>  create mode 100644 gcc/testsuite/gcc.dg/param-type-mismatch-2.c
>  create mode 100644 gcc/testsuite/gcc.dg/permerror-default.c
>  create mode 100644 gcc/testsuite/gcc.dg/permerror-fpermissive.c
>  create mode 100644 gcc/testsuite/gcc.dg/permerror-gnu89-pedantic.c
>  create mode 100644 gcc/testsuite/gcc.dg/permerror-gnu89.c
>  create mode 100644 gcc/testsuite/gcc.dg/permerror-noerror.c
>  create mode 100644 gcc/testsuite/gcc.dg/permerror-pedantic.c
>  create mode 100644 gcc/testsuite/gcc.dg/permerror-system.c
>  create mode 100644 gcc/testsuite/gcc.dg/pointer-array-atomic-2.c
>  create mode 100644 gcc/testsuite/gcc.dg/pr105635-2.c
>  create mode 100644 gcc/testsuite/gcc.dg/pr23075-2.c
>  create mode 100644 gcc/testsuite/gcc.dg/pr29521-a.c
>  create mode 100644 gcc/testsuite/gcc.dg/pr61162-3.c
>  create mode 100644 gcc/testsuite/gcc.dg/pr67730-a.c
>  create mode 100644 gcc/testsuite/gcc.dg/spec-barrier-3a.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
>  create mode 100644 gcc/testsuite/gcc.dg/transparent-union-1a.c
>  create mode 100644 gcc/testsuite/gcc.target/aarch64/acle/memtag_2a.c
>
>
> base-commit: 69d69865a792a93cce2905617c53913769d0f260
> prerequisite-patch-id: f46d6a56470ab459865ba2e45372d60e131b9ee2
> prerequisite-patch-id: 7e0b407ec2bbd5e3b9c7ed1342b08d3677a65283
> prerequisite-patch-id: 02e95117add6ada9d5cdb489399fb2e562db76e2


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v2 0/8] Turn some C warnings into errors by default
  2023-11-15  5:16 ` [PATCH v2 0/8] Turn some C warnings into errors by default Sam James
@ 2023-11-15  6:37   ` Florian Weimer
  0 siblings, 0 replies; 17+ messages in thread
From: Florian Weimer @ 2023-11-15  6:37 UTC (permalink / raw)
  To: Sam James; +Cc: gcc-patches, jason, jeffreyalaw, joseph

* Sam James:

> When posting v3, I guess consider CCing the aarch64 maintainers (or just
> pinging them separately)?

I already pinged them, they are likely busy with posting their patches
before stage 1 closes.

> I'm not really sure how approval of (an earlier version of) this series
> interacts with stage 3 ending on Friday.

The posting date of the patch is what counts, not whether it's been
reviewed and pushed.

Thanks,
Florian


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v2 5/8] c: Do not ignore some forms of -Wimplicit-int in system headers
  2023-11-15  5:13       ` Sam James
@ 2023-11-21 21:18         ` Jason Merrill
  0 siblings, 0 replies; 17+ messages in thread
From: Jason Merrill @ 2023-11-21 21:18 UTC (permalink / raw)
  To: Sam James, Florian Weimer; +Cc: gcc-patches, jeffreyalaw, joseph

On 11/15/23 00:13, Sam James wrote:
> Florian Weimer <fweimer@redhat.com> writes:
>> * Sam James:
>>> Florian Weimer <fweimer@redhat.com> writes:
>>>
>>>> Most -Wimplicit-int warnings were unconditionally disabled for system
>>>> headers.  Only missing types for parameters in old-style function
>>>> definitions resulted in warnings.  This is inconsistent with the
>>>> treatment of other permerrors, which are active in system headers.
>>>
>>> The situation with system headers is kind of a mess still. I went
>>> looking for a bug for the -Wimplicit-int behaviour but I only found
>>> PR78000 for -Wimplicit-function-declaration. But in the bug, Joseph
>>> makes the same observation.
>>>
>>> I don't suppose he'll want to block on that at this late point though.
>>>
>>> Do you know offhand what Clang's behaviour is wrt warnings in system
>>> headers?
>>
>> Clang ignores these new errors in system headers by default.  I don't
>> know if that's deliberate or a bug.  Our permerrors are deliberately
>> active in system headers.  As the test shows, -Wimplicit-int really was
>> the outlier here because of that check outside the permerror machinery.
> 
> Thanks - my assumption was that it was more widespread because of a few
> lingering bugs I've seen a few projects complain about, but maybe they
> were using old versions or similar.

The permerror behavior was chosen for C++, which was the only front-end 
that used it before; we might want to reconsider if this patch set runs 
into problems with system C headers.

Jason


^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2023-11-21 21:18 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-11-14 17:50 [PATCH v2 0/8] Turn some C warnings into errors by default Florian Weimer
2023-11-14 17:50 ` [PATCH v2 1/8] Add tests for validating future C permerrors Florian Weimer
2023-11-14 17:50 ` [PATCH v2 2/8] c: Turn int-conversion warnings into permerrors Florian Weimer
2023-11-14 17:50 ` [PATCH v2 3/8] c: Turn -Wimplicit-function-declaration into a permerror Florian Weimer
2023-11-14 17:50 ` [PATCH v2 4/8] c: Turn -Wimplicit-int " Florian Weimer
2023-11-14 17:50 ` [PATCH v2 5/8] c: Do not ignore some forms of -Wimplicit-int in system headers Florian Weimer
2023-11-15  5:03   ` Sam James
2023-11-15  5:12     ` Florian Weimer
2023-11-15  5:13       ` Sam James
2023-11-21 21:18         ` Jason Merrill
2023-11-14 17:50 ` [PATCH v2 6/8] c: Turn -Wreturn-mismatch into a permerror Florian Weimer
2023-11-14 17:50 ` [PATCH v2 7/8] c: Turn -Wincompatible-pointer-types " Florian Weimer
2023-11-14 17:50 ` [PATCH v2 8/8] c: Add new -Wdeclaration-missing-parameter-type permerror Florian Weimer
2023-11-14 20:26   ` Marek Polacek
2023-11-14 22:27     ` Florian Weimer
2023-11-15  5:16 ` [PATCH v2 0/8] Turn some C warnings into errors by default Sam James
2023-11-15  6:37   ` Florian Weimer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).