diff options
-rw-r--r-- | gcc/c/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/c/c-parser.c | 3 | ||||
-rw-r--r-- | gcc/c/c-typeck.c | 28 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/diagnostic-range-bad-return.c | 52 |
5 files changed, 87 insertions, 9 deletions
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index 22692d4..7c1247d 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,5 +1,14 @@ 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 to 4. (c_parser_peek_nth_token): New function. diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c index 43c26ae..353e3da 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<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; diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c index a147ac6..b605f81 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, "%<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 { diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 976356d..2cbde3b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -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 index 0000000..063fdf1 --- /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. */ +} |