102 const MatchFinder::MatchResult &Result) {
103 const auto *OuterIf = Result.Nodes.getNodeAs<IfStmt>(
OuterIfStr);
104 const auto *InnerIf = Result.Nodes.getNodeAs<IfStmt>(
InnerIfStr);
105 const auto *CondVar = Result.Nodes.getNodeAs<VarDecl>(
CondVarStr);
106 const auto *Func = Result.Nodes.getNodeAs<FunctionDecl>(
FuncStr);
108 const DeclRefExpr *OuterIfVar =
nullptr, *InnerIfVar =
nullptr;
109 if (
const auto *Inner = Result.Nodes.getNodeAs<DeclRefExpr>(
InnerIfVar1Str))
113 if (
const auto *Outer = Result.Nodes.getNodeAs<DeclRefExpr>(
OuterIfVar1Str))
118 if (OuterIfVar && InnerIfVar) {
119 if (
isChangedBefore(OuterIf->getThen(), InnerIfVar, OuterIfVar, CondVar,
123 if (
isChangedBefore(OuterIf->getCond(), InnerIfVar, OuterIfVar, CondVar,
132 ExprMutationAnalyzer(*Loop, *Result.Context).findMutation(CondVar))
141 const auto Diag = diag(InnerIf->getBeginLoc(),
"redundant condition %0")
146 const auto *BinOpCond =
147 dyn_cast<BinaryOperator>(InnerIf->getCond()->IgnoreParenImpCasts());
149 if (isa<DeclRefExpr>(InnerIf->getCond()->IgnoreParenImpCasts()) ||
150 (BinOpCond && BinOpCond->getOpcode() == BO_LOr)) {
151 const SourceLocation IfBegin = InnerIf->getBeginLoc();
152 const Stmt *Body = InnerIf->getThen();
153 const Expr *OtherSide =
nullptr;
155 const auto *LeftDRE =
156 dyn_cast<DeclRefExpr>(BinOpCond->getLHS()->IgnoreParenImpCasts());
157 if (LeftDRE && LeftDRE->getDecl() == CondVar)
158 OtherSide = BinOpCond->getRHS();
160 OtherSide = BinOpCond->getLHS();
163 SourceLocation IfEnd = Body->getBeginLoc().getLocWithOffset(-1);
166 if (isa<CompoundStmt>(Body))
167 IfEnd = Body->getBeginLoc();
170 if (OtherSide && OtherSide->HasSideEffects(*Result.Context)) {
171 const SourceLocation BeforeOtherSide =
172 OtherSide->getBeginLoc().getLocWithOffset(-1);
174 OtherSide->getEndLoc(), *Result.SourceManager, getLangOpts())) {
175 const SourceLocation AfterOtherSide = NextToken->getLocation();
176 Diag << FixItHint::CreateRemoval(
177 CharSourceRange::getTokenRange(IfBegin, BeforeOtherSide))
178 << FixItHint::CreateInsertion(AfterOtherSide,
";")
179 << FixItHint::CreateRemoval(
180 CharSourceRange::getTokenRange(AfterOtherSide, IfEnd));
183 Diag << FixItHint::CreateRemoval(
184 CharSourceRange::getTokenRange(IfBegin, IfEnd));
188 if (isa<CompoundStmt>(Body))
189 Diag << FixItHint::CreateRemoval(
190 CharSourceRange::getTokenRange(Body->getEndLoc(), Body->getEndLoc()));
196 cast<BinaryOperator>(InnerIf->getCond()->IgnoreParenImpCasts());
197 const auto *LeftDRE =
198 dyn_cast<DeclRefExpr>(CondOp->getLHS()->IgnoreParenImpCasts());
199 if (LeftDRE && LeftDRE->getDecl() == CondVar) {
200 const SourceLocation BeforeRHS =
201 CondOp->getRHS()->getBeginLoc().getLocWithOffset(-1);
202 Diag << FixItHint::CreateRemoval(CharSourceRange::getTokenRange(
203 CondOp->getLHS()->getBeginLoc(), BeforeRHS));
204 }
else if (
const auto NextToken =
206 CondOp->getLHS()->getEndLoc(), *Result.SourceManager,
208 const SourceLocation AfterLHS = NextToken->getLocation();
209 Diag << FixItHint::CreateRemoval(CharSourceRange::getTokenRange(
210 AfterLHS, CondOp->getRHS()->getEndLoc()));