//===---------- ExprMutationAnalyzer.cpp ----------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "clang/Analysis/Analyses/ExprMutationAnalyzer.h"
#include "clang/AST/Expr.h"
#include "clang/AST/OperationKinds.h"
#include "clang/AST/Stmt.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/ASTMatchers/ASTMatchers.h"
#include "clang/ASTMatchers/ASTMatchersMacros.h"
#include "llvm/ADT/STLExtras.h"

namespace clang {
using namespace ast_matchers;

// Check if result of Source expression could be a Target expression.
// Checks:
//  - Implicit Casts
//  - Binary Operators
//  - ConditionalOperator
//  - BinaryConditionalOperator
static bool canExprResolveTo(const Expr *Source, const Expr *Target) {
  const auto IgnoreDerivedToBase = [](const Expr *E, auto Matcher) {
    if (Matcher(E))
      return true;
    if (const auto *Cast = dyn_cast<ImplicitCastExpr>(E)) {
      if ((Cast->getCastKind() == CK_DerivedToBase ||
           Cast->getCastKind() == CK_UncheckedDerivedToBase) &&
          Matcher(Cast->getSubExpr()))
        return true;
    }
    return false;
  };

  const auto EvalCommaExpr = [](const Expr *E, auto Matcher) {
    const Expr *Result = E;
    while (const auto *BOComma =
               dyn_cast_or_null<BinaryOperator>(Result->IgnoreParens())) {
      if (!BOComma->isCommaOp())
        break;
      Result = BOComma->getRHS();
    }

    return Result != E && Matcher(Result);
  };

  // The 'ConditionalOperatorM' matches on `<anything> ? <expr> : <expr>`.
  // This matching must be recursive because `<expr>` can be anything resolving
  // to the `InnerMatcher`, for example another conditional operator.
  // The edge-case `BaseClass &b = <cond> ? DerivedVar1 : DerivedVar2;`
  // is handled, too. The implicit cast happens outside of the conditional.
  // This is matched by `IgnoreDerivedToBase(canResolveToExpr(InnerMatcher))`
  // below.
  const auto ConditionalOperatorM = [Target](const Expr *E) {
    if (const auto *CO = dyn_cast<AbstractConditionalOperator>(E)) {
      const auto *TE = CO->getTrueExpr()->IgnoreParens();
      if (TE && canExprResolveTo(TE, Target))
        return true;
      const auto *FE = CO->getFalseExpr()->IgnoreParens();
      if (FE && canExprResolveTo(FE, Target))
        return true;
    }
    return false;
  };

  const Expr *SourceExprP = Source->IgnoreParens();
  return IgnoreDerivedToBase(SourceExprP,
                             [&](const Expr *E) {
                               return E == Target || ConditionalOperatorM(E);
                             }) ||
         EvalCommaExpr(SourceExprP, [&](const Expr *E) {
           return IgnoreDerivedToBase(
               E->IgnoreParens(), [&](const Expr *EE) { return EE == Target; });
         });
}

namespace {

AST_MATCHER(Type, isDependentType) { return Node.isDependentType(); }

AST_MATCHER_P(LambdaExpr, hasCaptureInit, const Expr *, E) {
  return llvm::is_contained(Node.capture_inits(), E);
}

AST_MATCHER_P(CXXForRangeStmt, hasRangeStmt,
              ast_matchers::internal::Matcher<DeclStmt>, InnerMatcher) {
  const DeclStmt *const Range = Node.getRangeStmt();
  return InnerMatcher.matches(*Range, Finder, Builder);
}

AST_MATCHER_P(Stmt, canResolveToExpr, const Stmt *, Inner) {
  auto *Exp = dyn_cast<Expr>(&Node);
  if (!Exp)
    return true;
  auto *Target = dyn_cast<Expr>(Inner);
  if (!Target)
    return false;
  return canExprResolveTo(Exp, Target);
}

// use class member to store data can reduce stack usage to avoid stack overflow
// when recursive call.
class ExprPointeeResolve {
  const Expr *T;

