From d3f7b2c67ed130a856a1d7425e76d69d47bb6006 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20L=C3=B3pez-Ib=C3=A1=C3=B1ez?= Date: Wed, 29 Oct 2008 16:05:27 +0000 Subject: re PR c++/26997 (g++ reports misleading error message when the identifier with error occurs earlier on the same line) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 2008-10-29 Manuel López-Ibáñez 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 --- gcc/cp/parser.c | 77 +++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 67 insertions(+), 10 deletions(-) (limited to 'gcc/cp/parser.c') 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 -- cgit v1.1