Skip to content

[flang][runtime] Fix finalization case in assignment #113611

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Nov 5, 2024

Conversation

klausler
Copy link
Contributor

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.

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 llvm#113375.
@klausler klausler requested a review from DanielCChen October 24, 2024 19:20
@llvmbot llvmbot added flang:runtime flang Flang issues not falling into any other category labels Oct 24, 2024
@llvmbot
Copy link
Member

llvmbot commented Oct 24, 2024

@llvm/pr-subscribers-flang-runtime

Author: Peter Klausler (klausler)

Changes

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.


Full diff: https://github.com/llvm/llvm-project/pull/113611.diff

1 Files Affected:

  • (modified) flang/runtime/assign.cpp (+3-5)
diff --git a/flang/runtime/assign.cpp b/flang/runtime/assign.cpp
index d558ada51cd21a..5c2ea2e4162834 100644
--- a/flang/runtime/assign.cpp
+++ b/flang/runtime/assign.cpp
@@ -155,9 +155,9 @@ static RT_API_ATTRS bool MayAlias(const Descriptor &x, const Descriptor &y) {
     return false; // not both allocated
   }
   const char *xDesc{reinterpret_cast<const char *>(&x)};
-  const char *xDescLast{xDesc + x.SizeInBytes()};
+  const char *xDescLast{xDesc + x.SizeInBytes() - 1};
   const char *yDesc{reinterpret_cast<const char *>(&y)};
-  const char *yDescLast{yDesc + y.SizeInBytes()};
+  const char *yDescLast{yDesc + y.SizeInBytes() - 1};
   std::int64_t xLeast, xMost, yLeast, yMost;
   MaximalByteOffsetRange(x, xLeast, xMost);
   MaximalByteOffsetRange(y, yLeast, yMost);
@@ -318,10 +318,8 @@ RT_API_ATTRS static void Assign(
     if (mustDeallocateLHS) {
       if (deferDeallocation) {
         if ((flags & NeedFinalization) && toDerived) {
-          Finalize(to, *toDerived, &terminator);
+          Finalize(*deferDeallocation, *toDerived, &terminator);
           flags &= ~NeedFinalization;
-        } else if (toDerived && !toDerived->noDestructionNeeded()) {
-          Destroy(to, /*finalize=*/false, *toDerived, &terminator);
         }
       } else {
         to.Destroy((flags & NeedFinalization) != 0, /*destroyPointers=*/false,

Copy link
Contributor

@DanielCChen DanielCChen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.
Thanks for the quick fix. The test case is passing with this patch.

@klausler klausler merged commit 07e053f into llvm:main Nov 5, 2024
11 checks passed
@klausler klausler deleted the bug113375 branch November 5, 2024 21:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
flang:runtime flang Flang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Flang] Missing finalization call at intrinsic assignment.
3 participants