c: Add -Wreturn-mismatch warning, split from -Wreturn-type

Message ID 87fs26pbh2.fsf@oldenburg.str.redhat.com
State Accepted
Headers
Series c: Add -Wreturn-mismatch warning, split from -Wreturn-type |

Checks

Context Check Description
snail/gcc-patch-check success Github commit url

Commit Message

Florian Weimer Oct. 19, 2023, 9:07 p.m. UTC
  The existing -Wreturn-type option covers both constraint violations
(which are mandatory to diagnose) and warnings that have known
false positives.  The new -Wreturn-mismatch warning is only about
the constraint violations (missing or extra return expressions),
and should eventually be turned into a permerror.

The -std=gnu89 test cases show that by default, we do not warn for
return; in a function not returning void.  This matches previous
practice for -Wreturn-type.

gcc/c-family/

	* c.opt (Wreturn-mismatch): New.

gcc/c/

	* c-typeck.cc (c_finish_return): Use pedwarn with
	OPT_Wreturn_mismatch for missing/extra return expressions.

gcc/

	* doc/invoke.texi (Warning Options): Document
	-Wreturn-mismatch.  Update -Wreturn-type documentation.

gcc/testsuite/

	* gcc.dg/Wreturn-mismatch-1.c: New.
	* gcc.dg/Wreturn-mismatch-2.c: New.
	* gcc.dg/Wreturn-mismatch-3.c: New.
	* gcc.dg/Wreturn-mismatch-4.c: New.
	* gcc.dg/Wreturn-mismatch-5.c: New.
	* gcc.dg/noncompile/pr55976-1.c: Change -Werror=return-type
	to -Werror=return-mismatch.
	* gcc.dg/noncompile/pr55976-2.c: Likewise.

---
 gcc/c-family/c.opt                          |  4 +++
 gcc/c/c-typeck.cc                           | 15 +++--------
 gcc/doc/invoke.texi                         | 35 +++++++++++++++---------
 gcc/testsuite/gcc.dg/Wreturn-mismatch-1.c   | 40 ++++++++++++++++++++++++++++
 gcc/testsuite/gcc.dg/Wreturn-mismatch-2.c   | 41 +++++++++++++++++++++++++++++
 gcc/testsuite/gcc.dg/Wreturn-mismatch-3.c   | 40 ++++++++++++++++++++++++++++
 gcc/testsuite/gcc.dg/Wreturn-mismatch-4.c   | 40 ++++++++++++++++++++++++++++
 gcc/testsuite/gcc.dg/Wreturn-mismatch-5.c   | 40 ++++++++++++++++++++++++++++
 gcc/testsuite/gcc.dg/noncompile/pr55976-1.c |  2 +-
 gcc/testsuite/gcc.dg/noncompile/pr55976-2.c |  2 +-
 10 files changed, 234 insertions(+), 25 deletions(-)


base-commit: 8f4bbdc28df6e87a7ad5ec5ca191a7a836a4f016
  

Comments

Joseph Myers Oct. 19, 2023, 9:33 p.m. UTC | #1
On Thu, 19 Oct 2023, Florian Weimer wrote:

> diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc
> index 6e044b4afbc..1da622160a3 100644
> --- a/gcc/c/c-typeck.cc
> +++ b/gcc/c/c-typeck.cc
> @@ -11281,17 +11281,10 @@ c_finish_return (location_t loc, tree retval, tree origtype)
>        if ((warn_return_type >= 0 || flag_isoc99)
>  	  && valtype != NULL_TREE && TREE_CODE (valtype) != VOID_TYPE)
>  	{
> -	  bool warned_here;
> -	  if (flag_isoc99)
> -	    warned_here = pedwarn
> -	      (loc, warn_return_type >= 0 ? OPT_Wreturn_type : 0,
> -	       "%<return%> with no value, in function returning non-void");
> -	  else
> -	    warned_here = warning_at
> -	      (loc, OPT_Wreturn_type,
> -	       "%<return%> with no value, in function returning non-void");
>  	  no_warning = true;
> -	  if (warned_here)
> +	  if (pedwarn (loc, OPT_Wreturn_mismatch,
> +		       "%<return%> with no value,"
> +		       " in function returning non-void"))

This should not be a pedwarn before C99 (should not be an error with 
-std=c90 -pedantic-errors -Wreturn-type), such a return is valid before 
C99.
  
Eric Gallager Oct. 19, 2023, 11:32 p.m. UTC | #2
On Thu, Oct 19, 2023 at 5:08 PM Florian Weimer <fweimer@redhat.com> wrote:
>
> The existing -Wreturn-type option covers both constraint violations
> (which are mandatory to diagnose) and warnings that have known
> false positives.  The new -Wreturn-mismatch warning is only about
> the constraint violations (missing or extra return expressions),
> and should eventually be turned into a permerror.
>
> The -std=gnu89 test cases show that by default, we do not warn for
> return; in a function not returning void.  This matches previous
> practice for -Wreturn-type.
>
> gcc/c-family/
>
>         * c.opt (Wreturn-mismatch): New.
>
> gcc/c/
>
>         * c-typeck.cc (c_finish_return): Use pedwarn with
>         OPT_Wreturn_mismatch for missing/extra return expressions.
>
> gcc/
>
>         * doc/invoke.texi (Warning Options): Document
>         -Wreturn-mismatch.  Update -Wreturn-type documentation.
>
> gcc/testsuite/
>
>         * gcc.dg/Wreturn-mismatch-1.c: New.
>         * gcc.dg/Wreturn-mismatch-2.c: New.
>         * gcc.dg/Wreturn-mismatch-3.c: New.
>         * gcc.dg/Wreturn-mismatch-4.c: New.
>         * gcc.dg/Wreturn-mismatch-5.c: New.
>         * gcc.dg/noncompile/pr55976-1.c: Change -Werror=return-type
>         to -Werror=return-mismatch.
>         * gcc.dg/noncompile/pr55976-2.c: Likewise.
>
> ---
>  gcc/c-family/c.opt                          |  4 +++
>  gcc/c/c-typeck.cc                           | 15 +++--------
>  gcc/doc/invoke.texi                         | 35 +++++++++++++++---------
>  gcc/testsuite/gcc.dg/Wreturn-mismatch-1.c   | 40 ++++++++++++++++++++++++++++
>  gcc/testsuite/gcc.dg/Wreturn-mismatch-2.c   | 41 +++++++++++++++++++++++++++++
>  gcc/testsuite/gcc.dg/Wreturn-mismatch-3.c   | 40 ++++++++++++++++++++++++++++
>  gcc/testsuite/gcc.dg/Wreturn-mismatch-4.c   | 40 ++++++++++++++++++++++++++++
>  gcc/testsuite/gcc.dg/Wreturn-mismatch-5.c   | 40 ++++++++++++++++++++++++++++
>  gcc/testsuite/gcc.dg/noncompile/pr55976-1.c |  2 +-
>  gcc/testsuite/gcc.dg/noncompile/pr55976-2.c |  2 +-
>  10 files changed, 234 insertions(+), 25 deletions(-)
>
> diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
> index 44b9c862c14..4c2ebd08af5 100644
> --- a/gcc/c-family/c.opt
> +++ b/gcc/c-family/c.opt
> @@ -1263,6 +1263,10 @@ Wreorder
>  C++ ObjC++ Var(warn_reorder) Warning LangEnabledBy(C++ ObjC++,Wall)
>  Warn when the compiler reorders code.
>
> +Wreturn-mismatch
> +C ObjC Var(warn_return_mismatch) Warning Init(1)
> +Warn whenever void-returning functions return a non-void expressions, or a return expression is missing in a function not returning void.
> +
>  Wreturn-type
>  C ObjC C++ ObjC++ Var(warn_return_type) Warning LangEnabledBy(C ObjC C++ ObjC++,Wall) Init(-1)
>  Warn whenever a function's return type defaults to \"int\" (C), or about inconsistent return types (C++).
> diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc
> index 6e044b4afbc..1da622160a3 100644
> --- a/gcc/c/c-typeck.cc
> +++ b/gcc/c/c-typeck.cc
> @@ -11281,17 +11281,10 @@ c_finish_return (location_t loc, tree retval, tree origtype)
>        if ((warn_return_type >= 0 || flag_isoc99)
>           && valtype != NULL_TREE && TREE_CODE (valtype) != VOID_TYPE)
>         {
> -         bool warned_here;
> -         if (flag_isoc99)
> -           warned_here = pedwarn
> -             (loc, warn_return_type >= 0 ? OPT_Wreturn_type : 0,
> -              "%<return%> with no value, in function returning non-void");
> -         else
> -           warned_here = warning_at
> -             (loc, OPT_Wreturn_type,
> -              "%<return%> with no value, in function returning non-void");
>           no_warning = true;
> -         if (warned_here)
> +         if (pedwarn (loc, OPT_Wreturn_mismatch,
> +                      "%<return%> with no value,"
> +                      " in function returning non-void"))
>             inform (DECL_SOURCE_LOCATION (current_function_decl),
>                     "declared here");
>         }
> @@ -11302,7 +11295,7 @@ c_finish_return (location_t loc, tree retval, tree origtype)
>        bool warned_here;
>        if (TREE_CODE (TREE_TYPE (retval)) != VOID_TYPE)
>         warned_here = pedwarn
> -         (xloc, warn_return_type >= 0 ? OPT_Wreturn_type : 0,
> +         (xloc, OPT_Wreturn_mismatch,
>            "%<return%> with a value, in function returning void");
>        else
>         warned_here = pedwarn
> diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
> index 9b5ff457027..c0c155af7cd 100644
> --- a/gcc/doc/invoke.texi
> +++ b/gcc/doc/invoke.texi
> @@ -7338,22 +7338,33 @@ This warning is enabled by @option{-Wall} for C and C++.
>  Do not warn about returning a pointer (or in C++, a reference) to a
>  variable that goes out of scope after the function returns.
>
> +@opindex Wreturn-mismatch
> +@opindex Wno-return-mismatch
> +@item -Wreturn-mismatch
> +Warn about return statements without an expressions in functions which
> +do not return @code{void}.  Also warn about a @code{return} statement
> +with an expression in a function whose return type is @code{void},
> +unless the expression type is also @code{void}.  As a GNU extension, the
> +latter case is accepted without a warning unless @option{-Wpedantic} is
> +used.
> +
> +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.
> +
>  @opindex Wreturn-type
>  @opindex Wno-return-type
>  @item -Wreturn-type
> -Warn whenever a function is defined with a return type that defaults
> -to @code{int}.  Also warn about any @code{return} statement with no
> -return value in a function whose return type is not @code{void}
> -(falling off the end of the function body is considered returning
> -without a value).
> +Warn whenever a function is defined with a return type that defaults to
> +@code{int} (unless @option{-Wimplicit-int} is active, which takes
> +precedence).  Also warn if execution may reach the end of the function
> +body, or if the function does not contain any return statement at all.
>
> -For C only, warn about a @code{return} statement with an expression in a
> -function whose return type is @code{void}, unless the expression type is
> -also @code{void}.  As a GNU extension, the latter case is accepted
> -without a warning unless @option{-Wpedantic} is used.  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.
> +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.
>
>  Unlike in C, in C++, flowing off the end of a non-@code{void} function other
>  than @code{main} results in undefined behavior even when the value of
> diff --git a/gcc/testsuite/gcc.dg/Wreturn-mismatch-1.c b/gcc/testsuite/gcc.dg/Wreturn-mismatch-1.c
> new file mode 100644
> index 00000000000..3bad847ecf7
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/Wreturn-mismatch-1.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-warning "'return' with a value\[^\n\r\]*-Wreturn-mismatch" } */
> +}
> +
> +void
> +f5 (void)
> +{
> +  return f1 (); /* { dg-bogus "ISO C" } */
> +}
> +
> +int
> +f6 (void)
> +{
> +  return; /* { dg-warning "'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
> new file mode 100644
> index 00000000000..49eb5a5a95c
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/Wreturn-mismatch-2.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-warning "with a value,\[^\n\r\]*-Wreturn-mismatch" } */
> +}
> +
> +void
> +f5 (void)
> +{
> +  return f1 ();
> +}
> +
> +int
> +f6 (void)
> +{
> +  return; /* { dg-warning "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/Wreturn-mismatch-3.c b/gcc/testsuite/gcc.dg/Wreturn-mismatch-3.c
> new file mode 100644
> index 00000000000..ee77ec6a769
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/Wreturn-mismatch-3.c
> @@ -0,0 +1,40 @@
> +/* { dg-do compile } */
> +/* { dg-options "-pedantic-errors" } */
> +
> +void f1 (void);
> +
> +int
> +f2 (void)
> +{
> +  f1 ();
> +}
> +
> +static inline int
> +f3 (void)
> +{
> +  f1 ();
> +}
> +
> +void
> +f4 (void)
> +{
> +  return 1; /* { dg-error "with a value,\[^\n\r\]*-Wreturn-mismatch" } */
> +}
> +
> +void
> +f5 (void)
> +{
> +  return f1 (); /* { dg-error "with expression, in function\[^\n\r\]*-Wpedantic" } */
> +}
> +
> +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" } */
> +}
> diff --git a/gcc/testsuite/gcc.dg/Wreturn-mismatch-4.c b/gcc/testsuite/gcc.dg/Wreturn-mismatch-4.c
> new file mode 100644
> index 00000000000..f73e8a05dc6
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/Wreturn-mismatch-4.c
> @@ -0,0 +1,40 @@
> +/* { dg-do compile } */
> +/* { dg-options "-std=gnu89" } */
> +
> +void f1 (void);
> +
> +int
> +f2 (void)
> +{
> +  f1 ();
> +}
> +
> +static inline int
> +f3 (void)
> +{
> +  f1 ();
> +}
> +
> +void
> +f4 (void)
> +{
> +  return 1; /* { dg-warning "with a value,\[^\n\r\]*-Wreturn-mismatch" } */
> +}
> +
> +void
> +f5 (void)
> +{
> +  return f1 ();
> +}
> +
> +int
> +f6 (void)
> +{
> +  return; /* { dg-bogus "with no value" }  */
> +}
> +
> +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-5.c b/gcc/testsuite/gcc.dg/Wreturn-mismatch-5.c
> new file mode 100644
> index 00000000000..f2fd3294b7b
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/Wreturn-mismatch-5.c
> @@ -0,0 +1,40 @@
> +/* { dg-do compile } */
> +/* { dg-options "-std=gnu89 -pedantic-errors" } */
> +
> +void f1 (void);
> +
> +int
> +f2 (void)
> +{
> +  f1 ();
> +}
> +
> +static inline int
> +f3 (void)
> +{
> +  f1 ();
> +}
> +
> +void
> +f4 (void)
> +{
> +  return 1; /* { dg-error "with a value,\[^\n\r\]*-Wreturn-mismatch" } */
> +}
> +
> +void
> +f5 (void)
> +{
> +  return f1 (); /* { dg-error "with expression\[^\n\r\]*-Wpedantic" } */
> +}
> +
> +int
> +f6 (void)
> +{
> +  return;
> +}
> +
> +int
> +f7 (void)
> +{
> +  return f1 (); /* { dg-error "void value not ignored as it ought to be" } */
> +}
> diff --git a/gcc/testsuite/gcc.dg/noncompile/pr55976-1.c b/gcc/testsuite/gcc.dg/noncompile/pr55976-1.c
> index d078990bd88..d348b03ad94 100644
> --- a/gcc/testsuite/gcc.dg/noncompile/pr55976-1.c
> +++ b/gcc/testsuite/gcc.dg/noncompile/pr55976-1.c
> @@ -1,6 +1,6 @@
>  /* PR c/55976 */
>  /* { dg-do compile } */
> -/* { dg-options "-Werror=return-type" } */
> +/* { dg-options "-Werror=return-mismatch" } */
>  /* { dg-prune-output "some warnings being treated as errors" } */
>
>  /* Verify warnings for return type become errors.  */
> diff --git a/gcc/testsuite/gcc.dg/noncompile/pr55976-2.c b/gcc/testsuite/gcc.dg/noncompile/pr55976-2.c
> index 0e493d0e8af..a9494255369 100644
> --- a/gcc/testsuite/gcc.dg/noncompile/pr55976-2.c
> +++ b/gcc/testsuite/gcc.dg/noncompile/pr55976-2.c
> @@ -1,6 +1,6 @@
>  /* PR c/55976 */
>  /* { dg-do compile } */
> -/* { dg-options "-Wno-return-type" } */
> +/* { dg-options "-Wno-return-mismatch" } */
>
>  /* Verify that -Wno-return-type turns off warnings about function return
>     type.  */

