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 const auto Diag = diag(InnerIf->getBeginLoc(),
"redundant condition %0")
112 const auto *BinOpCond =
113 dyn_cast<BinaryOperator>(InnerIf->getCond()->IgnoreParenImpCasts());
115 if (isa<DeclRefExpr>(InnerIf->getCond()->IgnoreParenImpCasts()) ||
116 (BinOpCond && BinOpCond->getOpcode() == BO_LOr)) {
117 const SourceLocation IfBegin = InnerIf->getBeginLoc();
118 const Stmt *Body = InnerIf->getThen();
119 const Expr *OtherSide =
nullptr;
121 const auto *LeftDRE =
122 dyn_cast<DeclRefExpr>(BinOpCond->getLHS()->IgnoreParenImpCasts());
123 if (LeftDRE && LeftDRE->getDecl() == CondVar)
124 OtherSide = BinOpCond->getRHS();
126 OtherSide = BinOpCond->getLHS();
129 SourceLocation IfEnd = Body->getBeginLoc().getLocWithOffset(-1);
132 if (isa<CompoundStmt>(Body))
133 IfEnd = Body->getBeginLoc();
136 if (OtherSide && OtherSide->HasSideEffects(*Result.Context)) {
137 const SourceLocation BeforeOtherSide =
138 OtherSide->getBeginLoc().getLocWithOffset(-1);
140 OtherSide->getEndLoc(), *Result.SourceManager, getLangOpts())) {
141 const SourceLocation AfterOtherSide = NextToken->getLocation();
142 Diag << FixItHint::CreateRemoval(
143 CharSourceRange::getTokenRange(IfBegin, BeforeOtherSide))
144 << FixItHint::CreateInsertion(AfterOtherSide,
";")
145 << FixItHint::CreateRemoval(
146 CharSourceRange::getTokenRange(AfterOtherSide, IfEnd));
149 Diag << FixItHint::CreateRemoval(
150 CharSourceRange::getTokenRange(IfBegin, IfEnd));
154 if (isa<CompoundStmt>(Body))
155 Diag << FixItHint::CreateRemoval(
156 CharSourceRange::getTokenRange(Body->getEndLoc(), Body->getEndLoc()));
162 cast<BinaryOperator>(InnerIf->getCond()->IgnoreParenImpCasts());
163 const auto *LeftDRE =
164 dyn_cast<DeclRefExpr>(CondOp->getLHS()->IgnoreParenImpCasts());
165 if (LeftDRE && LeftDRE->getDecl() == CondVar) {
166 const SourceLocation BeforeRHS =
167 CondOp->getRHS()->getBeginLoc().getLocWithOffset(-1);
168 Diag << FixItHint::CreateRemoval(CharSourceRange::getTokenRange(
169 CondOp->getLHS()->getBeginLoc(), BeforeRHS));
170 }
else if (
const auto NextToken =
172 CondOp->getLHS()->getEndLoc(), *Result.SourceManager,
174 const SourceLocation AfterLHS = NextToken->getLocation();
175 Diag << FixItHint::CreateRemoval(CharSourceRange::getTokenRange(
176 AfterLHS, CondOp->getRHS()->getEndLoc()));