1 /* This test has architecture specific function passing details.  */
2 /* { dg-do compile } */
3 /* { dg-options "-O2 -fdump-tree-stdarg" } */
4 
5 #include <stdarg.h>
6 
7 extern void foo (int, va_list);
8 extern void bar (int);
9 struct S1 { int i; double d; int j; double e; } s1;
10 struct S2 { double d; long i; } s2;
11 int y;
12 _Complex int ci;
13 _Complex double cd;
14 
15 /* Here va_arg can be executed more than once for one va_start.  */
16 void
f1(int i,...)17 f1 (int i, ...)
18 {
19   va_list ap;
20   va_start (ap, i);
21   while (i-- > 0)
22     s1 = va_arg (ap, struct S1);
23   va_end (ap);
24 }
25 /* { dg-final { scan-tree-dump "f1: va_list escapes 0, needs to save 0 GPR units and 0 FPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && { ! { ia32 || llp64 } } } } } } */
26 /* { dg-final { scan-tree-dump "f1: va_list escapes 0, needs to save all GPR units and 1" "stdarg" { target alpha*-*-linux* } } } */
27 /* { dg-final { scan-tree-dump "f1: va_list escapes 0, needs to save all GPR units and 0 FPR units" "stdarg" { target s390*-*-linux* } } } */
28 
29 void
f2(int i,...)30 f2 (int i, ...)
31 {
32   va_list ap;
33   va_start (ap, i);
34   while (i-- > 0)
35     s2 = va_arg (ap, struct S2);
36   va_end (ap);
37 }
38 /* { dg-final { scan-tree-dump "f2: va_list escapes 0, needs to save all GPR units and all FPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && { ! { ia32 || llp64 } } } } } } */
39 /* { dg-final { scan-tree-dump "f2: va_list escapes 0, needs to save all GPR units and 1" "stdarg" { target alpha*-*-linux* } } } */
40 /* { dg-final { scan-tree-dump "f2: va_list escapes 0, needs to save all GPR units and 0 FPR units" "stdarg" { target s390*-*-linux* } } } */
41 
42 /* Here va_arg can be executed at most as many times as va_start.  */
43 void
f3(int i,...)44 f3 (int i, ...)
45 {
46   va_list ap;
47   int j = i;
48   while (j-- > 0)
49     {
50       va_start (ap, i);
51       s1 = va_arg (ap, struct S1);
52       va_end (ap);
53       bar (s1.i);
54     }
55 }
56 /* { dg-final { scan-tree-dump "f3: va_list escapes 0, needs to save 0 GPR units and 0 FPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && { ! { ia32 || llp64 } } } } } } */
57 /* { dg-final { scan-tree-dump "f3: va_list escapes 0, needs to save 32 GPR units and 1" "stdarg" { target alpha*-*-linux* } } } */
58 /* { dg-final { scan-tree-dump "f3: va_list escapes 0, needs to save 1 GPR units and 0 FPR units" "stdarg" { target s390*-*-linux* } } } */
59 
60 void
f4(int i,...)61 f4 (int i, ...)
62 {
63   va_list ap;
64   int j = i;
65   while (j-- > 0)
66     {
67       va_start (ap, i);
68       s2 = va_arg (ap, struct S2);
69       y = va_arg (ap, int);
70       va_end (ap);
71       bar (s2.i);
72     }
73 }
74 /* { dg-final { scan-tree-dump "f4: va_list escapes 0, needs to save 16 GPR units and 16 FPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && { ! { ia32 || llp64 } } } } } } */
75 /* { dg-final { scan-tree-dump "f4: va_list escapes 0, needs to save 24 GPR units and 1" "stdarg" { target alpha*-*-linux* } } } */
76 /* { dg-final { scan-tree-dump "f4: va_list escapes 0, needs to save 2 GPR units and 0 FPR units" "stdarg" { target s390*-*-linux* } } } */
77 
78 void
f5(int i,...)79 f5 (int i, ...)
80 {
81   va_list ap;
82   va_start (ap, i);
83   ci = va_arg (ap, _Complex int);
84   ci += va_arg (ap, _Complex int);
85   va_end (ap);
86   bar (__real__ ci + __imag__ ci);
87 }
88 /* { dg-final { scan-tree-dump "f5: va_list escapes 0, needs to save 16 GPR units and 0 FPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && { ! { ia32 || llp64 } } } } } } */
89 /* { dg-final { scan-tree-dump "f5: va_list escapes 0, needs to save 32 GPR units and 1" "stdarg" { target alpha*-*-linux* } } } */
90 /* { dg-final { scan-tree-dump "f5: va_list escapes 0, needs to save (4|2) GPR units and 0 FPR units" "stdarg" { target s390*-*-linux* } } } */
91 
92 void
f6(int i,...)93 f6 (int i, ...)
94 {
95   va_list ap;
96   va_start (ap, i);
97   ci = va_arg (ap, _Complex int);
98   cd = va_arg (ap, _Complex double);
99   va_end (ap);
100   bar (__real__ ci + __imag__ cd);
101 }
102 /* { dg-final { scan-tree-dump "f6: va_list escapes 0, needs to save 8 GPR units and 32 FPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && { ! { ia32 || llp64 } } } } } } */
103 /* { dg-final { scan-tree-dump "f6: va_list escapes 0, needs to save 32 GPR units and 3" "stdarg" { target alpha*-*-linux* } } } */
104 /* { dg-final { scan-tree-dump "f6: va_list escapes 0, needs to save (3|2) GPR units and 0 FPR units" "stdarg" { target s390*-*-linux* } } } */
105 
106 void
f7(int i,...)107 f7 (int i, ...)
108 {
109   va_list ap;
110   va_start (ap, i);
111   cd = va_arg (ap, _Complex double);
112   cd += va_arg (ap, _Complex double);
113   va_end (ap);
114   bar (__real__ cd + __imag__ cd);
115 }
116 /* { dg-final { scan-tree-dump "f7: va_list escapes 0, needs to save 0 GPR units and 64 FPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && { ! { ia32 || llp64 } } } } } } */
117 /* { dg-final { scan-tree-dump "f7: va_list escapes 0, needs to save 32 GPR units and 2" "stdarg" { target alpha*-*-linux* } } } */
118 /* { dg-final { scan-tree-dump "f7: va_list escapes 0, needs to save 2 GPR units and 0 FPR units" "stdarg" { target s390*-*-linux* } } } */
119 /* { dg-final { cleanup-tree-dump "stdarg" } } */
120