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 | |
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')
-rw-r--r-- | gcc/cp/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/cp/parser.c | 77 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/parse/pr26997.C | 50 |
4 files changed, 130 insertions, 10 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 0293d49..5115c1b 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,11 @@ +2008-10-29 Manuel López-Ibáñez <manu@gcc.gnu.org> + + PR c++/26997 + * 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. + 2008-10-24 Manuel López-Ibáñez <manu@gcc.gnu.org> PR c/7543 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 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d6159e9..2a863f3 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2008-10-29 Manuel López-Ibáñez <manu@gcc.gnu.org> + + PR c++/26997 + * g++.dg/parse/pr26997.C: New. + 2008-10-29 Jakub Jelinek <jakub@redhat.com> PR middle-end/37913 diff --git a/gcc/testsuite/g++.dg/parse/pr26997.C b/gcc/testsuite/g++.dg/parse/pr26997.C new file mode 100644 index 0000000..acd1e07 --- /dev/null +++ b/gcc/testsuite/g++.dg/parse/pr26997.C @@ -0,0 +1,50 @@ +// PR c++/26997 +// { dg-do compile } +void * malloc (unsigned long size); +typedef struct { int a; } t; + +void foo() +{ + t *v3; + v3 = (t *) + malloc( + sizeof(t) + * + t->a // { dg-error "before '->' token" } + ); +} + +class C { +public: + void operator[](int); +}; + +C bar (void) +{ + (C ())(3); // { dg-error "invalid cast" } + return (C ()); +} + +extern void baz (C,C); + +void foo1 (void) +{ + baz ((C()), (C())); +} + +struct S { + void operator()(int); +}; + +int *var; +void foo2 (void) +{ + C ()[2]; + (C ())[2]; + (S ())(3); // { dg-error "invalid cast" } + (C())*var; // { dg-error "invalid cast" } + (C())+var; // { dg-error "invalid cast" } + S()(3); + (S()(3)); +} + |