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 
test1(int i1,int i2,bool b1,bool b2)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 
test2(E e)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 
test_bitwise_op(int x)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 
PR16673(int x)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