1  /* PR tree-optimization/56205 */
       2  
       3  #include <stdarg.h>
       4  
       5  int a, b;
       6  char c[128];
       7  
       8  __attribute__((noinline, noclone)) static void
       9  f1 (const char *fmt, ...)
      10  {
      11    va_list ap;
      12    asm volatile ("" : : : "memory");
      13    if (__builtin_strcmp (fmt, "%s %d %s") != 0)
      14      __builtin_abort ();
      15    va_start (ap, fmt);
      16    if (__builtin_strcmp (va_arg (ap, const char *), "foo") != 0
      17        || va_arg (ap, int) != 1
      18        || __builtin_strcmp (va_arg (ap, const char *), "bar") != 0)
      19      __builtin_abort ();
      20    va_end (ap);
      21  }
      22  
      23  __attribute__((noinline, noclone)) static void
      24  f2 (const char *fmt, va_list ap)
      25  {
      26    asm volatile ("" : : : "memory");
      27    if (__builtin_strcmp (fmt, "baz") != 0
      28        || __builtin_strcmp (va_arg (ap, const char *), "foo") != 0
      29        || va_arg (ap, double) != 12.0
      30        || va_arg (ap, int) != 26)
      31      __builtin_abort ();
      32  }
      33  
      34  static void
      35  f3 (int x, char const *y, va_list z)
      36  {
      37    f1 ("%s %d %s", x ? "" : "foo", ++a, (y && *y) ? "bar" : "");
      38    if (y && *y)
      39      f2 (y, z);
      40  }
      41  
      42  __attribute__((noinline, noclone)) void
      43  f4 (int x, char const *y, ...)
      44  {
      45    va_list z;
      46    va_start (z, y);
      47    if (!x && *c == '\0')
      48      ++b;
      49    f3 (x, y, z);
      50    va_end (z);
      51  }
      52  
      53  int
      54  main ()
      55  {
      56    asm volatile ("" : : : "memory");
      57    f4 (0, "baz", "foo", 12.0, 26);
      58    if (a != 1 || b != 1)
      59      __builtin_abort ();
      60    return 0;
      61  }