Clang Project

clang_source_code/test/SemaCXX/warn-logical-not-compare.cpp
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
4bool getBool();
5int getInt();
6
7bool 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
121enum E {e1, e2};
122E getE();
123
124bool 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
192bool 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
231bool 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