msg_130.c revision 1.10
11.10Srillig/* $NetBSD: msg_130.c,v 1.10 2021/03/09 23:40:43 rillig Exp $ */ 21.1Srillig# 3 "msg_130.c" 31.1Srillig 41.5Srillig// Test for message: enum type mismatch: '%s' '%s' '%s' [130] 51.1Srillig 61.7Srillig/* See also msg_241.c, which covers unusual operators on enums. */ 71.7Srillig 81.2Srilligenum color { 91.4Srillig RED = 1 << 0, 101.4Srillig GREEN = 1 << 1, 111.4Srillig BLUE = 1 << 2 121.4Srillig}; 131.4Srillig 141.4Srilligenum size { 151.4Srillig SMALL, 161.4Srillig MEDIUM, 171.4Srillig LARGE 181.2Srillig}; 191.2Srillig 201.2Srilligenum daytime { 211.2Srillig NIGHT, MORNING, NOON, EVENING 221.2Srillig}; 231.2Srillig 241.4Srilligvoid sink(_Bool); 251.4Srillig 261.4Srilligvoid 271.4Srilligexample(_Bool cond, enum color c, enum size s) 281.2Srillig{ 291.4Srillig sink(cond ? GREEN : MORNING); /* expect: 130 */ 301.4Srillig 311.4Srillig sink(c != s); /* expect: 130 */ 321.4Srillig sink(c == s); /* expect: 130 */ 331.4Srillig sink((c & MEDIUM) != 0); /* might be useful to warn about */ 341.4Srillig sink((c | MEDIUM) != 0); /* might be useful to warn about */ 351.4Srillig 361.4Srillig c |= MEDIUM; /* might be useful to warn about */ 371.4Srillig c &= MEDIUM; /* might be useful to warn about */ 381.4Srillig 391.4Srillig /* The cast to unsigned is required by GCC at WARNS=6. */ 401.4Srillig c &= ~(unsigned)MEDIUM; /* might be useful to warn about */ 411.2Srillig} 421.6Srillig 431.6Srilligvoid 441.6Srilligswitch_example(enum color c) 451.6Srillig{ 461.6Srillig switch (c) { 471.8Srillig case EVENING: /* expect: 130 */ 481.8Srillig case LARGE: /* expect: 130 */ 491.8Srillig case 0: /* expect: 130 */ 501.6Srillig sink(1 == 1); 511.6Srillig break; 521.6Srillig default: 531.6Srillig break; 541.6Srillig } 551.6Srillig} 561.9Srillig 571.9Srillig/* 581.9Srillig * Unnamed enum types can be used as a container for constants, especially 591.9Srillig * since in C90 and C99, even after the declaration 'static const int x = 3', 601.9Srillig * 'x' is not a constant expression. 611.9Srillig */ 621.9Srilligenum { 631.9Srillig sizeof_int = sizeof(int), 641.9Srillig sizeof_long = sizeof(long) 651.9Srillig}; 661.9Srillig 671.9Srilligenum { 681.9Srillig sizeof_uint = sizeof(unsigned int) 691.9Srillig}; 701.9Srillig 711.9Srilligint 721.9Srilligenum_constant_from_unnamed_type(int x) 731.9Srillig{ 741.9Srillig switch (x) { 751.9Srillig case sizeof_int: /* expect: 130 *//* FIXME */ 761.9Srillig return 1; 771.9Srillig case sizeof_long: /* expect: 130 *//* FIXME */ 781.9Srillig return 2; 791.9Srillig default: 801.9Srillig break; 811.9Srillig } 821.9Srillig 831.9Srillig if (x == sizeof_int) 841.9Srillig return 4; 851.9Srillig if (x > sizeof_int) 861.9Srillig return 5; 871.9Srillig 881.9Srillig if (sizeof_int == sizeof_uint) /* expect: 130 *//* FIXME */ 891.9Srillig return 6; 901.9Srillig 911.9Srillig return 0; 921.9Srillig} 931.10Srillig 941.10Srillig/* 951.10Srillig * A typical legitimate use case for an anonymous enum type that should not 961.10Srillig * be mixed with other types is a state machine. 971.10Srillig * 981.10Srillig * This example demonstrates that the type of the 'switch' expression can be 991.10Srillig * an anonymous enum. 1001.10Srillig */ 1011.10Srilligvoid 1021.10Srilligstate_machine(const char *str) 1031.10Srillig{ 1041.10Srillig enum { 1051.10Srillig begin, 1061.10Srillig seen_letter, 1071.10Srillig seen_letter_digit, 1081.10Srillig error 1091.10Srillig } state = begin; 1101.10Srillig 1111.10Srillig for (const char *p = str; *p != '\0'; p++) { 1121.10Srillig switch (state) { 1131.10Srillig case begin: 1141.10Srillig state = *p == 'A' ? seen_letter : error; 1151.10Srillig break; 1161.10Srillig case seen_letter: 1171.10Srillig state = *p == '1' ? seen_letter_digit : error; 1181.10Srillig break; 1191.10Srillig default: 1201.10Srillig state = error; 1211.10Srillig } 1221.10Srillig } 1231.10Srillig 1241.10Srillig if (state == 2) /* might be worth a warning */ 1251.10Srillig return; 1261.10Srillig if (state == sizeof_int) /* expect: 130 */ 1271.10Srillig return; 1281.10Srillig} 129