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]
Other format: [Raw text]

PATCH: Fix ObjC stret-method handling on Darwin


This has been broken in the FSF tree since mid-October, which you could
see by running the objc/execute/class_self-2.m test case on Mac OS X.

The NeXT runtime has specialized entry points for handling dispatches to methods that
return structs. Alas, their use was inadvertently disabled when several
gcc-wide macros were replaced with target hooks.


As a result of applying this patch, we have one progression (namely,
objc/execute/class_self-2.m) plus two new passing test cases.
I will commit this to both mainline and the 3.4 branch (since it's definitely
a bug fix) tomorrow, unless someone gives me a convincing reason not to.



[gcc/ChangeLog] 2004-01-17 Ziemowit Laski <zlaski@apple.com>

        * objc/objc-act.c (build_objc_method_call): Use target
        hooks instead of macros to determine if ..._stret
        dispatchers should be used (NeXT runtime only).

[gcc/testsuite/ChangeLog]
2004-01-17  Ziemowit Laski  <zlaski@apple.com>

        * objc.dg/stret-1.m: New.
        * objc.dg/stret-2.m: New.

Index: gcc/objc/objc-act.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/objc/objc-act.c,v
retrieving revision 1.202
diff -c -3 -p -r1.202 objc-act.c
*** gcc/objc/objc-act.c 13 Dec 2003 00:23:51 -0000      1.202
--- gcc/objc/objc-act.c 17 Jan 2004 07:35:20 -0000
*************** build_objc_method_call (int super_flag,
*** 5890,5910 ****

if (flag_next_runtime)
{
- #ifdef STRUCT_VALUE
/* If we are returning a struct in memory, and the address
of that memory location is passed as a hidden first
argument, then change which messenger entry point this
expr will call. NB: Note that sender_cast remains
unchanged (it already has a struct return type). */
! if ((TREE_CODE (ret_type) == RECORD_TYPE
! || TREE_CODE (ret_type) == UNION_TYPE)
! #if defined (DEFAULT_PCC_STRUCT_RETURN) && DEFAULT_PCC_STRUCT_RETURN == 0
! && RETURN_IN_MEMORY (ret_type)
! #endif
! && STRUCT_VALUE == 0)
sender = (super_flag ? umsg_super_stret_decl :
flag_nil_receivers ? umsg_stret_decl : umsg_nonnil_stret_decl);
! #endif
method_params = tree_cons (NULL_TREE, lookup_object,
tree_cons (NULL_TREE, selector,
method_params));
--- 5890,5907 ----


if (flag_next_runtime)
{
/* If we are returning a struct in memory, and the address
of that memory location is passed as a hidden first
argument, then change which messenger entry point this
expr will call. NB: Note that sender_cast remains
unchanged (it already has a struct return type). */
! if (!targetm.calls.struct_value_rtx (0, 0)
! && (TREE_CODE (ret_type) == RECORD_TYPE
! || TREE_CODE (ret_type) == UNION_TYPE)
! && targetm.calls.return_in_memory (ret_type, 0))
sender = (super_flag ? umsg_super_stret_decl :
flag_nil_receivers ? umsg_stret_decl : umsg_nonnil_stret_decl);
!
method_params = tree_cons (NULL_TREE, lookup_object,
tree_cons (NULL_TREE, selector,
method_params));
Index: gcc/testsuite/objc.dg/stret-1.m
===================================================================
RCS file: gcc/testsuite/objc.dg/stret-1.m
diff -N gcc/testsuite/objc.dg/stret-1.m
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- gcc/testsuite/objc.dg/stret-1.m 17 Jan 2004 07:35:27 -0000
***************
*** 0 ****
--- 1,62 ----
+ /* Test for handling of struct-returning methods. */
+ /* Contributed by Ziemowit Laski <zlaski@apple.com>. */
+ /* { dg-do run } */
+
+ #include <objc/Object.h>
+
+ extern void abort(void);
+ #define CHECK_IF(expr) if(!(expr)) abort()
+
+ struct astruct {
+ float a, b;
+ } glob = { 1.0, 2.0 };
+
+ struct bstruct {
+ float a, b, c, d, e, f;
+ } globb = { 1, 2, 3, 4, 5, 6 };
+
+ @interface foo : Object
+ - (struct astruct) stret;
+ - (struct bstruct) stretb;
+ @end
+
+ @implementation foo : Object
+ - (struct astruct) stret { return glob; }
+ - (struct bstruct) stretb { return globb; }
+ @end
+
+ @interface bar: foo
+ - (struct astruct) stret;
+ - (struct bstruct) stretb;
+ @end
+
+ @implementation bar
+ - (struct astruct) stret { struct astruct a = [super stret]; a.b = 77; return a; }
+ - (struct bstruct) stretb { struct bstruct b = [super stretb]; b.e = 99; return b; }
+ @end
+
+ int main(void)
+ {
+ foo *obj = [foo new];
+ bar *obj2 = [bar new];
+ struct astruct loc, loc2;
+ struct bstruct locb, locb2;
+
+ loc = [obj stret];
+ CHECK_IF(loc.a == 1.0 && loc.b == 2.0);
+
+ locb = [obj stretb];
+ CHECK_IF(locb.f == 6 && locb.c == 3);
+ CHECK_IF(locb.e == 5 && locb.b == 2);
+ CHECK_IF(locb.d == 4 && locb.a == 1);
+
+ loc2 = [obj2 stret];
+ CHECK_IF(loc2.a == 1.0 && loc2.b == 77);
+
+ locb2 = [obj2 stretb];
+ CHECK_IF(locb2.f == 6 && locb2.c == 3);
+ CHECK_IF(locb2.e == 99 && locb2.b == 2);
+ CHECK_IF(locb2.d == 4 && locb2.a == 1);
+
+ return 0;
+ }
Index: gcc/testsuite/objc.dg/stret-2.m
===================================================================
RCS file: gcc/testsuite/objc.dg/stret-2.m
diff -N gcc/testsuite/objc.dg/stret-2.m
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- gcc/testsuite/objc.dg/stret-2.m 17 Jan 2004 07:35:27 -0000
***************
*** 0 ****
--- 1,46 ----
+ /* Test for handling of struct-returning methods
+ for the Mac OS X ("NeXT") runtime (which uses specialized entry
+ points). */
+ /* Contributed by Ziemowit Laski <zlaski@apple.com>. */
+ /* { dg-do compile { target *-*-darwin* } } */
+
+ #include <objc/Object.h>
+
+ struct astruct {
+ float a, b;
+ } glob = { 1.0, 2.0 };
+
+ struct bstruct {
+ float a, b, c, d, e, f;
+ } globb = { 1, 2, 3, 4, 5, 6 };
+
+ @interface foo : Object
+ - (struct astruct) stret;
+ - (struct bstruct) stretb;
+ @end
+
+ @implementation foo : Object
+ - (struct astruct) stret { return glob; }
+ - (struct bstruct) stretb { return globb; }
+ @end
+
+ @interface bar: foo
+ - (struct astruct) stret;
+ - (struct bstruct) stretb;
+ @end
+
+ @implementation bar
+ - (struct astruct) stret { return [super stret]; }
+ - (struct bstruct) stretb { return [super stretb]; }
+ @end
+
+ struct astruct afunc(foo *foo_obj) {
+ return [foo_obj stret];
+ }
+
+ /* { dg-final { scan-assembler "objc_msgSend_stret" } } */
+ /* { dg-final { scan-assembler "objc_msgSendSuper_stret" } } */
+
+ /* { dg-final { scan-assembler-not "objc_msgSend\[^_S\]" } } */
+ /* { dg-final { scan-assembler-not "objc_msgSendSuper\[^_\]" } } */
+



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