|
|
1.1 root 1: /* The Plum Hall Validation Suite for C
2: * Unpublished copyright (c) 1986-1991, Chiron Systems Inc and Plum Hall Inc.
3: * VERSION: 4
4: * DATE: 1993-01-01
5: * The "ANSI" mode of this suite corresponds to official ANSI C, X3.159-1989.
6: * As per your license agreement, your distribution is not to be moved or copied outside the Designated Site
7: * without specific permission from Plum Hall Inc.
8: */
9:
10: #include "flags.h"
11: #ifndef SKIP33
12: /*
13: * 3.3 - Expressions
14: */
15: #include "defs.h"
16:
17:
18: static void c3_3_1();
19: static void c3_3_2_1();
20: static void c3_3_2_2();
21: static void c3_3_2_3();
22: static void c3_3_2_4();
23: static void c3_3_3();
24: static void c3_3_3_1();
25: static void c3_3_3_2();
26: static void c3_3_3_3();
27: static void c3_3_3_4();
28: static void c3_3_4();
29: extern void c3_3b(); /* in c33b.c */
30: extern void structures(); /* in c33c.c */
31: static long f() { return 99; }
32: /*
33: * 3.3 - Expressions
34: */
35: void c3_3()
36: {
37: Filename = "c33a.c";
38:
39: c3_3_1();
40: c3_3_2_1();
41: c3_3_2_2();
42: c3_3_2_3();
43: c3_3_2_4();
44: c3_3_3();
45: c3_3_3_1();
46: c3_3_3_2();
47: c3_3_3_3();
48: c3_3_3_4();
49: c3_3_4();
50: /* too big for one module */
51: c3_3b();
52: }
53: /*
54: * 3.3.1 - Primary expressions
55: */
56: static int x;
57: static int *fp(){ return &x;}
58: static void c3_3_1()
59: {
60: char c = 0;
61: char *pc = &c;
62: char **ppc = &pc;
63: char ***pppc = &ppc;
64: char ****ppppc = &pppc;
65: char *****pppppc = &ppppc;
66: long int larray[2][3][4];
67: int i=1,j=2,k=3;
68:
69: i = 1; j = 2; k = 3;
70: do_nothing(&i,&j,&k);
71: *fp() = 7;
72: iequals(__LINE__, x, 7);
73: *****pppppc = 17;
74: iequals(__LINE__, c, 17);
75: larray[i][j][k] = 277777;
76: lequals(__LINE__, larray[1][2][3], 277777L);
77:
78: /* parentheses do not affect lvalues -- try the above examples */
79: {
80: char (((c))) = 0;
81: char (*(pc)) = &c;
82: char (*(*(ppc))) = &pc;
83: char (*(*(*(pppc)))) = &ppc;
84: char (*(*(*(*(ppppc))))) = &pppc;
85: char (*(*(*(*(*(pppppc)))))) = &ppppc;
86: long int larray[2][3][4];
87: int i=1,j=2,k=3;
88:
89: do_nothing(&i,&j,&k);
90: (*(fp())) = 8;
91: ((iequals(__LINE__, x, 8)));
92: (*(*(*(*(*(pppppc)))))) = 18;
93: iequals(__LINE__, c, 18);
94: (larray[i][j][k]) = 288888;
95: lequals(__LINE__, larray[1][2][3], 288888L);
96: }
97: } /* end c3_3_1 */
98:
99:
100:
101:
102:
103: /*
104: * 3.3.2.1 - Array subscripting
105: */
106: static void c3_3_2_1()
107: {
108: int iarray[10], *pi = iarray, i = 3, j = -3, k;
109: int i3d[2][3][4], count;
110:
111: iarray[0] = 17;
112: iarray[3] = 3;
113:
114: /* the array name is equivalent to a pointer to the first element */
115: iequals(__LINE__, *iarray, 17);
116: iequals(__LINE__, iarray[i], 3);
117: iequals(__LINE__, *(iarray + i), 3);
118: iequals(__LINE__, *(i + iarray), 3);
119: iequals(__LINE__, i[iarray], 3);
120: iequals(__LINE__, (pi+3)[j], 17);
121: iequals(__LINE__, *(pi + 3 + j), 17);
122: iequals(__LINE__, *(j + pi + 3), 17);
123: iequals(__LINE__, j[pi + 3], 17);
124:
125: /* multi dimensional arrays */
126: for (i = 0, count = 0; i < 2; ++i)
127: for (j = 0; j < 3; ++j)
128: for (k = 0; k < 4; ++k)
129: i3d[i][j][k] = count++;
130: i = ivalue(1);
131: j = ivalue(2);
132: k = ivalue(3);
133: pi = (int *)i3d[i];
134: iequals(__LINE__, *pi, 12);
135: pi = (int *)i3d[i][j];
136: iequals(__LINE__, *pi, 20);
137: pi = &i3d[i][j][k];
138: iequals(__LINE__, *pi, 23);
139:
140: /* partial addressing yields pointers to sub-dimensions */
141: aequals(__LINE__, i3d+1, &i3d[i][0][0]);
142: aequals(__LINE__, i3d+1, &i3d[1][0][0]);
143: aequals(__LINE__, i3d+2, &i3d[i+1][0][0]);
144: aequals(__LINE__, i3d+2, &i3d[2][0][0]);
145: aequals(__LINE__, i3d+2, &i3d[i][j][k+1]);
146: aequals(__LINE__, i3d+2, &i3d[1][2][4]);
147: aequals(__LINE__, i3d[i], &i3d[1][0][0]);
148: aequals(__LINE__, i3d[i]+1, &i3d[1][1][0]);
149: aequals(__LINE__, i3d[i][j], &i3d[1][2][0]);
150: aequals(__LINE__, i3d[i][j]+1, &i3d[1][2][1]);
151: aequals(__LINE__, j[i3d[i]]+1, &i3d[1][2][1]);
152: }
153:
154:
155:
156:
157: /*
158: * 3.3.2.2 - Function calls
159: */
160: char cfun(){return ivalue(1);}
161: int ifun(){return ivalue(2);}
162: long lfun(){return lvalue(3L);}
163: float ffun(){return dvalue(4.0);}
164: double dfun(){return dvalue(5.0);}
165: #if ANSI
166: long double ldfun(){return dvalue(6.0L);}
167: #endif
168: #if ANSI && HAS_PROTOTYPES
169: unsigned knothole(unsigned char uc) { return uc; }
170: int f_int(int i) { return ivalue(i); }
171: typedef int (*pfi)(int i);
172: pfi f_dbl(double x) { return &f_int; }
173: #endif
174: static void c3_3_2_2();
175: void (*fpfun())(){return c3_3_2_2;}
176: static void c3_3_2_2()
177: {
178: int i = 0;
179: extern int Side;
180:
181: /* Functions can return any type. Test for the simple types */
182: iequals(__LINE__, cfun(), 1);
183: iequals(__LINE__, ifun(), 2);
184: lequals(__LINE__, lfun(), 3L);
185: dequals(__LINE__, ffun(), 4.0);
186: dequals(__LINE__, dfun(), 5.0);
187: #if ANSI
188: {
189: long double (*pldfun)() = ldfun;
190:
191: ldequals(__LINE__, ldfun(), 6.0L);
192: ldequals(__LINE__, (*ldfun)(), 6.0L);
193: ldequals(__LINE__, (**ldfun)(), 6.0L);
194: ldequals(__LINE__, pldfun(), 6.0L);
195: ldequals(__LINE__, (*pldfun)(), 6.0L);
196: ldequals(__LINE__, (**pldfun)(), 6.0L);
197: }
198: #endif
199: checkthat(__LINE__, fpfun() == c3_3_2_2);
200:
201: /* this tests calls/returns involving structs and unions */
202: structures();
203: Filename = "c33a.c";
204:
205:
206: /* make sure that argument passing is by value */ /* 3.3.2.2 (cont.) */
207: (void) wfunc(i); /* tests call with no decl in scope */
208: iequals(__LINE__, i, 0);
209:
210: #if ANSI && HAS_PROTOTYPES
211: /* check argument coercion in the presence of a prototype */
212: {
213: iequals(__LINE__, knothole(ULONG_MAX), UCHAR_MAX);
214: iequals(__LINE__, 2.0, 2L);
215: lequals(__LINE__, 3, 3.0);
216: dequals(__LINE__, 4, 4L);
217: do_nothing(&i, 1, 2, 3, 4, 5, 6, 7, 8, 9);
218: }
219: /* check calling through pointer-to-function */
220: iequals(__LINE__, f_dbl(1.)(2), 2);
221: #endif
222:
223: /* side effects are completed before a function call */
224: xfunc(Side++);
225: Side = 0;
226: {
227: int zfunc();
228:
229: /* recursion must be possible */
230: yfunc(3, zfunc, &i); /* no proto, default conversions */
231:
232: /* zfunc changes a value through a pointer */
233: iequals(__LINE__, i, 99);
234: }
235: } /* end c3_3_2_2 */
236:
237:
238:
239:
240:
241:
242:
243:
244:
245:
246:
247:
248:
249:
250:
251:
252:
253:
254:
255:
256:
257:
258: wfunc(i) int i; { i = ivalue(17); return i; } /* 3.3.2.2 (cont.) */
259:
260: xfunc(i) /* no return type, default to int */
261: int i;
262: {
263: extern int Side;
264:
265: /* the side effect will have been completed at this point */
266: iequals(__LINE__, i, 0);
267: iequals(__LINE__, Side, 1);
268: } /* no return expression, would be erroneous to use value */
269:
270: yfunc(i, pfn, pi) /* no return type, default to int */
271: int i;
272: #if ANSI
273: int pfn(); /* parm w fn type becomes ptr-to-fn */
274: #else
275: int (*pfn)();
276: #endif
277: int *pi;
278: {
279: static int j = 3;
280:
281: iequals(__LINE__, i, j);
282: if (--i == 0)
283: return;
284: --j;
285: yfunc(i, pfn, pi);
286: iequals(__LINE__, i, j);
287: ++j;
288: #if ANSI
289: pfn(pi); /* converts to (*pfn)() */
290: #else
291: (*pfn)(pi);
292: #endif
293: } /* no return expression, would be erroneous to use value */
294:
295: zfunc(pi) /* no return type, default to int */
296: int pi[2]; /* array parm is converted to ptr */
297: {
298: *pi = 99;
299: } /* no return expression, would be erroneous to use value */
300:
301:
302:
303:
304:
305:
306:
307:
308: /*
309: * 3.3.2.3 - Structure and union members
310: */
311: static void c3_3_2_3()
312: {
313: /* See strucs() in c33c.c (appx lines 50-90) for lvalue uses.
314: * These have been tested all over. One special assurance to check:
315: * if the union begins with several structures with identical initial
316: * sequences, then the common part may be inspected. Otherwise, the
317: * only guarantee is that the member you put in comes back out
318: * correctly.
319: */
320: union
321: {
322: struct { int a; double d; } s1;
323: struct { int b; long l; } s2; /* ANSI8804 - types matter, names don't */
324: }u;
325:
326: u.s1.a = 1;
327: u.s1.d = 2.0;
328: if (u.s2.b == 1)
329: dequals(__LINE__, u.s1.d, 2.0);
330: else
331: complain(__LINE__);
332: }
333:
334:
335:
336:
337:
338:
339:
340:
341:
342:
343:
344:
345:
346:
347:
348:
349:
350:
351:
352:
353:
354:
355:
356:
357:
358: /*
359: * 3.3.2.4 - Postfix increment and decrement operators
360: */
361: static long larray[] = {1, 2};
362: static void c3_3_2_4()
363: {
364: long *p = larray;
365: double d = 2.2;
366: int i = 3;
367: long l = 4;
368: char c = 5;
369:
370: /* these are tested in several places. make sure that ++ and --
371: * work right together.
372: * See prec*.c for combination of ++ and other ops.
373: * See bitfields() in c35b.c for ++ with bitfield.
374: */
375: lequals(__LINE__, *p++, 1L);
376: lequals(__LINE__, *p--, 2L);
377: lequals(__LINE__, *p, 1L);
378:
379: /* make sure that they work on scalar types correctly */
380: dequals(__LINE__, d++, 2.2);
381: dequals(__LINE__, d--, 3.2);
382: dequals(__LINE__, d, 2.2);
383: iequals(__LINE__, i++, 3);
384: iequals(__LINE__, i--, 4);
385: iequals(__LINE__, i, 3);
386: lequals(__LINE__, l++, 4L);
387: lequals(__LINE__, l--, 5L);
388: lequals(__LINE__, l, 4L);
389: iequals(__LINE__, c++, 5);
390: iequals(__LINE__, c--, 6);
391: iequals(__LINE__, c, 5);
392: #if ANSI
393: {
394: enum {ZERO, ONE, TWO} x = ivalue(0);
395: long double ld = dvalue(1E9);
396:
397: iequals(__LINE__, x++, 0);
398: iequals(__LINE__, x++, ONE);
399: iequals(__LINE__, x--, TWO);
400: iequals(__LINE__, x, 1);
401: ldequals(__LINE__, ld++, 1E9);
402: ldequals(__LINE__, ld--, 1E9 + 1);
403: ldequals(__LINE__, --ld, 999999999);
404: }
405: #endif
406: } /* end c3_3_2_4 */
407:
408: /*
409: * 3.3.3 - Unary operators.
410: */
411: static void c3_3_3() {}
412:
413: /*
414: * 3.3.3.1 - Prefix increment and decrement operators
415: */
416: static void c3_3_3_1()
417: {
418: long *p = larray;
419: long *q;
420: double d = 2.2;
421: int i = 3;
422: long l = 4;
423: char c = 5;
424:
425: /* these are tested in several places. make sure that ++ and --
426: * work right together.
427: * See prec*.c for combination of ++ and other ops.
428: * See bitfield.c for ++ with bitfield.
429: */
430: lequals(__LINE__, *++p, 2L);
431: lequals(__LINE__, *--p, 1L);
432: q = p;
433: lequals(__LINE__, *++p, *(q+=1));
434: lequals(__LINE__, *--p, *(q-=1));
435:
436: /* make sure that they work on scalar types correctly */
437: dequals(__LINE__, ++d, 3.2);
438: dequals(__LINE__, --d, 2.2);
439: iequals(__LINE__, ++i, 4);
440: iequals(__LINE__, --i, 3);
441: lequals(__LINE__, ++l, 5L);
442: lequals(__LINE__, --l, 4L);
443: iequals(__LINE__, ++c, 6);
444: iequals(__LINE__, --c, 5);
445: }
446:
447:
448:
449:
450:
451:
452:
453:
454:
455:
456:
457:
458: /*
459: * 3.3.3.2 - Address and indirection operators.
460: */
461: static void c3_3_3_2()
462: {
463: char c;
464: char *p = &c;
465: long l = 0;
466:
467: #if ANSI
468: {
469: void (*pf)() = &c3_3_3_2; /* & with fn designator */
470: char a[2];
471: char (*pa)[2] = &a; /* & with lvalue of array type */
472: struct { int x; } s;
473: union { char c; float f; } u;
474:
475: checkthat(__LINE__, pf == c3_3_3_2);
476: aequals(__LINE__, pa, &a);
477: aequals(__LINE__, &s.x, &s);
478: aequals(__LINE__, &u.c, &u.f);
479: checkthat(__LINE__, &*pf == c3_3_3_2);
480: }
481: #endif
482: aequals(__LINE__, *&p, &c);
483: aequals(__LINE__, &*p, &c);
484:
485: #if (V7 || ANSI)
486: /* casts of addresses are allowed */
487: p = (char *)&l;
488: *(long *)p = 17;
489: lequals(__LINE__, l, 17L);
490: #endif
491: }
492:
493:
494:
495:
496:
497:
498:
499:
500:
501:
502:
503:
504:
505:
506:
507:
508: /*
509: * 3.3.3.3 - Unary arithmetic operators
510: */
511: static void c3_3_3_3()
512: {
513: float f = dvalue(1.1);
514: double d = dvalue(2.2);
515: int i = ivalue(3);
516: long l = ivalue(4);
517: char c = ivalue(5);
518: char *p = &c, *q = 0;
519:
520: /* test on arithmetic operands */
521: #if ANSI
522: checkthat(__LINE__, ~(unsigned)i == (UINT_MAX - 3));
523: checkthat(__LINE__, ~(unsigned long)l == (ULONG_MAX - 4));
524: fequals(__LINE__, +f, 1.1);
525: dequals(__LINE__, +d, 2.2);
526: iequals(__LINE__, +i, 3);
527: lequals(__LINE__, +l, 4L);
528: iequals(__LINE__, +c, 5);
529: /* aequals(__LINE__, +p, &c); DELETED, ACCORDING TO LATEST ANSI */
530: #endif
531: dequals(__LINE__, -d, -2.2);
532: iequals(__LINE__, -i, -3);
533: lequals(__LINE__, -l, -4L);
534: iequals(__LINE__, -c, -5);
535:
536: /* a few miscellaneous checks */
537: iequals(__LINE__, -i, 0-i);
538: iequals(__LINE__, - -i, i);
539: iequals(__LINE__, ~i, ~3);
540: iequals(__LINE__, !i, 0);
541: iequals(__LINE__, !i, 0 == i);
542: iequals(__LINE__, !!i, 1);
543: iequals(__LINE__, !!!i, 0);
544:
545: /* ! can take any scalar type */
546: iequals(__LINE__, !p, 0);
547: iequals(__LINE__, !q, 1);
548: }
549:
550:
551:
552:
553:
554:
555:
556:
557:
558: #if ANSI
559: #include <stddef.h> /* for size_t below */
560: #endif
561: /*
562: * 3.3.3.4 - The 'sizeof' operator
563: */
564: static void c3_3_3_4()
565: {
566: int iarray[10];
567: double *pd = 0;
568: int i = 1;
569:
570: /* get the size of objects */
571: checkthat(__LINE__, sizeof iarray == 10 * sizeof(int));
572: checkthat(__LINE__, sizeof *pd == sizeof(double));
573:
574: /* works on types too */
575: checkthat(__LINE__, sizeof (int [10]) == 10 * sizeof(int));
576: checkthat(__LINE__, sizeof (struct x { int a, b, c;}) == sizeof (struct x));
577: checkthat(__LINE__, sizeof(char) == 1);
578:
579: #if ANSI
580: /* the operand of sizeof is not evaluated */
581: checkthat(__LINE__, sizeof(++i) == sizeof(int));
582: iequals(__LINE__, i, 1);
583: /* test the size of sizeof */
584: {
585: size_t usize = 0;
586: unsigned char uc;
587:
588: checkthat(__LINE__, usize - 1 > 0); /* must be an unsigned type */
589: checkthat(__LINE__, sizeof(size_t) == sizeof(sizeof(int)));
590: checkthat(__LINE__, sizeof(size_t) == sizeof(sizeof(const char *const)));
591: checkthat(__LINE__, sizeof(size_t) == sizeof(sizeof(const char *)));
592: checkthat(__LINE__, sizeof(size_t) == sizeof(sizeof(const int)));
593: iequals(__LINE__, sizeof(+uc), sizeof(int));
594: iequals(__LINE__, sizeof(-uc), sizeof(int));
595: }
596: checkthat(__LINE__, sizeof("123456") == 7);
597: #endif
598: }
599:
600:
601:
602:
603:
604:
605:
606:
607:
608: /*
609: * 3.3.4 - Cast operators
610: */
611: static void c3_3_4()
612: {
613: short i, j;
614: long l, *pl = &l;
615: char c, *pc = &c;
616: double (*fp)();
617:
618: i = (char)(short)(long)(float)(double)(double)(float)(long)(short)(char)dvalue(3.0);
619: iequals(__LINE__, i, ivalue(3));
620: i = ivalue(-1);
621: lequals(__LINE__, (long)i, -1L);
622: iequals(__LINE__, (int)3.1416, 3);
623: dequals(__LINE__, (double)4, 4.0);
624:
625: /* pointer to integer conversion (implem-def, strictly speaking) */
626: l = (long)pc;
627: aequals( - __LINE__, pc, (char *)l);
628: /* and back again should preserve original value */
629: pc = (char *)l;
630: aequals( - __LINE__, pc, &c);
631:
632: /* pointer type conversion */
633: l = 7;
634: pc = (char *)pl;
635: lequals(__LINE__, *(long *)pc, 7L);
636:
637: /* function pointer type conversion */
638: fp = (double (*)())f;
639: lequals(__LINE__, (*(long(*)())fp)(), 99L);
640: #if ANSI
641: {
642: float f = (float)1. / (float)2.;
643: long double ld = dvalue(1.234 - 90 - 90 - 9);
644:
645: checkthat(__LINE__, f == .5F);
646: f = ld;
647: dequals(__LINE__, dvalue(f), (float)ld);
648: }
649: #endif
650:
651:
652:
653:
654:
655:
656:
657:
658: #if ANSI8706 /* 3.3.4 (cont.) */
659: {
660: struct known { int i; } s = {0};
661: struct unknown *psu;
662: char *pc;
663:
664: psu = (struct unknown *)avalue(&s);
665: pc = (char *)avalue(psu);
666: checkthat(__LINE__, pc == (char *)psu);
667: }
668: #endif
669: } /* end c3_3_4 */
670:
671: #else /* if SKIP33 */
672:
673: void c3_3() { pr_skip("c3_3: SKIPPED ENTIRELY\n"); }
674: #endif /* SKIP33 */
675:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.