  bool resolveExpr(const Expr *E) {
    if (E == nullptr)
      return false;
    if (E == T)
      return true;

    if (const auto *BO = dyn_cast<BinaryOperator>(E)) {
      if (BO->isAdditiveOp())
        return (resolveExpr(BO->getLHS()) || resolveExpr(BO->getRHS()));
      if (BO->isCommaOp())
        return resolveExpr(BO->getRHS());
      return false;
    }

    if (const auto *PE = dyn_cast<ParenExpr>(E))
      return resolveExpr(PE->getSubExpr());

    if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E)) {
      // only implicit cast needs to be treated as resolvable.
      // explicit cast will be checked in `findPointeeToNonConst`
      const CastKind kind = ICE->getCastKind();
      if (kind == CK_LValueToRValue || kind == CK_DerivedToBase ||
          kind == CK_UncheckedDerivedToBase)
        return resolveExpr(ICE->getSubExpr());
      return false;
    }

    if (const auto *ACE = dyn_cast<AbstractConditionalOperator>(E))
      return resolve(ACE->getTrueExpr()) || resolve(ACE->getFalseExpr());

    return false;
  }

public:
  ExprPointeeResolve(const Expr *T) : T(T) {}
  bool resolve(const Expr *S) { return resolveExpr(S); }
};

AST_MATCHER_P(Stmt, canResolveToExprPointee, const Stmt *, T) {
  auto *Exp = dyn_cast<Expr>(&Node);
  if (!Exp)
    return true;
  auto *Target = dyn_cast<Expr>(T);
  if (!Target)
    return false;
  return ExprPointeeResolve{Target}.resolve(Exp);
}

// Similar to 'hasAnyArgument', but does not work because 'InitListExpr' does
// not have the 'arguments()' method.
AST_MATCHER_P(InitListExpr, hasAnyInit, ast_matchers::internal::Matcher<Expr>,
              InnerMatcher) {
  for (const Expr *Arg : Node.inits()) {
    if (Arg == nullptr)
      continue;
    ast_matchers::internal::BoundNodesTreeBuilder Result(*Builder);
    if (InnerMatcher.matches(*Arg, Finder, &Result)) {
      *Builder = std::move(Result);
      return true;
    }
  }
  return false;
}

const ast_matchers::internal::VariadicDynCastAllOfMatcher<Stmt, CXXTypeidExpr>
    cxxTypeidExpr;

AST_MATCHER(CXXTypeidExpr, isPotentiallyEvaluated) {
  return Node.isPotentiallyEvaluated();
}

AST_MATCHER(CXXMemberCallExpr, isConstCallee) {
  const Decl *CalleeDecl = Node.getCalleeDecl();
  const auto *VD = dyn_cast_or_null<ValueDecl>(CalleeDecl);
  if (!VD)
    return false;
  const QualType T = VD->getType().getCanonicalType();
  const auto *MPT = dyn_cast<MemberPointerType>(T);
  const auto *FPT = MPT ? cast<FunctionProtoType>(MPT->getPointeeType())
                        : dyn_cast<FunctionProtoType>(T);
  if (!FPT)
    return false;
  return FPT->isConst();
}

AST_MATCHER_P(GenericSelectionExpr, hasControllingExpr,
              ast_matchers::internal::Matcher<Expr>, InnerMatcher) {
  if (Node.isTypePredicate())
    return false;
  return InnerMatcher.matches(*Node.getControllingExpr(), Finder, Builder);
}

template <typename T>
ast_matchers::internal::Matcher<T>
findFirst(const ast_matchers::internal::Matcher<T> &Matcher) {
  return anyOf(Matcher, hasDescendant(Matcher));
}

const auto nonConstReferenceType = [] {
  return hasUnqualifiedDesugaredType(
      referenceType(pointee(unless(isConstQualified()))));
};

const auto nonConstPointerType = [] {
  return hasUnqualifiedDesugaredType(
      pointerType(pointee(unless(isConstQualified()))));
};

const auto isMoveOnly = [] {
  return cxxRecordDecl(
      hasMethod(cxxConstructorDecl(isMoveConstructor(), unless(isDeleted()))),
      hasMethod(cxxMethodDecl(isMoveAssignmentOperator(), unless(isDeleted()))),
      unless(anyOf(hasMethod(cxxConstructorDecl(isCopyConstructor(),
                                                unless(isDeleted()))),
                   hasMethod(cxxMethodDecl(isCopyAssignmentOperator(),
                                           unless(isDeleted()))))));
};

