[clang] [mutation analyzer] support mutation analysis for pointee (PR #118593)
Julian Schmidt via cfe-commits
cfe-commits at lists.llvm.org
Tue Jan 21 01:03:26 PST 2025
================
@@ -654,6 +716,83 @@ ExprMutationAnalyzer::Analyzer::findFunctionArgMutation(const Expr *Exp) {
return nullptr;
}
+const Stmt *
+ExprMutationAnalyzer::Analyzer::findPointeeValueMutation(const Expr *Exp) {
+ const auto Matches = match(
+ stmt(forEachDescendant(
+ expr(anyOf(
+ // deref by *
+ unaryOperator(hasOperatorName("*"),
+ hasUnaryOperand(canResolveToExprPointee(Exp))),
+ // deref by []
+ arraySubscriptExpr(hasBase(canResolveToExprPointee(Exp)))))
+ .bind(NodeID<Expr>::value))),
+ Stm, Context);
+ return findExprMutation(Matches);
+}
+
+const Stmt *
+ExprMutationAnalyzer::Analyzer::findPointeeMemberMutation(const Expr *Exp) {
+ const Stmt *MemberCallExpr = selectFirst<Stmt>(
+ "stmt", match(stmt(forEachDescendant(
+ cxxMemberCallExpr(on(canResolveToExprPointee(Exp)),
+ unless(isConstCallee()))
+ .bind("stmt"))),
+ Stm, Context));
+ if (MemberCallExpr)
+ return MemberCallExpr;
+ const auto Matches =
+ match(stmt(forEachDescendant(
+ memberExpr(hasObjectExpression(canResolveToExprPointee(Exp)))
+ .bind(NodeID<Expr>::value))),
+ Stm, Context);
+ return findExprMutation(Matches);
+}
+
+const Stmt *
+ExprMutationAnalyzer::Analyzer::findPointeeToNonConst(const Expr *Exp) {
+ const auto NonConstPointerOrDependentType =
+ type(anyOf(nonConstPointerType(), isDependentType()));
+
+ // assign
+ const auto InitToNonConst =
+ varDecl(hasType(NonConstPointerOrDependentType),
+ hasInitializer(expr(canResolveToExprPointee(Exp)).bind("stmt")));
+ const auto AssignToNonConst =
+ binaryOperation(hasOperatorName("="),
+ hasLHS(expr(hasType(NonConstPointerOrDependentType))),
+ hasRHS(canResolveToExprPointee(Exp)));
+ // arguments like
+ const auto ArgOfInstantiationDependent = allOf(
+ hasAnyArgument(canResolveToExprPointee(Exp)), isInstantiationDependent());
+ const auto ArgOfNonConstParameter = forEachArgumentWithParamType(
+ canResolveToExprPointee(Exp), NonConstPointerOrDependentType);
+ const auto CallLikeMatcher =
+ anyOf(ArgOfNonConstParameter, ArgOfInstantiationDependent);
+ const auto PassAsNonConstArg =
+ expr(anyOf(cxxUnresolvedConstructExpr(ArgOfInstantiationDependent),
+ cxxConstructExpr(CallLikeMatcher), callExpr(CallLikeMatcher),
+ parenListExpr(has(canResolveToExprPointee(Exp))),
+ initListExpr(hasAnyInit(canResolveToExprPointee(Exp)))));
+ // cast
+ const auto CastToNonConst =
+ explicitCastExpr(hasSourceExpression(canResolveToExprPointee(Exp)),
+ hasDestinationType(NonConstPointerOrDependentType));
+
+ // capture
+ // FIXME: false positive if the pointee does not change in lambda
+ const auto CaptureNoConst = lambdaExpr(hasCaptureInit(Exp));
+
+ const auto Matches =
+ match(stmt(anyOf(forEachDescendant(
+ stmt(anyOf(AssignToNonConst, PassAsNonConstArg,
+ CastToNonConst, CaptureNoConst))
+ .bind("stmt")),
+ forEachDescendant(decl(InitToNonConst)))),
----------------
5chmidti wrote:
nit: the `decl` around `InitToNonConst` is not needed
https://github.com/llvm/llvm-project/pull/118593
More information about the cfe-commits
mailing list