1 #include <stdarg.h>
2 #include <stdlib.h>
3 #include <stdio.h>
4 
5 struct tiny {
6 	char c;
7 	char d;
8 };
9 
10 /*
11  * Check that small structs are passed correctly (aligned to dword
12  * boundary on both sides) via stdarg
13  */
14 void
f(int n,...)15 f(int n, ...)
16 {
17 	struct tiny 	x;
18 	long		l;
19 	va_list 	ap;
20 
21 	puts("===\nf()");
22 
23 	va_start (ap,n);
24 
25 	x = va_arg (ap,struct tiny);
26 	printf("%d, %d\n", x.c, x.d);
27 	x = va_arg (ap,struct tiny);
28 	printf("%d, %d\n", x.c, x.d);
29 	x = va_arg (ap,struct tiny);
30 	printf("%d, %d\n", x.c, x.d);
31 	l = va_arg(ap, long);
32 	printf("%ld\n", l);
33 	va_end (ap);
34 }
35 
36 /*
37  * Check that small structs are passed correctly (aligned to dword
38  * boundary on both sides)
39  */
40 void
f2(int n,struct tiny x1,struct tiny x2,struct tiny x3,...)41 f2(int n, struct tiny x1, struct tiny x2, struct tiny x3, ...)
42 {
43 	long		l;
44 	va_list 	ap;
45 
46 	puts("===\nf2()");
47 
48 	va_start (ap,x3);
49 
50 	printf("%d, %d\n", x1.c, x1.d);
51 	printf("%d, %d\n", x2.c, x2.d);
52 	printf("%d, %d\n", x3.c, x3.d);
53 	l = va_arg(ap, long);
54 	printf("%ld\n", l);
55 	va_end (ap);
56 }
57 
58 /*
59  * Check that small structs are passed correctly (aligned to dword
60  * boundary on both sides) even with intervening (and alignment-
61  * changing) small types
62  */
63 void
f3(int n,char dummy,struct tiny x1,char dummy2,struct tiny x2,short dummy3,long foo,struct tiny x3,...)64 f3(int n, char dummy, struct tiny x1, char dummy2, struct tiny x2, short dummy3, long foo, struct tiny x3, ...)
65 {
66 	long		l;
67 	va_list 	ap;
68 
69 	puts("===\nf3()");
70 
71 	va_start (ap,x3);
72 
73 	printf("%d, %d\n", x1.c, x1.d);
74 	printf("%d, %d\n", x2.c, x2.d);
75 	printf("%d, %d\n", x3.c, x3.d);
76 	l = va_arg(ap, long);
77 	printf("%ld\n", l);
78 	printf("%d, %d, %d\n", dummy, dummy2, dummy3);
79 	printf("%ld\n", foo);
80 	va_end (ap);
81 }
82 
83 /*
84  * Check that small structs are passed correctly (aligned to dword
85  * boundary on both sides) even with intervening (and alignment-
86  * changing) small types
87  */
88 void
f4(int n,...)89 f4(int n, ...)
90 {
91 	long		l;
92 	va_list 	ap;
93 	struct tiny	tmp;
94 
95 	puts("===\nf4()");
96 
97 	va_start(ap,n);
98 
99 	printf("%d\n", va_arg(ap, int)); /* char */
100 	tmp = va_arg(ap, struct tiny);
101 	printf("%d, %d\n", tmp.c, tmp.d);
102 	printf("%ld\n", va_arg(ap, long));
103 	printf("%f\n", va_arg(ap, double));
104 	tmp = va_arg(ap, struct tiny);
105 	printf("%d, %d\n", tmp.c, tmp.d);
106 	printf("%d\n", va_arg(ap, int)); /* char */
107 	printf("%d\n", va_arg(ap, int)); /* short */
108 	printf("%lld\n", va_arg(ap, long long));
109 	tmp = va_arg(ap, struct tiny);
110 	printf("%d, %d\n", tmp.c, tmp.d);
111 
112 	l = va_arg(ap, long);
113 	va_end (ap);
114 }
115 
116 int
main()117 main ()
118 {
119 	struct tiny x[3];
120 
121 	x[0].c = 10;
122 	x[1].c = 11;
123 	x[2].c = 12;
124 	x[0].d = 20;
125 	x[1].d = 21;
126 	x[2].d = 22;
127 
128 	printf("%d, %d\n", x[0].c, x[0].d);
129 	printf("%d, %d\n", x[1].c, x[1].d);
130 	printf("%d, %d\n", x[2].c, x[2].d);
131 	puts("===");
132 
133 	f(3, x[0], x[1], x[2], (long)123);
134 	f2(3, x[0], x[1], x[2], (long)123);
135 	f3(3,    11,   x[0],   22,    x[1],   33,    77777,  x[2], (long)123);
136 	f4(0, 1/*char*/, x[0], 2L, 3.4, x[1], (char)5, (short)6, 7LL, x[2]);
137 	exit(0);
138 }
139 
140