template <class T> struct NodeID;
template <> struct NodeID<Expr> { static constexpr StringRef value = "expr"; };
template <> struct NodeID<Decl> { static constexpr StringRef value = "decl"; };
constexpr StringRef NodeID<Expr>::value;
constexpr StringRef NodeID<Decl>::value;

template <class T,
          class F = const Stmt *(ExprMutationAnalyzer::Analyzer::*)(const T *)>
const Stmt *tryEachMatch(ArrayRef<ast_matchers::BoundNodes> Matches,
                         ExprMutationAnalyzer::Analyzer *Analyzer, F Finder) {
  const StringRef ID = NodeID<T>::value;
  for (const auto &Nodes : Matches) {
    if (const Stmt *S = (Analyzer->*Finder)(Nodes.getNodeAs<T>(ID)))
      return S;
  }
  return nullptr;
}

} // namespace

const Stmt *ExprMutationAnalyzer::Analyzer::findMutation(const Expr *Exp) {
  return findMutationMemoized(
      Exp,
      {&ExprMutationAnalyzer::Analyzer::findDirectMutation,
       &ExprMutationAnalyzer::Analyzer::findMemberMutation,
       &ExprMutationAnalyzer::Analyzer::findArrayElementMutation,
       &ExprMutationAnalyzer::Analyzer::findCastMutation,
       &ExprMutationAnalyzer::Analyzer::findRangeLoopMutation,
       &ExprMutationAnalyzer::Analyzer::findReferenceMutation,
       &ExprMutationAnalyzer::Analyzer::findFunctionArgMutation},
      Memorized.Results);
}

const Stmt *ExprMutationAnalyzer::Analyzer::findMutation(const Decl *Dec) {
  return tryEachDeclRef(Dec, &ExprMutationAnalyzer::Analyzer::findMutation);
}

const Stmt *
ExprMutationAnalyzer::Analyzer::findPointeeMutation(const Expr *Exp) {
  return findMutationMemoized(
      Exp,
      {
          &ExprMutationAnalyzer::Analyzer::findPointeeValueMutation,
          &ExprMutationAnalyzer::Analyzer::findPointeeMemberMutation,
          &ExprMutationAnalyzer::Analyzer::findPointeeToNonConst,
      },
      Memorized.PointeeResults);
}

const Stmt *
ExprMutationAnalyzer::Analyzer::findPointeeMutation(const Decl *Dec) {
  return tryEachDeclRef(Dec,
                        &ExprMutationAnalyzer::Analyzer::findPointeeMutation);
}

const Stmt *ExprMutationAnalyzer::Analyzer::findMutationMemoized(
    const Expr *Exp, llvm::ArrayRef<MutationFinder> Finders,
    Memoized::ResultMap &MemoizedResults) {
  // Assume Exp is not mutated before analyzing Exp.
  auto [Memoized, Inserted] = MemoizedResults.try_emplace(Exp);
  if (!Inserted)
    return Memoized->second;

  if (ExprMutationAnalyzer::isUnevaluated(Exp, Context))
    return nullptr;

  for (const auto &Finder : Finders) {
    if (const Stmt *S = (this->*Finder)(Exp))
      return MemoizedResults[Exp] = S;
  }

  return nullptr;
}

const Stmt *
ExprMutationAnalyzer::Analyzer::tryEachDeclRef(const Decl *Dec,
                                               MutationFinder Finder) {
  const auto Refs = match(
      findAll(
          declRefExpr(to(
                          // `Dec` or a binding if `Dec` is a decomposition.
                          anyOf(equalsNode(Dec),
                                bindingDecl(forDecomposition(equalsNode(Dec))))
                          //
                          ))
              .bind(NodeID<Expr>::value)),
      Stm, Context);
  for (const auto &RefNodes : Refs) {
    const auto *E = RefNodes.getNodeAs<Expr>(NodeID<Expr>::value);
    if ((this->*Finder)(E))
      return E;
  }
  return nullptr;
}

