Skip to content
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

[flang] Don't change size of allocatable in error situation #77386

Merged
merged 1 commit into from
Jan 15, 2024

Conversation

klausler
Copy link
Contributor

@klausler klausler commented Jan 8, 2024

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.

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.
@klausler klausler requested a review from vzakhari January 8, 2024 22:19
@llvmbot llvmbot added flang:runtime flang Flang issues not falling into any other category labels Jan 8, 2024
@llvmbot
Copy link
Collaborator

llvmbot commented Jan 8, 2024

@llvm/pr-subscribers-flang-runtime

Author: Peter Klausler (klausler)

Changes

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.


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

1 Files Affected:

  • (modified) flang/runtime/allocatable.cpp (+34-34)
diff --git a/flang/runtime/allocatable.cpp b/flang/runtime/allocatable.cpp
index e69795e6f824ba..5e065f47636a89 100644
--- a/flang/runtime/allocatable.cpp
+++ b/flang/runtime/allocatable.cpp
@@ -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,
@@ -114,24 +111,26 @@ 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,
@@ -139,21 +138,22 @@ int RTDEF(AllocatableAllocate)(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, 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,
@@ -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,

Copy link
Contributor

@vzakhari vzakhari left a comment

Choose a reason for hiding this comment

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

LGTM

@klausler klausler merged commit 9fdd25e into llvm:main Jan 15, 2024
6 checks passed
@klausler klausler deleted the multiple-alloc branch January 15, 2024 20:18
justinfargnoli pushed a commit to justinfargnoli/llvm-project that referenced this pull request Jan 28, 2024
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.
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.

None yet

3 participants