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&regrtested 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

Reply via email to