1 // RUN: %check_clang_tidy %s readability-simplify-boolean-expr %t 2 3 class A { 4 public: 5 int m; 6 }; 7 8 struct S { SS9 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 operator_equals()40void 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 operator_or()76void 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 operator_and()112void 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 ternary_operator()148void 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 operator_not_equal()163void 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 simple_conditional_assignment_statements()199void 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 complex_conditional_assignment_statements()244void 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. chained_conditional_assignment()267void 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 non_null_pointer_condition()278bool 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 null_pointer_condition()288bool 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 negated_non_null_pointer_condition()298bool 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 negated_null_pointer_condition()308bool 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 integer_not_zero()318bool 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 member_pointer_nullptr()328bool 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 integer_member_implicit_cast()338bool 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 operator !=(const A &,const A &)348bool operator!=(const A &, const A &) { return false; } expr_with_cleanups()349bool 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