|
|
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 SKIP33B
12: /*
13: * c33b.c - extension of 3.3 (Expressions).
14: */
15: #include "defs.h"
16: static void c3_3_5();
17: static void c3_3_6();
18: static void c3_3_7();
19: static void c3_3_8();
20: static void c3_3_9();
21: static void c3_3_10();
22: static void c3_3_11();
23: static void c3_3_12();
24: static void c3_3_13();
25: static void c3_3_14();
26: static void c3_3_15();
27: static void c3_3_16();
28: static void c3_3_16_1();
29: static void c3_3_16_2();
30: static void c3_3_17();
31: static long larray[10] = {0,1,2,3,4,5,6,7,8,9};
32: void c3_3b()
33: {
34: Filename = "c33b.c";
35: c3_3_5();
36: c3_3_6();
37: c3_3_7();
38: c3_3_8();
39: c3_3_9();
40: c3_3_10();
41: c3_3_11();
42: c3_3_12();
43: c3_3_13();
44: c3_3_14();
45: c3_3_15();
46: c3_3_16();
47: c3_3_16_1((generic_ptr)Filename);
48: c3_3_16_2();
49: c3_3_17();
50: }
51:
52: /*
53: * 3.3.5 - Multiplicative operators
54: */
55: static void c3_3_5()
56: {
57: double d = 1.9, e = 2.7;
58: int i = 4, j = 7;
59:
60: /* commutativity */
61: iequals(__LINE__, i*j, j*i);
62:
63: /* associates L->R */
64: dequals(__LINE__, j % i * d, d * 3);
65:
66: /* "usual arith conversions" (ANSI) are value-preserving */
67: #if ANSI
68: {
69: unsigned char uc = 5;
70:
71: #if MAX_UCHAR <= MAX_INT
72: checkthat(__LINE__, uc / -2 == -3 || uc / -2 == -2);
73: #endif
74: }
75: #endif
76:
77: /* positive result of division must round toward 0 */
78: iequals(__LINE__, j / i, 1);
79: iequals(__LINE__, -j / -i, 1);
80:
81: /* mixed mode arithmetic -- this is done as double */
82: iequals(__LINE__, (int)(d * i), 7);
83: iequals(__LINE__, (int)(i * d), 7);
84: iequals(__LINE__, (int)(i / d), 2);
85:
86: /* but not this */
87: iequals(__LINE__, i % (int)e, 0);
88:
89: /* definitive property */
90: iequals(__LINE__, (i/j)*j + i%j, i);
91: i = -4;
92: iequals(__LINE__, (i/j)*j + i%j, i);
93:
94: }
95:
96:
97:
98:
99:
100:
101:
102: /*
103: * 3.3.6 - Additive operators
104: */
105: static void c3_3_6()
106: {
107: double d = 4.2;
108: long *pd1, *pd2;
109: int i = 1;
110:
111: /* check out mixed mode addition/subtraction */
112: dequals(__LINE__, d+ivalue(7), 11.2);
113:
114: /* adding/subtracting an integral expression from a pointer */
115: pd1 = &larray[4];
116: pd2 = &larray[7];
117: lequals(__LINE__, *(pd1 - ivalue(3)), 1L);
118: lequals(__LINE__, *(pd2 - ivalue(3)), 4L);
119:
120: /* pointer - pointer */
121: iequals(__LINE__, pd2 - pd1, 3);
122: iequals(__LINE__, pd1 - pd2, -3);
123: pd1 = &larray[9];
124: pd2 = pd1 + 1;
125: checkthat(__LINE__, pd2 - pd1 == 1);
126:
127: /* no re-grouping, except by "as-if" rule */
128: #if ANSI
129: {
130: unsigned ui = MAX_UINT;
131: ULONG ul = 0;
132: double d1 = dvalue((DBL_MAX/3.)*2. + DBL_MAX/10.);
133:
134: ul = (ui + 1) + ul;
135: checkthat(__LINE__, ul == 0L);
136: #define SUM (d1 + -(DBL_MAX/3.)*2.)
137: dequals(__LINE__, SUM + SUM, dvalue(DBL_MAX/10. + DBL_MAX/10.)); /* no re-grouping */
138: }
139: #endif
140: } /* end c3_3_6 */
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152: /*
153: * 3.3.7 - Bitwise shift operators
154: */
155: static void c3_3_7()
156: {
157: unsigned char c = 1;
158: int i = 4;
159: unsigned int ui = 0xffff;
160: int count;
161:
162: /* how many bits in a char ? */
163: for (count = 0; c; c <<= 1, ++count)
164: ;
165: /* bits in a long */
166: count *= sizeof(long);
167:
168: #if !ANSI
169: /* before ANSI, if either operand was long, the shift was long */
170: lequals(__LINE__, 1 << (count - 1L), 1L << (long)(count - 1L));
171: #else
172: iequals(__LINE__, sizeof(c << 2L), sizeof(int));
173: iequals(__LINE__, count, CHAR_BIT * sizeof(long));
174: #endif
175:
176: /* make sure that 'vacated bits' are filled with 0 */
177: checkthat(__LINE__, ((int)0xff << i) == (int)0xff0);
178:
179: /* shift of unsigned must 0 fill */
180: iequals(__LINE__, (ui >> i), (int)0x0fff);
181:
182: /* right shift of signed item -- behavior is implem-defined */
183: checkthat( - __LINE__, (~0 >> 1) == ~0 || (~0 >> 1) == ((unsigned)~0 >> 1));
184: }
185:
186:
187:
188:
189:
190:
191:
192:
193:
194:
195:
196:
197:
198:
199:
200:
201:
202: /*
203: * 3.3.8 - Relational operators
204: */
205: static void c3_3_8()
206: {
207: long *pl1 = &larray[3];
208: long *pl2 = &larray[5];
209: double d = 11.0;
210: unsigned ui1 = 5;
211: int i = -2;
212:
213: /* (non-intuitive?) integer promotions */
214: checkthat(__LINE__, ui1 < i);
215:
216: /* value context */
217: iequals(__LINE__, pl1 < pl2, 1);
218: iequals(__LINE__, d > *pl1, 1);
219: iequals(__LINE__, pl1 <= pl2, 1);
220: iequals(__LINE__, d >= *pl1, 1);
221:
222: /* condition context */
223: if(pl1 < pl2)
224: ;
225: else
226: complain(__LINE__);
227: if(d > *pl1)
228: ;
229: else
230: complain(__LINE__);
231:
232: if(pl1 <= pl2)
233: ;
234: else
235: complain(__LINE__);
236: if(d >= *pl1)
237: ;
238: else
239: complain(__LINE__);
240:
241: /* check out associativity */
242: iequals(__LINE__, pl1[0] < d < pl1[1] , 1);
243: iequals(__LINE__, pl1[0] < d < 1 , 0);
244: iequals(__LINE__, pl1[0] < d <= 1 , 1);
245: iequals(__LINE__, *pl1 > d >= 0, 1);
246:
247:
248:
249:
250:
251:
252: #if ANSI8706 /* 3.3.8 (cont.) */
253: {
254: struct known { int i; } s = {0};
255: struct unknown *psu;
256: void *gp; volatile void *vgp;
257:
258: psu = (struct unknown *)&s;
259: vgp = gp = psu;
260: checkthat(__LINE__, gp == psu);
261: iequals(__LINE__, gp < vgp, 0);
262: iequals(__LINE__, (const struct unknown *)psu < (struct unknown *)avalue(psu), 0);
263: }
264: #endif
265: #if ANSI8709
266: iequals(__LINE__, (const char *)avalue(pl1) < (char *)avalue(pl1), 0);
267: #endif
268:
269: /* special cases for "last-plus-one" members */
270: {
271: long a[10];
272: long *p = &a[9];
273: iequals(__LINE__, &a[9] < &a[10], 1);
274: iequals(__LINE__, p+1 > p, 1);
275: iequals(__LINE__, p+1 < p, 0);
276: iequals(__LINE__, &a[9] < a+10 , 1);
277: }
278:
279: /* result has type int */
280: #if ANSI
281: { double x=0, y=0; iequals(__LINE__, sizeof(x < y), sizeof(int)); }
282: #endif
283: } /* end c3_3_8 */
284:
285:
286:
287:
288:
289:
290:
291:
292:
293:
294:
295:
296:
297:
298:
299:
300:
301:
302: /*
303: * 3.3.9 - Equality operators
304: */
305: static void c3_3_9()
306: {
307: long *pl1 = &larray[4];
308: long *pl2 = &larray[6];
309: generic_ptr gp = (generic_ptr)pl1;
310: void (*p3_8)() = c3_3_8;
311: void (*p3_9)() = c3_3_9;
312:
313: /* equality of pointers */
314: checkthat(__LINE__, p3_8 == c3_3_8);
315: checkthat(__LINE__, p3_9 != c3_3_8);
316: #if ANSI
317: checkthat(__LINE__, gp == pl1);
318: #else
319: checkthat(__LINE__, gp == (generic_ptr)pl1);
320: #endif
321: #if ANSI8709
322: checkthat(__LINE__, (char *)pl1 == (void *)pl1);
323: checkthat(__LINE__, (const char *)pl1 == (char *)pl1);
324: checkthat(__LINE__, pl1 != (void *)0);
325: checkthat(__LINE__, pl1 != (const void *)pl2);
326: #endif
327:
328: /* value context */
329: iequals(__LINE__, pl1 == &larray[4], 1);
330: iequals(__LINE__, pl1 == pl2, 0);
331: iequals(__LINE__, pl1 != 0, 1);
332: iequals(__LINE__, *pl1 != *pl2, 1);
333:
334: /* condition context */
335: if (pl1 == &larray[4])
336: ;
337: else
338: complain(__LINE__);
339:
340: if (pl1 != pl2)
341: ;
342: else
343: complain(__LINE__);
344: if (pl1 != 0)
345: ;
346: else
347: complain(__LINE__);
348: if (*pl1 != *pl2)
349: ;
350: else
351: complain(__LINE__);
352: /* 3.3.9 (cont.) */
353: /* associativity */
354: iequals(__LINE__, *pl1 == *pl2 == 1, 0);
355: iequals(__LINE__, *pl1 != *pl2 == 1, 1);
356: iequals(__LINE__, pl1 < pl2 != pl2 < pl1, 1);
357:
358: /* result has type int */
359: #if ANSI
360: { double x=0, y=0; iequals(__LINE__, sizeof(x != y), sizeof(int)); }
361: #endif
362: }
363:
364:
365:
366:
367:
368:
369:
370:
371:
372:
373:
374:
375:
376:
377:
378:
379:
380:
381:
382:
383:
384:
385:
386:
387:
388:
389:
390:
391:
392:
393:
394:
395:
396:
397:
398:
399:
400:
401:
402: /*
403: * 3.3.10 - Bitwise AND operator
404: */
405: static void c3_3_10()
406: {
407: int a = 7, b = 2;
408: long l = 6;
409: #if ANSI
410: iequals(__LINE__, sizeof(a & l), sizeof(long));
411: #endif
412: lequals(__LINE__, a & l, 6L);
413: iequals(__LINE__, a & b, 2);
414: iequals(__LINE__, b & a, 2);
415: iequals(__LINE__, a & 0, 0);
416: iequals(__LINE__, a & ~0, a);
417: }
418: /*
419: * 3.3.11 - Bitwise exclusive OR operator
420: */
421: static void c3_3_11()
422: {
423: int a = 7, b = 2;
424: long l = 6;
425: #if ANSI
426: iequals(__LINE__, sizeof(a ^ l), sizeof(long));
427: #endif
428: lequals(__LINE__, a ^ l, 1L);
429: iequals(__LINE__, a ^ b, 5);
430: iequals(__LINE__, b ^ a, 5);
431: a = a^b; b = a^b; a = a^b; /* swap a and b */
432: iequals(__LINE__, a, 2);
433: iequals(__LINE__, b, 7);
434: }
435: /*
436: * 3.3.12 - Bitwise OR operator
437: */
438: static void c3_3_12()
439: {
440: int a = 5, b = 2;
441: long l = 6;
442: #if ANSI
443: iequals(__LINE__, sizeof(a | l), sizeof(long));
444: #endif
445: lequals(__LINE__, a | l, 7L);
446: iequals(__LINE__, a | b, 7);
447: iequals(__LINE__, b | a, 7);
448: iequals(__LINE__, a | 0, a);
449: iequals(__LINE__, a | ~0, ~0);
450: }
451:
452: /*
453: * 3.3.13 - Logical AND operator
454: */
455: static void c3_3_13()
456: {
457: int zero = 0;
458: int one = 1;
459: extern int Side;
460:
461: /* side effect checks in a value producing context */
462: Side = 0;
463: scheck(__LINE__, ++Side && zero, 1, 0);
464: scheck(__LINE__, ++Side && one, 1, 1);
465: scheck(__LINE__, zero && ++Side, 0, 0);
466: scheck(__LINE__, one && ++Side, 1, 1);
467:
468: /* side effects in a condition producing context */
469: if (++Side && zero)
470: complain(__LINE__);
471: iequals(__LINE__, Side--, 1);
472:
473: if (++Side && one)
474: ;
475: else
476: complain(__LINE__);
477: iequals(__LINE__, Side--, 1);
478:
479: if (zero && ++Side)
480: complain(__LINE__);
481: iequals(__LINE__, Side, 0);
482:
483: if (one && ++Side)
484: ;
485: else
486: complain(__LINE__);
487: iequals(__LINE__, Side--, 1);
488:
489: #if ANSI
490: /* result is of type int */
491: { double x=0, y=0; iequals(__LINE__, sizeof(x && y), sizeof(int)); }
492: #endif
493: /* operands are of scalar type */
494: { double x=0, y=0; iequals(__LINE__, x && y, 0); }
495: { generic_ptr x=0, y=0; iequals(__LINE__, x && y, 0); }
496: { enum {z} x=0, y=0; iequals(__LINE__, x && y, 0); }
497: } /* end c3_3_14 */
498:
499:
500:
501:
502: /*
503: * 3.3.14 - Logical OR operator
504: */
505: static void c3_3_14()
506: {
507: int zero = 0;
508: int one = 1;
509: extern int Side;
510:
511: /* side effect checks in a value producing context */
512: Side = 0;
513: scheck(__LINE__, ++Side || zero, 1, 1);
514: scheck(__LINE__, ++Side || one, 1, 1);
515: scheck(__LINE__, zero || ++Side, 1, 1);
516: scheck(__LINE__, one || ++Side, 0, 1);
517:
518: /* side effects in a condition producing context */
519: if (++Side || zero)
520: ;
521: else
522: complain(__LINE__);
523: iequals(__LINE__, Side--, 1);
524:
525: if (++Side || one)
526: ;
527: else
528: complain(__LINE__);
529: iequals(__LINE__, Side--, 1);
530:
531: if (zero || ++Side)
532: ;
533: else
534: complain(__LINE__);
535: iequals(__LINE__, Side--, 1);
536:
537: if (one || ++Side)
538: ;
539: else
540: complain(__LINE__);
541: iequals(__LINE__, Side, 0);
542:
543: #if ANSI
544: /* result is of type int */
545: { double x=0, y=0; iequals(__LINE__, sizeof(x || y), sizeof(int)); }
546: #endif
547: /* operands are of scalar type */
548: { double x=0, y=0; iequals(__LINE__, x || y, 0); }
549: { generic_ptr x=0, y=0; iequals(__LINE__, x || y, 0); }
550: { enum {z} x=0, y=0; iequals(__LINE__, x || y, 0); }
551: } /* end c3_3_13 */
552: /*
553: * 3.3.15 - Conditional operator
554: */
555: static int If1, If2;
556: void f1(){If1 = 7;}
557: void f2(){If2 = 11;}
558: static int iarray[] = {7, 11};
559: static void c3_3_15()
560: {
561: int one = ivalue(1), zero = ivalue(0);
562: int *p1 = &one, *p0 = &zero;
563: generic_ptr gp = (generic_ptr)p1;
564: extern int Side;
565: char *pc;
566:
567: Side = 0;
568: /* side effect checks in a value producing context */
569: scheck(__LINE__, ++Side ? one : zero, 1, 1);
570: scheck(__LINE__, zero ? one : ++Side, 1, 1);
571: scheck(__LINE__, one ? one : ++Side, 0, 1);
572:
573: /* side effects in a condition producing context */
574: if (++Side ? one : zero)
575: ;
576: else
577: complain(__LINE__);
578: iequals(__LINE__, Side--, 1);
579:
580: if (zero ? one : ++Side)
581: ;
582: else
583: complain(__LINE__);
584: iequals(__LINE__, Side--, 1);
585:
586: if (one ? ++Side: zero)
587: ;
588: else
589: complain(__LINE__);
590: iequals(__LINE__, Side, 1);
591:
592: #if ANSI8709
593: checkthat(__LINE__, (one ? Side=5 : 6) == 5);
594: checkthat(__LINE__, (one ? 2,3 : 4) == 3);
595: checkthat(__LINE__, (one ? (char *)p1 : (const char *)p0) == (const char *)p1);
596: checkthat(__LINE__, (one ? (char *)p1 : (void *)p0) == /* (void *) */ p1);
597: pc = zero ? (char *)p1 : 0;
598: checkthat(__LINE__, pc == 0);
599: { double x=0; char y=1; checkthat(__LINE__, sizeof(one ? x : y) == sizeof(x) && (one ? x : y) == 0); }
600: #endif
601:
602: /* arms can be scalar, void, struct, pointer */ /* 3.3.15 (cont.) */
603: iequals(__LINE__, one ? one : zero, one);
604: iequals(__LINE__, zero ? one : zero, zero);
605: aequals(__LINE__, one ? p1 : p0, p1);
606: aequals(__LINE__, zero ? p1 : p0, p0);
607: aequals(__LINE__, one ? NULL : p0, NULL);
608: aequals(__LINE__, zero ? p1 : NULL, NULL);
609: iequals(__LINE__, *(one ? p1 : p0), 1);
610: iequals(__LINE__, *(zero ? p1 : p0), 0);
611: #if ANSI
612: aequals(__LINE__, one ? gp : p0, gp);
613: checkthat(__LINE__, (zero ? &f1 : 0) == 0);
614: #endif
615: checkthat(__LINE__, (one ? f1 : 0) == f1);
616: #if ANSI
617: /* function calls in both arms -- only one should be called */
618: If1 = If2 = 0;
619: one ? f1(): f2();
620: iequals(__LINE__, If1, 7);
621: iequals(__LINE__, If2, 0);
622: If1 = If2 = 0;
623: zero ? f1(): f2();
624: iequals(__LINE__, If1, 0);
625: iequals(__LINE__, If2, 11);
626: #endif
627: /* function pointers in both arms */
628: If1 = If2 = 0;
629: (*(one ? f1 : f2))();
630: iequals(__LINE__, If1, 7);
631: iequals(__LINE__, If2, 0);
632: If1 = If2 = 0;
633: (*(zero ? f1 : f2))();
634: iequals(__LINE__, If1, 0);
635: iequals(__LINE__, If2, 11);
636:
637: /* struct/union in arms are tested in structures() in c33c.c */
638:
639: /* check out nested question ops */
640: iequals(__LINE__,
641: zero ? 1 : zero ? 2 : zero ? 3 : zero ? 4 : 5, 5);
642: iequals(__LINE__,
643: one ? one ? one ? one ? one ? 1 : 2 : 3 : 4 : 5 : 6, 1);
644:
645: /* questions as array indexes */
646: iequals(__LINE__, iarray[zero ? zero : one], 11);
647: iequals(__LINE__, iarray[one ? zero : one], 7);
648:
649:
650:
651:
652: /* question in a switch */ /* 3.3.15 (cont.) */
653: switch (one ? one : zero)
654: {
655: case 1 :
656: break;
657: default :
658: complain(__LINE__);
659: }
660:
661: /* conditional is a sequence point */
662: {
663: int i = ivalue(1);
664:
665: iequals(__LINE__, i++ == 1 ? i : 0, ivalue(2));
666: iequals(__LINE__, i++ != 2 ? 0 : i, ivalue(3));
667: }
668:
669: } /* end c3_3_15 */
670:
671:
672:
673:
674:
675:
676:
677:
678:
679:
680:
681: /*
682: * 3.3.16 - Assignment operators
683: */
684: static void c3_3_16()
685: {
686: int i = 3;
687: double d = 4.0;
688: /* takes type and value from the left operand */
689: iequals(__LINE__, i = d, 4);
690: i = 2;
691: dequals(__LINE__, d = i, 2.0);
692: iequals(__LINE__, i += d, 4);
693: #if ANSI
694: { char x=0; double y=1; checkthat(__LINE__, sizeof(x = y) == sizeof(x) && (x = y) == 1); }
695: #endif
696: }
697:
698:
699:
700:
701:
702: /*
703: * 3.3.16.1 - Simple assignment
704: */
705: static void c3_3_16_1(q)
706: generic_ptr q;
707: {
708: char *p;
709: unsigned ui;
710:
711: #if ANSI8712
712: struct unk; /* structure of unkown contents */
713:
714: /* The constraints for assignment are quite detailed:
715: * Define a "sufficiently-qualified" (or "suf-qual") left operand type
716: * to be one that has all the qualifiers of the type pointed to by the
717: * right operand (and perhaps others).
718: * Let qual=qualified, arith=arithmetic, ptr=pointer.
719: * Then, as the Standard says, one of the folllowing
720: * shall hold:
721:
722: Left operand Right operand
723: 1. qual arith type arith type
724: 2. unqual arith type arith type
725: 3. qual struct type compatible struct type
726: 4. qual union type compatible union type
727: 5. unqual struct type compatible struct type
728: 6. unqual union type compatible union type
729: 7. ptr to suf-qual type ptr to compatible qual type
730: 8. ptr to suf-qual type ptr to compatible unqual type
731: 9. ptr to suf-qual object ptr to qual void
732: 10. ptr to suf-qual object ptr to unqual void
733: 11. ptr to suf-qual incomplete ptr to qual void
734: 12. ptr to suf-qual incomplete ptr to unqual void
735: 13. any ptr null ptr constant ...
736: */
737: /* 1 */ { volatile int a; int b={1}; a = b; iequals(__LINE__, a, b); }
738: /* 2 */ { int a; int b={2}; a = b; iequals(__LINE__, a, b); }
739: /* 3 */ { volatile struct s {int i;} a; struct s b={3}; a = b; iequals(__LINE__, a.i, b.i); }
740: /* 4 */ { volatile union u {int i;} a; union u b={4}; a = b; iequals(__LINE__, a.i, b.i); }
741: /* 5 */ { struct s {int i;} a; struct s b={5}; a = b; iequals(__LINE__, a.i, b.i); }
742: /* 6 */ { union u {int i;} a; union u b={6}; a = b; iequals(__LINE__, a.i, b.i); }
743: /* 7 */ { const int *a; const signed *b=q; a = b; aequals(__LINE__, a, b); }
744: /* 8 */ { const int *a; signed *b=q; a = b; aequals(__LINE__, a, b); }
745: /* 9 */ { const int *a; const void *b=q; a = b; aequals(__LINE__, a, (int *)b); }
746: /* 10*/ { volatile int *a; void *b=q; a = b; aequals(__LINE__, (int *)a, (int *)b); }
747: /* 11*/ { const struct unk *a; const void *b=q; a = b; aequals(__LINE__, a, (struct unk *)b); }
748: /* 12*/ { struct unk *a; void *b=q; a = b; aequals(__LINE__, a, (struct unk *)b); }
749: /* 13*/ { struct unk *a; a = (void *)0L; aequals(__LINE__, a, 0); }
750: #endif
751:
752: /* struct/union assignments are done in structures() in c33c.c */
753: /* 3.3.16.1 (cont.) */
754:
755: /* assignment of pointers */
756: p = q;
757: aequals(__LINE__, p, Filename);
758: q = 0L;
759: aequals(__LINE__, q, NULL);
760: q = p;
761: aequals(__LINE__, p, q);
762:
763: /* integral constant expression with value 0 */
764: p = 0;
765: aequals(__LINE__, p, NULL);
766:
767: #if (V7 || ANSI)
768: {
769: UCHAR c;
770:
771: /* right side values are converted to the type on the left */
772: c = MAX_ULONG;
773: iequals(__LINE__, c, MAX_UCHAR);
774: }
775: #endif
776:
777: /* right side values are converted to the type on the left */
778: ui = MAX_ULONG;
779: checkthat(__LINE__, ui == MAX_UINT);
780: }
781:
782:
783:
784:
785:
786:
787:
788:
789:
790:
791:
792:
793:
794:
795:
796:
797:
798:
799:
800:
801:
802:
803: /*
804: * 3.3.16.2 - Compound assignment
805: */
806: static int *fpi() { ++If1; return & If2;}
807: static void c3_3_16_2()
808: {
809: long *pl1 = &larray[4];
810: long *pl2 = &larray[6];
811: char c = 10;
812: double d = 1.21;
813:
814: /* allow pointer ops on += and -= */
815: aequals(__LINE__, pl1+=2, pl2);
816: aequals(__LINE__, pl1-=6, larray);
817: /* make sure that the left side is only evaluated once */
818: If2 = ivalue(5);
819: If1 = ivalue(0);
820: *fpi()*=2;
821: iequals(__LINE__, If1, 1);
822: iequals(__LINE__, If2, 10);
823: *fpi()/=2;
824: iequals(__LINE__, If1, 2);
825: iequals(__LINE__, If2, 5);
826: *fpi()%=2;
827: iequals(__LINE__, If1, 3);
828: iequals(__LINE__, If2, 1);
829: *fpi()+=2;
830: iequals(__LINE__, If1, 4);
831: iequals(__LINE__, If2, 3);
832: *fpi()-=2;
833: iequals(__LINE__, If1, 5);
834: iequals(__LINE__, If2, 1);
835: *fpi()<<=2;
836: iequals(__LINE__, If1, 6);
837: iequals(__LINE__, If2, 4);
838: *fpi()>>=2;
839: iequals(__LINE__, If1, 7);
840: iequals(__LINE__, If2, 1);
841: *fpi()&=7;
842: iequals(__LINE__, If1, 8);
843: iequals(__LINE__, If2, 1);
844: *fpi()^=7;
845: iequals(__LINE__, If1, 9);
846: iequals(__LINE__, If2, 6);
847: *fpi()|=1;
848: iequals(__LINE__, If1, 10);
849: iequals(__LINE__, If2, 7);
850:
851:
852: /* 3.3.16.2 (cont.) */
853: /* make sure that mixed mode ops are done right */
854: iequals(__LINE__, c *= d, 12);
855: iequals(__LINE__, c /= d, 9);
856: }
857:
858: /*
859: * 3.3.17 - Comma operator
860: */
861: static void c3_3_17()
862: {
863: If1 = ivalue(0);
864: iequals(__LINE__, (If1++,If1++,If1++,If1++,If1++,If1++,0), 0);
865: iequals(__LINE__, If1, 6);
866: iequals(__LINE__, (If1 = 6, If1 >>= 1, If1 + 2), 5);
867: If2 = ivalue(5);
868: If1 = ivalue(0);
869: iequals(__LINE__, (*fpi(), If1), 1);
870: #if ANSI8809
871: {
872: char arr[100];
873: char c;
874:
875: /* array-conversion takes place in comma (3.2.2.1 doesn't mention it), ... */
876: /* but integral conversions do not take place (because no mention in Semantics of comma */
877: iequals(__LINE__, sizeof(0,arr), sizeof(&arr[0]));
878: iequals(__LINE__, sizeof(0,c), ivalue(1));
879: }
880: #endif
881: }
882:
883: #else /* if SKIP33B */
884:
885: void c3_3b() { pr_skip("c3_3b: SKIPPED ENTIRELY\n"); }
886: #endif /* SKIP33B */
887:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.