bool ExprMutationAnalyzer::isUnevaluated(const Stmt *Stm, ASTContext &Context) {
  return !match(stmt(anyOf(
                    // `Exp` is part of the underlying expression of
                    // decltype/typeof if it has an ancestor of
                    // typeLoc.
                    hasAncestor(typeLoc(
                        unless(hasAncestor(unaryExprOrTypeTraitExpr())))),
                    hasAncestor(expr(anyOf(
                        // `UnaryExprOrTypeTraitExpr` is unevaluated
                        // unless it's sizeof on VLA.
                        unaryExprOrTypeTraitExpr(unless(sizeOfExpr(
                            hasArgumentOfType(variableArrayType())))),
                        // `CXXTypeidExpr` is unevaluated unless it's
                        // applied to an expression of glvalue of
                        // polymorphic class type.
                        cxxTypeidExpr(unless(isPotentiallyEvaluated())),
                        // The controlling expression of
                        // `GenericSelectionExpr` is unevaluated.
                        genericSelectionExpr(
                            hasControllingExpr(hasDescendant(equalsNode(Stm)))),
                        cxxNoexceptExpr()))))),
                *Stm, Context)
              .empty();
}

const Stmt *
ExprMutationAnalyzer::Analyzer::findExprMutation(ArrayRef<BoundNodes> Matches) {
  return tryEachMatch<Expr>(Matches, this,
                            &ExprMutationAnalyzer::Analyzer::findMutation);
}

const Stmt *
ExprMutationAnalyzer::Analyzer::findDeclMutation(ArrayRef<BoundNodes> Matches) {
  return tryEachMatch<Decl>(Matches, this,
                            &ExprMutationAnalyzer::Analyzer::findMutation);
}

const Stmt *ExprMutationAnalyzer::Analyzer::findExprPointeeMutation(
    ArrayRef<ast_matchers::BoundNodes> Matches) {
  return tryEachMatch<Expr>(
      Matches, this, &ExprMutationAnalyzer::Analyzer::findPointeeMutation);
}

const Stmt *ExprMutationAnalyzer::Analyzer::findDeclPointeeMutation(
    ArrayRef<ast_matchers::BoundNodes> Matches) {
  return tryEachMatch<Decl>(
      Matches, this, &ExprMutationAnalyzer::Analyzer::findPointeeMutation);
}

