1 /* Area: ffi_call
2 Purpose: Check non-standard complex types.
3 Limitations: none.
4 PR: none.
5 Originator: <vogt@linux.vnet.ibm.com>. */
6
7 /* { dg-do run } */
8
9 #include "ffitest.h"
10 #include "ffi.h"
11 #include <complex.h>
12
f_complex(_Complex int c,int x,int * py)13 _Complex int f_complex(_Complex int c, int x, int *py)
14 {
15 c = -(2 * creal (c)) + (cimag (c) + 1)* I;
16 *py += x;
17
18 return c;
19 }
20
21 /*
22 * This macro can be used to define new complex type descriptors
23 * in a platform independent way.
24 *
25 * name: Name of the new descriptor is ffi_type_complex_<name>.
26 * type: The C base type of the complex type.
27 */
28 #define FFI_COMPLEX_TYPEDEF(name, type, ffitype) \
29 static ffi_type *ffi_elements_complex_##name [2] = { \
30 (ffi_type *)(&ffitype), NULL \
31 }; \
32 struct struct_align_complex_##name { \
33 char c; \
34 _Complex type x; \
35 }; \
36 ffi_type ffi_type_complex_##name = { \
37 sizeof(_Complex type), \
38 offsetof(struct struct_align_complex_##name, x), \
39 FFI_TYPE_COMPLEX, \
40 (ffi_type **)ffi_elements_complex_##name \
41 }
42
43 /* Define new complex type descriptors using the macro: */
44 /* ffi_type_complex_sint */
45 FFI_COMPLEX_TYPEDEF(sint, int, ffi_type_sint);
46 /* ffi_type_complex_uchar */
47 FFI_COMPLEX_TYPEDEF(uchar, unsigned char, ffi_type_uint8);
48
main(void)49 int main (void)
50 {
51 ffi_cif cif;
52 ffi_type *args[MAX_ARGS];
53 void *values[MAX_ARGS];
54
55 _Complex int tc_arg;
56 _Complex int tc_result;
57 int tc_int_arg_x;
58 int tc_y;
59 int *tc_ptr_arg_y = &tc_y;
60
61 args[0] = &ffi_type_complex_sint;
62 args[1] = &ffi_type_sint;
63 args[2] = &ffi_type_pointer;
64 values[0] = &tc_arg;
65 values[1] = &tc_int_arg_x;
66 values[2] = &tc_ptr_arg_y;
67
68 /* Initialize the cif */
69 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3, &ffi_type_complex_sint, args)
70 == FFI_OK);
71
72 tc_arg = 1 + 7 * I;
73 tc_int_arg_x = 1234;
74 tc_y = 9876;
75 ffi_call(&cif, FFI_FN(f_complex), &tc_result, values);
76
77 printf ("%d,%di %d,%di, x %d 1234, y %d 11110\n",
78 (int)tc_result, (int)(tc_result * -I), 2, 8, tc_int_arg_x, tc_y);
79 /* dg-output "-2,8i 2,8i, x 1234 1234, y 11110 11110" */
80 CHECK (creal (tc_result) == -2);
81 CHECK (cimag (tc_result) == 8);
82 CHECK (tc_int_arg_x == 1234);
83 CHECK (*tc_ptr_arg_y == 11110);
84
85 exit(0);
86 }
87