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