75 const MatchFinder::MatchResult &Result) {
76 const auto *OuterIf = Result.Nodes.getNodeAs<IfStmt>(
OuterIfStr);
77 const auto *InnerIf = Result.Nodes.getNodeAs<IfStmt>(
InnerIfStr);
78 const auto *CondVar = Result.Nodes.getNodeAs<VarDecl>(
CondVarStr);
79 const auto *Func = Result.Nodes.getNodeAs<FunctionDecl>(
FuncStr);
81 const DeclRefExpr *OuterIfVar =
nullptr, *InnerIfVar =
nullptr;
82 if (
const auto *Inner = Result.Nodes.getNodeAs<DeclRefExpr>(
InnerIfVar1Str))
86 if (
const auto *Outer = Result.Nodes.getNodeAs<DeclRefExpr>(
OuterIfVar1Str))
91 if (OuterIfVar && InnerIfVar) {
92 if (
isChangedBefore(OuterIf->getThen(), InnerIfVar, OuterIfVar, CondVar,
96 if (
isChangedBefore(OuterIf->getCond(), InnerIfVar, OuterIfVar, CondVar,
107 auto Diag = diag(InnerIf->getBeginLoc(),
"redundant condition %0") << CondVar;
111 const auto *BinOpCond =
112 dyn_cast<BinaryOperator>(InnerIf->getCond()->IgnoreParenImpCasts());
114 if (isa<DeclRefExpr>(InnerIf->getCond()->IgnoreParenImpCasts()) ||
115 (BinOpCond && BinOpCond->getOpcode() == BO_LOr)) {
116 const SourceLocation IfBegin = InnerIf->getBeginLoc();
117 const Stmt *Body = InnerIf->getThen();
118 const Expr *OtherSide =
nullptr;
120 const auto *LeftDRE =
121 dyn_cast<DeclRefExpr>(BinOpCond->getLHS()->IgnoreParenImpCasts());
122 if (LeftDRE && LeftDRE->getDecl() == CondVar)
123 OtherSide = BinOpCond->getRHS();
125 OtherSide = BinOpCond->getLHS();
128 SourceLocation IfEnd = Body->getBeginLoc().getLocWithOffset(-1);
131 if (isa<CompoundStmt>(Body))
132 IfEnd = Body->getBeginLoc();
135 if (OtherSide && OtherSide->HasSideEffects(*Result.Context)) {
136 const SourceLocation BeforeOtherSide =
137 OtherSide->getBeginLoc().getLocWithOffset(-1);
138 const SourceLocation AfterOtherSide =
140 OtherSide->getEndLoc(), *Result.SourceManager, getLangOpts())
142 Diag << FixItHint::CreateRemoval(
143 CharSourceRange::getTokenRange(IfBegin, BeforeOtherSide))
144 << FixItHint::CreateInsertion(AfterOtherSide,
";")
145 << FixItHint::CreateRemoval(
146 CharSourceRange::getTokenRange(AfterOtherSide, IfEnd));
148 Diag << FixItHint::CreateRemoval(
149 CharSourceRange::getTokenRange(IfBegin, IfEnd));
153 if (isa<CompoundStmt>(Body))
154 Diag << FixItHint::CreateRemoval(
155 CharSourceRange::getTokenRange(Body->getEndLoc(), Body->getEndLoc()));
161 cast<BinaryOperator>(InnerIf->getCond()->IgnoreParenImpCasts());
162 const auto *LeftDRE =
163 dyn_cast<DeclRefExpr>(CondOp->getLHS()->IgnoreParenImpCasts());
164 if (LeftDRE && LeftDRE->getDecl() == CondVar) {
165 const SourceLocation BeforeRHS =
166 CondOp->getRHS()->getBeginLoc().getLocWithOffset(-1);
167 Diag << FixItHint::CreateRemoval(CharSourceRange::getTokenRange(
168 CondOp->getLHS()->getBeginLoc(), BeforeRHS));
170 const SourceLocation AfterLHS =
172 CondOp->getLHS()->getEndLoc(), *Result.SourceManager,
175 Diag << FixItHint::CreateRemoval(CharSourceRange::getTokenRange(
176 AfterLHS, CondOp->getRHS()->getEndLoc()));