Commit 94c40e19 by David Malcolm Committed by David Malcolm

C FE: improvements to ranges of bad return values

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
parent e357a5e0
2015-12-16 David Malcolm <dmalcolm@redhat.com> 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 * c-parser.c (struct c_parser): Expand array "tokens_buf" from 2
to 4. to 4.
(c_parser_peek_nth_token): New function. (c_parser_peek_nth_token): New function.
......
...@@ -5179,7 +5179,8 @@ c_parser_statement_after_labels (c_parser *parser, vec<tree> *chain) ...@@ -5179,7 +5179,8 @@ c_parser_statement_after_labels (c_parser *parser, vec<tree> *chain)
location_t xloc = c_parser_peek_token (parser)->location; location_t xloc = c_parser_peek_token (parser)->location;
struct c_expr expr = c_parser_expression_conv (parser); struct c_expr expr = c_parser_expression_conv (parser);
mark_exp_read (expr.value); 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; goto expect_semicolon;
} }
break; break;
......
...@@ -9545,24 +9545,36 @@ c_finish_return (location_t loc, tree retval, tree origtype) ...@@ -9545,24 +9545,36 @@ c_finish_return (location_t loc, tree retval, tree origtype)
if ((warn_return_type || flag_isoc99) if ((warn_return_type || flag_isoc99)
&& valtype != 0 && TREE_CODE (valtype) != VOID_TYPE) && valtype != 0 && TREE_CODE (valtype) != VOID_TYPE)
{ {
bool warned_here;
if (flag_isoc99) if (flag_isoc99)
pedwarn (loc, 0, "%<return%> with no value, in " warned_here = pedwarn
"function returning non-void"); (loc, 0,
"%<return%> with no value, in function returning non-void");
else else
warning_at (loc, OPT_Wreturn_type, "%<return%> with no value, " warned_here = warning_at
"in function returning non-void"); (loc, OPT_Wreturn_type,
"%<return%> with no value, in function returning non-void");
no_warning = true; no_warning = true;
if (warned_here)
inform (DECL_SOURCE_LOCATION (current_function_decl),
"declared here");
} }
} }
else if (valtype == 0 || TREE_CODE (valtype) == VOID_TYPE) else if (valtype == 0 || TREE_CODE (valtype) == VOID_TYPE)
{ {
current_function_returns_null = 1; current_function_returns_null = 1;
bool warned_here;
if (TREE_CODE (TREE_TYPE (retval)) != VOID_TYPE) if (TREE_CODE (TREE_TYPE (retval)) != VOID_TYPE)
pedwarn (xloc, 0, warned_here = pedwarn
"%<return%> with a value, in function returning void"); (xloc, 0,
"%<return%> with a value, in function returning void");
else else
pedwarn (xloc, OPT_Wpedantic, "ISO C forbids " warned_here = pedwarn
"%<return%> with expression, in function returning void"); (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 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> 2015-12-17 Richard Biener <rguenther@suse.de>
PR tree-optimization/68946 PR tree-optimization/68946
......
/* { 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. */
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment