+2010-10-05 Nicola Pero <nicola.pero@meta-innovation.com>
+
+ PR objc++/31125
+ * parser.c (cp_parser_objc_class_interface): If no identifier
+ follows an @interface token, stop parsing the interface after
+ printing an error.
+ (cp_parser_objc_class_implementation): If no identifier follows an
+ @implementation token, stop parsing the implementation after
+ printing an error.
+
+2010-10-05 Nicola Pero <nicola.pero@meta-innovation.com>
+
+ PR objc++/23707
+ * parser.c (cp_parser_objc_method_keyword_params): If the required
+ colon is not found while parsing parameters, stop parsing them.
+
+2010-10-05 Nicola Pero <nicola.pero@meta-innovation.com>
+
+ PR objc++/31126
+ * parser.c (cp_parser_objc_class_ivars): Do not eat the EOF or
+ @end after detecting it. Print an error if @end is found without
+ a '}'.
+ (cp_parser_objc_method_prototype_list): Do not eat the EOF after
+ detecting it. Fixed reading the next token when continuing
+ because of an error in a method signature. Print an error if EOF
+ is found without an '@end'.
+ (cp_parser_objc_method_definition_list): Same change.
+
+2010-10-05 Nicola Pero <nicola.pero@meta-innovation.com>
+
+ Merge from apple/trunk branch on FSF servers:
+
+ 2005-10-17 Fariborz Jahanian <fjahanian@apple.com>
+
+ Radar 4290840
+ * parser.c (cp_parser_objc_method_keyword_params): Check for valid
+ method parameters and issue error.
+ (cp_parser_objc_method_definition_list): Check for invalid tokens
+ which cannot start a function definition.
+
+ 2005-10-14 Fariborz Jahanian <fjahanian@apple.com>
+
+ Radar 4294425
+ * parser.c (cp_parser_objc_message_args): Check for missing message
+ arguments and syntax error.
+
+ 2005-10-13 Fariborz Jahanian <fjahanian@apple.com>
+
+ Radar 4261146
+ * parser.c (cp_parser_objc_class_ivars): Check for @end/eof while
+ looking for '}'.
+
+ 2005-08-15 Ziemowit Laski <zlaski@apple.com>
+
+ Radar 4093475
+ * parser.c (cp_parser_objc_interstitial_code): Catch stray
+ '{' and '}' tokens and issue appropriate errors.
+
+ 2005-08-02 Ziemowit Laski <zlaski@apple.com>
+
+ Radar 4185810
+ (cp_parser_statement_seq_opt): In addition to '}' and
+ end-of-file, a statement sequence may also be terminated
+ by a stray '@end'.
+
2010-10-05 Joseph Myers <joseph@codesourcery.com>
* cp-tree.h (cxx_print_error_function,
{
cp_token *token = cp_lexer_peek_token (parser->lexer);
- /* If we're looking at a `}', then we've run out of statements. */
+ /* If we are looking at a `}', then we have run out of
+ statements; the same is true if we have reached the end
+ of file, or have stumbled upon a stray '@end'. */
if (token->type == CPP_CLOSE_BRACE
|| token->type == CPP_EOF
- || token->type == CPP_PRAGMA_EOL)
+ || token->type == CPP_PRAGMA_EOL
+ || (token->type == CPP_KEYWORD && token->keyword == RID_AT_END))
break;
/* If we are in a compound statement and find 'else' then
token = cp_lexer_peek_token (parser->lexer);
}
+ if (sel_args == NULL_TREE && addl_args == NULL_TREE)
+ {
+ cp_parser_error (parser, "objective-c++ message argument(s) are expected");
+ return build_tree_list (error_mark_node, error_mark_node);
+ }
+
return build_tree_list (sel_args, addl_args);
}
}
maybe_unary_selector_p = false;
- cp_parser_require (parser, CPP_COLON, RT_COLON);
+ if (!cp_parser_require (parser, CPP_COLON, RT_COLON))
+ {
+ /* Something went quite wrong. There should be a colon
+ here, but there is not. Stop parsing parameters. */
+ break;
+ }
type_name = cp_parser_objc_typename (parser);
/* New ObjC allows attributes on parameters too. */
if (cp_lexer_next_token_is_keyword (parser->lexer, RID_ATTRIBUTE))
return error_mark_node;
}
+ if (params == NULL_TREE)
+ {
+ cp_parser_error (parser, "objective-c++ method declaration is expected");
+ return error_mark_node;
+ }
return params;
}
cp_lexer_consume_token (parser->lexer);
objc_set_method_opt (false);
}
+ /* Other stray characters must generate errors. */
+ else if (token->type == CPP_OPEN_BRACE || token->type == CPP_CLOSE_BRACE)
+ {
+ cp_lexer_consume_token (parser->lexer);
+ error ("stray `%s' between Objective-C++ methods",
+ token->type == CPP_OPEN_BRACE ? "{" : "}");
+ }
/* Finally, try to parse a block-declaration, or a function-definition. */
else
cp_parser_block_declaration (parser, /*statement_p=*/false);
if (sig == error_mark_node)
{
cp_parser_skip_to_end_of_block_or_statement (parser);
+ token = cp_lexer_peek_token (parser->lexer);
continue;
}
objc_add_method_declaration (sig, attributes);
token = cp_lexer_peek_token (parser->lexer);
}
- cp_lexer_consume_token (parser->lexer); /* Eat '@end'. */
+ if (token->type != CPP_EOF)
+ cp_lexer_consume_token (parser->lexer); /* Eat '@end'. */
+ else
+ cp_parser_error (parser, "expected %<@end%>");
+
objc_finish_interface ();
}
if (sig == error_mark_node)
{
cp_parser_skip_to_end_of_block_or_statement (parser);
+ token = cp_lexer_peek_token (parser->lexer);
continue;
}
objc_start_method_definition (sig, attribute);
perform_deferred_access_checks ();
stop_deferring_access_checks ();
meth = cp_parser_function_definition_after_declarator (parser,
- false);
+ false);
pop_deferring_access_checks ();
objc_finish_method_definition (meth);
}
token = cp_lexer_peek_token (parser->lexer);
}
- cp_lexer_consume_token (parser->lexer); /* Eat '@end'. */
+ if (token->type != CPP_EOF)
+ cp_lexer_consume_token (parser->lexer); /* Eat '@end'. */
+ else
+ cp_parser_error (parser, "expected %<@end%>");
+
objc_finish_implementation ();
}
cp_lexer_consume_token (parser->lexer); /* Eat '{'. */
token = cp_lexer_peek_token (parser->lexer);
- while (token->type != CPP_CLOSE_BRACE)
+ while (token->type != CPP_CLOSE_BRACE
+ && token->keyword != RID_AT_END && token->type != CPP_EOF)
{
cp_decl_specifier_seq declspecs;
int decl_class_or_enum_p;
token = cp_lexer_peek_token (parser->lexer);
}
- cp_lexer_consume_token (parser->lexer); /* Eat '}'. */
+ if (token->keyword == RID_AT_END)
+ cp_parser_error (parser, "expected %<}%>");
+
+ /* Do not consume the RID_AT_END, so it will be read again as terminating
+ the @interface of @implementation. */
+ if (token->keyword != RID_AT_END && token->type != CPP_EOF)
+ cp_lexer_consume_token (parser->lexer); /* Eat '}'. */
+
/* For historical reasons, we accept an optional semicolon. */
if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
cp_lexer_consume_token (parser->lexer);
cp_lexer_consume_token (parser->lexer); /* Eat '@interface'. */
name = cp_parser_identifier (parser);
+ if (name == error_mark_node)
+ {
+ /* It's hard to recover because even if valid @interface stuff
+ is to follow, we can't compile it (or validate it) if we
+ don't even know which class it refers to. Let's assume this
+ was a stray '@interface' token in the stream and skip it.
+ */
+ return;
+ }
cp_parser_objc_superclass_or_category (parser, &super, &categ);
protos = cp_parser_objc_protocol_refs_opt (parser);
cp_lexer_consume_token (parser->lexer); /* Eat '@implementation'. */
name = cp_parser_identifier (parser);
+ if (name == error_mark_node)
+ {
+ /* It's hard to recover because even if valid @implementation
+ stuff is to follow, we can't compile it (or validate it) if
+ we don't even know which class it refers to. Let's assume
+ this was a stray '@implementation' token in the stream and
+ skip it.
+ */
+ return;
+ }
cp_parser_objc_superclass_or_category (parser, &super, &categ);
/* We have either a class or a category on our hands. */