Comment here should be updated to match the flag being used.

>
> base-commit: 8f4bbdc28df6e87a7ad5ec5ca191a7a836a4f016
>
  

Patch

diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
index 44b9c862c14..4c2ebd08af5 100644
--- a/gcc/c-family/c.opt
+++ b/gcc/c-family/c.opt
@@ -1263,6 +1263,10 @@  Wreorder
 C++ ObjC++ Var(warn_reorder) Warning LangEnabledBy(C++ ObjC++,Wall)
 Warn when the compiler reorders code.
 
+Wreturn-mismatch
+C ObjC Var(warn_return_mismatch) Warning Init(1)
+Warn whenever void-returning functions return a non-void expressions, or a return expression is missing in a function not returning void.
+
 Wreturn-type
 C ObjC C++ ObjC++ Var(warn_return_type) Warning LangEnabledBy(C ObjC C++ ObjC++,Wall) Init(-1)
 Warn whenever a function's return type defaults to \"int\" (C), or about inconsistent return types (C++).
diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc
index 6e044b4afbc..1da622160a3 100644
--- a/gcc/c/c-typeck.cc
+++ b/gcc/c/c-typeck.cc
@@ -11281,17 +11281,10 @@  c_finish_return (location_t loc, tree retval, tree origtype)
       if ((warn_return_type >= 0 || flag_isoc99)
 	  && valtype != NULL_TREE && TREE_CODE (valtype) != VOID_TYPE)
 	{
-	  bool warned_here;
-	  if (flag_isoc99)
-	    warned_here = pedwarn
-	      (loc, warn_return_type >= 0 ? OPT_Wreturn_type : 0,
-	       "%<return%> with no value, in function returning non-void");
-	  else
-	    warned_here = warning_at
-	      (loc, OPT_Wreturn_type,
-	       "%<return%> with no value, in function returning non-void");
 	  no_warning = true;
-	  if (warned_here)
+	  if (pedwarn (loc, OPT_Wreturn_mismatch,
+		       "%<return%> with no value,"
+		       " in function returning non-void"))
 	    inform (DECL_SOURCE_LOCATION (current_function_decl),
 		    "declared here");
 	}
