| 1 | // RUN: %check_clang_tidy --match-partial-fixes %s readability-simplify-boolean-expr %t |
| 2 | |
| 3 | class A { |
| 4 | public: |
| 5 | int m; |
| 6 | }; |
| 7 | |
| 8 | struct S { |
| 9 | S() : m_ar(s_a) {} |
| 10 | |
| 11 | void operator_equals(); |
| 12 | void operator_or(); |
| 13 | void operator_and(); |
| 14 | void ternary_operator(); |
| 15 | void operator_not_equal(); |
| 16 | void simple_conditional_assignment_statements(); |
| 17 | void complex_conditional_assignment_statements(); |
| 18 | void chained_conditional_assignment(); |
| 19 | bool non_null_pointer_condition(); |
| 20 | bool null_pointer_condition(); |
| 21 | bool negated_non_null_pointer_condition(); |
| 22 | bool negated_null_pointer_condition(); |
| 23 | bool integer_not_zero(); |
| 24 | bool member_pointer_nullptr(); |
| 25 | bool integer_member_implicit_cast(); |
| 26 | bool expr_with_cleanups(); |
| 27 | |
| 28 | bool m_b1 = false; |
| 29 | bool m_b2 = false; |
| 30 | bool m_b3 = false; |
| 31 | bool m_b4 = false; |
| 32 | int *m_p = nullptr; |
| 33 | int A::*m_m = nullptr; |
| 34 | int m_i = 0; |
| 35 | A *m_a = nullptr; |
| 36 | static A s_a; |
| 37 | A &m_ar; |
| 38 | }; |
| 39 | |
| 40 | void S::operator_equals() { |
| 41 | int i = 0; |
| 42 | m_b1 = (i > 2); |
| 43 | if (m_b1 == true) { |
| 44 | // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: {{.*}} to boolean operator |
| 45 | // CHECK-FIXES: {{^ if \(m_b1\) {$}} |
| 46 | i = 5; |
| 47 | } else { |
| 48 | i = 6; |
| 49 | } |
| 50 | m_b2 = (i > 4); |
| 51 | if (m_b2 == false) { |
| 52 | // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: {{.*}} to boolean operator |
| 53 | // CHECK-FIXES: {{^ if \(!m_b2\) {$}} |
| 54 | i = 7; |
| 55 | } else { |
| 56 | i = 9; |
| 57 | } |
| 58 | m_b3 = (i > 6); |
| 59 | if (true == m_b3) { |
| 60 | // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: {{.*}} to boolean operator |
| 61 | // CHECK-FIXES: {{^ if \(m_b3\) {$}} |
| 62 | i = 10; |
| 63 | } else { |
| 64 | i = 11; |
| 65 | } |
| 66 | m_b4 = (i > 8); |
| 67 | if (false == m_b4) { |
| 68 | // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: {{.*}} to boolean operator |
| 69 | // CHECK-FIXES: {{^ if \(!m_b4\) {$}} |
| 70 | i = 12; |
| 71 | } else { |
| 72 | i = 13; |
| 73 | } |
| 74 | } |
| 75 | |
| 76 | void S::operator_or() { |
| 77 | int i = 0; |
| 78 | m_b1 = (i > 10); |
| 79 | if (m_b1 || false) { |
| 80 | // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: {{.*}} to boolean operator |
| 81 | // CHECK-FIXES: {{^ if \(m_b1\) {$}} |
| 82 | i = 14; |
| 83 | } else { |
| 84 | i = 15; |
| 85 | } |
| 86 | m_b2 = (i > 10); |
| 87 | if (m_b2 || true) { |
| 88 | // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: {{.*}} to boolean operator |
| 89 | // CHECK-FIXES: {{^ if \(true\) {$}} |
| 90 | i = 16; |
| 91 | } else { |
| 92 | i = 17; |
| 93 | } |
| 94 | m_b3 = (i > 10); |
| 95 | if (false || m_b3) { |
| 96 | // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: {{.*}} to boolean operator |
| 97 | // CHECK-FIXES: {{^ if \(m_b3\) {$}} |
| 98 | i = 18; |
| 99 | } else { |
| 100 | i = 19; |
| 101 | } |
| 102 | m_b4 = (i > 10); |
| 103 | if (true || m_b4) { |
| 104 | // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: {{.*}} to boolean operator |
| 105 | // CHECK-FIXES: {{^ if \(true\) {$}} |
| 106 | i = 20; |
| 107 | } else { |
| 108 | i = 21; |
| 109 | } |
| 110 | } |
| 111 | |
| 112 | void S::operator_and() { |
| 113 | int i = 0; |
| 114 | m_b1 = (i > 20); |
| 115 | if (m_b1 && false) { |
| 116 | // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: {{.*}} to boolean operator |
| 117 | // CHECK-FIXES: {{^ if \(false\) {$}} |
| 118 | i = 22; |
| 119 | } else { |
| 120 | i = 23; |
| 121 | } |
| 122 | m_b2 = (i > 20); |
| 123 | if (m_b2 && true) { |
| 124 | // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: {{.*}} to boolean operator |
| 125 | // CHECK-FIXES: {{^ if \(m_b2\) {$}} |
| 126 | i = 24; |
| 127 | } else { |
| 128 | i = 25; |
| 129 | } |
| 130 | m_b3 = (i > 20); |
| 131 | if (false && m_b3) { |
| 132 | // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: {{.*}} to boolean operator |
| 133 | // CHECK-FIXES: {{^ if \(false\) {$}} |
| 134 | i = 26; |
| 135 | } else { |
| 136 | i = 27; |
| 137 | } |
| 138 | m_b4 = (i > 20); |
| 139 | if (true && m_b4) { |
| 140 | // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: {{.*}} to boolean operator |
| 141 | // CHECK-FIXES: {{^ if \(m_b4\) {$}} |
| 142 | i = 28; |
| 143 | } else { |
| 144 | i = 29; |
| 145 | } |
| 146 | } |
| 147 | |
| 148 | void S::ternary_operator() { |
| 149 | int i = 0; |
| 150 | m_b1 = (i > 20) ? true : false; |
| 151 | // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: {{.*}} in ternary expression result |
| 152 | // CHECK-FIXES: {{^ m_b1 = i > 20;$}} |
| 153 | |
| 154 | m_b2 = (i > 20) ? false : true; |
| 155 | // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: {{.*}} in ternary expression result |
| 156 | // CHECK-FIXES: {{^ m_b2 = i <= 20;$}} |
| 157 | |
| 158 | m_b3 = ((i > 20)) ? false : true; |
| 159 | // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: {{.*}} in ternary expression result |
| 160 | // CHECK-FIXES: {{^ m_b3 = i <= 20;$}} |
| 161 | } |
| 162 | |
| 163 | void S::operator_not_equal() { |
| 164 | int i = 0; |
| 165 | m_b1 = (i > 20); |
| 166 | if (false != m_b1) { |
| 167 | // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: {{.*}} to boolean operator |
| 168 | // CHECK-FIXES: {{^ if \(m_b1\) {$}} |
| 169 | i = 30; |
| 170 | } else { |
| 171 | i = 31; |
| 172 | } |
| 173 | m_b2 = (i > 20); |
| 174 | if (true != m_b2) { |
| 175 | // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: {{.*}} to boolean operator |
| 176 | // CHECK-FIXES: {{^ if \(!m_b2\) {$}} |
| 177 | i = 32; |
| 178 | } else { |
| 179 | i = 33; |
| 180 | } |
| 181 | m_b3 = (i > 20); |
| 182 | if (m_b3 != false) { |
| 183 | // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: {{.*}} to boolean operator |
| 184 | // CHECK-FIXES: {{^ if \(m_b3\) {$}} |
| 185 | i = 34; |
| 186 | } else { |
| 187 | i = 35; |
| 188 | } |
| 189 | m_b4 = (i > 20); |
| 190 | if (m_b4 != true) { |
| 191 | // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: {{.*}} to boolean operator |
| 192 | // CHECK-FIXES: {{^ if \(!m_b4\) {$}} |
| 193 | i = 36; |
| 194 | } else { |
| 195 | i = 37; |
| 196 | } |
| 197 | } |
| 198 | |
| 199 | void S::simple_conditional_assignment_statements() { |
| 200 | if (m_i > 10) |
| 201 | m_b1 = true; |
| 202 | else |
| 203 | m_b1 = false; |
| 204 | bool bb = false; |
| 205 | // CHECK-MESSAGES: :[[@LINE-4]]:12: warning: {{.*}} in conditional assignment |
| 206 | // CHECK-FIXES: {{^ }}m_b1 = m_i > 10;{{$}} |
| 207 | // CHECK-FIXES: bool bb = false; |
| 208 | |
| 209 | if (m_i > 20) |
| 210 | m_b2 = false; |
| 211 | else |
| 212 | m_b2 = true; |
| 213 | bool c2 = false; |
| 214 | // CHECK-MESSAGES: :[[@LINE-4]]:12: warning: {{.*}} in conditional assignment |
| 215 | // CHECK-FIXES: {{^ }}m_b2 = m_i <= 20;{{$}} |
| 216 | // CHECK-FIXES: bool c2 = false; |
| 217 | |
| 218 | // Unchanged: different variables. |
| 219 | if (m_i > 12) |
| 220 | m_b1 = true; |
| 221 | else |
| 222 | m_b2 = false; |
| 223 | |
| 224 | // Unchanged: no else statement. |
| 225 | if (m_i > 15) |
| 226 | m_b3 = true; |
| 227 | |
| 228 | // Unchanged: not boolean assignment. |
| 229 | int j; |
| 230 | if (m_i > 17) |
| 231 | j = 10; |
| 232 | else |
| 233 | j = 20; |
| 234 | |
| 235 | // Unchanged: different variables assigned. |
| 236 | int k = 0; |
| 237 | m_b4 = false; |
| 238 | if (m_i > 10) |
| 239 | m_b4 = true; |
| 240 | else |
| 241 | k = 10; |
| 242 | } |
| 243 | |
| 244 | void S::complex_conditional_assignment_statements() { |
| 245 | if (m_i > 30) { |
| 246 | m_b1 = true; |
| 247 | } else { |
| 248 | m_b1 = false; |
| 249 | } |
| 250 | m_b1 = false; |
| 251 | // CHECK-MESSAGES: :[[@LINE-5]]:12: warning: {{.*}} in conditional assignment |
| 252 | // CHECK-FIXES: {{^ }}m_b1 = m_i > 30;{{$}} |
| 253 | // CHECK-FIXES: m_b1 = false; |
| 254 | |
| 255 | if (m_i > 40) { |
| 256 | m_b2 = false; |
| 257 | } else { |
| 258 | m_b2 = true; |
| 259 | } |
| 260 | m_b2 = false; |
| 261 | // CHECK-MESSAGES: :[[@LINE-5]]:12: warning: {{.*}} in conditional assignment |
| 262 | // CHECK-FIXES: {{^ }}m_b2 = m_i <= 40;{{$}} |
| 263 | // CHECK-FIXES: m_b2 = false; |
| 264 | } |
| 265 | |
| 266 | // Unchanged: chained return statements, but ChainedConditionalReturn not set. |
| 267 | void S::chained_conditional_assignment() { |
| 268 | if (m_i < 0) |
| 269 | m_b1 = true; |
| 270 | else if (m_i < 10) |
| 271 | m_b1 = false; |
| 272 | else if (m_i > 20) |
| 273 | m_b1 = true; |
| 274 | else |
| 275 | m_b1 = false; |
| 276 | } |
| 277 | |
| 278 | bool S::non_null_pointer_condition() { |
| 279 | if (m_p) { |
| 280 | return true; |
| 281 | } else { |
| 282 | return false; |
| 283 | } |
| 284 | } |
| 285 | // CHECK-MESSAGES: :[[@LINE-5]]:12: warning: {{.*}} in conditional return |
| 286 | // CHECK-FIXES: return m_p != nullptr;{{$}} |
| 287 | |
| 288 | bool S::null_pointer_condition() { |
| 289 | if (!m_p) { |
| 290 | return true; |
| 291 | } else { |
| 292 | return false; |
| 293 | } |
| 294 | } |
| 295 | // CHECK-MESSAGES: :[[@LINE-5]]:12: warning: {{.*}} in conditional return |
| 296 | // CHECK-FIXES: return m_p == nullptr;{{$}} |
| 297 | |
| 298 | bool S::negated_non_null_pointer_condition() { |
| 299 | if (m_p) { |
| 300 | return false; |
| 301 | } else { |
| 302 | return true; |
| 303 | } |
| 304 | } |
| 305 | // CHECK-MESSAGES: :[[@LINE-5]]:12: warning: {{.*}} in conditional return |
| 306 | // CHECK-FIXES: return m_p == nullptr;{{$}} |
| 307 | |
| 308 | bool S::negated_null_pointer_condition() { |
| 309 | if (!m_p) { |
| 310 | return false; |
| 311 | } else { |
| 312 | return true; |
| 313 | } |
| 314 | } |
| 315 | // CHECK-MESSAGES: :[[@LINE-5]]:12: warning: {{.*}} in conditional return |
| 316 | // CHECK-FIXES: return m_p != nullptr;{{$}} |
| 317 | |
| 318 | bool S::integer_not_zero() { |
| 319 | if (m_i) { |
| 320 | return false; |
| 321 | } else { |
| 322 | return true; |
| 323 | } |
| 324 | } |
| 325 | // CHECK-MESSAGES: :[[@LINE-5]]:12: warning: {{.*}} in conditional return |
| 326 | // CHECK-FIXES: {{^}} return m_i == 0;{{$}} |
| 327 | |
| 328 | bool S::member_pointer_nullptr() { |
| 329 | if (m_m) { |
| 330 | return true; |
| 331 | } else { |
| 332 | return false; |
| 333 | } |
| 334 | } |
| 335 | // CHECK-MESSAGES: :[[@LINE-5]]:12: warning: {{.*}} in conditional return |
| 336 | // CHECK-FIXES: return m_m != nullptr;{{$}} |
| 337 | |
| 338 | bool S::integer_member_implicit_cast() { |
| 339 | if (m_a->m) { |
| 340 | return true; |
| 341 | } else { |
| 342 | return false; |
| 343 | } |
| 344 | } |
| 345 | // CHECK-MESSAGES: :[[@LINE-5]]:12: warning: {{.*}} in conditional return |
| 346 | // CHECK-FIXES: return m_a->m != 0;{{$}} |
| 347 | |
| 348 | bool operator!=(const A &, const A &) { return false; } |
| 349 | bool S::expr_with_cleanups() { |
| 350 | if (m_ar != (A)m_ar) |
| 351 | return false; |
| 352 | |
| 353 | return true; |
| 354 | } |
| 355 | // CHECK-MESSAGES: :[[@LINE-4]]:12: warning: {{.*}} in conditional return |
| 356 | // CHECK-FIXES: m_ar == (A)m_ar;{{$}} |
| 357 | |