From: nicola Date: Tue, 5 Oct 2010 19:23:33 +0000 (+0000) Subject: In gcc/: X-Git-Tag: upstream/4.9.2~26118 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=06517bd4d841ffa7c8ebb91aeb4dfe1ddc9eba60;p=platform%2Fupstream%2Flinaro-gcc.git In gcc/: 2010-10-05 Nicola Pero * c-parser.c (c_parser_objc_method_definition): Updated comment. In gcc/cp/: 2010-10-05 Nicola Pero 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 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 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 Merge from apple/trunk branch on FSF servers: 2005-10-17 Fariborz Jahanian 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 Radar 4294425 * parser.c (cp_parser_objc_message_args): Check for missing message arguments and syntax error. 2005-10-13 Fariborz Jahanian Radar 4261146 * parser.c (cp_parser_objc_class_ivars): Check for @end/eof while looking for '}'. 2005-08-15 Ziemowit Laski Radar 4093475 * parser.c (cp_parser_objc_interstitial_code): Catch stray '{' and '}' tokens and issue appropriate errors. 2005-08-02 Ziemowit Laski 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'. In gcc/objc/: 2010-10-05 Nicola Pero Merge from 'apple/trunk' branch on FSF servers. 2005-10-17 Fariborz Jahanian Radar 4290840 * objc-act.c (objc_start_method_definition): Check for error_mark_node for the selector name and make a quick exit. In gcc/testsuite/: 2010-10-05 Nicola Pero PR objc++/28050 * obj-c++.dg/syntax-error-10.mm: New. 2010-10-05 Nicola Pero PR objc++/23707 * obj-c++.dg/syntax-error-9.mm: New. 2010-10-05 Nicola Pero PR objc++/31126 * obj-c++.dg/syntax-error-8.mm: New. 2010-10-05 Nicola Pero Merge from 'apple/trunk' branch on FSF servers. 2005-10-17 Fariborz Jahanian Radar 4290840 * obj-c++.dg/syntax-error-7.mm: New 2005-10-14 Fariborz Jahanian Radar 4294425 * obj-c++.dg/syntax-error-6.mm: New 2005-10-13 Fariborz Jahanian Radar 4261146 * obj-c++.dg/syntax-error-5.mm: New 2005-08-15 Ziemowit Laski Radar 4093475 * obj-c++.dg/syntax-error-[3-4].mm: New. 2005-08-02 Ziemowit Laski Radar 4185810 * obj-c++.dg/syntax-error-[1-2].mm: New. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@164997 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index de2ab3b..5031176 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,7 @@ +2010-10-05 Nicola Pero + + * c-parser.c (c_parser_objc_method_definition): Updated comment. + 2010-10-05 Jan Hubicka * doc/invoke.texi (-flto-partition, lto-partitions, lto-minpartition): @@ -1768,7 +1772,6 @@ unconditionally if TODO_rebuild_alias is set, else only when optimizing if TODO_update_address_taken is set. ->>>>>>> .r164755 2010-09-23 Anatoly Sokolov * config/arm/arm.h (OUTPUT_ADDR_CONST_EXTRA): Remove. diff --git a/gcc/c-parser.c b/gcc/c-parser.c index dc5ea8d..5b38a48 100644 --- a/gcc/c-parser.c +++ b/gcc/c-parser.c @@ -6729,8 +6729,9 @@ c_parser_objc_method_definition (c_parser *parser) else { /* This code is executed when we find a method definition - outside of an @implementation context. Parse the method (to - keep going) but do not emit any code. + outside of an @implementation context (or invalid for other + reasons). Parse the method (to keep going) but do not emit + any code. */ c_parser_compound_statement (parser); } diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 7f77a7b..e347e6d 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,68 @@ +2010-10-05 Nicola Pero + + 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 + + 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 + + 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 + + Merge from apple/trunk branch on FSF servers: + + 2005-10-17 Fariborz Jahanian + + 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 + + Radar 4294425 + * parser.c (cp_parser_objc_message_args): Check for missing message + arguments and syntax error. + + 2005-10-13 Fariborz Jahanian + + Radar 4261146 + * parser.c (cp_parser_objc_class_ivars): Check for @end/eof while + looking for '}'. + + 2005-08-15 Ziemowit Laski + + Radar 4093475 + * parser.c (cp_parser_objc_interstitial_code): Catch stray + '{' and '}' tokens and issue appropriate errors. + + 2005-08-02 Ziemowit Laski + + 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 * cp-tree.h (cxx_print_error_function, 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. */ diff --git a/gcc/objc/ChangeLog b/gcc/objc/ChangeLog index 135d503..a68b46d71 100644 --- a/gcc/objc/ChangeLog +++ b/gcc/objc/ChangeLog @@ -1,3 +1,13 @@ +2010-10-05 Nicola Pero + + Merge from 'apple/trunk' branch on FSF servers. + + 2005-10-17 Fariborz Jahanian + + Radar 4290840 + * objc-act.c (objc_start_method_definition): Check for error_mark_node for + the selector name and make a quick exit. + 2010-10-04 Andi Kleen * Make-lang.in (cc1obj-dummy, cc1obj): Add + to build rule. diff --git a/gcc/objc/objc-act.c b/gcc/objc/objc-act.c index dffdb71..5aaadc67 100644 --- a/gcc/objc/objc-act.c +++ b/gcc/objc/objc-act.c @@ -821,6 +821,9 @@ objc_start_method_definition (tree decl, tree attributes) return false; } + if (decl != NULL_TREE && METHOD_SEL_NAME (decl) == error_mark_node) + return false; + if (attributes) warning_at (input_location, OPT_Wattributes, "method attributes are not available in this version" diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index b94bb69..b70a6b2 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,47 @@ +2010-10-05 Nicola Pero + + PR objc++/28050 + * obj-c++.dg/syntax-error-10.mm: New. + +2010-10-05 Nicola Pero + + PR objc++/23707 + * obj-c++.dg/syntax-error-9.mm: New. + +2010-10-05 Nicola Pero + + PR objc++/31126 + * obj-c++.dg/syntax-error-8.mm: New. + +2010-10-05 Nicola Pero + + Merge from 'apple/trunk' branch on FSF servers. + + 2005-10-17 Fariborz Jahanian + + Radar 4290840 + * obj-c++.dg/syntax-error-7.mm: New + + 2005-10-14 Fariborz Jahanian + + Radar 4294425 + * obj-c++.dg/syntax-error-6.mm: New + + 2005-10-13 Fariborz Jahanian + + Radar 4261146 + * obj-c++.dg/syntax-error-5.mm: New + + 2005-08-15 Ziemowit Laski + + Radar 4093475 + * obj-c++.dg/syntax-error-[3-4].mm: New. + + 2005-08-02 Ziemowit Laski + + Radar 4185810 + * obj-c++.dg/syntax-error-[1-2].mm: New. + 2010-10-05 Ira Rosen PR tree-optimization/45752 diff --git a/gcc/testsuite/obj-c++.dg/syntax-error-1.mm b/gcc/testsuite/obj-c++.dg/syntax-error-1.mm new file mode 100644 index 0000000..13f3c27 --- /dev/null +++ b/gcc/testsuite/obj-c++.dg/syntax-error-1.mm @@ -0,0 +1,26 @@ +/* Graceful handling of a syntax error. */ +/* { dg-do compile } */ + +#include + +class foo { + public: + foo(); + virtual ~foo(); +}; + + +extern void NXLog(const char *, ...); + +@interface Test2 : Object { +} +- (void) foo2; +@end + +@implementation Test2 +- (void) foo2 + NXLog("Hello, world!"); /* { dg-error "expected .\{. before .NXLog." } */ +} /* { dg-error "stray .\}. between Objective\\-C\\+\\+ methods" } */ +@end + +/* { dg-error "expected constructor, destructor, or type conversion before" "" { target *-*-* } 22 } */ diff --git a/gcc/testsuite/obj-c++.dg/syntax-error-10.mm b/gcc/testsuite/obj-c++.dg/syntax-error-10.mm new file mode 100644 index 0000000..e45abcc --- /dev/null +++ b/gcc/testsuite/obj-c++.dg/syntax-error-10.mm @@ -0,0 +1 @@ +@interface /* { dg-error "expected identifier" } */ diff --git a/gcc/testsuite/obj-c++.dg/syntax-error-2.mm b/gcc/testsuite/obj-c++.dg/syntax-error-2.mm new file mode 100644 index 0000000..ba8804a --- /dev/null +++ b/gcc/testsuite/obj-c++.dg/syntax-error-2.mm @@ -0,0 +1,16 @@ +/* Recover gracefully from a syntax error. */ + +@implementation Whatever /* { dg-warning "cannot find interface declaration for .Whatever." } */ + +- (void) function +{ + if( 1 ) + { + else /* { dg-error "expected .\}. before .else." } */ + { + } +} + +- (void) another {} + +@end diff --git a/gcc/testsuite/obj-c++.dg/syntax-error-3.mm b/gcc/testsuite/obj-c++.dg/syntax-error-3.mm new file mode 100644 index 0000000..34f914b --- /dev/null +++ b/gcc/testsuite/obj-c++.dg/syntax-error-3.mm @@ -0,0 +1,10 @@ +/* Yet another stray infinite loop... */ +/* { dg-do compile } */ + +@interface Foo +{ + int x; + int y; +} +- (int) foo ; { /* { dg-error "stray .\{. between Objective\\-C\\+\\+ methods" } */ +@end diff --git a/gcc/testsuite/obj-c++.dg/syntax-error-4.mm b/gcc/testsuite/obj-c++.dg/syntax-error-4.mm new file mode 100644 index 0000000..0df0618 --- /dev/null +++ b/gcc/testsuite/obj-c++.dg/syntax-error-4.mm @@ -0,0 +1,15 @@ +/* Yet another stray infinite loop... */ +/* { dg-do compile } */ + +@interface t +{ +} +- (void)go; +@end +@implementation t +- (void)go +{ + } +} /* { dg-error "stray .\}. between Objective\\-C\\+\\+ methods" } */ +@end + diff --git a/gcc/testsuite/obj-c++.dg/syntax-error-5.mm b/gcc/testsuite/obj-c++.dg/syntax-error-5.mm new file mode 100644 index 0000000..f0d0605 --- /dev/null +++ b/gcc/testsuite/obj-c++.dg/syntax-error-5.mm @@ -0,0 +1,13 @@ +/* { dg-do compile } */ + +typedef struct S { int i; } NSDictionary; + +@interface A +{ +} +@end + +@interface B : A +{ + NSDictionary * _userInfo; +@end /* { dg-error "expected .\}. before .end." } */ diff --git a/gcc/testsuite/obj-c++.dg/syntax-error-6.mm b/gcc/testsuite/obj-c++.dg/syntax-error-6.mm new file mode 100644 index 0000000..21423ec --- /dev/null +++ b/gcc/testsuite/obj-c++.dg/syntax-error-6.mm @@ -0,0 +1,12 @@ +/* { dg-do compile } */ + +@interface NSButton +- (int) state; +@end + +void FOO() +{ + NSButton * mCopyAcrobatCB; + + [ [ mCopyAcrobatCB state ] == 0 ] != 1; /* { dg-error "objective\\-c\\+\\+" } */ +} diff --git a/gcc/testsuite/obj-c++.dg/syntax-error-7.mm b/gcc/testsuite/obj-c++.dg/syntax-error-7.mm new file mode 100644 index 0000000..eef5bc7 --- /dev/null +++ b/gcc/testsuite/obj-c++.dg/syntax-error-7.mm @@ -0,0 +1,13 @@ +/* { dg-do compile } */ + +@interface Foo +-(void) someMethod; +@end + +@implementation Foo +-(void) +-(void) someMethod /* { dg-error "expected before .-." } */ +{ +} +@end /* { dg-error "incomplete implementation of class" } */ +/* { dg-error "method definition for ..someMethod. not found" "" { target *-*-* } 12 } */ diff --git a/gcc/testsuite/obj-c++.dg/syntax-error-8.mm b/gcc/testsuite/obj-c++.dg/syntax-error-8.mm new file mode 100644 index 0000000..731ffda --- /dev/null +++ b/gcc/testsuite/obj-c++.dg/syntax-error-8.mm @@ -0,0 +1 @@ +@interface A /* { dg-error "expected ..end." } */ \ No newline at end of file diff --git a/gcc/testsuite/obj-c++.dg/syntax-error-9.mm b/gcc/testsuite/obj-c++.dg/syntax-error-9.mm new file mode 100644 index 0000000..97706d5 --- /dev/null +++ b/gcc/testsuite/obj-c++.dg/syntax-error-9.mm @@ -0,0 +1,3 @@ +@implementation SaturnDoc /* { dg-warning "cannot find interface declaration" } */ +- read: (void*)aStream ggg /* { dg-error "expected .:. at end of input" } */ +/* { dg-error "expected ..end. at end of input" "" { target *-*-* } 2 } */ \ No newline at end of file