+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
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:
/* 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
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
--- /dev/null
+// 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));
+}
+