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: PR objc/18971


This was noticed by Alex, and it turned out that ObjC method parameters were not being properly decayed from arrays to pointers. This patch hopefully fixes this, along with ObjC pretty-printing of array types.

I see absolutely no regressions with this, but I'll wait until next week before committing so that people may comment. Happy holidays to all...

--Zem

[gcc/objc/ChangeLog]
2004-12-24  Ziemowit Laski  <zlaski@apple.com>

        PR objc/18971
        * objc-act.c (get_arg_type_list, start_method_def): Decay
        array arguments into pointers.
        (gen_type_name_0): Learn to pretty-print array types.

[gcc/testsuite/ChangeLog]
2004-12-24  Alexander Malmberg  <alexander@malmberg.org>
            Ziemowit Laski  <zlaski@apple.com>

        PR objc/18971
        * objc.dg/encode-5.m: New test.



Index: gcc/objc/objc-act.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/objc/objc-act.c,v
retrieving revision 1.258
diff -u -3 -p -r1.258 objc-act.c
--- gcc/objc/objc-act.c 16 Dec 2004 01:10:36 -0000      1.258
+++ gcc/objc/objc-act.c 24 Dec 2004 21:36:05 -0000
@@ -5300,6 +5300,10 @@ get_arg_type_list (tree meth, int contex
     {
       tree arg_type = TREE_VALUE (TREE_TYPE (akey));

+      /* Decay arrays into pointers.  */
+      if (TREE_CODE (arg_type) == ARRAY_TYPE)
+       arg_type = build_pointer_type (TREE_TYPE (arg_type));
+
       chainon (arglist, build_tree_list (NULL_TREE, arg_type));
     }

@@ -7473,9 +7481,13 @@ start_method_def (tree method)
   parmlist = METHOD_SEL_ARGS (method);
   while (parmlist)
     {
-      tree parm = build_decl (PARM_DECL, KEYWORD_ARG_NAME (parmlist),
-                             TREE_VALUE (TREE_TYPE (parmlist)));
+      tree type = TREE_VALUE (TREE_TYPE (parmlist)), parm;
+
+      /* Decay arrays into pointers.  */
+      if (TREE_CODE (type) == ARRAY_TYPE)
+       type = build_pointer_type (TREE_TYPE (type));

+      parm = build_decl (PARM_DECL, KEYWORD_ARG_NAME (parmlist), type);
       objc_push_parm (parm);
       parmlist = TREE_CHAIN (parmlist);
     }
@@ -7941,14 +7953,39 @@ gen_type_name_0 (tree type)

   if (TYPE_P (type) && TYPE_NAME (type))
     type = TYPE_NAME (type);
-  else if (POINTER_TYPE_P (type))
+  else if (POINTER_TYPE_P (type) || TREE_CODE (type) == ARRAY_TYPE)
     {
-      gen_type_name_0 (TREE_TYPE (type));
+      tree inner = TREE_TYPE (type);
+
+      while (TREE_CODE (inner) == ARRAY_TYPE)
+       inner = TREE_TYPE (inner);
+
+      gen_type_name_0 (inner);

-      if (!POINTER_TYPE_P (TREE_TYPE (type)))
+      if (!POINTER_TYPE_P (inner))
        strcat (errbuf, " ");

-      strcat (errbuf, "*");
+      if (POINTER_TYPE_P (type))
+       strcat (errbuf, "*");
+      else
+       while (type != inner)
+         {
+           strcat (errbuf, "[");
+
+           if (TYPE_DOMAIN (type))
+             {
+               char sz[20];
+
+               sprintf (sz, HOST_WIDE_INT_PRINT_DEC,
+                        (TREE_INT_CST_LOW
+                         (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) + 1));
+               strcat (errbuf, sz);
+             }
+
+           strcat (errbuf, "]");
+           type = TREE_TYPE (type);
+         }
+
       goto exit_function;
     }

Index: gcc/testsuite/objc.dg/encode-5.m
===================================================================
RCS file: gcc/testsuite/objc.dg/encode-5.m
diff -N gcc/testsuite/objc.dg/encode-5.m
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ gcc/testsuite/objc.dg/encode-5.m 24 Dec 2004 21:36:19 -0000
@@ -0,0 +1,78 @@
+/* Check if array arguments of ObjC methods are decayed to pointer types
+ in a proper fashion:
+ (1) The _encodings_ for the array arguments should remain to be '[4i]' and
+ such, since this has been the case since at least gcc 3.3.
+ (2) However, when building the static C functions out of ObjC method signatures,
+ we need to decay the arrays into pointers (as C does).
+ (3) If array size is not known (e.g., 'int a[]'), then the type shall be
+ encoded as a pointer. */
+
+/* Contributed by Alexander Malmberg <alexander@malmberg.org> */
+
+#include <objc/Object.h>
+#include <stdlib.h>
+#include <stdio.h>
+#define CHECK_IF(expr) if(!(expr)) abort()
+
+#ifdef __NEXT_RUNTIME__
+#define METHOD Method
+#define OBJC_GETCLASS objc_getClass
+#define CLASS_GETINSTANCEMETHOD class_getInstanceMethod
+#else
+#include <objc/objc-api.h>
+#define METHOD Method_t
+#define OBJC_GETCLASS objc_get_class
+#define CLASS_GETINSTANCEMETHOD class_get_instance_method
+#endif
+
+@interface Test : Object
+{ float j; }
+-(void) test2: (int [5])a with: (int [])b;
+-(id) test3: (Test **)b; /* { dg-warning "previous declaration of .\\-\\(id\\)test3:\\(Test \\*\\*\\)b." } */
+@end
+
+@implementation Test
+-(void) test2: (int [5])a with: (int [])b
+{
+ a[3] = *b;
+}
+-(void) test3: (Test [3][4])b { /* { dg-warning "conflicting types for .\\-\\(void\\)test3:\\(Test \\\[3\\\]\\\[4\\\]\\)b." } */
+}
+@end
+
+int bb[6] = { 0, 1, 2, 3, 4, 5 };
+int *b = bb;
+Test *cc[4];
+Test **c = cc;
+
+int offs1, offs2, offs3, offs4, offs5, offs6;
+
+int main(int argc, char **argv)
+{
+ Class testClass = OBJC_GETCLASS("Test");
+ METHOD meth;
+
+ cc[0] = [Test new];
+ CHECK_IF (bb[3] == 3);
+ [*c test2: b with: bb + 4];
+ CHECK_IF (bb[3] == 4);
+ bb[3] = 0;
+ [*c test2: bb with: bb + 5];
+ CHECK_IF (bb[3] == 5);
+
+ meth = CLASS_GETINSTANCEMETHOD(testClass, @selector(test2:with:));
+ offs1 = offs2 = offs3 = offs4 = offs5 = offs6 = -1;
+ sscanf(meth->method_types, "v%d@%d:%d[%di]%d^i%d", &offs1, &offs2, &offs3,
+ &offs4, &offs5, &offs6);
+ CHECK_IF (!offs2 && offs4 == 5 && offs3 > 0);
+ CHECK_IF (offs5 == 2 * offs3 && offs6 == 3 * offs3 && offs1 == 4 * offs3);
+
+ meth = CLASS_GETINSTANCEMETHOD(testClass, @selector(test3:));
+ offs1 = offs2 = offs3 = offs4 = offs5 = offs6 = -1;
+ sscanf(meth->method_types, "v%d@%d:%d[%d[%d{Test=#f}]]%d", &offs1, &offs2, &offs3,
+ &offs4, &offs5, &offs6);
+ CHECK_IF (!offs2 && offs4 == 3 && offs5 == 4 && offs3 > 0);
+ CHECK_IF (offs6 == 2 * offs3 && offs1 == 3 * offs3);
+
+ return 0;
+}



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