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