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
foo1(int x,int y,...)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
foo2(int x,int y,...)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
foo3(void)116 foo3 (void)
117 {
118   return 6;
119 }
120 
121 extern inline __attribute__ ((always_inline, gnu_inline)) int
bar(int x,...)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
main(void)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 }
144