|
|
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.