//===-- lib/Semantics/pointer-assignment.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 "pointer-assignment.h"
#include "definable.h"
#include "flang/Common/idioms.h"
#include "flang/Common/restorer.h"
#include "flang/Common/template.h"
#include "flang/Evaluate/characteristics.h"
#include "flang/Evaluate/expression.h"
#include "flang/Evaluate/fold.h"
#include "flang/Evaluate/tools.h"
#include "flang/Parser/message.h"
#include "flang/Parser/parse-tree-visitor.h"
#include "flang/Parser/parse-tree.h"
#include "flang/Semantics/expression.h"
#include "flang/Semantics/symbol.h"
#include "flang/Semantics/tools.h"
#include "llvm/Support/raw_ostream.h"
#include <optional>
#include <set>
#include <string>
#include <type_traits>

// Semantic checks for pointer assignment.

namespace Fortran::semantics {

using namespace parser::literals;
using evaluate::characteristics::DummyDataObject;
using evaluate::characteristics::FunctionResult;
using evaluate::characteristics::Procedure;
using evaluate::characteristics::TypeAndShape;
using parser::MessageFixedText;
using parser::MessageFormattedText;

class PointerAssignmentChecker {
public:
  PointerAssignmentChecker(SemanticsContext &context, const Scope &scope,
      parser::CharBlock source, const std::string &description)
      : context_{context}, scope_{scope}, source_{source}, description_{
                                                               description} {}
  PointerAssignmentChecker(
      SemanticsContext &context, const Scope &scope, const Symbol &lhs)
      : context_{context}, scope_{scope}, source_{lhs.name()},
        description_{"pointer '"s + lhs.name().ToString() + '\''}, lhs_{&lhs} {
    set_lhsType(TypeAndShape::Characterize(lhs, foldingContext_));
    set_isContiguous(lhs.attrs().test(Attr::CONTIGUOUS));
    set_isVolatile(lhs.attrs().test(Attr::VOLATILE));
  }
  PointerAssignmentChecker &set_lhsType(std::optional<TypeAndShape> &&);
  PointerAssignmentChecker &set_isContiguous(bool);
  PointerAssignmentChecker &set_isVolatile(bool);
  PointerAssignmentChecker &set_isBoundsRemapping(bool);
  PointerAssignmentChecker &set_isAssumedRank(bool);
  PointerAssignmentChecker &set_pointerComponentLHS(const Symbol *);
  bool CheckLeftHandSide(const SomeExpr &);
  bool Check(const SomeExpr &);

private:
  bool CharacterizeProcedure();
  template <typename T> bool Check(const T &);
  template <typename T> bool Check(const evaluate::Expr<T> &);
  template <typename T> bool Check(const evaluate::FunctionRef<T> &);
  template <typename T> bool Check(const evaluate::Designator<T> &);
  bool Check(const evaluate::NullPointer &);
  bool Check(const evaluate::ProcedureDesignator &);
  bool Check(const evaluate::ProcedureRef &);
  // Target is a procedure
  bool Check(parser::CharBlock rhsName, bool isCall,
      const Procedure * = nullptr,
      const evaluate::SpecificIntrinsic *specific = nullptr);
  bool LhsOkForUnlimitedPoly() const;
  template <typename... A> parser::Message *Say(A &&...);

