246 lines · cpp
1// RUN: %clang_cc1 -fsyntax-only -Wlogical-not-parentheses -verify %s2// RUN: not %clang_cc1 -fsyntax-only -Wlogical-not-parentheses -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s3 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: warning15 // CHECK: to evaluate the comparison first16 // CHECK: fix-it:"{{.*}}":{[[line]]:10-[[line]]:10}:"("17 // CHECK: fix-it:"{{.*}}":{[[line]]:18-[[line]]:18}:")"18 // CHECK: to silence this warning19 // 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: warning27 // CHECK: to evaluate the comparison first28 // CHECK: fix-it:"{{.*}}":{[[line]]:10-[[line]]:10}:"("29 // CHECK: fix-it:"{{.*}}":{[[line]]:18-[[line]]:18}:")"30 // CHECK: to silence this warning31 // 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: warning39 // CHECK: to evaluate the comparison first40 // CHECK: fix-it:"{{.*}}":{[[line]]:10-[[line]]:10}:"("41 // CHECK: fix-it:"{{.*}}":{[[line]]:17-[[line]]:17}:")"42 // CHECK: to silence this warning43 // 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: warning51 // CHECK: to evaluate the comparison first52 // CHECK: fix-it:"{{.*}}":{[[line]]:10-[[line]]:10}:"("53 // CHECK: fix-it:"{{.*}}":{[[line]]:17-[[line]]:17}:")"54 // CHECK: to silence this warning55 // 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: warning63 // CHECK: to evaluate the comparison first64 // CHECK: fix-it:"{{.*}}":{[[line]]:10-[[line]]:10}:"("65 // CHECK: fix-it:"{{.*}}":{[[line]]:18-[[line]]:18}:")"66 // CHECK: to silence this warning67 // 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: warning75 // CHECK: to evaluate the comparison first76 // CHECK: fix-it:"{{.*}}":{[[line]]:10-[[line]]:10}:"("77 // CHECK: fix-it:"{{.*}}":{[[line]]:18-[[line]]:18}:")"78 // CHECK: to silence this warning79 // 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: warning109 // CHECK: to evaluate the comparison first110 // CHECK: fix-it:"{{.*}}":{[[line]]:10-[[line]]:10}:"("111 // CHECK: fix-it:"{{.*}}":{[[line]]:24-[[line]]:24}:")"112 // CHECK: to silence this warning113 // 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: warning136 // CHECK: to evaluate the comparison first137 // CHECK: fix-it:"{{.*}}":{[[line]]:10-[[line]]:10}:"("138 // CHECK: fix-it:"{{.*}}":{[[line]]:17-[[line]]:17}:")"139 // CHECK: to silence this warning140 // 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: warning148 // CHECK: to evaluate the comparison first149 // CHECK: fix-it:"{{.*}}":{[[line]]:10-[[line]]:10}:"("150 // CHECK: fix-it:"{{.*}}":{[[line]]:21-[[line]]:21}:")"151 // CHECK: to silence this warning152 // 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: warning160 // CHECK: to evaluate the comparison first161 // CHECK: fix-it:"{{.*}}":{[[line]]:10-[[line]]:10}:"("162 // CHECK: fix-it:"{{.*}}":{[[line]]:22-[[line]]:22}:")"163 // CHECK: to silence this warning164 // 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: warning172 // CHECK: to evaluate the comparison first173 // CHECK: fix-it:"{{.*}}":{[[line]]:10-[[line]]:10}:"("174 // CHECK: fix-it:"{{.*}}":{[[line]]:26-[[line]]:26}:")"175 // CHECK: to silence this warning176 // 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: warning200 // CHECK: to evaluate the bitwise operator first201 // CHECK: fix-it:"{{.*}}":{[[line]]:10-[[line]]:10}:"("202 // CHECK: fix-it:"{{.*}}":{[[line]]:15-[[line]]:15}:")"203 // CHECK: to silence this warning204 // 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 misspelling210 // of the negated bit test !(x & FOO). Don't warn for | and ^, since211 // it's at least conceivable that the user wants to use | as an212 // alternative to || that evaluates both branches. (The warning above is213 // 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: warning240 // CHECK: to evaluate the comparison first241 // CHECK-NOT: fix-it242 // CHECK: to silence this warning243 // CHECK-NOT: fix-it244 return ret;245}246