1 /*  Test passing of arguments to functions.  Use various sorts of arguments,
2     including basic types, pointers to those types, structures, lots of
3     args, etc, in various combinations. */
4 
5 /* AIX requires this to be the first thing in the file.  */
6 #ifdef __GNUC__
7 #  define alloca __builtin_alloca
8 #  define HAVE_STACK_ALLOCA 1
9 #else /* not __GNUC__ */
10 #  ifdef _AIX
11      #pragma alloca
12 #    define HAVE_STACK_ALLOCA 1
13 #  else /* Not AIX */
14 #    ifdef sparc
15 #      include <alloca.h>
16 #      define HAVE_STACK_ALLOCA 1
17 #      ifdef __STDC__
18          void *alloca ();
19 #      else
20          char *alloca ();
21 #      endif /* __STDC__ */
22 #    endif /* sparc */
23 #  endif /* Not AIX */
24 #endif /* not __GNUC__ */
25 
26 char c = 'a';
27 char *cp = &c;
28 
29 unsigned char uc = 'b';
30 unsigned char *ucp = &uc;
31 
32 short s = 1;
33 short *sp = &s;
34 
35 unsigned short us = 6;
36 unsigned short *usp = &us;
37 
38 int i = 2;
39 int *ip = &i;
40 
41 unsigned int ui = 7;
42 unsigned int *uip = &ui;
43 
44 long l = 3;
45 long *lp = &l;
46 
47 unsigned long ul = 8;
48 unsigned long *ulp = &ul;
49 
50 float f = 4.0;
51 float *fp = &f;
52 
53 double d = 5.0;
54 double *dp = &d;
55 
56 struct stag {
57     int s1;
58     int s2;
59 } st = { 101, 102 };
60 struct stag *stp = &st;
61 
62 union utag {
63     int u1;
64     long u2;
65 } un;
66 union utag *unp = &un;
67 
68 char carray[] = {'a', 'n', ' ', 'a', 'r', 'r', 'a', 'y', '\0'};
69 
70 
71 /* Test various permutations and interleaving of integral arguments */
72 
73 
74 call0a (c, s, i, l)
75 char c; short s; int i; long l;
76 {
77   c = 'a';
78   s = 5;
79   i = 6;
80   l = 7;
81 }
82 
83 call0b (s, i, l, c)
84 short s; int i; long l; char c;
85 {
86   s = 6; i = 7; l = 8; c = 'j';
87 }
88 
89 call0c (i, l, c, s)
90 int i; long l; char c; short s;
91 {
92   i = 3; l = 4; c = 'k'; s = 5;
93 }
94 
95 call0d (l, c, s, i)
96 long l; char c; short s; int i;
97 {
98   l = 7; c = 'z'; s = 8; i = 9;
99 }
100 
101 call0e (c1, l, c2, i, c3, s, c4, c5)
102 char c1; long l; char c2; int i; char c3; short s; char c4; char c5;
103 {
104   c1 = 'a'; l = 5; c2 = 'b'; i = 7; c3 = 'c'; s = 7; c4 = 'f'; c5 = 'g';
105 }
106 
107 
108 /* Test various permutations and interleaving of unsigned integral arguments */
109 
110 
111 call1a (uc, us, ui, ul)
112 unsigned char uc; unsigned short us; unsigned int ui; unsigned long ul;
113 {
114   uc = 5; us = 6; ui = 7; ul = 8;
115 }
116 
117 call1b (us, ui, ul, uc)
118 unsigned short us; unsigned int ui; unsigned long ul; unsigned char uc;
119 {
120   uc = 5; us = 6; ui = 7; ul = 8;
121 }
122 
123 call1c (ui, ul, uc, us)
124 unsigned int ui; unsigned long ul; unsigned char uc; unsigned short us;
125 {
126   uc = 5; us = 6; ui = 7; ul = 8;
127 }
128 
129 call1d (ul, uc, us, ui)
130 unsigned long ul; unsigned char uc; unsigned short us; unsigned int ui;
131 {
132   uc = 5; us = 6; ui = 7; ul = 8;
133 }
134 
135 call1e (uc1, ul, uc2, ui, uc3, us, uc4, uc5)
136 unsigned char uc1; unsigned long ul; unsigned char uc2; unsigned int ui;
137 unsigned char uc3; unsigned short us; unsigned char uc4; unsigned char uc5;
138 {
139   uc1 = 5; ul = 7; uc2 = 8; ui = 9; uc3 = 10; us = 11; uc4 = 12; uc5 = 55;
140 }
141 
142 /* Test various permutations and interleaving of integral arguments with
143    floating point arguments. */
144 
145 
146 call2a (c, f1, s, d1, i, f2, l, d2)
147 char c; float f1; short s; double d1; int i; float f2; long l; double d2;
148 {
149   c = 'a'; f1 = 0.0; s = 5; d1 = 0.0; i = 6; f2 = 0.1; l = 7; d2 = 0.2;
150 }
151 
152 call2b (f1, s, d1, i, f2, l, d2, c)
153 float f1; short s; double d1; int i; float f2; long l; double d2; char c;
154 {
155   c = 'a'; f1 = 0.0; s = 5; d1 = 0.0; i = 6; f2 = 0.1; l = 7; d2 = 0.2;
156 }
157 
158 call2c (s, d1, i, f2, l, d2, c, f1)
159 short s; double d1; int i; float f2; long l; double d2; char c; float f1;
160 {
161   c = 'a'; f1 = 0.0; s = 5; d1 = 0.0; i = 6; f2 = 0.1; l = 7; d2 = 0.2;
162 }
163 
164 call2d (d1, i, f2, l, d2, c, f1, s)
165 double d1; int i; float f2; long l; double d2; char c; float f1; short s;
166 {
167   c = 'a'; f1 = 0.0; s = 5; d1 = 0.0; i = 6; f2 = 0.1; l = 7; d2 = 0.2;
168 }
169 
170 call2e (i, f2, l, d2, c, f1, s, d1)
171 int i; float f2; long l; double d2; char c; float f1; short s; double d1;
172 {
173   c = 'a'; f1 = 0.0; s = 5; d1 = 0.0; i = 6; f2 = 0.1; l = 7; d2 = 0.2;
174 }
175 
176 call2f (f2, l, d2, c, f1, s, d1, i)
177 float f2; long l; double d2; char c; float f1; short s; double d1; int i;
178 {
179   c = 'a'; f1 = 0.0; s = 5; d1 = 0.0; i = 6; f2 = 0.1; l = 7; d2 = 0.2;
180 }
181 
182 call2g (l, d2, c, f1, s, d1, i, f2)
183 long l; double d2; char c; float f1; short s; double d1; int i; float f2;
184 {
185   c = 'a'; f1 = 0.0; s = 5; d1 = 0.0; i = 6; f2 = 0.1; l = 7; d2 = 0.2;
186 }
187 
188 call2h (d2, c, f1, s, d1, i, f2, l)
189 double d2; char c; float f1; short s; double d1; int i; float f2; long l;
190 {
191   c = 'a'; f1 = 0.0; s = 5; d1 = 0.0; i = 6; f2 = 0.1; l = 7; d2 = 0.2;
192 }
193 
194 call2i (c1, f1, c2, c3, d1, c4, c5, c6, f2, s, c7, d2)
195 char c1; float f1; char c2; char c3; double d1; char c4; char c5; char c6;
196 float f2; short s; char c7; double d2;
197 {
198   c1 = 'a'; f1 = 0.0; c2 = 5; d1 = 0.0; c3 = 6; f2 = 0.1; c4 = 7; d2 = 0.2;
199   c5 = 's'; c6 = 'f'; c7 = 'z'; s = 77;
200 }
201 
202 
203 /* Test pointers to various integral and floating types. */
204 
205 
206 call3a (cp, sp, ip, lp)
207 char *cp; short *sp; int *ip; long *lp;
208 {
209   cp = 0; sp = 0; ip = 0; lp = 0;
210 }
211 
212 call3b (ucp, usp, uip, ulp)
213 unsigned char *ucp; unsigned short *usp; unsigned int *uip;
214 unsigned long *ulp;
215 {
216   ucp = 0; usp = 0; uip = 0; ulp = 0;
217 }
218 
219 call3c (fp, dp)
220 float *fp; double *dp;
221 {
222   fp = 0; dp = 0;
223 }
224 
225 
226 /* Test passing structures and unions by reference. */
227 
228 
229 call4a (stp)
230 struct stag *stp; {
231 stp = 0;}
232 
233 call4b (unp)
234 union utag *unp;
235 {
236   unp = 0;
237 }
238 
239 
240 /* Test passing structures and unions by value. */
241 
242 
243 call5a (st)
244 struct stag st; {st.s1 = 5;}
245 
246 call5b (un)
247 union utag un; {un.u1 = 7;}
248 
249 
250 /* Test shuffling of args */
251 
252 
253 call6a (c, s, i, l, f, d, uc, us, ui, ul)
254 char c; short s; int i; long l; float f; double d;
255 unsigned char uc; unsigned short us; unsigned int ui; unsigned long ul;
256 {
257   c = c;
258     call6b (s, i, l, f, d, uc, us, ui, ul);
259 }
260 
261 call6b (s, i, l, f, d, uc, us, ui, ul)
262 short s; int i; long l; float f; double d;
263 unsigned char uc; unsigned short us; unsigned int ui; unsigned long ul;
264 {
265   s = s;
266     call6c (i, l, f, d, uc, us, ui, ul);
267 }
268 
269 call6c (i, l, f, d, uc, us, ui, ul)
270 int i; long l; float f; double d;
271 unsigned char uc; unsigned short us; unsigned int ui; unsigned long ul;
272 {
273   i = i;
274     call6d (l, f, d, uc, us, ui, ul);
275 }
276 
277 call6d (l, f, d, uc, us, ui, ul)
278 long l; float f; double d;
279 unsigned char uc; unsigned short us; unsigned int ui; unsigned long ul;
280 {
281   l = l;
282     call6e (f, d, uc, us, ui, ul);
283 }
284 
285 call6e (f, d, uc, us, ui, ul)
286 float f; double d;
287 unsigned char uc; unsigned short us; unsigned int ui; unsigned long ul;
288 {
289   f = f;
290     call6f (d, uc, us, ui, ul);
291 }
292 
293 call6f (d, uc, us, ui, ul)
294 double d;
295 unsigned char uc; unsigned short us; unsigned int ui; unsigned long ul;
296 {
297   d = d;
298     call6g (uc, us, ui, ul);
299 }
300 
301 call6g (uc, us, ui, ul)
302 unsigned char uc; unsigned short us; unsigned int ui; unsigned long ul;
303 {
304   uc = uc;
305     call6h (us, ui, ul);
306 }
307 
308 call6h (us, ui, ul)
309 unsigned short us; unsigned int ui; unsigned long ul;
310 {
311   us = us;
312     call6i (ui, ul);
313 }
314 
315 call6i (ui, ul)
316 unsigned int ui; unsigned long ul;
317 {
318   ui = ui;
319     call6j (ul);
320 }
321 
322 call6j (ul)
323 unsigned long ul;
324 {
325   ul = ul;
326     call6k ();
327 }
328 
329 call6k ()
330 {
331 }
332 
333 
334 /*  Test shuffling of args, round robin */
335 
336 
337 call7a (c, i, s, l, f, uc, d, us, ul, ui)
338 char c; int i; short s; long l; float f; unsigned char uc; double d; unsigned short us; unsigned long ul; unsigned int ui;
339 {
340     call7b (i, s, l, f, uc, d, us, ul, ui, c);
341 }
342 
343 call7b (i, s, l, f, uc, d, us, ul, ui, c)
344 int i; short s; long l; float f; unsigned char uc; double d; unsigned short us; unsigned long ul; unsigned int ui; char c;
345 {
346     call7c (s, l, f, uc, d, us, ul, ui, c, i);
347 }
348 
349 call7c (s, l, f, uc, d, us, ul, ui, c, i)
350 short s; long l; float f; unsigned char uc; double d; unsigned short us; unsigned long ul; unsigned int ui; char c; int i;
351 {
352     call7d (l, f, uc, d, us, ul, ui, c, i, s);
353 }
354 
355 call7d (l, f, uc, d, us, ul, ui, c, i, s)
356 long l; float f; unsigned char uc; double d; unsigned short us; unsigned long ul; unsigned int ui; char c; int i; short s;
357 {
358     call7e (f, uc, d, us, ul, ui, c, i, s, l);
359 }
360 
361 call7e (f, uc, d, us, ul, ui, c, i, s, l)
362 float f; unsigned char uc; double d; unsigned short us; unsigned long ul; unsigned int ui; char c; int i; short s; long l;
363 {
364     call7f (uc, d, us, ul, ui, c, i, s, l, f);
365 }
366 
367 call7f (uc, d, us, ul, ui, c, i, s, l, f)
368 unsigned char uc; double d; unsigned short us; unsigned long ul; unsigned int ui; char c; int i; short s; long l; float f;
369 {
370     call7g (d, us, ul, ui, c, i, s, l, f, uc);
371 }
372 
373 call7g (d, us, ul, ui, c, i, s, l, f, uc)
374 double d; unsigned short us; unsigned long ul; unsigned int ui; char c; int i; short s; long l; float f; unsigned char uc;
375 {
376     call7h (us, ul, ui, c, i, s, l, f, uc, d);
377 }
378 
379 call7h (us, ul, ui, c, i, s, l, f, uc, d)
380 unsigned short us; unsigned long ul; unsigned int ui; char c; int i; short s; long l; float f; unsigned char uc; double d;
381 {
382     call7i (ul, ui, c, i, s, l, f, uc, d, us);
383 }
384 
385 call7i (ul, ui, c, i, s, l, f, uc, d, us)
386 unsigned long ul; unsigned int ui; char c; int i; short s; long l; float f; unsigned char uc; double d; unsigned short us;
387 {
388     call7j (ui, c, i, s, l, f, uc, d, us, ul);
389 }
390 
391 call7j (ui, c, i, s, l, f, uc, d, us, ul)
392 unsigned int ui; char c; int i; short s; long l; float f; unsigned char uc; double d; unsigned short us; unsigned long ul;
393 {
394     call7k (c, i, s, l, f, uc, d, us, ul, ui);
395 }
396 
397 call7k (c, i, s, l, f, uc, d, us, ul, ui)
398 char c; int i; short s; long l; float f; unsigned char uc; double d; unsigned short us; unsigned long ul; unsigned int ui;
399 {
400   c = 'a'; i = 7; s = 8; l = 7; f = 0.3; uc = 44; d = 0.44; us = 77;
401   ul = 43; ui = 33;
402 }
403 
404 
405 /*  Test printing of structures passed as arguments to recursive functions. */
406 
407 
408 typedef struct s
409 {
410   short s;
411   int i;
412   long l;
413 } SVAL;
414 
415 hitbottom ()
416 {
417 }
418 
419 void recurse (a, depth)
420 SVAL a;
421 int depth;
422 {
423   a.s = a.i = a.l = --depth;
424   if (depth == 0)
425     hitbottom ();
426   else
427     recurse (a, depth);
428 }
429 
430 test_struct_args ()
431 {
432   SVAL s; s.s = 5; s.i = 5; s.l = 5;
433 
434   recurse (s, 5);
435 }
436 
437 /* On various machines (pa, 29k, and rs/6000, at least), a function which
438    calls alloca may do things differently with respect to frames.  So give
439    it a try.  */
440 
441 int
442 localvars_after_alloca (c, s, i, l)
443      char c;
444      short s;
445      int i;
446      long l;
447 {
448 #ifdef HAVE_STACK_ALLOCA
449   /* No need to use the alloca.c alloca-on-top-of-malloc; it doesn't
450      test what we are looking for, so if we don't have an alloca which
451      allocates on the stack, just don't bother to call alloca at all.  */
452 
453   char *z = alloca (s + 50);
454 #endif
455   c = 'a';
456   s = 5;
457   i = 6;
458   l = 7;
459 }
460 
461 void
462 call_after_alloca_subr (c, s, i, l, uc, us, ui, ul)
463 char c; int i; short s; long l; unsigned char uc; unsigned short us; unsigned long ul; unsigned int ui;
464 {
465   c = 'a';
466   i = 7; s = 8; l = 7; uc = 44; us = 77;
467   ul = 43; ui = 33;
468 }
469 
470 int
471 call_after_alloca (c, s, i, l)
472      char c;
473      short s;
474      int i;
475      long l;
476 {
477 #ifdef HAVE_STACK_ALLOCA
478   /* No need to use the alloca.c alloca-on-top-of-malloc; it doesn't
479      test what we are looking for, so if we don't have an alloca which
480      allocates on the stack, just don't bother to call alloca at all.  */
481 
482   char *z = alloca (s + 50);
483 #endif
484   call_after_alloca_subr (c, s, i, l, 'b', 11, 12, (unsigned long)13);
485 }
486 
487 
488 
489 /* The point behind this test is the PA will call this indirectly
490    through dyncall.  Unlike the indirect calls to call0a, this test
491    will require a trampoline between dyncall and this function on the
492    call path, then another trampoline on between this function and main
493    on the return path.  */
494 double
495 call_with_trampolines (d1)
496 double d1;
497 {
498   return d1;
499 } /* End of call_with_trampolines, this comment is needed by funcargs.exp */
500 
501 /* Dummy functions which the testsuite can use to run to, etc.  */
502 
503 void
504 marker_indirect_call () {}
505 
506 void
507 marker_call_with_trampolines () {}
508 
509 main ()
510 {
511   int (*pointer_to_call0a) () = call0a;
512   double (*pointer_to_call_with_trampolines) () = call_with_trampolines;
513 
514 #ifdef usestubs
515   set_debug_traps();
516   breakpoint();
517 #endif
518   /* Test calling with basic integer types */
519   call0a (c, s, i, l);
520   call0b (s, i, l, c);
521   call0c (i, l, c, s);
522   call0d (l, c, s, i);
523   call0e (c, l, c, i, c, s, c, c);
524 
525   /* Test calling with unsigned integer types */
526   call1a (uc, us, ui, ul);
527   call1b (us, ui, ul, uc);
528   call1c (ui, ul, uc, us);
529   call1d (ul, uc, us, ui);
530   call1e (uc, ul, uc, ui, uc, us, uc, uc);
531 
532   /* Test calling with integral types mixed with floating point types */
533   call2a (c, f, s, d, i, f, l, d);
534   call2b (f, s, d, i, f, l, d, c);
535   call2c (s, d, i, f, l, d, c, f);
536   call2d (d, i, f, l, d, c, f, s);
537   call2e (i, f, l, d, c, f, s, d);
538   call2f (f, l, d, c, f, s, d, i);
539   call2g (l, d, c, f, s, d, i, f);
540   call2h (d, c, f, s, d, i, f, l);
541   call2i (c, f, c, c, d, c, c, c, f, s, c, d);;
542 
543   /* Test dereferencing pointers to various integral and floating types */
544 
545   call3a (cp, sp, ip, lp);
546   call3b (ucp, usp, uip, ulp);
547   call3c (fp, dp);
548 
549   /* Test dereferencing pointers to structs and unions */
550 
551   call4a (stp);
552   un.u1 = 1;
553   call4b (unp);
554 
555   /* Test calling with structures and unions. */
556 
557   call5a (st);
558   un.u1 = 2;
559   call5b (un);
560 
561   /* Test shuffling of args */
562 
563   call6a (c, s, i, l, f, d, uc, us, ui, ul);
564   call7a (c, i, s, l, f, uc, d, us, ul, ui);
565 
566   /* Test passing structures recursively. */
567 
568   test_struct_args ();
569 
570   localvars_after_alloca (c, s, i, l);
571 
572   call_after_alloca (c, s, i, l);
573 
574   /* This is for localvars_in_indirect_call.  */
575   marker_indirect_call ();
576   /* The comment on the following two lines is used by funcargs.exp,
577      don't change it.  */
578   (*pointer_to_call0a) (c, s, i, l);	/* First step into call0a.  */
579   (*pointer_to_call0a) (c, s, i, l);	/* Second step into call0a.  */
580   marker_call_with_trampolines ();
581   (*pointer_to_call_with_trampolines) (d); /* Test multiple trampolines.  */
582 }
583