msg_169.c revision 1.5 1 1.5 rillig /* $NetBSD: msg_169.c,v 1.5 2021/01/31 11:12:07 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.5 rillig con = a + b << c; /* expect: 169 */
16 1.2 rillig okl = (a + b) << c;
17 1.2 rillig okr = a + (b << c);
18 1.2 rillig
19 1.5 rillig con = a << b + c; /* expect: 169 */
20 1.2 rillig okl = (a << b) + c;
21 1.2 rillig okr = a << (b + c);
22 1.2 rillig
23 1.5 rillig con = a - b >> c; /* expect: 169 */
24 1.2 rillig okl = (a - b) >> c;
25 1.2 rillig okr = a - (b >> c);
26 1.2 rillig
27 1.5 rillig con = a >> b - c; /* expect: 169 */
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.5 rillig con = (a) + b << c; /* expect: 169 */
33 1.5 rillig con = a + (b) << c; /* expect: 169 */
34 1.5 rillig con = a + b << (c); /* expect: 169 */
35 1.2 rillig
36 1.2 rillig // The usual arithmetic promotions have no effect on the warning.
37 1.5 rillig con = ch + b << c; /* expect: 169 */
38 1.5 rillig con = a + ch << c; /* expect: 169 */
39 1.5 rillig con = a + b << ch; /* expect: 169 */
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.5 rillig con = a && b || c; /* expect: 169 */
51 1.2 rillig okl = (a && b) || c;
52 1.2 rillig okr = a && (b || c);
53 1.2 rillig
54 1.5 rillig con = a || b && c; /* expect: 169 */
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.5 rillig con = a | b ^ c; /* expect: 169 */
69 1.2 rillig okl = (a | b) ^ c;
70 1.2 rillig okr = a | (b ^ c);
71 1.2 rillig
72 1.5 rillig con = a | b & c; /* expect: 169 */
73 1.2 rillig okl = (a | b) & c;
74 1.2 rillig okr = a | (b & c);
75 1.2 rillig
76 1.5 rillig con = a ^ b | c; /* expect: 169 */
77 1.2 rillig okl = (a ^ b) | c;
78 1.2 rillig okr = a ^ (b | c);
79 1.2 rillig
80 1.5 rillig con = a ^ b & c; /* expect: 169 */
81 1.2 rillig okl = (a ^ b) & c;
82 1.2 rillig okr = a ^ (b & c);
83 1.2 rillig
84 1.5 rillig con = a & b | c; /* expect: 169 */
85 1.2 rillig okl = (a & b) ^ c;
86 1.2 rillig okr = a & (b ^ c);
87 1.2 rillig
88 1.5 rillig con = a & b ^ c; /* expect: 169 */
89 1.2 rillig okl = (a & b) ^ c;
90 1.2 rillig okr = a & (b ^ c);
91 1.2 rillig
92 1.5 rillig con = a & b + c; /* expect: 169 */
93 1.2 rillig okl = (a & b) + c;
94 1.2 rillig okr = a & (b + c);
95 1.2 rillig
96 1.5 rillig con = a - b | c; /* expect: 169 */
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.5 rillig con = a ^ 2 - 2 * a * b + b ^ 2; /* expect: 169 */
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.5 rillig con = (unsigned)a | (unsigned)b & (unsigned)c; /* expect: 169 */
127 1.5 rillig con = (unsigned)a & (unsigned)b | (unsigned)c; /* expect: 169 */
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.5 rillig con = (unsigned)(a | b & c); /* expect: 169 */
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 void
150 1.4 rillig implicit_conversion_to_long(long la, int a)
151 1.4 rillig {
152 1.4 rillig int ok;
153 1.4 rillig
154 1.5 rillig ok = a & a | la; /* expect: 169 */
155 1.5 rillig
156 1.5 rillig /*
157 1.5 rillig * Before tree.c 1.132 from 2021-01-04, there was a typo in
158 1.5 rillig * check_precedence_confusion that prevented the right-hand operand
159 1.5 rillig * from being flagged as possibly confusing if there was an implicit
160 1.5 rillig * conversion or an explicit cast between the main operator ('|') and
161 1.5 rillig * the nested operator ('&').
162 1.5 rillig */
163 1.5 rillig ok = la | a & a; /* expect: 169 */
164 1.4 rillig
165 1.4 rillig ok = (a & a) | la; /* always ok */
166 1.4 rillig ok = la | (a & a); /* always ok */
167 1.4 rillig
168 1.4 rillig /*
169 1.4 rillig * Before tree.c 1.132, this expression didn't generate a warning
170 1.4 rillig * because the right-hand operand was CVT, and there is no confusing
171 1.4 rillig * precedence between BITOR and CVT.
172 1.4 rillig *
173 1.4 rillig * Since tree.c 1.132, this expression doesn't generate a warning
174 1.4 rillig * because the right-hand operand is parenthesized. There is no way
175 1.4 rillig * to have the right operand casted and at the same time not
176 1.4 rillig * parenthesized since the cast operator has higher precedence.
177 1.4 rillig *
178 1.4 rillig * In summary, there is no visible change, but the implementation is
179 1.4 rillig * now works as intended.
180 1.4 rillig */
181 1.4 rillig ok = la | (int)(a & a); /* always ok */
182 1.4 rillig }
183