//===---------- 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 {

// `ArraySubscriptExpr` can switch base and idx, e.g. `a[4]` is the same as
// `4[a]`. When type is dependent, we conservatively assume both sides are base.
AST_MATCHER_P(ArraySubscriptExpr, hasBaseConservative,
              ast_matchers::internal::Matcher<Expr>, InnerMatcher) {
  if (Node.isTypeDependent()) {
    return InnerMatcher.matches(*Node.getLHS(), Finder, Builder) ||
           InnerMatcher.matches(*Node.getRHS(), Finder, Builder);
  }
  return InnerMatcher.matches(*Node.getBase(), Finder, Builder);
}

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 ||
          (kind == CK_NoOp && (ICE->getType() == ICE->getSubExpr()->getType())))
        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";
};

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(hasBaseConservative(canResolveToExpr(Exp)),
                        hasBaseConservative(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() &&
          isa<TemplateTypeParmType>(
              RefType->getPointeeType().getCanonicalType())) {
        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(
                       hasBaseConservative(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(
          expr(anyOf(memberExpr(
                         hasObjectExpression(canResolveToExprPointee(Exp))),
                     binaryOperator(hasOperatorName("->*"),
                                    hasLHS(canResolveToExprPointee(Exp)))))
              .bind(NodeID<Expr>::value))),
      Stm, Context);
  return findExprMutation(Matches);
}

const Stmt *
ExprMutationAnalyzer::Analyzer::findPointeeToNonConst(const Expr *Exp) {
  const auto NonConstPointerOrNonConstRefOrDependentType = type(
      anyOf(nonConstPointerType(), nonConstReferenceType(), isDependentType()));

  // assign
  const auto InitToNonConst =
      varDecl(hasType(NonConstPointerOrNonConstRefOrDependentType),
              hasInitializer(expr(canResolveToExprPointee(Exp)).bind("stmt")));
  const auto AssignToNonConst = binaryOperation(
      hasOperatorName("="),
      hasLHS(expr(hasType(NonConstPointerOrNonConstRefOrDependentType))),
      hasRHS(canResolveToExprPointee(Exp)));
  // arguments like
  const auto ArgOfInstantiationDependent = allOf(
      hasAnyArgument(canResolveToExprPointee(Exp)), isInstantiationDependent());
  const auto ArgOfNonConstParameter =
      forEachArgumentWithParamType(canResolveToExprPointee(Exp),
                                   NonConstPointerOrNonConstRefOrDependentType);
  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(NonConstPointerOrNonConstRefOrDependentType));

  // capture
  // FIXME: false positive if the pointee does not change in lambda
  const auto CaptureNoConst = lambdaExpr(hasCaptureInit(Exp));

  const auto ReturnNoConst =
      returnStmt(hasReturnValue(canResolveToExprPointee(Exp)));

  const auto Matches = match(
      stmt(anyOf(forEachDescendant(
                     stmt(anyOf(AssignToNonConst, PassAsNonConstArg,
                                CastToNonConst, CaptureNoConst, ReturnNoConst))
                         .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) {
  auto [Place, Inserted] = Results.try_emplace(Parm);
  if (!Inserted)
    return Place->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.
  return Place->second = BodyAnalyzer.findMutation(Parm);
}

} // namespace clang
