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