1 /* $NetBSD: msg_129.c,v 1.10 2024/10/29 20:44:22 rillig Exp $ */ 2 # 3 "msg_129.c" 3 4 // Test for message: expression has null effect [129] 5 6 /* lint1-extra-flags: -h -X 351 */ 7 8 typedef unsigned char uint8_t; 9 typedef unsigned int uint32_t; 10 11 _Bool side_effect(void); 12 13 /* 14 * Before tree.c 1.198 from 2021-01-30, the nested comma operators were 15 * wrongly reported as having no side effect. 16 * 17 * The bug was that has_side_effect did not properly examine the sub-nodes. 18 * The ',' operator itself has m_has_side_effect == false since it depends 19 * on its operands whether the ',' actually has side effects. For nested ',' 20 * operators, the function did not evaluate the operands deeply but only did 21 * a quick shallow test on the m_has_side_effect property. Since that is 22 * false, lint thought that the whole expression would have no side effect. 23 */ 24 void 25 uint8_buffer_write_uint32(uint8_t *c, uint32_t l) 26 { 27 (*(c++) = (uint8_t)(l & 0xff), 28 *(c++) = (uint8_t)((l >> 8L) & 0xff), 29 *(c++) = (uint8_t)((l >> 16L) & 0xff), 30 *(c++) = (uint8_t)((l >> 24L) & 0xff)); 31 } 32 33 void 34 operator_comma(void) 35 { 36 side_effect(), 0; /* the 0 is redundant */ 37 /* expect+1: warning: expression has null effect [129] */ 38 0, side_effect(); 39 40 if (side_effect(), 0) /* the 0 controls the 'if' */ 41 return; 42 /* expect+1: warning: expression has null effect [129] */ 43 if (0, side_effect()) 44 return; 45 } 46 47 void 48 legitimate_use_cases(int arg) 49 { 50 int local = 3; 51 52 /* 53 * This expression is commonly used to mark the parameter as 54 * deliberately unused. 55 */ 56 (void)arg; 57 58 /* 59 * This expression is commonly used to mark the local variable as 60 * deliberately unused. This situation occurs when the local 61 * variable is only used in some but not all compile-time selectable 62 * variants of the code, such as in debugging mode, and writing down 63 * the exact conditions would complicate the code unnecessarily. 64 */ 65 (void)local; 66 67 /* This is a shorthand notation for a do-nothing command. */ 68 (void)0; 69 70 /* 71 * At the point where lint checks for expressions having a null 72 * effect, constants have been folded, therefore the following 73 * expression is considered safe as well. It does not appear in 74 * practice though. 75 */ 76 (void)(3 - 3); 77 78 /* 79 * This variant of the do-nothing command is commonly used in 80 * preprocessor macros since it works nicely with if-else and if-then 81 * statements. It is longer than the above variant, and it is not 82 * embeddable into an expression. 83 */ 84 do { 85 } while (0); 86 87 /* 88 * Only the expression '(void)0' is common, other expressions are 89 * unusual enough to warrant a warning. 90 */ 91 /* expect+1: warning: expression has null effect [129] */ 92 (void)13; 93 94 /* Double casts are unusual enough to warrant a warning. */ 95 /* expect+1: warning: expression has null effect [129] */ 96 (void)(void)0; 97 } 98 99 int 100 return_statement_expression(int arg) 101 { 102 ({ 103 int local = arg; 104 local + 4; 105 /* expect+1: warning: expression has null effect [129] */ 106 }); 107 108 if (arg == 1) 109 return ({ 110 int local = arg; 111 // Before cgram.y 1.513 from 2024-10-29, lint wrongly 112 // warned that this expression would have a null effect. 113 local; 114 }); 115 116 if (arg == 2) 117 return ({ 118 int local = arg; 119 // Before cgram.y 1.513 from 2024-10-29, lint wrongly 120 // warned that this expression would have a null effect. 121 local + 4; 122 }); 123 124 return 0; 125 } 126