va_struct1.c 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. /* Area: ffi_call
  2. Purpose: Test passing struct in variable argument lists.
  3. Limitations: none.
  4. PR: none.
  5. Originator: ARM Ltd. */
  6. /* { dg-do run } */
  7. /* { dg-output "" { xfail avr32*-*-* } } */
  8. #include "ffitest.h"
  9. #include <stdarg.h>
  10. struct small_tag
  11. {
  12. unsigned char a;
  13. unsigned char b;
  14. };
  15. struct large_tag
  16. {
  17. unsigned a;
  18. unsigned b;
  19. unsigned c;
  20. unsigned d;
  21. unsigned e;
  22. };
  23. static int
  24. test_fn (int n, ...)
  25. {
  26. va_list ap;
  27. struct small_tag s1;
  28. struct small_tag s2;
  29. struct large_tag l;
  30. va_start (ap, n);
  31. s1 = va_arg (ap, struct small_tag);
  32. l = va_arg (ap, struct large_tag);
  33. s2 = va_arg (ap, struct small_tag);
  34. printf ("%u %u %u %u %u %u %u %u %u\n", s1.a, s1.b, l.a, l.b, l.c, l.d, l.e,
  35. s2.a, s2.b);
  36. va_end (ap);
  37. return n + 1;
  38. }
  39. int
  40. main (void)
  41. {
  42. ffi_cif cif;
  43. void* args[5];
  44. ffi_type* arg_types[5];
  45. ffi_type s_type;
  46. ffi_type *s_type_elements[3];
  47. ffi_type l_type;
  48. ffi_type *l_type_elements[6];
  49. struct small_tag s1;
  50. struct small_tag s2;
  51. struct large_tag l1;
  52. int n;
  53. ffi_arg res;
  54. s_type.size = 0;
  55. s_type.alignment = 0;
  56. s_type.type = FFI_TYPE_STRUCT;
  57. s_type.elements = s_type_elements;
  58. s_type_elements[0] = &ffi_type_uchar;
  59. s_type_elements[1] = &ffi_type_uchar;
  60. s_type_elements[2] = NULL;
  61. l_type.size = 0;
  62. l_type.alignment = 0;
  63. l_type.type = FFI_TYPE_STRUCT;
  64. l_type.elements = l_type_elements;
  65. l_type_elements[0] = &ffi_type_uint;
  66. l_type_elements[1] = &ffi_type_uint;
  67. l_type_elements[2] = &ffi_type_uint;
  68. l_type_elements[3] = &ffi_type_uint;
  69. l_type_elements[4] = &ffi_type_uint;
  70. l_type_elements[5] = NULL;
  71. arg_types[0] = &ffi_type_sint;
  72. arg_types[1] = &s_type;
  73. arg_types[2] = &l_type;
  74. arg_types[3] = &s_type;
  75. arg_types[4] = NULL;
  76. CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 4, &ffi_type_sint, arg_types) == FFI_OK);
  77. s1.a = 5;
  78. s1.b = 6;
  79. l1.a = 10;
  80. l1.b = 11;
  81. l1.c = 12;
  82. l1.d = 13;
  83. l1.e = 14;
  84. s2.a = 7;
  85. s2.b = 8;
  86. n = 41;
  87. args[0] = &n;
  88. args[1] = &s1;
  89. args[2] = &l1;
  90. args[3] = &s2;
  91. args[4] = NULL;
  92. ffi_call(&cif, FFI_FN(test_fn), &res, args);
  93. /* { dg-output "5 6 10 11 12 13 14 7 8" } */
  94. printf("res: %d\n", (int) res);
  95. /* { dg-output "\nres: 42" } */
  96. return 0;
  97. }