===================================================================
@@ -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"
===================================================================
@@ -1,3 +1,13 @@
+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
+ * 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 <ak@linux.intel.com>
* Make-lang.in (cc1obj-dummy, cc1obj): Add + to build rule.
===================================================================
@@ -1,3 +1,7 @@
+2010-10-05 Nicola Pero <nicola.pero@meta-innovation.com>
+
+ * c-parser.c (c_parser_objc_method_definition): Updated comment.
+
2010-10-05 Olivier Hainque <hainque@adacore.com>
Nicolas Roche <roche@adacore.com>
===================================================================
@@ -1,3 +1,37 @@
+2010-10-05 Nicola Pero <nicola.pero@meta-innovation.com>
+
+ PR objc++/31126
+ * obj-c++.dg/syntax-error.8.mm: New.
+
+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
+ * obj-c++.dg/syntax-error-7.mm: New
+
+ 2005-10-14 Fariborz Jahanian <fjahanian@apple.com>
+
+ Radar 4294425
+ * obj-c++.dg/syntax-error-6.mm: New
+
+ 2005-10-13 Fariborz Jahanian <fjahanian@apple.com>
+
+ Radar 4261146
+ * obj-c++.dg/syntax-error-5.mm: New
+
+ 2005-08-15 Ziemowit Laski <zlaski@apple.com>
+
+ Radar 4093475
+ * obj-c++.dg/syntax-error-[3-4].mm: New.
+
+ 2005-08-02 Ziemowit Laski <zlaski@apple.com>
+
+ Radar 4185810
+ * obj-c++.dg/syntax-error-[1-2].mm: New.
+
2010-10-05 Ira Rosen <irar@il.ibm.com>
PR tree-optimization/45752
===================================================================
@@ -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
+
===================================================================
@@ -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 } */
===================================================================
@@ -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
===================================================================
@@ -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." } */
===================================================================
@@ -0,0 +1 @@
+@interface A /* { dg-error "expected ..end." } */
\ No newline at end of file
===================================================================
@@ -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
===================================================================
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+
+@interface NSButton
+- (int) state;
+@end
+
+void FOO()
+{
+ NSButton * mCopyAcrobatCB;
+
+ [ [ mCopyAcrobatCB state ] == 0 ] != 1; /* { dg-error "objective\\-c\\+\\+" } */
+}
===================================================================
@@ -0,0 +1,26 @@
+/* Graceful handling of a syntax error. */
+/* { dg-do compile } */
+
+#include <objc/Object.h>
+
+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 } */
===================================================================
@@ -1,3 +1,52 @@
+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-04 Andi Kleen <ak@linux.intel.com>
* Make-lang.in (g++, cc1plus): Add + to build rule.
===================================================================
@@ -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);
===================================================================
@@ -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);
}