summaryrefslogtreecommitdiff
path: root/flang-rt/lib/runtime/assign.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'flang-rt/lib/runtime/assign.cpp')
-rw-r--r--flang-rt/lib/runtime/assign.cpp37
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 {