From patchwork Tue Oct 5 16:01:44 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicola Pero X-Patchwork-Id: 66840 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id DE529B70E6 for ; Wed, 6 Oct 2010 03:02:06 +1100 (EST) Received: (qmail 20143 invoked by alias); 5 Oct 2010 16:02:05 -0000 Received: (qmail 20106 invoked by uid 22791); 5 Oct 2010 16:02:01 -0000 X-SWARE-Spam-Status: No, hits=-1.2 required=5.0 tests=AWL, BAYES_00, TW_BJ, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from fencepost.gnu.org (HELO fencepost.gnu.org) (140.186.70.10) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Tue, 05 Oct 2010 16:01:54 +0000 Received: from eggs.gnu.org ([140.186.70.92]:44549) by fencepost.gnu.org with esmtps (TLS-1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.69) (envelope-from ) id 1P39xg-0000yb-FU for gcc-patches@gnu.org; Tue, 05 Oct 2010 12:01:52 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1P39xZ-0008Bc-OP for gcc-patches@gnu.org; Tue, 05 Oct 2010 12:01:52 -0400 Received: from smtp131.iad.emailsrvr.com ([207.97.245.131]:59153) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1P39xZ-0008BS-Kr for gcc-patches@gnu.org; Tue, 05 Oct 2010 12:01:45 -0400 Received: from localhost (localhost.localdomain [127.0.0.1]) by smtp43.relay.iad1a.emailsrvr.com (SMTP Server) with ESMTP id EE8F22D036A for ; Tue, 5 Oct 2010 12:01:44 -0400 (EDT) Received: from dynamic8.wm-web.iad.mlsrvr.com (dynamic8.wm-web.iad1a.rsapps.net [192.168.2.149]) by smtp43.relay.iad1a.emailsrvr.com (SMTP Server) with ESMTP id D78D62D033E for ; Tue, 5 Oct 2010 12:01:44 -0400 (EDT) Received: from meta-innovation.com (localhost [127.0.0.1]) by dynamic8.wm-web.iad.mlsrvr.com (Postfix) with ESMTP id C650D305006C for ; Tue, 5 Oct 2010 12:01:44 -0400 (EDT) Received: by www2.webmail.us (Authenticated sender: nicola.pero@meta-innovation.com, from: nicola.pero@meta-innovation.com) with HTTP; Tue, 5 Oct 2010 18:01:44 +0200 (CEST) Date: Tue, 5 Oct 2010 18:01:44 +0200 (CEST) Subject: ObjC++ bugfixes From: "Nicola Pero" To: "gcc-patches@gnu.org" MIME-Version: 1.0 X-Type: plain Message-ID: <1286294504.810816345@192.168.2.231> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 3) X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org This patch includes a bunch of ObjC++ bugfixes I merged from the apple/trunk branch, plus some changes and bugfixes I had to do on top of these to get all the testcases to work on the new codebase (and fix PR objc++/31126, which is closely related). Ok to apply ? Thanks In gcc/: 2010-10-05 Nicola Pero * c-parser.c (c_parser_objc_method_definition): Updated comment. 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/cp/: 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/testsuite/: 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. Index: objc/objc-act.c =================================================================== --- objc/objc-act.c (revision 164989) +++ objc/objc-act.c (working copy) @@ -821,6 +821,9 @@ objc_start_method_definition (tree decl, tree attr 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" Index: objc/ChangeLog =================================================================== --- objc/ChangeLog (revision 164989) +++ objc/ChangeLog (working copy) @@ -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. Index: ChangeLog =================================================================== --- ChangeLog (revision 164989) +++ ChangeLog (working copy) @@ -1,3 +1,7 @@ +2010-10-05 Nicola Pero + + * c-parser.c (c_parser_objc_method_definition): Updated comment. + 2010-10-05 Olivier Hainque Nicolas Roche Index: testsuite/ChangeLog =================================================================== --- testsuite/ChangeLog (revision 164989) +++ testsuite/ChangeLog (working copy) @@ -1,3 +1,37 @@ +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 Index: testsuite/obj-c++.dg/syntax-error-4.mm =================================================================== --- testsuite/obj-c++.dg/syntax-error-4.mm (revision 0) +++ testsuite/obj-c++.dg/syntax-error-4.mm (revision 0) @@ -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 + Index: testsuite/obj-c++.dg/syntax-error-7.mm =================================================================== --- testsuite/obj-c++.dg/syntax-error-7.mm (revision 0) +++ testsuite/obj-c++.dg/syntax-error-7.mm (revision 0) @@ -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 } */ Index: testsuite/obj-c++.dg/syntax-error-2.mm =================================================================== --- testsuite/obj-c++.dg/syntax-error-2.mm (revision 0) +++ testsuite/obj-c++.dg/syntax-error-2.mm (revision 0) @@ -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 Index: testsuite/obj-c++.dg/syntax-error-5.mm =================================================================== --- testsuite/obj-c++.dg/syntax-error-5.mm (revision 0) +++ testsuite/obj-c++.dg/syntax-error-5.mm (revision 0) @@ -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." } */ Index: testsuite/obj-c++.dg/syntax-error-8.mm =================================================================== --- testsuite/obj-c++.dg/syntax-error-8.mm (revision 0) +++ testsuite/obj-c++.dg/syntax-error-8.mm (revision 0) @@ -0,0 +1 @@ +@interface A /* { dg-error "expected ..end." } */ \ No newline at end of file Index: testsuite/obj-c++.dg/syntax-error-3.mm =================================================================== --- testsuite/obj-c++.dg/syntax-error-3.mm (revision 0) +++ testsuite/obj-c++.dg/syntax-error-3.mm (revision 0) @@ -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 Index: testsuite/obj-c++.dg/syntax-error-6.mm =================================================================== --- testsuite/obj-c++.dg/syntax-error-6.mm (revision 0) +++ testsuite/obj-c++.dg/syntax-error-6.mm (revision 0) @@ -0,0 +1,12 @@ +/* { dg-do compile } */ + +@interface NSButton +- (int) state; +@end + +void FOO() +{ + NSButton * mCopyAcrobatCB; + + [ [ mCopyAcrobatCB state ] == 0 ] != 1; /* { dg-error "objective\\-c\\+\\+" } */ +} Index: testsuite/obj-c++.dg/syntax-error-1.mm =================================================================== --- testsuite/obj-c++.dg/syntax-error-1.mm (revision 0) +++ testsuite/obj-c++.dg/syntax-error-1.mm (revision 0) @@ -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 } */ Index: cp/ChangeLog =================================================================== --- cp/ChangeLog (revision 164989) +++ cp/ChangeLog (working copy) @@ -1,3 +1,52 @@ +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-04 Andi Kleen * Make-lang.in (g++, cc1plus): Add + to build rule. Index: cp/parser.c =================================================================== --- cp/parser.c (revision 164989) +++ cp/parser.c (working copy) @@ -8294,10 +8294,13 @@ cp_parser_statement_seq_opt (cp_parser* parser, tr { 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); } @@ -21517,6 +21526,11 @@ cp_parser_objc_method_keyword_params (cp_parser* p 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 +21622,13 @@ cp_parser_objc_interstitial_code (cp_parser* parse 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 +21691,7 @@ cp_parser_objc_method_prototype_list (cp_parser* p 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 +21709,11 @@ cp_parser_objc_method_prototype_list (cp_parser* p 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 +21737,7 @@ cp_parser_objc_method_definition_list (cp_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 +21753,7 @@ cp_parser_objc_method_definition_list (cp_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 +21769,11 @@ cp_parser_objc_method_definition_list (cp_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 +21790,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 +21890,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); Index: c-parser.c =================================================================== --- c-parser.c (revision 164989) +++ c-parser.c (working copy) @@ -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); }