|
|
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 SKIP36
12: /*
13: * 3.6 - Statements
14: */
15: #include "defs.h"
16:
17: static void c3_6_1();
18: static void c3_6_2();
19: static void c3_6_3();
20: static void c3_6_4_1();
21: static void c3_6_4_2();
22: static void c3_6_5_1();
23: static void c3_6_5_2();
24: static void c3_6_5_3();
25: static void c3_6_6_1();
26: static void c3_6_6_2();
27: static void c3_6_6_3();
28: static void c3_6_6_4();
29:
30: void c3_6()
31: {
32: Filename = "c36.c";
33: c3_6_1();
34: c3_6_2();
35: c3_6_3();
36: c3_6_4_1();
37: c3_6_4_2();
38: c3_6_5_1();
39: c3_6_5_2();
40: c3_6_5_3();
41: c3_6_6_1();
42: c3_6_6_2();
43: c3_6_6_3();
44: c3_6_6_4();
45: }
46:
47:
48:
49:
50:
51:
52: /*
53: * 3.6.1 - Labeled statements
54: */
55: static void c3_6_1()
56: {
57: int i;
58: /* labels do not interfere with the flow of control */
59: i = 1;
60: a:
61: iequals(__LINE__, i, 1);
62: i = 2;
63: b:
64: iequals(__LINE__, i, 2);
65: i = 3;
66: c: d: e:
67: iequals(__LINE__, i, 3);
68: }
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102: /*
103: * 3.6.2 - Compound statement or block
104: */
105: static void c3_6_2()
106: {
107: int i = 1;
108: {
109: int i = 2;
110: {
111: int i = 3, j = i + 1;
112: static float c3_6var = 5.; /* see also 3.1.2.1 Scope */
113: {
114: /* initialize the block each time it is entered */
115: int j;
116: for (j = 7; j < 10; ++j)
117: lab:{
118: int i = j;
119: static int k = 9;
120: #if ANSI
121: extern int c3_6var;
122: iequals(__LINE__, i, j);
123: iequals(__LINE__, k, 9);
124: iequals(__LINE__, c3_6var, 12);
125: #endif /* ANSI */
126: }
127: }
128: iequals(__LINE__, i, 3);
129: iequals(__LINE__, j, 4);
130: dequals(__LINE__, c3_6var, 5.);
131: }
132: iequals(__LINE__, i, 2);
133: }
134: iequals(__LINE__, i, 1);
135: }
136: int c3_6var = 12;
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152: /*
153: * 3.6.3 Expression and null statement
154: */
155: static void c3_6_3()
156: {
157: int i, j, k;
158: char p[4];
159: /* expressions don't have to do anything */
160: i = ivalue(11);
161: ;;;;;
162: i;
163: 1;2;(void)3;
164: iequals(__LINE__, i, 11);
165:
166: #if (V7 || ANSI)
167: /* evaluate an expression for its side effects */
168: (void)str_cpye(p, "abc");
169: checkthat(__LINE__, str_cmp(p, "abc") == 0);
170: str_cpye(p, "xyz");
171: checkthat(__LINE__, str_cmp(p, "xyz") == 0);
172: #endif
173:
174: /* null statement in use */
175: for (i = 0; i < 10; ++i)
176: ;
177: iequals(__LINE__, i, 10);
178: label: ;
179: }
180:
181:
182:
183:
184:
185:
186:
187:
188:
189:
190:
191:
192:
193:
194:
195:
196:
197:
198:
199:
200:
201:
202: /*
203: * 3.6.4 - Selection statements
204: */
205:
206: /*
207: * 3.6.4.1 - The 'if' statement
208: */
209: static void c3_6_4_1()
210: {
211: int i = ivalue(1), j = ivalue(2), k = ivalue(3);
212: double d = dvalue(1.);
213: char *p = 0;
214:
215: /* the controlling expr is of scalar type */
216: if (d) dequals(__LINE__, d, 1.);
217: else complain(__LINE__);
218:
219: if (p) complain(__LINE__);
220: else aequals(__LINE__, p, (char *)0);
221:
222: /* check else binding (nearest if) */
223: if (ivalue(i+j) == 0)
224: complain(__LINE__);
225: else if (ivalue(j+k) == 0)
226: complain(__LINE__);
227: else
228: lab: i = 4;
229: iequals(__LINE__, i, 4);
230:
231: /* and in the presence of labels */
232: goto lab1;
233: if (i != 0)
234: lab1: i = 5;
235: else
236: i = 6;
237: iequals(__LINE__, i, 5);
238:
239: goto lab2;
240: if (i != 0)
241: i = 7;
242: else
243: lab2: i = 8;
244: iequals(__LINE__, i, 8);
245:
246: /* The tested expr is a sequence point. */
247: i = ivalue(8);
248: if (i == 0) { complain(__LINE__); if ( i > 0 ) complain(__LINE__); }
249: else iequals(__LINE__, i, 8);
250: }
251:
252: /*
253: * 3.6.4.2 - The 'switch' statement
254: */
255: static char carray[] = { 0, 1, 2, 3};
256: static short sarray[] = { 0, 1, 2, 3};
257: static long larray[] = { 0xff00000, 0xff10000, 0xff20000, 3};
258: static void c3_6_4_2()
259: {
260: #if (ANSI || V7)
261: enum e {zero, one, two, three} e;
262: #endif
263: char c;
264: int i, sum, flag;
265: unsigned u;
266: long l;
267: short s;
268:
269: #if ANSI
270: {
271: int a = 1;
272:
273: /* syntax does not require a block, only a stmt */
274: switch (a) default: switch (a+1) default: a = 9;
275: iequals(__LINE__, a, 9);
276: switch(a) ; /* do-nothing */
277: }
278: #endif
279:
280: flag = sum = 0;
281: for (i = 0; i < 10; ++i)
282: {
283: switch(i)
284: {
285: inswitch:
286: case 0:
287: case 9:
288: sum += 1;
289: /* falls through */
290: case 1:
291: case 8:
292: sum += 2;
293: break;
294: default:
295: sum += 4;
296: }
297: if (flag)
298: break;
299: }
300:
301:
302: /* 3.6.4.2 (cont.) */
303: if (flag)
304: /* gets here via goto below */
305: iequals(__LINE__, sum, 37);
306: else
307: {
308: iequals(__LINE__, sum, 34);
309: /* check that switch control works on obscure entry */
310: flag = 1;
311: goto inswitch;
312: }
313:
314: /* nested switch */
315: for (i = 0; i < 2; ++i)
316: switch(i)
317: {
318: default :
319: switch(i)
320: {
321: case 0:
322: sum = 0;
323: break;
324: case 1 :
325: sum += 1;
326: break;
327: }
328: break;
329: case 11:
330: sum = 123;
331: }
332: iequals(__LINE__, sum, 1);
333:
334: /* the tested expr is a sequence point */
335: i = ivalue(9);
336: switch (i++)
337: {
338: case 9:
339: iequals(__LINE__, i, 10);
340: break;
341: default:
342: complain(__LINE__);
343: }
344:
345:
346:
347:
348:
349:
350:
351:
352: /* 3.6.4.2 (cont.) */
353: /* switch with no match */
354: switch(sum)
355: {
356: case 0:
357: case 2:
358: case 3:
359: sum = 123;
360: break;
361: }
362: iequals(__LINE__, sum, 1);
363:
364: /* unsigned should work correctly at the zero crossing */
365: for (u = (unsigned)-1, sum = 0; u != 2; ++u)
366: switch (u)
367: {
368: case -1: /* promoted to unsigned */
369: sum += 1;
370: break;
371: case 0:
372: sum += 2;
373: break;
374: case 1:
375: sum += 4;
376: break;
377: default:
378: complain(__LINE__);
379: }
380: iequals(__LINE__, sum, 7);
381:
382:
383:
384:
385:
386:
387:
388:
389:
390:
391:
392:
393:
394:
395:
396:
397:
398:
399:
400:
401:
402: /* 3.6.4.2 (cont.) */
403: #if ANSI
404: /* ANSI allows all integral types to be used in a switch */
405: for (i = 0, sum = 0; i <= 3; ++i)
406: {
407: switch (carray[i])
408: {
409: case 0:
410: sum += 1;
411: break;
412: case 1:
413: sum += 2;
414: break;
415: case 2:
416: sum += 4;
417: break;
418: case 3:
419: sum += 8;
420: break;
421: default:
422: complain(__LINE__);
423: }
424: }
425: iequals(__LINE__, sum, 15);
426:
427: for (i = 0, sum = 0; i <= 3; ++i)
428: {
429: switch (sarray[i])
430: {
431: case 0:
432: sum += 1;
433: break;
434: case 1:
435: sum += 2;
436: break;
437: case 2:
438: sum += 4;
439: break;
440: case 3:
441: sum += 8;
442: break;
443: default:
444: complain(__LINE__);
445: }
446: }
447: iequals(__LINE__, sum, 15);
448:
449:
450:
451:
452: /* 3.6.4.2 (cont.) */
453: for (i = 0, sum = 0; i <= 3; ++i)
454: {
455: switch (larray[i])
456: {
457: case 0xff00000:
458: sum += 1;
459: break;
460: case 0xff10000:
461: sum += 2;
462: break;
463: case 0xff20000:
464: sum += 4;
465: break;
466: case 3: /* must convert to long */
467: sum += 8;
468: break;
469: default:
470: complain(__LINE__);
471: }
472: }
473: iequals(__LINE__, sum, 15);
474: for (e = (enum e)(i = 0), sum = 0; i <= 3; ++i, e = (enum e)i)
475: {
476: switch (e)
477: {
478: case zero:
479: sum += 1;
480: break;
481: case one:
482: sum += 2;
483: break;
484: case two:
485: sum += 4;
486: break;
487: case three:
488: sum += 8;
489: break;
490: default:
491: complain(__LINE__);
492: }
493: }
494: iequals(__LINE__, sum, 15);
495: #endif /* ANSI */
496: } /* end c3_6_4_2 */
497:
498:
499:
500:
501:
502: /*
503: * 3.6.5 - Iteration statements
504: */
505:
506: /*
507: * 3.6.5.1 - The 'while' statement
508: */
509: static void c3_6_5_1()
510: {
511: int sum, i;
512:
513: /* the controlling expr is of scalar type */
514: { float v=0; while (v) { complain(__LINE__); break; } }
515: { int (*v)()=0; while (v) { complain(__LINE__); break; } }
516: { char *v=0; while (v) { complain(__LINE__); break; } }
517: { struct unk *v=0; while (v) { complain(__LINE__); break; } }
518: { enum {z} v=0; while (v) { complain(__LINE__); break; } }
519: { char v=0; while (v) { complain(__LINE__); break; } }
520: { unsigned v=0; while (v) { complain(__LINE__); break; } }
521:
522: i = 10;
523: sum = 0;
524: /* make sure the bounds are computed each time through */
525: while (i)
526: {
527: sum += i;
528: if (--i == 5)
529: i = 0;
530: }
531: iequals(__LINE__, sum, 40);
532:
533: /* zero execution loop */
534: sum = 0;
535: while (i)
536: sum = 99;
537: iequals(__LINE__, sum, 0);
538:
539: /* the controlling expr is a sequence point */
540: i = ivalue(1);
541: while ( i -- )
542: iequals(__LINE__, i, 0);
543: }
544:
545:
546:
547:
548:
549:
550:
551:
552: /*
553: * 3.6.5.2 - The 'do' statement
554: */
555: static void c3_6_5_2()
556: {
557: int sum, i;
558:
559: /* the controlling expr is of scalar type */
560: { float v=0; do { checkthat(__LINE__, v == 0); } while (v); }
561: { int (*v)()=0; do { checkthat(__LINE__, v == 0); } while (v); }
562: { char *v=0; do { checkthat(__LINE__, v == 0); } while (v); }
563: { struct unk *v=0; do { checkthat(__LINE__, v == 0); } while (v); }
564: { enum {z} v=0; do { checkthat(__LINE__, v == 0); } while (v); }
565: { char v=0; do { checkthat(__LINE__, v == 0); } while (v); }
566: { unsigned v=0; do { checkthat(__LINE__, v == 0); } while (v); }
567: i = 10;
568: sum = 0;
569: /* make sure the bounds are computed each time through */
570: do
571: {
572: sum += i;
573: if (--i == 5)
574: i = 0;
575: } while(i);
576: iequals(__LINE__, sum, 40);
577:
578: /* guarantee one execution of the loop */
579: sum = 0;
580: do
581: {
582: i = 0;
583: sum ++;
584: } while(i);
585: iequals(__LINE__, sum, 1);
586:
587: /* the controlling expr is a sequence point */
588: i = ivalue(1);
589: do { } while (i-- == 1); iequals(__LINE__, i, -1);
590: }
591:
592:
593:
594:
595:
596:
597:
598:
599:
600:
601:
602: /*
603: * 3.6.5.3 - The 'for' loop.
604: */
605: static void c3_6_5_3()
606: {
607: int i, j;
608:
609: /* check that the for loop behaves the same as its decomposition */
610: for (i = 0, j = 0; i < 10; ++i)
611: j += i;
612: iequals(__LINE__, j, 45);
613:
614: i = 0; j = 0;
615: while(i < 10)
616: {
617: j += i;
618: ++i;
619: }
620: iequals(__LINE__, j, 45);
621:
622: /* any of the three fields can be left out */
623: i = 0; j = 0;
624: for (; i < 10; ++i)
625: j += i;
626: iequals(__LINE__, j, 45);
627:
628: for (i = 0, j = 0; ; (void)++i)
629: {
630: j += i;
631: if (i >= 10)
632: break;
633: }
634: iequals(__LINE__, j, 55);
635:
636: for (i = 0, (void)(j = 0); i < 10;)
637: {
638: j += i;
639: ++i;
640: }
641: iequals(__LINE__, j, 45);
642:
643: /* a for loop can be jumped into */
644: i = 5, j = 0;
645: goto forloop;
646: for (i = 0, j = 0; i < 10; ++i)
647: forloop: j += i;
648: iequals(__LINE__, j, 35);
649:
650:
651:
652: /* each 'for' line expr is a sequence point */
653: for (i = ivalue(1); i-- ; )
654: iequals(__LINE__, i, 0);
655: } /* end 3.6.5.3 */
656:
657:
658: /*
659: * 3.6.6 - Jump statements
660: */
661:
662: /*
663: * 3.6.6.1 - The goto statement
664: */
665: static void c3_6_6_1()
666: {
667: goto label;
668: complain(__LINE__);
669: {
670: complain(__LINE__);
671: label:;
672: goto label2;
673: complain(__LINE__);
674: }
675: complain(__LINE__);
676: label2: ;
677: }
678:
679:
680:
681:
682:
683:
684:
685:
686:
687:
688:
689:
690:
691:
692:
693:
694:
695:
696:
697:
698:
699:
700:
701:
702: /*
703: * 3.6.6.2 - The 'continue' statement
704: */
705: static void c3_6_6_2()
706: {
707: int i, j, k;
708: /* check them out in for/while/do loops */
709: /* a nested example ... */
710: i = ivalue(0);
711: for (k = 0; k < 3; ++k)
712: {
713: iequals(__LINE__, i, 0);
714: for (i = 0, j = 0; i < 10; ++i)
715: if (i%2)
716: continue;
717: else
718: j += i;
719: iequals(__LINE__, j, 20);
720: i = ivalue(0);
721: }
722:
723: i = ivalue(10);
724: j = ivalue(0);
725: while (--i)
726: if (i%2)
727: continue;
728: else
729: j += i;
730: iequals(__LINE__, j, 20);
731:
732: j = ivalue(0);
733: do
734: if (i%2)
735: continue;
736: else
737: j += i;
738: while (++i < 10);
739: iequals(__LINE__, j, 20);
740: }
741:
742:
743:
744:
745:
746:
747:
748:
749:
750:
751:
752: /*
753: * 3.6.6.3 - The 'break' statement
754: */
755: static void c3_6_6_3()
756: {
757: int i, j, k;
758:
759: /* test in each of for/while/do/switch */
760: /* a nested example ... */
761: for (k = 0; k < 3; ++k)
762: {
763: j = 0;
764: for (i = 0; i < 10; ++i)
765: if (i == 4)
766: break;
767: else
768: j += i;
769: iequals(__LINE__, j, 6);
770: }
771: iequals(__LINE__, k, 3);
772:
773: while (i--)
774: if (i == 1)
775: break;
776: else
777: --j;
778: iequals(__LINE__, j, 4);
779:
780: do
781: if (--j == 3)
782: break;
783: else
784: ++i;
785: while (j);
786: iequals(__LINE__, i, 1);
787:
788: switch(i)
789: {
790: case 1:
791: break;
792: default:
793: i = 99;
794: }
795: iequals(__LINE__, i, 1);
796: }
797:
798:
799:
800:
801:
802: /*
803: * 3.6.6.4 - The 'return' statement
804: */
805: double fc3_664() { return 99; } /* must convert */
806:
807: static void c3_6_6_4()
808: {
809: int i;
810:
811: dequals(__LINE__, fc3_664(), 99.);
812: i = ivalue(0);
813: if (!i)
814: return;
815: complain(__LINE__);
816:
817: /* the expression on the return stmt is a sequence point, */
818: /* but so too is any means of examining its side-effects */
819: }
820:
821: #else /* if SKIP36 */
822:
823: void c3_6() { pr_skip("c3_6: SKIPPED ENTIRELY\n"); }
824: #endif /* SKIP36 */
825:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.