modernc.org/ccgo/v3@v3.16.14/lib/testdata/gcc-9.1.0/gcc/testsuite/gcc.c-torture/execute/va-arg-pack-1.c (about)

     1  /* __builtin_va_arg_pack () builtin tests.  */
     2  
     3  #include <stdarg.h>
     4  
     5  extern void abort (void);
     6  
     7  int v1 = 8;
     8  long int v2 = 3;
     9  void *v3 = (void *) &v2;
    10  struct A { char c[16]; } v4 = { "foo" };
    11  long double v5 = 40;
    12  char seen[20];
    13  int cnt;
    14  
    15  __attribute__ ((noinline)) int
    16  foo1 (int x, int y, ...)
    17  {
    18    int i;
    19    long int l;
    20    void *v;
    21    struct A a;
    22    long double ld;
    23    va_list ap;
    24  
    25    va_start (ap, y);
    26    if (x < 0 || x >= 20 || seen[x])
    27      abort ();
    28    seen[x] = ++cnt;
    29    if (y != 6)
    30      abort ();
    31    i = va_arg (ap, int);
    32    if (i != 5)
    33      abort ();
    34    switch (x)
    35      {
    36      case 0:
    37        i = va_arg (ap, int);
    38        if (i != 9 || v1 != 9)
    39  	abort ();
    40        a = va_arg (ap, struct A);
    41        if (__builtin_memcmp (a.c, v4.c, sizeof (a.c)) != 0)
    42  	abort ();
    43        v = (void *) va_arg (ap, struct A *);
    44        if (v != (void *) &v4)
    45  	abort ();
    46        l = va_arg (ap, long int);
    47        if (l != 3 || v2 != 4)
    48  	abort ();
    49        break;
    50      case 1:
    51        ld = va_arg (ap, long double);
    52        if (ld != 41 || v5 != ld)
    53  	abort ();
    54        i = va_arg (ap, int);
    55        if (i != 8)
    56  	abort ();
    57        v = va_arg (ap, void *);
    58        if (v != &v2)
    59  	abort ();
    60        break;
    61      case 2:
    62        break;
    63      default:
    64        abort ();
    65      }
    66    va_end (ap);
    67    return x;
    68  }
    69  
    70  __attribute__ ((noinline)) int
    71  foo2 (int x, int y, ...)
    72  {
    73    long long int ll;
    74    void *v;
    75    struct A a, b;
    76    long double ld;
    77    va_list ap;
    78  
    79    va_start (ap, y);
    80    if (x < 0 || x >= 20 || seen[x])
    81      abort ();
    82    seen[x] = ++cnt | 64;
    83    if (y != 10)
    84      abort ();
    85    switch (x)
    86      {
    87      case 11:
    88        break;
    89      case 12:
    90        ld = va_arg (ap, long double);
    91        if (ld != 41 || v5 != 40)
    92  	abort ();
    93        a = va_arg (ap, struct A);
    94        if (__builtin_memcmp (a.c, v4.c, sizeof (a.c)) != 0)
    95  	abort ();
    96        b = va_arg (ap, struct A);
    97        if (__builtin_memcmp (b.c, v4.c, sizeof (b.c)) != 0)
    98  	abort ();
    99        v = va_arg (ap, void *);
   100        if (v != &v2)
   101  	abort ();
   102        ll = va_arg (ap, long long int);
   103        if (ll != 16LL)
   104  	abort ();
   105        break;
   106      case 2:
   107        break;
   108      default:
   109        abort ();
   110      }
   111    va_end (ap);
   112    return x + 8;
   113  }
   114  
   115  __attribute__ ((noinline)) int
   116  foo3 (void)
   117  {
   118    return 6;
   119  }
   120  
   121  extern inline __attribute__ ((always_inline, gnu_inline)) int
   122  bar (int x, ...)
   123  {
   124    if (x < 10)
   125      return foo1 (x, foo3 (), 5, __builtin_va_arg_pack ());
   126    return foo2 (x, foo3 () + 4, __builtin_va_arg_pack ());
   127  }
   128  
   129  int
   130  main (void)
   131  {
   132    if (bar (0, ++v1, v4, &v4, v2++) != 0)
   133      abort ();
   134    if (bar (1, ++v5, 8, v3) != 1)
   135      abort ();
   136    if (bar (2) != 2)
   137      abort ();
   138    if (bar (v1 + 2) != 19)
   139      abort ();
   140    if (bar (v1 + 3, v5--, v4, v4, v3, 16LL) != 20)
   141      abort ();
   142    return 0;
   143  }