@@ -11302,7 +11295,7 @@  c_finish_return (location_t loc, tree retval, tree origtype)
       bool warned_here;
       if (TREE_CODE (TREE_TYPE (retval)) != VOID_TYPE)
 	warned_here = pedwarn
-	  (xloc, warn_return_type >= 0 ? OPT_Wreturn_type : 0,
+	  (xloc, OPT_Wreturn_mismatch,
 	   "%<return%> with a value, in function returning void");
       else
 	warned_here = pedwarn
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 9b5ff457027..c0c155af7cd 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -7338,22 +7338,33 @@  This warning is enabled by @option{-Wall} for C and C++.
 Do not warn about returning a pointer (or in C++, a reference) to a
 variable that goes out of scope after the function returns.
 
+@opindex Wreturn-mismatch
+@opindex Wno-return-mismatch
+@item -Wreturn-mismatch
+Warn about return statements without an expressions in functions which
+do not return @code{void}.  Also warn about a @code{return} statement
+with an expression in a function whose return type is @code{void},
+unless the expression type is also @code{void}.  As a GNU extension, the
+latter case is accepted without a warning unless @option{-Wpedantic} is
+used.
+
+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.
+
 @opindex Wreturn-type
 @opindex Wno-return-type
 @item -Wreturn-type
-Warn whenever a function is defined with a return type that defaults
-to @code{int}.  Also warn about any @code{return} statement with no
-return value in a function whose return type is not @code{void}
-(falling off the end of the function body is considered returning
-without a value).
+Warn whenever a function is defined with a return type that defaults to
+@code{int} (unless @option{-Wimplicit-int} is active, which takes
+precedence).  Also warn if execution may reach the end of the function
+body, or if the function does not contain any return statement at all.
 
-For C only, warn about a @code{return} statement with an expression in a
-function whose return type is @code{void}, unless the expression type is
-also @code{void}.  As a GNU extension, the latter case is accepted
-without a warning unless @option{-Wpedantic} is used.  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.
+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.
 
 Unlike in C, in C++, flowing off the end of a non-@code{void} function other
 than @code{main} results in undefined behavior even when the value of
diff --git a/gcc/testsuite/gcc.dg/Wreturn-mismatch-1.c b/gcc/testsuite/gcc.dg/Wreturn-mismatch-1.c
new file mode 100644
index 00000000000..3bad847ecf7
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wreturn-mismatch-1.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-warning "'return' with a value\[^\n\r\]*-Wreturn-mismatch" } */
+}
+
+void
+f5 (void)
+{
+  return f1 (); /* { dg-bogus "ISO C" } */
+}
+
+int
+f6 (void)
+{
+  return; /* { dg-warning "'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
new file mode 100644
index 00000000000..49eb5a5a95c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wreturn-mismatch-2.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-warning "with a value,\[^\n\r\]*-Wreturn-mismatch" } */
+}
+
+void
+f5 (void)
+{
+  return f1 ();
+}
+
+int
+f6 (void)
+{
+  return; /* { dg-warning "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/Wreturn-mismatch-3.c b/gcc/testsuite/gcc.dg/Wreturn-mismatch-3.c
new file mode 100644
index 00000000000..ee77ec6a769
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wreturn-mismatch-3.c
@@ -0,0 +1,40 @@ 
+/* { dg-do compile } */
+/* { dg-options "-pedantic-errors" } */
+
+void f1 (void);
+
+int
+f2 (void)
+{
+  f1 ();
+}
+
+static inline int
+f3 (void)
+{
+  f1 ();
+}
+
+void
+f4 (void)
+{
+  return 1; /* { dg-error "with a value,\[^\n\r\]*-Wreturn-mismatch" } */
+}
+
+void
+f5 (void)
+{
+  return f1 (); /* { dg-error "with expression, in function\[^\n\r\]*-Wpedantic" } */
+}
+
+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" } */
+}
diff --git a/gcc/testsuite/gcc.dg/Wreturn-mismatch-4.c b/gcc/testsuite/gcc.dg/Wreturn-mismatch-4.c
new file mode 100644
index 00000000000..f73e8a05dc6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wreturn-mismatch-4.c
@@ -0,0 +1,40 @@ 
+/* { dg-do compile } */
+/* { dg-options "-std=gnu89" } */
+
+void f1 (void);
+
+int
+f2 (void)
+{
+  f1 ();
+}
+
+static inline int
+f3 (void)
+{
+  f1 ();
+}
+
+void
+f4 (void)
+{
+  return 1; /* { dg-warning "with a value,\[^\n\r\]*-Wreturn-mismatch" } */
+}
+
+void
+f5 (void)
+{
+  return f1 ();
+}
+
+int
+f6 (void)
+{
+  return; /* { dg-bogus "with no value" }  */
+}
+
+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-5.c b/gcc/testsuite/gcc.dg/Wreturn-mismatch-5.c
new file mode 100644
index 00000000000..f2fd3294b7b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wreturn-mismatch-5.c
@@ -0,0 +1,40 @@ 
+/* { dg-do compile } */
+/* { dg-options "-std=gnu89 -pedantic-errors" } */
+
+void f1 (void);
+
+int
+f2 (void)
+{
+  f1 ();
+}
+
+static inline int
+f3 (void)
+{
+  f1 ();
+}
+
+void
+f4 (void)
+{
+  return 1; /* { dg-error "with a value,\[^\n\r\]*-Wreturn-mismatch" } */
+}
+
+void
+f5 (void)
+{
+  return f1 (); /* { dg-error "with expression\[^\n\r\]*-Wpedantic" } */
+}
+
+int
+f6 (void)
+{
+  return;
+}
+
+int
+f7 (void)
+{
+  return f1 (); /* { dg-error "void value not ignored as it ought to be" } */
+}
diff --git a/gcc/testsuite/gcc.dg/noncompile/pr55976-1.c b/gcc/testsuite/gcc.dg/noncompile/pr55976-1.c
index d078990bd88..d348b03ad94 100644
--- a/gcc/testsuite/gcc.dg/noncompile/pr55976-1.c
+++ b/gcc/testsuite/gcc.dg/noncompile/pr55976-1.c
@@ -1,6 +1,6 @@ 
 /* PR c/55976 */
 /* { dg-do compile } */
-/* { dg-options "-Werror=return-type" } */
+/* { dg-options "-Werror=return-mismatch" } */
 /* { dg-prune-output "some warnings being treated as errors" } */
 
 /* Verify warnings for return type become errors.  */
diff --git a/gcc/testsuite/gcc.dg/noncompile/pr55976-2.c b/gcc/testsuite/gcc.dg/noncompile/pr55976-2.c
index 0e493d0e8af..a9494255369 100644
--- a/gcc/testsuite/gcc.dg/noncompile/pr55976-2.c
+++ b/gcc/testsuite/gcc.dg/noncompile/pr55976-2.c
@@ -1,6 +1,6 @@ 
 /* PR c/55976 */
 /* { dg-do compile } */
-/* { dg-options "-Wno-return-type" } */
+/* { dg-options "-Wno-return-mismatch" } */
 
 /* Verify that -Wno-return-type turns off warnings about function return
    type.  */