va_struct2.c 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  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 struct small_tag
  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. s1.a += s2.a;
  38. s1.b += s2.b;
  39. return s1;
  40. }
  41. int
  42. main (void)
  43. {
  44. ffi_cif cif;
  45. void* args[5];
  46. ffi_type* arg_types[5];
  47. ffi_type s_type;
  48. ffi_type *s_type_elements[3];
  49. ffi_type l_type;
  50. ffi_type *l_type_elements[6];
  51. struct small_tag s1;
  52. struct small_tag s2;
  53. struct large_tag l1;
  54. int n;
  55. struct small_tag res;
  56. s_type.size = 0;
  57. s_type.alignment = 0;
  58. s_type.type = FFI_TYPE_STRUCT;
  59. s_type.elements = s_type_elements;
  60. s_type_elements[0] = &ffi_type_uchar;
  61. s_type_elements[1] = &ffi_type_uchar;
  62. s_type_elements[2] = NULL;
  63. l_type.size = 0;
  64. l_type.alignment = 0;
  65. l_type.type = FFI_TYPE_STRUCT;
  66. l_type.elements = l_type_elements;
  67. l_type_elements[0] = &ffi_type_uint;
  68. l_type_elements[1] = &ffi_type_uint;
  69. l_type_elements[2] = &ffi_type_uint;
  70. l_type_elements[3] = &ffi_type_uint;
  71. l_type_elements[4] = &ffi_type_uint;
  72. l_type_elements[5] = NULL;
  73. arg_types[0] = &ffi_type_sint;
  74. arg_types[1] = &s_type;
  75. arg_types[2] = &l_type;
  76. arg_types[3] = &s_type;
  77. arg_types[4] = NULL;
  78. CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 4, &s_type, arg_types) == FFI_OK);
  79. s1.a = 5;
  80. s1.b = 6;
  81. l1.a = 10;
  82. l1.b = 11;
  83. l1.c = 12;
  84. l1.d = 13;
  85. l1.e = 14;
  86. s2.a = 7;
  87. s2.b = 8;
  88. n = 41;
  89. args[0] = &n;
  90. args[1] = &s1;
  91. args[2] = &l1;
  92. args[3] = &s2;
  93. args[4] = NULL;
  94. ffi_call(&cif, FFI_FN(test_fn), &res, args);
  95. /* { dg-output "5 6 10 11 12 13 14 7 8" } */
  96. printf("res: %d %d\n", res.a, res.b);
  97. /* { dg-output "\nres: 12 14" } */
  98. return 0;
  99. }