Skip to content

Commit 9fdd25e

Browse files
authored
[flang] Don't change size of allocatable in error situation (#77386)
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.
1 parent 7b80123 commit 9fdd25e

File tree

1 file changed

+34
-34
lines changed

1 file changed

+34
-34
lines changed

flang/runtime/allocatable.cpp

Lines changed: 34 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -44,26 +44,23 @@ void RTDEF(AllocatableInitDerived)(Descriptor &descriptor,
4444

4545
void RTDEF(AllocatableInitIntrinsicForAllocate)(Descriptor &descriptor,
4646
TypeCategory category, int kind, int rank, int corank) {
47-
if (descriptor.IsAllocated()) {
48-
return;
47+
if (!descriptor.IsAllocated()) {
48+
RTNAME(AllocatableInitIntrinsic)(descriptor, category, kind, rank, corank);
4949
}
50-
RTNAME(AllocatableInitIntrinsic)(descriptor, category, kind, rank, corank);
5150
}
5251

5352
void RTDEF(AllocatableInitCharacterForAllocate)(Descriptor &descriptor,
5453
SubscriptValue length, int kind, int rank, int corank) {
55-
if (descriptor.IsAllocated()) {
56-
return;
54+
if (!descriptor.IsAllocated()) {
55+
RTNAME(AllocatableInitCharacter)(descriptor, length, kind, rank, corank);
5756
}
58-
RTNAME(AllocatableInitCharacter)(descriptor, length, kind, rank, corank);
5957
}
6058

6159
void RTDEF(AllocatableInitDerivedForAllocate)(Descriptor &descriptor,
6260
const typeInfo::DerivedType &derivedType, int rank, int corank) {
63-
if (descriptor.IsAllocated()) {
64-
return;
61+
if (!descriptor.IsAllocated()) {
62+
RTNAME(AllocatableInitDerived)(descriptor, derivedType, rank, corank);
6563
}
66-
RTNAME(AllocatableInitDerived)(descriptor, derivedType, rank, corank);
6764
}
6865

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

121120
void RTDEF(AllocatableSetDerivedLength)(
122121
Descriptor &descriptor, int which, SubscriptValue x) {
123-
DescriptorAddendum *addendum{descriptor.Addendum()};
124-
INTERNAL_CHECK(addendum != nullptr);
125-
addendum->SetLenParameterValue(which, x);
122+
if (descriptor.IsAllocatable() && !descriptor.IsAllocated()) {
123+
DescriptorAddendum *addendum{descriptor.Addendum()};
124+
INTERNAL_CHECK(addendum != nullptr);
125+
addendum->SetLenParameterValue(which, x);
126+
}
126127
}
127128

128129
void RTDEF(AllocatableApplyMold)(
129130
Descriptor &descriptor, const Descriptor &mold, int rank) {
130-
if (descriptor.IsAllocated()) {
131-
// 9.7.1.3 Return so the error can be emitted by AllocatableAllocate.
132-
return;
131+
if (descriptor.IsAllocatable() && !descriptor.IsAllocated()) {
132+
descriptor.ApplyMold(mold, rank);
133133
}
134-
descriptor.ApplyMold(mold, rank);
135134
}
136135

137136
int RTDEF(AllocatableAllocate)(Descriptor &descriptor, bool hasStat,
138137
const Descriptor *errMsg, const char *sourceFile, int sourceLine) {
139138
Terminator terminator{sourceFile, sourceLine};
140139
if (!descriptor.IsAllocatable()) {
141140
return ReturnError(terminator, StatInvalidDescriptor, errMsg, hasStat);
142-
}
143-
if (descriptor.IsAllocated()) {
141+
} else if (descriptor.IsAllocated()) {
144142
return ReturnError(terminator, StatBaseNotNull, errMsg, hasStat);
145-
}
146-
int stat{ReturnError(terminator, descriptor.Allocate(), errMsg, hasStat)};
147-
if (stat == StatOk) {
148-
if (const DescriptorAddendum * addendum{descriptor.Addendum()}) {
149-
if (const auto *derived{addendum->derivedType()}) {
150-
if (!derived->noInitializationNeeded()) {
151-
stat = Initialize(descriptor, *derived, terminator, hasStat, errMsg);
143+
} else {
144+
int stat{ReturnError(terminator, descriptor.Allocate(), errMsg, hasStat)};
145+
if (stat == StatOk) {
146+
if (const DescriptorAddendum * addendum{descriptor.Addendum()}) {
147+
if (const auto *derived{addendum->derivedType()}) {
148+
if (!derived->noInitializationNeeded()) {
149+
stat =
150+
Initialize(descriptor, *derived, terminator, hasStat, errMsg);
151+
}
152152
}
153153
}
154154
}
155+
return stat;
155156
}
156-
return stat;
157157
}
158158

159159
int RTDEF(AllocatableAllocateSource)(Descriptor &alloc,
@@ -173,14 +173,14 @@ int RTDEF(AllocatableDeallocate)(Descriptor &descriptor, bool hasStat,
173173
Terminator terminator{sourceFile, sourceLine};
174174
if (!descriptor.IsAllocatable()) {
175175
return ReturnError(terminator, StatInvalidDescriptor, errMsg, hasStat);
176-
}
177-
if (!descriptor.IsAllocated()) {
176+
} else if (!descriptor.IsAllocated()) {
178177
return ReturnError(terminator, StatBaseNull, errMsg, hasStat);
178+
} else {
179+
return ReturnError(terminator,
180+
descriptor.Destroy(
181+
/*finalize=*/true, /*destroyPointers=*/false, &terminator),
182+
errMsg, hasStat);
179183
}
180-
return ReturnError(terminator,
181-
descriptor.Destroy(
182-
/*finalize=*/true, /*destroyPointers=*/false, &terminator),
183-
errMsg, hasStat);
184184
}
185185

186186
int RTDEF(AllocatableDeallocatePolymorphic)(Descriptor &descriptor,

0 commit comments

Comments
 (0)