1// RUN: %check_clang_tidy %s misc-redundant-expression %t -- -- -fno-delayed-template-parsing -Wno-array-compare-cxx26
2// RUN: %check_clang_tidy %s misc-redundant-expression %t -- -- -fno-delayed-template-parsing -Wno-array-compare-cxx26 -DTEST_MACRO
3
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 equivalent
24 if (X % X) return 1;
25 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: both sides of operator are equivalent
26
27 if (X & X) return 1;
28 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: both sides of operator are equivalent
29 if (X | X) return 1;
30 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: both sides of operator are equivalent
31 if (X ^ X) return 1;
32 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: both sides of operator are equivalent
33
34 if (X < X) return 1;
35 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: both sides of operator are equivalent
36 if (X <= X) return 1;
37 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: both sides of operator are equivalent
38 if (X > X) return 1;
39 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: both sides of operator are equivalent
40 if (X >= X) return 1;
41 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: both sides of operator are equivalent
42
43 if (X && X) return 1;
44 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: both sides of operator are equivalent
45 if (X || X) return 1;
46 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: both sides of operator are equivalent
47
48 if (X != (((X)))) return 1;
49 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: both sides of operator are equivalent
50
51 if (X + 1 == X + 1) return 1;
52 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: both sides of operator are equivalent
53 if (X + 1 != X + 1) return 1;
54 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: both sides of operator are equivalent
55 if (X + 1 <= X + 1) return 1;
56 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: both sides of operator are equivalent
57 if (X + 1 >= X + 1) return 1;
58 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: both sides of operator are equivalent
59
60 if ((X != 1 || Y != 1) && (X != 1 || Y != 1)) return 1;
61 // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: both sides of operator are equivalent
62 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 equivalent
64
65 if ((int)X < (int)X) return 1;
66 // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: both sides of operator are equivalent
67 if (int(X) < int(X)) return 1;
68 // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: both sides of operator are equivalent
69
70 if ( + "dummy" == + "dummy") return 1;
71 // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: both sides of operator are equivalent
72 if (L"abc" == L"abc") return 1;
73 // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: both sides of operator are equivalent
74
75 if (foo(x: 0) - 2 < foo(x: 0) - 2) return 1;
76 // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: both sides of operator are equivalent
77 if (foo(x: bar(x: 0)) < (foo(x: bar(x: (0))))) return 1;
78 // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: both sides of operator are equivalent
79
80 if (P1.x < P2.x && P1.x < P2.x) return 1;
81 // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: both sides of operator are equivalent
82 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 equivalent
84
85 if (X && Y && X) return 1;
86 // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: operator has equivalent nested operands
87 if (X || (Y || X)) return 1;
88 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: operator has equivalent nested operands
89 if ((X ^ Y) ^ (Y ^ X)) return 1;
90 // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: operator has equivalent nested operands
91
92 return 0;
93}
94
95#ifndef TEST_MACRO
96#define VAL_1 2
97#define VAL_3 3
98#else
99#define VAL_1 3
100#define VAL_3 2
101#endif
102
103#define VAL_2 2
104
105#ifndef TEST_MACRO
106#define VAL_4 2 + 1
107#define VAL_6 3 + 1
108#else
109#define VAL_4 3 + 1
110#define VAL_6 2 + 1
111#endif
112
113#define VAL_5 2 + 1
114
115struct TestStruct
116{
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 reported
130 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 equivalent
160 if (VAL_2 <= VAL_2) return 0;
161 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: both sides of operator are equivalent
162 if (VAL_3 > VAL_3) return 0;
163 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: both sides of operator are equivalent
164 if (VAL_4 < VAL_4) return 0;
165 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: both sides of operator are equivalent
166 if (VAL_6 == VAL_6) return 2;
167 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: both sides of operator are equivalent
168 if (VAL_5 != VAL_5) return 2;
169 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: both sides of operator are equivalent
170
171 // Test prefixes
172 if (+VAL_6 == +VAL_6) return 2;
173 // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: both sides of operator are equivalent
174 if (-VAL_6 == -VAL_6) return 2;
175 // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: both sides of operator are equivalent
176 if ((+VAL_6) == (+VAL_6)) return 2;
177 // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: both sides of operator are equivalent
178 if ((-VAL_6) == (-VAL_6)) return 2;
179 // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: both sides of operator are equivalent
180
181 if (1 >= 1) return 0;
182 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: both sides of operator are equivalent
183 if (0xFF <= 0xFF) return 0;
184 // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: both sides of operator are equivalent
185 if (042 > 042) return 0;
186 // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: both sides of operator are equivalent
187
188 int_val = (VAL_6 == VAL_6)?int_val1: int_val2;
189 // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: both sides of operator are equivalent
190 int_val = (042 > 042)?int_val1: int_val2;
191 // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: both sides of operator are equivalent
192
193
194 // Ternary operator cases which should not be reported
195 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 equivalent
220 };
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 equivalent
227 };
228
229 return 1 + int_val + sizeof(tsVar1) + sizeof(tsVar2) +
230 sizeof(tsVar3) + sizeof(tsVar4);
231}
232
233#define LOOP_DEFINE 1
234
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 equivalent
243 {
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 equivalent
248 {
249 }
250
251 return localIndex;
252}
253
254#define getValue(a) a
255#define getValueM(a) a
256
257int TestParamDefine() {
258 int ret = 0;
259
260 // Negative cases
261 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 cases
275 ret += (+getValue(1)) > (+getValue( 1));
276 // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: both sides of operator are equivalent
277 ret += (-getValue(1)) > (-getValue( 1));
278 // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: both sides of operator are equivalent
279
280 ret += +getValue(1) > +getValue( 1);
281 // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: both sides of operator are equivalent
282 ret += -getValue(1) > -getValue( 1);
283 // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: both sides of operator are equivalent
284
285 ret += getValue(1) > getValue( 1);
286 // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: both sides of operator are equivalent
287 ret += getValue(1) > getValue( 1 );
288 // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: both sides of operator are equivalent
289 ret += getValue(1) > getValue( 1);
290 // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: both sides of operator are equivalent
291 ret += getValue( 1) > getValue( 1);
292 // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: both sides of operator are equivalent
293 ret += getValue( 1 ) > getValue( 1);
294 // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: both sides of operator are equivalent
295 ret += getValue( VAL_5 ) > getValue(VAL_5);
296 // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: both sides of operator are equivalent
297 ret += getValue( VAL_5 ) > getValue( VAL_5);
298 // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: both sides of operator are equivalent
299 ret += getValue( VAL_5 ) > getValue( VAL_5 ) ;
300 // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: both sides of operator are equivalent
301 ret += getValue(VAL_5) > getValue( VAL_5 ) ;
302 // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: both sides of operator are equivalent
303 ret += getValue(VAL_1+VAL_2) > getValue(VAL_1 + VAL_2) ;
304 // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: both sides of operator are equivalent
305 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 equivalent
307 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 equivalent
309 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 equivalent
316
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(x: bar(x: 0)) < (foo(x: bat(x: 0, y: 1)))) return 1;
338 return 0;
339}
340
341#define COND_OP_MACRO 9
342#define COND_OP_OTHER_MACRO 9
343#define COND_OP_THIRD_MACRO COND_OP_MACRO
344int 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 equivalent
348 k += (y < 0) ? x + 1 : x + 1;
349 // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: 'true' and 'false' expressions are equivalent
350 k += (y < 0) ? COND_OP_MACRO : COND_OP_MACRO;
351 // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: 'true' and 'false' expressions are equivalent
352 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 equivalent
354
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 macro
360 k += (y < 0) ? COND_OP_MACRO : COND_OP_THIRD_MACRO;
361#undef COND_OP_THIRD_MACRO
362#define COND_OP_THIRD_MACRO 8
363 k += (y < 0) ? COND_OP_MACRO : COND_OP_THIRD_MACRO;
364#undef COND_OP_THIRD_MACRO
365
366 k += (y < 0) ? sizeof(I64) : sizeof(I64);
367 // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: 'true' and 'false' expressions are equivalent
368 k += (y < 0) ? sizeof(TestConditional(x: k,y)) : sizeof(TestConditional(x: k,y));
369 // CHECK-MESSAGES: :[[@LINE-1]]:47: warning: 'true' and 'false' expressions are equivalent
370 // No warning if the expression arguments are different.
371 k += (y < 0) ? sizeof(TestConditional(x: k,y)) : sizeof(Valid(X: k,Y: y));
372
373 return k;
374}
375#undef COND_OP_MACRO
376#undef COND_OP_OTHER_MACRO
377
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 modifing
382 bool operator>=(const MyStruct& rhs) const { return this->x >= rhs.x; } // not modifing
383 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 modifing
388bool operator<(const MyStruct& lhs, const MyStruct& rhs) { return lhs.x < rhs.x; } // not modifing
389bool 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 equivalent
411 if (S < S) return true;
412 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: both sides of overloaded operator are equivalent
413 if (S != S) return true;
414 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: both sides of overloaded operator are equivalent
415 if (S >= S) return true;
416 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: both sides of overloaded operator are equivalent
417
418 MyStruct1 U(false);
419 MyStruct1 V(true);
420
421 // valid because the operator is not const
422 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 operands
426
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 3
456#define NOT_EAGAIN 3
457 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 equivalent
460 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 equivalent
471}
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 false
477 if (X + 1 != X) return 1;
478 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: logical expression is always true
479 if (X - 1 == X) return 1;
480 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: logical expression is always false
481 if (X - 1 != X) return 1;
482 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: logical expression is always true
483
484 if (X + 1LL == X) return 1;
485 // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: logical expression is always false
486 if (X + 1ULL == X) return 1;
487 // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: logical expression is always false
488
489 if (X == X + 1) return 1;
490 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: logical expression is always false
491 if (X != X + 1) return 1;
492 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: logical expression is always true
493 if (X == X - 1) return 1;
494 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: logical expression is always false
495 if (X != X - 1) return 1;
496 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: logical expression is always true
497
498 if (X != X - 1U) return 1;
499 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: logical expression is always true
500 if (X != X - 1LL) return 1;
501 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: logical expression is always true
502
503 if ((X+X) != (X+X) - 1) return 1;
504 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: logical expression is always true
505
506 if (X + 1 == X + 2) return 1;
507 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: logical expression is always false
508 if (X + 1 != X + 2) return 1;
509 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: logical expression is always true
510
511 if (X - 1 == X - 2) return 1;
512 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: logical expression is always false
513 if (X - 1 != X - 2) return 1;
514 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: logical expression is always true
515
516 if (X + 1 == X - -1) return 1;
517 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: logical expression is always true
518 if (X + 1 != X - -1) return 1;
519 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: logical expression is always false
520 if (X + 1 == X - -2) return 1;
521 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: logical expression is always false
522 if (X + 1 != X - -2) return 1;
523 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: logical expression is always true
524
525 if (X + 1 == X - (~0)) return 1;
526 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: logical expression is always true
527 if (X + 1 == X - (~0U)) return 1;
528 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: logical expression is always true
529
530 if (X + 1 == X - (~0ULL)) return 1;
531 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: logical expression is always true
532
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 false
546 if ((X & 0xFF) != 0xF00) return 1;
547 // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: logical expression is always true
548 if ((X | 0xFF) == 0xF00) return 1;
549 // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: logical expression is always false
550 if ((X | 0xFF) != 0xF00) return 1;
551 // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: logical expression is always true
552
553 if ((X | 0xFFULL) != 0xF00) return 1;
554 // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: logical expression is always true
555 if ((X | 0xFF) != 0xF00ULL) return 1;
556 // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: logical expression is always true
557
558 if ((0xFF & X) == 0xF00) return 1;
559 // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: logical expression is always false
560 if ((0xFF & X) != 0xF00) return 1;
561 // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: logical expression is always true
562 if ((0xFF & X) == 0xF00) return 1;
563 // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: logical expression is always false
564 if ((0xFF & X) != 0xF00) return 1;
565 // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: logical expression is always true
566
567 if ((0xFFLL & X) == 0xF00) return 1;
568 // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: logical expression is always false
569 if ((0xFF & X) == 0xF00ULL) return 1;
570 // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: logical expression is always false
571
572 return 0;
573}
574
575// Overloaded operators that compare an instance of a struct and an integer
576// 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 modifying
582 bool operator!=(int i) const { return x != i; } // not modifying
583 bool operator>(const int &i) const { return x > i; } // not modifying
584 bool operator<(int i) const { return x < i; } // not modifying
585};
586
587bool operator<=(const S &s, int i) { return s.x <= i; } // not modifying
588bool operator>=(const S &s, const int &i) { return s.x >= i; } // not modifying
589
590bool operator==(int i, const S &s) { return s == i; } // not modifying
591bool operator<(const int &i, const S &s) { return s > i; } // not modifying
592bool operator<=(const int &i, const S &s) { return s >= i; } // not modifying
593bool operator>(const int &i, const S &s) { return s < i; } // not modifying
594
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 0
619 if (CONFIG && X) return 1;
620#undef CONFIG
621#define CONFIG 1
622 if (CONFIG || X) return 1;
623#undef CONFIG
624
625 if (X == 10 && X != 10) return 1;
626 // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: logical expression is always false
627 if (X == 10 && (X != 10)) return 1;
628 // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: logical expression is always false
629 if (X == 10 && !(X == 10)) return 1;
630 // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: logical expression is always false
631 if (!(X != 10) && !(X == 10)) return 1;
632 // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: logical expression is always false
633
634 if (X == 10ULL && X != 10ULL) return 1;
635 // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: logical expression is always false
636 if (!(X != 10U) && !(X == 10)) return 1;
637 // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: logical expression is always false
638 if (!(X != 10LL) && !(X == 10)) return 1;
639 // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: logical expression is always false
640 if (!(X != 10ULL) && !(X == 10)) return 1;
641 // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: logical expression is always false
642
643 if (X == 0 && X) return 1;
644 // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: logical expression is always false
645 if (X != 0 && !X) return 1;
646 // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: logical expression is always false
647 if (X && !X) return 1;
648 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: logical expression is always false
649
650 if (X && !!X) return 1;
651 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: equivalent expression on both sides of logical operator
652 if (X != 0 && X) return 1;
653 // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: equivalent expression on both sides of logical operator
654 if (X != 0 && !!X) return 1;
655 // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: equivalent expression on both sides of logical operator
656 if (X == 0 && !X) return 1;
657 // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: equivalent expression on both sides of logical operator
658
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 operator
672 if (s1 == 1 || s1 != 1) return true;
673 // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: logical expression is always true
674 if (s1 > 1 && s1 < 1) return true;
675 // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: logical expression is always false
676 if (s1 >= 1 || s1 <= 1) return true;
677 // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: logical expression is always true
678 if (s1 >= 2 && s1 <= 0) return true;
679 // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: logical expression is always false
680
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 operator
684 if (1 == s1 || s1 != 1) return true;
685 // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: logical expression is always true
686 if (1 < s1 && s1 < 1) return true;
687 // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: logical expression is always false
688 if (1 <= s1 || s1 <= 1) return true;
689 // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: logical expression is always true
690 if (2 < s1 && 0 > s1) return true;
691 // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: logical expression is always false
692
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 false
709 if (X == 10 && X < 10) return 1;
710 // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: logical expression is always false
711 if (X < 10 && X > 10) return 1;
712 // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: logical expression is always false
713 if (X <= 10 && X > 10) return 1;
714 // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: logical expression is always false
715 if (X < 10 && X >= 10) return 1;
716 // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: logical expression is always false
717 if (X < 10 && X == 10) return 1;
718 // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: logical expression is always false
719
720 if (X > 5 && X <= 5) return 1;
721 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: logical expression is always false
722 if (X > -5 && X <= -5) return 1;
723 // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: logical expression is always false
724
725 if (X < 10 || X >= 10) return 1;
726 // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: logical expression is always true
727 if (X <= 10 || X > 10) return 1;
728 // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: logical expression is always true
729 if (X <= 10 || X >= 11) return 1;
730 // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: logical expression is always true
731 if (X != 7 || X != 14) return 1;
732 // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: logical expression is always true
733 if (X == 7 || X != 5) return 1;
734 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant
735 if (X != 7 || X == 7) return 1;
736 // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: logical expression is always true
737
738 if (X < 7 && X < 6) return 1;
739 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant
740 if (X < 7 && X < 7) return 1;
741 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: both sides of operator are equivalent
742 if (X < 7 && X < 8) return 1;
743 // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: expression is redundant
744
745 if (X < 7 && X <= 5) return 1;
746 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant
747 if (X < 7 && X <= 6) return 1;
748 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: equivalent expression on both sides of logical operator
749 if (X < 7 && X <= 7) return 1;
750 // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: expression is redundant
751 if (X < 7 && X <= 8) return 1;
752 // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: expression is redundant
753
754 if (X <= 7 && X < 6) return 1;
755 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant
756 if (X <= 7 && X < 7) return 1;
757 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant
758 if (X <= 7 && X < 8) return 1;
759 // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: equivalent expression on both sides of logical operator
760
761 if (X >= 7 && X > 6) return 1;
762 // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: equivalent expression on both sides of logical operator
763 if (X >= 7 && X > 7) return 1;
764 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant
765 if (X >= 7 && X > 8) return 1;
766 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant
767
768 if (X <= 7 && X <= 5) return 1;
769 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant
770 if (X <= 7 && X <= 6) return 1;
771 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant
772 if (X <= 7 && X <= 7) return 1;
773 // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: both sides of operator are equivalent
774 if (X <= 7 && X <= 8) return 1;
775 // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: expression is redundant
776
777 if (X == 11 && X > 10) return 1;
778 // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: expression is redundant
779 if (X == 11 && X < 12) return 1;
780 // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: expression is redundant
781 if (X > 10 && X == 11) return 1;
782 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant
783 if (X < 12 && X == 11) return 1;
784 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant
785
786 if (X != 11 && X == 42) return 1;
787 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant
788 if (X != 11 && X > 11) return 1;
789 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant
790 if (X != 11 && X < 11) return 1;
791 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant
792 if (X != 11 && X < 8) return 1;
793 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant
794 if (X != 11 && X > 14) return 1;
795 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant
796
797 if (X < 7 || X < 6) return 1;
798 // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: expression is redundant
799 if (X < 7 || X < 7) return 1;
800 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: both sides of operator are equivalent
801 if (X < 7 || X < 8) return 1;
802 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant
803
804 if (X > 7 || X > 6) return 1;
805 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant
806 if (X > 7 || X > 7) return 1;
807 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: both sides of operator are equivalent
808 if (X > 7 || X > 8) return 1;
809 // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: expression is redundant
810
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 3
831#define SOME_MACRO_SAME_VALUE 3
832#define SOME_OTHER_MACRO 9
833 // Do not match for redundant relational macro expressions that can be
834 // 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 false
839 if (X < SOME_MACRO && X == SOME_MACRO) return 1;
840 // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: logical expression is always false
841 if (X < SOME_MACRO || X >= SOME_MACRO) return 1;
842 // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: logical expression is always true
843 if (X <= SOME_MACRO || X > SOME_MACRO) return 1;
844 // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: logical expression is always true
845 if (X != SOME_MACRO && X > SOME_MACRO) return 1;
846 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant
847 if (X != SOME_MACRO && X < SOME_MACRO) return 1;
848 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant
849
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_MACRO
874#undef SOME_MACRO_SAME_VALUE
875#undef SOME_MACRO
876 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 false
891 if (C == Red && C != Red) return 1;
892 // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: logical expression is always false
893 if (C != Red || C != Yellow) return 1;
894 // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: logical expression is always true
895
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 type
906 // is dependent. There is an assert failing when evaluating
907 // 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 true
919
920 if ((X & 0xFFU) == 0xF00) return 1;
921 // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: logical expression is always false
922
923 if ((X & 0xFF) == 0xF00U) return 1;
924 // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: logical expression is always false
925
926 if ((X & 0xFFU) == 0xF00U) return 1;
927 // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: logical expression is always false
928
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 true
954
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 1
962#define FLAG2 2
963#define FLAG3 4
964#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 operation
971 Y = (Y << 12) & 0xfff;
972 // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: ineffective bitwise and
973 Y = (Y << 12) & 0xff;
974 // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: ineffective bitwise and
975 Y = (Y << 8) & 0x77;
976 // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: ineffective bitwise and
977 Y = (Y << 5) & 0x11;
978 // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: ineffective bitwise and
979
980 // Tests for unmatched types
981 Z = (Z << 8) & 0xff;
982 // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: ineffective bitwise and operation
983 Y = (Y << 12) & 0xfffL;
984 // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: ineffective bitwise and
985 Z = (Y << 12) & 0xffLL;
986 // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: ineffective bitwise and
987 Y = (Z << 8L) & 0x77L;
988 // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: ineffective bitwise and
989
990 Y = (Y << 8) & 0;
991 // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: ineffective bitwise and
992
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 operator
1005 // CHECK-FIXES: {{^}} K = ~(FLAG1 & FLAG2 & FLAG3);{{$}}
1006 K = !(3 | 4);
1007 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: ineffective logical negation operator
1008 // CHECK-FIXES: {{^}} K = ~(3 | 4);{{$}}
1009 int NotFlags = !FLAGS;
1010 // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: ineffective logical negation operator
1011 // CHECK-FIXES: {{^}} int NotFlags = ~FLAGS;{{$}}
1012 NotFlags = NOTFLAGS;
1013 // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: ineffective logical negation operator
1014 return !(1 | 2 | 4);
1015 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: ineffective logical negation operator
1016 // 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 FLAG1
1025#undef FLAG2
1026#undef FLAG3
1027
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 `&&` operator
1043 // here is unresolved and could resolve to an overloaded operator that might
1044 // have side-effects on its operands. For other constructs with the same
1045 // property (eg, the `S2` cases above) we suppress this diagnostic. This
1046 // started failing when Clang started properly modeling the fold-expression as
1047 // 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_crash
1052
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(x: 0)) != 1 || (k = foo(x: 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 equivalent
1074
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

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