aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/parser.c
diff options
context:
space:
mode:
authorManuel López-Ibáñez <manu@gcc.gnu.org>2008-10-29 16:05:27 +0000
committerManuel López-Ibáñez <manu@gcc.gnu.org>2008-10-29 16:05:27 +0000
commitd3f7b2c67ed130a856a1d7425e76d69d47bb6006 (patch)
tree9c49a5c382331cf9f1fdb138bf377d7c9a3eb901 /gcc/cp/parser.c
parente49cf927540b9eda4c905538d401fa0c27cd174a (diff)
downloadgcc-d3f7b2c67ed130a856a1d7425e76d69d47bb6006.zip
gcc-d3f7b2c67ed130a856a1d7425e76d69d47bb6006.tar.gz
gcc-d3f7b2c67ed130a856a1d7425e76d69d47bb6006.tar.bz2
re PR c++/26997 (g++ reports misleading error message when the identifier with error occurs earlier on the same line)
2008-10-29 Manuel López-Ibáñez <manu@gcc.gnu.org> PR c++/26997 cp/ * parser.c (cp_parser_token_starts_cast_expression): New. (cp_parser_cast_expression): Peek the next token to decide whether this could be a parenthesized constructor or is definitely an actual cast. testsuite/ * g++.dg/parse/pr26997.C: New. From-SVN: r141429
Diffstat (limited to 'gcc/cp/parser.c')
-rw-r--r--gcc/cp/parser.c77
1 files changed, 67 insertions, 10 deletions
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 7596048..40f2a3a 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -5910,6 +5910,60 @@ cp_parser_delete_expression (cp_parser* parser)
return delete_sanity (expression, NULL_TREE, array_p, global_scope_p);
}
+/* Returns true if TOKEN may start a cast-expression and false
+ otherwise. */
+
+static bool
+cp_parser_token_starts_cast_expression (cp_token *token)
+{
+ switch (token->type)
+ {
+ case CPP_COMMA:
+ case CPP_SEMICOLON:
+ case CPP_QUERY:
+ case CPP_COLON:
+ case CPP_CLOSE_SQUARE:
+ case CPP_CLOSE_PAREN:
+ case CPP_CLOSE_BRACE:
+ case CPP_DOT:
+ case CPP_DOT_STAR:
+ case CPP_DEREF:
+ case CPP_DEREF_STAR:
+ case CPP_DIV:
+ case CPP_MOD:
+ case CPP_LSHIFT:
+ case CPP_RSHIFT:
+ case CPP_LESS:
+ case CPP_GREATER:
+ case CPP_LESS_EQ:
+ case CPP_GREATER_EQ:
+ case CPP_EQ_EQ:
+ case CPP_NOT_EQ:
+ case CPP_EQ:
+ case CPP_MULT_EQ:
+ case CPP_DIV_EQ:
+ case CPP_MOD_EQ:
+ case CPP_PLUS_EQ:
+ case CPP_MINUS_EQ:
+ case CPP_RSHIFT_EQ:
+ case CPP_LSHIFT_EQ:
+ case CPP_AND_EQ:
+ case CPP_XOR_EQ:
+ case CPP_OR_EQ:
+ case CPP_XOR:
+ case CPP_OR:
+ case CPP_OR_OR:
+ return false;
+
+ /* '[' may start a primary-expression in obj-c++. */
+ case CPP_OPEN_SQUARE:
+ return c_dialect_objc ();
+
+ default:
+ return true;
+ }
+}
+
/* Parse a cast-expression.
cast-expression:
@@ -5988,17 +6042,18 @@ cp_parser_cast_expression (cp_parser *parser, bool address_p, bool cast_p)
/* Restore the saved message. */
parser->type_definition_forbidden_message = saved_message;
- /* If ok so far, parse the dependent expression. We cannot be
- sure it is a cast. Consider `(T ())'. It is a parenthesized
- ctor of T, but looks like a cast to function returning T
- without a dependent expression. */
- if (!cp_parser_error_occurred (parser))
- expr = cp_parser_cast_expression (parser,
- /*address_p=*/false,
- /*cast_p=*/true);
-
- if (cp_parser_parse_definitely (parser))
+ /* At this point this can only be either a cast or a
+ parenthesized ctor such as `(T ())' that looks like a cast to
+ function returning T. */
+ if (!cp_parser_error_occurred (parser)
+ && cp_parser_token_starts_cast_expression (cp_lexer_peek_token
+ (parser->lexer)))
{
+ cp_parser_parse_definitely (parser);
+ expr = cp_parser_cast_expression (parser,
+ /*address_p=*/false,
+ /*cast_p=*/true);
+
/* Warn about old-style casts, if so requested. */
if (warn_old_style_cast
&& !in_system_header
@@ -6019,6 +6074,8 @@ cp_parser_cast_expression (cp_parser *parser, bool address_p, bool cast_p)
expr = build_c_cast (type, expr);
return expr;
}
+ else
+ cp_parser_abort_tentative_parse (parser);
}
/* If we get here, then it's not a cast, so it must be a