This patch fixes handling of -Werror=return-type as well as -Wno-return-type. Currently, -Werror=return-type does not turn the warnings into errors and -Wno-return-type does not turn off warning/error. Now they both work as expected.

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=55976

Initialize warn_return_type only for C++/C++ with ObjC extensions. In C, this allows us to differentiate between default (no option), or cases where -Wreturn-type/-Wno-return-type are specified. Elsewhere, update references to warn_return_type (for C) to reflect change in initialization.

Patch was successfully bootstrapped and tested on x86_64-linux.

--Dave

/c
2018-04-22  David Pagan  <dave.pa...@oracle.com>

        PR c/55976
        * c-decl.c (grokdeclarator): Update check for return type warnings.
        (start_function): Likewise.
        (finish_function): Likewise.
        * c-typeck.c (c_finish_return): Update check for return type warnings.
        Pass OPT_Wreturn_type to pedwarn when appropriate.
        * c-opts.c (c_common_post_options): Set default for warn_return_type
        for C++/C++ with ObjC extensions only. For C, makes it possible to 
        differentiate between default (no option), -Wreturn-type, and
        -Wno-return-type.

/testsuite
2018-04-22  David Pagan  <dave.pa...@oracle.com>

        PR c/55976
        * gcc.dg/noncompile/pr55976-1.c: New test.
        * gcc.dg/noncompile/pr55976-2.c: New test.
Index: gcc/c/c-decl.c
===================================================================
--- gcc/c/c-decl.c      (revision 259017)
+++ gcc/c/c-decl.c      (working copy)
@@ -5745,7 +5745,7 @@ grokdeclarator (const struct c_declarator *declara
       /* Issue a warning if this is an ISO C 99 program or if
         -Wreturn-type and this is a function, or if -Wimplicit;
         prefer the former warning since it is more explicit.  */
-      if ((warn_implicit_int || warn_return_type || flag_isoc99)
+      if ((warn_implicit_int || warn_return_type > 0 || flag_isoc99)
          && funcdef_flag)
        warn_about_return_type = 1;
       else
@@ -8739,7 +8739,7 @@ start_function (struct c_declspecs *declspecs, str
 
   if (warn_about_return_type)
     warn_defaults_to (loc, flag_isoc99 ? OPT_Wimplicit_int
-                          : (warn_return_type ? OPT_Wreturn_type
+                          : (warn_return_type > 0 ? OPT_Wreturn_type
                              : OPT_Wimplicit_int),
                      "return type defaults to %<int%>");
 
@@ -9450,8 +9450,9 @@ finish_function (void)
 
   finish_fname_decls ();
 
-  /* Complain if there's just no return statement.  */
-  if (warn_return_type
+  /* Complain if there's no return statement only if option specified on
+     command line.  */
+  if (warn_return_type > 0
       && TREE_CODE (TREE_TYPE (TREE_TYPE (fndecl))) != VOID_TYPE
       && !current_function_returns_value && !current_function_returns_null
       /* Don't complain if we are no-return.  */
Index: gcc/c/c-typeck.c
===================================================================
--- gcc/c/c-typeck.c    (revision 259017)
+++ gcc/c/c-typeck.c    (working copy)
@@ -10129,13 +10129,13 @@ c_finish_return (location_t loc, tree retval, tree
   if (!retval)
     {
       current_function_returns_null = 1;
-      if ((warn_return_type || flag_isoc99)
+      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, 0,
+             (loc, warn_return_type >= 0 ? OPT_Wreturn_type : 0,
               "%<return%> with no value, in function returning non-void");
          else
            warned_here = warning_at
@@ -10153,7 +10153,7 @@ c_finish_return (location_t loc, tree retval, tree
       bool warned_here;
       if (TREE_CODE (TREE_TYPE (retval)) != VOID_TYPE)
        warned_here = pedwarn
-         (xloc, 0,
+         (xloc, warn_return_type >= 0 ? OPT_Wreturn_type : 0,
           "%<return%> with a value, in function returning void");
       else
        warned_here = pedwarn
Index: gcc/c-family/c-opts.c
===================================================================
--- gcc/c-family/c-opts.c       (revision 259017)
+++ gcc/c-family/c-opts.c       (working copy)
@@ -994,8 +994,9 @@ c_common_post_options (const char **pfilename)
        flag_extern_tls_init = 1;
     }
 
-  if (warn_return_type == -1)
-    warn_return_type = c_dialect_cxx ();
+  /* Enable by default only for C++ and C++ with ObjC extensions.  */
+  if (warn_return_type == -1 && c_dialect_cxx ())
+    warn_return_type = 1;
 
   if (num_in_fnames > 1)
     error ("too many filenames given.  Type %s --help for usage",
Index: gcc/testsuite/gcc.dg/noncompile/pr55976-1.c
===================================================================
--- gcc/testsuite/gcc.dg/noncompile/pr55976-1.c (revision 0)
+++ gcc/testsuite/gcc.dg/noncompile/pr55976-1.c (working copy)
@@ -0,0 +1,14 @@
+/* PR c/55976 */
+/* { dg-do compile } */
+/* { dg-options "-Werror=return-type" } */
+
+/* Verify warnings for return type become errors.  */
+
+void t () { return 1; } /* { dg-error "return" "function returning void" } */
+int b () { return; } /* { dg-error "return" "function returning non-void" } */
+
+int main()
+{
+  t(); b();
+  return 0;
+}
Index: gcc/testsuite/gcc.dg/noncompile/pr55976-2.c
===================================================================
--- gcc/testsuite/gcc.dg/noncompile/pr55976-2.c (revision 0)
+++ gcc/testsuite/gcc.dg/noncompile/pr55976-2.c (working copy)
@@ -0,0 +1,16 @@
+/* PR c/55976 */
+/* { dg-do compile } */
+/* { dg-options "-Wno-return-type" } */
+
+/* Verify that -Wno-return-type turns off warnings about function return
+   type.  */
+
+void t () { return 1; } /* normally generates function returning void */
+int b () { return; } /* normally generates function returning non-void */
+
+int main()
+{
+  t (); b ();
+  return 0;
+}
+

Reply via email to