const Stmt *
ExprMutationAnalyzer::Analyzer::findDirectMutation(const Expr *Exp) {
  // LHS of any assignment operators.
  const auto AsAssignmentLhs =
      binaryOperator(isAssignmentOperator(), hasLHS(canResolveToExpr(Exp)));

  // Operand of increment/decrement operators.
  const auto AsIncDecOperand =
      unaryOperator(anyOf(hasOperatorName("++"), hasOperatorName("--")),
                    hasUnaryOperand(canResolveToExpr(Exp)));

  // Invoking non-const member function.
  // A member function is assumed to be non-const when it is unresolved.
  const auto NonConstMethod = cxxMethodDecl(unless(isConst()));

  const auto AsNonConstThis = expr(anyOf(
      cxxMemberCallExpr(on(canResolveToExpr(Exp)), unless(isConstCallee())),
      cxxOperatorCallExpr(callee(NonConstMethod),
                          hasArgument(0, canResolveToExpr(Exp))),
      // In case of a templated type, calling overloaded operators is not
      // resolved and modelled as `binaryOperator` on a dependent type.
      // Such instances are considered a modification, because they can modify
      // in different instantiations of the template.
      binaryOperator(isTypeDependent(),
                     hasEitherOperand(ignoringImpCasts(canResolveToExpr(Exp)))),
      // A fold expression may contain `Exp` as it's initializer.
      // We don't know if the operator modifies `Exp` because the
      // operator is type dependent due to the parameter pack.
      cxxFoldExpr(hasFoldInit(ignoringImpCasts(canResolveToExpr(Exp)))),
      // Within class templates and member functions the member expression might
      // not be resolved. In that case, the `callExpr` is considered to be a
      // modification.
      callExpr(callee(expr(anyOf(
          unresolvedMemberExpr(hasObjectExpression(canResolveToExpr(Exp))),
          cxxDependentScopeMemberExpr(
              hasObjectExpression(canResolveToExpr(Exp))))))),
      // Match on a call to a known method, but the call itself is type
      // dependent (e.g. `vector<T> v; v.push(T{});` in a templated function).
      callExpr(allOf(
          isTypeDependent(),
          callee(memberExpr(hasDeclaration(NonConstMethod),
                            hasObjectExpression(canResolveToExpr(Exp))))))));

  // Taking address of 'Exp'.
  // We're assuming 'Exp' is mutated as soon as its address is taken, though in
  // theory we can follow the pointer and see whether it escaped `Stm` or is
  // dereferenced and then mutated. This is left for future improvements.
  const auto AsAmpersandOperand =
      unaryOperator(hasOperatorName("&"),
                    // A NoOp implicit cast is adding const.
                    unless(hasParent(implicitCastExpr(hasCastKind(CK_NoOp)))),
                    hasUnaryOperand(canResolveToExpr(Exp)));
  const auto AsPointerFromArrayDecay = castExpr(
      hasCastKind(CK_ArrayToPointerDecay),
      unless(hasParent(arraySubscriptExpr())), has(canResolveToExpr(Exp)));
  // Treat calling `operator->()` of move-only classes as taking address.
  // These are typically smart pointers with unique ownership so we treat
  // mutation of pointee as mutation of the smart pointer itself.
  const auto AsOperatorArrowThis = cxxOperatorCallExpr(
      hasOverloadedOperatorName("->"),
      callee(
          cxxMethodDecl(ofClass(isMoveOnly()), returns(nonConstPointerType()))),
      argumentCountIs(1), hasArgument(0, canResolveToExpr(Exp)));

  // Used as non-const-ref argument when calling a function.
  // An argument is assumed to be non-const-ref when the function is unresolved.
  // Instantiated template functions are not handled here but in
  // findFunctionArgMutation which has additional smarts for handling forwarding
  // references.
  const auto NonConstRefParam = forEachArgumentWithParamType(
      anyOf(canResolveToExpr(Exp),
            memberExpr(
                hasObjectExpression(ignoringImpCasts(canResolveToExpr(Exp))))),
      nonConstReferenceType());
  const auto NotInstantiated = unless(hasDeclaration(isInstantiated()));

  const auto AsNonConstRefArg =
      anyOf(callExpr(NonConstRefParam, NotInstantiated),
            cxxConstructExpr(NonConstRefParam, NotInstantiated),
            // If the call is type-dependent, we can't properly process any
            // argument because required type conversions and implicit casts
            // will be inserted only after specialization.
            callExpr(isTypeDependent(), hasAnyArgument(canResolveToExpr(Exp))),
            cxxUnresolvedConstructExpr(hasAnyArgument(canResolveToExpr(Exp))),
            // Previous False Positive in the following Code:
            // `template <typename T> void f() { int i = 42; new Type<T>(i); }`
            // Where the constructor of `Type` takes its argument as reference.
            // The AST does not resolve in a `cxxConstructExpr` because it is
            // type-dependent.
            parenListExpr(hasDescendant(expr(canResolveToExpr(Exp)))),
            // If the initializer is for a reference type, there is no cast for
            // the variable. Values are cast to RValue first.
            initListExpr(hasAnyInit(expr(canResolveToExpr(Exp)))));

  // Captured by a lambda by reference.
  // If we're initializing a capture with 'Exp' directly then we're initializing
  // a reference capture.
  // For value captures there will be an ImplicitCastExpr <LValueToRValue>.
  const auto AsLambdaRefCaptureInit = lambdaExpr(hasCaptureInit(Exp));

  // Returned as non-const-ref.
  // If we're returning 'Exp' directly then it's returned as non-const-ref.
  // For returning by value there will be an ImplicitCastExpr <LValueToRValue>.
  // For returning by const-ref there will be an ImplicitCastExpr <NoOp> (for
  // adding const.)
  const auto AsNonConstRefReturn =
      returnStmt(hasReturnValue(canResolveToExpr(Exp)));

  // It is used as a non-const-reference for initializing a range-for loop.
  const auto AsNonConstRefRangeInit = cxxForRangeStmt(hasRangeInit(declRefExpr(
      allOf(canResolveToExpr(Exp), hasType(nonConstReferenceType())))));

  const auto Matches = match(
      traverse(
          TK_AsIs,
          findFirst(stmt(anyOf(AsAssignmentLhs, AsIncDecOperand, AsNonConstThis,
                               AsAmpersandOperand, AsPointerFromArrayDecay,
                               AsOperatorArrowThis, AsNonConstRefArg,
                               AsLambdaRefCaptureInit, AsNonConstRefReturn,
                               AsNonConstRefRangeInit))
                        .bind("stmt"))),
      Stm, Context);
  return selectFirst<Stmt>("stmt", Matches);
}

