+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
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;
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
{
+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
--- /dev/null
+/* { 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. */
+}