1// RUN: %check_clang_tidy %s misc-redundant-expression %t -- -- -fno-delayed-template-parsing
2
3typedef __INT64_TYPE__ I64;
4
5struct Point {
6 int x;
7 int y;
8 int a[5];
9} P;
10
11extern Point P1;
12extern Point P2;
13
14extern int foo(int x);
15extern int bar(int x);
16extern int bat(int x, int y);
17
18int 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(x: 0) - 2 < foo(x: 0) - 2) return 1;
75 // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: both sides of operator are equivalent
76 if (foo(x: bar(x: 0)) < (foo(x: bar(x: (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
94template <int DX>
95int 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
102int 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(x: bar(x: 0)) < (foo(x: bat(x: 0, y: 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
126int 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(x: k,y)) : sizeof(TestConditional(x: 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(x: k,y)) : sizeof(Valid(X: k,Y: 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.
161struct 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
169bool operator!=(const MyStruct& lhs, const MyStruct& rhs) { return lhs.x == rhs.x; } // not modifing
170bool operator<(const MyStruct& lhs, const MyStruct& rhs) { return lhs.x < rhs.x; } // not modifing
171bool operator>(const MyStruct& lhs, MyStruct& rhs) { rhs.x--; return lhs.x > rhs.x; }
172bool operator||(MyStruct& lhs, const MyStruct& rhs) { lhs.x++; return lhs.x || rhs.x; }
173
174struct MyStruct1 {
175 bool x;
176 MyStruct1(bool x) : x(x) {};
177 operator bool() { return x; }
178};
179
180MyStruct1 operator&&(const MyStruct1& lhs, const MyStruct1& rhs) { return lhs.x && rhs.x; }
181MyStruct1 operator||(MyStruct1& lhs, MyStruct1& rhs) { return lhs.x && rhs.x; }
182
183bool 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
216int 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
226int 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
236int 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
245struct MyClass {
246static const int Value = 42;
247};
248template <typename T, typename U>
249void 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}
254void TestTemplate() { TemplateCheck<MyClass, MyClass>(); }
255
256int 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
324int 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.
359struct 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
369bool operator<=(const S &s, int i) { return s.x <= i; } // not modifying
370bool operator>=(const S &s, const int &i) { return s.x >= i; } // not modifying
371
372bool operator==(int i, const S &s) { return s == i; } // not modifying
373bool operator<(const int &i, const S &s) { return s > i; } // not modifying
374bool operator<=(const int &i, const S &s) { return s >= i; } // not modifying
375bool operator>(const int &i, const S &s) { return s < i; } // not modifying
376
377struct 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
393bool operator>=(S2 &s, const int &i) { return s.x >= i; }
394bool operator<=(S2 &s, int i) {
395 s.x++;
396 return s.x <= i;
397}
398
399int 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
488int 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
611int 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
661int 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
669enum Color { Red, Yellow, Green };
670int 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
685template<class T>
686int 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
698int 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
714int 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
726int 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)
748int 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
801template <int Shift, int Mask>
802int 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
810namespace no_crash {
811struct Foo {};
812bool operator<(const Foo&, const Foo&);
813template <class T>
814struct 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
821template <class... Values>
822struct 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
835int 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(x: 0)) != 1 || (k = foo(x: 0)) != 2)
842 return 1;
843
844 return 2;
845}
846
847namespace PR63096 {
848
849struct alignas(sizeof(int)) X {
850 int x;
851};
852
853static_assert(alignof(X) == sizeof(X));
854static_assert(sizeof(X) == sizeof(X));
855// CHECK-MESSAGES: :[[@LINE-1]]:25: warning: both sides of operator are equivalent
856
857}
858
859namespace PR35857 {
860 void test() {
861 int x = 0;
862 int y = 0;
863 decltype(x + y - (x + y)) z = 10;
864 }
865}
866

source code of clang-tools-extra/test/clang-tidy/checkers/misc/redundant-expression.cpp