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