cls_many_mixed_args.c 1.7 KB

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