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