//===-- runtime/assign.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 "flang/Runtime/assign.h"
#include "assign-impl.h"
#include "derived.h"
#include "stat.h"
#include "terminator.h"
#include "tools.h"
#include "type-info.h"
#include "flang/Runtime/descriptor.h"

namespace Fortran::runtime {

enum AssignFlags {
  NoAssignFlags = 0,
  MaybeReallocate = 1 << 0,
  NeedFinalization = 1 << 1,
  CanBeDefinedAssignment = 1 << 2,
  ComponentCanBeDefinedAssignment = 1 << 3,
  ExplicitLengthCharacterLHS = 1 << 4,
  PolymorphicLHS = 1 << 5,
  DeallocateLHS = 1 << 6
};

// Predicate: is the left-hand side of an assignment an allocated allocatable
// that must be deallocated?
static inline RT_API_ATTRS bool MustDeallocateLHS(
    Descriptor &to, const Descriptor &from, Terminator &terminator, int flags) {
  // Top-level assignments to allocatable variables (*not* components)
  // may first deallocate existing content if there's about to be a
  // change in type or shape; see F'2018 10.2.1.3(3).
  if (!(flags & MaybeReallocate)) {
    return false;
  }
  if (!to.IsAllocatable() || !to.IsAllocated()) {
    return false;
  }
  if (to.type() != from.type()) {
    return true;
  }
  if (!(flags & ExplicitLengthCharacterLHS) && to.type().IsCharacter() &&
      to.ElementBytes() != from.ElementBytes()) {
    return true;
  }
  if (flags & PolymorphicLHS) {
    DescriptorAddendum *toAddendum{to.Addendum()};
    const typeInfo::DerivedType *toDerived{
        toAddendum ? toAddendum->derivedType() : nullptr};
    const DescriptorAddendum *fromAddendum{from.Addendum()};
    const typeInfo::DerivedType *fromDerived{
        fromAddendum ? fromAddendum->derivedType() : nullptr};
    if (toDerived != fromDerived) {
      return true;
    }
    if (fromDerived) {
      // Distinct LEN parameters? Deallocate
      std::size_t lenParms{fromDerived->LenParameters()};
      for (std::size_t j{0}; j < lenParms; ++j) {
        if (toAddendum->LenParameterValue(j) !=
            fromAddendum->LenParameterValue(j)) {
          return true;
        }
      }
    }
  }
  if (from.rank() > 0) {
    // Distinct shape? Deallocate
    int rank{to.rank()};
    for (int j{0}; j < rank; ++j) {
      if (to.GetDimension(j).Extent() != from.GetDimension(j).Extent()) {
        return true;
      }
    }
  }
  return false;
}

// Utility: allocate the allocatable left-hand side, either because it was
// originally deallocated or because it required reallocation
static RT_API_ATTRS int AllocateAssignmentLHS(
    Descriptor &to, const Descriptor &from, Terminator &terminator, int flags) {
  to.raw().type = from.raw().type;
  if (!(flags & ExplicitLengthCharacterLHS)) {
    to.raw().elem_len = from.ElementBytes();
  }
  const typeInfo::DerivedType *derived{nullptr};
  if (const DescriptorAddendum * fromAddendum{from.Addendum()}) {
    derived = fromAddendum->derivedType();
    if (DescriptorAddendum * toAddendum{to.Addendum()}) {
      toAddendum->set_derivedType(derived);
      std::size_t lenParms{derived ? derived->LenParameters() : 0};
      for (std::size_t j{0}; j < lenParms; ++j) {
        toAddendum->SetLenParameterValue(j, fromAddendum->LenParameterValue(j));
      }
    }
  }
  // subtle: leave bounds in place when "from" is scalar (10.2.1.3(3))
  int rank{from.rank()};
  auto stride{static_cast<SubscriptValue>(to.ElementBytes())};
  for (int j{0}; j < rank; ++j) {
    auto &toDim{to.GetDimension(j)};
    const auto &fromDim{from.GetDimension(j)};
    toDim.SetBounds(fromDim.LowerBound(), fromDim.UpperBound());
    toDim.SetByteStride(stride);
    stride *= toDim.Extent();
  }
  int result{ReturnError(terminator, to.Allocate())};
  if (result == StatOk && derived && !derived->noInitializationNeeded()) {
    result = ReturnError(terminator, Initialize(to, *derived, terminator));
  }
  return result;
}

// least <= 0, most >= 0
static RT_API_ATTRS void MaximalByteOffsetRange(
    const Descriptor &desc, std::int64_t &least, std::int64_t &most) {
  least = most = 0;
  if (desc.ElementBytes() == 0) {
    return;
  }
  int n{desc.raw().rank};
  for (int j{0}; j < n; ++j) {
    const auto &dim{desc.GetDimension(j)};
    auto extent{dim.Extent()};
    if (extent > 0) {
      auto sm{dim.ByteStride()};
      if (sm < 0) {
        least += (extent - 1) * sm;
      } else {
        most += (extent - 1) * sm;
      }
    }
  }
  most += desc.ElementBytes() - 1;
}

static inline RT_API_ATTRS bool RangesOverlap(const char *aStart,
    const char *aEnd, const char *bStart, const char *bEnd) {
  return aEnd >= bStart && bEnd >= aStart;
}

// Predicate: could the left-hand and right-hand sides of the assignment
// possibly overlap in memory?  Note that the descriptors themeselves
// are included in the test.
static RT_API_ATTRS bool MayAlias(const Descriptor &x, const Descriptor &y) {
  const char *xBase{x.OffsetElement()};
  const char *yBase{y.OffsetElement()};
  if (!xBase || !yBase) {
    return false; // not both allocated
  }
  const char *xDesc{reinterpret_cast<const char *>(&x)};
  const char *xDescLast{xDesc + x.SizeInBytes()};
  const char *yDesc{reinterpret_cast<const char *>(&y)};
  const char *yDescLast{yDesc + y.SizeInBytes()};
  std::int64_t xLeast, xMost, yLeast, yMost;
  MaximalByteOffsetRange(x, xLeast, xMost);
  MaximalByteOffsetRange(y, yLeast, yMost);
  if (RangesOverlap(xDesc, xDescLast, yBase + yLeast, yBase + yMost) ||
      RangesOverlap(yDesc, yDescLast, xBase + xLeast, xBase + xMost)) {
    // A descriptor overlaps with the storage described by the other;
    // this can arise when an allocatable or pointer component is
    // being assigned to/from.
    return true;
  }
  if (!RangesOverlap(
          xBase + xLeast, xBase + xMost, yBase + yLeast, yBase + yMost)) {
    return false; // no storage overlap
  }
  // TODO: check dimensions: if any is independent, return false
  return true;
}

static RT_API_ATTRS void DoScalarDefinedAssignment(const Descriptor &to,
    const Descriptor &from, const typeInfo::SpecialBinding &special) {
  bool toIsDesc{special.IsArgDescriptor(0)};
  bool fromIsDesc{special.IsArgDescriptor(1)};
  if (toIsDesc) {
    if (fromIsDesc) {
      auto *p{
          special.GetProc<void (*)(const Descriptor &, const Descriptor &)>()};
      p(to, from);
    } else {
      auto *p{special.GetProc<void (*)(const Descriptor &, void *)>()};
      p(to, from.raw().base_addr);
    }
  } else {
    if (fromIsDesc) {
      auto *p{special.GetProc<void (*)(void *, const Descriptor &)>()};
      p(to.raw().base_addr, from);
    } else {
      auto *p{special.GetProc<void (*)(void *, void *)>()};
      p(to.raw().base_addr, from.raw().base_addr);
    }
  }
}

static RT_API_ATTRS void DoElementalDefinedAssignment(const Descriptor &to,
    const Descriptor &from, const typeInfo::DerivedType &derived,
    const typeInfo::SpecialBinding &special) {
  SubscriptValue toAt[maxRank], fromAt[maxRank];
  to.GetLowerBounds(toAt);
  from.GetLowerBounds(fromAt);
  StaticDescriptor<maxRank, true, 8 /*?*/> statDesc[2];
  Descriptor &toElementDesc{statDesc[0].descriptor()};
  Descriptor &fromElementDesc{statDesc[1].descriptor()};
  toElementDesc.Establish(derived, nullptr, 0, nullptr, CFI_attribute_pointer);
  fromElementDesc.Establish(
      derived, nullptr, 0, nullptr, CFI_attribute_pointer);
  for (std::size_t toElements{to.Elements()}; toElements-- > 0;
       to.IncrementSubscripts(toAt), from.IncrementSubscripts(fromAt)) {
    toElementDesc.set_base_addr(to.Element<char>(toAt));
    fromElementDesc.set_base_addr(from.Element<char>(fromAt));
    DoScalarDefinedAssignment(toElementDesc, fromElementDesc, special);
  }
}

template <typename CHAR>
static RT_API_ATTRS void BlankPadCharacterAssignment(Descriptor &to,
    const Descriptor &from, SubscriptValue toAt[], SubscriptValue fromAt[],
    std::size_t elements, std::size_t toElementBytes,
    std::size_t fromElementBytes) {
  std::size_t padding{(toElementBytes - fromElementBytes) / sizeof(CHAR)};
  std::size_t copiedCharacters{fromElementBytes / sizeof(CHAR)};
  for (; elements-- > 0;
       to.IncrementSubscripts(toAt), from.IncrementSubscripts(fromAt)) {
    CHAR *p{to.Element<CHAR>(toAt)};
    Fortran::runtime::memmove(
        p, from.Element<std::add_const_t<CHAR>>(fromAt), fromElementBytes);
    p += copiedCharacters;
    for (auto n{padding}; n-- > 0;) {
      *p++ = CHAR{' '};
    }
  }
}

// Common implementation of assignments, both intrinsic assignments and
// those cases of polymorphic user-defined ASSIGNMENT(=) TBPs that could not
// be resolved in semantics.  Most assignment statements do not need any
// of the capabilities of this function -- but when the LHS is allocatable,
// the type might have a user-defined ASSIGNMENT(=), or the type might be
// finalizable, this function should be used.
// When "to" is not a whole allocatable, "from" is an array, and defined
// assignments are not used, "to" and "from" only need to have the same number
// of elements, but their shape need not to conform (the assignment is done in
// element sequence order). This facilitates some internal usages, like when
// dealing with array constructors.
RT_API_ATTRS static void Assign(
    Descriptor &to, const Descriptor &from, Terminator &terminator, int flags) {
  bool mustDeallocateLHS{(flags & DeallocateLHS) ||
      MustDeallocateLHS(to, from, terminator, flags)};
  DescriptorAddendum *toAddendum{to.Addendum()};
  const typeInfo::DerivedType *toDerived{
      toAddendum ? toAddendum->derivedType() : nullptr};
  if (toDerived && (flags & NeedFinalization) &&
      toDerived->noFinalizationNeeded()) {
    flags &= ~NeedFinalization;
  }
  std::size_t toElementBytes{to.ElementBytes()};
  std::size_t fromElementBytes{from.ElementBytes()};
  // The following lambda definition violates the conding style,
  // but cuda-11.8 nvcc hits an internal error with the brace initialization.
  auto isSimpleMemmove = [&]() {
    return !toDerived && to.rank() == from.rank() && to.IsContiguous() &&
        from.IsContiguous() && toElementBytes == fromElementBytes;
  };
  StaticDescriptor<maxRank, true, 10 /*?*/> deferredDeallocStatDesc;
  Descriptor *deferDeallocation{nullptr};
  if (MayAlias(to, from)) {
    if (mustDeallocateLHS) {
      deferDeallocation = &deferredDeallocStatDesc.descriptor();
      std::memcpy(deferDeallocation, &to, to.SizeInBytes());
      to.set_base_addr(nullptr);
    } else if (!isSimpleMemmove()) {
      // Handle LHS/RHS aliasing by copying RHS into a temp, then
      // recursively assigning from that temp.
      auto descBytes{from.SizeInBytes()};
      StaticDescriptor<maxRank, true, 16> staticDesc;
      Descriptor &newFrom{staticDesc.descriptor()};
      std::memcpy(&newFrom, &from, descBytes);
      // Pretend the temporary descriptor is for an ALLOCATABLE
      // entity, otherwise, the Deallocate() below will not
      // free the descriptor memory.
      newFrom.raw().attribute = CFI_attribute_allocatable;
      auto stat{ReturnError(terminator, newFrom.Allocate())};
      if (stat == StatOk) {
        if (HasDynamicComponent(from)) {
          // If 'from' has allocatable/automatic component, we cannot
          // just make a shallow copy of the descriptor member.
          // This will still leave data overlap in 'to' and 'newFrom'.
          // For example:
          //   type t
          //     character, allocatable :: c(:)
          //   end type t
          //   type(t) :: x(3)
          //   x(2:3) = x(1:2)
          // We have to make a deep copy into 'newFrom' in this case.
          RTNAME(AssignTemporary)
          (newFrom, from, terminator.sourceFileName(), terminator.sourceLine());
        } else {
          ShallowCopy(newFrom, from, true, from.IsContiguous());
        }
        Assign(to, newFrom, terminator,
            flags &
                (NeedFinalization | ComponentCanBeDefinedAssignment |
                    ExplicitLengthCharacterLHS | CanBeDefinedAssignment));
        newFrom.Deallocate();
      }
      return;
    }
  }
  if (to.IsAllocatable()) {
    if (mustDeallocateLHS) {
      if (deferDeallocation) {
        if ((flags & NeedFinalization) && toDerived) {
          Finalize(to, *toDerived, &terminator);
          flags &= ~NeedFinalization;
        } else if (toDerived && !toDerived->noDestructionNeeded()) {
          Destroy(to, /*finalize=*/false, *toDerived, &terminator);
        }
      } else {
        to.Destroy((flags & NeedFinalization) != 0, /*destroyPointers=*/false,
            &terminator);
        flags &= ~NeedFinalization;
      }
    } else if (to.rank() != from.rank() && !to.IsAllocated()) {
      terminator.Crash("Assign: mismatched ranks (%d != %d) in assignment to "
                       "unallocated allocatable",
          to.rank(), from.rank());
    }
    if (!to.IsAllocated()) {
      if (AllocateAssignmentLHS(to, from, terminator, flags) != StatOk) {
        return;
      }
      flags &= ~NeedFinalization;
      toElementBytes = to.ElementBytes(); // may have changed
    }
  }
  if (toDerived && (flags & CanBeDefinedAssignment)) {
    // Check for a user-defined assignment type-bound procedure;
    // see 10.2.1.4-5.  A user-defined assignment TBP defines all of
    // the semantics, including allocatable (re)allocation and any
    // finalization.
    //
    // Note that the aliasing and LHS (re)allocation handling above
    // needs to run even with CanBeDefinedAssignment flag, when
    // the Assign() is invoked recursively for component-per-component
    // assignments.
    if (to.rank() == 0) {
      if (const auto *special{toDerived->FindSpecialBinding(
              typeInfo::SpecialBinding::Which::ScalarAssignment)}) {
        return DoScalarDefinedAssignment(to, from, *special);
      }
    }
    if (const auto *special{toDerived->FindSpecialBinding(
            typeInfo::SpecialBinding::Which::ElementalAssignment)}) {
      return DoElementalDefinedAssignment(to, from, *toDerived, *special);
    }
  }
  SubscriptValue toAt[maxRank];
  to.GetLowerBounds(toAt);
  // Scalar expansion of the RHS is implied by using the same empty
  // subscript values on each (seemingly) elemental reference into
  // "from".
  SubscriptValue fromAt[maxRank];
  from.GetLowerBounds(fromAt);
  std::size_t toElements{to.Elements()};
  if (from.rank() > 0 && toElements != from.Elements()) {
    terminator.Crash("Assign: mismatching element counts in array assignment "
                     "(to %zd, from %zd)",
        toElements, from.Elements());
  }
  if (to.type() != from.type()) {
    terminator.Crash("Assign: mismatching types (to code %d != from code %d)",
        to.type().raw(), from.type().raw());
  }
  if (toElementBytes > fromElementBytes && !to.type().IsCharacter()) {
    terminator.Crash("Assign: mismatching non-character element sizes (to %zd "
                     "bytes != from %zd bytes)",
        toElementBytes, fromElementBytes);
  }
  if (const typeInfo::DerivedType *
      updatedToDerived{toAddendum ? toAddendum->derivedType() : nullptr}) {
    // Derived type intrinsic assignment, which is componentwise and elementwise
    // for all components, including parent components (10.2.1.2-3).
    // The target is first finalized if still necessary (7.5.6.3(1))
    if (flags & NeedFinalization) {
      Finalize(to, *updatedToDerived, &terminator);
    } else if (updatedToDerived && !updatedToDerived->noDestructionNeeded()) {
      Destroy(to, /*finalize=*/false, *updatedToDerived, &terminator);
    }
    // Copy the data components (incl. the parent) first.
    const Descriptor &componentDesc{updatedToDerived->component()};
    std::size_t numComponents{componentDesc.Elements()};
    for (std::size_t j{0}; j < toElements;
         ++j, to.IncrementSubscripts(toAt), from.IncrementSubscripts(fromAt)) {
      for (std::size_t k{0}; k < numComponents; ++k) {
        const auto &comp{
            *componentDesc.ZeroBasedIndexedElement<typeInfo::Component>(
                k)}; // TODO: exploit contiguity here
        // Use PolymorphicLHS for components so that the right things happen
        // when the components are polymorphic; when they're not, they're both
        // not, and their declared types will match.
        int nestedFlags{MaybeReallocate | PolymorphicLHS};
        if (flags & ComponentCanBeDefinedAssignment) {
          nestedFlags |=
              CanBeDefinedAssignment | ComponentCanBeDefinedAssignment;
        }
        switch (comp.genre()) {
        case typeInfo::Component::Genre::Data:
          if (comp.category() == TypeCategory::Derived) {
            StaticDescriptor<maxRank, true, 10 /*?*/> statDesc[2];
            Descriptor &toCompDesc{statDesc[0].descriptor()};
            Descriptor &fromCompDesc{statDesc[1].descriptor()};
            comp.CreatePointerDescriptor(toCompDesc, to, terminator, toAt);
            comp.CreatePointerDescriptor(
                fromCompDesc, from, terminator, fromAt);
            Assign(toCompDesc, fromCompDesc, terminator, nestedFlags);
          } else { // Component has intrinsic type; simply copy raw bytes
            std::size_t componentByteSize{comp.SizeInBytes(to)};
            Fortran::runtime::memmove(to.Element<char>(toAt) + comp.offset(),
                from.Element<const char>(fromAt) + comp.offset(),
                componentByteSize);
          }
          break;
        case typeInfo::Component::Genre::Pointer: {
          std::size_t componentByteSize{comp.SizeInBytes(to)};
          Fortran::runtime::memmove(to.Element<char>(toAt) + comp.offset(),
              from.Element<const char>(fromAt) + comp.offset(),
              componentByteSize);
        } break;
        case typeInfo::Component::Genre::Allocatable:
        case typeInfo::Component::Genre::Automatic: {
          auto *toDesc{reinterpret_cast<Descriptor *>(
              to.Element<char>(toAt) + comp.offset())};
          const auto *fromDesc{reinterpret_cast<const Descriptor *>(
              from.Element<char>(fromAt) + comp.offset())};
          // Allocatable components of the LHS are unconditionally
          // deallocated before assignment (F'2018 10.2.1.3(13)(1)),
          // unlike a "top-level" assignment to a variable, where
          // deallocation is optional.
          //
          // Be careful not to destroy/reallocate the LHS, if there is
          // overlap between LHS and RHS (it seems that partial overlap
          // is not possible, though).
          // Invoke Assign() recursively to deal with potential aliasing.
          if (toDesc->IsAllocatable()) {
            if (!fromDesc->IsAllocated()) {
              // No aliasing.
              //
              // If to is not allocated, the Destroy() call is a no-op.
              // This is just a shortcut, because the recursive Assign()
              // below would initiate the destruction for to.
              // No finalization is required.
              toDesc->Destroy(
                  /*finalize=*/false, /*destroyPointers=*/false, &terminator);
              continue; // F'2018 10.2.1.3(13)(2)
            }
          }
          // Force LHS deallocation with DeallocateLHS flag.
          // The actual deallocation may be avoided, if the existing
          // location can be reoccupied.
          Assign(*toDesc, *fromDesc, terminator, nestedFlags | DeallocateLHS);
        } break;
        }
      }
      // Copy procedure pointer components
      const Descriptor &procPtrDesc{updatedToDerived->procPtr()};
      std::size_t numProcPtrs{procPtrDesc.Elements()};
      for (std::size_t k{0}; k < numProcPtrs; ++k) {
        const auto &procPtr{
            *procPtrDesc.ZeroBasedIndexedElement<typeInfo::ProcPtrComponent>(
                k)};
        Fortran::runtime::memmove(to.Element<char>(toAt) + procPtr.offset,
            from.Element<const char>(fromAt) + procPtr.offset,
            sizeof(typeInfo::ProcedurePointer));
      }
    }
  } else { // intrinsic type, intrinsic assignment
    if (isSimpleMemmove()) {
      Fortran::runtime::memmove(to.raw().base_addr, from.raw().base_addr,
          toElements * toElementBytes);
    } else if (toElementBytes > fromElementBytes) { // blank padding
      switch (to.type().raw()) {
      case CFI_type_signed_char:
      case CFI_type_char:
        BlankPadCharacterAssignment<char>(to, from, toAt, fromAt, toElements,
            toElementBytes, fromElementBytes);
        break;
      case CFI_type_char16_t:
        BlankPadCharacterAssignment<char16_t>(to, from, toAt, fromAt,
            toElements, toElementBytes, fromElementBytes);
        break;
      case CFI_type_char32_t:
        BlankPadCharacterAssignment<char32_t>(to, from, toAt, fromAt,
            toElements, toElementBytes, fromElementBytes);
        break;
      default:
        terminator.Crash("unexpected type code %d in blank padded Assign()",
            to.type().raw());
      }
    } else { // elemental copies, possibly with character truncation
      for (std::size_t n{toElements}; n-- > 0;
           to.IncrementSubscripts(toAt), from.IncrementSubscripts(fromAt)) {
        Fortran::runtime::memmove(to.Element<char>(toAt),
            from.Element<const char>(fromAt), toElementBytes);
      }
    }
  }
  if (deferDeallocation) {
    // deferDeallocation is used only when LHS is an allocatable.
    // The finalization has already been run for it.
    deferDeallocation->Destroy(
        /*finalize=*/false, /*destroyPointers=*/false, &terminator);
  }
}

RT_OFFLOAD_API_GROUP_BEGIN

RT_API_ATTRS void DoFromSourceAssign(
    Descriptor &alloc, const Descriptor &source, Terminator &terminator) {
  if (alloc.rank() > 0 && source.rank() == 0) {
    // The value of each element of allocate object becomes the value of source.
    DescriptorAddendum *allocAddendum{alloc.Addendum()};
    const typeInfo::DerivedType *allocDerived{
        allocAddendum ? allocAddendum->derivedType() : nullptr};
    SubscriptValue allocAt[maxRank];
    alloc.GetLowerBounds(allocAt);
    if (allocDerived) {
      for (std::size_t n{alloc.Elements()}; n-- > 0;
           alloc.IncrementSubscripts(allocAt)) {
        Descriptor allocElement{*Descriptor::Create(*allocDerived,
            reinterpret_cast<void *>(alloc.Element<char>(allocAt)), 0)};
        Assign(allocElement, source, terminator, NoAssignFlags);
      }
    } else { // intrinsic type
      for (std::size_t n{alloc.Elements()}; n-- > 0;
           alloc.IncrementSubscripts(allocAt)) {
        Fortran::runtime::memmove(alloc.Element<char>(allocAt),
            source.raw().base_addr, alloc.ElementBytes());
      }
    }
  } else {
    Assign(alloc, source, terminator, NoAssignFlags);
  }
}

RT_OFFLOAD_API_GROUP_END

extern "C" {
RT_EXT_API_GROUP_BEGIN

void RTDEF(Assign)(Descriptor &to, const Descriptor &from,
    const char *sourceFile, int sourceLine) {
  Terminator terminator{sourceFile, sourceLine};
  // All top-level defined assignments can be recognized in semantics and
  // will have been already been converted to calls, so don't check for
  // defined assignment apart from components.
  Assign(to, from, terminator,
      MaybeReallocate | NeedFinalization | ComponentCanBeDefinedAssignment);
}

void RTDEF(AssignTemporary)(Descriptor &to, const Descriptor &from,
    const char *sourceFile, int sourceLine) {
  Terminator terminator{sourceFile, sourceLine};
  // Initialize the "to" if it is of derived type that needs initialization.
  if (const DescriptorAddendum * addendum{to.Addendum()}) {
    if (const auto *derived{addendum->derivedType()}) {
      // Do not invoke the initialization, if the descriptor is unallocated.
      // AssignTemporary() is used for component-by-component assignments,
      // for example, for structure constructors. This means that the LHS
      // may be an allocatable component with unallocated status.
      // The initialization will just fail in this case. By skipping
      // the initialization we let Assign() automatically allocate
      // and initialize the component according to the RHS.
      // So we only need to initialize the LHS here if it is allocated.
      // Note that initializing already initialized entity has no visible
      // effect, though, it is assumed that the compiler does not initialize
      // the temporary and leaves the initialization to this runtime code.
      if (!derived->noInitializationNeeded() && to.IsAllocated()) {
        if (ReturnError(terminator, Initialize(to, *derived, terminator)) !=
            StatOk) {
          return;
        }
      }
    }
  }

  Assign(to, from, terminator, PolymorphicLHS);
}

void RTDEF(CopyOutAssign)(Descriptor &to, const Descriptor &from,
    bool skipToInit, const char *sourceFile, int sourceLine) {
  Terminator terminator{sourceFile, sourceLine};
  // Initialize the "to" if it is of derived type that needs initialization.
  if (!skipToInit) {
    if (const DescriptorAddendum * addendum{to.Addendum()}) {
      if (const auto *derived{addendum->derivedType()}) {
        if (!derived->noInitializationNeeded()) {
          if (ReturnError(terminator, Initialize(to, *derived, terminator)) !=
              StatOk) {
            return;
          }
        }
      }
    }
  }

  // Copyout from the temporary must not cause any finalizations
  // for LHS.
  Assign(to, from, terminator, NoAssignFlags);
}

void RTDEF(AssignExplicitLengthCharacter)(Descriptor &to,
    const Descriptor &from, const char *sourceFile, int sourceLine) {
  Terminator terminator{sourceFile, sourceLine};
  Assign(to, from, terminator,
      MaybeReallocate | NeedFinalization | ComponentCanBeDefinedAssignment |
          ExplicitLengthCharacterLHS);
}

void RTDEF(AssignPolymorphic)(Descriptor &to, const Descriptor &from,
    const char *sourceFile, int sourceLine) {
  Terminator terminator{sourceFile, sourceLine};
  Assign(to, from, terminator,
      MaybeReallocate | NeedFinalization | ComponentCanBeDefinedAssignment |
          PolymorphicLHS);
}

RT_EXT_API_GROUP_END
} // extern "C"
} // namespace Fortran::runtime
