Index: gcc/objc/objc-act.c
===================================================================
--- gcc/objc/objc-act.c	(revision 164235)
+++ gcc/objc/objc-act.c	(working copy)
@@ -788,6 +788,13 @@ objc_start_method_definition (tree decl)
   if (!objc_implementation_context)
     fatal_error ("method definition not in @implementation context");
 
+#ifndef OBJCPLUS
+  /* Indicate no valid break/continue context by setting these variables
+     to some non-null, non-label value.  We'll notice and emit the proper
+     error message in c_finish_bc_stmt.  */
+  c_break_label = c_cont_label = size_zero_node;
+#endif
+
   objc_add_method (objc_implementation_context,
 		   decl,
 		   objc_inherit_code == CLASS_METHOD_DECL);
@@ -1131,6 +1138,29 @@ objc_compare_types (tree ltyp, tree rtyp
     }
   while (POINTER_TYPE_P (ltyp) && POINTER_TYPE_P (rtyp));
 
+  /* We must also handle function pointers, since ObjC is a bit more
+     lenient than C or C++ on this.  */
+  if (TREE_CODE (ltyp) == FUNCTION_TYPE && TREE_CODE (rtyp) == FUNCTION_TYPE)
+    {
+      /* Return types must be covariant.  */
+      if (!comptypes (TREE_TYPE (ltyp), TREE_TYPE (rtyp))
+	  && !objc_compare_types (TREE_TYPE (ltyp), TREE_TYPE (rtyp),
+				  argno, callee))
+      return false;
+
+      /* Argument types must be contravariant.  */
+      for (ltyp = TYPE_ARG_TYPES (ltyp), rtyp = TYPE_ARG_TYPES (rtyp);
+	   ltyp && rtyp; ltyp = TREE_CHAIN (ltyp), rtyp = TREE_CHAIN (rtyp))
+	{
+	  if (!comptypes (TREE_VALUE (rtyp), TREE_VALUE (ltyp))
+	      && !objc_compare_types (TREE_VALUE (rtyp), TREE_VALUE (ltyp),
+				      argno, callee))
+	    return false;
+      }
+
+      return (ltyp == rtyp);
+    }
+
   /* Past this point, we are only interested in ObjC class instances,
      or 'id' or 'Class'.  */
   if (TREE_CODE (ltyp) != RECORD_TYPE || TREE_CODE (rtyp) != RECORD_TYPE)
@@ -1415,7 +1445,17 @@ objc_get_protocol_qualified_type (tree i
       type = objc_is_class_name (interface);
 
       if (type)
-	type = xref_tag (RECORD_TYPE, type);
+	{
+	  /* If looking at a typedef, retrieve the precise type it
+	     describes.  */
+	  if (TREE_CODE (interface) == IDENTIFIER_NODE)
+	    interface = identifier_global_value (interface);
+
+	  type = ((interface && TREE_CODE (interface) == TYPE_DECL
+		   && DECL_ORIGINAL_TYPE (interface))
+		  ? DECL_ORIGINAL_TYPE (interface)
+		  : xref_tag (RECORD_TYPE, type));
+	}
       else
         return interface;
     }
