1 /* $NetBSD: msg_169.c,v 1.5 2021/01/31 11:12:07 rillig Exp $ */ 2 # 3 "msg_169.c" 3 4 // Test for message: precedence confusion possible: parenthesize! [169] 5 6 /* lint1-flags: -g -h -S -w */ 7 8 typedef _Bool bool; 9 10 void 11 confusing_shift_arith(unsigned a, unsigned b, unsigned c, unsigned char ch) 12 { 13 unsigned con, okl, okr; 14 15 con = a + b << c; /* expect: 169 */ 16 okl = (a + b) << c; 17 okr = a + (b << c); 18 19 con = a << b + c; /* expect: 169 */ 20 okl = (a << b) + c; 21 okr = a << (b + c); 22 23 con = a - b >> c; /* expect: 169 */ 24 okl = (a - b) >> c; 25 okr = a - (b >> c); 26 27 con = a >> b - c; /* expect: 169 */ 28 okl = (a >> b) - c; 29 okr = a >> (b - c); 30 31 // Parenthesizing the inner operands has no effect on the warning. 32 con = (a) + b << c; /* expect: 169 */ 33 con = a + (b) << c; /* expect: 169 */ 34 con = a + b << (c); /* expect: 169 */ 35 36 // The usual arithmetic promotions have no effect on the warning. 37 con = ch + b << c; /* expect: 169 */ 38 con = a + ch << c; /* expect: 169 */ 39 con = a + b << ch; /* expect: 169 */ 40 } 41 42 void 43 confusing_logical(bool a, bool b, bool c) 44 { 45 bool con, okl, okr, eql; 46 47 eql = a && b && c; 48 eql = a || b || c; 49 50 con = a && b || c; /* expect: 169 */ 51 okl = (a && b) || c; 52 okr = a && (b || c); 53 54 con = a || b && c; /* expect: 169 */ 55 okl = (a || b) && c; 56 okr = a || (b && c); 57 } 58 59 void 60 confusing_bitwise(unsigned a, unsigned b, unsigned c) 61 { 62 bool con, okl, okr, eql; 63 64 eql = a & b & c; 65 eql = a | b | c; 66 eql = a ^ b ^ c; 67 68 con = a | b ^ c; /* expect: 169 */ 69 okl = (a | b) ^ c; 70 okr = a | (b ^ c); 71 72 con = a | b & c; /* expect: 169 */ 73 okl = (a | b) & c; 74 okr = a | (b & c); 75 76 con = a ^ b | c; /* expect: 169 */ 77 okl = (a ^ b) | c; 78 okr = a ^ (b | c); 79 80 con = a ^ b & c; /* expect: 169 */ 81 okl = (a ^ b) & c; 82 okr = a ^ (b & c); 83 84 con = a & b | c; /* expect: 169 */ 85 okl = (a & b) ^ c; 86 okr = a & (b ^ c); 87 88 con = a & b ^ c; /* expect: 169 */ 89 okl = (a & b) ^ c; 90 okr = a & (b ^ c); 91 92 con = a & b + c; /* expect: 169 */ 93 okl = (a & b) + c; 94 okr = a & (b + c); 95 96 con = a - b | c; /* expect: 169 */ 97 okl = (a - b) | c; 98 okr = a - (b | c); 99 100 // This looks like a binomial formula but isn't. 101 con = a ^ 2 - 2 * a * b + b ^ 2; /* expect: 169 */ 102 103 // This isn't a binomial formula either since '^' means xor. 104 con = (a ^ 2) - 2 * a * b + (b ^ 2); 105 } 106 107 void 108 constant_expressions(void) 109 { 110 unsigned con; 111 112 // The check for confusing precedence happens after constant folding. 113 // Therefore the following lines do not generate warnings. 114 con = 1 & 2 | 3; 115 con = 4 << 5 + 6; 116 con = 7 ^ 8 & 9; 117 } 118 119 void 120 cast_expressions(char a, char b, char c) 121 { 122 unsigned con; 123 124 // Adding casts to the leaf nodes doesn't change anything about the 125 // confusing precedence. 126 con = (unsigned)a | (unsigned)b & (unsigned)c; /* expect: 169 */ 127 con = (unsigned)a & (unsigned)b | (unsigned)c; /* expect: 169 */ 128 129 // Adding a cast around the whole calculation doesn't change the 130 // precedence as well. 131 con = (unsigned)(a | b & c); /* expect: 169 */ 132 133 // Adding a cast around an intermediate result groups the operands 134 // of the main node, which prevents any confusion about precedence. 135 con = (unsigned)a | (unsigned)(b & c); 136 con = a | (unsigned)(b & c); 137 con = (unsigned)(a | b) & (unsigned)c; 138 con = (unsigned)(a | b) & c; 139 } 140 141 void 142 expected_precedence(int a, int b, int c) 143 { 144 int ok; 145 146 ok = a + b * c; 147 } 148 149 void 150 implicit_conversion_to_long(long la, int a) 151 { 152 int ok; 153 154 ok = a & a | la; /* expect: 169 */ 155 156 /* 157 * Before tree.c 1.132 from 2021-01-04, there was a typo in 158 * check_precedence_confusion that prevented the right-hand operand 159 * from being flagged as possibly confusing if there was an implicit 160 * conversion or an explicit cast between the main operator ('|') and 161 * the nested operator ('&'). 162 */ 163 ok = la | a & a; /* expect: 169 */ 164 165 ok = (a & a) | la; /* always ok */ 166 ok = la | (a & a); /* always ok */ 167 168 /* 169 * Before tree.c 1.132, this expression didn't generate a warning 170 * because the right-hand operand was CVT, and there is no confusing 171 * precedence between BITOR and CVT. 172 * 173 * Since tree.c 1.132, this expression doesn't generate a warning 174 * because the right-hand operand is parenthesized. There is no way 175 * to have the right operand casted and at the same time not 176 * parenthesized since the cast operator has higher precedence. 177 * 178 * In summary, there is no visible change, but the implementation is 179 * now works as intended. 180 */ 181 ok = la | (int)(a & a); /* always ok */ 182 } 183