1 /*
2    stdarg-4.c from the execute part of the gcc torture tests.
3  */
4 
5 #include <testfwk.h>
6 
7 #pragma disable_warning 93 // Using float for double.
8 
9 #include <stdarg.h>
10 
11 #if !defined(__SDCC_pdk14) && !defined(__SDCC_pdk15) // Lack of memory
12 long x, y;
13 
14 void
f1i(va_list ap)15 f1i (va_list ap)
16 {
17   x = va_arg (ap, double);
18   x += va_arg (ap, long);
19   x += va_arg (ap, double);
20 }
21 
22 void
f1(int i,...)23 f1 (int i, ...)
24 {
25   va_list ap;
26   va_start (ap, i);
27   f1i (ap);
28   va_end (ap);
29 }
30 
31 void
f2i(va_list ap)32 f2i (va_list ap)
33 {
34   y = va_arg (ap, int);
35   y += va_arg (ap, long);
36   y += va_arg (ap, double);
37   f1i (ap);
38 }
39 
40 void
f2(int i,...)41 f2 (int i, ...)
42 {
43   va_list ap;
44   va_start (ap, i);
45   f2i (ap);
46   va_end (ap);
47 }
48 
49 long
f3h(int i,long arg0,long arg1,long arg2,long arg3)50 f3h (int i, long arg0, long arg1, long arg2, long arg3)
51 {
52   return i + arg0 + arg1 + arg2 + arg3;
53 }
54 
55 long
f3(int i,...)56 f3 (int i, ...)
57 {
58   long t, arg0, arg1, arg2, arg3;
59   va_list ap;
60 
61   va_start (ap, i);
62   switch (i)
63     {
64     case 0:
65       t = f3h (i, 0, 0, 0, 0);
66       break;
67     case 1:
68       arg0 = va_arg (ap, long);
69       t = f3h (i, arg0, 0, 0, 0);
70       break;
71     case 2:
72       arg0 = va_arg (ap, long);
73       arg1 = va_arg (ap, long);
74       t = f3h (i, arg0, arg1, 0, 0);
75       break;
76     case 3:
77       arg0 = va_arg (ap, long);
78       arg1 = va_arg (ap, long);
79       arg2 = va_arg (ap, long);
80       t = f3h (i, arg0, arg1, arg2, 0);
81       break;
82     case 4:
83       arg0 = va_arg (ap, long);
84       arg1 = va_arg (ap, long);
85       arg2 = va_arg (ap, long);
86       arg3 = va_arg (ap, long);
87       t = f3h (i, arg0, arg1, arg2, arg3);
88       break;
89     default:
90       t = 0;
91       ASSERT (0);
92     }
93   va_end (ap);
94 
95   return t;
96 }
97 
98 void
f4(int i,...)99 f4 (int i, ...)
100 {
101   va_list ap;
102 
103   va_start (ap, i);
104   switch (i)
105     {
106     case 4:
107       y = va_arg (ap, double);
108       break;
109     case 5:
110       y = va_arg (ap, double);
111       y += va_arg (ap, double);
112       break;
113     default:
114       ASSERT (0);
115     }
116   f1i (ap);
117   va_end (ap);
118 }
119 #endif
120 
121 void
testTortureExecute(void)122 testTortureExecute (void)
123 {
124 #if !defined(__SDCC_pic16) && !defined(__SDCC_pdk14) && !defined(__SDCC_pdk15)
125   f1 (3, 16.0, 128L, 32.0);
126   ASSERT (x == 176L);
127   f2 (6, 5, 7L, 18.0, 19.0, 17L, 64.0);
128   ASSERT (x == 100L && y == 30L);
129   ASSERT (f3 (0) == 0);
130   ASSERT (f3 (1, 18L) == 19L);
131   ASSERT (f3 (2, 18L, 100L) == 120L);
132   ASSERT (f3 (3, 18L, 100L, 300L) == 421L);
133   ASSERT (f3 (4, 18L, 71L, 64L, 86L) == 243L);
134   f4 (4, 6.0, 9.0, 16L, 18.0);
135   ASSERT (x == 43L && y == 6L);
136   f4 (5, 7.0, 21.0, 1.0, 17L, 126.0);
137 
138 // Failed on z80 and related before #7265
139   ASSERT (x == 144L && y == 28L);
140 #endif
141   return;
142 }
143