const Stmt *
ExprMutationAnalyzer::Analyzer::findMemberMutation(const Expr *Exp) {
  // Check whether any member of 'Exp' is mutated.
  const auto MemberExprs = match(
      findAll(expr(anyOf(memberExpr(hasObjectExpression(canResolveToExpr(Exp))),
                         cxxDependentScopeMemberExpr(
                             hasObjectExpression(canResolveToExpr(Exp))),
                         binaryOperator(hasOperatorName(".*"),
                                        hasLHS(equalsNode(Exp)))))
                  .bind(NodeID<Expr>::value)),
      Stm, Context);
  return findExprMutation(MemberExprs);
}

const Stmt *
ExprMutationAnalyzer::Analyzer::findArrayElementMutation(const Expr *Exp) {
  // Check whether any element of an array is mutated.
  const auto SubscriptExprs = match(
      findAll(arraySubscriptExpr(
                  anyOf(hasBase(canResolveToExpr(Exp)),
                        hasBase(implicitCastExpr(allOf(
                            hasCastKind(CK_ArrayToPointerDecay),
                            hasSourceExpression(canResolveToExpr(Exp)))))))
                  .bind(NodeID<Expr>::value)),
      Stm, Context);
  return findExprMutation(SubscriptExprs);
}

const Stmt *ExprMutationAnalyzer::Analyzer::findCastMutation(const Expr *Exp) {
  // If the 'Exp' is explicitly casted to a non-const reference type the
  // 'Exp' is considered to be modified.
  const auto ExplicitCast =
      match(findFirst(stmt(castExpr(hasSourceExpression(canResolveToExpr(Exp)),
                                    explicitCastExpr(hasDestinationType(
                                        nonConstReferenceType()))))
                          .bind("stmt")),
            Stm, Context);

  if (const auto *CastStmt = selectFirst<Stmt>("stmt", ExplicitCast))
    return CastStmt;

  // If 'Exp' is casted to any non-const reference type, check the castExpr.
  const auto Casts = match(
      findAll(expr(castExpr(hasSourceExpression(canResolveToExpr(Exp)),
                            anyOf(explicitCastExpr(hasDestinationType(
                                      nonConstReferenceType())),
                                  implicitCastExpr(hasImplicitDestinationType(
                                      nonConstReferenceType())))))
                  .bind(NodeID<Expr>::value)),
      Stm, Context);

  if (const Stmt *S = findExprMutation(Casts))
    return S;
  // Treat std::{move,forward} as cast.
  const auto Calls =
      match(findAll(callExpr(callee(namedDecl(
                                 hasAnyName("::std::move", "::std::forward"))),
                             hasArgument(0, canResolveToExpr(Exp)))
                        .bind("expr")),
            Stm, Context);
  return findExprMutation(Calls);
}

