]>
Commit | Line | Data |
---|---|---|
d1e270fe ZL |
1 | /* 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 <alexander@malmberg.org> */ | |
11 | ||
88b470b8 NP |
12 | #include "../objc-obj-c++-shared/TestsuiteObject.m" |
13 | #include "../objc-obj-c++-shared/runtime.h" | |
d1e270fe ZL |
14 | #include <stdlib.h> |
15 | #include <stdio.h> | |
16 | #define CHECK_IF(expr) if(!(expr)) abort() | |
17 | ||
88b470b8 | 18 | @interface Test : TestsuiteObject |
d1e270fe ZL |
19 | { float j; } |
20 | -(void) test2: (int [5])a with: (int [])b; | |
81dc6eea | 21 | -(id) test3: (Test **)b; /* { dg-message "previous declaration of .\\-\\(id\\)test3:\\(Test \\*\\*\\)b." } */ |
d1e270fe ZL |
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 | { | |
88b470b8 NP |
42 | Class testClass = objc_getClass("Test"); |
43 | Method meth; | |
d1e270fe ZL |
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 | ||
88b470b8 | 53 | meth = class_getInstanceMethod(testClass, @selector(test2:with:)); |
d1e270fe | 54 | offs1 = offs2 = offs3 = offs4 = offs5 = offs6 = -1; |
88b470b8 | 55 | sscanf(method_getTypeEncoding(meth), "v%d@%d:%d[%di]%d^i%d", &offs1, &offs2, &offs3, |
d1e270fe ZL |
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 | ||
88b470b8 | 60 | meth = class_getInstanceMethod(testClass, @selector(test3:)); |
d1e270fe | 61 | offs1 = offs2 = offs3 = offs4 = offs5 = offs6 = -1; |
88b470b8 | 62 | sscanf(method_getTypeEncoding(meth), "v%d@%d:%d[%d[%d{Test=#f}]]%d", &offs1, &offs2, &offs3, |
d1e270fe ZL |
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 | } |