1 | // RUN: %clang_cc1 -fsyntax-only -Wlogical-not-parentheses -verify %s |
2 | // RUN: not %clang_cc1 -fsyntax-only -Wlogical-not-parentheses -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s |
3 | |
4 | bool getBool(); |
5 | int getInt(); |
6 | |
7 | bool test1(int i1, int i2, bool b1, bool b2) { |
8 | bool ret; |
9 | |
10 | ret = !i1 == i2; |
11 | // expected-warning@-1 {{logical not is only applied to the left hand side of this comparison}} |
12 | // expected-note@-2 {{add parentheses after the '!' to evaluate the comparison first}} |
13 | // expected-note@-3 {{add parentheses around left hand side expression to silence this warning}} |
14 | // CHECK: warn-logical-not-compare.cpp:[[line:[0-9]*]]:9: warning |
15 | // CHECK: to evaluate the comparison first |
16 | // CHECK: fix-it:"{{.*}}":{[[line]]:10-[[line]]:10}:"(" |
17 | // CHECK: fix-it:"{{.*}}":{[[line]]:18-[[line]]:18}:")" |
18 | // CHECK: to silence this warning |
19 | // CHECK: fix-it:"{{.*}}":{[[line]]:9-[[line]]:9}:"(" |
20 | // CHECK: fix-it:"{{.*}}":{[[line]]:12-[[line]]:12}:")" |
21 | |
22 | ret = !i1 != i2; |
23 | //expected-warning@-1 {{logical not is only applied to the left hand side of this comparison}} |
24 | // expected-note@-2 {{add parentheses after the '!' to evaluate the comparison first}} |
25 | // expected-note@-3 {{add parentheses around left hand side expression to silence this warning}} |
26 | // CHECK: warn-logical-not-compare.cpp:[[line:[0-9]*]]:9: warning |
27 | // CHECK: to evaluate the comparison first |
28 | // CHECK: fix-it:"{{.*}}":{[[line]]:10-[[line]]:10}:"(" |
29 | // CHECK: fix-it:"{{.*}}":{[[line]]:18-[[line]]:18}:")" |
30 | // CHECK: to silence this warning |
31 | // CHECK: fix-it:"{{.*}}":{[[line]]:9-[[line]]:9}:"(" |
32 | // CHECK: fix-it:"{{.*}}":{[[line]]:12-[[line]]:12}:")" |
33 | |
34 | ret = !i1 < i2; |
35 | //expected-warning@-1 {{logical not is only applied to the left hand side of this comparison}} |
36 | // expected-note@-2 {{add parentheses after the '!' to evaluate the comparison first}} |
37 | // expected-note@-3 {{add parentheses around left hand side expression to silence this warning}} |
38 | // CHECK: warn-logical-not-compare.cpp:[[line:[0-9]*]]:9: warning |
39 | // CHECK: to evaluate the comparison first |
40 | // CHECK: fix-it:"{{.*}}":{[[line]]:10-[[line]]:10}:"(" |
41 | // CHECK: fix-it:"{{.*}}":{[[line]]:17-[[line]]:17}:")" |
42 | // CHECK: to silence this warning |
43 | // CHECK: fix-it:"{{.*}}":{[[line]]:9-[[line]]:9}:"(" |
44 | // CHECK: fix-it:"{{.*}}":{[[line]]:12-[[line]]:12}:")" |
45 | |
46 | ret = !i1 > i2; |
47 | //expected-warning@-1 {{logical not is only applied to the left hand side of this comparison}} |
48 | // expected-note@-2 {{add parentheses after the '!' to evaluate the comparison first}} |
49 | // expected-note@-3 {{add parentheses around left hand side expression to silence this warning}} |
50 | // CHECK: warn-logical-not-compare.cpp:[[line:[0-9]*]]:9: warning |
51 | // CHECK: to evaluate the comparison first |
52 | // CHECK: fix-it:"{{.*}}":{[[line]]:10-[[line]]:10}:"(" |
53 | // CHECK: fix-it:"{{.*}}":{[[line]]:17-[[line]]:17}:")" |
54 | // CHECK: to silence this warning |
55 | // CHECK: fix-it:"{{.*}}":{[[line]]:9-[[line]]:9}:"(" |
56 | // CHECK: fix-it:"{{.*}}":{[[line]]:12-[[line]]:12}:")" |
57 | |
58 | ret = !i1 <= i2; |
59 | //expected-warning@-1 {{logical not is only applied to the left hand side of this comparison}} |
60 | // expected-note@-2 {{add parentheses after the '!' to evaluate the comparison first}} |
61 | // expected-note@-3 {{add parentheses around left hand side expression to silence this warning}} |
62 | // CHECK: warn-logical-not-compare.cpp:[[line:[0-9]*]]:9: warning |
63 | // CHECK: to evaluate the comparison first |
64 | // CHECK: fix-it:"{{.*}}":{[[line]]:10-[[line]]:10}:"(" |
65 | // CHECK: fix-it:"{{.*}}":{[[line]]:18-[[line]]:18}:")" |
66 | // CHECK: to silence this warning |
67 | // CHECK: fix-it:"{{.*}}":{[[line]]:9-[[line]]:9}:"(" |
68 | // CHECK: fix-it:"{{.*}}":{[[line]]:12-[[line]]:12}:")" |
69 | |
70 | ret = !i1 >= i2; |
71 | //expected-warning@-1 {{logical not is only applied to the left hand side of this comparison}} |
72 | // expected-note@-2 {{add parentheses after the '!' to evaluate the comparison first}} |
73 | // expected-note@-3 {{add parentheses around left hand side expression to silence this warning}} |
74 | // CHECK: warn-logical-not-compare.cpp:[[line:[0-9]*]]:9: warning |
75 | // CHECK: to evaluate the comparison first |
76 | // CHECK: fix-it:"{{.*}}":{[[line]]:10-[[line]]:10}:"(" |
77 | // CHECK: fix-it:"{{.*}}":{[[line]]:18-[[line]]:18}:")" |
78 | // CHECK: to silence this warning |
79 | // CHECK: fix-it:"{{.*}}":{[[line]]:9-[[line]]:9}:"(" |
80 | // CHECK: fix-it:"{{.*}}":{[[line]]:12-[[line]]:12}:")" |
81 | |
82 | ret = i1 == i2; |
83 | ret = i1 != i2; |
84 | ret = i1 < i2; |
85 | ret = i1 > i2; |
86 | ret = i1 <= i2; |
87 | ret = i1 >= i2; |
88 | |
89 | // Warning silenced by parens. |
90 | ret = (!i1) == i2; |
91 | ret = (!i1) != i2; |
92 | ret = (!i1) < i2; |
93 | ret = (!i1) > i2; |
94 | ret = (!i1) <= i2; |
95 | ret = (!i1) >= i2; |
96 | |
97 | ret = !b1 == b2; |
98 | ret = !b1 != b2; |
99 | ret = !b1 < b2; |
100 | ret = !b1 > b2; |
101 | ret = !b1 <= b2; |
102 | ret = !b1 >= b2; |
103 | |
104 | ret = !getInt() == i1; |
105 | // expected-warning@-1 {{logical not is only applied to the left hand side of this comparison}} |
106 | // expected-note@-2 {{add parentheses after the '!' to evaluate the comparison first}} |
107 | // expected-note@-3 {{add parentheses around left hand side expression to silence this warning}} |
108 | // CHECK: warn-logical-not-compare.cpp:[[line:[0-9]*]]:9: warning |
109 | // CHECK: to evaluate the comparison first |
110 | // CHECK: fix-it:"{{.*}}":{[[line]]:10-[[line]]:10}:"(" |
111 | // CHECK: fix-it:"{{.*}}":{[[line]]:24-[[line]]:24}:")" |
112 | // CHECK: to silence this warning |
113 | // CHECK: fix-it:"{{.*}}":{[[line]]:9-[[line]]:9}:"(" |
114 | // CHECK: fix-it:"{{.*}}":{[[line]]:18-[[line]]:18}:")" |
115 | |
116 | ret = (!getInt()) == i1; |
117 | ret = !getBool() == b1; |
118 | return ret; |
119 | } |
120 | |
121 | enum E {e1, e2}; |
122 | E getE(); |
123 | |
124 | bool test2 (E e) { |
125 | bool ret; |
126 | ret = e == e1; |
127 | ret = e == getE(); |
128 | ret = getE() == e1; |
129 | ret = getE() == getE(); |
130 | |
131 | ret = !e == e1; |
132 | // expected-warning@-1 {{logical not is only applied to the left hand side of this comparison}} |
133 | // expected-note@-2 {{add parentheses after the '!' to evaluate the comparison first}} |
134 | // expected-note@-3 {{add parentheses around left hand side expression to silence this warning}} |
135 | // CHECK: warn-logical-not-compare.cpp:[[line:[0-9]*]]:9: warning |
136 | // CHECK: to evaluate the comparison first |
137 | // CHECK: fix-it:"{{.*}}":{[[line]]:10-[[line]]:10}:"(" |
138 | // CHECK: fix-it:"{{.*}}":{[[line]]:17-[[line]]:17}:")" |
139 | // CHECK: to silence this warning |
140 | // CHECK: fix-it:"{{.*}}":{[[line]]:9-[[line]]:9}:"(" |
141 | // CHECK: fix-it:"{{.*}}":{[[line]]:11-[[line]]:11}:")" |
142 | |
143 | ret = !e == getE(); |
144 | // expected-warning@-1 {{logical not is only applied to the left hand side of this comparison}} |
145 | // expected-note@-2 {{add parentheses after the '!' to evaluate the comparison first}} |
146 | // expected-note@-3 {{add parentheses around left hand side expression to silence this warning}} |
147 | // CHECK: warn-logical-not-compare.cpp:[[line:[0-9]*]]:9: warning |
148 | // CHECK: to evaluate the comparison first |
149 | // CHECK: fix-it:"{{.*}}":{[[line]]:10-[[line]]:10}:"(" |
150 | // CHECK: fix-it:"{{.*}}":{[[line]]:21-[[line]]:21}:")" |
151 | // CHECK: to silence this warning |
152 | // CHECK: fix-it:"{{.*}}":{[[line]]:9-[[line]]:9}:"(" |
153 | // CHECK: fix-it:"{{.*}}":{[[line]]:11-[[line]]:11}:")" |
154 | |
155 | ret = !getE() == e1; |
156 | // expected-warning@-1 {{logical not is only applied to the left hand side of this comparison}} |
157 | // expected-note@-2 {{add parentheses after the '!' to evaluate the comparison first}} |
158 | // expected-note@-3 {{add parentheses around left hand side expression to silence this warning}} |
159 | // CHECK: warn-logical-not-compare.cpp:[[line:[0-9]*]]:9: warning |
160 | // CHECK: to evaluate the comparison first |
161 | // CHECK: fix-it:"{{.*}}":{[[line]]:10-[[line]]:10}:"(" |
162 | // CHECK: fix-it:"{{.*}}":{[[line]]:22-[[line]]:22}:")" |
163 | // CHECK: to silence this warning |
164 | // CHECK: fix-it:"{{.*}}":{[[line]]:9-[[line]]:9}:"(" |
165 | // CHECK: fix-it:"{{.*}}":{[[line]]:16-[[line]]:16}:")" |
166 | |
167 | ret = !getE() == getE(); |
168 | // expected-warning@-1 {{logical not is only applied to the left hand side of this comparison}} |
169 | // expected-note@-2 {{add parentheses after the '!' to evaluate the comparison first}} |
170 | // expected-note@-3 {{add parentheses around left hand side expression to silence this warning}} |
171 | // CHECK: warn-logical-not-compare.cpp:[[line:[0-9]*]]:9: warning |
172 | // CHECK: to evaluate the comparison first |
173 | // CHECK: fix-it:"{{.*}}":{[[line]]:10-[[line]]:10}:"(" |
174 | // CHECK: fix-it:"{{.*}}":{[[line]]:26-[[line]]:26}:")" |
175 | // CHECK: to silence this warning |
176 | // CHECK: fix-it:"{{.*}}":{[[line]]:9-[[line]]:9}:"(" |
177 | // CHECK: fix-it:"{{.*}}":{[[line]]:16-[[line]]:16}:")" |
178 | |
179 | ret = !(e == e1); |
180 | ret = !(e == getE()); |
181 | ret = !(getE() == e1); |
182 | ret = !(getE() == getE()); |
183 | |
184 | ret = (!e) == e1; |
185 | ret = (!e) == getE(); |
186 | ret = (!getE()) == e1; |
187 | ret = (!getE()) == getE(); |
188 | |
189 | return ret; |
190 | } |
191 | |
192 | bool test_bitwise_op(int x) { |
193 | bool ret; |
194 | |
195 | ret = !x & 1; |
196 | // expected-warning@-1 {{logical not is only applied to the left hand side of this bitwise operator}} |
197 | // expected-note@-2 {{add parentheses after the '!' to evaluate the bitwise operator first}} |
198 | // expected-note@-3 {{add parentheses around left hand side expression to silence this warning}} |
199 | // CHECK: warn-logical-not-compare.cpp:[[line:[0-9]*]]:9: warning |
200 | // CHECK: to evaluate the bitwise operator first |
201 | // CHECK: fix-it:"{{.*}}":{[[line]]:10-[[line]]:10}:"(" |
202 | // CHECK: fix-it:"{{.*}}":{[[line]]:15-[[line]]:15}:")" |
203 | // CHECK: to silence this warning |
204 | // CHECK: fix-it:"{{.*}}":{[[line]]:9-[[line]]:9}:"(" |
205 | // CHECK: fix-it:"{{.*}}":{[[line]]:11-[[line]]:11}:")" |
206 | ret = !(x & 1); |
207 | ret = (!x) & 1; |
208 | |
209 | // This warning is really about !x & FOO since that's a common misspelling |
210 | // of the negated bit test !(x & FOO). Don't warn for | and ^, since |
211 | // it's at least conceivable that the user wants to use | as an |
212 | // alternative to || that evaluates both branches. (The warning above is |
213 | // only emitted if the operand to ! is not a bool, but in C that's common.) |
214 | // And there's no logical ^. |
215 | ret = !x | 1; |
216 | ret = !(x | 1); |
217 | ret = (!x) | 1; |
218 | |
219 | ret = !x ^ 1; |
220 | ret = !(x ^ 1); |
221 | ret = (!x) ^ 1; |
222 | |
223 | // These already err, don't also warn. |
224 | !x &= 1; // expected-error{{expression is not assignable}} |
225 | !x |= 1; // expected-error{{expression is not assignable}} |
226 | !x ^= 1; // expected-error{{expression is not assignable}} |
227 | |
228 | return ret; |
229 | } |
230 | |
231 | bool PR16673(int x) { |
232 | bool ret; |
233 | // Make sure we don't emit a fixit for the left paren, but not the right paren. |
234 | #define X(x) x |
235 | ret = X(!x == 1 && 1); |
236 | // expected-warning@-1 {{logical not is only applied to the left hand side of this comparison}} |
237 | // expected-note@-2 {{add parentheses after the '!' to evaluate the comparison first}} |
238 | // expected-note@-3 {{add parentheses around left hand side expression to silence this warning}} |
239 | // CHECK: warn-logical-not-compare.cpp:[[line:[0-9]*]]:11: warning |
240 | // CHECK: to evaluate the comparison first |
241 | // CHECK-NOT: fix-it |
242 | // CHECK: to silence this warning |
243 | // CHECK-NOT: fix-it |
244 | return ret; |
245 | } |
246 | |