1 /* Area: closure_call 2 Purpose: Check closures called with many args of mixed types 3 Limitations: none. 4 PR: none. 5 Originator: <david.schneider (at) picle.org> */ 6 7 /* { dg-do run } */ 8 #include "ffitest.h" 9 #include <float.h> 10 #include <math.h> 11 12 #define NARGS 16 13 14 static void cls_ret_double_fn(ffi_cif* cif __UNUSED__, void* resp, void** args, 15 void* userdata __UNUSED__) 16 { 17 int i; 18 double r = 0; 19 double t; 20 for(i = 0; i < NARGS; i++) 21 { 22 if(i == 4 || i == 9 || i == 11 || i == 13 || i == 15) 23 { 24 t = *(long int *)args[i]; 25 CHECK(t == i+1); 26 } 27 else 28 { 29 t = *(double *)args[i]; 30 CHECK(fabs(t - ((i+1) * 0.1)) < FLT_EPSILON); 31 } 32 r += t; 33 } 34 *(double *)resp = r; 35 } 36 typedef double (*cls_ret_double)(double, double, double, double, long int, 37 double, double, double, double, long int, double, long int, double, long int, 38 double, long int); 39 40 int main (void) 41 { 42 ffi_cif cif; 43 void *code; 44 ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); 45 ffi_type * cl_arg_types[NARGS]; 46 double res; 47 int i; 48 double expected = 64.9; 49 50 for(i = 0; i < NARGS; i++) 51 { 52 if(i == 4 || i == 9 || i == 11 || i == 13 || i == 15) 53 cl_arg_types[i] = &ffi_type_slong; 54 else 55 cl_arg_types[i] = &ffi_type_double; 56 } 57 58 /* Initialize the cif */ 59 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, NARGS, 60 &ffi_type_double, cl_arg_types) == FFI_OK); 61 62 CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_double_fn, NULL, code) == FFI_OK); 63 64 res = (((cls_ret_double)code))(0.1, 0.2, 0.3, 0.4, 5, 0.6, 0.7, 0.8, 0.9, 10, 65 1.1, 12, 1.3, 14, 1.5, 16); 66 if (abs(res - expected) < FLT_EPSILON) 67 exit(0); 68 else 69 abort(); 70 } 71