74 const MatchFinder::MatchResult &Result) {
75 const auto *OuterIf = Result.Nodes.getNodeAs<IfStmt>(
OuterIfStr);
76 const auto *InnerIf = Result.Nodes.getNodeAs<IfStmt>(
InnerIfStr);
77 const auto *CondVar = Result.Nodes.getNodeAs<VarDecl>(
CondVarStr);
78 const auto *Func = Result.Nodes.getNodeAs<FunctionDecl>(
FuncStr);
80 const DeclRefExpr *OuterIfVar =
nullptr, *InnerIfVar =
nullptr;
81 if (
const auto *Inner = Result.Nodes.getNodeAs<DeclRefExpr>(
InnerIfVar1Str))
85 if (
const auto *Outer = Result.Nodes.getNodeAs<DeclRefExpr>(
OuterIfVar1Str))
90 if (OuterIfVar && InnerIfVar) {
91 if (
isChangedBefore(OuterIf->getThen(), InnerIfVar, OuterIfVar, CondVar,
95 if (
isChangedBefore(OuterIf->getCond(), InnerIfVar, OuterIfVar, CondVar,
106 auto Diag = diag(InnerIf->getBeginLoc(),
"redundant condition %0") << CondVar;
110 const auto *BinOpCond =
111 dyn_cast<BinaryOperator>(InnerIf->getCond()->IgnoreParenImpCasts());
113 if (isa<DeclRefExpr>(InnerIf->getCond()->IgnoreParenImpCasts()) ||
114 (BinOpCond && BinOpCond->getOpcode() == BO_LOr)) {
115 SourceLocation IfBegin = InnerIf->getBeginLoc();
116 const Stmt *Body = InnerIf->getThen();
117 const Expr *OtherSide =
nullptr;
119 const auto *LeftDRE =
120 dyn_cast<DeclRefExpr>(BinOpCond->getLHS()->IgnoreParenImpCasts());
121 if (LeftDRE && LeftDRE->getDecl() == CondVar)
122 OtherSide = BinOpCond->getRHS();
124 OtherSide = BinOpCond->getLHS();
127 SourceLocation IfEnd = Body->getBeginLoc().getLocWithOffset(-1);
130 if (isa<CompoundStmt>(Body))
131 IfEnd = Body->getBeginLoc();
134 if (OtherSide && OtherSide->HasSideEffects(*Result.Context)) {
135 SourceLocation BeforeOtherSide =
136 OtherSide->getBeginLoc().getLocWithOffset(-1);
137 SourceLocation AfterOtherSide =
138 Lexer::findNextToken(OtherSide->getEndLoc(), *Result.SourceManager,
141 Diag << FixItHint::CreateRemoval(
142 CharSourceRange::getTokenRange(IfBegin, BeforeOtherSide))
143 << FixItHint::CreateInsertion(AfterOtherSide,
";")
144 << FixItHint::CreateRemoval(
145 CharSourceRange::getTokenRange(AfterOtherSide, IfEnd));
147 Diag << FixItHint::CreateRemoval(
148 CharSourceRange::getTokenRange(IfBegin, IfEnd));
152 if (isa<CompoundStmt>(Body))
153 Diag << FixItHint::CreateRemoval(
154 CharSourceRange::getTokenRange(Body->getEndLoc(), Body->getEndLoc()));
160 cast<BinaryOperator>(InnerIf->getCond()->IgnoreParenImpCasts());
161 const auto *LeftDRE =
162 dyn_cast<DeclRefExpr>(CondOp->getLHS()->IgnoreParenImpCasts());
163 if (LeftDRE && LeftDRE->getDecl() == CondVar) {
164 SourceLocation BeforeRHS =
165 CondOp->getRHS()->getBeginLoc().getLocWithOffset(-1);
166 Diag << FixItHint::CreateRemoval(CharSourceRange::getTokenRange(
167 CondOp->getLHS()->getBeginLoc(), BeforeRHS));
169 SourceLocation AfterLHS =
170 Lexer::findNextToken(CondOp->getLHS()->getEndLoc(),
171 *Result.SourceManager, getLangOpts())
173 Diag << FixItHint::CreateRemoval(CharSourceRange::getTokenRange(
174 AfterLHS, CondOp->getRHS()->getEndLoc()));