Skip to content

Commit 6111c9c

Browse files
authored
[flang][runtime] Handle ALLOCATE(..., short SOURCE=) (#155715)
Ensure that blank padding takes place when a fixed-length character allocatable is allocated with a short SOURCE= specifier. While here, clean up DoFromSourceAssign() so that it uses a temporary descriptor on the stack rather than allocating one from the heap. Fixes #155703.
1 parent 9005ae5 commit 6111c9c

File tree

2 files changed

+23
-11
lines changed

2 files changed

+23
-11
lines changed

flang-rt/lib/runtime/assign.cpp

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ static RT_API_ATTRS void BlankPadCharacterAssignment(Descriptor &to,
244244
for (; elements-- > 0;
245245
to.IncrementSubscripts(toAt), from.IncrementSubscripts(fromAt)) {
246246
CHAR *p{to.Element<CHAR>(toAt)};
247-
Fortran::runtime::memmove(
247+
runtime::memmove(
248248
p, from.Element<std::add_const_t<CHAR>>(fromAt), fromElementBytes);
249249
p += copiedCharacters;
250250
for (auto n{padding}; n-- > 0;) {
@@ -743,22 +743,35 @@ RT_API_ATTRS void DoFromSourceAssign(Descriptor &alloc,
743743
if (alloc.rank() > 0 && source.rank() == 0) {
744744
// The value of each element of allocate object becomes the value of source.
745745
DescriptorAddendum *allocAddendum{alloc.Addendum()};
746-
const typeInfo::DerivedType *allocDerived{
747-
allocAddendum ? allocAddendum->derivedType() : nullptr};
748746
SubscriptValue allocAt[maxRank];
749747
alloc.GetLowerBounds(allocAt);
750-
if (allocDerived) {
748+
std::size_t allocElementBytes{alloc.ElementBytes()};
749+
if (const typeInfo::DerivedType *allocDerived{
750+
allocAddendum ? allocAddendum->derivedType() : nullptr}) {
751+
// Handle derived type or short character source
751752
for (std::size_t n{alloc.InlineElements()}; n-- > 0;
752753
alloc.IncrementSubscripts(allocAt)) {
753-
Descriptor allocElement{*Descriptor::Create(*allocDerived,
754-
reinterpret_cast<void *>(alloc.Element<char>(allocAt)), 0)};
754+
StaticDescriptor<maxRank, true, 8 /*?*/> statDesc;
755+
Descriptor &allocElement{statDesc.descriptor()};
756+
allocElement.Establish(*allocDerived,
757+
reinterpret_cast<void *>(alloc.Element<char>(allocAt)), 0);
755758
Assign(allocElement, source, terminator, NoAssignFlags, memmoveFct);
756759
}
757-
} else { // intrinsic type
760+
} else if (allocElementBytes > source.ElementBytes()) {
761+
// Scalar expansion of short character source
762+
for (std::size_t n{alloc.InlineElements()}; n-- > 0;
763+
alloc.IncrementSubscripts(allocAt)) {
764+
StaticDescriptor<maxRank, true, 8 /*?*/> statDesc;
765+
Descriptor &allocElement{statDesc.descriptor()};
766+
allocElement.Establish(source.type(), allocElementBytes,
767+
reinterpret_cast<void *>(alloc.Element<char>(allocAt)), 0);
768+
Assign(allocElement, source, terminator, NoAssignFlags, memmoveFct);
769+
}
770+
} else { // intrinsic type scalar expansion, same data size
758771
for (std::size_t n{alloc.InlineElements()}; n-- > 0;
759772
alloc.IncrementSubscripts(allocAt)) {
760773
memmoveFct(alloc.Element<char>(allocAt), source.raw().base_addr,
761-
alloc.ElementBytes());
774+
allocElementBytes);
762775
}
763776
}
764777
} else {

flang/include/flang/Runtime/assign.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,10 @@ enum AssignFlags {
4444

4545
#ifdef RT_DEVICE_COMPILATION
4646
RT_API_ATTRS void Assign(Descriptor &to, const Descriptor &from,
47-
Terminator &terminator, int flags, MemmoveFct memmoveFct = &MemmoveWrapper);
47+
Terminator &terminator, int flags, MemmoveFct = &MemmoveWrapper);
4848
#else
4949
RT_API_ATTRS void Assign(Descriptor &to, const Descriptor &from,
50-
Terminator &terminator, int flags,
51-
MemmoveFct memmoveFct = &Fortran::runtime::memmove);
50+
Terminator &terminator, int flags, MemmoveFct = &runtime::memmove);
5251
#endif
5352

5453
extern "C" {

0 commit comments

Comments
 (0)