From: David Malcolm Date: Thu, 17 Dec 2015 21:25:36 +0000 (+0000) Subject: C FE: improvements to ranges of bad return values X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=94c40e19af4ca5fe57c990df7f7abec48f5aa3af;p=gcc.git 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 --- diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index 22692d42a64..7c1247d120e 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,12 @@ +2015-12-16 David Malcolm + + * 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 * c-parser.c (struct c_parser): Expand array "tokens_buf" from 2 diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c index 43c26ae7384..353e3da5377 100644 --- a/gcc/c/c-parser.c +++ b/gcc/c/c-parser.c @@ -5179,7 +5179,8 @@ c_parser_statement_after_labels (c_parser *parser, vec *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; diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c index a147ac6a7ce..b605f81fb43 100644 --- a/gcc/c/c-typeck.c +++ b/gcc/c/c-typeck.c @@ -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, "% with no value, in " - "function returning non-void"); + warned_here = pedwarn + (loc, 0, + "% with no value, in function returning non-void"); else - warning_at (loc, OPT_Wreturn_type, "% with no value, " - "in function returning non-void"); + warned_here = warning_at + (loc, OPT_Wreturn_type, + "% 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, - "% with a value, in function returning void"); + warned_here = pedwarn + (xloc, 0, + "% with a value, in function returning void"); else - pedwarn (xloc, OPT_Wpedantic, "ISO C forbids " - "% with expression, in function returning void"); + warned_here = pedwarn + (xloc, OPT_Wpedantic, "ISO C forbids " + "% with expression, in function returning void"); + if (warned_here) + inform (DECL_SOURCE_LOCATION (current_function_decl), + "declared here"); } else { diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 976356d42db..2cbde3b8552 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2015-12-17 David Malcolm + + * gcc.dg/diagnostic-range-bad-return.c: New test case. + 2015-12-17 Richard Biener 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 index 00000000000..063fdf1f636 --- /dev/null +++ b/gcc/testsuite/gcc.dg/diagnostic-range-bad-return.c @@ -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. */ +}