diff options
| author | Peter Klausler <pklausler@nvidia.com> | 2025-08-29 07:50:17 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-08-29 07:50:17 -0700 |
| commit | 6111c9cfdcc054306de0a17d9eab5274ca6a34e1 (patch) | |
| tree | befbd914c6fe629281d6edd611d34af0eda679a8 /flang-rt | |
| parent | 9005ae5d89b6d4430ea5eb25d37cb4089d8267b8 (diff) | |
[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 https://github.com/llvm/llvm-project/issues/155703.
Diffstat (limited to 'flang-rt')
| -rw-r--r-- | flang-rt/lib/runtime/assign.cpp | 29 |
1 files changed, 21 insertions, 8 deletions
diff --git a/flang-rt/lib/runtime/assign.cpp b/flang-rt/lib/runtime/assign.cpp index 2c29a98d5a5c..a21e899c2c65 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;) { @@ -743,22 +743,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 { |
