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