1  #include <stdarg.h>
       2  
       3  extern void abort (void);
       4  
       5  int foo_arg, bar_arg;
       6  long x;
       7  double d;
       8  va_list gap;
       9  
      10  void
      11  foo (int v, va_list ap)
      12  {
      13    switch (v)
      14      {
      15      case 5:
      16        foo_arg = va_arg (ap, int);
      17        foo_arg += va_arg (ap, double);
      18        foo_arg += va_arg (ap, long long);
      19        break;
      20      case 8:
      21        foo_arg = va_arg (ap, long long);
      22        foo_arg += va_arg (ap, double);
      23        break;
      24      case 11:
      25        foo_arg = va_arg (ap, int);
      26        foo_arg += va_arg (ap, long double);
      27        break;
      28      default:
      29        abort ();
      30      }
      31  }
      32  
      33  void
      34  bar (int v)
      35  {
      36    if (v == 0x4002)
      37      {
      38        if (va_arg (gap, int) != 13 || va_arg (gap, double) != -14.0)
      39  	abort ();
      40      }
      41    bar_arg = v;
      42  }
      43  
      44  void
      45  f1 (int i, ...)
      46  {
      47    va_start (gap, i);
      48    x = va_arg (gap, long);
      49    va_end (gap);
      50  }
      51  
      52  void
      53  f2 (int i, ...)
      54  {
      55    va_start (gap, i);
      56    bar (i);
      57    va_end (gap);
      58  }
      59  
      60  void
      61  f3 (int i, ...)
      62  {
      63    va_list aps[10];
      64    va_start (aps[4], i);
      65    x = va_arg (aps[4], long);
      66    va_end (aps[4]);
      67  }
      68  
      69  void
      70  f4 (int i, ...)
      71  {
      72    va_list aps[10];
      73    va_start (aps[4], i);
      74    bar (i);
      75    va_end (aps[4]);
      76  }
      77  
      78  void
      79  f5 (int i, ...)
      80  {
      81    va_list aps[10];
      82    va_start (aps[4], i);
      83    foo (i, aps[4]);
      84    va_end (aps[4]);
      85  }
      86  
      87  struct A { int i; va_list g; va_list h[2]; };
      88  
      89  void
      90  f6 (int i, ...)
      91  {
      92    struct A a;
      93    va_start (a.g, i);
      94    x = va_arg (a.g, long);
      95    va_end (a.g);
      96  }
      97  
      98  void
      99  f7 (int i, ...)
     100  {
     101    struct A a;
     102    va_start (a.g, i);
     103    bar (i);
     104    va_end (a.g);
     105  }
     106  
     107  void
     108  f8 (int i, ...)
     109  {
     110    struct A a;
     111    va_start (a.g, i);
     112    foo (i, a.g);
     113    va_end (a.g);
     114  }
     115  
     116  void
     117  f10 (int i, ...)
     118  {
     119    struct A a;
     120    va_start (a.h[1], i);
     121    x = va_arg (a.h[1], long);
     122    va_end (a.h[1]);
     123  }
     124  
     125  void
     126  f11 (int i, ...)
     127  {
     128    struct A a;
     129    va_start (a.h[1], i);
     130    bar (i);
     131    va_end (a.h[1]);
     132  }
     133  
     134  void
     135  f12 (int i, ...)
     136  {
     137    struct A a;
     138    va_start (a.h[1], i);
     139    foo (i, a.h[1]);
     140    va_end (a.h[1]);
     141  }
     142  
     143  int
     144  main (void)
     145  {
     146    f1 (1, 79L);
     147    if (x != 79L)
     148      abort ();
     149    f2 (0x4002, 13, -14.0);
     150    if (bar_arg != 0x4002)
     151      abort ();
     152    f3 (3, 2031L);
     153    if (x != 2031)
     154      abort ();
     155    f4 (4, 18);
     156    if (bar_arg != 4)
     157      abort ();
     158    f5 (5, 1, 19.0, 18LL);
     159    if (foo_arg != 38)
     160      abort ();
     161    f6 (6, 18L);
     162    if (x != 18L)
     163      abort ();
     164    f7 (7);
     165    if (bar_arg != 7)
     166      abort ();
     167    f8 (8, 2031LL, 13.0);
     168    if (foo_arg != 2044)
     169      abort ();
     170    f10 (9, 180L);
     171    if (x != 180L)
     172      abort ();
     173    f11 (10);
     174    if (bar_arg != 10)
     175      abort ();
     176    f12 (11, 2030, 12.0L);
     177    if (foo_arg != 2042)
     178      abort ();
     179    return 0;
     180  }