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  <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.
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 164989)
+++ ChangeLog	(working copy)
@@ -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>
 
Index: testsuite/ChangeLog
===================================================================
--- testsuite/ChangeLog	(revision 164989)
+++ testsuite/ChangeLog	(working copy)
@@ -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
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 <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 } */
Index: cp/ChangeLog
===================================================================
--- cp/ChangeLog	(revision 164989)
+++ cp/ChangeLog	(working copy)
@@ -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.
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);
     }
