Patchwork ObjC/ObjC++: fixed 'too many arguments to method xxx' error

login
register
mail settings
Submitter Nicola Pero
Date Sept. 12, 2010, 10 p.m.
Message ID <1284328807.214516779@192.168.2.229>
Download mbox | patch
Permalink /patch/64568/
State New
Headers show

Comments

Nicola Pero - Sept. 12, 2010, 10 p.m.
>> I took the testcase (marked as Apple Radar 4491608) from the 
>> 
>>  gcc.gnu.org/svn/gcc/branches/apple/trunk
>
> In general, I'll pre-approve the gcc/objc subdirectory changes from that branch and the corresponding objc testsuite changes as well.

Thanks

Here is a patch that merges 4 bug fixes from the apple/trunk branch.  It only requires
changing objc/objc-act.c and all the bug fixes come with an associated testcase.  It passes
all existing tests, plus the new ones, which would otherwise fail.

I guess Mike approved it so I can commit ? :-)

Thanks
Mike Stump - Sept. 12, 2010, 10:47 p.m.
On Sep 12, 2010, at 3:00 PM, Nicola Pero wrote:
> Here is a patch that merges 4 bug fixes from the apple/trunk branch.  It only requires
> changing objc/objc-act.c and all the bug fixes come with an associated testcase.  It passes
> all existing tests, plus the new ones, which would otherwise fail.
> 
> I guess Mike approved it so I can commit ? :-)

Yes, looks fine.
Nicola Pero - Sept. 15, 2010, 12:09 a.m.
Thanks, committed

-----Original Message-----
From: "Mike Stump" <mikestump@comcast.net>
Sent: Monday, 13 September, 2010 00:47
To: "Nicola Pero" <nicola.pero@meta-innovation.com>
Cc: gcc-patches@gnu.org
Subject: Re: ObjC/ObjC++: fixed 'too many arguments to method xxx' error

On Sep 12, 2010, at 3:00 PM, Nicola Pero wrote:
> Here is a patch that merges 4 bug fixes from the apple/trunk branch.  It only requires
> changing objc/objc-act.c and all the bug fixes come with an associated testcase.  It passes
> all existing tests, plus the new ones, which would otherwise fail.
> 
> I guess Mike approved it so I can commit ? :-)

Yes, looks fine.

Patch

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];
+}
+