const Stmt *
ExprMutationAnalyzer::Analyzer::findRangeLoopMutation(const Expr *Exp) {
  // Keep the ordering for the specific initialization matches to happen first,
  // because it is cheaper to match all potential modifications of the loop
  // variable.

  // The range variable is a reference to a builtin array. In that case the
  // array is considered modified if the loop-variable is a non-const reference.
  const auto DeclStmtToNonRefToArray = declStmt(hasSingleDecl(varDecl(hasType(
      hasUnqualifiedDesugaredType(referenceType(pointee(arrayType())))))));
  const auto RefToArrayRefToElements = match(
      findFirst(stmt(cxxForRangeStmt(
                         hasLoopVariable(
                             varDecl(anyOf(hasType(nonConstReferenceType()),
                                           hasType(nonConstPointerType())))
                                 .bind(NodeID<Decl>::value)),
                         hasRangeStmt(DeclStmtToNonRefToArray),
                         hasRangeInit(canResolveToExpr(Exp))))
                    .bind("stmt")),
      Stm, Context);

  if (const auto *BadRangeInitFromArray =
          selectFirst<Stmt>("stmt", RefToArrayRefToElements))
    return BadRangeInitFromArray;

  // Small helper to match special cases in range-for loops.
  //
  // It is possible that containers do not provide a const-overload for their
  // iterator accessors. If this is the case, the variable is used non-const
  // no matter what happens in the loop. This requires special detection as it
  // is then faster to find all mutations of the loop variable.
  // It aims at a different modification as well.
  const auto HasAnyNonConstIterator =
      anyOf(allOf(hasMethod(allOf(hasName("begin"), unless(isConst()))),
                  unless(hasMethod(allOf(hasName("begin"), isConst())))),
            allOf(hasMethod(allOf(hasName("end"), unless(isConst()))),
                  unless(hasMethod(allOf(hasName("end"), isConst())))));

  const auto DeclStmtToNonConstIteratorContainer = declStmt(
      hasSingleDecl(varDecl(hasType(hasUnqualifiedDesugaredType(referenceType(
          pointee(hasDeclaration(cxxRecordDecl(HasAnyNonConstIterator)))))))));

  const auto RefToContainerBadIterators = match(
      findFirst(stmt(cxxForRangeStmt(allOf(
                         hasRangeStmt(DeclStmtToNonConstIteratorContainer),
                         hasRangeInit(canResolveToExpr(Exp)))))
                    .bind("stmt")),
      Stm, Context);

  if (const auto *BadIteratorsContainer =
          selectFirst<Stmt>("stmt", RefToContainerBadIterators))
    return BadIteratorsContainer;

  // If range for looping over 'Exp' with a non-const reference loop variable,
  // check all declRefExpr of the loop variable.
  const auto LoopVars =
      match(findAll(cxxForRangeStmt(
                hasLoopVariable(varDecl(hasType(nonConstReferenceType()))
                                    .bind(NodeID<Decl>::value)),
                hasRangeInit(canResolveToExpr(Exp)))),
            Stm, Context);
  return findDeclMutation(LoopVars);
}

const Stmt *
ExprMutationAnalyzer::Analyzer::findReferenceMutation(const Expr *Exp) {
  // Follow non-const reference returned by `operator*()` of move-only classes.
  // These are typically smart pointers with unique ownership so we treat
  // mutation of pointee as mutation of the smart pointer itself.
  const auto Ref = match(
      findAll(cxxOperatorCallExpr(
                  hasOverloadedOperatorName("*"),
                  callee(cxxMethodDecl(ofClass(isMoveOnly()),
                                       returns(nonConstReferenceType()))),
                  argumentCountIs(1), hasArgument(0, canResolveToExpr(Exp)))
                  .bind(NodeID<Expr>::value)),
      Stm, Context);
  if (const Stmt *S = findExprMutation(Ref))
    return S;

  // If 'Exp' is bound to a non-const reference, check all declRefExpr to that.
  const auto Refs = match(
      stmt(forEachDescendant(
          varDecl(hasType(nonConstReferenceType()),
                  hasInitializer(anyOf(
                      canResolveToExpr(Exp),
                      memberExpr(hasObjectExpression(canResolveToExpr(Exp))))),
                  hasParent(declStmt().bind("stmt")),
                  // Don't follow the reference in range statement, we've
                  // handled that separately.
                  unless(hasParent(declStmt(hasParent(cxxForRangeStmt(
                      hasRangeStmt(equalsBoundNode("stmt"))))))))
              .bind(NodeID<Decl>::value))),
      Stm, Context);
  return findDeclMutation(Refs);
}