@@ -6360,7 +6400,14 @@ objc_finish_message_expr (tree receiver,
 	 more intelligent about which methods the receiver will
 	 understand. */
       if (!rtype || TREE_CODE (rtype) == IDENTIFIER_NODE)
-	rtype = NULL_TREE;
+	{
+	  rtype = NULL_TREE;
+	  /* We could not find an @interface declaration, yet Message maybe in a 
+	     @class's protocol. */
+	  if (!method_prototype && rprotos)
+	    method_prototype
+	      = lookup_method_in_protocol_list (rprotos, sel_name, 0);
+	}
       else if (TREE_CODE (rtype) == CLASS_INTERFACE_TYPE
 	  || TREE_CODE (rtype) == CLASS_IMPLEMENTATION_TYPE)
 	{
Index: gcc/objc/ChangeLog
===================================================================
--- gcc/objc/ChangeLog	(revision 164235)
+++ gcc/objc/ChangeLog	(working copy)
@@ -1,3 +1,34 @@
+2010-09-12  Nicola Pero  <nicola.pero@meta-innovation.com>
+
+	Merge from 'apple/trunk' branch on FSF servers.
+
+	2006-03-09 Fariborz Jahanian <fjahanian@apple.com>
+
+        Radar 4457381
+	* objc/objc-act.c (objc_finish_message_expr): Look for message in
+	@class's protocol list.
+
+	2006-02-07  Fariborz Jahanian <fjahanian@apple.com>
+
+	Radar 4219590
+	* objc/objc-act.c (objc_start_method_definition): Initialize
+	break/continue labels.
+
+	2005-08-22  Ziemowit Laski  <zlaski@apple.com>
+
+	Radar 4174166
+	* objc-act.c (objc_compare_types): Compare function
+	pointers; indicate success if the right-hand side has
+	a return type that is covariant, and the argument types
+	contravariant, with those of the left side.
+
+	2005-08-22  Ziemowit Laski  <zlaski@apple.com>
+
+	Radar 4216500
+	* objc-act.c (objc_get_protocol_qualified_type): When looking
+	at a typedef, retrieve the precise type it describes (rather
+	than merely looking up a class by name).
+	
 2010-09-10  Nicola Pero  <nicola.pero@meta-innovation.com>
 
 	* objc/objc-act.c (objc_begin_try_stmt): Generate an error if
Index: gcc/testsuite/ChangeLog
===================================================================
--- gcc/testsuite/ChangeLog	(revision 164235)
+++ gcc/testsuite/ChangeLog	(working copy)
@@ -1,3 +1,30 @@
+2010-09-12  Nicola Pero  <nicola.pero@meta-innovation.com>
+
+	Merge from 'apple/trunk' branch on FSF servers.
+
+	2006-03-09 Fariborz Jahanian <fjahanian@apple.com>
+
+	Radar 4457381
+	* objc.dg/msg-in-protocol.m: New.
+	* obj-c++.dg/msg-in-protocol.mm: New.
+
+	2006-02-07  Fariborz Jahanian <fjahanian@apple.com>
+
+	Radar 4219590
+	* objc.dg/break-in-ifstmt.m: New.
+	
+	2005-08-22  Ziemowit Laski  <zlaski@apple.com>
+
+	Radar 4174166
+	* obj-c++.dg/comp-types-13.mm: New.
+	* objc.dg/comp-types-12.m: New.
+
+	2005-08-22  Ziemowit Laski  <zlaski@apple.com>
+
+	Radar 4216500
+	* obj-c++.dg/proto-lossage-7.mm: New.
+	* objc.dg/proto-lossage-7.m: New.
+	
 2010-09-11  Francois-Xavier Coudert  <fxcoudert@gcc.gnu.org>
 
 	* gfortran.dg/promotion.f90: Fix options.
Index: gcc/testsuite/objc.dg/proto-lossage-7.m
===================================================================
--- gcc/testsuite/objc.dg/proto-lossage-7.m	(revision 0)
+++ gcc/testsuite/objc.dg/proto-lossage-7.m	(revision 0)
@@ -0,0 +1,28 @@
+/* Check that typedefs of ObjC classes preserve 
+   any @protocol qualifiers.  */
+/* { dg-do compile } */
+#include <objc/Object.h>
+
+@protocol CanDoStuff;
+
+typedef Object<CanDoStuff> CanDoStuffType;
+typedef Object<CanDoStuff> *CanDoStuffTypePtr;
+
+@protocol CanDoStuff
+- (int) dostuff;
+@end
+
+@protocol MoreStuff
+- (int) morestuff;
+@end
+
+int main(void)
+{
+    CanDoStuffTypePtr  dice     = nil;
+    CanDoStuffType    *nodice   = nil;
+    int count;
+    count = [dice dostuff];
+    count = [nodice dostuff];
+    return 0;
+}
+
Index: gcc/testsuite/objc.dg/break-in-ifstmt.m
===================================================================
--- gcc/testsuite/objc.dg/break-in-ifstmt.m	(revision 0)
+++ gcc/testsuite/objc.dg/break-in-ifstmt.m	(revision 0)
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+
+@interface foo
+- (void) test;
+@end
+
+@implementation foo
+-(void) test {
+  if (1) {
+        break;	/* { dg-error "break" } */
+        }
+}
+@end
+
Index: gcc/testsuite/objc.dg/comp-types-12.m
===================================================================
--- gcc/testsuite/objc.dg/comp-types-12.m	(revision 0)
+++ gcc/testsuite/objc.dg/comp-types-12.m	(revision 0)
@@ -0,0 +1,19 @@
+/* When assigning function pointers, allow for covariant return types
+   and contravariant argument types.  */
+/* { dg-do compile } */
+#include <objc/Object.h>
+
+@class Derived;
+
+Object *ExternFunc (Object *filePath, Object *key);
+typedef id FuncSignature (Object *arg1, Derived *arg2);
+
+@interface Derived: Object
++ (void)registerFunc:(FuncSignature *)function;
+@end
+
+void foo(void)
+{
+  [Derived registerFunc: ExternFunc];
+}
+
Index: gcc/testsuite/objc.dg/msg-in-protocol.m
===================================================================
--- gcc/testsuite/objc.dg/msg-in-protocol.m	(revision 0)
+++ gcc/testsuite/objc.dg/msg-in-protocol.m	(revision 0)
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+
+#include <objc/objc.h>
+
+@class Foo;
+
+@protocol Bar
+
+- (void)bang;
+
+@end
+
+void foo()
+{
+    Foo<Bar> *foo = nil;
+    [foo bang];
+}
+
Index: gcc/testsuite/obj-c++.dg/comp-types-13.mm
===================================================================
--- gcc/testsuite/obj-c++.dg/comp-types-13.mm	(revision 0)
+++ gcc/testsuite/obj-c++.dg/comp-types-13.mm	(revision 0)
@@ -0,0 +1,19 @@
+/* When assigning function pointers, allow for covariant return types
+   and contravariant argument types.  */
+/* { dg-do compile } */
+#include <objc/Object.h>
+
+@class Derived;
+
+Object *ExternFunc (Object *filePath, Object *key);
+typedef id FuncSignature (Object *arg1, Derived *arg2);
+
+@interface Derived: Object
++ (void)registerFunc:(FuncSignature *)function;
+@end
+
+void foo(void)
+{
+  [Derived registerFunc: ExternFunc];
+}
+
Index: gcc/testsuite/obj-c++.dg/proto-lossage-7.mm
===================================================================
--- gcc/testsuite/obj-c++.dg/proto-lossage-7.mm	(revision 0)
+++ gcc/testsuite/obj-c++.dg/proto-lossage-7.mm	(revision 0)
@@ -0,0 +1,28 @@
+/* Check that typedefs of ObjC classes preserve 
+   any @protocol qualifiers.  */
+/* { dg-do compile } */
+#include <objc/Object.h>
+
+@protocol CanDoStuff;
+
+typedef Object<CanDoStuff> CanDoStuffType;
+typedef Object<CanDoStuff> *CanDoStuffTypePtr;
+
+@protocol CanDoStuff
+- (int) dostuff;
+@end
+
+@protocol MoreStuff
+- (int) morestuff;
+@end
+
+int main(void)
+{
+    CanDoStuffTypePtr  dice     = nil;
+    CanDoStuffType    *nodice   = nil;
+    int count;
+    count = [dice dostuff];
+    count = [nodice dostuff];
+    return 0;
+}
+
Index: gcc/testsuite/obj-c++.dg/msg-in-protocol.mm
===================================================================
--- gcc/testsuite/obj-c++.dg/msg-in-protocol.mm	(revision 0)
+++ gcc/testsuite/obj-c++.dg/msg-in-protocol.mm	(revision 0)
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+
+#include <objc/objc.h>
+
+@class Foo;
+
+@protocol Bar
+
+- (void)bang;
+
+@end
+
+void foo()
+{
+    Foo<Bar> *foo = nil;
+    [foo bang];
+}
+
