1 // RUN: %check_clang_tidy %s misc-redundant-expression %t -- -- -fno-delayed-template-parsing -Wno-array-compare-cxx26 2 3 typedef __INT64_TYPE__ I64; 4 5 struct Point { 6 int x; 7 int y; 8 int a[5]; 9 } P; 10 11 extern Point P1; 12 extern Point P2; 13 14 extern int foo(int x); 15 extern int bar(int x); 16 extern int bat(int x, int y); 17 18 int TestSimpleEquivalent(int X, int Y) { 19 if (X - X) return 1; 20 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: both sides of operator are equivalent [misc-redundant-expression] 21 if (X / X) return 1; 22 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: both sides of operator are equivalent 23 if (X % X) return 1; 24 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: both sides of operator are equivalent 25 26 if (X & X) return 1; 27 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: both sides of operator are equivalent 28 if (X | X) return 1; 29 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: both sides of operator are equivalent 30 if (X ^ X) return 1; 31 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: both sides of operator are equivalent 32 33 if (X < X) return 1; 34 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: both sides of operator are equivalent 35 if (X <= X) return 1; 36 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: both sides of operator are equivalent 37 if (X > X) return 1; 38 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: both sides of operator are equivalent 39 if (X >= X) return 1; 40 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: both sides of operator are equivalent 41 42 if (X && X) return 1; 43 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: both sides of operator are equivalent 44 if (X || X) return 1; 45 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: both sides of operator are equivalent 46 47 if (X != (((X)))) return 1; 48 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: both sides of operator are equivalent 49 50 if (X + 1 == X + 1) return 1; 51 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: both sides of operator are equivalent 52 if (X + 1 != X + 1) return 1; 53 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: both sides of operator are equivalent 54 if (X + 1 <= X + 1) return 1; 55 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: both sides of operator are equivalent 56 if (X + 1 >= X + 1) return 1; 57 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: both sides of operator are equivalent 58 59 if ((X != 1 || Y != 1) && (X != 1 || Y != 1)) return 1; 60 // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: both sides of operator are equivalent 61 if (P.a[X - P.x] != P.a[X - P.x]) return 1; 62 // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: both sides of operator are equivalent 63 64 if ((int)X < (int)X) return 1; 65 // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: both sides of operator are equivalent 66 if (int(X) < int(X)) return 1; 67 // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: both sides of operator are equivalent 68 69 if ( + "dummy" == + "dummy") return 1; 70 // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: both sides of operator are equivalent 71 if (L"abc" == L"abc") return 1; 72 // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: both sides of operator are equivalent 73 74 if (foo(0) - 2 < foo(0) - 2) return 1; 75 // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: both sides of operator are equivalent 76 if (foo(bar(0)) < (foo(bar((0))))) return 1; 77 // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: both sides of operator are equivalent 78 79 if (P1.x < P2.x && P1.x < P2.x) return 1; 80 // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: both sides of operator are equivalent 81 if (P2.a[P1.x + 2] < P2.x && P2.a[(P1.x) + (2)] < (P2.x)) return 1; 82 // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: both sides of operator are equivalent 83 84 if (X && Y && X) return 1; 85 // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: operator has equivalent nested operands 86 if (X || (Y || X)) return 1; 87 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: operator has equivalent nested operands 88 if ((X ^ Y) ^ (Y ^ X)) return 1; 89 // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: operator has equivalent nested operands 90 91 return 0; 92 } 93 94 template <int DX> 95 int TestSimpleEquivalentDependent() { 96 if (DX > 0 && DX > 0) return 1; 97 // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: both sides of operator are equivalent 98 99 return 0; 100 } 101 102 int Valid(int X, int Y) { 103 if (X != Y) return 1; 104 if (X == Y + 0) return 1; 105 if (P.x == P.y) return 1; 106 if (P.a[P.x] < P.a[P.y]) return 1; 107 if (P.a[0] < P.a[1]) return 1; 108 109 if (P.a[0] < P.a[0ULL]) return 1; 110 if (0 < 0ULL) return 1; 111 if ((int)0 < (int)0ULL) return 1; 112 113 if (++X != ++X) return 1; 114 if (P.a[X]++ != P.a[X]++) return 1; 115 if (P.a[X++] != P.a[X++]) return 1; 116 if (X && X++ && X) return 1; 117 118 if ("abc" == "ABC") return 1; 119 if (foo(bar(0)) < (foo(bat(0, 1)))) return 1; 120 return 0; 121 } 122 123 #define COND_OP_MACRO 9 124 #define COND_OP_OTHER_MACRO 9 125 #define COND_OP_THIRD_MACRO COND_OP_MACRO 126 int TestConditional(int x, int y) { 127 int k = 0; 128 k += (y < 0) ? x : x; 129 // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: 'true' and 'false' expressions are equivalent 130 k += (y < 0) ? x + 1 : x + 1; 131 // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: 'true' and 'false' expressions are equivalent 132 k += (y < 0) ? COND_OP_MACRO : COND_OP_MACRO; 133 // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: 'true' and 'false' expressions are equivalent 134 k += (y < 0) ? COND_OP_MACRO + COND_OP_OTHER_MACRO : COND_OP_MACRO + COND_OP_OTHER_MACRO; 135 // CHECK-MESSAGES: :[[@LINE-1]]:54: warning: 'true' and 'false' expressions are equivalent 136 137 // Do not match for conditional operators with a macro and a const. 138 k += (y < 0) ? COND_OP_MACRO : 9; 139 // Do not match for conditional operators with expressions from different macros. 140 k += (y < 0) ? COND_OP_MACRO : COND_OP_OTHER_MACRO; 141 // Do not match for conditional operators when a macro is defined to another macro 142 k += (y < 0) ? COND_OP_MACRO : COND_OP_THIRD_MACRO; 143 #undef COND_OP_THIRD_MACRO 144 #define COND_OP_THIRD_MACRO 8 145 k += (y < 0) ? COND_OP_MACRO : COND_OP_THIRD_MACRO; 146 #undef COND_OP_THIRD_MACRO 147 148 k += (y < 0) ? sizeof(I64) : sizeof(I64); 149 // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: 'true' and 'false' expressions are equivalent 150 k += (y < 0) ? sizeof(TestConditional(k,y)) : sizeof(TestConditional(k,y)); 151 // CHECK-MESSAGES: :[[@LINE-1]]:47: warning: 'true' and 'false' expressions are equivalent 152 // No warning if the expression arguments are different. 153 k += (y < 0) ? sizeof(TestConditional(k,y)) : sizeof(Valid(k,y)); 154 155 return k; 156 } 157 #undef COND_OP_MACRO 158 #undef COND_OP_OTHER_MACRO 159 160 // Overloaded operators that compare two instances of a struct. 161 struct MyStruct { 162 int x; 163 bool operator==(const MyStruct& rhs) const {return this->x == rhs.x; } // not modifing 164 bool operator>=(const MyStruct& rhs) const { return this->x >= rhs.x; } // not modifing 165 bool operator<=(MyStruct& rhs) const { return this->x <= rhs.x; } 166 bool operator&&(const MyStruct& rhs){ this->x++; return this->x && rhs.x; } 167 } Q; 168 169 bool operator!=(const MyStruct& lhs, const MyStruct& rhs) { return lhs.x == rhs.x; } // not modifing 170 bool operator<(const MyStruct& lhs, const MyStruct& rhs) { return lhs.x < rhs.x; } // not modifing 171 bool operator>(const MyStruct& lhs, MyStruct& rhs) { rhs.x--; return lhs.x > rhs.x; } 172 bool operator||(MyStruct& lhs, const MyStruct& rhs) { lhs.x++; return lhs.x || rhs.x; } 173 174 struct MyStruct1 { 175 bool x; 176 MyStruct1(bool x) : x(x) {}; 177 operator bool() { return x; } 178 }; 179 180 MyStruct1 operator&&(const MyStruct1& lhs, const MyStruct1& rhs) { return lhs.x && rhs.x; } 181 MyStruct1 operator||(MyStruct1& lhs, MyStruct1& rhs) { return lhs.x && rhs.x; } 182 183 bool TestOverloadedOperator(MyStruct& S) { 184 if (S == Q) return false; 185 186 if (S <= S) return false; 187 if (S && S) return false; 188 if (S > S) return false; 189 if (S || S) return false; 190 191 if (S == S) return true; 192 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: both sides of overloaded operator are equivalent 193 if (S < S) return true; 194 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: both sides of overloaded operator are equivalent 195 if (S != S) return true; 196 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: both sides of overloaded operator are equivalent 197 if (S >= S) return true; 198 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: both sides of overloaded operator are equivalent 199 200 MyStruct1 U(false); 201 MyStruct1 V(true); 202 203 // valid because the operator is not const 204 if ((U || V) || U) return true; 205 206 if (U && V && U && V) return true; 207 // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: overloaded operator has equivalent nested operands 208 209 return true; 210 } 211 212 #define LT(x, y) (void)((x) < (y)) 213 #define COND(x, y, z) ((x)?(y):(z)) 214 #define EQUALS(x, y) (x) == (y) 215 216 int TestMacro(int X, int Y) { 217 LT(0, 0); 218 LT(1, 0); 219 LT(X, X); 220 LT(X+1, X + 1); 221 COND(X < Y, X, X); 222 EQUALS(Q, Q); 223 return 0; 224 } 225 226 int TestFalsePositive(int* A, int X, float F) { 227 // Produced by bison. 228 X = A[(2) - (2)]; 229 X = A['a' - 'a']; 230 231 // Testing NaN. 232 if (F != F && F == F) return 1; 233 return 0; 234 } 235 236 int TestBannedMacros() { 237 #define EAGAIN 3 238 #define NOT_EAGAIN 3 239 if (EAGAIN == 0 | EAGAIN == 0) return 0; 240 if (NOT_EAGAIN == 0 | NOT_EAGAIN == 0) return 0; 241 // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: both sides of operator are equivalent 242 return 0; 243 } 244 245 struct MyClass { 246 static const int Value = 42; 247 }; 248 template <typename T, typename U> 249 void TemplateCheck() { 250 static_assert(T::Value == U::Value, "should be identical"); 251 static_assert(T::Value == T::Value, "should be identical"); 252 // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: both sides of operator are equivalent 253 } 254 void TestTemplate() { TemplateCheck<MyClass, MyClass>(); } 255 256 int TestArithmetic(int X, int Y) { 257 if (X + 1 == X) return 1; 258 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: logical expression is always false 259 if (X + 1 != X) return 1; 260 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: logical expression is always true 261 if (X - 1 == X) return 1; 262 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: logical expression is always false 263 if (X - 1 != X) return 1; 264 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: logical expression is always true 265 266 if (X + 1LL == X) return 1; 267 // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: logical expression is always false 268 if (X + 1ULL == X) return 1; 269 // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: logical expression is always false 270 271 if (X == X + 1) return 1; 272 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: logical expression is always false 273 if (X != X + 1) return 1; 274 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: logical expression is always true 275 if (X == X - 1) return 1; 276 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: logical expression is always false 277 if (X != X - 1) return 1; 278 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: logical expression is always true 279 280 if (X != X - 1U) return 1; 281 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: logical expression is always true 282 if (X != X - 1LL) return 1; 283 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: logical expression is always true 284 285 if ((X+X) != (X+X) - 1) return 1; 286 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: logical expression is always true 287 288 if (X + 1 == X + 2) return 1; 289 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: logical expression is always false 290 if (X + 1 != X + 2) return 1; 291 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: logical expression is always true 292 293 if (X - 1 == X - 2) return 1; 294 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: logical expression is always false 295 if (X - 1 != X - 2) return 1; 296 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: logical expression is always true 297 298 if (X + 1 == X - -1) return 1; 299 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: logical expression is always true 300 if (X + 1 != X - -1) return 1; 301 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: logical expression is always false 302 if (X + 1 == X - -2) return 1; 303 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: logical expression is always false 304 if (X + 1 != X - -2) return 1; 305 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: logical expression is always true 306 307 if (X + 1 == X - (~0)) return 1; 308 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: logical expression is always true 309 if (X + 1 == X - (~0U)) return 1; 310 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: logical expression is always true 311 312 if (X + 1 == X - (~0ULL)) return 1; 313 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: logical expression is always true 314 315 // Should not match. 316 if (X + 0.5 == X) return 1; 317 if (X + 1 == Y) return 1; 318 if (X + 1 == Y + 1) return 1; 319 if (X + 1 == Y + 2) return 1; 320 321 return 0; 322 } 323 324 int TestBitwise(int X, int Y) { 325 326 if ((X & 0xFF) == 0xF00) return 1; 327 // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: logical expression is always false 328 if ((X & 0xFF) != 0xF00) return 1; 329 // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: logical expression is always true 330 if ((X | 0xFF) == 0xF00) return 1; 331 // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: logical expression is always false 332 if ((X | 0xFF) != 0xF00) return 1; 333 // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: logical expression is always true 334 335 if ((X | 0xFFULL) != 0xF00) return 1; 336 // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: logical expression is always true 337 if ((X | 0xFF) != 0xF00ULL) return 1; 338 // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: logical expression is always true 339 340 if ((0xFF & X) == 0xF00) return 1; 341 // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: logical expression is always false 342 if ((0xFF & X) != 0xF00) return 1; 343 // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: logical expression is always true 344 if ((0xFF & X) == 0xF00) return 1; 345 // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: logical expression is always false 346 if ((0xFF & X) != 0xF00) return 1; 347 // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: logical expression is always true 348 349 if ((0xFFLL & X) == 0xF00) return 1; 350 // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: logical expression is always false 351 if ((0xFF & X) == 0xF00ULL) return 1; 352 // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: logical expression is always false 353 354 return 0; 355 } 356 357 // Overloaded operators that compare an instance of a struct and an integer 358 // constant. 359 struct S { 360 S() { x = 1; } 361 int x; 362 // Overloaded comparison operators without any possible side effect. 363 bool operator==(const int &i) const { return x == i; } // not modifying 364 bool operator!=(int i) const { return x != i; } // not modifying 365 bool operator>(const int &i) const { return x > i; } // not modifying 366 bool operator<(int i) const { return x < i; } // not modifying 367 }; 368 369 bool operator<=(const S &s, int i) { return s.x <= i; } // not modifying 370 bool operator>=(const S &s, const int &i) { return s.x >= i; } // not modifying 371 372 bool operator==(int i, const S &s) { return s == i; } // not modifying 373 bool operator<(const int &i, const S &s) { return s > i; } // not modifying 374 bool operator<=(const int &i, const S &s) { return s >= i; } // not modifying 375 bool operator>(const int &i, const S &s) { return s < i; } // not modifying 376 377 struct S2 { 378 S2() { x = 1; } 379 int x; 380 // Overloaded comparison operators that are able to modify their params. 381 bool operator==(const int &i) { 382 this->x++; 383 return x == i; 384 } 385 bool operator!=(int i) { return x != i; } 386 bool operator>(const int &i) { return x > i; } 387 bool operator<(int i) { 388 this->x--; 389 return x < i; 390 } 391 }; 392 393 bool operator>=(S2 &s, const int &i) { return s.x >= i; } 394 bool operator<=(S2 &s, int i) { 395 s.x++; 396 return s.x <= i; 397 } 398 399 int TestLogical(int X, int Y){ 400 #define CONFIG 0 401 if (CONFIG && X) return 1; 402 #undef CONFIG 403 #define CONFIG 1 404 if (CONFIG || X) return 1; 405 #undef CONFIG 406 407 if (X == 10 && X != 10) return 1; 408 // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: logical expression is always false 409 if (X == 10 && (X != 10)) return 1; 410 // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: logical expression is always false 411 if (X == 10 && !(X == 10)) return 1; 412 // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: logical expression is always false 413 if (!(X != 10) && !(X == 10)) return 1; 414 // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: logical expression is always false 415 416 if (X == 10ULL && X != 10ULL) return 1; 417 // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: logical expression is always false 418 if (!(X != 10U) && !(X == 10)) return 1; 419 // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: logical expression is always false 420 if (!(X != 10LL) && !(X == 10)) return 1; 421 // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: logical expression is always false 422 if (!(X != 10ULL) && !(X == 10)) return 1; 423 // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: logical expression is always false 424 425 if (X == 0 && X) return 1; 426 // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: logical expression is always false 427 if (X != 0 && !X) return 1; 428 // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: logical expression is always false 429 if (X && !X) return 1; 430 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: logical expression is always false 431 432 if (X && !!X) return 1; 433 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: equivalent expression on both sides of logical operator 434 if (X != 0 && X) return 1; 435 // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: equivalent expression on both sides of logical operator 436 if (X != 0 && !!X) return 1; 437 // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: equivalent expression on both sides of logical operator 438 if (X == 0 && !X) return 1; 439 // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: equivalent expression on both sides of logical operator 440 441 // Should not match. 442 if (X == 10 && Y == 10) return 1; 443 if (X != 10 && X != 12) return 1; 444 if (X == 10 || X == 12) return 1; 445 if (!X && !Y) return 1; 446 if (!X && Y) return 1; 447 if (!X && Y == 0) return 1; 448 if (X == 10 && Y != 10) return 1; 449 450 // Test for overloaded operators with constant params. 451 S s1; 452 if (s1 == 1 && s1 == 1) return true; 453 // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: equivalent expression on both sides of logical operator 454 if (s1 == 1 || s1 != 1) return true; 455 // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: logical expression is always true 456 if (s1 > 1 && s1 < 1) return true; 457 // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: logical expression is always false 458 if (s1 >= 1 || s1 <= 1) return true; 459 // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: logical expression is always true 460 if (s1 >= 2 && s1 <= 0) return true; 461 // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: logical expression is always false 462 463 // Same test as above but with swapped LHS/RHS on one side of the logical operator. 464 if (1 == s1 && s1 == 1) return true; 465 // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: equivalent expression on both sides of logical operator 466 if (1 == s1 || s1 != 1) return true; 467 // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: logical expression is always true 468 if (1 < s1 && s1 < 1) return true; 469 // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: logical expression is always false 470 if (1 <= s1 || s1 <= 1) return true; 471 // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: logical expression is always true 472 if (2 < s1 && 0 > s1) return true; 473 // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: logical expression is always false 474 475 // Test for absence of false positives (issue #54011). 476 if (s1 == 1 || s1 == 2) return true; 477 if (s1 > 1 && s1 < 3) return true; 478 if (s1 >= 2 || s1 <= 0) return true; 479 480 // Test for overloaded operators that may modify their params. 481 S2 s2; 482 if (s2 == 1 || s2 != 1) return true; 483 if (s2 == 1 || s2 == 1) return true; 484 if (s2 > 1 && s2 < 1) return true; 485 if (s2 >= 1 || s2 <= 1) return true; 486 } 487 488 int TestRelational(int X, int Y) { 489 if (X == 10 && X > 10) return 1; 490 // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: logical expression is always false 491 if (X == 10 && X < 10) return 1; 492 // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: logical expression is always false 493 if (X < 10 && X > 10) return 1; 494 // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: logical expression is always false 495 if (X <= 10 && X > 10) return 1; 496 // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: logical expression is always false 497 if (X < 10 && X >= 10) return 1; 498 // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: logical expression is always false 499 if (X < 10 && X == 10) return 1; 500 // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: logical expression is always false 501 502 if (X > 5 && X <= 5) return 1; 503 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: logical expression is always false 504 if (X > -5 && X <= -5) return 1; 505 // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: logical expression is always false 506 507 if (X < 10 || X >= 10) return 1; 508 // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: logical expression is always true 509 if (X <= 10 || X > 10) return 1; 510 // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: logical expression is always true 511 if (X <= 10 || X >= 11) return 1; 512 // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: logical expression is always true 513 if (X != 7 || X != 14) return 1; 514 // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: logical expression is always true 515 if (X == 7 || X != 5) return 1; 516 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant 517 if (X != 7 || X == 7) return 1; 518 // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: logical expression is always true 519 520 if (X < 7 && X < 6) return 1; 521 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant 522 if (X < 7 && X < 7) return 1; 523 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: both sides of operator are equivalent 524 if (X < 7 && X < 8) return 1; 525 // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: expression is redundant 526 527 if (X < 7 && X <= 5) return 1; 528 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant 529 if (X < 7 && X <= 6) return 1; 530 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: equivalent expression on both sides of logical operator 531 if (X < 7 && X <= 7) return 1; 532 // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: expression is redundant 533 if (X < 7 && X <= 8) return 1; 534 // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: expression is redundant 535 536 if (X <= 7 && X < 6) return 1; 537 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant 538 if (X <= 7 && X < 7) return 1; 539 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant 540 if (X <= 7 && X < 8) return 1; 541 // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: equivalent expression on both sides of logical operator 542 543 if (X >= 7 && X > 6) return 1; 544 // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: equivalent expression on both sides of logical operator 545 if (X >= 7 && X > 7) return 1; 546 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant 547 if (X >= 7 && X > 8) return 1; 548 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant 549 550 if (X <= 7 && X <= 5) return 1; 551 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant 552 if (X <= 7 && X <= 6) return 1; 553 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant 554 if (X <= 7 && X <= 7) return 1; 555 // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: both sides of operator are equivalent 556 if (X <= 7 && X <= 8) return 1; 557 // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: expression is redundant 558 559 if (X == 11 && X > 10) return 1; 560 // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: expression is redundant 561 if (X == 11 && X < 12) return 1; 562 // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: expression is redundant 563 if (X > 10 && X == 11) return 1; 564 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant 565 if (X < 12 && X == 11) return 1; 566 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant 567 568 if (X != 11 && X == 42) return 1; 569 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant 570 if (X != 11 && X > 11) return 1; 571 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant 572 if (X != 11 && X < 11) return 1; 573 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant 574 if (X != 11 && X < 8) return 1; 575 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant 576 if (X != 11 && X > 14) return 1; 577 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant 578 579 if (X < 7 || X < 6) return 1; 580 // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: expression is redundant 581 if (X < 7 || X < 7) return 1; 582 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: both sides of operator are equivalent 583 if (X < 7 || X < 8) return 1; 584 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant 585 586 if (X > 7 || X > 6) return 1; 587 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant 588 if (X > 7 || X > 7) return 1; 589 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: both sides of operator are equivalent 590 if (X > 7 || X > 8) return 1; 591 // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: expression is redundant 592 593 // Should not match. 594 if (X < 10 || X > 12) return 1; 595 if (X > 10 && X < 12) return 1; 596 if (X < 10 || X >= 12) return 1; 597 if (X > 10 && X <= 12) return 1; 598 if (X <= 10 || X > 12) return 1; 599 if (X >= 10 && X < 12) return 1; 600 if (X <= 10 || X >= 12) return 1; 601 if (X >= 10 && X <= 12) return 1; 602 if (X >= 10 && X <= 11) return 1; 603 if (X >= 10 && X < 11) return 1; 604 if (X > 10 && X <= 11) return 1; 605 if (X > 10 && X != 11) return 1; 606 if (X >= 10 && X <= 10) return 1; 607 if (X <= 10 && X >= 10) return 1; 608 if (X < 0 || X > 0) return 1; 609 } 610 611 int TestRelationalMacros(int X){ 612 #define SOME_MACRO 3 613 #define SOME_MACRO_SAME_VALUE 3 614 #define SOME_OTHER_MACRO 9 615 // Do not match for redundant relational macro expressions that can be 616 // considered intentional, and for some particular values, non redundant. 617 618 // Test cases for expressions with the same macro on both sides. 619 if (X < SOME_MACRO && X > SOME_MACRO) return 1; 620 // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: logical expression is always false 621 if (X < SOME_MACRO && X == SOME_MACRO) return 1; 622 // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: logical expression is always false 623 if (X < SOME_MACRO || X >= SOME_MACRO) return 1; 624 // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: logical expression is always true 625 if (X <= SOME_MACRO || X > SOME_MACRO) return 1; 626 // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: logical expression is always true 627 if (X != SOME_MACRO && X > SOME_MACRO) return 1; 628 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant 629 if (X != SOME_MACRO && X < SOME_MACRO) return 1; 630 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant 631 632 // Test cases for two different macros. 633 if (X < SOME_MACRO && X > SOME_OTHER_MACRO) return 1; 634 if (X != SOME_MACRO && X >= SOME_OTHER_MACRO) return 1; 635 if (X != SOME_MACRO && X != SOME_OTHER_MACRO) return 1; 636 if (X == SOME_MACRO || X == SOME_MACRO_SAME_VALUE) return 1; 637 if (X == SOME_MACRO || X <= SOME_MACRO_SAME_VALUE) return 1; 638 if (X == SOME_MACRO || X > SOME_MACRO_SAME_VALUE) return 1; 639 if (X < SOME_MACRO && X <= SOME_OTHER_MACRO) return 1; 640 if (X == SOME_MACRO && X > SOME_OTHER_MACRO) return 1; 641 if (X == SOME_MACRO && X != SOME_OTHER_MACRO) return 1; 642 if (X == SOME_MACRO && X != SOME_MACRO_SAME_VALUE) return 1; 643 if (X == SOME_MACRO_SAME_VALUE && X == SOME_MACRO ) return 1; 644 645 // Test cases for a macro and a const. 646 if (X < SOME_MACRO && X > 9) return 1; 647 if (X != SOME_MACRO && X >= 9) return 1; 648 if (X != SOME_MACRO && X != 9) return 1; 649 if (X == SOME_MACRO || X == 3) return 1; 650 if (X == SOME_MACRO || X <= 3) return 1; 651 if (X < SOME_MACRO && X <= 9) return 1; 652 if (X == SOME_MACRO && X != 9) return 1; 653 if (X == SOME_MACRO && X == 9) return 1; 654 655 #undef SOME_OTHER_MACRO 656 #undef SOME_MACRO_SAME_VALUE 657 #undef SOME_MACRO 658 return 0; 659 } 660 661 int TestValidExpression(int X) { 662 if (X - 1 == 1 - X) return 1; 663 if (2 * X == X) return 1; 664 if ((X << 1) == X) return 1; 665 666 return 0; 667 } 668 669 enum Color { Red, Yellow, Green }; 670 int TestRelationalWithEnum(enum Color C) { 671 if (C == Red && C == Yellow) return 1; 672 // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: logical expression is always false 673 if (C == Red && C != Red) return 1; 674 // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: logical expression is always false 675 if (C != Red || C != Yellow) return 1; 676 // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: logical expression is always true 677 678 // Should not match. 679 if (C == Red || C == Yellow) return 1; 680 if (C != Red && C != Yellow) return 1; 681 682 return 0; 683 } 684 685 template<class T> 686 int TestRelationalTemplated(int X) { 687 // This test causes a corner case with |isIntegerConstantExpr| where the type 688 // is dependent. There is an assert failing when evaluating 689 // sizeof(<incomplet-type>). 690 if (sizeof(T) == 4 || sizeof(T) == 8) return 1; 691 692 if (X + 0 == -X) return 1; 693 if (X + 0 < X) return 1; 694 695 return 0; 696 } 697 698 int TestWithSignedUnsigned(int X) { 699 if (X + 1 == X + 1ULL) return 1; 700 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: logical expression is always true 701 702 if ((X & 0xFFU) == 0xF00) return 1; 703 // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: logical expression is always false 704 705 if ((X & 0xFF) == 0xF00U) return 1; 706 // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: logical expression is always false 707 708 if ((X & 0xFFU) == 0xF00U) return 1; 709 // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: logical expression is always false 710 711 return 0; 712 } 713 714 int TestWithLong(int X, I64 Y) { 715 if (X + 0ULL == -X) return 1; 716 if (Y + 0 == -Y) return 1; 717 if (Y <= 10 && X >= 10LL) return 1; 718 if (Y <= 10 && X >= 10ULL) return 1; 719 if (X <= 10 || X > 12LL) return 1; 720 if (X <= 10 || X > 12ULL) return 1; 721 if (Y <= 10 || Y > 12) return 1; 722 723 return 0; 724 } 725 726 int TestWithMinMaxInt(int X) { 727 if (X <= X + 0xFFFFFFFFU) return 1; 728 if (X <= X + 0x7FFFFFFF) return 1; 729 if (X <= X + 0x80000000) return 1; 730 731 if (X <= 0xFFFFFFFFU && X > 0) return 1; 732 if (X <= 0xFFFFFFFFU && X > 0U) return 1; 733 734 if (X + 0x80000000 == X - 0x80000000) return 1; 735 // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: logical expression is always true 736 737 if (X > 0x7FFFFFFF || X < ((-0x7FFFFFFF)-1)) return 1; 738 if (X <= 0x7FFFFFFF && X >= ((-0x7FFFFFFF)-1)) return 1; 739 740 return 0; 741 } 742 743 #define FLAG1 1 744 #define FLAG2 2 745 #define FLAG3 4 746 #define FLAGS (FLAG1 | FLAG2 | FLAG3) 747 #define NOTFLAGS !(FLAG1 | FLAG2 | FLAG3) 748 int TestOperatorConfusion(int X, int Y, long Z) 749 { 750 // Ineffective & expressions. 751 Y = (Y << 8) & 0xff; 752 // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: ineffective bitwise and operation 753 Y = (Y << 12) & 0xfff; 754 // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: ineffective bitwise and 755 Y = (Y << 12) & 0xff; 756 // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: ineffective bitwise and 757 Y = (Y << 8) & 0x77; 758 // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: ineffective bitwise and 759 Y = (Y << 5) & 0x11; 760 // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: ineffective bitwise and 761 762 // Tests for unmatched types 763 Z = (Z << 8) & 0xff; 764 // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: ineffective bitwise and operation 765 Y = (Y << 12) & 0xfffL; 766 // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: ineffective bitwise and 767 Z = (Y << 12) & 0xffLL; 768 // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: ineffective bitwise and 769 Y = (Z << 8L) & 0x77L; 770 // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: ineffective bitwise and 771 772 Y = (Y << 8) & 0; 773 // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: ineffective bitwise and 774 775 Y = (Y << 8) & -1; 776 777 // Effective expressions. Do not check. 778 Y = (Y << 4) & 0x15; 779 Y = (Y << 3) & 0x250; 780 Y = (Y << 9) & 0xF33; 781 782 int K = !(1 | 2 | 4); 783 // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: ineffective logical negation operator used; did you mean '~'? 784 // CHECK-FIXES: {{^}} int K = ~(1 | 2 | 4);{{$}} 785 K = !(FLAG1 & FLAG2 & FLAG3); 786 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: ineffective logical negation operator 787 // CHECK-FIXES: {{^}} K = ~(FLAG1 & FLAG2 & FLAG3);{{$}} 788 K = !(3 | 4); 789 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: ineffective logical negation operator 790 // CHECK-FIXES: {{^}} K = ~(3 | 4);{{$}} 791 int NotFlags = !FLAGS; 792 // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: ineffective logical negation operator 793 // CHECK-FIXES: {{^}} int NotFlags = ~FLAGS;{{$}} 794 NotFlags = NOTFLAGS; 795 // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: ineffective logical negation operator 796 return !(1 | 2 | 4); 797 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: ineffective logical negation operator 798 // CHECK-FIXES: {{^}} return ~(1 | 2 | 4);{{$}} 799 } 800 801 template <int Shift, int Mask> 802 int TestOperatorConfusionDependent(int Y) { 803 int r1 = (Y << Shift) & 0xff; 804 int r2 = (Y << 8) & Mask; 805 } 806 #undef FLAG1 807 #undef FLAG2 808 #undef FLAG3 809 810 namespace no_crash { 811 struct Foo {}; 812 bool operator<(const Foo&, const Foo&); 813 template <class T> 814 struct Bar { 815 static const Foo &GetFoo(); 816 static bool Test(const T & maybe_foo, const Foo& foo) { 817 return foo < GetFoo() && foo < maybe_foo; 818 } 819 }; 820 821 template <class... Values> 822 struct Bar2 { 823 static_assert((... && (sizeof(Values) > 0)) == (... && (sizeof(Values) > 0))); 824 // FIXME: It's not clear that we should be diagnosing this. The `&&` operator 825 // here is unresolved and could resolve to an overloaded operator that might 826 // have side-effects on its operands. For other constructs with the same 827 // property (eg, the `S2` cases above) we suppress this diagnostic. This 828 // started failing when Clang started properly modeling the fold-expression as 829 // containing an unresolved operator name. 830 // FIXME-MESSAGES: :[[@LINE-1]]:47: warning: both sides of operator are equivalent [misc-redundant-expression] 831 }; 832 833 } // namespace no_crash 834 835 int TestAssignSideEffect(int i) { 836 int k = i; 837 838 if ((k = k + 1) != 1 || (k = k + 1) != 2) 839 return 0; 840 841 if ((k = foo(0)) != 1 || (k = foo(0)) != 2) 842 return 1; 843 844 return 2; 845 } 846 847 namespace PR63096 { 848 849 struct alignas(sizeof(int)) X { 850 int x; 851 }; 852 853 static_assert(alignof(X) == sizeof(X)); 854 static_assert(sizeof(X) == sizeof(X)); 855 // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: both sides of operator are equivalent 856 857 } 858 859 namespace PR35857 { 860 void test() { 861 int x = 0; 862 int y = 0; 863 decltype(x + y - (x + y)) z = 10; 864 } 865 } 866