PR c++/80016 reports an issue with bizarre underlined range for a complicated expression.
The root cause for the incorrect *starting* location of that range is that alignof and sizeof expressions currently have start == finish == caret at the opening parenthesis of the expression. This patch fixes this by generating appropriate start and finish locations for alignof and sizeof expressions. Successfully bootstrapped®rtested on x86_64-pc-linux-gnu. OK for trunk now, or should this wait until stage 1? gcc/cp/ChangeLog: PR c++/80016 * parser.c (cp_parser_unary_expression): Generate a location range for alignof and sizeof expressions. gcc/testsuite/ChangeLog: PR c++/80016 * g++.dg/plugin/diagnostic-test-expressions-1.C (test_sizeof): New test function. (test_alignof): New test function. --- gcc/cp/parser.c | 19 +++++-- .../g++.dg/plugin/diagnostic-test-expressions-1.C | 66 ++++++++++++++++++++++ 2 files changed, 81 insertions(+), 4 deletions(-) diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index aecf9a5..0d9667e 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -7817,12 +7817,11 @@ cp_parser_unary_expression (cp_parser *parser, cp_id_kind * pidk, { tree operand, ret; enum tree_code op; - location_t first_loc; + location_t start_loc = token->location; op = keyword == RID_ALIGNOF ? ALIGNOF_EXPR : SIZEOF_EXPR; /* Consume the token. */ cp_lexer_consume_token (parser->lexer); - first_loc = cp_lexer_peek_token (parser->lexer)->location; /* Parse the operand. */ operand = cp_parser_sizeof_operand (parser, keyword); @@ -7858,9 +7857,21 @@ cp_parser_unary_expression (cp_parser *parser, cp_id_kind * pidk, TREE_SIDE_EFFECTS (ret) = 0; TREE_READONLY (ret) = 1; } - SET_EXPR_LOCATION (ret, first_loc); } - return ret; + + /* Construct a location e.g. : + alignof (expr) + ^~~~~~~~~~~~~~ + with start == caret at the start of the "alignof"/"sizeof" + token, with the endpoint at the final closing paren. */ + location_t finish_loc + = cp_lexer_previous_token (parser->lexer)->location; + location_t compound_loc + = make_location (start_loc, start_loc, finish_loc); + + cp_expr ret_expr (ret); + ret_expr.set_location (compound_loc); + return ret_expr; } case RID_NEW: diff --git a/gcc/testsuite/g++.dg/plugin/diagnostic-test-expressions-1.C b/gcc/testsuite/g++.dg/plugin/diagnostic-test-expressions-1.C index 3554086..64eb660 100644 --- a/gcc/testsuite/g++.dg/plugin/diagnostic-test-expressions-1.C +++ b/gcc/testsuite/g++.dg/plugin/diagnostic-test-expressions-1.C @@ -101,6 +101,72 @@ int test_postfix_incdec (int i) /* Unary operators. ****************************************************/ +int test_sizeof (int i) +{ + __emit_expression_range (0, sizeof(int) + i); /* { dg-warning "range" } */ +/* { dg-begin-multiline-output "" } + __emit_expression_range (0, sizeof(int) + i); + ~~~~~~~~~~~~^~~ + { dg-end-multiline-output "" } */ + + __emit_expression_range (0, i + sizeof(int)); /* { dg-warning "range" } */ +/* { dg-begin-multiline-output "" } + __emit_expression_range (0, i + sizeof(int)); + ~~^~~~~~~~~~~~~ + { dg-end-multiline-output "" } */ + + __emit_expression_range (0, sizeof i + i); /* { dg-warning "range" } */ +/* { dg-begin-multiline-output "" } + __emit_expression_range (0, sizeof i + i); + ~~~~~~~~~^~~ + { dg-end-multiline-output "" } */ + + __emit_expression_range (0, i + sizeof i); /* { dg-warning "range" } */ +/* { dg-begin-multiline-output "" } + __emit_expression_range (0, i + sizeof i); + ~~^~~~~~~~~~ + { dg-end-multiline-output "" } */ +} + +int test_alignof (int i) +{ + __emit_expression_range (0, alignof(int) + i); /* { dg-warning "range" } */ +/* { dg-begin-multiline-output "" } + __emit_expression_range (0, alignof(int) + i); + ~~~~~~~~~~~~~^~~ + { dg-end-multiline-output "" } */ + + __emit_expression_range (0, i + alignof(int)); /* { dg-warning "range" } */ +/* { dg-begin-multiline-output "" } + __emit_expression_range (0, i + alignof(int)); + ~~^~~~~~~~~~~~~~ + { dg-end-multiline-output "" } */ + + __emit_expression_range (0, __alignof__(int) + i); /* { dg-warning "range" } */ +/* { dg-begin-multiline-output "" } + __emit_expression_range (0, __alignof__(int) + i); + ~~~~~~~~~~~~~~~~~^~~ + { dg-end-multiline-output "" } */ + + __emit_expression_range (0, i + __alignof__(int)); /* { dg-warning "range" } */ +/* { dg-begin-multiline-output "" } + __emit_expression_range (0, i + __alignof__(int)); + ~~^~~~~~~~~~~~~~~~~~ + { dg-end-multiline-output "" } */ + + __emit_expression_range (0, __alignof__ i + i); /* { dg-warning "range" } */ +/* { dg-begin-multiline-output "" } + __emit_expression_range (0, __alignof__ i + i); + ~~~~~~~~~~~~~~^~~ + { dg-end-multiline-output "" } */ + + __emit_expression_range (0, i + __alignof__ i); /* { dg-warning "range" } */ +/* { dg-begin-multiline-output "" } + __emit_expression_range (0, i + __alignof__ i); + ~~^~~~~~~~~~~~~~~ + { dg-end-multiline-output "" } */ +} + int test_prefix_incdec (int i) { __emit_expression_range (0, ++i ); /* { dg-warning "range" } */ -- 1.8.5.3