1 //===--- RedundantExpressionCheck.cpp - clang-tidy-------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "RedundantExpressionCheck.h"
11 #include "../utils/Matchers.h"
12 #include "../utils/OptionsUtils.h"
13 #include "clang/AST/ASTContext.h"
14 #include "clang/ASTMatchers/ASTMatchFinder.h"
15 #include "clang/Basic/LLVM.h"
16 #include "clang/Basic/SourceLocation.h"
17 #include "clang/Basic/SourceManager.h"
18 #include "clang/Lex/Lexer.h"
19 #include "llvm/ADT/APInt.h"
20 #include "llvm/ADT/APSInt.h"
21 #include "llvm/ADT/FoldingSet.h"
22 #include "llvm/Support/Casting.h"
23 #include <algorithm>
24 #include <cassert>
25 #include <cstdint>
26 #include <string>
27 #include <vector>
28 
29 using namespace clang::ast_matchers;
30 using namespace clang::tidy::matchers;
31 
32 namespace clang {
33 namespace tidy {
34 namespace misc {
35 namespace {
36 using llvm::APSInt;
37 
38 static constexpr llvm::StringLiteral KnownBannedMacroNames[] = {
39     "EAGAIN",
40     "EWOULDBLOCK",
41     "SIGCLD",
42     "SIGCHLD",
43 };
44 
45 static bool incrementWithoutOverflow(const APSInt &Value, APSInt &Result) {
46   Result = Value;
47   ++Result;
48   return Value < Result;
49 }
50 
51 static bool areEquivalentNameSpecifier(const NestedNameSpecifier *Left,
52                                        const NestedNameSpecifier *Right) {
53   llvm::FoldingSetNodeID LeftID, RightID;
54   Left->Profile(LeftID);
55   Right->Profile(RightID);
56   return LeftID == RightID;
57 }
58 
59 static bool areEquivalentExpr(const Expr *Left, const Expr *Right) {
60   if (!Left || !Right)
61     return !Left && !Right;
62 
63   Left = Left->IgnoreParens();
64   Right = Right->IgnoreParens();
65 
66   // Compare classes.
67   if (Left->getStmtClass() != Right->getStmtClass())
68     return false;
69 
70   // Compare children.
71   Expr::const_child_iterator LeftIter = Left->child_begin();
72   Expr::const_child_iterator RightIter = Right->child_begin();
73   while (LeftIter != Left->child_end() && RightIter != Right->child_end()) {
74     if (!areEquivalentExpr(dyn_cast<Expr>(*LeftIter),
75                            dyn_cast<Expr>(*RightIter)))
76       return false;
77     ++LeftIter;
78     ++RightIter;
79   }
80   if (LeftIter != Left->child_end() || RightIter != Right->child_end())
81     return false;
82 
83   // Perform extra checks.
84   switch (Left->getStmtClass()) {
85   default:
86     return false;
87 
88   case Stmt::CharacterLiteralClass:
89     return cast<CharacterLiteral>(Left)->getValue() ==
90            cast<CharacterLiteral>(Right)->getValue();
91   case Stmt::IntegerLiteralClass: {
92     llvm::APInt LeftLit = cast<IntegerLiteral>(Left)->getValue();
93     llvm::APInt RightLit = cast<IntegerLiteral>(Right)->getValue();
94     return LeftLit.getBitWidth() == RightLit.getBitWidth() &&
95            LeftLit == RightLit;
96   }
97   case Stmt::FloatingLiteralClass:
98     return cast<FloatingLiteral>(Left)->getValue().bitwiseIsEqual(
99         cast<FloatingLiteral>(Right)->getValue());
100   case Stmt::StringLiteralClass:
101     return cast<StringLiteral>(Left)->getBytes() ==
102            cast<StringLiteral>(Right)->getBytes();
103   case Stmt::CXXOperatorCallExprClass:
104     return cast<CXXOperatorCallExpr>(Left)->getOperator() ==
105            cast<CXXOperatorCallExpr>(Right)->getOperator();
106   case Stmt::DependentScopeDeclRefExprClass:
107     if (cast<DependentScopeDeclRefExpr>(Left)->getDeclName() !=
108         cast<DependentScopeDeclRefExpr>(Right)->getDeclName())
109       return false;
110     return areEquivalentNameSpecifier(
111         cast<DependentScopeDeclRefExpr>(Left)->getQualifier(),
112         cast<DependentScopeDeclRefExpr>(Right)->getQualifier());
113   case Stmt::DeclRefExprClass:
114     return cast<DeclRefExpr>(Left)->getDecl() ==
115            cast<DeclRefExpr>(Right)->getDecl();
116   case Stmt::MemberExprClass:
117     return cast<MemberExpr>(Left)->getMemberDecl() ==
118            cast<MemberExpr>(Right)->getMemberDecl();
119   case Stmt::CXXFunctionalCastExprClass:
120   case Stmt::CStyleCastExprClass:
121     return cast<ExplicitCastExpr>(Left)->getTypeAsWritten() ==
122            cast<ExplicitCastExpr>(Right)->getTypeAsWritten();
123   case Stmt::CallExprClass:
124   case Stmt::ImplicitCastExprClass:
125   case Stmt::ArraySubscriptExprClass:
126     return true;
127   case Stmt::UnaryOperatorClass:
128     if (cast<UnaryOperator>(Left)->isIncrementDecrementOp())
129       return false;
130     return cast<UnaryOperator>(Left)->getOpcode() ==
131            cast<UnaryOperator>(Right)->getOpcode();
132   case Stmt::BinaryOperatorClass:
133     return cast<BinaryOperator>(Left)->getOpcode() ==
134            cast<BinaryOperator>(Right)->getOpcode();
135   }
136 }
137 
138 // For a given expression 'x', returns whether the ranges covered by the
139 // relational operators are equivalent (i.e.  x <= 4 is equivalent to x < 5).
140 static bool areEquivalentRanges(BinaryOperatorKind OpcodeLHS,
141                                 const APSInt &ValueLHS,
142                                 BinaryOperatorKind OpcodeRHS,
143                                 const APSInt &ValueRHS) {
144   assert(APSInt::compareValues(ValueLHS, ValueRHS) <= 0 &&
145          "Values must be ordered");
146   // Handle the case where constants are the same: x <= 4  <==>  x <= 4.
147   if (APSInt::compareValues(ValueLHS, ValueRHS) == 0)
148     return OpcodeLHS == OpcodeRHS;
149 
150   // Handle the case where constants are off by one: x <= 4  <==>  x < 5.
151   APSInt ValueLHS_plus1;
152   return ((OpcodeLHS == BO_LE && OpcodeRHS == BO_LT) ||
153           (OpcodeLHS == BO_GT && OpcodeRHS == BO_GE)) &&
154          incrementWithoutOverflow(ValueLHS, ValueLHS_plus1) &&
155          APSInt::compareValues(ValueLHS_plus1, ValueRHS) == 0;
156 }
157 
158 // For a given expression 'x', returns whether the ranges covered by the
159 // relational operators are fully disjoint (i.e. x < 4  and  x > 7).
160 static bool areExclusiveRanges(BinaryOperatorKind OpcodeLHS,
161                                const APSInt &ValueLHS,
162                                BinaryOperatorKind OpcodeRHS,
163                                const APSInt &ValueRHS) {
164   assert(APSInt::compareValues(ValueLHS, ValueRHS) <= 0 &&
165          "Values must be ordered");
166 
167   // Handle cases where the constants are the same.
168   if (APSInt::compareValues(ValueLHS, ValueRHS) == 0) {
169     switch (OpcodeLHS) {
170     case BO_EQ:
171       return OpcodeRHS == BO_NE || OpcodeRHS == BO_GT || OpcodeRHS == BO_LT;
172     case BO_NE:
173       return OpcodeRHS == BO_EQ;
174     case BO_LE:
175       return OpcodeRHS == BO_GT;
176     case BO_GE:
177       return OpcodeRHS == BO_LT;
178     case BO_LT:
179       return OpcodeRHS == BO_EQ || OpcodeRHS == BO_GT || OpcodeRHS == BO_GE;
180     case BO_GT:
181       return OpcodeRHS == BO_EQ || OpcodeRHS == BO_LT || OpcodeRHS == BO_LE;
182     default:
183       return false;
184     }
185   }
186 
187   // Handle cases where the constants are different.
188   if ((OpcodeLHS == BO_EQ || OpcodeLHS == BO_LT || OpcodeLHS == BO_LE) &&
189       (OpcodeRHS == BO_EQ || OpcodeRHS == BO_GT || OpcodeRHS == BO_GE))
190     return true;
191 
192   // Handle the case where constants are off by one: x > 5 && x < 6.
193   APSInt ValueLHS_plus1;
194   if (OpcodeLHS == BO_GT && OpcodeRHS == BO_LT &&
195       incrementWithoutOverflow(ValueLHS, ValueLHS_plus1) &&
196       APSInt::compareValues(ValueLHS_plus1, ValueRHS) == 0)
197     return true;
198 
199   return false;
200 }
201 
202 // Returns whether the ranges covered by the union of both relational
203 // expressions cover the whole domain (i.e. x < 10  and  x > 0).
204 static bool rangesFullyCoverDomain(BinaryOperatorKind OpcodeLHS,
205                                    const APSInt &ValueLHS,
206                                    BinaryOperatorKind OpcodeRHS,
207                                    const APSInt &ValueRHS) {
208   assert(APSInt::compareValues(ValueLHS, ValueRHS) <= 0 &&
209          "Values must be ordered");
210 
211   // Handle cases where the constants are the same:  x < 5 || x >= 5.
212   if (APSInt::compareValues(ValueLHS, ValueRHS) == 0) {
213     switch (OpcodeLHS) {
214     case BO_EQ:
215       return OpcodeRHS == BO_NE;
216     case BO_NE:
217       return OpcodeRHS == BO_EQ;
218     case BO_LE:
219       return OpcodeRHS == BO_GT || OpcodeRHS == BO_GE;
220     case BO_LT:
221       return OpcodeRHS == BO_GE;
222     case BO_GE:
223       return OpcodeRHS == BO_LT || OpcodeRHS == BO_LE;
224     case BO_GT:
225       return OpcodeRHS == BO_LE;
226     default:
227       return false;
228     }
229   }
230 
231   // Handle the case where constants are off by one: x <= 4 || x >= 5.
232   APSInt ValueLHS_plus1;
233   if (OpcodeLHS == BO_LE && OpcodeRHS == BO_GE &&
234       incrementWithoutOverflow(ValueLHS, ValueLHS_plus1) &&
235       APSInt::compareValues(ValueLHS_plus1, ValueRHS) == 0)
236     return true;
237 
238   // Handle cases where the constants are different: x > 4 || x <= 7.
239   if ((OpcodeLHS == BO_GT || OpcodeLHS == BO_GE) &&
240       (OpcodeRHS == BO_LT || OpcodeRHS == BO_LE))
241     return true;
242 
243   // Handle cases where constants are different but both ops are !=, like:
244   // x != 5 || x != 10
245   if (OpcodeLHS == BO_NE && OpcodeRHS == BO_NE)
246     return true;
247 
248   return false;
249 }
250 
251 static bool rangeSubsumesRange(BinaryOperatorKind OpcodeLHS,
252                                const APSInt &ValueLHS,
253                                BinaryOperatorKind OpcodeRHS,
254                                const APSInt &ValueRHS) {
255   int Comparison = APSInt::compareValues(ValueLHS, ValueRHS);
256   switch (OpcodeLHS) {
257   case BO_EQ:
258     return OpcodeRHS == BO_EQ && Comparison == 0;
259   case BO_NE:
260     return (OpcodeRHS == BO_NE && Comparison == 0) ||
261            (OpcodeRHS == BO_EQ && Comparison != 0) ||
262            (OpcodeRHS == BO_LT && Comparison >= 0) ||
263            (OpcodeRHS == BO_LE && Comparison > 0) ||
264            (OpcodeRHS == BO_GT && Comparison <= 0) ||
265            (OpcodeRHS == BO_GE && Comparison < 0);
266 
267   case BO_LT:
268     return ((OpcodeRHS == BO_LT && Comparison >= 0) ||
269             (OpcodeRHS == BO_LE && Comparison > 0) ||
270             (OpcodeRHS == BO_EQ && Comparison > 0));
271   case BO_GT:
272     return ((OpcodeRHS == BO_GT && Comparison <= 0) ||
273             (OpcodeRHS == BO_GE && Comparison < 0) ||
274             (OpcodeRHS == BO_EQ && Comparison < 0));
275   case BO_LE:
276     return (OpcodeRHS == BO_LT || OpcodeRHS == BO_LE || OpcodeRHS == BO_EQ) &&
277            Comparison >= 0;
278   case BO_GE:
279     return (OpcodeRHS == BO_GT || OpcodeRHS == BO_GE || OpcodeRHS == BO_EQ) &&
280            Comparison <= 0;
281   default:
282     return false;
283   }
284 }
285 
286 static void transformSubToCanonicalAddExpr(BinaryOperatorKind &Opcode,
287                                            APSInt &Value) {
288   if (Opcode == BO_Sub) {
289     Opcode = BO_Add;
290     Value = -Value;
291   }
292 }
293 
294 AST_MATCHER(Expr, isIntegerConstantExpr) {
295   if (Node.isInstantiationDependent())
296     return false;
297   return Node.isIntegerConstantExpr(Finder->getASTContext());
298 }
299 
300 AST_MATCHER(BinaryOperator, operandsAreEquivalent) {
301   return areEquivalentExpr(Node.getLHS(), Node.getRHS());
302 }
303 
304 AST_MATCHER(ConditionalOperator, expressionsAreEquivalent) {
305   return areEquivalentExpr(Node.getTrueExpr(), Node.getFalseExpr());
306 }
307 
308 AST_MATCHER(CallExpr, parametersAreEquivalent) {
309   return Node.getNumArgs() == 2 &&
310          areEquivalentExpr(Node.getArg(0), Node.getArg(1));
311 }
312 
313 AST_MATCHER(BinaryOperator, binaryOperatorIsInMacro) {
314   return Node.getOperatorLoc().isMacroID();
315 }
316 
317 AST_MATCHER(ConditionalOperator, conditionalOperatorIsInMacro) {
318   return Node.getQuestionLoc().isMacroID() || Node.getColonLoc().isMacroID();
319 }
320 
321 AST_MATCHER(Expr, isMacro) { return Node.getExprLoc().isMacroID(); }
322 
323 AST_MATCHER_P(Expr, expandedByMacro, ArrayRef<llvm::StringLiteral>, Names) {
324   const SourceManager &SM = Finder->getASTContext().getSourceManager();
325   const LangOptions &LO = Finder->getASTContext().getLangOpts();
326   SourceLocation Loc = Node.getExprLoc();
327   while (Loc.isMacroID()) {
328     StringRef MacroName = Lexer::getImmediateMacroName(Loc, SM, LO);
329     if (llvm::is_contained(Names, MacroName))
330       return true;
331     Loc = SM.getImmediateMacroCallerLoc(Loc);
332   }
333   return false;
334 }
335 
336 // Returns a matcher for integer constant expressions.
337 static ast_matchers::internal::Matcher<Expr>
338 matchIntegerConstantExpr(StringRef Id) {
339   std::string CstId = (Id + "-const").str();
340   return expr(isIntegerConstantExpr()).bind(CstId);
341 }
342 
343 // Retrieves the integer expression matched by 'matchIntegerConstantExpr' with
344 // name 'Id' and stores it into 'ConstExpr', the value of the expression is
345 // stored into `Value`.
346 static bool retrieveIntegerConstantExpr(const MatchFinder::MatchResult &Result,
347                                         StringRef Id, APSInt &Value,
348                                         const Expr *&ConstExpr) {
349   std::string CstId = (Id + "-const").str();
350   ConstExpr = Result.Nodes.getNodeAs<Expr>(CstId);
351   return ConstExpr && ConstExpr->isIntegerConstantExpr(Value, *Result.Context);
352 }
353 
354 // Overloaded `retrieveIntegerConstantExpr` for compatibility.
355 static bool retrieveIntegerConstantExpr(const MatchFinder::MatchResult &Result,
356                                         StringRef Id, APSInt &Value) {
357   const Expr *ConstExpr = nullptr;
358   return retrieveIntegerConstantExpr(Result, Id, Value, ConstExpr);
359 }
360 
361 // Returns a matcher for symbolic expressions (matches every expression except
362 // ingeter constant expressions).
363 static ast_matchers::internal::Matcher<Expr> matchSymbolicExpr(StringRef Id) {
364   std::string SymId = (Id + "-sym").str();
365   return ignoringParenImpCasts(
366       expr(unless(isIntegerConstantExpr())).bind(SymId));
367 }
368 
369 // Retrieves the expression matched by 'matchSymbolicExpr' with name 'Id' and
370 // stores it into 'SymExpr'.
371 static bool retrieveSymbolicExpr(const MatchFinder::MatchResult &Result,
372                                  StringRef Id, const Expr *&SymExpr) {
373   std::string SymId = (Id + "-sym").str();
374   if (const auto *Node = Result.Nodes.getNodeAs<Expr>(SymId)) {
375     SymExpr = Node;
376     return true;
377   }
378   return false;
379 }
380 
381 // Match a binary operator between a symbolic expression and an integer constant
382 // expression.
383 static ast_matchers::internal::Matcher<Expr>
384 matchBinOpIntegerConstantExpr(StringRef Id) {
385   const auto BinOpCstExpr =
386       expr(
387           anyOf(binaryOperator(anyOf(hasOperatorName("+"), hasOperatorName("|"),
388                                      hasOperatorName("&")),
389                                hasEitherOperand(matchSymbolicExpr(Id)),
390                                hasEitherOperand(matchIntegerConstantExpr(Id))),
391                 binaryOperator(hasOperatorName("-"),
392                                hasLHS(matchSymbolicExpr(Id)),
393                                hasRHS(matchIntegerConstantExpr(Id)))))
394           .bind(Id);
395   return ignoringParenImpCasts(BinOpCstExpr);
396 }
397 
398 // Retrieves sub-expressions matched by 'matchBinOpIntegerConstantExpr' with
399 // name 'Id'.
400 static bool
401 retrieveBinOpIntegerConstantExpr(const MatchFinder::MatchResult &Result,
402                                  StringRef Id, BinaryOperatorKind &Opcode,
403                                  const Expr *&Symbol, APSInt &Value) {
404   if (const auto *BinExpr = Result.Nodes.getNodeAs<BinaryOperator>(Id)) {
405     Opcode = BinExpr->getOpcode();
406     return retrieveSymbolicExpr(Result, Id, Symbol) &&
407            retrieveIntegerConstantExpr(Result, Id, Value);
408   }
409   return false;
410 }
411 
412 // Matches relational expressions: 'Expr <op> k' (i.e. x < 2, x != 3, 12 <= x).
413 static ast_matchers::internal::Matcher<Expr>
414 matchRelationalIntegerConstantExpr(StringRef Id) {
415   std::string CastId = (Id + "-cast").str();
416   std::string SwapId = (Id + "-swap").str();
417   std::string NegateId = (Id + "-negate").str();
418   std::string OverloadId = (Id + "-overload").str();
419 
420   const auto RelationalExpr = ignoringParenImpCasts(binaryOperator(
421       isComparisonOperator(), expr().bind(Id),
422       anyOf(allOf(hasLHS(matchSymbolicExpr(Id)),
423                   hasRHS(matchIntegerConstantExpr(Id))),
424             allOf(hasLHS(matchIntegerConstantExpr(Id)),
425                   hasRHS(matchSymbolicExpr(Id)), expr().bind(SwapId)))));
426 
427   // A cast can be matched as a comparator to zero. (i.e. if (x) is equivalent
428   // to if (x != 0)).
429   const auto CastExpr =
430       implicitCastExpr(hasCastKind(CK_IntegralToBoolean),
431                        hasSourceExpression(matchSymbolicExpr(Id)))
432           .bind(CastId);
433 
434   const auto NegateRelationalExpr =
435       unaryOperator(hasOperatorName("!"),
436                     hasUnaryOperand(anyOf(CastExpr, RelationalExpr)))
437           .bind(NegateId);
438 
439   // Do not bind to double negation.
440   const auto NegateNegateRelationalExpr =
441       unaryOperator(hasOperatorName("!"),
442                     hasUnaryOperand(unaryOperator(
443                         hasOperatorName("!"),
444                         hasUnaryOperand(anyOf(CastExpr, RelationalExpr)))));
445 
446   const auto OverloadedOperatorExpr =
447       cxxOperatorCallExpr(
448           anyOf(hasOverloadedOperatorName("=="),
449                 hasOverloadedOperatorName("!="), hasOverloadedOperatorName("<"),
450                 hasOverloadedOperatorName("<="), hasOverloadedOperatorName(">"),
451                 hasOverloadedOperatorName(">=")),
452           // Filter noisy false positives.
453           unless(isMacro()), unless(isInTemplateInstantiation()))
454           .bind(OverloadId);
455 
456   return anyOf(RelationalExpr, CastExpr, NegateRelationalExpr,
457                NegateNegateRelationalExpr, OverloadedOperatorExpr);
458 }
459 
460 // Checks whether a function param is non constant reference type, and may
461 // be modified in the function.
462 static bool isNonConstReferenceType(QualType ParamType) {
463   return ParamType->isReferenceType() &&
464          !ParamType.getNonReferenceType().isConstQualified();
465 }
466 
467 // Checks whether the arguments of an overloaded operator can be modified in the
468 // function.
469 // For operators that take an instance and a constant as arguments, only the
470 // first argument (the instance) needs to be checked, since the constant itself
471 // is a temporary expression. Whether the second parameter is checked is
472 // controlled by the parameter `ParamsToCheckCount`.
473 static bool
474 canOverloadedOperatorArgsBeModified(const FunctionDecl *OperatorDecl,
475                                     bool checkSecondParam) {
476   unsigned ParamCount = OperatorDecl->getNumParams();
477 
478   // Overloaded operators declared inside a class have only one param.
479   // These functions must be declared const in order to not be able to modify
480   // the instance of the class they are called through.
481   if (ParamCount == 1 &&
482       !OperatorDecl->getType()->getAs<FunctionType>()->isConst())
483     return true;
484 
485   if (isNonConstReferenceType(OperatorDecl->getParamDecl(0)->getType()))
486     return true;
487 
488   return checkSecondParam && ParamCount == 2 &&
489          isNonConstReferenceType(OperatorDecl->getParamDecl(1)->getType());
490 }
491 
492 // Retrieves sub-expressions matched by 'matchRelationalIntegerConstantExpr'
493 // with name 'Id'.
494 static bool retrieveRelationalIntegerConstantExpr(
495     const MatchFinder::MatchResult &Result, StringRef Id,
496     const Expr *&OperandExpr, BinaryOperatorKind &Opcode, const Expr *&Symbol,
497     APSInt &Value, const Expr *&ConstExpr) {
498   std::string CastId = (Id + "-cast").str();
499   std::string SwapId = (Id + "-swap").str();
500   std::string NegateId = (Id + "-negate").str();
501   std::string OverloadId = (Id + "-overload").str();
502 
503   if (const auto *Bin = Result.Nodes.getNodeAs<BinaryOperator>(Id)) {
504     // Operand received with explicit comparator.
505     Opcode = Bin->getOpcode();
506     OperandExpr = Bin;
507 
508     if (!retrieveIntegerConstantExpr(Result, Id, Value, ConstExpr))
509       return false;
510   } else if (const auto *Cast = Result.Nodes.getNodeAs<CastExpr>(CastId)) {
511     // Operand received with implicit comparator (cast).
512     Opcode = BO_NE;
513     OperandExpr = Cast;
514     Value = APSInt(32, false);
515   } else if (const auto *OverloadedOperatorExpr =
516                  Result.Nodes.getNodeAs<CXXOperatorCallExpr>(OverloadId)) {
517     const auto *OverloadedFunctionDecl = dyn_cast_or_null<FunctionDecl>(OverloadedOperatorExpr->getCalleeDecl());
518     if (!OverloadedFunctionDecl)
519       return false;
520 
521     if (canOverloadedOperatorArgsBeModified(OverloadedFunctionDecl, false))
522       return false;
523 
524     if (canOverloadedOperatorArgsBeModified(OverloadedFunctionDecl, false))
525       return false;
526 
527     if (!OverloadedOperatorExpr->getArg(1)->isIntegerConstantExpr(
528             Value, *Result.Context))
529       return false;
530 
531     Symbol = OverloadedOperatorExpr->getArg(0);
532     OperandExpr = OverloadedOperatorExpr;
533     Opcode = BinaryOperator::getOverloadedOpcode(OverloadedOperatorExpr->getOperator());
534 
535     return BinaryOperator::isComparisonOp(Opcode);
536   } else {
537     return false;
538   }
539 
540   if (!retrieveSymbolicExpr(Result, Id, Symbol))
541     return false;
542 
543   if (Result.Nodes.getNodeAs<Expr>(SwapId))
544     Opcode = BinaryOperator::reverseComparisonOp(Opcode);
545   if (Result.Nodes.getNodeAs<Expr>(NegateId))
546     Opcode = BinaryOperator::negateComparisonOp(Opcode);
547   return true;
548 }
549 
550 // Checks for expressions like (X == 4) && (Y != 9)
551 static bool areSidesBinaryConstExpressions(const BinaryOperator *&BinOp, const ASTContext *AstCtx) {
552   const auto *LhsBinOp = dyn_cast<BinaryOperator>(BinOp->getLHS());
553   const auto *RhsBinOp = dyn_cast<BinaryOperator>(BinOp->getRHS());
554 
555   if (!LhsBinOp || !RhsBinOp)
556     return false;
557 
558   if ((LhsBinOp->getLHS()->isIntegerConstantExpr(*AstCtx) ||
559        LhsBinOp->getRHS()->isIntegerConstantExpr(*AstCtx)) &&
560       (RhsBinOp->getLHS()->isIntegerConstantExpr(*AstCtx) ||
561        RhsBinOp->getRHS()->isIntegerConstantExpr(*AstCtx)))
562     return true;
563   return false;
564 }
565 
566 // Retrieves integer constant subexpressions from binary operator expressions
567 // that have two equivalent sides.
568 // E.g.: from (X == 5) && (X == 5) retrieves 5 and 5.
569 static bool retrieveConstExprFromBothSides(const BinaryOperator *&BinOp,
570                                            BinaryOperatorKind &MainOpcode,
571                                            BinaryOperatorKind &SideOpcode,
572                                            const Expr *&LhsConst,
573                                            const Expr *&RhsConst,
574                                            const ASTContext *AstCtx) {
575   assert(areSidesBinaryConstExpressions(BinOp, AstCtx) &&
576          "Both sides of binary operator must be constant expressions!");
577 
578   MainOpcode = BinOp->getOpcode();
579 
580   const auto *BinOpLhs = cast<BinaryOperator>(BinOp->getLHS());
581   const auto *BinOpRhs = cast<BinaryOperator>(BinOp->getRHS());
582 
583   LhsConst = BinOpLhs->getLHS()->isIntegerConstantExpr(*AstCtx)
584                  ? BinOpLhs->getLHS()
585                  : BinOpLhs->getRHS();
586   RhsConst = BinOpRhs->getLHS()->isIntegerConstantExpr(*AstCtx)
587                  ? BinOpRhs->getLHS()
588                  : BinOpRhs->getRHS();
589 
590   if (!LhsConst || !RhsConst)
591     return false;
592 
593   assert(BinOpLhs->getOpcode() == BinOpRhs->getOpcode() &&
594          "Sides of the binary operator must be equivalent expressions!");
595 
596   SideOpcode = BinOpLhs->getOpcode();
597 
598   return true;
599 }
600 
601 static bool areExprsFromDifferentMacros(const Expr *LhsExpr,
602                                         const Expr *RhsExpr,
603                                         const ASTContext *AstCtx) {
604   if (!LhsExpr || !RhsExpr)
605     return false;
606 
607   SourceLocation LhsLoc = LhsExpr->getExprLoc();
608   SourceLocation RhsLoc = RhsExpr->getExprLoc();
609 
610   if (!LhsLoc.isMacroID() || !RhsLoc.isMacroID())
611     return false;
612 
613   const SourceManager &SM = AstCtx->getSourceManager();
614   const LangOptions &LO = AstCtx->getLangOpts();
615 
616   return !(Lexer::getImmediateMacroName(LhsLoc, SM, LO) ==
617           Lexer::getImmediateMacroName(RhsLoc, SM, LO));
618 }
619 
620 static bool areExprsMacroAndNonMacro(const Expr *&LhsExpr,
621                                      const Expr *&RhsExpr) {
622   if (!LhsExpr || !RhsExpr)
623     return false;
624 
625   SourceLocation LhsLoc = LhsExpr->getExprLoc();
626   SourceLocation RhsLoc = RhsExpr->getExprLoc();
627 
628   return LhsLoc.isMacroID() != RhsLoc.isMacroID();
629 }
630 } // namespace
631 
632 void RedundantExpressionCheck::registerMatchers(MatchFinder *Finder) {
633   const auto AnyLiteralExpr = ignoringParenImpCasts(
634       anyOf(cxxBoolLiteral(), characterLiteral(), integerLiteral()));
635 
636   const auto BannedIntegerLiteral =
637       integerLiteral(expandedByMacro(KnownBannedMacroNames));
638 
639   // Binary with equivalent operands, like (X != 2 && X != 2).
640   Finder->addMatcher(
641       binaryOperator(anyOf(hasOperatorName("-"), hasOperatorName("/"),
642                            hasOperatorName("%"), hasOperatorName("|"),
643                            hasOperatorName("&"), hasOperatorName("^"),
644                            matchers::isComparisonOperator(),
645                            hasOperatorName("&&"), hasOperatorName("||"),
646                            hasOperatorName("=")),
647                      operandsAreEquivalent(),
648                      // Filter noisy false positives.
649                      unless(isInTemplateInstantiation()),
650                      unless(binaryOperatorIsInMacro()),
651                      unless(hasType(realFloatingPointType())),
652                      unless(hasEitherOperand(hasType(realFloatingPointType()))),
653                      unless(hasLHS(AnyLiteralExpr)),
654                      unless(hasDescendant(BannedIntegerLiteral)))
655           .bind("binary"),
656       this);
657 
658   // Conditional (trenary) operator with equivalent operands, like (Y ? X : X).
659   Finder->addMatcher(conditionalOperator(expressionsAreEquivalent(),
660                                          // Filter noisy false positives.
661                                          unless(conditionalOperatorIsInMacro()),
662                                          unless(isInTemplateInstantiation()))
663                          .bind("cond"),
664                      this);
665 
666   // Overloaded operators with equivalent operands.
667   Finder->addMatcher(
668       cxxOperatorCallExpr(
669           anyOf(
670               hasOverloadedOperatorName("-"), hasOverloadedOperatorName("/"),
671               hasOverloadedOperatorName("%"), hasOverloadedOperatorName("|"),
672               hasOverloadedOperatorName("&"), hasOverloadedOperatorName("^"),
673               hasOverloadedOperatorName("=="), hasOverloadedOperatorName("!="),
674               hasOverloadedOperatorName("<"), hasOverloadedOperatorName("<="),
675               hasOverloadedOperatorName(">"), hasOverloadedOperatorName(">="),
676               hasOverloadedOperatorName("&&"), hasOverloadedOperatorName("||"),
677               hasOverloadedOperatorName("=")),
678           parametersAreEquivalent(),
679           // Filter noisy false positives.
680           unless(isMacro()), unless(isInTemplateInstantiation()))
681           .bind("call"),
682       this);
683 
684   // Match expressions like: !(1 | 2 | 3)
685   Finder->addMatcher(
686       implicitCastExpr(
687           hasImplicitDestinationType(isInteger()),
688           has(unaryOperator(
689                   hasOperatorName("!"),
690                   hasUnaryOperand(ignoringParenImpCasts(binaryOperator(
691                       anyOf(hasOperatorName("|"), hasOperatorName("&")),
692                       hasLHS(anyOf(binaryOperator(anyOf(hasOperatorName("|"),
693                                                         hasOperatorName("&"))),
694                                    integerLiteral())),
695                       hasRHS(integerLiteral())))))
696                   .bind("logical-bitwise-confusion"))),
697       this);
698 
699   // Match expressions like: (X << 8) & 0xFF
700   Finder->addMatcher(
701       binaryOperator(hasOperatorName("&"),
702                      hasEitherOperand(ignoringParenImpCasts(binaryOperator(
703                          hasOperatorName("<<"),
704                          hasRHS(ignoringParenImpCasts(
705                              integerLiteral().bind("shift-const")))))),
706                      hasEitherOperand(ignoringParenImpCasts(
707                          integerLiteral().bind("and-const"))))
708           .bind("left-right-shift-confusion"),
709       this);
710 
711   // Match common expressions and apply more checks to find redundant
712   // sub-expressions.
713   //   a) Expr <op> K1 == K2
714   //   b) Expr <op> K1 == Expr
715   //   c) Expr <op> K1 == Expr <op> K2
716   // see: 'checkArithmeticExpr' and 'checkBitwiseExpr'
717   const auto BinOpCstLeft = matchBinOpIntegerConstantExpr("lhs");
718   const auto BinOpCstRight = matchBinOpIntegerConstantExpr("rhs");
719   const auto CstRight = matchIntegerConstantExpr("rhs");
720   const auto SymRight = matchSymbolicExpr("rhs");
721 
722   // Match expressions like: x <op> 0xFF == 0xF00.
723   Finder->addMatcher(binaryOperator(isComparisonOperator(),
724                                     hasEitherOperand(BinOpCstLeft),
725                                     hasEitherOperand(CstRight))
726                          .bind("binop-const-compare-to-const"),
727                      this);
728 
729   // Match expressions like: x <op> 0xFF == x.
730   Finder->addMatcher(
731       binaryOperator(isComparisonOperator(),
732                      anyOf(allOf(hasLHS(BinOpCstLeft), hasRHS(SymRight)),
733                            allOf(hasLHS(SymRight), hasRHS(BinOpCstLeft))))
734           .bind("binop-const-compare-to-sym"),
735       this);
736 
737   // Match expressions like: x <op> 10 == x <op> 12.
738   Finder->addMatcher(binaryOperator(isComparisonOperator(),
739                                     hasLHS(BinOpCstLeft), hasRHS(BinOpCstRight),
740                                     // Already reported as redundant.
741                                     unless(operandsAreEquivalent()))
742                          .bind("binop-const-compare-to-binop-const"),
743                      this);
744 
745   // Match relational expressions combined with logical operators and find
746   // redundant sub-expressions.
747   // see: 'checkRelationalExpr'
748 
749   // Match expressions like: x < 2 && x > 2.
750   const auto ComparisonLeft = matchRelationalIntegerConstantExpr("lhs");
751   const auto ComparisonRight = matchRelationalIntegerConstantExpr("rhs");
752   Finder->addMatcher(
753       binaryOperator(anyOf(hasOperatorName("||"), hasOperatorName("&&")),
754                      hasLHS(ComparisonLeft), hasRHS(ComparisonRight),
755                      // Already reported as redundant.
756                      unless(operandsAreEquivalent()))
757           .bind("comparisons-of-symbol-and-const"),
758       this);
759 }
760 
761 void RedundantExpressionCheck::checkArithmeticExpr(
762     const MatchFinder::MatchResult &Result) {
763   APSInt LhsValue, RhsValue;
764   const Expr *LhsSymbol = nullptr, *RhsSymbol = nullptr;
765   BinaryOperatorKind LhsOpcode, RhsOpcode;
766 
767   if (const auto *ComparisonOperator = Result.Nodes.getNodeAs<BinaryOperator>(
768           "binop-const-compare-to-sym")) {
769     BinaryOperatorKind Opcode = ComparisonOperator->getOpcode();
770     if (!retrieveBinOpIntegerConstantExpr(Result, "lhs", LhsOpcode, LhsSymbol,
771                                           LhsValue) ||
772         !retrieveSymbolicExpr(Result, "rhs", RhsSymbol) ||
773         !areEquivalentExpr(LhsSymbol, RhsSymbol))
774       return;
775 
776     // Check expressions: x + k == x  or  x - k == x.
777     if (LhsOpcode == BO_Add || LhsOpcode == BO_Sub) {
778       if ((LhsValue != 0 && Opcode == BO_EQ) ||
779           (LhsValue == 0 && Opcode == BO_NE))
780         diag(ComparisonOperator->getOperatorLoc(),
781              "logical expression is always false");
782       else if ((LhsValue == 0 && Opcode == BO_EQ) ||
783                (LhsValue != 0 && Opcode == BO_NE))
784         diag(ComparisonOperator->getOperatorLoc(),
785              "logical expression is always true");
786     }
787   } else if (const auto *ComparisonOperator =
788                  Result.Nodes.getNodeAs<BinaryOperator>(
789                      "binop-const-compare-to-binop-const")) {
790     BinaryOperatorKind Opcode = ComparisonOperator->getOpcode();
791 
792     if (!retrieveBinOpIntegerConstantExpr(Result, "lhs", LhsOpcode, LhsSymbol,
793                                           LhsValue) ||
794         !retrieveBinOpIntegerConstantExpr(Result, "rhs", RhsOpcode, RhsSymbol,
795                                           RhsValue) ||
796         !areEquivalentExpr(LhsSymbol, RhsSymbol))
797       return;
798 
799     transformSubToCanonicalAddExpr(LhsOpcode, LhsValue);
800     transformSubToCanonicalAddExpr(RhsOpcode, RhsValue);
801 
802     // Check expressions: x + 1 == x + 2  or  x + 1 != x + 2.
803     if (LhsOpcode == BO_Add && RhsOpcode == BO_Add) {
804       if ((Opcode == BO_EQ && APSInt::compareValues(LhsValue, RhsValue) == 0) ||
805           (Opcode == BO_NE && APSInt::compareValues(LhsValue, RhsValue) != 0)) {
806         diag(ComparisonOperator->getOperatorLoc(),
807              "logical expression is always true");
808       } else if ((Opcode == BO_EQ &&
809                   APSInt::compareValues(LhsValue, RhsValue) != 0) ||
810                  (Opcode == BO_NE &&
811                   APSInt::compareValues(LhsValue, RhsValue) == 0)) {
812         diag(ComparisonOperator->getOperatorLoc(),
813              "logical expression is always false");
814       }
815     }
816   }
817 }
818 
819 static bool exprEvaluatesToZero(BinaryOperatorKind Opcode, APSInt Value) {
820   return (Opcode == BO_And || Opcode == BO_AndAssign) && Value == 0;
821 }
822 
823 static bool exprEvaluatesToBitwiseNegatedZero(BinaryOperatorKind Opcode,
824                                               APSInt Value) {
825   return (Opcode == BO_Or || Opcode == BO_OrAssign) && ~Value == 0;
826 }
827 
828 static bool exprEvaluatesToSymbolic(BinaryOperatorKind Opcode, APSInt Value) {
829   return ((Opcode == BO_Or || Opcode == BO_OrAssign) && Value == 0) ||
830          ((Opcode == BO_And || Opcode == BO_AndAssign) && ~Value == 0);
831 }
832 
833 
834 void RedundantExpressionCheck::checkBitwiseExpr(
835     const MatchFinder::MatchResult &Result) {
836   if (const auto *ComparisonOperator = Result.Nodes.getNodeAs<BinaryOperator>(
837           "binop-const-compare-to-const")) {
838     BinaryOperatorKind Opcode = ComparisonOperator->getOpcode();
839 
840     APSInt LhsValue, RhsValue;
841     const Expr *LhsSymbol = nullptr;
842     BinaryOperatorKind LhsOpcode;
843     if (!retrieveBinOpIntegerConstantExpr(Result, "lhs", LhsOpcode, LhsSymbol,
844                                           LhsValue) ||
845         !retrieveIntegerConstantExpr(Result, "rhs", RhsValue))
846       return;
847 
848     uint64_t LhsConstant = LhsValue.getZExtValue();
849     uint64_t RhsConstant = RhsValue.getZExtValue();
850     SourceLocation Loc = ComparisonOperator->getOperatorLoc();
851 
852     // Check expression: x & k1 == k2  (i.e. x & 0xFF == 0xF00)
853     if (LhsOpcode == BO_And && (LhsConstant & RhsConstant) != RhsConstant) {
854       if (Opcode == BO_EQ)
855         diag(Loc, "logical expression is always false");
856       else if (Opcode == BO_NE)
857         diag(Loc, "logical expression is always true");
858     }
859 
860     // Check expression: x | k1 == k2  (i.e. x | 0xFF == 0xF00)
861     if (LhsOpcode == BO_Or && (LhsConstant | RhsConstant) != RhsConstant) {
862       if (Opcode == BO_EQ)
863         diag(Loc, "logical expression is always false");
864       else if (Opcode == BO_NE)
865         diag(Loc, "logical expression is always true");
866     }
867   } else if (const auto *IneffectiveOperator =
868                  Result.Nodes.getNodeAs<BinaryOperator>(
869                      "ineffective-bitwise")) {
870     APSInt Value;
871     const Expr *Sym = nullptr, *ConstExpr = nullptr;
872 
873     if (!retrieveSymbolicExpr(Result, "ineffective-bitwise", Sym) ||
874         !retrieveIntegerConstantExpr(Result, "ineffective-bitwise", Value,
875                                      ConstExpr))
876       return;
877 
878     if((Value != 0 && ~Value != 0) || Sym->getExprLoc().isMacroID())
879         return;
880 
881     SourceLocation Loc = IneffectiveOperator->getOperatorLoc();
882 
883     BinaryOperatorKind Opcode = IneffectiveOperator->getOpcode();
884     if (exprEvaluatesToZero(Opcode, Value)) {
885       diag(Loc, "expression always evaluates to 0");
886     } else if (exprEvaluatesToBitwiseNegatedZero(Opcode, Value)) {
887       SourceRange ConstExprRange(ConstExpr->getLocStart(),
888                                  ConstExpr->getLocEnd());
889       StringRef ConstExprText = Lexer::getSourceText(
890           CharSourceRange::getTokenRange(ConstExprRange), *Result.SourceManager,
891           Result.Context->getLangOpts());
892 
893       diag(Loc, "expression always evaluates to '%0'") << ConstExprText;
894 
895     } else if (exprEvaluatesToSymbolic(Opcode, Value)) {
896       SourceRange SymExprRange(Sym->getLocStart(), Sym->getLocEnd());
897 
898       StringRef ExprText = Lexer::getSourceText(
899           CharSourceRange::getTokenRange(SymExprRange), *Result.SourceManager,
900           Result.Context->getLangOpts());
901 
902       diag(Loc, "expression always evaluates to '%0'") << ExprText;
903     }
904   }
905 }
906 
907 void RedundantExpressionCheck::checkRelationalExpr(
908     const MatchFinder::MatchResult &Result) {
909   if (const auto *ComparisonOperator = Result.Nodes.getNodeAs<BinaryOperator>(
910           "comparisons-of-symbol-and-const")) {
911     // Matched expressions are: (x <op> k1) <REL> (x <op> k2).
912     // E.g.: (X < 2) && (X > 4)
913     BinaryOperatorKind Opcode = ComparisonOperator->getOpcode();
914 
915     const Expr *LhsExpr = nullptr, *RhsExpr = nullptr;
916     const Expr *LhsSymbol = nullptr, *RhsSymbol = nullptr;
917     const Expr *LhsConst = nullptr, *RhsConst = nullptr;
918     BinaryOperatorKind LhsOpcode, RhsOpcode;
919     APSInt LhsValue, RhsValue;
920 
921     if (!retrieveRelationalIntegerConstantExpr(
922             Result, "lhs", LhsExpr, LhsOpcode, LhsSymbol, LhsValue, LhsConst) ||
923         !retrieveRelationalIntegerConstantExpr(
924             Result, "rhs", RhsExpr, RhsOpcode, RhsSymbol, RhsValue, RhsConst) ||
925         !areEquivalentExpr(LhsSymbol, RhsSymbol))
926       return;
927 
928     // Bring expr to a canonical form: smallest constant must be on the left.
929     if (APSInt::compareValues(LhsValue, RhsValue) > 0) {
930       std::swap(LhsExpr, RhsExpr);
931       std::swap(LhsValue, RhsValue);
932       std::swap(LhsSymbol, RhsSymbol);
933       std::swap(LhsOpcode, RhsOpcode);
934     }
935 
936     // Constants come from two different macros, or one of them is a macro.
937     if (areExprsFromDifferentMacros(LhsConst, RhsConst, Result.Context) ||
938         areExprsMacroAndNonMacro(LhsConst, RhsConst))
939       return;
940 
941     if ((Opcode == BO_LAnd || Opcode == BO_LOr) &&
942         areEquivalentRanges(LhsOpcode, LhsValue, RhsOpcode, RhsValue)) {
943       diag(ComparisonOperator->getOperatorLoc(),
944            "equivalent expression on both sides of logical operator");
945       return;
946     }
947 
948     if (Opcode == BO_LAnd) {
949       if (areExclusiveRanges(LhsOpcode, LhsValue, RhsOpcode, RhsValue)) {
950         diag(ComparisonOperator->getOperatorLoc(),
951              "logical expression is always false");
952       } else if (rangeSubsumesRange(LhsOpcode, LhsValue, RhsOpcode, RhsValue)) {
953         diag(LhsExpr->getExprLoc(), "expression is redundant");
954       } else if (rangeSubsumesRange(RhsOpcode, RhsValue, LhsOpcode, LhsValue)) {
955         diag(RhsExpr->getExprLoc(), "expression is redundant");
956       }
957     }
958 
959     if (Opcode == BO_LOr) {
960       if (rangesFullyCoverDomain(LhsOpcode, LhsValue, RhsOpcode, RhsValue)) {
961         diag(ComparisonOperator->getOperatorLoc(),
962              "logical expression is always true");
963       } else if (rangeSubsumesRange(LhsOpcode, LhsValue, RhsOpcode, RhsValue)) {
964         diag(RhsExpr->getExprLoc(), "expression is redundant");
965       } else if (rangeSubsumesRange(RhsOpcode, RhsValue, LhsOpcode, LhsValue)) {
966         diag(LhsExpr->getExprLoc(), "expression is redundant");
967       }
968     }
969   }
970 }
971 
972 void RedundantExpressionCheck::check(const MatchFinder::MatchResult &Result) {
973   if (const auto *BinOp = Result.Nodes.getNodeAs<BinaryOperator>("binary")) {
974     // If the expression's constants are macros, check whether they are
975     // intentional.
976     if (areSidesBinaryConstExpressions(BinOp, Result.Context)) {
977       const Expr *LhsConst = nullptr, *RhsConst = nullptr;
978       BinaryOperatorKind MainOpcode, SideOpcode;
979 
980       if (!retrieveConstExprFromBothSides(BinOp, MainOpcode, SideOpcode,
981                                           LhsConst, RhsConst, Result.Context))
982         return;
983 
984       if (areExprsFromDifferentMacros(LhsConst, RhsConst, Result.Context) ||
985           areExprsMacroAndNonMacro(LhsConst, RhsConst))
986         return;
987     }
988 
989     diag(BinOp->getOperatorLoc(), "both sides of operator are equivalent");
990   }
991 
992   if (const auto *CondOp =
993           Result.Nodes.getNodeAs<ConditionalOperator>("cond")) {
994     const Expr *TrueExpr = CondOp->getTrueExpr();
995     const Expr *FalseExpr = CondOp->getFalseExpr();
996 
997     if (areExprsFromDifferentMacros(TrueExpr, FalseExpr, Result.Context) ||
998         areExprsMacroAndNonMacro(TrueExpr, FalseExpr))
999       return;
1000     diag(CondOp->getColonLoc(),
1001          "'true' and 'false' expressions are equivalent");
1002   }
1003 
1004   if (const auto *Call = Result.Nodes.getNodeAs<CXXOperatorCallExpr>("call")) {
1005     const auto *OverloadedFunctionDecl = dyn_cast_or_null<FunctionDecl>(Call->getCalleeDecl());
1006     if (!OverloadedFunctionDecl)
1007       return;
1008 
1009     if (canOverloadedOperatorArgsBeModified(OverloadedFunctionDecl, true))
1010       return;
1011 
1012     diag(Call->getOperatorLoc(),
1013          "both sides of overloaded operator are equivalent");
1014   }
1015 
1016   if (const auto *NegateOperator =
1017           Result.Nodes.getNodeAs<UnaryOperator>("logical-bitwise-confusion")) {
1018     SourceLocation OperatorLoc = NegateOperator->getOperatorLoc();
1019 
1020     auto Diag =
1021         diag(OperatorLoc,
1022              "ineffective logical negation operator used; did you mean '~'?");
1023     SourceLocation LogicalNotLocation = OperatorLoc.getLocWithOffset(1);
1024 
1025     if (!LogicalNotLocation.isMacroID())
1026       Diag << FixItHint::CreateReplacement(
1027           CharSourceRange::getCharRange(OperatorLoc, LogicalNotLocation), "~");
1028   }
1029 
1030   if (const auto *BinaryAndExpr = Result.Nodes.getNodeAs<BinaryOperator>(
1031           "left-right-shift-confusion")) {
1032     const auto *ShiftingConst = Result.Nodes.getNodeAs<Expr>("shift-const");
1033     assert(ShiftingConst && "Expr* 'ShiftingConst' is nullptr!");
1034     APSInt ShiftingValue;
1035 
1036     if (!ShiftingConst->isIntegerConstantExpr(ShiftingValue, *Result.Context))
1037       return;
1038 
1039     const auto *AndConst = Result.Nodes.getNodeAs<Expr>("and-const");
1040     assert(AndConst && "Expr* 'AndCont' is nullptr!");
1041     APSInt AndValue;
1042     if (!AndConst->isIntegerConstantExpr(AndValue, *Result.Context))
1043       return;
1044 
1045     // If ShiftingConst is shifted left with more bits than the position of the
1046     // leftmost 1 in the bit representation of AndValue, AndConstant is
1047     // ineffective.
1048     if (AndValue.getActiveBits() > ShiftingValue)
1049       return;
1050 
1051     auto Diag = diag(BinaryAndExpr->getOperatorLoc(),
1052                      "ineffective bitwise and operation");
1053   }
1054 
1055   // Check for the following bound expressions:
1056   // - "binop-const-compare-to-sym",
1057   // - "binop-const-compare-to-binop-const",
1058   // Produced message:
1059   // -> "logical expression is always false/true"
1060   checkArithmeticExpr(Result);
1061 
1062   // Check for the following bound expression:
1063   // - "binop-const-compare-to-const",
1064   // - "ineffective-bitwise"
1065   // Produced message:
1066   // -> "logical expression is always false/true"
1067   // -> "expression always evaluates to ..."
1068   checkBitwiseExpr(Result);
1069 
1070   // Check for te following bound expression:
1071   // - "comparisons-of-symbol-and-const",
1072   // Produced messages:
1073   // -> "equivalent expression on both sides of logical operator",
1074   // -> "logical expression is always false/true"
1075   // -> "expression is redundant"
1076   checkRelationalExpr(Result);
1077 }
1078 
1079 } // namespace misc
1080 } // namespace tidy
1081 } // namespace clang
1082