Hash :
de95947a
Author :
Date :
2022-05-24T03:04:43
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
/* Area: ffi_call
Purpose: Test function with multiple fixed args and variable argument list.
Limitations: none.
PR: none.
Originator: ARM Ltd., Oracle */
/* { dg-do run } */
/* { dg-output "" { xfail avr32*-*-* m68k-*-* } } */
#include "ffitest.h"
#include <stdarg.h>
/*
* This is a modified version of va_2.c that has fixed arguments with "small" types that
* are not allowed as variable arguments, but they should be still allowed as fixed args.
*/
static int
test_fn (char a1, float a2, int n, ...)
{
va_list ap;
unsigned char uc;
signed char sc;
unsigned short us;
signed short ss;
unsigned int ui;
signed int si;
unsigned long ul;
signed long sl;
float f;
double d;
va_start (ap, n);
uc = va_arg (ap, unsigned);
sc = va_arg (ap, signed);
us = va_arg (ap, unsigned);
ss = va_arg (ap, signed);
ui = va_arg (ap, unsigned int);
si = va_arg (ap, signed int);
ul = va_arg (ap, unsigned long);
sl = va_arg (ap, signed long);
f = va_arg (ap, double); /* C standard promotes float->double
when anonymous */
d = va_arg (ap, double);
printf ("%d %f uc=%u sc=%d %u %d %u %d %lu %ld %f %f\n",
a1, a2,
uc, sc,
us, ss,
ui, si,
ul, sl,
f, d);
va_end (ap);
CHECK(a1 == 1);
CHECK((int)a2 == 2);
CHECK(uc == 9);
CHECK(sc == 10);
CHECK(us == 11);
CHECK(ss == 12);
CHECK(ui == 13);
CHECK(si == 14);
CHECK(ul == 15);
CHECK(sl == 16);
CHECK((int)f == 2);
CHECK((int)d == 3);
return n + 1;
}
int
main (void)
{
ffi_cif cif;
void* args[14];
ffi_type* arg_types[14];
char a1;
float a2;
int n;
ffi_arg res;
unsigned int uc;
signed int sc;
unsigned int us;
signed int ss;
unsigned int ui;
signed int si;
unsigned long ul;
signed long sl;
double d1;
double f1;
arg_types[0] = &ffi_type_schar;
arg_types[1] = &ffi_type_float;
arg_types[2] = &ffi_type_sint;
arg_types[3] = &ffi_type_uint;
arg_types[4] = &ffi_type_sint;
arg_types[5] = &ffi_type_uint;
arg_types[6] = &ffi_type_sint;
arg_types[7] = &ffi_type_uint;
arg_types[8] = &ffi_type_sint;
arg_types[9] = &ffi_type_ulong;
arg_types[10] = &ffi_type_slong;
arg_types[11] = &ffi_type_double;
arg_types[12] = &ffi_type_double;
arg_types[13] = NULL;
CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 3, 13, &ffi_type_sint, arg_types) == FFI_OK);
a1 = 1;
a2 = 2.0f;
n = 41;
uc = 9;
sc = 10;
us = 11;
ss = 12;
ui = 13;
si = 14;
ul = 15;
sl = 16;
f1 = 2.12;
d1 = 3.13;
args[0] = &a1;
args[1] = &a2;
args[2] = &n;
args[3] = &uc;
args[4] = ≻
args[5] = &us;
args[6] = &ss;
args[7] = &ui;
args[8] = &si;
args[9] = &ul;
args[10] = &sl;
args[11] = &f1;
args[12] = &d1;
args[13] = NULL;
ffi_call(&cif, FFI_FN(test_fn), &res, args);
/* { dg-output "1 2.000000 uc=9 sc=10 11 12 13 14 15 16 2.120000 3.130000" } */
printf("res: %d\n", (int) res);
/* { dg-output "\nres: 42" } */
CHECK(res == 42);
return 0;
}