For clarity, here's the entire split-up patch I intend to push, if it looks OK. Tested on x86_64-pc-linux-gnu.
I've renamed the field we've discussed and also a few parameters that refer to 'kw' to be less specific. The code is functionally identical. OK for trunk? TIA, have a lovely day. ---------- >8 ---------- This patch improves the EXPR_LOCATION associated with parsed RETURN_EXPRs so that they can be used in diagnostics later. This change also happened to un-suppress an analyzer false-negative that was happening because the location of RETURN_EXPR was entirely within the NULL macro, which was defined in a system header. PR analyzer/116304. gcc/cp/ChangeLog: * cp-tree.h (finish_return_stmt): Add optional location_t parameter, defaulting to input_location. * parser.cc (cp_parser_jump_statement): Improve return and co_return locations so that they span their entire statements. * semantics.cc (finish_return_stmt): Use the new stmt_loc parameter in place of input_location. gcc/testsuite/ChangeLog: * c-c++-common/analyzer/inlining-4-multiline.c: Adjust locations in diagnostics. * c-c++-common/analyzer/malloc-paths-9-noexcept.c: Ditto. * c-c++-common/analyzer/malloc-CWE-401-example.c: Accept the new warning on line 34 (fixed false negative). --- gcc/cp/cp-tree.h | 2 +- gcc/cp/parser.cc | 9 +++++++-- gcc/cp/semantics.cc | 4 ++-- .../c-c++-common/analyzer/inlining-4-multiline.c | 6 ------ .../c-c++-common/analyzer/malloc-CWE-401-example.c | 1 + .../c-c++-common/analyzer/malloc-paths-9-noexcept.c | 10 +++++----- 6 files changed, 16 insertions(+), 16 deletions(-) diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index a53fbcb43ec4..83be768420aa 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -7794,7 +7794,7 @@ extern void finish_while_stmt (tree); extern tree begin_do_stmt (void); extern void finish_do_body (tree); extern void finish_do_stmt (tree, tree, bool, tree, bool); -extern tree finish_return_stmt (tree); +extern tree finish_return_stmt (tree, location_t = input_location); extern tree begin_for_scope (tree *); extern tree begin_for_stmt (tree, tree); extern void finish_init_stmt (tree); diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc index c9654cfff9d2..68b3f0a0f5c4 100644 --- a/gcc/cp/parser.cc +++ b/gcc/cp/parser.cc @@ -14952,14 +14952,19 @@ cp_parser_jump_statement (cp_parser* parser, tree &std_attrs) set_musttail_on_return (expr, token->location, musttail_p); } + /* A location spanning the whole statement (up to ';'). */ + auto stmt_loc = make_location (token->location, + token->location, + input_location); + /* Build the return-statement, check co-return first, since type deduction is not valid there. */ if (keyword == RID_CO_RETURN) - statement = finish_co_return_stmt (token->location, expr); + statement = finish_co_return_stmt (stmt_loc, expr); else if (FNDECL_USED_AUTO (current_function_decl) && in_discarded_stmt) /* Don't deduce from a discarded return statement. */; else - statement = finish_return_stmt (expr); + statement = finish_return_stmt (expr, stmt_loc); /* Look for the final `;'. */ cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON); } diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc index 5ab2076b673c..734c613a474e 100644 --- a/gcc/cp/semantics.cc +++ b/gcc/cp/semantics.cc @@ -1400,7 +1400,7 @@ finish_do_stmt (tree cond, tree do_stmt, bool ivdep, tree unroll, indicated. */ tree -finish_return_stmt (tree expr) +finish_return_stmt (tree expr, location_t stmt_loc) { tree r; bool no_warning; @@ -1423,7 +1423,7 @@ finish_return_stmt (tree expr) verify_sequence_points (expr); } - r = build_stmt (input_location, RETURN_EXPR, expr); + r = build_stmt (stmt_loc, RETURN_EXPR, expr); RETURN_EXPR_LOCAL_ADDR_P (r) = dangling; if (no_warning) suppress_warning (r, OPT_Wreturn_type); diff --git a/gcc/testsuite/c-c++-common/analyzer/inlining-4-multiline.c b/gcc/testsuite/c-c++-common/analyzer/inlining-4-multiline.c index 5c971c581ae4..235b715cff96 100644 --- a/gcc/testsuite/c-c++-common/analyzer/inlining-4-multiline.c +++ b/gcc/testsuite/c-c++-common/analyzer/inlining-4-multiline.c @@ -109,15 +109,9 @@ outer (int flag) | 'const char* inner(int)': event 5 (depth 3) | - | - | #define NULL - | - | | - | (5) ...to here { dg-end-multiline-output "" { target c++ } } */ /* { dg-begin-multiline-output "" } | return NULL; - | ^~~~ | <-------------+ | diff --git a/gcc/testsuite/c-c++-common/analyzer/malloc-CWE-401-example.c b/gcc/testsuite/c-c++-common/analyzer/malloc-CWE-401-example.c index cfb5e86260c1..659c38adf2f0 100644 --- a/gcc/testsuite/c-c++-common/analyzer/malloc-CWE-401-example.c +++ b/gcc/testsuite/c-c++-common/analyzer/malloc-CWE-401-example.c @@ -32,6 +32,7 @@ char* getBlock(int fd) { if (read(fd, buf, BLOCK_SIZE) != BLOCK_SIZE) { return NULL; /* TODO: should complain that "buf" is leaked on this path. */ + // { dg-warning "CWE-401" "" { target c++ } {.-1} } } return buf; } diff --git a/gcc/testsuite/c-c++-common/analyzer/malloc-paths-9-noexcept.c b/gcc/testsuite/c-c++-common/analyzer/malloc-paths-9-noexcept.c index 57d25f436a08..156bfb2c5300 100644 --- a/gcc/testsuite/c-c++-common/analyzer/malloc-paths-9-noexcept.c +++ b/gcc/testsuite/c-c++-common/analyzer/malloc-paths-9-noexcept.c @@ -374,7 +374,7 @@ int test_3 (int x, int y) { dg-end-multiline-output "" { target c } } */ /* { dg-begin-multiline-output "" } NN | return *ptr; - | ^~~ + | ^~~~~~~~~~~ 'int test_3(int, int)': events 1-7 NN | int *ptr = (int *)malloc (sizeof (int)); | ~~~~~~~^~~~~~~~~~~~~~ @@ -400,8 +400,8 @@ int test_3 (int x, int y) | (5) following 'false' branch (when 'y == 0')... ...... NN | return *ptr; - | ~~~ - | | - | (6) ...to here - | (7) 'ptr' leaks here; was allocated at (1) + | ~~~~~~~~~~~ + | | | + | | (6) ...to here + | (7) 'ptr' leaks here; was allocated at (1) { dg-end-multiline-output "" { target c++ } } */ -- 2.46.0