================ @@ -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 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits