aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorDavid Malcolm <dmalcolm@redhat.com>2017-06-30 15:20:55 +0000
committerDavid Malcolm <dmalcolm@gcc.gnu.org>2017-06-30 15:20:55 +0000
commite59e8b5a1c86c6e901201e1d0fdcf53e2c453637 (patch)
tree6c3e05190bdb092ce15fa48cc6a65a8f933716e5 /gcc
parente855bdc04db3b2ff010d6d490dc9a4bee5f08b3b (diff)
downloadgcc-e59e8b5a1c86c6e901201e1d0fdcf53e2c453637.zip
gcc-e59e8b5a1c86c6e901201e1d0fdcf53e2c453637.tar.gz
gcc-e59e8b5a1c86c6e901201e1d0fdcf53e2c453637.tar.bz2
Fix location of typeid() (PR c++/80014)
gcc/cp/ChangeLog: PR c++/80014 * parser.c (cp_parser_postfix_expression): Construct a location for typeid expressions. gcc/testsuite/ChangeLog: PR c++/80014 * g++.dg/plugin/diagnostic-test-expressions-1.C (std::type_info): Add declaration. (test_typeid): New test function. From-SVN: r249845
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/parser.c18
-rw-r--r--gcc/testsuite/ChangeLog7
-rw-r--r--gcc/testsuite/g++.dg/plugin/diagnostic-test-expressions-1.C32
4 files changed, 61 insertions, 2 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 4260bbf..6c230a9 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,9 @@
+2017-06-30 David Malcolm <dmalcolm@redhat.com>
+
+ PR c++/80014
+ * parser.c (cp_parser_postfix_expression): Construct a location
+ for typeid expressions.
+
2017-06-30 Nathan Sidwell <nathan@acm.org>
* cp-tree.h (lookup_fnfields_1, class_method_index_for_fn): Don't
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 375cd0a..c6a8e37 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -6542,7 +6542,8 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
/* Look for the `)' token. Otherwise, we can't be sure that
we're not looking at an expression: consider `typeid (int
(3))', for example. */
- cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
+ cp_token *close_paren = cp_parser_require (parser, CPP_CLOSE_PAREN,
+ RT_CLOSE_PAREN);
/* If all went well, simply lookup the type-id. */
if (cp_parser_parse_definitely (parser))
postfix_expression = get_typeid (type, tf_warning_or_error);
@@ -6556,13 +6557,26 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
/* Compute its typeid. */
postfix_expression = build_typeid (expression, tf_warning_or_error);
/* Look for the `)' token. */
- cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
+ close_paren
+ = cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
}
/* Restore the saved message. */
parser->type_definition_forbidden_message = saved_message;
/* `typeid' may not appear in an integral constant expression. */
if (cp_parser_non_integral_constant_expression (parser, NIC_TYPEID))
postfix_expression = error_mark_node;
+
+ /* Construct a location e.g. :
+ typeid (expr)
+ ^~~~~~~~~~~~~
+ ranging from the start of the "typeid" token to the final closing
+ paren, with the caret at the start. */
+ if (close_paren)
+ {
+ location_t typeid_loc
+ = make_location (start_loc, start_loc, close_paren->location);
+ postfix_expression.set_location (typeid_loc);
+ }
}
break;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index f42ea73..f0555b9 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,10 @@
+2017-06-30 David Malcolm <dmalcolm@redhat.com>
+
+ PR c++/80014
+ * g++.dg/plugin/diagnostic-test-expressions-1.C (std::type_info):
+ Add declaration.
+ (test_typeid): New test function.
+
2017-06-30 Jakub Jelinek <jakub@redhat.com>
PR target/81225
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 2c004f3..62d3c36 100644
--- a/gcc/testsuite/g++.dg/plugin/diagnostic-test-expressions-1.C
+++ b/gcc/testsuite/g++.dg/plugin/diagnostic-test-expressions-1.C
@@ -848,3 +848,35 @@ tests::test_method_calls ()
~~~~~~~~~~~~~~~~~~^~
{ dg-end-multiline-output "" } */
}
+
+namespace std
+{
+ class type_info { public: int foo; };
+}
+
+void test_typeid (int i)
+{
+ __emit_expression_range (0, &typeid(i)); /* { dg-warning "range" } */
+/* { dg-begin-multiline-output "" }
+ __emit_expression_range (0, &typeid(i));
+ ^~~~~~~~~~
+ { dg-end-multiline-output "" } */
+
+ __emit_expression_range (0, &typeid(int)); /* { dg-warning "range" } */
+/* { dg-begin-multiline-output "" }
+ __emit_expression_range (0, &typeid(int));
+ ^~~~~~~~~~~~
+ { dg-end-multiline-output "" } */
+
+ __emit_expression_range (0, &typeid(i * 2)); /* { dg-warning "range" } */
+/* { dg-begin-multiline-output "" }
+ __emit_expression_range (0, &typeid(i * 2));
+ ^~~~~~~~~~~~~~
+ { dg-end-multiline-output "" } */
+
+ __emit_expression_range (0, typeid(int).foo); /* { dg-warning "range" } */
+/* { dg-begin-multiline-output "" }
+ __emit_expression_range (0, typeid(int).foo);
+ ~~~~~~~~~~~~^~~
+ { dg-end-multiline-output "" } */
+}