OSDN Git Service

2012-06-14 Richard Guenther <rguenther@suse.de>
[pf3gnuchains/gcc-fork.git] / gcc / testsuite / g++.dg / ext / va-arg-pack-1.C
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 }