re PR objc/18971 (Can't send messages to methods with arrays as parameters)
[gcc/objc/ChangeLog] 2004-12-30 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-30 Alexander Malmberg <alexander@malmberg.org> Ziemowit Laski <zlaski@apple.com> PR objc/18971 * objc.dg/encode-5.m: New test. From-SVN: r92731
This commit is contained in:
parent
2fdb7cd791
commit
9eb892ec7f
@ -1,3 +1,10 @@
|
||||
2004-12-30 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.
|
||||
|
||||
2004-12-15 Ziemowit Laski <zlaski@apple.com>
|
||||
|
||||
* objc-act.c (build_private_template): Change to return 'void'; do
|
||||
|
@ -5300,6 +5300,10 @@ get_arg_type_list (tree meth, int context, int superflag)
|
||||
{
|
||||
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 +7477,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 +7949,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;
|
||||
}
|
||||
|
||||
|
@ -1,3 +1,9 @@
|
||||
2004-12-30 Alexander Malmberg <alexander@malmberg.org>
|
||||
Ziemowit Laski <zlaski@apple.com>
|
||||
|
||||
PR objc/18971
|
||||
* objc.dg/encode-5.m: New test.
|
||||
|
||||
2004-12-29 Richard Henderson <rth@redhat.com>
|
||||
|
||||
* gcc.dg/20040813-1.c: Disable for alpha and ia64.
|
||||
|
78
gcc/testsuite/objc.dg/encode-5.m
Normal file
78
gcc/testsuite/objc.dg/encode-5.m
Normal file
@ -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;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user