Skip to content

Commit

Permalink
[flang] Don't change size of allocatable in error situation (#77386)
Browse files Browse the repository at this point in the history
When an already-allocated allocatable array is about to fail
reallocation, don't allow its size or other characteristics to be
changed.

Fixes
llvm-test-suite/Fortran/gfortran/regression/multiple_allocation_1.f90
and .../multiple_allocation_3.f90.
  • Loading branch information
klausler committed Jan 15, 2024
1 parent 7b80123 commit 9fdd25e
Showing 1 changed file with 34 additions and 34 deletions.
68 changes: 34 additions & 34 deletions flang/runtime/allocatable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,26 +44,23 @@ void RTDEF(AllocatableInitDerived)(Descriptor &descriptor,

void RTDEF(AllocatableInitIntrinsicForAllocate)(Descriptor &descriptor,
TypeCategory category, int kind, int rank, int corank) {
if (descriptor.IsAllocated()) {
return;
if (!descriptor.IsAllocated()) {
RTNAME(AllocatableInitIntrinsic)(descriptor, category, kind, rank, corank);
}
RTNAME(AllocatableInitIntrinsic)(descriptor, category, kind, rank, corank);
}

void RTDEF(AllocatableInitCharacterForAllocate)(Descriptor &descriptor,
SubscriptValue length, int kind, int rank, int corank) {
if (descriptor.IsAllocated()) {
return;
if (!descriptor.IsAllocated()) {
RTNAME(AllocatableInitCharacter)(descriptor, length, kind, rank, corank);
}
RTNAME(AllocatableInitCharacter)(descriptor, length, kind, rank, corank);
}

void RTDEF(AllocatableInitDerivedForAllocate)(Descriptor &descriptor,
const typeInfo::DerivedType &derivedType, int rank, int corank) {
if (descriptor.IsAllocated()) {
return;
if (!descriptor.IsAllocated()) {
RTNAME(AllocatableInitDerived)(descriptor, derivedType, rank, corank);
}
RTNAME(AllocatableInitDerived)(descriptor, derivedType, rank, corank);
}

std::int32_t RTDEF(MoveAlloc)(Descriptor &to, Descriptor &from,
Expand Down Expand Up @@ -114,46 +111,49 @@ std::int32_t RTDEF(MoveAlloc)(Descriptor &to, Descriptor &from,
void RTDEF(AllocatableSetBounds)(Descriptor &descriptor, int zeroBasedDim,
SubscriptValue lower, SubscriptValue upper) {
INTERNAL_CHECK(zeroBasedDim >= 0 && zeroBasedDim < descriptor.rank());
descriptor.GetDimension(zeroBasedDim).SetBounds(lower, upper);
// The byte strides are computed when the object is allocated.
if (descriptor.IsAllocatable() && !descriptor.IsAllocated()) {
descriptor.GetDimension(zeroBasedDim).SetBounds(lower, upper);
// The byte strides are computed when the object is allocated.
}
}

void RTDEF(AllocatableSetDerivedLength)(
Descriptor &descriptor, int which, SubscriptValue x) {
DescriptorAddendum *addendum{descriptor.Addendum()};
INTERNAL_CHECK(addendum != nullptr);
addendum->SetLenParameterValue(which, x);
if (descriptor.IsAllocatable() && !descriptor.IsAllocated()) {
DescriptorAddendum *addendum{descriptor.Addendum()};
INTERNAL_CHECK(addendum != nullptr);
addendum->SetLenParameterValue(which, x);
}
}

void RTDEF(AllocatableApplyMold)(
Descriptor &descriptor, const Descriptor &mold, int rank) {
if (descriptor.IsAllocated()) {
// 9.7.1.3 Return so the error can be emitted by AllocatableAllocate.
return;
if (descriptor.IsAllocatable() && !descriptor.IsAllocated()) {
descriptor.ApplyMold(mold, rank);
}
descriptor.ApplyMold(mold, rank);
}

int RTDEF(AllocatableAllocate)(Descriptor &descriptor, bool hasStat,
const Descriptor *errMsg, const char *sourceFile, int sourceLine) {
Terminator terminator{sourceFile, sourceLine};
if (!descriptor.IsAllocatable()) {
return ReturnError(terminator, StatInvalidDescriptor, errMsg, hasStat);
}
if (descriptor.IsAllocated()) {
} else if (descriptor.IsAllocated()) {
return ReturnError(terminator, StatBaseNotNull, errMsg, hasStat);
}
int stat{ReturnError(terminator, descriptor.Allocate(), errMsg, hasStat)};
if (stat == StatOk) {
if (const DescriptorAddendum * addendum{descriptor.Addendum()}) {
if (const auto *derived{addendum->derivedType()}) {
if (!derived->noInitializationNeeded()) {
stat = Initialize(descriptor, *derived, terminator, hasStat, errMsg);
} else {
int stat{ReturnError(terminator, descriptor.Allocate(), errMsg, hasStat)};
if (stat == StatOk) {
if (const DescriptorAddendum * addendum{descriptor.Addendum()}) {
if (const auto *derived{addendum->derivedType()}) {
if (!derived->noInitializationNeeded()) {
stat =
Initialize(descriptor, *derived, terminator, hasStat, errMsg);
}
}
}
}
return stat;
}
return stat;
}

int RTDEF(AllocatableAllocateSource)(Descriptor &alloc,
Expand All @@ -173,14 +173,14 @@ int RTDEF(AllocatableDeallocate)(Descriptor &descriptor, bool hasStat,
Terminator terminator{sourceFile, sourceLine};
if (!descriptor.IsAllocatable()) {
return ReturnError(terminator, StatInvalidDescriptor, errMsg, hasStat);
}
if (!descriptor.IsAllocated()) {
} else if (!descriptor.IsAllocated()) {
return ReturnError(terminator, StatBaseNull, errMsg, hasStat);
} else {
return ReturnError(terminator,
descriptor.Destroy(
/*finalize=*/true, /*destroyPointers=*/false, &terminator),
errMsg, hasStat);
}
return ReturnError(terminator,
descriptor.Destroy(
/*finalize=*/true, /*destroyPointers=*/false, &terminator),
errMsg, hasStat);
}

int RTDEF(AllocatableDeallocatePolymorphic)(Descriptor &descriptor,
Expand Down

0 comments on commit 9fdd25e

Please sign in to comment.