/* Simple test of vararg passing for problematic types with and without double values passed between them. */ #include #ifdef DBG #include #endif extern void abort (void); int failcnt; DTYPE a[10]; double b[10]; union U { DTYPE d; unsigned int i[INTS]; }; void compare (double r, double s, int *p, int *q, int n, int line) { int i; for (i = 0; i < n; i++) if (r != s || p[i] != q[i]) #ifdef DBG { int j; printf ("line %-3d", line); for (j = 0; j < n; j++) printf (" %08x", p[j]); printf (" %10.2g\n ", r); for (j = 0; j < n; j++) printf (" %08x", q[j]); printf (" %10.2g\n\n", s); return; } #else abort (); #endif } void bar0 (int n, ...) { union U u; int j; va_list ap; va_start (ap, n); for (j = 0; j < n; j++) a[j] = va_arg (ap, DTYPE); va_end (ap); } void bar1 (int n, ...) { union U u; int j; va_list ap; va_start (ap, n); for (j = 0; j < n; j++) { a[j] = va_arg (ap, DTYPE); b[j] = va_arg (ap, double); } va_end (ap); } void bar2 (int n, ...) { union U u; int j; va_list ap; va_start (ap, n); for (j = 0; j < n; j++) { b[j] = va_arg (ap, double); a[j] = va_arg (ap, DTYPE); } va_end (ap); } void doit () { DTYPE x, y, z; union U u1, u2; /* Sanity check that test setup is right, especially for long double which can be changed by command line option. */ if (INTS * 4 != sizeof (DTYPE)) { #ifdef DBG printf ("test error: INTS = %d, sizeof (DTYPE) = %d\n", INTS, sizeof (DTYPE)); #endif abort (); } x = ONE / THREE; y = ONE / SEVEN; z = ONE / ELEVEN; bar0 (1, x); u1.d = x; u2.d = a[0]; compare (0.0, 0.0, u1.i, u2.i, INTS, __LINE__); bar0 (2, x, y); u1.d = x; u2.d = a[0]; compare (0.0, 0.0, u1.i, u2.i, INTS, __LINE__); u1.d = y; u2.d = a[1]; compare (0.0, 0.0, u1.i, u2.i, INTS, __LINE__); bar0 (3, x, y, z); u1.d = x; u2.d = a[0]; compare (0.0, 0.0, u1.i, u2.i, INTS, __LINE__); u1.d = y; u2.d = a[1]; compare (0.0, 0.0, u1.i, u2.i, INTS, __LINE__); u1.d = z; u2.d = a[2]; compare (0.0, 0.0, u1.i, u2.i, INTS, __LINE__); bar1 (1, x, 1.5); u1.d = x; u2.d = a[0]; compare (1.5, b[0], u1.i, u2.i, INTS, __LINE__); bar1 (2, x, 1.5, y, 2.5); u1.d = x; u2.d = a[0]; compare (1.5, b[0], u1.i, u2.i, INTS, __LINE__); u1.d = y; u2.d = a[1]; compare (2.5, b[1], u1.i, u2.i, INTS, __LINE__); bar1 (3, x, 1.5, y, 2.5, z, 3.5); u1.d = x; u2.d = a[0]; compare (1.5, b[0], u1.i, u2.i, INTS, __LINE__); u1.d = y; u2.d = a[1]; compare (2.5, b[1], u1.i, u2.i, INTS, __LINE__); u1.d = z; u2.d = a[2]; compare (3.5, b[2], u1.i, u2.i, INTS, __LINE__); bar2 (1, 1.5, x); u1.d = x; u2.d = a[0]; compare (1.5, b[0], u1.i, u2.i, INTS, __LINE__); bar2 (2, 1.5, x, 2.5, y); u1.d = x; u2.d = a[0]; compare (1.5, b[0], u1.i, u2.i, INTS, __LINE__); u1.d = y; u2.d = a[1]; compare (2.5, b[1], u1.i, u2.i, INTS, __LINE__); bar2 (3, 1.5, x, 2.5, y, 3.5, z); u1.d = x; u2.d = a[0]; compare (1.5, b[0], u1.i, u2.i, INTS, __LINE__); u1.d = y; u2.d = a[1]; compare (2.5, b[1], u1.i, u2.i, INTS, __LINE__); u1.d = z; u2.d = a[2]; compare (3.5, b[2], u1.i, u2.i, INTS, __LINE__); if (failcnt != 0) abort (); }