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  va_list *pap;
      10  
      11  void
      12  foo (int v, va_list ap)
      13  {
      14    switch (v)
      15      {
      16      case 5: foo_arg = va_arg (ap, int); break;
      17      default: abort ();
      18      }
      19  }
      20  
      21  void
      22  bar (int v)
      23  {
      24    if (v == 0x4006)
      25      {
      26        if (va_arg (gap, double) != 17.0
      27  	  || va_arg (gap, long) != 129L)
      28  	abort ();
      29      }
      30    else if (v == 0x4008)
      31      {
      32        if (va_arg (*pap, long long) != 14LL
      33  	  || va_arg (*pap, long double) != 131.0L
      34  	  || va_arg (*pap, int) != 17)
      35  	abort ();
      36      }
      37    bar_arg = v;
      38  }
      39  
      40  void
      41  f0 (int i, ...)
      42  {
      43  }
      44  
      45  void
      46  f1 (int i, ...)
      47  {
      48    va_list ap;
      49    va_start (ap, i);
      50    va_end (ap);
      51  }
      52  
      53  void
      54  f2 (int i, ...)
      55  {
      56    va_list ap;
      57    va_start (ap, i);
      58    bar (d);
      59    x = va_arg (ap, long);
      60    bar (x);
      61    va_end (ap);
      62  }
      63  
      64  void
      65  f3 (int i, ...)
      66  {
      67    va_list ap;
      68    va_start (ap, i);
      69    d = va_arg (ap, double);
      70    va_end (ap);
      71  }
      72  
      73  void
      74  f4 (int i, ...)
      75  {
      76    va_list ap;
      77    va_start (ap, i);
      78    x = va_arg (ap, double);
      79    foo (i, ap);
      80    va_end (ap);
      81  }
      82  
      83  void
      84  f5 (int i, ...)
      85  {
      86    va_list ap;
      87    va_start (ap, i);
      88    va_copy (gap, ap);
      89    bar (i);
      90    va_end (ap);
      91    va_end (gap);
      92  }
      93  
      94  void
      95  f6 (int i, ...)
      96  {
      97    va_list ap;
      98    va_start (ap, i);
      99    bar (d);
     100    va_arg (ap, long);
     101    va_arg (ap, long);
     102    x = va_arg (ap, long);
     103    bar (x);
     104    va_end (ap);
     105  }
     106  
     107  void
     108  f7 (int i, ...)
     109  {
     110    va_list ap;
     111    va_start (ap, i);
     112    pap = ≈
     113    bar (i);
     114    va_end (ap);
     115  }
     116  
     117  void
     118  f8 (int i, ...)
     119  {
     120    va_list ap;
     121    va_start (ap, i);
     122    pap = ≈
     123    bar (i);
     124    d = va_arg (ap, double);
     125    va_end (ap);
     126  }
     127  
     128  int
     129  main (void)
     130  {
     131    f0 (1);
     132    f1 (2);
     133    d = 31.0;
     134    f2 (3, 28L);
     135    if (bar_arg != 28 || x != 28)
     136      abort ();
     137    f3 (4, 131.0);
     138    if (d != 131.0)
     139      abort ();
     140    f4 (5, 16.0, 128);
     141    if (x != 16 || foo_arg != 128)
     142      abort ();
     143    f5 (0x4006, 17.0, 129L);
     144    if (bar_arg != 0x4006)
     145      abort ();
     146    f6 (7, 12L, 14L, -31L);
     147    if (bar_arg != -31)
     148      abort ();
     149    f7 (0x4008, 14LL, 131.0L, 17, 26.0);
     150    if (bar_arg != 0x4008)
     151      abort ();
     152    f8 (0x4008, 14LL, 131.0L, 17, 27.0);
     153    if (bar_arg != 0x4008 || d != 27.0)
     154      abort ();
     155    return 0;
     156  }