[flang][runtime] Fix AllocateAssignmentLHS for monomorphic LHS (#153073)

When the left-hand side of an assignment statement is an allocatable
that has a monomorphic derived type, and the right-hand side of the
assignment has a type that is an extension of that type, *don't* change
the incoming type or element size of the descriptor before allocating
it.

Fixes https://github.com/llvm/llvm-project/issues/152758.
This commit is contained in:
Peter Klausler 2025-08-18 14:42:16 -07:00 committed by GitHub
parent ec4e6aaac4
commit 50b55a5ee9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -88,23 +88,32 @@ static inline RT_API_ATTRS bool MustDeallocateLHS(
// originally deallocated or because it required reallocation
static RT_API_ATTRS int AllocateAssignmentLHS(
Descriptor &to, const Descriptor &from, Terminator &terminator, int flags) {
to.raw().type = from.raw().type;
if (!(flags & ExplicitLengthCharacterLHS)) {
to.raw().elem_len = from.ElementBytes();
}
const typeInfo::DerivedType *derived{nullptr};
DescriptorAddendum *toAddendum{to.Addendum()};
const typeInfo::DerivedType *derived{nullptr};
if (toAddendum) {
derived = toAddendum->derivedType();
}
if (const DescriptorAddendum * fromAddendum{from.Addendum()}) {
derived = fromAddendum->derivedType();
if (toAddendum) {
toAddendum->set_derivedType(derived);
std::size_t lenParms{derived ? derived->LenParameters() : 0};
if (!derived || (flags & PolymorphicLHS)) {
derived = fromAddendum->derivedType();
}
if (toAddendum && derived) {
std::size_t lenParms{derived->LenParameters()};
for (std::size_t j{0}; j < lenParms; ++j) {
toAddendum->SetLenParameterValue(j, fromAddendum->LenParameterValue(j));
}
}
} else if (toAddendum) {
toAddendum->set_derivedType(nullptr);
} else {
derived = nullptr;
}
if (toAddendum) {
toAddendum->set_derivedType(derived);
}
to.raw().type = from.raw().type;
if (derived) {
to.raw().elem_len = derived->sizeInBytes();
} else if (!(flags & ExplicitLengthCharacterLHS)) {
to.raw().elem_len = from.ElementBytes();
}
// subtle: leave bounds in place when "from" is scalar (10.2.1.3(3))
int rank{from.rank()};