diff options
author | Manuel López-Ibáñez <manu@gcc.gnu.org> | 2008-10-29 16:05:27 +0000 |
---|---|---|
committer | Manuel López-Ibáñez <manu@gcc.gnu.org> | 2008-10-29 16:05:27 +0000 |
commit | d3f7b2c67ed130a856a1d7425e76d69d47bb6006 (patch) | |
tree | 9c49a5c382331cf9f1fdb138bf377d7c9a3eb901 /gcc/cp/parser.c | |
parent | e49cf927540b9eda4c905538d401fa0c27cd174a (diff) | |
download | gcc-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.c | 77 |
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 |