[v3,09/11] c: Turn -Wreturn-mismatch into a permerror

Message ID 2a00ce2d44edbda185460d72519a879fbac9bf59.1700473918.git.fweimer@redhat.com
State Unresolved
Headers
Series : More warnings as errors by default |

Checks

Context Check Description
snail/gcc-patch-check warning Git am fail log

Commit Message

Florian Weimer Nov. 20, 2023, 9:56 a.m. UTC
  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-gnu89-nopermissive.c (return_mismatch_1):
	Likewise.
	* 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.dg/permerror-gnu89-nopermissive.c     |  2 +-
 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 +-
 23 files changed, 238 insertions(+), 16 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
  

Comments

Marek Polacek Nov. 23, 2023, 5:32 p.m. UTC | #1
On Mon, Nov 20, 2023 at 10:56:30AM +0100, Florian Weimer wrote:
> gcc/
> 
> 	* doc/invoke.texi (Warning Options): Document changes.

That's pretty vague :).  How about "Document that -Wreturn-mismatch is a
permerror in C99."?
 
> 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-gnu89-nopermissive.c (return_mismatch_1):
> 	Likewise.
> 	* 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.

There seem to be some extra whitespaces after "expected".

> ---
>  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.dg/permerror-gnu89-nopermissive.c     |  2 +-
>  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 +-
>  23 files changed, 238 insertions(+), 16 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 eb7417fd9be..831242d134b 100644
> --- a/gcc/doc/invoke.texi
> +++ b/gcc/doc/invoke.texi
> @@ -6185,6 +6185,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
> @@ -7375,7 +7376,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

an -> can

> +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-gnu89-nopermissive.c b/gcc/testsuite/gcc.dg/permerror-gnu89-nopermissive.c
> index 0780e42b5cc..dc282a44489 100644
> --- a/gcc/testsuite/gcc.dg/permerror-gnu89-nopermissive.c
> +++ b/gcc/testsuite/gcc.dg/permerror-gnu89-nopermissive.c
> @@ -75,7 +75,7 @@ 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
> 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 } */

You may want to use 'return' here too (as in, add the leading ').

> 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} } } */
>  

These seem fine.

Should we have a test for -Wno-error=return-mismatch and -Wno-return-mismatch?
I didn't see those.

Marek
  
Florian Weimer Nov. 23, 2023, 6:22 p.m. UTC | #2
* Marek Polacek:

> On Mon, Nov 20, 2023 at 10:56:30AM +0100, Florian Weimer wrote:
>> gcc/
>> 
>> 	* doc/invoke.texi (Warning Options): Document changes.
>
> That's pretty vague :).  How about "Document that -Wreturn-mismatch is a
> permerror in C99."?

Applied (with “in C99 and later”).

>> 	* gcc.target/powerpc/conditional-return.c: Compile with
>> 	-fpermissive due to expected	-Wreturn-mismatch error.
>
> There seem to be some extra whitespaces after "expected".

Fixed.

>> @@ -7375,7 +7376,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
>
> an -> can

Fixed.

>> 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} } } */
>>  
>
> These seem fine.
>
> Should we have a test for -Wno-error=return-mismatch and -Wno-return-mismatch?
> I didn't see those.

See gcc/testsuite/gcc.dg/permerror-noerror.c and
gcc/testsuite/gcc.dg/permerror-nowarning.c.  They don't show up in the
patch because the diagnostics don't change.

Thanks,
Florian
  
Marek Polacek Nov. 30, 2023, 4:17 p.m. UTC | #3
On Thu, Nov 23, 2023 at 07:22:58PM +0100, Florian Weimer wrote:
> * Marek Polacek:
> 
> > On Mon, Nov 20, 2023 at 10:56:30AM +0100, Florian Weimer wrote:
> >> gcc/
> >> 
> >> 	* doc/invoke.texi (Warning Options): Document changes.
> >
> > That's pretty vague :).  How about "Document that -Wreturn-mismatch is a
> > permerror in C99."?
> 
> Applied (with “in C99 and later”).
> 
> >> 	* gcc.target/powerpc/conditional-return.c: Compile with
> >> 	-fpermissive due to expected	-Wreturn-mismatch error.
> >
> > There seem to be some extra whitespaces after "expected".
> 
> Fixed.
> 
> >> @@ -7375,7 +7376,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
> >
> > an -> can
> 
> Fixed.
> 
> >> 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} } } */
> >>  
> >
> > These seem fine.
> >
> > Should we have a test for -Wno-error=return-mismatch and -Wno-return-mismatch?
> > I didn't see those.
> 
> See gcc/testsuite/gcc.dg/permerror-noerror.c and
> gcc/testsuite/gcc.dg/permerror-nowarning.c.  They don't show up in the
> patch because the diagnostics don't change.

Ah, I see that now.  This patch is OK then.  Thanks.

Marek
  

Patch

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 eb7417fd9be..831242d134b 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -6185,6 +6185,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
@@ -7375,7 +7376,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-gnu89-nopermissive.c b/gcc/testsuite/gcc.dg/permerror-gnu89-nopermissive.c
index 0780e42b5cc..dc282a44489 100644
--- a/gcc/testsuite/gcc.dg/permerror-gnu89-nopermissive.c
+++ b/gcc/testsuite/gcc.dg/permerror-gnu89-nopermissive.c
@@ -75,7 +75,7 @@  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
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} } } */