| 1 |
703 |
jeremybenn |
/* Check if array arguments of ObjC methods are decayed to pointer types
|
| 2 |
|
|
in a proper fashion:
|
| 3 |
|
|
(1) The _encodings_ for the array arguments should remain to be '[4i]' and
|
| 4 |
|
|
such, since this has been the case since at least gcc 3.3.
|
| 5 |
|
|
(2) However, when building the static C functions out of ObjC method signatures,
|
| 6 |
|
|
we need to decay the arrays into pointers (as C does).
|
| 7 |
|
|
(3) If array size is not known (e.g., 'int a[]'), then the type shall be
|
| 8 |
|
|
encoded as a pointer. */
|
| 9 |
|
|
|
| 10 |
|
|
/* Contributed by Alexander Malmberg */
|
| 11 |
|
|
|
| 12 |
|
|
#include "../objc-obj-c++-shared/TestsuiteObject.m"
|
| 13 |
|
|
#include "../objc-obj-c++-shared/runtime.h"
|
| 14 |
|
|
#include
|
| 15 |
|
|
#include
|
| 16 |
|
|
#define CHECK_IF(expr) if(!(expr)) abort()
|
| 17 |
|
|
|
| 18 |
|
|
@interface Test : TestsuiteObject
|
| 19 |
|
|
{ float j; }
|
| 20 |
|
|
-(void) test2: (int [5])a with: (int [])b;
|
| 21 |
|
|
-(id) test3: (Test **)b; /* { dg-message "previous declaration of .\\-\\(id\\)test3:\\(Test \\*\\*\\)b." } */
|
| 22 |
|
|
@end
|
| 23 |
|
|
|
| 24 |
|
|
@implementation Test
|
| 25 |
|
|
-(void) test2: (int [5])a with: (int [])b
|
| 26 |
|
|
{
|
| 27 |
|
|
a[3] = *b;
|
| 28 |
|
|
}
|
| 29 |
|
|
-(void) test3: (Test [3][4])b { /* { dg-warning "conflicting types for .\\-\\(void\\)test3:\\(Test \\\[3\\\]\\\[4\\\]\\)b." } */
|
| 30 |
|
|
}
|
| 31 |
|
|
@end
|
| 32 |
|
|
|
| 33 |
|
|
int bb[6] = { 0, 1, 2, 3, 4, 5 };
|
| 34 |
|
|
int *b = bb;
|
| 35 |
|
|
Test *cc[4];
|
| 36 |
|
|
Test **c = cc;
|
| 37 |
|
|
|
| 38 |
|
|
int offs1, offs2, offs3, offs4, offs5, offs6;
|
| 39 |
|
|
|
| 40 |
|
|
int main(int argc, char **argv)
|
| 41 |
|
|
{
|
| 42 |
|
|
Class testClass = objc_getClass("Test");
|
| 43 |
|
|
Method meth;
|
| 44 |
|
|
|
| 45 |
|
|
cc[0] = [Test new];
|
| 46 |
|
|
CHECK_IF (bb[3] == 3);
|
| 47 |
|
|
[*c test2: b with: bb + 4];
|
| 48 |
|
|
CHECK_IF (bb[3] == 4);
|
| 49 |
|
|
bb[3] = 0;
|
| 50 |
|
|
[*c test2: bb with: bb + 5];
|
| 51 |
|
|
CHECK_IF (bb[3] == 5);
|
| 52 |
|
|
|
| 53 |
|
|
meth = class_getInstanceMethod(testClass, @selector(test2:with:));
|
| 54 |
|
|
offs1 = offs2 = offs3 = offs4 = offs5 = offs6 = -1;
|
| 55 |
|
|
sscanf(method_getTypeEncoding(meth), "v%d@%d:%d[%di]%d^i%d", &offs1, &offs2, &offs3,
|
| 56 |
|
|
&offs4, &offs5, &offs6);
|
| 57 |
|
|
CHECK_IF (!offs2 && offs4 == 5 && offs3 > 0);
|
| 58 |
|
|
CHECK_IF (offs5 == 2 * offs3 && offs6 == 3 * offs3 && offs1 == 4 * offs3);
|
| 59 |
|
|
|
| 60 |
|
|
meth = class_getInstanceMethod(testClass, @selector(test3:));
|
| 61 |
|
|
offs1 = offs2 = offs3 = offs4 = offs5 = offs6 = -1;
|
| 62 |
|
|
sscanf(method_getTypeEncoding(meth), "v%d@%d:%d[%d[%d{Test=#f}]]%d", &offs1, &offs2, &offs3,
|
| 63 |
|
|
&offs4, &offs5, &offs6);
|
| 64 |
|
|
CHECK_IF (!offs2 && offs4 == 3 && offs5 == 4 && offs3 > 0);
|
| 65 |
|
|
CHECK_IF (offs6 == 2 * offs3 && offs1 == 3 * offs3);
|
| 66 |
|
|
|
| 67 |
|
|
return 0;
|
| 68 |
|
|
}
|