// Because the fix (changing to `const auto &`) will introduce an unused
// compiler warning which can't be suppressed.
// Since this case is very rare, it is safe to ignore it.
- if (!utils::ExprMutationAnalyzer(ForRange.getBody(), &Context)
- .isMutated(&LoopVar) &&
+ if (!utils::ExprMutationAnalyzer(*ForRange.getBody(), Context)
+ .isMutated(&LoopVar) &&
!utils::decl_ref_expr::allDeclRefExprs(LoopVar, *ForRange.getBody(),
Context)
.empty()) {
// Do not trigger on non-const value parameters when they are mutated either
// within the function body or within init expression(s) when the function is
// a ctor.
- if (utils::ExprMutationAnalyzer(Function->getBody(), Result.Context)
+ if (utils::ExprMutationAnalyzer(*Function->getBody(), *Result.Context)
.isMutated(Param))
return;
// CXXCtorInitializer might also mutate Param but they're not part of function
// body, so check them separately here.
if (const auto *Ctor = dyn_cast<CXXConstructorDecl>(Function)) {
for (const auto *Init : Ctor->inits()) {
- if (utils::ExprMutationAnalyzer(Init->getInit(), Result.Context)
+ if (utils::ExprMutationAnalyzer(*Init->getInit(), *Result.Context)
.isMutated(Param))
return;
}
hasDescendant(equalsNode(Exp)))),
cxxNoexceptExpr())))))
.bind("expr")),
- *Stm, *Context)) != nullptr;
+ Stm, Context)) != nullptr;
}
const Stmt *
const Stmt *ExprMutationAnalyzer::findDeclMutation(const Decl *Dec) {
const auto Refs = match(
- findAll(declRefExpr(to(equalsNode(Dec))).bind("expr")), *Stm, *Context);
+ findAll(declRefExpr(to(equalsNode(Dec))).bind("expr")), Stm, Context);
for (const auto &RefNodes : Refs) {
const auto *E = RefNodes.getNodeAs<Expr>("expr");
if (findMutation(E))
AsNonConstRefArg, AsLambdaRefCaptureInit,
AsNonConstRefReturn))
.bind("stmt")),
- *Stm, *Context);
+ Stm, Context);
return selectFirst<Stmt>("stmt", Matches);
}
cxxDependentScopeMemberExpr(
hasObjectExpression(equalsNode(Exp)))))
.bind("expr")),
- *Stm, *Context);
+ Stm, Context);
return findExprMutation(MemberExprs);
}
const auto SubscriptExprs = match(
findAll(arraySubscriptExpr(hasBase(ignoringImpCasts(equalsNode(Exp))))
.bind("expr")),
- *Stm, *Context);
+ Stm, Context);
return findExprMutation(SubscriptExprs);
}
implicitCastExpr(hasImplicitDestinationType(
nonConstReferenceType()))))
.bind("expr")),
- *Stm, *Context);
+ Stm, Context);
return findExprMutation(Casts);
}
hasLoopVariable(
varDecl(hasType(nonConstReferenceType())).bind("decl")),
hasRangeInit(equalsNode(Exp)))),
- *Stm, *Context);
+ Stm, Context);
return findDeclMutation(LoopVars);
}
unless(hasParent(declStmt(hasParent(
cxxForRangeStmt(hasRangeStmt(equalsBoundNode("stmt"))))))))
.bind("decl"))),
- *Stm, *Context);
+ Stm, Context);
return findDeclMutation(Refs);
}
/// a given statement.
class ExprMutationAnalyzer {
public:
- ExprMutationAnalyzer(const Stmt *Stm, ASTContext *Context)
+ ExprMutationAnalyzer(const Stmt &Stm, ASTContext &Context)
: Stm(Stm), Context(Context) {}
bool isMutated(const Decl *Dec) { return findDeclMutation(Dec) != nullptr; }
const Stmt *findRangeLoopMutation(const Expr *Exp);
const Stmt *findReferenceMutation(const Expr *Exp);
- const Stmt *const Stm;
- ASTContext *const Context;
+ const Stmt &Stm;
+ ASTContext &Context;
llvm::DenseMap<const Expr *, const Stmt *> Results;
};
bool isMutated(const SmallVectorImpl<BoundNodes> &Results, ASTUnit *AST) {
const auto *const S = selectFirst<Stmt>("stmt", Results);
const auto *const E = selectFirst<Expr>("expr", Results);
- return utils::ExprMutationAnalyzer(S, &AST->getASTContext()).isMutated(E);
+ return utils::ExprMutationAnalyzer(*S, AST->getASTContext()).isMutated(E);
}
SmallVector<std::string, 1>
mutatedBy(const SmallVectorImpl<BoundNodes> &Results, ASTUnit *AST) {
const auto *const S = selectFirst<Stmt>("stmt", Results);
SmallVector<std::string, 1> Chain;
- utils::ExprMutationAnalyzer Analyzer(S, &AST->getASTContext());
+ utils::ExprMutationAnalyzer Analyzer(*S, AST->getASTContext());
for (const auto *E = selectFirst<Expr>("expr", Results); E != nullptr;) {
const Stmt *By = Analyzer.findMutation(E);
std::string buffer;