This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: objc.dg/method-2.m fix with the GNU runtime


Thanks!  I'll makes sure to test out your two new testcases with
the NeXT runtime as soon as they appear in the mainline.

--Zem

On Friday, October 26, 2001, at 11:48 , Nicola Pero wrote:

>
> Hi,
>
> here is a patch which fixes the objc.dg/method-2.m testcase with the GNU
> runtime (I think adapting/porting what was done by apple for the next
> runtime).
>
> One comment on the fix so it's recorded on the mailing list - the fix
> statically types `self' in a class method to be the class the method is
> part of.  This maximes error checking in normal situations, but gets in
> the way if you want to redefine self in a class method to be something
> else.  But in that case, you can still get the old behaviour of having
> self to be untyped id by simply casting self to id.
>
> I wrote some testcases while playing with it, I'd like to commit the
> following two -
>
> objc/class_self-1.m: brings the problem of having an untyped self to the
> extreme consequences - an instance method of an unrelated class - with a
> different signature - is picked up by the compiler instead of the 
> intended
> class method, and that causes compilation to fail.  fixed by the patch.
>
> objc/class_self-2.m: is the case in which the new compiler code requires
> you to use a cast.  self is redefined to be another class, so you have 
> to
> cast it to an id to have it compile.  This testcase is not failing, but
> I'd like to add it anyway to make sure we don't break it in the future.
>
> Ok to commit the new two testcases and apply the patch ?
>
> gcc/gcc/ChangeLog:
> ==================
>
> Fri Oct 26 07:42:53 2001  Nicola Pero  <n.pero@mi.flashnet.it>
>
> 	* objc/objc-act.c (finish_message_expr): For the GNU runtime: when
> 	determining the type of the receiver, do not check that TREE_CODE
> 	of receiver is CALL_EXPR before calling receiver_is_class_object
> 	().  (receiver_is_class_object): For the GNU runtime: recognize
> 	the case that the receiver is self in a class method context.
> 	Check that TREE_CODE of receiver is CALL_EXPR when checking that
> 	the receiver is a call to objc_get_class.
>
> Index: objc-act.c
> ===================================================================
> RCS file: /cvs/gcc/gcc/gcc/objc/objc-act.c,v
> retrieving revision 1.99
> diff -u -r1.99 objc-act.c
> --- objc-act.c	2001/10/21 21:03:48	1.99
> +++ objc-act.c	2001/10/27 12:18:56
> @@ -4710,14 +4710,16 @@
>  {
>    tree chain, exp, arg;
>
> +  /* The receiver is 'self' in the context of a class method.  */
> +  if (objc_method_context
> +      && receiver == self_decl
> +      && TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
> +    {
> +      return CLASS_NAME (objc_implementation_context);
> +    }
> +
>    if (flag_next_runtime)
>      {
> -      /* The receiver is 'self' in the context of a class method.  */
> -      if (objc_method_context
> -	  && receiver == self_decl
> -	  && TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
> -	return CLASS_NAME (objc_implementation_context);
> -
>        /* The receiver is a variable created by
>           build_class_reference_decl.  */
>        if (TREE_CODE (receiver) == VAR_DECL
> @@ -4731,7 +4733,8 @@
>      {
>        /* The receiver is a function call that returns an id.  Check if
>  	 it is a call to objc_getClass, if so, pick up the class name.  */
> -      if ((exp = TREE_OPERAND (receiver, 0))
> +      if (TREE_CODE (receiver) == CALL_EXPR
> +	  && (exp = TREE_OPERAND (receiver, 0))
>  	  && TREE_CODE (exp) == ADDR_EXPR
>  	  && (exp = TREE_OPERAND (exp, 0))
>  	  && TREE_CODE (exp) == FUNCTION_DECL
> @@ -4844,8 +4847,8 @@
>  	       && TREE_STATIC_TEMPLATE (TREE_TYPE (rtype)))
>  	statically_typed = 1;
>        else if ((flag_next_runtime
> -		|| (TREE_CODE (receiver) == CALL_EXPR && IS_ID (rtype)))
> -	       && (class_ident = receiver_is_class_object (receiver)))
> +		|| (IS_ID (rtype)
> +		    && (class_ident = receiver_is_class_object (receiver)))))
>  	;
>        else if (! IS_ID (rtype)
>  	       /* Allow any type that matches objc_class_type.  */
> @@ -5022,9 +5025,9 @@
>
>        /* We think we have an instance...loophole: extern id Object; */
>        hsh = hash_lookup (nst_method_hash_list, sel_name);
> +
>        if (!hsh)
> -	/* For various loopholes, like sending messages to self in a
> -	   factory context.  */
> +	/* For various loopholes */	
>  	hsh = hash_lookup (cls_method_hash_list, sel_name);
>
>        method_prototype = check_duplicates (hsh);
>
> gcc/gcc/testsuite/ChangeLog:
> ============================
>
> Fri Oct 26 09:02:07 2001  Nicola Pero  <n.pero@mi.flashnet.it>
>
> 	* objc/execute/class_self-1.m: New test.
> 	* objc/execute/class_self-2.m: New test.
>
> gcc/gcc/testsuite/objc/execute/class_self-1.m:
> ==============================================
> /* Contributed by Nicola Pero - Fri Oct 26 22:39:32 BST 2001 */
> #include <objc/objc.h>
>
> /* Test calling a class method when there is an instance method
>    with conflicting types */
>
> /* This class should be unused but on broken compilers its instance
>    method might get picked up and used instead of the class method of
>    another class ! */
> struct d
> {
>   int a;
> };
>
> @interface UnusedClass
> {
>   Class isa;
> }
> - (struct d) method;
> @end
>
> @implementation UnusedClass
> - (struct d) method
> {
>   struct d u;
>   u.a = 0;
>
>   return u;
> }
> @end
>
> /* The real class */
> @interface TestClass
> {
>   Class isa;
> }
> + (void) test;
> + (int) method;
> @end
>
> @implementation TestClass
> + (void) test
> {
>   if ([self method] != 4)
>     {
>       abort ();
>     }
> }
>
> + (int) method
> {
>   return 4;
> }
> @end
>
>
> int main (void)
> {
>   [TestClass test];
>
>   return 0;
> }
>
> gcc/gcc/testsuite/objc/execute/class_self-2.m:
> ==============================================
> /* Contributed by Nicola Pero - Fri Oct 26 22:39:32 BST 2001 */
> #include <objc/objc.h>
>
> /* Test calling a class method on self where self has been redefined
>    to be another class - the call requires a cast */
>
>
> /* The first class */
> struct d
> {
>   int a;
> };
>
> @interface ClassA
> {
>   Class isa;
> }
> + (Class) class;
> + (struct d) method;
> @end
>
> @implementation ClassA
> + (Class) class
> {
>   return self;
> }
>
> + (struct d) method
> {
>   struct d u;
>   u.a = 5;
>
>   return u;
> }
> @end
>
> /* The second class */
> @interface TestClass
> {
>   Class isa;
> }
> + (void) test;
> @end
>
> @implementation TestClass
> + (void) test
> {
>   self = [ClassA class];
>
>
>   if ([(Class)self method].a != 5)
>     {
>       abort ();
>     }
> }
>
> @end
>
>
> int main (void)
> {
>   [TestClass test];
>
>   return 0;
> }
>
>
--------------------------------------------------------------
Ziemowit Laski                   Apple Computer, Inc.
zlaski@apple.com                 2 Infinite Loop, MS 302-4SN
+1.408.974.6229  Fax .1344       Cupertino, CA  95014-2085


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]