aboutsummaryrefslogtreecommitdiff
path: root/gcc
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
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')
-rw-r--r--gcc/cp/ChangeLog8
-rw-r--r--gcc/cp/parser.c77
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/parse/pr26997.C50
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));
+}
+