msg_169.c revision 1.5 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