C FE: improvements to ranges of bad return values
authorDavid Malcolm <dmalcolm@redhat.com>
Thu, 17 Dec 2015 21:25:36 +0000 (21:25 +0000)
committerDavid Malcolm <dmalcolm@gcc.gnu.org>
Thu, 17 Dec 2015 21:25:36 +0000 (21:25 +0000)
gcc/c/ChangeLog:
* c-parser.c (c_parser_statement_after_labels): When calling
c_finish_return, Use the return expression's location if it has
one, falling back to the location of the first token within it.
* c-typeck.c (c_finish_return): When issuing warnings about
the incorrect presence/absence of a return value, issue a note
showing the declaration of the function.

gcc/testsuite/ChangeLog:
* gcc.dg/diagnostic-range-bad-return.c: New test case.

From-SVN: r231786

gcc/c/ChangeLog
gcc/c/c-parser.c
gcc/c/c-typeck.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/diagnostic-range-bad-return.c [new file with mode: 0644]

index 22692d42a642e30ffbbee4ebfff45475b33b2420..7c1247d120e25a2920bcbe15d4194fadbe6753f2 100644 (file)
@@ -1,3 +1,12 @@
+2015-12-16  David Malcolm  <dmalcolm@redhat.com>
+
+       * c-parser.c (c_parser_statement_after_labels): When calling
+       c_finish_return, Use the return expression's location if it has
+       one, falling back to the location of the first token within it.
+       * c-typeck.c (c_finish_return): When issuing warnings about
+       the incorrect presence/absence of a return value, issue a note
+       showing the declaration of the function.
+
 2015-12-16  David Malcolm  <dmalcolm@redhat.com>
 
        * c-parser.c (struct c_parser): Expand array "tokens_buf" from 2
index 43c26ae73847ebcb7817ec8a44eb894ae8af6260..353e3da5377b18dba21da0615717027b3a4d2364 100644 (file)
@@ -5179,7 +5179,8 @@ c_parser_statement_after_labels (c_parser *parser, vec<tree> *chain)
              location_t xloc = c_parser_peek_token (parser)->location;
              struct c_expr expr = c_parser_expression_conv (parser);
              mark_exp_read (expr.value);
-             stmt = c_finish_return (xloc, expr.value, expr.original_type);
+             stmt = c_finish_return (EXPR_LOC_OR_LOC (expr.value, xloc),
+                                     expr.value, expr.original_type);
              goto expect_semicolon;
            }
          break;
index a147ac6a7cedf5a5e60f4c560c2b5b6ba0c19479..b605f81fb43b504c277e37802cd8a547708b229b 100644 (file)
@@ -9545,24 +9545,36 @@ c_finish_return (location_t loc, tree retval, tree origtype)
       if ((warn_return_type || flag_isoc99)
          && valtype != 0 && TREE_CODE (valtype) != VOID_TYPE)
        {
+         bool warned_here;
          if (flag_isoc99)
-           pedwarn (loc, 0, "%<return%> with no value, in "
-                    "function returning non-void");
+           warned_here = pedwarn
+             (loc, 0,
+              "%<return%> with no value, in function returning non-void");
          else
-           warning_at (loc, OPT_Wreturn_type, "%<return%> with no value, "
-                       "in function returning non-void");
+           warned_here = warning_at
+             (loc, OPT_Wreturn_type,
+              "%<return%> with no value, in function returning non-void");
          no_warning = true;
+         if (warned_here)
+           inform (DECL_SOURCE_LOCATION (current_function_decl),
+                   "declared here");
        }
     }
   else if (valtype == 0 || TREE_CODE (valtype) == VOID_TYPE)
     {
       current_function_returns_null = 1;
+      bool warned_here;
       if (TREE_CODE (TREE_TYPE (retval)) != VOID_TYPE)
-       pedwarn (xloc, 0,
-                "%<return%> with a value, in function returning void");
+       warned_here = pedwarn
+         (xloc, 0,
+          "%<return%> with a value, in function returning void");
       else
-       pedwarn (xloc, OPT_Wpedantic, "ISO C forbids "
-                "%<return%> with expression, in function returning void");
+       warned_here = pedwarn
+         (xloc, OPT_Wpedantic, "ISO C forbids "
+          "%<return%> with expression, in function returning void");
+      if (warned_here)
+       inform (DECL_SOURCE_LOCATION (current_function_decl),
+               "declared here");
     }
   else
     {
index 976356d42dba26987f4d8f5f0f26e6148e3ecf16..2cbde3b85527813172873d1ad12c7f402fdc6cc7 100644 (file)
@@ -1,3 +1,7 @@
+2015-12-17  David Malcolm  <dmalcolm@redhat.com>
+
+       * gcc.dg/diagnostic-range-bad-return.c: New test case.
+
 2015-12-17  Richard Biener  <rguenther@suse.de>
 
        PR tree-optimization/68946
diff --git a/gcc/testsuite/gcc.dg/diagnostic-range-bad-return.c b/gcc/testsuite/gcc.dg/diagnostic-range-bad-return.c
new file mode 100644 (file)
index 0000000..063fdf1
--- /dev/null
@@ -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-warning "'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-warning "'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-warning "'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.  */
+}