Fix location of sizeof/alignof (PR c++/80016)
authorDavid Malcolm <dmalcolm@redhat.com>
Mon, 24 Apr 2017 19:12:52 +0000 (19:12 +0000)
committerDavid Malcolm <dmalcolm@gcc.gnu.org>
Mon, 24 Apr 2017 19:12:52 +0000 (19:12 +0000)
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.

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.

From-SVN: r247108

gcc/cp/ChangeLog
gcc/cp/parser.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/plugin/diagnostic-test-expressions-1.C

index 317415ca43d3965351a52b23f481337526db41b1..97bf27ffc8f429ca931697e86015017319ee84f7 100644 (file)
@@ -1,3 +1,9 @@
+2017-04-24  David Malcolm  <dmalcolm@redhat.com>
+
+       PR c++/80016
+       * parser.c (cp_parser_unary_expression):  Generate a location
+       range for alignof and sizeof expressions.
+
 2017-04-24  Volker Reichelt  <v.reichelt@netcologne.de>
 
        * parser.c (cp_parser_cv_qualifier_seq_opt): Add fix-it info to
index 3efb28c727f3159a115e56b8a688045fe8bb9063..3a0e0cb050fcf37b1760f8f2c61e7df8aac7cac1 100644 (file)
@@ -7805,12 +7805,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);
 
@@ -7846,9 +7845,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:
index c8d79e3663a02dea97574a69b16c428b511560eb..a8381fa65415a352ef7586d94ac280706ef0ea6a 100644 (file)
@@ -1,3 +1,10 @@
+2017-04-24  David Malcolm  <dmalcolm@redhat.com>
+
+       PR c++/80016
+       * g++.dg/plugin/diagnostic-test-expressions-1.C (test_sizeof): New
+       test function.
+       (test_alignof): New test function.
+
 2017-04-24  Marc Glisse  <marc.glisse@inria.fr>
 
        * gcc.dg/tree-ssa/cmpexactdiv-2.c: New file.
index 4d3b07cbc5fe6f697c6f1cabf2330584191e2c8b..2c004f306206f763824d34050f73621cf5b612a8 100644 (file)
@@ -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" } */