1 // RUN: %check_clang_tidy %s misc-redundant-expression %t -- -- -fno-delayed-template-parsing
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 
TestSimpleEquivalent(int X,int Y)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>
TestSimpleEquivalentDependent()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 
Valid(int X,int Y)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
TestConditional(int x,int y)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;
operator ==MyStruct163   bool operator==(const MyStruct& rhs) const {return this->x == rhs.x; } // not modifing
operator >=MyStruct164   bool operator>=(const MyStruct& rhs) const { return this->x >= rhs.x; } // not modifing
operator <=MyStruct165   bool operator<=(MyStruct& rhs) const { return this->x <= rhs.x; }
operator &&MyStruct166   bool operator&&(const MyStruct& rhs){ this->x++; return this->x && rhs.x; }
167 } Q;
168 
operator !=(const MyStruct & lhs,const MyStruct & rhs)169 bool operator!=(const MyStruct& lhs, const MyStruct& rhs) { return lhs.x == rhs.x; } // not modifing
operator <(const MyStruct & lhs,const MyStruct & rhs)170 bool operator<(const MyStruct& lhs, const MyStruct& rhs) { return lhs.x < rhs.x; } // not modifing
operator >(const MyStruct & lhs,MyStruct & rhs)171 bool operator>(const MyStruct& lhs, MyStruct& rhs) { rhs.x--; return lhs.x > rhs.x; }
operator ||(MyStruct & lhs,const MyStruct & rhs)172 bool operator||(MyStruct& lhs, const MyStruct& rhs) { lhs.x++; return lhs.x || rhs.x; }
173 
174 struct MyStruct1 {
175   bool x;
MyStruct1MyStruct1176   MyStruct1(bool x) : x(x) {};
operator boolMyStruct1177   operator bool() { return x; }
178 };
179 
operator &&(const MyStruct1 & lhs,const MyStruct1 & rhs)180 MyStruct1 operator&&(const MyStruct1& lhs, const MyStruct1& rhs) { return lhs.x && rhs.x; }
operator ||(MyStruct1 & lhs,MyStruct1 & rhs)181 MyStruct1 operator||(MyStruct1& lhs, MyStruct1& rhs) { return lhs.x && rhs.x; }
182 
TestOverloadedOperator(MyStruct & S)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 
TestMacro(int X,int Y)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 
TestFalsePositive(int * A,int X,float F)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 
TestBannedMacros()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>
TemplateCheck()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 }
TestTemplate()254 void TestTemplate() { TemplateCheck<MyClass, MyClass>(); }
255 
TestArithmetic(int X,int Y)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 
TestBitwise(int X,int Y)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 {
SS360   S() { x = 1; }
361   int x;
362   // Overloaded comparison operators without any possible side effect.
operator ==S363   bool operator==(const int &i) const { return x == i; } // not modifying
operator !=S364   bool operator!=(int i) const { return x != i; } // not modifying
operator >S365   bool operator>(const int &i) const { return x > i; } // not modifying
operator <S366   bool operator<(int i) const { return x < i; } // not modifying
367 };
368 
operator <=(const S & s,int i)369 bool operator<=(const S &s, int i) { return s.x <= i; } // not modifying
operator >=(const S & s,const int & i)370 bool operator>=(const S &s, const int &i) { return s.x >= i; } // not modifying
371 
372 struct S2 {
S2S2373   S2() { x = 1; }
374   int x;
375   // Overloaded comparison operators that are able to modify their params.
operator ==S2376   bool operator==(const int &i) {
377     this->x++;
378     return x == i;
379   }
operator !=S2380   bool operator!=(int i) { return x != i; }
operator >S2381   bool operator>(const int &i) { return x > i; }
operator <S2382   bool operator<(int i) {
383     this->x--;
384     return x < i;
385   }
386 };
387 
operator >=(S2 & s,const int & i)388 bool operator>=(S2 &s, const int &i) { return s.x >= i; }
operator <=(S2 & s,int i)389 bool operator<=(S2 &s, int i) {
390   s.x++;
391   return s.x <= i;
392 }
393 
TestLogical(int X,int Y)394 int TestLogical(int X, int Y){
395 #define CONFIG 0
396   if (CONFIG && X) return 1;
397 #undef CONFIG
398 #define CONFIG 1
399   if (CONFIG || X) return 1;
400 #undef CONFIG
401 
402   if (X == 10 && X != 10) return 1;
403   // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: logical expression is always false
404   if (X == 10 && (X != 10)) return 1;
405   // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: logical expression is always false
406   if (X == 10 && !(X == 10)) return 1;
407   // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: logical expression is always false
408   if (!(X != 10) && !(X == 10)) return 1;
409   // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: logical expression is always false
410 
411   if (X == 10ULL && X != 10ULL) return 1;
412   // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: logical expression is always false
413   if (!(X != 10U) && !(X == 10)) return 1;
414   // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: logical expression is always false
415   if (!(X != 10LL) && !(X == 10)) return 1;
416   // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: logical expression is always false
417   if (!(X != 10ULL) && !(X == 10)) return 1;
418   // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: logical expression is always false
419 
420   if (X == 0 && X) return 1;
421   // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: logical expression is always false
422   if (X != 0 && !X) return 1;
423   // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: logical expression is always false
424   if (X && !X) return 1;
425   // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: logical expression is always false
426 
427   if (X && !!X) return 1;
428   // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: equivalent expression on both sides of logical operator
429   if (X != 0 && X) return 1;
430   // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: equivalent expression on both sides of logical operator
431   if (X != 0 && !!X) return 1;
432   // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: equivalent expression on both sides of logical operator
433   if (X == 0 && !X) return 1;
434   // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: equivalent expression on both sides of logical operator
435 
436   // Should not match.
437   if (X == 10 && Y == 10) return 1;
438   if (X != 10 && X != 12) return 1;
439   if (X == 10 || X == 12) return 1;
440   if (!X && !Y) return 1;
441   if (!X && Y) return 1;
442   if (!X && Y == 0) return 1;
443   if (X == 10 && Y != 10) return 1;
444 
445   // Test for overloaded operators with constant params.
446   S s1;
447   if (s1 == 1 && s1 == 1) return true;
448   // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: equivalent expression on both sides of logical operator
449   if (s1 == 1 || s1 != 1) return true;
450   // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: logical expression is always true
451   if (s1 > 1 && s1 < 1) return true;
452   // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: logical expression is always false
453   if (s1 >= 1 || s1 <= 1) return true;
454   // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: logical expression is always true
455 
456   // Test for overloaded operators that may modify their params.
457   S2 s2;
458   if (s2 == 1 || s2 != 1) return true;
459   if (s2 == 1 || s2 == 1) return true;
460   if (s2 > 1 && s2 < 1) return true;
461   if (s2 >= 1 || s2 <= 1) return true;
462 }
463 
TestRelational(int X,int Y)464 int TestRelational(int X, int Y) {
465   if (X == 10 && X > 10) return 1;
466   // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: logical expression is always false
467   if (X == 10 && X < 10) return 1;
468   // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: logical expression is always false
469   if (X < 10 && X > 10) return 1;
470   // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: logical expression is always false
471   if (X <= 10 && X > 10) return 1;
472   // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: logical expression is always false
473   if (X < 10 && X >= 10) return 1;
474   // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: logical expression is always false
475   if (X < 10 && X == 10) return 1;
476   // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: logical expression is always false
477 
478   if (X > 5 && X <= 5) return 1;
479   // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: logical expression is always false
480   if (X > -5 && X <= -5) return 1;
481   // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: logical expression is always false
482 
483   if (X < 10 || X >= 10) return 1;
484   // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: logical expression is always true
485   if (X <= 10 || X > 10) return 1;
486   // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: logical expression is always true
487   if (X <= 10 || X >= 11) return 1;
488   // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: logical expression is always true
489   if (X != 7 || X != 14) return 1;
490   // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: logical expression is always true
491   if (X == 7 || X != 5) return 1;
492   // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant
493   if (X != 7 || X == 7) return 1;
494   // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: logical expression is always true
495 
496   if (X < 7 && X < 6) return 1;
497   // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant
498   if (X < 7 && X < 7) return 1;
499   // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: both sides of operator are equivalent
500   if (X < 7 && X < 8) return 1;
501   // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: expression is redundant
502 
503   if (X < 7 && X <= 5) return 1;
504   // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant
505   if (X < 7 && X <= 6) return 1;
506   // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: equivalent expression on both sides of logical operator
507   if (X < 7 && X <= 7) return 1;
508   // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: expression is redundant
509   if (X < 7 && X <= 8) return 1;
510   // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: expression is redundant
511 
512   if (X <= 7 && X < 6) return 1;
513   // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant
514   if (X <= 7 && X < 7) return 1;
515   // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant
516   if (X <= 7 && X < 8) return 1;
517   // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: equivalent expression on both sides of logical operator
518 
519   if (X >= 7 && X > 6) return 1;
520   // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: equivalent expression on both sides of logical operator
521   if (X >= 7 && X > 7) return 1;
522   // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant
523   if (X >= 7 && X > 8) return 1;
524   // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant
525 
526   if (X <= 7 && X <= 5) return 1;
527   // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant
528   if (X <= 7 && X <= 6) return 1;
529   // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant
530   if (X <= 7 && X <= 7) return 1;
531   // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: both sides of operator are equivalent
532   if (X <= 7 && X <= 8) return 1;
533   // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: expression is redundant
534 
535   if (X == 11 && X > 10) return 1;
536   // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: expression is redundant
537   if (X == 11 && X < 12) return 1;
538   // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: expression is redundant
539   if (X > 10 && X == 11) return 1;
540   // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant
541   if (X < 12 && X == 11) return 1;
542   // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant
543 
544   if (X != 11 && X == 42) return 1;
545   // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant
546   if (X != 11 && X > 11) return 1;
547   // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant
548   if (X != 11 && X < 11) return 1;
549   // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant
550   if (X != 11 && X < 8) return 1;
551   // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant
552   if (X != 11 && X > 14) return 1;
553   // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant
554 
555   if (X < 7 || X < 6) return 1;
556   // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: expression is redundant
557   if (X < 7 || X < 7) return 1;
558   // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: both sides of operator are equivalent
559   if (X < 7 || X < 8) return 1;
560   // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant
561 
562   if (X > 7 || X > 6) return 1;
563   // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant
564   if (X > 7 || X > 7) return 1;
565   // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: both sides of operator are equivalent
566   if (X > 7 || X > 8) return 1;
567   // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: expression is redundant
568 
569   // Should not match.
570   if (X < 10 || X > 12) return 1;
571   if (X > 10 && X < 12) return 1;
572   if (X < 10 || X >= 12) return 1;
573   if (X > 10 && X <= 12) return 1;
574   if (X <= 10 || X > 12) return 1;
575   if (X >= 10 && X < 12) return 1;
576   if (X <= 10 || X >= 12) return 1;
577   if (X >= 10 && X <= 12) return 1;
578   if (X >= 10 && X <= 11) return 1;
579   if (X >= 10 && X < 11) return 1;
580   if (X > 10 && X <= 11) return 1;
581   if (X > 10 && X != 11) return 1;
582   if (X >= 10 && X <= 10) return 1;
583   if (X <= 10 && X >= 10) return 1;
584   if (X < 0 || X > 0) return 1;
585 }
586 
TestRelationalMacros(int X)587 int TestRelationalMacros(int X){
588 #define SOME_MACRO 3
589 #define SOME_MACRO_SAME_VALUE 3
590 #define SOME_OTHER_MACRO 9
591   // Do not match for redundant relational macro expressions that can be
592   // considered intentional, and for some particular values, non redundant.
593 
594   // Test cases for expressions with the same macro on both sides.
595   if (X < SOME_MACRO && X > SOME_MACRO) return 1;
596   // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: logical expression is always false
597   if (X < SOME_MACRO && X == SOME_MACRO) return 1;
598   // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: logical expression is always false
599   if (X < SOME_MACRO || X >= SOME_MACRO) return 1;
600   // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: logical expression is always true
601   if (X <= SOME_MACRO || X > SOME_MACRO) return 1;
602   // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: logical expression is always true
603   if (X != SOME_MACRO && X > SOME_MACRO) return 1;
604   // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant
605   if (X != SOME_MACRO && X < SOME_MACRO) return 1;
606   // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant
607 
608   // Test cases for two different macros.
609   if (X < SOME_MACRO && X > SOME_OTHER_MACRO) return 1;
610   if (X != SOME_MACRO && X >= SOME_OTHER_MACRO) return 1;
611   if (X != SOME_MACRO && X != SOME_OTHER_MACRO) return 1;
612   if (X == SOME_MACRO || X == SOME_MACRO_SAME_VALUE) return 1;
613   if (X == SOME_MACRO || X <= SOME_MACRO_SAME_VALUE) return 1;
614   if (X == SOME_MACRO || X > SOME_MACRO_SAME_VALUE) return 1;
615   if (X < SOME_MACRO && X <= SOME_OTHER_MACRO) return 1;
616   if (X == SOME_MACRO && X > SOME_OTHER_MACRO) return 1;
617   if (X == SOME_MACRO && X != SOME_OTHER_MACRO) return 1;
618   if (X == SOME_MACRO && X != SOME_MACRO_SAME_VALUE) return 1;
619   if (X == SOME_MACRO_SAME_VALUE && X == SOME_MACRO ) return 1;
620 
621   // Test cases for a macro and a const.
622   if (X < SOME_MACRO && X > 9) return 1;
623   if (X != SOME_MACRO && X >= 9) return 1;
624   if (X != SOME_MACRO && X != 9) return 1;
625   if (X == SOME_MACRO || X == 3) return 1;
626   if (X == SOME_MACRO || X <= 3) return 1;
627   if (X < SOME_MACRO && X <= 9) return 1;
628   if (X == SOME_MACRO && X != 9) return 1;
629   if (X == SOME_MACRO && X == 9) return 1;
630 
631 #undef SOME_OTHER_MACRO
632 #undef SOME_MACRO_SAME_VALUE
633 #undef SOME_MACRO
634   return 0;
635 }
636 
TestValidExpression(int X)637 int TestValidExpression(int X) {
638   if (X - 1 == 1 - X) return 1;
639   if (2 * X == X) return 1;
640   if ((X << 1) == X) return 1;
641 
642   return 0;
643 }
644 
645 enum Color { Red, Yellow, Green };
TestRelationalWithEnum(enum Color C)646 int TestRelationalWithEnum(enum Color C) {
647   if (C == Red && C == Yellow) return 1;
648   // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: logical expression is always false
649   if (C == Red && C != Red) return 1;
650   // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: logical expression is always false
651   if (C != Red || C != Yellow) return 1;
652   // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: logical expression is always true
653 
654   // Should not match.
655   if (C == Red || C == Yellow) return 1;
656   if (C != Red && C != Yellow) return 1;
657 
658   return 0;
659 }
660 
661 template<class T>
TestRelationalTemplated(int X)662 int TestRelationalTemplated(int X) {
663   // This test causes a corner case with |isIntegerConstantExpr| where the type
664   // is dependent. There is an assert failing when evaluating
665   // sizeof(<incomplet-type>).
666   if (sizeof(T) == 4 || sizeof(T) == 8) return 1;
667 
668   if (X + 0 == -X) return 1;
669   if (X + 0 < X) return 1;
670 
671   return 0;
672 }
673 
TestWithSignedUnsigned(int X)674 int TestWithSignedUnsigned(int X) {
675   if (X + 1 == X + 1ULL) return 1;
676   // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: logical expression is always true
677 
678   if ((X & 0xFFU) == 0xF00) return 1;
679   // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: logical expression is always false
680 
681   if ((X & 0xFF) == 0xF00U) return 1;
682   // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: logical expression is always false
683 
684   if ((X & 0xFFU) == 0xF00U) return 1;
685   // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: logical expression is always false
686 
687   return 0;
688 }
689 
TestWithLong(int X,I64 Y)690 int TestWithLong(int X, I64 Y) {
691   if (X + 0ULL == -X) return 1;
692   if (Y + 0 == -Y) return 1;
693   if (Y <= 10 && X >= 10LL) return 1;
694   if (Y <= 10 && X >= 10ULL) return 1;
695   if (X <= 10 || X > 12LL) return 1;
696   if (X <= 10 || X > 12ULL) return 1;
697   if (Y <= 10 || Y > 12) return 1;
698 
699   return 0;
700 }
701 
TestWithMinMaxInt(int X)702 int TestWithMinMaxInt(int X) {
703   if (X <= X + 0xFFFFFFFFU) return 1;
704   if (X <= X + 0x7FFFFFFF) return 1;
705   if (X <= X + 0x80000000) return 1;
706 
707   if (X <= 0xFFFFFFFFU && X > 0) return 1;
708   if (X <= 0xFFFFFFFFU && X > 0U) return 1;
709 
710   if (X + 0x80000000 == X - 0x80000000) return 1;
711   // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: logical expression is always true
712 
713   if (X > 0x7FFFFFFF || X < ((-0x7FFFFFFF)-1)) return 1;
714   if (X <= 0x7FFFFFFF && X >= ((-0x7FFFFFFF)-1)) return 1;
715 
716   return 0;
717 }
718 
719 #define FLAG1 1
720 #define FLAG2 2
721 #define FLAG3 4
722 #define FLAGS (FLAG1 | FLAG2 | FLAG3)
723 #define NOTFLAGS !(FLAG1 | FLAG2 | FLAG3)
TestOperatorConfusion(int X,int Y,long Z)724 int TestOperatorConfusion(int X, int Y, long Z)
725 {
726   // Ineffective & expressions.
727   Y = (Y << 8) & 0xff;
728   // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: ineffective bitwise and operation
729   Y = (Y << 12) & 0xfff;
730   // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: ineffective bitwise and
731   Y = (Y << 12) & 0xff;
732   // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: ineffective bitwise and
733   Y = (Y << 8) & 0x77;
734   // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: ineffective bitwise and
735   Y = (Y << 5) & 0x11;
736   // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: ineffective bitwise and
737 
738   // Tests for unmatched types
739   Z = (Z << 8) & 0xff;
740   // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: ineffective bitwise and operation
741   Y = (Y << 12) & 0xfffL;
742   // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: ineffective bitwise and
743   Z = (Y << 12) & 0xffLL;
744   // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: ineffective bitwise and
745   Y = (Z << 8L) & 0x77L;
746   // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: ineffective bitwise and
747 
748   Y = (Y << 8) & 0;
749   // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: ineffective bitwise and
750 
751   Y = (Y << 8) & -1;
752 
753   // Effective expressions. Do not check.
754   Y = (Y << 4) & 0x15;
755   Y = (Y << 3) & 0x250;
756   Y = (Y << 9) & 0xF33;
757 
758   int K = !(1 | 2 | 4);
759   // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: ineffective logical negation operator used; did you mean '~'?
760   // CHECK-FIXES: {{^}}  int K = ~(1 | 2 | 4);{{$}}
761   K = !(FLAG1 & FLAG2 & FLAG3);
762   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: ineffective logical negation operator
763   // CHECK-FIXES: {{^}}  K = ~(FLAG1 & FLAG2 & FLAG3);{{$}}
764   K = !(3 | 4);
765   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: ineffective logical negation operator
766   // CHECK-FIXES: {{^}}  K = ~(3 | 4);{{$}}
767   int NotFlags = !FLAGS;
768   // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: ineffective logical negation operator
769   // CHECK-FIXES: {{^}}  int NotFlags = ~FLAGS;{{$}}
770   NotFlags = NOTFLAGS;
771   // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: ineffective logical negation operator
772   return !(1 | 2 | 4);
773   // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: ineffective logical negation operator
774   // CHECK-FIXES: {{^}}  return ~(1 | 2 | 4);{{$}}
775 }
776 
777 template <int Shift, int Mask>
TestOperatorConfusionDependent(int Y)778 int TestOperatorConfusionDependent(int Y) {
779   int r1 = (Y << Shift) & 0xff;
780   int r2 = (Y << 8) & Mask;
781 }
782 #undef FLAG1
783 #undef FLAG2
784 #undef FLAG3
785 
786 namespace no_crash {
787 struct Foo {};
788 bool operator<(const Foo&, const Foo&);
789 template <class T>
790 struct Bar {
791   static const Foo &GetFoo();
Testno_crash::Bar792   static bool Test(const T & maybe_foo, const Foo& foo) {
793     return foo < GetFoo() && foo < maybe_foo;
794   }
795 };
796 
797 template <class... Values>
798 struct Bar2 {
799   static_assert((... && (sizeof(Values) > 0)) == (... && (sizeof(Values) > 0)));
800   // FIXME: It's not clear that we should be diagnosing this. The `&&` operator
801   // here is unresolved and could resolve to an overloaded operator that might
802   // have side-effects on its operands. For other constructs with the same
803   // property (eg, the `S2` cases above) we suppress this diagnostic. This
804   // started failing when Clang started properly modeling the fold-expression as
805   // containing an unresolved operator name.
806   // FIXME-MESSAGES: :[[@LINE-1]]:47: warning: both sides of operator are equivalent [misc-redundant-expression]
807 };
808 
809 } // namespace no_crash
810