brintos

brintos / llvm-project-archived public Read only

0
0
Text · 40.2 KiB · 4ff0ba8 Raw
1084 lines · cpp
1// RUN: %check_clang_tidy %s misc-redundant-expression %t -- -- -fno-delayed-template-parsing -Wno-array-compare-cxx262// RUN: %check_clang_tidy %s misc-redundant-expression %t -- -- -fno-delayed-template-parsing -Wno-array-compare-cxx26 -DTEST_MACRO3 4typedef __INT64_TYPE__ I64;5 6struct Point {7  int x;8  int y;9  int a[5];10} P;11 12extern Point P1;13extern Point P2;14 15extern int foo(int x);16extern int bar(int x);17extern int bat(int x, int y);18 19int TestSimpleEquivalent(int X, int Y) {20  if (X - X) return 1;21  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: both sides of operator are equivalent [misc-redundant-expression]22  if (X / X) return 1;23  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: both sides of operator are equivalent24  if (X % X) return 1;25  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: both sides of operator are equivalent26 27  if (X & X) return 1;28  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: both sides of operator are equivalent29  if (X | X) return 1;30  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: both sides of operator are equivalent31  if (X ^ X) return 1;32  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: both sides of operator are equivalent33 34  if (X < X) return 1;35  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: both sides of operator are equivalent36  if (X <= X) return 1;37  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: both sides of operator are equivalent38  if (X > X) return 1;39  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: both sides of operator are equivalent40  if (X >= X) return 1;41  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: both sides of operator are equivalent42 43  if (X && X) return 1;44  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: both sides of operator are equivalent45  if (X || X) return 1;46  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: both sides of operator are equivalent47 48  if (X != (((X)))) return 1;49  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: both sides of operator are equivalent50 51  if (X + 1 == X + 1) return 1;52  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: both sides of operator are equivalent53  if (X + 1 != X + 1) return 1;54  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: both sides of operator are equivalent55  if (X + 1 <= X + 1) return 1;56  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: both sides of operator are equivalent57  if (X + 1 >= X + 1) return 1;58  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: both sides of operator are equivalent59 60  if ((X != 1 || Y != 1) && (X != 1 || Y != 1)) return 1;61  // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: both sides of operator are equivalent62  if (P.a[X - P.x] != P.a[X - P.x]) return 1;63  // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: both sides of operator are equivalent64 65  if ((int)X < (int)X) return 1;66  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: both sides of operator are equivalent67  if (int(X) < int(X)) return 1;68  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: both sides of operator are equivalent69 70  if ( + "dummy" == + "dummy") return 1;71  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: both sides of operator are equivalent72  if (L"abc" == L"abc") return 1;73  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: both sides of operator are equivalent74 75  if (foo(0) - 2 < foo(0) - 2) return 1;76  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: both sides of operator are equivalent77  if (foo(bar(0)) < (foo(bar((0))))) return 1;78  // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: both sides of operator are equivalent79 80  if (P1.x < P2.x && P1.x < P2.x) return 1;81  // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: both sides of operator are equivalent82  if (P2.a[P1.x + 2] < P2.x && P2.a[(P1.x) + (2)] < (P2.x)) return 1;83  // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: both sides of operator are equivalent84 85  if (X && Y && X) return 1;86  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: operator has equivalent nested operands87  if (X || (Y || X)) return 1;88  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: operator has equivalent nested operands89  if ((X ^ Y) ^ (Y ^ X)) return 1;90  // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: operator has equivalent nested operands91 92  return 0;93}94 95#ifndef TEST_MACRO96#define VAL_1 297#define VAL_3 398#else99#define VAL_1 3100#define VAL_3 2101#endif102 103#define VAL_2 2104 105#ifndef TEST_MACRO106#define VAL_4 2 + 1107#define VAL_6 3 + 1108#else109#define VAL_4 3 + 1110#define VAL_6 2 + 1111#endif112 113#define VAL_5 2 + 1114 115struct TestStruct116{117  int mA;118  int mB;119  int mC[10];120};121 122int TestDefineEquivalent() {123 124  int int_val1 = 3;125  int int_val2 = 4;126  int int_val = 0;127  const int cint_val2 = 4;128 129  // Cases which should not be reported130  if (VAL_1 != VAL_2)  return 0;131  if (VAL_3 != VAL_2)  return 0;132  if (VAL_1 == VAL_2)  return 0;133  if (VAL_3 == VAL_2)  return 0;134  if (VAL_1 >= VAL_2)  return 0;135  if (VAL_3 >= VAL_2)  return 0;136  if (VAL_1 <= VAL_2)  return 0;137  if (VAL_3 <= VAL_2)  return 0;138  if (VAL_1 < VAL_2)  return 0;139  if (VAL_3 < VAL_2)  return 0;140  if (VAL_1 > VAL_2)  return 0;141  if (VAL_3 > VAL_2)  return 0;142 143  if (VAL_4 != VAL_5)  return 0;144  if (VAL_6 != VAL_5)  return 0;145  if (VAL_6 == VAL_5)  return 0;146  if (VAL_4 >= VAL_5)  return 0;147  if (VAL_6 >= VAL_5)  return 0;148  if (VAL_4 <= VAL_5)  return 0;149  if (VAL_6 <= VAL_5)  return 0;150  if (VAL_4 > VAL_5)  return 0;151  if (VAL_6 > VAL_5)  return 0;152  if (VAL_4 < VAL_5)  return 0;153  if (VAL_6 < VAL_5)  return 0;154 155  if (VAL_1 != 2)  return 0;156  if (VAL_3 == 3)  return 0;157 158  if (VAL_1 >= VAL_1)  return 0;159  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: both sides of operator are equivalent160  if (VAL_2 <= VAL_2)  return 0;161  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: both sides of operator are equivalent162  if (VAL_3 > VAL_3)  return 0;163  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: both sides of operator are equivalent164  if (VAL_4 < VAL_4)  return 0;165  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: both sides of operator are equivalent166  if (VAL_6 == VAL_6) return 2;167  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: both sides of operator are equivalent168  if (VAL_5 != VAL_5) return 2;169  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: both sides of operator are equivalent170 171  // Test prefixes172  if (+VAL_6 == +VAL_6) return 2;173  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: both sides of operator are equivalent174  if (-VAL_6 == -VAL_6) return 2;175  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: both sides of operator are equivalent176  if ((+VAL_6) == (+VAL_6)) return 2;177  // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: both sides of operator are equivalent178  if ((-VAL_6) == (-VAL_6)) return 2;179  // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: both sides of operator are equivalent180 181  if (1 >= 1)  return 0;182  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: both sides of operator are equivalent183  if (0xFF <= 0xFF)  return 0;184  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: both sides of operator are equivalent185  if (042 > 042)  return 0;186  // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: both sides of operator are equivalent187 188  int_val = (VAL_6 == VAL_6)?int_val1: int_val2;189  // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: both sides of operator are equivalent190  int_val = (042 > 042)?int_val1: int_val2;191  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: both sides of operator are equivalent192 193 194  // Ternary operator cases which should not be reported195  int_val = (VAL_4 == VAL_5)? int_val1: int_val2;196  int_val = (VAL_3 != VAL_2)? int_val1: int_val2;197  int_val = (VAL_6 != 10)? int_val1: int_val2;198  int_val = (VAL_6 != 3)? int_val1: int_val2;199  int_val = (VAL_6 != 4)? int_val1: int_val2;200  int_val = (VAL_6 == 3)? int_val1: int_val2;201  int_val = (VAL_6 == 4)? int_val1: int_val2;202 203  TestStruct tsVar1 = {204    .mA = 3,205    .mB = int_val,206    .mC[0 ... VAL_2 - 2] = int_val + 1,207  };208 209  TestStruct tsVar2 = {210    .mA = 3,211    .mB = int_val,212    .mC[0 ... cint_val2 - 2] = int_val + 1,213  };214 215  TestStruct tsVar3 = {216    .mA = 3,217    .mB = int_val,218    .mC[0 ... VAL_3 - VAL_3] = int_val + 1,219    // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: both sides of operator are equivalent220  };221 222  TestStruct tsVar4 = {223    .mA = 3,224    .mB = int_val,225    .mC[0 ... 5 - 5] = int_val + 1,226    // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: both sides of operator are equivalent227  };228 229  return 1 + int_val + sizeof(tsVar1) + sizeof(tsVar2) +230         sizeof(tsVar3) + sizeof(tsVar4);231}232 233#define LOOP_DEFINE 1234 235unsigned int testLoops(const unsigned int  arr1[LOOP_DEFINE])236{237  unsigned int localIndex;238  for (localIndex = LOOP_DEFINE - 1; localIndex > 0; localIndex--)239  {240  }241  for (localIndex = LOOP_DEFINE - 1; 10 > 10; localIndex--)242  // CHECK-MESSAGES: :[[@LINE-1]]:41: warning: both sides of operator are equivalent243  {244  }245 246  for (localIndex = LOOP_DEFINE - 1; LOOP_DEFINE > LOOP_DEFINE; localIndex--)247  // CHECK-MESSAGES: :[[@LINE-1]]:50: warning: both sides of operator are equivalent248  {249  }250 251  return localIndex;252}253 254#define getValue(a) a255#define getValueM(a) a256 257int TestParamDefine() {258  int ret = 0;259 260  // Negative cases261  ret += getValue(VAL_6) == getValue(2);262  ret += getValue(VAL_6) == getValue(3);263  ret += getValue(VAL_5) == getValue(2);264  ret += getValue(VAL_5) == getValue(3);265  ret += getValue(1) > getValue( 2);266  ret += getValue(VAL_1) == getValue(VAL_2);267  ret += getValue(VAL_1) != getValue(VAL_2);268  ret += getValue(VAL_1) == getValueM(VAL_1);269  ret += getValue(VAL_1 + VAL_2) == getValueM(VAL_1 + VAL_2);270  ret += getValue(1) == getValueM(1);271  ret += getValue(false) == getValueM(false);272  ret += -getValue(1) > +getValue( 1);273 274  // Positive cases275  ret += (+getValue(1)) > (+getValue( 1));276  // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: both sides of operator are equivalent277  ret += (-getValue(1)) > (-getValue( 1));278  // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: both sides of operator are equivalent279 280  ret += +getValue(1) > +getValue( 1);281  // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: both sides of operator are equivalent282  ret += -getValue(1) > -getValue( 1);283  // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: both sides of operator are equivalent284 285  ret += getValue(1) > getValue( 1);286  // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: both sides of operator are equivalent287  ret += getValue(1) > getValue( 1  );288  // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: both sides of operator are equivalent289  ret += getValue(1) > getValue(  1);290  // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: both sides of operator are equivalent291  ret += getValue(     1) > getValue( 1);292  // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: both sides of operator are equivalent293  ret += getValue( 1     ) > getValue( 1);294  // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: both sides of operator are equivalent295  ret += getValue( VAL_5     ) > getValue(VAL_5);296  // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: both sides of operator are equivalent297  ret += getValue( VAL_5     ) > getValue( VAL_5);298  // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: both sides of operator are equivalent299  ret += getValue( VAL_5     ) > getValue( VAL_5  )  ;300  // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: both sides of operator are equivalent301  ret += getValue(VAL_5) > getValue( VAL_5  )  ;302  // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: both sides of operator are equivalent303  ret += getValue(VAL_1+VAL_2) > getValue(VAL_1 + VAL_2)  ;304  // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: both sides of operator are equivalent305  ret += getValue(VAL_1)+getValue(VAL_2) > getValue(VAL_1) + getValue( VAL_2)  ;306  // CHECK-MESSAGES: :[[@LINE-1]]:42: warning: both sides of operator are equivalent307  ret += (getValue(VAL_1)+getValue(VAL_2)) > (getValue(VAL_1) + getValue( VAL_2) ) ;308  // CHECK-MESSAGES: :[[@LINE-1]]:44: warning: both sides of operator are equivalent309  return ret;310}311 312template <int DX>313int TestSimpleEquivalentDependent() {314  if (DX > 0 && DX > 0) return 1;315  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: both sides of operator are equivalent316 317  return 0;318}319 320int Valid(int X, int Y) {321  if (X != Y) return 1;322  if (X == Y + 0) return 1;323  if (P.x == P.y) return 1;324  if (P.a[P.x] < P.a[P.y]) return 1;325  if (P.a[0] < P.a[1]) return 1;326 327  if (P.a[0] < P.a[0ULL]) return 1;328  if (0 < 0ULL) return 1;329  if ((int)0 < (int)0ULL) return 1;330 331  if (++X != ++X) return 1;332  if (P.a[X]++ != P.a[X]++) return 1;333  if (P.a[X++] != P.a[X++]) return 1;334  if (X && X++ && X) return 1;335 336  if ("abc" == "ABC") return 1;337  if (foo(bar(0)) < (foo(bat(0, 1)))) return 1;338  return 0;339}340 341#define COND_OP_MACRO 9342#define COND_OP_OTHER_MACRO 9343#define COND_OP_THIRD_MACRO COND_OP_MACRO344int TestConditional(int x, int y) {345  int k = 0;346  k += (y < 0) ? x : x;347  // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: 'true' and 'false' expressions are equivalent348  k += (y < 0) ? x + 1 : x + 1;349  // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: 'true' and 'false' expressions are equivalent350  k += (y < 0) ? COND_OP_MACRO : COND_OP_MACRO;351  // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: 'true' and 'false' expressions are equivalent352  k += (y < 0) ? COND_OP_MACRO + COND_OP_OTHER_MACRO : COND_OP_MACRO + COND_OP_OTHER_MACRO;353  // CHECK-MESSAGES: :[[@LINE-1]]:54: warning: 'true' and 'false' expressions are equivalent354 355  // Do not match for conditional operators with a macro and a const.356  k += (y < 0) ? COND_OP_MACRO : 9;357  // Do not match for conditional operators with expressions from different macros.358  k += (y < 0) ? COND_OP_MACRO : COND_OP_OTHER_MACRO;359  // Do not match for conditional operators when a macro is defined to another macro360  k += (y < 0) ? COND_OP_MACRO : COND_OP_THIRD_MACRO;361#undef COND_OP_THIRD_MACRO362#define   COND_OP_THIRD_MACRO 8363  k += (y < 0) ? COND_OP_MACRO : COND_OP_THIRD_MACRO;364#undef COND_OP_THIRD_MACRO365 366  k += (y < 0) ? sizeof(I64) : sizeof(I64);367  // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: 'true' and 'false' expressions are equivalent368  k += (y < 0) ? sizeof(TestConditional(k,y)) : sizeof(TestConditional(k,y));369  // CHECK-MESSAGES: :[[@LINE-1]]:47: warning: 'true' and 'false' expressions are equivalent370  // No warning if the expression arguments are different.371  k += (y < 0) ? sizeof(TestConditional(k,y)) : sizeof(Valid(k,y));372 373  return k;374}375#undef COND_OP_MACRO376#undef COND_OP_OTHER_MACRO377 378// Overloaded operators that compare two instances of a struct.379struct MyStruct {380  int x;381  bool operator==(const MyStruct& rhs) const {return this->x == rhs.x; } // not modifing382  bool operator>=(const MyStruct& rhs) const { return this->x >= rhs.x; } // not modifing383  bool operator<=(MyStruct& rhs) const { return this->x <= rhs.x; }384  bool operator&&(const MyStruct& rhs){ this->x++; return this->x && rhs.x; }385} Q;386 387bool operator!=(const MyStruct& lhs, const MyStruct& rhs) { return lhs.x == rhs.x; } // not modifing388bool operator<(const MyStruct& lhs, const MyStruct& rhs) { return lhs.x < rhs.x; } // not modifing389bool operator>(const MyStruct& lhs, MyStruct& rhs) { rhs.x--; return lhs.x > rhs.x; }390bool operator||(MyStruct& lhs, const MyStruct& rhs) { lhs.x++; return lhs.x || rhs.x; }391 392struct MyStruct1 {393  bool x;394  MyStruct1(bool x) : x(x) {};395  operator bool() { return x; }396};397 398MyStruct1 operator&&(const MyStruct1& lhs, const MyStruct1& rhs) { return lhs.x && rhs.x; }399MyStruct1 operator||(MyStruct1& lhs, MyStruct1& rhs) { return lhs.x && rhs.x; }400 401bool TestOverloadedOperator(MyStruct& S) {402  if (S == Q) return false;403 404  if (S <= S) return false;405  if (S && S) return false;406  if (S > S) return false;407  if (S || S) return false;408 409  if (S == S) return true;410  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: both sides of overloaded operator are equivalent411  if (S < S) return true;412  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: both sides of overloaded operator are equivalent413  if (S != S) return true;414  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: both sides of overloaded operator are equivalent415  if (S >= S) return true;416  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: both sides of overloaded operator are equivalent417 418  MyStruct1 U(false);419  MyStruct1 V(true);420 421  // valid because the operator is not const422  if ((U || V) || U) return true;423 424  if (U && V && U && V) return true;425  // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: overloaded operator has equivalent nested operands426 427  return true;428}429 430#define LT(x, y) (void)((x) < (y))431#define COND(x, y, z) ((x)?(y):(z))432#define EQUALS(x, y) (x) == (y)433 434int TestMacro(int X, int Y) {435  LT(0, 0);436  LT(1, 0);437  LT(X, X);438  LT(X+1, X + 1);439  COND(X < Y, X, X);440  EQUALS(Q, Q);441  return 0;442}443 444int TestFalsePositive(int* A, int X, float F) {445  // Produced by bison.446  X = A[(2) - (2)];447  X = A['a' - 'a'];448 449  // Testing NaN.450  if (F != F && F == F) return 1;451  return 0;452}453 454int TestBannedMacros() {455#define EAGAIN 3456#define NOT_EAGAIN 3457  if (EAGAIN == 0 | EAGAIN == 0) return 0;458  if (NOT_EAGAIN == 0 | NOT_EAGAIN == 0) return 0;459  // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: both sides of operator are equivalent460  return 0;461}462 463struct MyClass {464static const int Value = 42;465};466template <typename T, typename U>467void TemplateCheck() {468  static_assert(T::Value == U::Value, "should be identical");469  static_assert(T::Value == T::Value, "should be identical");470  // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: both sides of operator are equivalent471}472void TestTemplate() { TemplateCheck<MyClass, MyClass>(); }473 474int TestArithmetic(int X, int Y) {475  if (X + 1 == X) return 1;476  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: logical expression is always false477  if (X + 1 != X) return 1;478  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: logical expression is always true479  if (X - 1 == X) return 1;480  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: logical expression is always false481  if (X - 1 != X) return 1;482  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: logical expression is always true483 484  if (X + 1LL == X) return 1;485  // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: logical expression is always false486  if (X + 1ULL == X) return 1;487  // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: logical expression is always false488 489  if (X == X + 1) return 1;490  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: logical expression is always false491  if (X != X + 1) return 1;492  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: logical expression is always true493  if (X == X - 1) return 1;494  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: logical expression is always false495  if (X != X - 1) return 1;496  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: logical expression is always true497 498  if (X != X - 1U) return 1;499  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: logical expression is always true500  if (X != X - 1LL) return 1;501  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: logical expression is always true502 503  if ((X+X) != (X+X) - 1) return 1;504  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: logical expression is always true505 506  if (X + 1 == X + 2) return 1;507  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: logical expression is always false508  if (X + 1 != X + 2) return 1;509  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: logical expression is always true510 511  if (X - 1 == X - 2) return 1;512  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: logical expression is always false513  if (X - 1 != X - 2) return 1;514  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: logical expression is always true515 516  if (X + 1 == X - -1) return 1;517  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: logical expression is always true518  if (X + 1 != X - -1) return 1;519  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: logical expression is always false520  if (X + 1 == X - -2) return 1;521  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: logical expression is always false522  if (X + 1 != X - -2) return 1;523  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: logical expression is always true524 525  if (X + 1 == X - (~0)) return 1;526  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: logical expression is always true527  if (X + 1 == X - (~0U)) return 1;528  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: logical expression is always true529 530  if (X + 1 == X - (~0ULL)) return 1;531  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: logical expression is always true532 533  // Should not match.534  if (X + 0.5 == X) return 1;535  if (X + 1 == Y) return 1;536  if (X + 1 == Y + 1) return 1;537  if (X + 1 == Y + 2) return 1;538 539  return 0;540}541 542int TestBitwise(int X, int Y) {543 544  if ((X & 0xFF) == 0xF00) return 1;545  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: logical expression is always false546  if ((X & 0xFF) != 0xF00) return 1;547  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: logical expression is always true548  if ((X | 0xFF) == 0xF00) return 1;549  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: logical expression is always false550  if ((X | 0xFF) != 0xF00) return 1;551  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: logical expression is always true552 553  if ((X | 0xFFULL) != 0xF00) return 1;554  // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: logical expression is always true555  if ((X | 0xFF) != 0xF00ULL) return 1;556  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: logical expression is always true557 558  if ((0xFF & X) == 0xF00) return 1;559  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: logical expression is always false560  if ((0xFF & X) != 0xF00) return 1;561  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: logical expression is always true562  if ((0xFF & X) == 0xF00) return 1;563  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: logical expression is always false564  if ((0xFF & X) != 0xF00) return 1;565  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: logical expression is always true566 567  if ((0xFFLL & X) == 0xF00) return 1;568  // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: logical expression is always false569  if ((0xFF & X) == 0xF00ULL) return 1;570  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: logical expression is always false571 572  return 0;573}574 575// Overloaded operators that compare an instance of a struct and an integer576// constant.577struct S {578  S() { x = 1; }579  int x;580  // Overloaded comparison operators without any possible side effect.581  bool operator==(const int &i) const { return x == i; } // not modifying582  bool operator!=(int i) const { return x != i; } // not modifying583  bool operator>(const int &i) const { return x > i; } // not modifying584  bool operator<(int i) const { return x < i; } // not modifying585};586 587bool operator<=(const S &s, int i) { return s.x <= i; } // not modifying588bool operator>=(const S &s, const int &i) { return s.x >= i; } // not modifying589 590bool operator==(int i, const S &s) { return s == i; } // not modifying591bool operator<(const int &i, const S &s) { return s > i; } // not modifying592bool operator<=(const int &i, const S &s) { return s >= i; } // not modifying593bool operator>(const int &i, const S &s) { return s < i; } // not modifying594 595struct S2 {596  S2() { x = 1; }597  int x;598  // Overloaded comparison operators that are able to modify their params.599  bool operator==(const int &i) {600    this->x++;601    return x == i;602  }603  bool operator!=(int i) { return x != i; }604  bool operator>(const int &i) { return x > i; }605  bool operator<(int i) {606    this->x--;607    return x < i;608  }609};610 611bool operator>=(S2 &s, const int &i) { return s.x >= i; }612bool operator<=(S2 &s, int i) {613  s.x++;614  return s.x <= i;615}616 617int TestLogical(int X, int Y){618#define CONFIG 0619  if (CONFIG && X) return 1;620#undef CONFIG621#define CONFIG 1622  if (CONFIG || X) return 1;623#undef CONFIG624 625  if (X == 10 && X != 10) return 1;626  // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: logical expression is always false627  if (X == 10 && (X != 10)) return 1;628  // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: logical expression is always false629  if (X == 10 && !(X == 10)) return 1;630  // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: logical expression is always false631  if (!(X != 10) && !(X == 10)) return 1;632  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: logical expression is always false633 634  if (X == 10ULL && X != 10ULL) return 1;635  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: logical expression is always false636  if (!(X != 10U) && !(X == 10)) return 1;637  // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: logical expression is always false638  if (!(X != 10LL) && !(X == 10)) return 1;639  // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: logical expression is always false640  if (!(X != 10ULL) && !(X == 10)) return 1;641  // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: logical expression is always false642 643  if (X == 0 && X) return 1;644  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: logical expression is always false645  if (X != 0 && !X) return 1;646  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: logical expression is always false647  if (X && !X) return 1;648  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: logical expression is always false649 650  if (X && !!X) return 1;651  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: equivalent expression on both sides of logical operator652  if (X != 0 && X) return 1;653  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: equivalent expression on both sides of logical operator654  if (X != 0 && !!X) return 1;655  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: equivalent expression on both sides of logical operator656  if (X == 0 && !X) return 1;657  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: equivalent expression on both sides of logical operator658 659  // Should not match.660  if (X == 10 && Y == 10) return 1;661  if (X != 10 && X != 12) return 1;662  if (X == 10 || X == 12) return 1;663  if (!X && !Y) return 1;664  if (!X && Y) return 1;665  if (!X && Y == 0) return 1;666  if (X == 10 && Y != 10) return 1;667 668  // Test for overloaded operators with constant params.669  S s1;670  if (s1 == 1 && s1 == 1) return true;671  // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: equivalent expression on both sides of logical operator672  if (s1 == 1 || s1 != 1) return true;673  // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: logical expression is always true674  if (s1 > 1 && s1 < 1) return true;675  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: logical expression is always false676  if (s1 >= 1 || s1 <= 1) return true;677  // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: logical expression is always true678  if (s1 >= 2 && s1 <= 0) return true;679  // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: logical expression is always false680 681  // Same test as above but with swapped LHS/RHS on one side of the logical operator.682  if (1 == s1 && s1 == 1) return true;683  // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: equivalent expression on both sides of logical operator684  if (1 == s1 || s1 != 1) return true;685  // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: logical expression is always true686  if (1 < s1 && s1 < 1) return true;687  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: logical expression is always false688  if (1 <= s1 || s1 <= 1) return true;689  // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: logical expression is always true690  if (2 < s1 && 0 > s1) return true;691  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: logical expression is always false692 693  // Test for absence of false positives (issue #54011).694  if (s1 == 1 || s1 == 2) return true;695  if (s1 > 1 && s1 < 3) return true;696  if (s1 >= 2 || s1 <= 0) return true;697 698  // Test for overloaded operators that may modify their params.699  S2 s2;700  if (s2 == 1 || s2 != 1) return true;701  if (s2 == 1 || s2 == 1) return true;702  if (s2 > 1 && s2 < 1) return true;703  if (s2 >= 1 || s2 <= 1) return true;704}705 706int TestRelational(int X, int Y) {707  if (X == 10 && X > 10) return 1;708  // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: logical expression is always false709  if (X == 10 && X < 10) return 1;710  // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: logical expression is always false711  if (X < 10 && X > 10) return 1;712  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: logical expression is always false713  if (X <= 10 && X > 10) return 1;714  // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: logical expression is always false715  if (X < 10 && X >= 10) return 1;716  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: logical expression is always false717  if (X < 10 && X == 10) return 1;718  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: logical expression is always false719 720  if (X > 5 && X <= 5) return 1;721  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: logical expression is always false722  if (X > -5 && X <= -5) return 1;723  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: logical expression is always false724 725  if (X < 10 || X >= 10) return 1;726  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: logical expression is always true727  if (X <= 10 || X > 10) return 1;728  // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: logical expression is always true729  if (X <= 10 || X >= 11) return 1;730  // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: logical expression is always true731  if (X != 7 || X != 14) return 1;732  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: logical expression is always true733  if (X == 7 || X != 5) return 1;734  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant735  if (X != 7 || X == 7) return 1;736  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: logical expression is always true737 738  if (X < 7 && X < 6) return 1;739  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant740  if (X < 7 && X < 7) return 1;741  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: both sides of operator are equivalent742  if (X < 7 && X < 8) return 1;743  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: expression is redundant744 745  if (X < 7 && X <= 5) return 1;746  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant747  if (X < 7 && X <= 6) return 1;748  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: equivalent expression on both sides of logical operator749  if (X < 7 && X <= 7) return 1;750  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: expression is redundant751  if (X < 7 && X <= 8) return 1;752  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: expression is redundant753 754  if (X <= 7 && X < 6) return 1;755  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant756  if (X <= 7 && X < 7) return 1;757  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant758  if (X <= 7 && X < 8) return 1;759  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: equivalent expression on both sides of logical operator760 761  if (X >= 7 && X > 6) return 1;762  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: equivalent expression on both sides of logical operator763  if (X >= 7 && X > 7) return 1;764  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant765  if (X >= 7 && X > 8) return 1;766  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant767 768  if (X <= 7 && X <= 5) return 1;769  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant770  if (X <= 7 && X <= 6) return 1;771  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant772  if (X <= 7 && X <= 7) return 1;773  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: both sides of operator are equivalent774  if (X <= 7 && X <= 8) return 1;775  // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: expression is redundant776 777  if (X == 11 && X > 10) return 1;778  // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: expression is redundant779  if (X == 11 && X < 12) return 1;780  // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: expression is redundant781  if (X > 10 && X == 11) return 1;782  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant783  if (X < 12 && X == 11) return 1;784  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant785 786  if (X != 11 && X == 42) return 1;787  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant788  if (X != 11 && X > 11) return 1;789  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant790  if (X != 11 && X < 11) return 1;791  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant792  if (X != 11 && X < 8) return 1;793  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant794  if (X != 11 && X > 14) return 1;795  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant796 797  if (X < 7 || X < 6) return 1;798  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: expression is redundant799  if (X < 7 || X < 7) return 1;800  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: both sides of operator are equivalent801  if (X < 7 || X < 8) return 1;802  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant803 804  if (X > 7 || X > 6) return 1;805  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant806  if (X > 7 || X > 7) return 1;807  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: both sides of operator are equivalent808  if (X > 7 || X > 8) return 1;809  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: expression is redundant810 811  // Should not match.812  if (X < 10 || X > 12) return 1;813  if (X > 10 && X < 12) return 1;814  if (X < 10 || X >= 12) return 1;815  if (X > 10 && X <= 12) return 1;816  if (X <= 10 || X > 12) return 1;817  if (X >= 10 && X < 12) return 1;818  if (X <= 10 || X >= 12) return 1;819  if (X >= 10 && X <= 12) return 1;820  if (X >= 10 && X <= 11) return 1;821  if (X >= 10 && X < 11) return 1;822  if (X > 10 && X <= 11) return 1;823  if (X > 10 && X != 11) return 1;824  if (X >= 10 && X <= 10) return 1;825  if (X <= 10 && X >= 10) return 1;826  if (X < 0 || X > 0) return 1;827}828 829int TestRelationalMacros(int X){830#define SOME_MACRO 3831#define SOME_MACRO_SAME_VALUE 3832#define SOME_OTHER_MACRO 9833  // Do not match for redundant relational macro expressions that can be834  // considered intentional, and for some particular values, non redundant.835 836  // Test cases for expressions with the same macro on both sides.837  if (X < SOME_MACRO && X > SOME_MACRO) return 1;838  // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: logical expression is always false839  if (X < SOME_MACRO && X == SOME_MACRO) return 1;840  // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: logical expression is always false841  if (X < SOME_MACRO || X >= SOME_MACRO) return 1;842  // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: logical expression is always true843  if (X <= SOME_MACRO || X > SOME_MACRO) return 1;844  // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: logical expression is always true845  if (X != SOME_MACRO && X > SOME_MACRO) return 1;846  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant847  if (X != SOME_MACRO && X < SOME_MACRO) return 1;848  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant849 850  // Test cases for two different macros.851  if (X < SOME_MACRO && X > SOME_OTHER_MACRO) return 1;852  if (X != SOME_MACRO && X >= SOME_OTHER_MACRO) return 1;853  if (X != SOME_MACRO && X != SOME_OTHER_MACRO) return 1;854  if (X == SOME_MACRO || X == SOME_MACRO_SAME_VALUE) return 1;855  if (X == SOME_MACRO || X <= SOME_MACRO_SAME_VALUE) return 1;856  if (X == SOME_MACRO || X > SOME_MACRO_SAME_VALUE) return 1;857  if (X < SOME_MACRO && X <= SOME_OTHER_MACRO) return 1;858  if (X == SOME_MACRO && X > SOME_OTHER_MACRO) return 1;859  if (X == SOME_MACRO && X != SOME_OTHER_MACRO) return 1;860  if (X == SOME_MACRO && X != SOME_MACRO_SAME_VALUE) return 1;861  if (X == SOME_MACRO_SAME_VALUE && X == SOME_MACRO ) return 1;862 863  // Test cases for a macro and a const.864  if (X < SOME_MACRO && X > 9) return 1;865  if (X != SOME_MACRO && X >= 9) return 1;866  if (X != SOME_MACRO && X != 9) return 1;867  if (X == SOME_MACRO || X == 3) return 1;868  if (X == SOME_MACRO || X <= 3) return 1;869  if (X < SOME_MACRO && X <= 9) return 1;870  if (X == SOME_MACRO && X != 9) return 1;871  if (X == SOME_MACRO && X == 9) return 1;872 873#undef SOME_OTHER_MACRO874#undef SOME_MACRO_SAME_VALUE875#undef SOME_MACRO876  return 0;877}878 879int TestValidExpression(int X) {880  if (X - 1 == 1 - X) return 1;881  if (2 * X == X) return 1;882  if ((X << 1) == X) return 1;883 884  return 0;885}886 887enum Color { Red, Yellow, Green };888int TestRelationalWithEnum(enum Color C) {889  if (C == Red && C == Yellow) return 1;890  // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: logical expression is always false891  if (C == Red && C != Red) return 1;892  // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: logical expression is always false893  if (C != Red || C != Yellow) return 1;894  // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: logical expression is always true895 896  // Should not match.897  if (C == Red || C == Yellow) return 1;898  if (C != Red && C != Yellow) return 1;899 900  return 0;901}902 903template<class T>904int TestRelationalTemplated(int X) {905  // This test causes a corner case with |isIntegerConstantExpr| where the type906  // is dependent. There is an assert failing when evaluating907  // sizeof(<incomplet-type>).908  if (sizeof(T) == 4 || sizeof(T) == 8) return 1;909 910  if (X + 0 == -X) return 1;911  if (X + 0 < X) return 1;912 913  return 0;914}915 916int TestWithSignedUnsigned(int X) {917  if (X + 1 == X + 1ULL) return 1;918  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: logical expression is always true919 920  if ((X & 0xFFU) == 0xF00) return 1;921  // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: logical expression is always false922 923  if ((X & 0xFF) == 0xF00U) return 1;924  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: logical expression is always false925 926  if ((X & 0xFFU) == 0xF00U) return 1;927  // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: logical expression is always false928 929  return 0;930}931 932int TestWithLong(int X, I64 Y) {933  if (X + 0ULL == -X) return 1;934  if (Y + 0 == -Y) return 1;935  if (Y <= 10 && X >= 10LL) return 1;936  if (Y <= 10 && X >= 10ULL) return 1;937  if (X <= 10 || X > 12LL) return 1;938  if (X <= 10 || X > 12ULL) return 1;939  if (Y <= 10 || Y > 12) return 1;940 941  return 0;942}943 944int TestWithMinMaxInt(int X) {945  if (X <= X + 0xFFFFFFFFU) return 1;946  if (X <= X + 0x7FFFFFFF) return 1;947  if (X <= X + 0x80000000) return 1;948 949  if (X <= 0xFFFFFFFFU && X > 0) return 1;950  if (X <= 0xFFFFFFFFU && X > 0U) return 1;951 952  if (X + 0x80000000 == X - 0x80000000) return 1;953  // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: logical expression is always true954 955  if (X > 0x7FFFFFFF || X < ((-0x7FFFFFFF)-1)) return 1;956  if (X <= 0x7FFFFFFF && X >= ((-0x7FFFFFFF)-1)) return 1;957 958  return 0;959}960 961#define FLAG1 1962#define FLAG2 2963#define FLAG3 4964#define FLAGS (FLAG1 | FLAG2 | FLAG3)965#define NOTFLAGS !(FLAG1 | FLAG2 | FLAG3)966int TestOperatorConfusion(int X, int Y, long Z)967{968  // Ineffective & expressions.969  Y = (Y << 8) & 0xff;970  // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: ineffective bitwise and operation971  Y = (Y << 12) & 0xfff;972  // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: ineffective bitwise and973  Y = (Y << 12) & 0xff;974  // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: ineffective bitwise and975  Y = (Y << 8) & 0x77;976  // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: ineffective bitwise and977  Y = (Y << 5) & 0x11;978  // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: ineffective bitwise and979 980  // Tests for unmatched types981  Z = (Z << 8) & 0xff;982  // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: ineffective bitwise and operation983  Y = (Y << 12) & 0xfffL;984  // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: ineffective bitwise and985  Z = (Y << 12) & 0xffLL;986  // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: ineffective bitwise and987  Y = (Z << 8L) & 0x77L;988  // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: ineffective bitwise and989 990  Y = (Y << 8) & 0;991  // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: ineffective bitwise and992 993  Y = (Y << 8) & -1;994 995  // Effective expressions. Do not check.996  Y = (Y << 4) & 0x15;997  Y = (Y << 3) & 0x250;998  Y = (Y << 9) & 0xF33;999 1000  int K = !(1 | 2 | 4);1001  // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: ineffective logical negation operator used; did you mean '~'?1002  // CHECK-FIXES: int K = ~(1 | 2 | 4);1003  K = !(FLAG1 & FLAG2 & FLAG3);1004  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: ineffective logical negation operator1005  // CHECK-FIXES: K = ~(FLAG1 & FLAG2 & FLAG3);1006  K = !(3 | 4);1007  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: ineffective logical negation operator1008  // CHECK-FIXES: K = ~(3 | 4);1009  int NotFlags = !FLAGS;1010  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: ineffective logical negation operator1011  // CHECK-FIXES: int NotFlags = ~FLAGS;1012  NotFlags = NOTFLAGS;1013  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: ineffective logical negation operator1014  return !(1 | 2 | 4);1015  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: ineffective logical negation operator1016  // CHECK-FIXES: return ~(1 | 2 | 4);1017}1018 1019template <int Shift, int Mask>1020int TestOperatorConfusionDependent(int Y) {1021  int r1 = (Y << Shift) & 0xff;1022  int r2 = (Y << 8) & Mask;1023}1024#undef FLAG11025#undef FLAG21026#undef FLAG31027 1028namespace no_crash {1029struct Foo {};1030bool operator<(const Foo&, const Foo&);1031template <class T>1032struct Bar {1033  static const Foo &GetFoo();1034  static bool Test(const T & maybe_foo, const Foo& foo) {1035    return foo < GetFoo() && foo < maybe_foo;1036  }1037};1038 1039template <class... Values>1040struct Bar2 {1041  static_assert((... && (sizeof(Values) > 0)) == (... && (sizeof(Values) > 0)));1042  // FIXME: It's not clear that we should be diagnosing this. The `&&` operator1043  // here is unresolved and could resolve to an overloaded operator that might1044  // have side-effects on its operands. For other constructs with the same1045  // property (eg, the `S2` cases above) we suppress this diagnostic. This1046  // started failing when Clang started properly modeling the fold-expression as1047  // containing an unresolved operator name.1048  // FIXME-MESSAGES: :[[@LINE-1]]:47: warning: both sides of operator are equivalent [misc-redundant-expression]1049};1050 1051} // namespace no_crash1052 1053int TestAssignSideEffect(int i) {1054  int k = i;1055 1056  if ((k = k + 1) != 1 || (k = k + 1) != 2)1057    return 0;1058 1059  if ((k = foo(0)) != 1 || (k = foo(0)) != 2)1060    return 1;1061 1062  return 2;1063}1064 1065namespace PR63096 {1066 1067struct alignas(sizeof(int)) X {1068  int x;1069};1070 1071static_assert(alignof(X) == sizeof(X));1072static_assert(sizeof(X) == sizeof(X));1073// CHECK-MESSAGES: :[[@LINE-1]]:25: warning: both sides of operator are equivalent1074 1075}1076 1077namespace PR35857 {1078  void test() {1079    int x = 0;1080    int y = 0;1081    decltype(x + y - (x + y)) z = 10;1082  }1083}1084