Skip to content

Commit 07e053f

Browse files
authored
[flang][runtime] Fix finalization case in assignment (#113611)
There were two bugs in derived type array assignment processing that caused finalization to fail to occur for a test case. The first bug was an off-by-one error in address overlap testing that caused a false positive result for the test, whose left-hand side's allocatable's descriptor was immediately adjacent in memory to the right-hand side's array's data. The second bug was that in such overlap cases (even when legitimate) finalization would fail due to the LHS's descriptor having been copied to a temporary for deferred deallocation and then nullified. This patch corrects the overlap analysis for this test, and also properly finalizes the LHS when overlap does exist. Some nearby dead code was removed to avoid future confusion. Fixes #113375.
1 parent fbbd8b0 commit 07e053f

File tree

1 file changed

+3
-5
lines changed

1 file changed

+3
-5
lines changed

flang/runtime/assign.cpp

+3-5
Original file line numberDiff line numberDiff line change
@@ -144,9 +144,9 @@ static RT_API_ATTRS bool MayAlias(const Descriptor &x, const Descriptor &y) {
144144
return false; // not both allocated
145145
}
146146
const char *xDesc{reinterpret_cast<const char *>(&x)};
147-
const char *xDescLast{xDesc + x.SizeInBytes()};
147+
const char *xDescLast{xDesc + x.SizeInBytes() - 1};
148148
const char *yDesc{reinterpret_cast<const char *>(&y)};
149-
const char *yDescLast{yDesc + y.SizeInBytes()};
149+
const char *yDescLast{yDesc + y.SizeInBytes() - 1};
150150
std::int64_t xLeast, xMost, yLeast, yMost;
151151
MaximalByteOffsetRange(x, xLeast, xMost);
152152
MaximalByteOffsetRange(y, yLeast, yMost);
@@ -307,10 +307,8 @@ RT_API_ATTRS void Assign(Descriptor &to, const Descriptor &from,
307307
if (mustDeallocateLHS) {
308308
if (deferDeallocation) {
309309
if ((flags & NeedFinalization) && toDerived) {
310-
Finalize(to, *toDerived, &terminator);
310+
Finalize(*deferDeallocation, *toDerived, &terminator);
311311
flags &= ~NeedFinalization;
312-
} else if (toDerived && !toDerived->noDestructionNeeded()) {
313-
Destroy(to, /*finalize=*/false, *toDerived, &terminator);
314312
}
315313
} else {
316314
to.Destroy((flags & NeedFinalization) != 0, /*destroyPointers=*/false,

0 commit comments

Comments
 (0)