1 /* Area: ffi_call
2 Purpose: Reproduce bug found in python ctypes
3 Limitations: none.
4 PR: Fedora 1174037 */
5
6 /* { dg-do run } */
7 #include "ffitest.h"
8
9 typedef struct {
10 long x;
11 long y;
12 } POINT;
13
14 typedef struct {
15 long left;
16 long top;
17 long right;
18 long bottom;
19 } RECT;
20
pr_test(int i __UNUSED__,RECT ar __UNUSED__,RECT * br __UNUSED__,POINT cp __UNUSED__,RECT dr __UNUSED__,RECT * er __UNUSED__,POINT fp,RECT gr __UNUSED__)21 static RECT ABI_ATTR pr_test(int i __UNUSED__, RECT ar __UNUSED__,
22 RECT* br __UNUSED__, POINT cp __UNUSED__,
23 RECT dr __UNUSED__, RECT *er __UNUSED__,
24 POINT fp, RECT gr __UNUSED__)
25 {
26 RECT result;
27
28 result.left = fp.x;
29 result.right = fp.y;
30 result.top = fp.x;
31 result.bottom = fp.y;
32
33 return result;
34 }
35
main(void)36 int main (void)
37 {
38 ffi_cif cif;
39 ffi_type *args[MAX_ARGS];
40 void *values[MAX_ARGS];
41 ffi_type point_type, rect_type;
42 ffi_type *point_type_elements[3];
43 ffi_type *rect_type_elements[5];
44
45 int i;
46 POINT cp, fp;
47 RECT ar, br, dr, er, gr;
48 RECT *p1, *p2;
49
50 /* This is a hack to get a properly aligned result buffer */
51 RECT *rect_result =
52 (RECT *) malloc (sizeof(RECT));
53
54 point_type.size = 0;
55 point_type.alignment = 0;
56 point_type.type = FFI_TYPE_STRUCT;
57 point_type.elements = point_type_elements;
58 point_type_elements[0] = &ffi_type_slong;
59 point_type_elements[1] = &ffi_type_slong;
60 point_type_elements[2] = NULL;
61
62 rect_type.size = 0;
63 rect_type.alignment = 0;
64 rect_type.type = FFI_TYPE_STRUCT;
65 rect_type.elements = rect_type_elements;
66 rect_type_elements[0] = &ffi_type_slong;
67 rect_type_elements[1] = &ffi_type_slong;
68 rect_type_elements[2] = &ffi_type_slong;
69 rect_type_elements[3] = &ffi_type_slong;
70 rect_type_elements[4] = NULL;
71
72 args[0] = &ffi_type_sint;
73 args[1] = &rect_type;
74 args[2] = &ffi_type_pointer;
75 args[3] = &point_type;
76 args[4] = &rect_type;
77 args[5] = &ffi_type_pointer;
78 args[6] = &point_type;
79 args[7] = &rect_type;
80
81 /* Initialize the cif */
82 CHECK(ffi_prep_cif(&cif, ABI_NUM, 8, &rect_type, args) == FFI_OK);
83
84 i = 1;
85 ar.left = 2;
86 ar.right = 3;
87 ar.top = 4;
88 ar.bottom = 5;
89 br.left = 6;
90 br.right = 7;
91 br.top = 8;
92 br.bottom = 9;
93 cp.x = 10;
94 cp.y = 11;
95 dr.left = 12;
96 dr.right = 13;
97 dr.top = 14;
98 dr.bottom = 15;
99 er.left = 16;
100 er.right = 17;
101 er.top = 18;
102 er.bottom = 19;
103 fp.x = 20;
104 fp.y = 21;
105 gr.left = 22;
106 gr.right = 23;
107 gr.top = 24;
108 gr.bottom = 25;
109
110 values[0] = &i;
111 values[1] = &ar;
112 p1 = &br;
113 values[2] = &p1;
114 values[3] = &cp;
115 values[4] = &dr;
116 p2 = &er;
117 values[5] = &p2;
118 values[6] = &fp;
119 values[7] = &gr;
120
121 ffi_call (&cif, FFI_FN(pr_test), rect_result, values);
122
123 CHECK(rect_result->top == 20);
124
125 free (rect_result);
126 exit(0);
127 }
128