1717
1818namespace Fortran ::runtime {
1919
20- enum AssignFlags {
21- NoAssignFlags = 0 ,
22- MaybeReallocate = 1 << 0 ,
23- NeedFinalization = 1 << 1 ,
24- CanBeDefinedAssignment = 1 << 2 ,
25- ComponentCanBeDefinedAssignment = 1 << 3 ,
26- ExplicitLengthCharacterLHS = 1 << 4 ,
27- PolymorphicLHS = 1 << 5 ,
28- DeallocateLHS = 1 << 6
29- };
30-
3120// Predicate: is the left-hand side of an assignment an allocated allocatable
3221// that must be deallocated?
3322static inline RT_API_ATTRS bool MustDeallocateLHS (
@@ -250,8 +239,8 @@ static RT_API_ATTRS void BlankPadCharacterAssignment(Descriptor &to,
250239// of elements, but their shape need not to conform (the assignment is done in
251240// element sequence order). This facilitates some internal usages, like when
252241// dealing with array constructors.
253- RT_API_ATTRS static void Assign (
254- Descriptor &to, const Descriptor &from, Terminator &terminator, int flags) {
242+ RT_API_ATTRS void Assign (Descriptor &to, const Descriptor &from,
243+ Terminator &terminator, int flags, MemmoveFct memmoveFct ) {
255244 bool mustDeallocateLHS{(flags & DeallocateLHS) ||
256245 MustDeallocateLHS (to, from, terminator, flags)};
257246 DescriptorAddendum *toAddendum{to.Addendum ()};
@@ -423,14 +412,14 @@ RT_API_ATTRS static void Assign(
423412 Assign (toCompDesc, fromCompDesc, terminator, nestedFlags);
424413 } else { // Component has intrinsic type; simply copy raw bytes
425414 std::size_t componentByteSize{comp.SizeInBytes (to)};
426- Fortran::runtime::memmove (to.Element <char >(toAt) + comp.offset (),
415+ memmoveFct (to.Element <char >(toAt) + comp.offset (),
427416 from.Element <const char >(fromAt) + comp.offset (),
428417 componentByteSize);
429418 }
430419 break ;
431420 case typeInfo::Component::Genre::Pointer: {
432421 std::size_t componentByteSize{comp.SizeInBytes (to)};
433- Fortran::runtime::memmove (to.Element <char >(toAt) + comp.offset (),
422+ memmoveFct (to.Element <char >(toAt) + comp.offset (),
434423 from.Element <const char >(fromAt) + comp.offset (),
435424 componentByteSize);
436425 } break ;
@@ -476,14 +465,14 @@ RT_API_ATTRS static void Assign(
476465 const auto &procPtr{
477466 *procPtrDesc.ZeroBasedIndexedElement <typeInfo::ProcPtrComponent>(
478467 k)};
479- Fortran::runtime::memmove (to.Element <char >(toAt) + procPtr.offset ,
468+ memmoveFct (to.Element <char >(toAt) + procPtr.offset ,
480469 from.Element <const char >(fromAt) + procPtr.offset ,
481470 sizeof (typeInfo::ProcedurePointer));
482471 }
483472 }
484473 } else { // intrinsic type, intrinsic assignment
485474 if (isSimpleMemmove ()) {
486- Fortran::runtime::memmove (to.raw ().base_addr , from.raw ().base_addr ,
475+ memmoveFct (to.raw ().base_addr , from.raw ().base_addr ,
487476 toElements * toElementBytes);
488477 } else if (toElementBytes > fromElementBytes) { // blank padding
489478 switch (to.type ().raw ()) {
@@ -507,8 +496,8 @@ RT_API_ATTRS static void Assign(
507496 } else { // elemental copies, possibly with character truncation
508497 for (std::size_t n{toElements}; n-- > 0 ;
509498 to.IncrementSubscripts (toAt), from.IncrementSubscripts (fromAt)) {
510- Fortran::runtime::memmove (to.Element <char >(toAt),
511- from. Element < const char >(fromAt), toElementBytes);
499+ memmoveFct (to.Element <char >(toAt), from. Element < const char >(fromAt ),
500+ toElementBytes);
512501 }
513502 }
514503 }
0 commit comments