discuss-gnustep
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[objc-improvements] Message passing breaks when receiver type doesn't ma


From: Alexander Malmberg
Subject: [objc-improvements] Message passing breaks when receiver type doesn't match promoted sender type (Was: How is it looking?)
Date: Fri, 15 Aug 2003 01:15:44 +0200

Ziemowit Laski wrote:
[snip]
> could any of you brave GNUStep folk take the branch for yet another
> spin, and let me know if there are any remaining problems?

GNUstep core/ built, but there were odd failures in the test suite and
apps. Investigation shows  that this change:

"""
2003-08-08 23:27  zlaski

        * objc-act.c: Fix build_objc_method_call() so that it does not
        produce warnings about mismatched argument types.  This was
subtly
        broken under both GNU and NeXT regimes.  While I was at it, I
        refactored some of the commonalities.  Remove stray APPLE LOCAL
        markers.
"""

breaks message passing in many cases. The relevant part is, quoting the
new comment:

""This is because the sender signature may in fact be incorrect,
especially if the type of the receiver is not known. The same applies to
sender's arguments (other than self and _cmd), so just cast them as
'...'.""

By casting the function to id (*)(id,SEL,...), arguments are always
passed as the promoted type of the argument expression, which might not
match what the method expects.

Eg. given:

-(void) anInt: (int)foo;

and

[receiver anInt: 1.0];

the sender will push a double on the stack, while the method expects an
int. Size mismatches between arguments (as in this case; 4 byte int vs.
8 byte double) also means that subsequent arguments will be messed up.
The problem does not appear to be specific to the GNU runtime.

I've attached a patch that fixes this by reverting to the old behavior
when method_prototype is non-null. This fixes my simple tests for it.
I'm waiting for GNUstep to finish (re)compiling to see if there are any
problems left. When method_prototype is null, it uses the new code since
it seems equivalent to the old code wrt arguments.

I've also attached a simple test for one instance of the problem.

- Alexander Malmberg
Index: objc-act.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/objc/objc-act.c,v
retrieving revision 1.179.2.6
diff -u -r1.179.2.6 objc-act.c
--- objc-act.c  12 Aug 2003 19:02:39 -0000      1.179.2.6
+++ objc-act.c  14 Aug 2003 22:51:33 -0000
@@ -5976,19 +5976,37 @@
   tree ret_type = (method_prototype
                   ? groktypename (TREE_TYPE (method_prototype))
                   : id_type);
-  tree sender_cast = build_pointer_type
-                    (build_function_type 
-                     ((ret_type == void_type_node 
-                       ? id_type 
+
+  tree sender_cast;
+
+  if (method_prototype)
+    {
+        
+      sender_cast = build_pointer_type
+                    (build_function_type
+                     ((ret_type == void_type_node
+                       ? id_type
+                       : ret_type),
+                      get_arg_type_list (method_prototype,
+                                         METHOD_REF,
+                                         super_flag)));
+    }
+  else
+    {
+      sender_cast = build_pointer_type
+                    (build_function_type
+                     ((ret_type == void_type_node
+                       ? id_type
                        : ret_type),
                      tree_cons (NULL_TREE,
                                 (super_flag && flag_next_runtime
                                  ? super_type
                                  : id_type),
-                                tree_cons (NULL_TREE, 
+                                tree_cons (NULL_TREE,
                                            selector_type,
                                            NULL_TREE))));
-        
+    }
+
   lookup_object = build_c_cast (rcv_p, lookup_object);
 
   if (flag_next_runtime)
#include <objc/Object.h>

@interface Foo : Object
{
}

-(void) brokenType: (float)x  anInt: (int)y;

@end


@implementation Foo

-(void) brokenType: (float)x  anInt: (int)y
{
        printf("x=%g y=%i\n",x,y);
}

@end

int main(int argc,char **argv)
{
        Foo *foo=[Foo new];

        [foo brokenType: 5.2 anInt: 1234.0];

        return 0;
}


reply via email to

[Prev in Thread] Current Thread [Next in Thread]