diff options
Diffstat (limited to 'gcc/cp/parser.c')
-rw-r--r-- | gcc/cp/parser.c | 79 |
1 files changed, 71 insertions, 8 deletions
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 82026b1..c481ae3 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -8294,10 +8294,13 @@ cp_parser_statement_seq_opt (cp_parser* parser, tree in_statement_expr) { 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 @@ -21090,6 +21093,12 @@ cp_parser_objc_message_args (cp_parser* parser) 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); } @@ -21482,7 +21491,12 @@ cp_parser_objc_method_keyword_params (cp_parser* parser, tree* attributes) } 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)) @@ -21517,6 +21531,11 @@ cp_parser_objc_method_keyword_params (cp_parser* parser, tree* attributes) return error_mark_node; } + if (params == NULL_TREE) + { + cp_parser_error (parser, "objective-c++ method declaration is expected"); + return error_mark_node; + } return params; } @@ -21608,6 +21627,13 @@ cp_parser_objc_interstitial_code (cp_parser* parser) 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); @@ -21670,6 +21696,7 @@ cp_parser_objc_method_prototype_list (cp_parser* parser) 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); @@ -21687,7 +21714,11 @@ cp_parser_objc_method_prototype_list (cp_parser* parser) 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 (); } @@ -21711,6 +21742,7 @@ cp_parser_objc_method_definition_list (cp_parser* parser) 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); @@ -21726,7 +21758,7 @@ cp_parser_objc_method_definition_list (cp_parser* parser) 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); } @@ -21742,7 +21774,11 @@ cp_parser_objc_method_definition_list (cp_parser* parser) 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 (); } @@ -21759,7 +21795,8 @@ cp_parser_objc_class_ivars (cp_parser* parser) 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; @@ -21858,7 +21895,14 @@ cp_parser_objc_class_ivars (cp_parser* parser) 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); @@ -21932,6 +21976,15 @@ cp_parser_objc_class_interface (cp_parser* parser, tree attributes) 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); @@ -21958,6 +22011,16 @@ cp_parser_objc_class_implementation (cp_parser* 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. */ |