const Stmt *
ExprMutationAnalyzer::Analyzer::findFunctionArgMutation(const Expr *Exp) {
  const auto NonConstRefParam = forEachArgumentWithParam(
      canResolveToExpr(Exp),
      parmVarDecl(hasType(nonConstReferenceType())).bind("parm"));
  const auto IsInstantiated = hasDeclaration(isInstantiated());
  const auto FuncDecl = hasDeclaration(functionDecl().bind("func"));
  const auto Matches = match(
      traverse(
          TK_AsIs,
          findAll(
              expr(anyOf(callExpr(NonConstRefParam, IsInstantiated, FuncDecl,
                                  unless(callee(namedDecl(hasAnyName(
                                      "::std::move", "::std::forward"))))),
                         cxxConstructExpr(NonConstRefParam, IsInstantiated,
                                          FuncDecl)))
                  .bind(NodeID<Expr>::value))),
      Stm, Context);
  for (const auto &Nodes : Matches) {
    const auto *Exp = Nodes.getNodeAs<Expr>(NodeID<Expr>::value);
    const auto *Func = Nodes.getNodeAs<FunctionDecl>("func");
    if (!Func->getBody() || !Func->getPrimaryTemplate())
      return Exp;

    const auto *Parm = Nodes.getNodeAs<ParmVarDecl>("parm");
    const ArrayRef<ParmVarDecl *> AllParams =
        Func->getPrimaryTemplate()->getTemplatedDecl()->parameters();
    QualType ParmType =
        AllParams[std::min<size_t>(Parm->getFunctionScopeIndex(),
                                   AllParams.size() - 1)]
            ->getType();
    if (const auto *T = ParmType->getAs<PackExpansionType>())
      ParmType = T->getPattern();

    // If param type is forwarding reference, follow into the function
    // definition and see whether the param is mutated inside.
    if (const auto *RefType = ParmType->getAs<RValueReferenceType>()) {
      if (!RefType->getPointeeType().getQualifiers() &&
          RefType->getPointeeType()->getAs<TemplateTypeParmType>()) {
        FunctionParmMutationAnalyzer *Analyzer =
            FunctionParmMutationAnalyzer::getFunctionParmMutationAnalyzer(
                *Func, Context, Memorized);
        if (Analyzer->findMutation(Parm))
          return Exp;
        continue;
      }
    }
    // Not forwarding reference.
    return 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(InitToNonConst))),
            Stm, Context);
  return selectFirst<Stmt>("stmt", Matches);
}

FunctionParmMutationAnalyzer::FunctionParmMutationAnalyzer(
    const FunctionDecl &Func, ASTContext &Context,
    ExprMutationAnalyzer::Memoized &Memorized)
    : BodyAnalyzer(*Func.getBody(), Context, Memorized) {
  if (const auto *Ctor = dyn_cast<CXXConstructorDecl>(&Func)) {
    // CXXCtorInitializer might also mutate Param but they're not part of
    // function body, check them eagerly here since they're typically trivial.
    for (const CXXCtorInitializer *Init : Ctor->inits()) {
      ExprMutationAnalyzer::Analyzer InitAnalyzer(*Init->getInit(), Context,
                                                  Memorized);
      for (const ParmVarDecl *Parm : Ctor->parameters()) {
        if (Results.contains(Parm))
          continue;
        if (const Stmt *S = InitAnalyzer.findMutation(Parm))
          Results[Parm] = S;
      }
    }
  }
}

const Stmt *
FunctionParmMutationAnalyzer::findMutation(const ParmVarDecl *Parm) {
  const auto Memoized = Results.find(Parm);
  if (Memoized != Results.end())
    return Memoized->second;
  // To handle call A -> call B -> call A. Assume parameters of A is not mutated
  // before analyzing parameters of A. Then when analyzing the second "call A",
  // FunctionParmMutationAnalyzer can use this memoized value to avoid infinite
  // recursion.
  Results[Parm] = nullptr;
  if (const Stmt *S = BodyAnalyzer.findMutation(Parm))
    return Results[Parm] = S;
  return Results[Parm];
}

} // namespace clang
