diff options
Diffstat (limited to 'flang-rt/lib/runtime/assign.cpp')
| -rw-r--r-- | flang-rt/lib/runtime/assign.cpp | 37 |
1 files changed, 26 insertions, 11 deletions
diff --git a/flang-rt/lib/runtime/assign.cpp b/flang-rt/lib/runtime/assign.cpp index 2c29a98d5a5c..b70182ccb317 100644 --- a/flang-rt/lib/runtime/assign.cpp +++ b/flang-rt/lib/runtime/assign.cpp @@ -244,7 +244,7 @@ static RT_API_ATTRS void BlankPadCharacterAssignment(Descriptor &to, for (; elements-- > 0; to.IncrementSubscripts(toAt), from.IncrementSubscripts(fromAt)) { CHAR *p{to.Element<CHAR>(toAt)}; - Fortran::runtime::memmove( + runtime::memmove( p, from.Element<std::add_const_t<CHAR>>(fromAt), fromElementBytes); p += copiedCharacters; for (auto n{padding}; n-- > 0;) { @@ -288,7 +288,7 @@ RT_API_ATTRS int AssignTicket::Begin(WorkQueue &workQueue) { if (mustDeallocateLHS) { // Convert the LHS into a temporary, then make it look deallocated. toDeallocate_ = &tempDescriptor_.descriptor(); - std::memcpy( + runtime::memcpy( reinterpret_cast<void *>(toDeallocate_), &to_, to_.SizeInBytes()); to_.set_base_addr(nullptr); if (toDerived_ && (flags_ & NeedFinalization)) { @@ -307,7 +307,7 @@ RT_API_ATTRS int AssignTicket::Begin(WorkQueue &workQueue) { auto descBytes{from_->SizeInBytes()}; Descriptor &newFrom{tempDescriptor_.descriptor()}; persist_ = true; // tempDescriptor_ state must outlive child tickets - std::memcpy(reinterpret_cast<void *>(&newFrom), from_, descBytes); + runtime::memcpy(reinterpret_cast<void *>(&newFrom), from_, descBytes); // Pretend the temporary descriptor is for an ALLOCATABLE // entity, otherwise, the Deallocate() below will not // free the descriptor memory. @@ -648,7 +648,8 @@ RT_API_ATTRS int DerivedAssignTicket<IS_COMPONENTWISE>::Continue( } } break; - case typeInfo::Component::Genre::Pointer: { + case typeInfo::Component::Genre::Pointer: + case typeInfo::Component::Genre::PointerDevice: { std::size_t componentByteSize{ this->component_->SizeInBytes(this->instance_)}; if (IS_COMPONENTWISE && toIsContiguous_ && fromIsContiguous_) { @@ -680,6 +681,7 @@ RT_API_ATTRS int DerivedAssignTicket<IS_COMPONENTWISE>::Continue( } } break; case typeInfo::Component::Genre::Allocatable: + case typeInfo::Component::Genre::AllocatableDevice: case typeInfo::Component::Genre::Automatic: { auto *toDesc{reinterpret_cast<Descriptor *>( this->instance_.template Element<char>(this->subscripts_) + @@ -743,22 +745,35 @@ RT_API_ATTRS void DoFromSourceAssign(Descriptor &alloc, 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) { + std::size_t allocElementBytes{alloc.ElementBytes()}; + if (const typeInfo::DerivedType *allocDerived{ + allocAddendum ? allocAddendum->derivedType() : nullptr}) { + // Handle derived type or short character source for (std::size_t n{alloc.InlineElements()}; n-- > 0; alloc.IncrementSubscripts(allocAt)) { - Descriptor allocElement{*Descriptor::Create(*allocDerived, - reinterpret_cast<void *>(alloc.Element<char>(allocAt)), 0)}; + StaticDescriptor<maxRank, true, 8 /*?*/> statDesc; + Descriptor &allocElement{statDesc.descriptor()}; + allocElement.Establish(*allocDerived, + reinterpret_cast<void *>(alloc.Element<char>(allocAt)), 0); Assign(allocElement, source, terminator, NoAssignFlags, memmoveFct); } - } else { // intrinsic type + } else if (allocElementBytes > source.ElementBytes()) { + // Scalar expansion of short character source + for (std::size_t n{alloc.InlineElements()}; n-- > 0; + alloc.IncrementSubscripts(allocAt)) { + StaticDescriptor<maxRank, true, 8 /*?*/> statDesc; + Descriptor &allocElement{statDesc.descriptor()}; + allocElement.Establish(source.type(), allocElementBytes, + reinterpret_cast<void *>(alloc.Element<char>(allocAt)), 0); + Assign(allocElement, source, terminator, NoAssignFlags, memmoveFct); + } + } else { // intrinsic type scalar expansion, same data size for (std::size_t n{alloc.InlineElements()}; n-- > 0; alloc.IncrementSubscripts(allocAt)) { memmoveFct(alloc.Element<char>(allocAt), source.raw().base_addr, - alloc.ElementBytes()); + allocElementBytes); } } } else { |