  SemanticsContext &context_;
  evaluate::FoldingContext &foldingContext_{context_.foldingContext()};
  const Scope &scope_;
  const parser::CharBlock source_;
  const std::string description_;
  const Symbol *lhs_{nullptr};
  std::optional<TypeAndShape> lhsType_;
  std::optional<Procedure> procedure_;
  bool characterizedProcedure_{false};
  bool isContiguous_{false};
  bool isVolatile_{false};
  bool isBoundsRemapping_{false};
  bool isAssumedRank_{false};
  const Symbol *pointerComponentLHS_{nullptr};
};

PointerAssignmentChecker &PointerAssignmentChecker::set_lhsType(
    std::optional<TypeAndShape> &&lhsType) {
  lhsType_ = std::move(lhsType);
  return *this;
}

PointerAssignmentChecker &PointerAssignmentChecker::set_isContiguous(
    bool isContiguous) {
  isContiguous_ = isContiguous;
  return *this;
}

PointerAssignmentChecker &PointerAssignmentChecker::set_isVolatile(
    bool isVolatile) {
  isVolatile_ = isVolatile;
  return *this;
}

PointerAssignmentChecker &PointerAssignmentChecker::set_isBoundsRemapping(
    bool isBoundsRemapping) {
  isBoundsRemapping_ = isBoundsRemapping;
  return *this;
}

PointerAssignmentChecker &PointerAssignmentChecker::set_isAssumedRank(
    bool isAssumedRank) {
  isAssumedRank_ = isAssumedRank;
  return *this;
}

PointerAssignmentChecker &PointerAssignmentChecker::set_pointerComponentLHS(
    const Symbol *symbol) {
  pointerComponentLHS_ = symbol;
  return *this;
}

bool PointerAssignmentChecker::CharacterizeProcedure() {
  if (!characterizedProcedure_) {
    characterizedProcedure_ = true;
    if (lhs_ && IsProcedure(*lhs_)) {
      procedure_ = Procedure::Characterize(*lhs_, foldingContext_);
    }
  }
  return procedure_.has_value();
}

bool PointerAssignmentChecker::CheckLeftHandSide(const SomeExpr &lhs) {
  if (auto whyNot{WhyNotDefinable(foldingContext_.messages().at(), scope_,
          DefinabilityFlags{DefinabilityFlag::PointerDefinition}, lhs)}) {
    if (auto *msg{Say(
            "The left-hand side of a pointer assignment is not definable"_err_en_US)}) {
      msg->Attach(std::move(*whyNot));
    }
    return false;
  } else {
    return true;
  }
}

template <typename T> bool PointerAssignmentChecker::Check(const T &) {
  // Catch-all case for really bad target expression
  Say("Target associated with %s must be a designator or a call to a"
      " pointer-valued function"_err_en_US,
      description_);
  return false;
}

template <typename T>
bool PointerAssignmentChecker::Check(const evaluate::Expr<T> &x) {
  return common::visit([&](const auto &x) { return Check(x); }, x.u);
}

bool PointerAssignmentChecker::Check(const SomeExpr &rhs) {
  if (HasVectorSubscript(rhs)) { // C1025
    Say("An array section with a vector subscript may not be a pointer target"_err_en_US);
    return false;
  }
  if (ExtractCoarrayRef(rhs)) { // C1026
    Say("A coindexed object may not be a pointer target"_err_en_US);
    return false;
  }
  if (!common::visit([&](const auto &x) { return Check(x); }, rhs.u)) {
    return false;
  }
  if (IsNullPointer(rhs)) {
    return true;
  }
  if (lhs_ && IsProcedure(*lhs_)) {
    return true;
  }
  if (const auto *pureProc{FindPureProcedureContaining(scope_)}) {
    if (pointerComponentLHS_) { // C1594(4) is a hard error
      if (const Symbol * object{FindExternallyVisibleObject(rhs, *pureProc)}) {
        if (auto *msg{Say(
                "Externally visible object '%s' may not be associated with pointer component '%s' in a pure procedure"_err_en_US,
                object->name(), pointerComponentLHS_->name())}) {
          msg->Attach(object->name(), "Object declaration"_en_US)
              .Attach(
                  pointerComponentLHS_->name(), "Pointer declaration"_en_US);
        }
        return false;
      }
    } else if (const Symbol * base{GetFirstSymbol(rhs)}) {
      if (const char *why{WhyBaseObjectIsSuspicious(
              base->GetUltimate(), scope_)}) { // C1594(3)
        evaluate::SayWithDeclaration(foldingContext_.messages(), *base,
            "A pure subprogram may not use '%s' as the target of pointer assignment because it is %s"_err_en_US,
            base->name(), why);
        return false;
      }
    }
  }
  if (isContiguous_) {
    if (auto contiguous{evaluate::IsContiguous(rhs, foldingContext_)}) {
      if (!*contiguous) {
        Say("CONTIGUOUS pointer may not be associated with a discontiguous target"_err_en_US);
        return false;
      }
    } else if (context_.ShouldWarn(
                   common::UsageWarning::PointerToPossibleNoncontiguous)) {
      Say("Target of CONTIGUOUS pointer association is not known to be contiguous"_warn_en_US);
    }
  }
  // Warn about undefinable data targets
  if (context_.ShouldWarn(common::UsageWarning::PointerToUndefinable)) {
    if (auto because{WhyNotDefinable(
            foldingContext_.messages().at(), scope_, {}, rhs)}) {
      if (auto *msg{
              Say("Pointer target is not a definable variable"_warn_en_US)}) {
        msg->Attach(std::move(*because));
      }
      return false;
    }
  }
  return true;
}

bool PointerAssignmentChecker::Check(const evaluate::NullPointer &) {
  return true; // P => NULL() without MOLD=; always OK
}

template <typename T>
bool PointerAssignmentChecker::Check(const evaluate::FunctionRef<T> &f) {
  std::string funcName;
  const auto *symbol{f.proc().GetSymbol()};
  if (symbol) {
    funcName = symbol->name().ToString();
  } else if (const auto *intrinsic{f.proc().GetSpecificIntrinsic()}) {
    funcName = intrinsic->name;
  }
  auto proc{Procedure::Characterize(f.proc(), foldingContext_)};
  if (!proc) {
    return false;
  }
  std::optional<MessageFixedText> msg;
  const auto &funcResult{proc->functionResult}; // C1025
  if (!funcResult) {
    msg = "%s is associated with the non-existent result of reference to"
          " procedure"_err_en_US;
  } else if (CharacterizeProcedure()) {
    // Shouldn't be here in this function unless lhs is an object pointer.
    msg = "Procedure %s is associated with the result of a reference to"
          " function '%s' that does not return a procedure pointer"_err_en_US;
  } else if (funcResult->IsProcedurePointer()) {
    msg = "Object %s is associated with the result of a reference to"
          " function '%s' that is a procedure pointer"_err_en_US;
  } else if (!funcResult->attrs.test(FunctionResult::Attr::Pointer)) {
    msg = "%s is associated with the result of a reference to function '%s'"
          " that is a not a pointer"_err_en_US;
  } else if (isContiguous_ &&
      !funcResult->attrs.test(FunctionResult::Attr::Contiguous)) {
    msg = "CONTIGUOUS %s is associated with the result of reference to"
          " function '%s' that is not contiguous"_err_en_US;
  } else if (lhsType_) {
    const auto *frTypeAndShape{funcResult->GetTypeAndShape()};
    CHECK(frTypeAndShape);
    if (!lhsType_->IsCompatibleWith(foldingContext_.messages(), *frTypeAndShape,
            "pointer", "function result",
            /*omitShapeConformanceCheck=*/isBoundsRemapping_ || isAssumedRank_,
            evaluate::CheckConformanceFlags::BothDeferredShape)) {
      return false; // IsCompatibleWith() emitted message
    }
  }
  if (msg) {
    auto restorer{common::ScopedSet(lhs_, symbol)};
    Say(*msg, description_, funcName);
    return false;
  }
  return true;
}

template <typename T>
bool PointerAssignmentChecker::Check(const evaluate::Designator<T> &d) {
  const Symbol *last{d.GetLastSymbol()};
  const Symbol *base{d.GetBaseObject().symbol()};
  if (!last || !base) {
    // P => "character literal"(1:3)
    Say("Pointer target is not a named entity"_err_en_US);
    return false;
  }
  std::optional<std::variant<MessageFixedText, MessageFormattedText>> msg;
  if (CharacterizeProcedure()) {
    // Shouldn't be here in this function unless lhs is an object pointer.
    msg = "In assignment to procedure %s, the target is not a procedure or"
          " procedure pointer"_err_en_US;
  } else if (!evaluate::GetLastTarget(GetSymbolVector(d))) { // C1025
    msg = "In assignment to object %s, the target '%s' is not an object with"
          " POINTER or TARGET attributes"_err_en_US;
  } else if (auto rhsType{TypeAndShape::Characterize(d, foldingContext_)}) {
    if (!lhsType_) {
      msg = "%s associated with object '%s' with incompatible type or"
            " shape"_err_en_US;
    } else if (rhsType->corank() > 0 &&
        (isVolatile_ != last->attrs().test(Attr::VOLATILE))) { // C1020
      // TODO: what if A is VOLATILE in A%B%C?  need a better test here
      if (isVolatile_) {
        msg = "Pointer may not be VOLATILE when target is a"
              " non-VOLATILE coarray"_err_en_US;
      } else {
        msg = "Pointer must be VOLATILE when target is a"
              " VOLATILE coarray"_err_en_US;
      }
    } else if (rhsType->type().IsUnlimitedPolymorphic()) {
      if (!LhsOkForUnlimitedPoly()) {
        msg = "Pointer type must be unlimited polymorphic or non-extensible"
              " derived type when target is unlimited polymorphic"_err_en_US;
      }
    } else {
      if (!lhsType_->type().IsTkLenCompatibleWith(rhsType->type())) {
        msg = MessageFormattedText{
            "Target type %s is not compatible with pointer type %s"_err_en_US,
            rhsType->type().AsFortran(), lhsType_->type().AsFortran()};

      } else if (!isBoundsRemapping_ &&
          !lhsType_->attrs().test(TypeAndShape::Attr::AssumedRank)) {
        int lhsRank{evaluate::GetRank(lhsType_->shape())};
        int rhsRank{evaluate::GetRank(rhsType->shape())};
        if (lhsRank != rhsRank) {
          msg = MessageFormattedText{
              "Pointer has rank %d but target has rank %d"_err_en_US, lhsRank,
              rhsRank};
        }
      }
    }
  }
  if (msg) {
    auto restorer{common::ScopedSet(lhs_, last)};
    if (auto *m{std::get_if<MessageFixedText>(&*msg)}) {
      std::string buf;
      llvm::raw_string_ostream ss{buf};
      d.AsFortran(ss);
      Say(*m, description_, ss.str());
    } else {
      Say(std::get<MessageFormattedText>(*msg));
    }
    return false;
  }
  return true;
}

// Common handling for procedure pointer right-hand sides
bool PointerAssignmentChecker::Check(parser::CharBlock rhsName, bool isCall,
    const Procedure *rhsProcedure,
    const evaluate::SpecificIntrinsic *specific) {
  std::string whyNot;
  std::optional<std::string> warning;
  CharacterizeProcedure();
  if (std::optional<MessageFixedText> msg{evaluate::CheckProcCompatibility(
          isCall, procedure_, rhsProcedure, specific, whyNot, warning)}) {
    Say(std::move(*msg), description_, rhsName, whyNot);
    return false;
  }
  if (context_.ShouldWarn(common::UsageWarning::ProcDummyArgShapes) &&
      warning) {
    Say("%s and %s may not be completely compatible procedures: %s"_warn_en_US,
        description_, rhsName, std::move(*warning));
  }
  return true;
}

bool PointerAssignmentChecker::Check(const evaluate::ProcedureDesignator &d) {
  const Symbol *symbol{d.GetSymbol()};
  if (symbol) {
    if (const auto *subp{
            symbol->GetUltimate().detailsIf<SubprogramDetails>()}) {
      if (subp->stmtFunction()) {
        evaluate::SayWithDeclaration(foldingContext_.messages(), *symbol,
            "Statement function '%s' may not be the target of a pointer assignment"_err_en_US,
            symbol->name());
        return false;
      }
    } else if (symbol->has<ProcBindingDetails>() &&
        context_.ShouldWarn(common::LanguageFeature::BindingAsProcedure)) {
      evaluate::SayWithDeclaration(foldingContext_.messages(), *symbol,
          "Procedure binding '%s' used as target of a pointer assignment"_port_en_US,
          symbol->name());
    }
  }
  if (auto chars{Procedure::Characterize(d, foldingContext_)}) {
    // Disregard the elemental attribute of RHS intrinsics.
    if (symbol && symbol->GetUltimate().attrs().test(Attr::INTRINSIC)) {
      chars->attrs.reset(Procedure::Attr::Elemental);
    }
    return Check(d.GetName(), false, &*chars, d.GetSpecificIntrinsic());
  } else {
    return Check(d.GetName(), false);
  }
}

bool PointerAssignmentChecker::Check(const evaluate::ProcedureRef &ref) {
  auto chars{Procedure::Characterize(ref, foldingContext_)};
  return Check(ref.proc().GetName(), true, common::GetPtrFromOptional(chars));
}

// The target can be unlimited polymorphic if the pointer is, or if it is
// a non-extensible derived type.
bool PointerAssignmentChecker::LhsOkForUnlimitedPoly() const {
  const auto &type{lhsType_->type()};
  if (type.category() != TypeCategory::Derived || type.IsAssumedType()) {
    return false;
  } else if (type.IsUnlimitedPolymorphic()) {
    return true;
  } else {
    return !IsExtensibleType(&type.GetDerivedTypeSpec());
  }
}

template <typename... A>
parser::Message *PointerAssignmentChecker::Say(A &&...x) {
  auto *msg{foldingContext_.messages().Say(std::forward<A>(x)...)};
  if (msg) {
    if (lhs_) {
      return evaluate::AttachDeclaration(msg, *lhs_);
    }
    if (!source_.empty()) {
      msg->Attach(source_, "Declaration of %s"_en_US, description_);
    }
  }
  return msg;
}

// Verify that any bounds on the LHS of a pointer assignment are valid.
// Return true if it is a bound-remapping so we can perform further checks.
static bool CheckPointerBounds(
    evaluate::FoldingContext &context, const evaluate::Assignment &assignment) {
  auto &messages{context.messages()};
  const SomeExpr &lhs{assignment.lhs};
  const SomeExpr &rhs{assignment.rhs};
  bool isBoundsRemapping{false};
  std::size_t numBounds{common::visit(
      common::visitors{
          [&](const evaluate::Assignment::BoundsSpec &bounds) {
            return bounds.size();
          },
          [&](const evaluate::Assignment::BoundsRemapping &bounds) {
            isBoundsRemapping = true;
            evaluate::ExtentExpr lhsSizeExpr{1};
            for (const auto &bound : bounds) {
              lhsSizeExpr = std::move(lhsSizeExpr) *
                  (common::Clone(bound.second) - common::Clone(bound.first) +
                      evaluate::ExtentExpr{1});
            }
            if (std::optional<std::int64_t> lhsSize{evaluate::ToInt64(
                    evaluate::Fold(context, std::move(lhsSizeExpr)))}) {
              if (auto shape{evaluate::GetShape(context, rhs)}) {
                if (std::optional<std::int64_t> rhsSize{
                        evaluate::ToInt64(evaluate::Fold(
                            context, evaluate::GetSize(std::move(*shape))))}) {
                  if (*lhsSize > *rhsSize) {
                    messages.Say(
                        "Pointer bounds require %d elements but target has"
                        " only %d"_err_en_US,
                        *lhsSize, *rhsSize); // 10.2.2.3(9)
                  }
                }
              }
            }
            return bounds.size();
          },
          [](const auto &) -> std::size_t {
            DIE("not valid for pointer assignment");
          },
      },
      assignment.u)};
  if (numBounds > 0) {
    if (lhs.Rank() != static_cast<int>(numBounds)) {
      messages.Say("Pointer '%s' has rank %d but the number of bounds specified"
                   " is %d"_err_en_US,
          lhs.AsFortran(), lhs.Rank(), numBounds); // C1018
    }
  }
  if (isBoundsRemapping && rhs.Rank() != 1 &&
      !evaluate::IsSimplyContiguous(rhs, context)) {
    messages.Say("Pointer bounds remapping target must have rank 1 or be"
                 " simply contiguous"_err_en_US); // 10.2.2.3(9)
  }
  return isBoundsRemapping;
}

bool CheckPointerAssignment(SemanticsContext &context,
    const evaluate::Assignment &assignment, const Scope &scope) {
  return CheckPointerAssignment(context, assignment.lhs, assignment.rhs, scope,
      CheckPointerBounds(context.foldingContext(), assignment),
      /*isAssumedRank=*/false);
}

bool CheckPointerAssignment(SemanticsContext &context, const SomeExpr &lhs,
    const SomeExpr &rhs, const Scope &scope, bool isBoundsRemapping,
    bool isAssumedRank) {
  const Symbol *pointer{GetLastSymbol(lhs)};
  if (!pointer) {
    return false; // error was reported
  }
  PointerAssignmentChecker checker{context, scope, *pointer};
  checker.set_isBoundsRemapping(isBoundsRemapping);
  checker.set_isAssumedRank(isAssumedRank);
  bool lhsOk{checker.CheckLeftHandSide(lhs)};
  bool rhsOk{checker.Check(rhs)};
  return lhsOk && rhsOk; // don't short-circuit
}

bool CheckStructConstructorPointerComponent(SemanticsContext &context,
    const Symbol &lhs, const SomeExpr &rhs, const Scope &scope) {
  return PointerAssignmentChecker{context, scope, lhs}
      .set_pointerComponentLHS(&lhs)
      .Check(rhs);
}

bool CheckPointerAssignment(SemanticsContext &context, parser::CharBlock source,
    const std::string &description, const DummyDataObject &lhs,
    const SomeExpr &rhs, const Scope &scope, bool isAssumedRank) {
  return PointerAssignmentChecker{context, scope, source, description}
      .set_lhsType(common::Clone(lhs.type))
      .set_isContiguous(lhs.attrs.test(DummyDataObject::Attr::Contiguous))
      .set_isVolatile(lhs.attrs.test(DummyDataObject::Attr::Volatile))
      .set_isAssumedRank(isAssumedRank)
      .Check(rhs);
}

bool CheckInitialDataPointerTarget(SemanticsContext &context,
    const SomeExpr &pointer, const SomeExpr &init, const Scope &scope) {
  return evaluate::IsInitialDataTarget(
             init, &context.foldingContext().messages()) &&
      CheckPointerAssignment(context, pointer, init, scope,
          /*isBoundsRemapping=*/false,
          /*isAssumedRank=*/false);
}

} // namespace Fortran::semantics
