1 // RUN: %clang_cc1 -fsyntax-only -Wlogical-not-parentheses -verify %s
2 // RUN: %clang_cc1 -fsyntax-only -Wlogical-not-parentheses -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s
3 
4 int getInt();
5 
6 int test1(int i1, int i2) {
7   int ret;
8 
9   ret = !i1 == i2;
10   // expected-warning@-1 {{logical not is only applied to the left hand side of this comparison}}
11   // expected-note@-2 {{add parentheses after the '!' to evaluate the comparison first}}
12   // expected-note@-3 {{add parentheses around left hand side expression to silence this warning}}
13   // CHECK: warn-logical-not-compare.c:[[line:[0-9]*]]:9: warning
14   // CHECK: to evaluate the comparison first
15   // CHECK: fix-it:"{{.*}}":{[[line]]:10-[[line]]:10}:"("
16   // CHECK: fix-it:"{{.*}}":{[[line]]:18-[[line]]:18}:")"
17   // CHECK: to silence this warning
18   // CHECK: fix-it:"{{.*}}":{[[line]]:9-[[line]]:9}:"("
19   // CHECK: fix-it:"{{.*}}":{[[line]]:12-[[line]]:12}:")"
20 
21   ret = !i1 != i2;
22   //expected-warning@-1 {{logical not is only applied to the left hand side of this comparison}}
23   // expected-note@-2 {{add parentheses after the '!' to evaluate the comparison first}}
24   // expected-note@-3 {{add parentheses around left hand side expression to silence this warning}}
25   // CHECK: warn-logical-not-compare.c:[[line:[0-9]*]]:9: warning
26   // CHECK: to evaluate the comparison first
27   // CHECK: fix-it:"{{.*}}":{[[line]]:10-[[line]]:10}:"("
28   // CHECK: fix-it:"{{.*}}":{[[line]]:18-[[line]]:18}:")"
29   // CHECK: to silence this warning
30   // CHECK: fix-it:"{{.*}}":{[[line]]:9-[[line]]:9}:"("
31   // CHECK: fix-it:"{{.*}}":{[[line]]:12-[[line]]:12}:")"
32 
33   ret = !i1 < i2;
34   //expected-warning@-1 {{logical not is only applied to the left hand side of this comparison}}
35   // expected-note@-2 {{add parentheses after the '!' to evaluate the comparison first}}
36   // expected-note@-3 {{add parentheses around left hand side expression to silence this warning}}
37   // CHECK: warn-logical-not-compare.c:[[line:[0-9]*]]:9: warning
38   // CHECK: to evaluate the comparison first
39   // CHECK: fix-it:"{{.*}}":{[[line]]:10-[[line]]:10}:"("
40   // CHECK: fix-it:"{{.*}}":{[[line]]:17-[[line]]:17}:")"
41   // CHECK: to silence this warning
42   // CHECK: fix-it:"{{.*}}":{[[line]]:9-[[line]]:9}:"("
43   // CHECK: fix-it:"{{.*}}":{[[line]]:12-[[line]]:12}:")"
44 
45   ret = !i1 > i2;
46   //expected-warning@-1 {{logical not is only applied to the left hand side of this comparison}}
47   // expected-note@-2 {{add parentheses after the '!' to evaluate the comparison first}}
48   // expected-note@-3 {{add parentheses around left hand side expression to silence this warning}}
49   // CHECK: warn-logical-not-compare.c:[[line:[0-9]*]]:9: warning
50   // CHECK: to evaluate the comparison first
51   // CHECK: fix-it:"{{.*}}":{[[line]]:10-[[line]]:10}:"("
52   // CHECK: fix-it:"{{.*}}":{[[line]]:17-[[line]]:17}:")"
53   // CHECK: to silence this warning
54   // CHECK: fix-it:"{{.*}}":{[[line]]:9-[[line]]:9}:"("
55   // CHECK: fix-it:"{{.*}}":{[[line]]:12-[[line]]:12}:")"
56 
57   ret = !i1 <= i2;
58   //expected-warning@-1 {{logical not is only applied to the left hand side of this comparison}}
59   // expected-note@-2 {{add parentheses after the '!' to evaluate the comparison first}}
60   // expected-note@-3 {{add parentheses around left hand side expression to silence this warning}}
61   // CHECK: warn-logical-not-compare.c:[[line:[0-9]*]]:9: warning
62   // CHECK: to evaluate the comparison first
63   // CHECK: fix-it:"{{.*}}":{[[line]]:10-[[line]]:10}:"("
64   // CHECK: fix-it:"{{.*}}":{[[line]]:18-[[line]]:18}:")"
65   // CHECK: to silence this warning
66   // CHECK: fix-it:"{{.*}}":{[[line]]:9-[[line]]:9}:"("
67   // CHECK: fix-it:"{{.*}}":{[[line]]:12-[[line]]:12}:")"
68 
69   ret = !i1 >= i2;
70   //expected-warning@-1 {{logical not is only applied to the left hand side of this comparison}}
71   // expected-note@-2 {{add parentheses after the '!' to evaluate the comparison first}}
72   // expected-note@-3 {{add parentheses around left hand side expression to silence this warning}}
73   // CHECK: warn-logical-not-compare.c:[[line:[0-9]*]]:9: warning
74   // CHECK: to evaluate the comparison first
75   // CHECK: fix-it:"{{.*}}":{[[line]]:10-[[line]]:10}:"("
76   // CHECK: fix-it:"{{.*}}":{[[line]]:18-[[line]]:18}:")"
77   // CHECK: to silence this warning
78   // CHECK: fix-it:"{{.*}}":{[[line]]:9-[[line]]:9}:"("
79   // CHECK: fix-it:"{{.*}}":{[[line]]:12-[[line]]:12}:")"
80 
81   ret = i1 == i2;
82   ret = i1 != i2;
83   ret = i1 < i2;
84   ret = i1 > i2;
85   ret = i1 <= i2;
86   ret = i1 >= i2;
87 
88   // Warning silenced by parens.
89   ret = (!i1) == i2;
90   ret = (!i1) != i2;
91   ret = (!i1) < i2;
92   ret = (!i1) > i2;
93   ret = (!i1) <= i2;
94   ret = (!i1) >= i2;
95 
96   ret = !getInt() == i1;
97   // expected-warning@-1 {{logical not is only applied to the left hand side of this comparison}}
98   // expected-note@-2 {{add parentheses after the '!' to evaluate the comparison first}}
99   // expected-note@-3 {{add parentheses around left hand side expression to silence this warning}}
100   // CHECK: warn-logical-not-compare.c:[[line:[0-9]*]]:9: warning
101   // CHECK: to evaluate the comparison first
102   // CHECK: fix-it:"{{.*}}":{[[line]]:10-[[line]]:10}:"("
103   // CHECK: fix-it:"{{.*}}":{[[line]]:24-[[line]]:24}:")"
104   // CHECK: to silence this warning
105   // CHECK: fix-it:"{{.*}}":{[[line]]:9-[[line]]:9}:"("
106   // CHECK: fix-it:"{{.*}}":{[[line]]:18-[[line]]:18}:")"
107 
108   ret = (!getInt()) == i1;
109   return ret;
110 }
111 
112 enum E {e1, e2};
113 enum E getE();
114 
115 int test2 (enum E e) {
116   int ret;
117   ret = e == e1;
118   ret = e == getE();
119   ret = getE() == e1;
120   ret = getE() == getE();
121 
122   ret = !e == e1;
123   // expected-warning@-1 {{logical not is only applied to the left hand side of this comparison}}
124   // expected-note@-2 {{add parentheses after the '!' to evaluate the comparison first}}
125   // expected-note@-3 {{add parentheses around left hand side expression to silence this warning}}
126   // CHECK: warn-logical-not-compare.c:[[line:[0-9]*]]:9: warning
127   // CHECK: to evaluate the comparison first
128   // CHECK: fix-it:"{{.*}}":{[[line]]:10-[[line]]:10}:"("
129   // CHECK: fix-it:"{{.*}}":{[[line]]:17-[[line]]:17}:")"
130   // CHECK: to silence this warning
131   // CHECK: fix-it:"{{.*}}":{[[line]]:9-[[line]]:9}:"("
132   // CHECK: fix-it:"{{.*}}":{[[line]]:11-[[line]]:11}:")"
133 
134   ret = !e == getE();
135   // expected-warning@-1 {{logical not is only applied to the left hand side of this comparison}}
136   // expected-note@-2 {{add parentheses after the '!' to evaluate the comparison first}}
137   // expected-note@-3 {{add parentheses around left hand side expression to silence this warning}}
138   // CHECK: warn-logical-not-compare.c:[[line:[0-9]*]]:9: warning
139   // CHECK: to evaluate the comparison first
140   // CHECK: fix-it:"{{.*}}":{[[line]]:10-[[line]]:10}:"("
141   // CHECK: fix-it:"{{.*}}":{[[line]]:21-[[line]]:21}:")"
142   // CHECK: to silence this warning
143   // CHECK: fix-it:"{{.*}}":{[[line]]:9-[[line]]:9}:"("
144   // CHECK: fix-it:"{{.*}}":{[[line]]:11-[[line]]:11}:")"
145 
146   ret = !getE() == e1;
147   // expected-warning@-1 {{logical not is only applied to the left hand side of this comparison}}
148   // expected-note@-2 {{add parentheses after the '!' to evaluate the comparison first}}
149   // expected-note@-3 {{add parentheses around left hand side expression to silence this warning}}
150   // CHECK: warn-logical-not-compare.c:[[line:[0-9]*]]:9: warning
151   // CHECK: to evaluate the comparison first
152   // CHECK: fix-it:"{{.*}}":{[[line]]:10-[[line]]:10}:"("
153   // CHECK: fix-it:"{{.*}}":{[[line]]:22-[[line]]:22}:")"
154   // CHECK: to silence this warning
155   // CHECK: fix-it:"{{.*}}":{[[line]]:9-[[line]]:9}:"("
156   // CHECK: fix-it:"{{.*}}":{[[line]]:16-[[line]]:16}:")"
157 
158   ret = !getE() == getE();
159   // expected-warning@-1 {{logical not is only applied to the left hand side of this comparison}}
160   // expected-note@-2 {{add parentheses after the '!' to evaluate the comparison first}}
161   // expected-note@-3 {{add parentheses around left hand side expression to silence this warning}}
162   // CHECK: warn-logical-not-compare.c:[[line:[0-9]*]]:9: warning
163   // CHECK: to evaluate the comparison first
164   // CHECK: fix-it:"{{.*}}":{[[line]]:10-[[line]]:10}:"("
165   // CHECK: fix-it:"{{.*}}":{[[line]]:26-[[line]]:26}:")"
166   // CHECK: to silence this warning
167   // CHECK: fix-it:"{{.*}}":{[[line]]:9-[[line]]:9}:"("
168   // CHECK: fix-it:"{{.*}}":{[[line]]:16-[[line]]:16}:")"
169 
170   ret = !(e == e1);
171   ret = !(e == getE());
172   ret = !(getE() == e1);
173   ret = !(getE() == getE());
174 
175   ret = (!e) == e1;
176   ret = (!e) == getE();
177   ret = (!getE()) == e1;
178   ret = (!getE()) == getE();
179 
180   return ret;
181 }
182 
183 int PR16673(int x) {
184   int ret;
185   // Make sure we don't emit a fixit for the left paren, but not the right paren.
186 #define X(x) x
187   ret = X(!x == 1 && 1);
188   // expected-warning@-1 {{logical not is only applied to the left hand side of this comparison}}
189   // expected-note@-2 {{add parentheses after the '!' to evaluate the comparison first}}
190   // expected-note@-3 {{add parentheses around left hand side expression to silence this warning}}
191   // CHECK: warn-logical-not-compare.c:[[line:[0-9]*]]:11: warning
192   // CHECK: to evaluate the comparison first
193   // CHECK-NOT: fix-it
194   // CHECK: to silence this warning
195   // CHECK-NOT: fix-it
196   return ret;
197 }
198 
199 int compare_pointers(int* a, int* b) {
200   int ret;
201   ret = !!a == !!b;
202   ret = !!a != !!b;
203   return ret;
204 }
205