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] Fix constant subscript operations #68352

Merged
merged 1 commit into from
Oct 17, 2023
Merged

Conversation

luporl
Copy link
Contributor

@luporl luporl commented Oct 5, 2023

Modify ConstantBounds' methods that handle subscripts and bounds to
avoid integer overflows. This is needed to properly handle arrays
with the maximum possible upper bound (INT64_MAX).

Modify ConstantBounds' methods that handle subscripts and bounds to
avoid integer overflows. This is needed to properly handle arrays
with the maximum possible upper bound (INT64_MAX).
@llvmbot llvmbot added flang Flang issues not falling into any other category flang:semantics labels Oct 5, 2023
@llvmbot
Copy link
Member

llvmbot commented Oct 5, 2023

@llvm/pr-subscribers-flang-semantics

Changes

Modify ConstantBounds' methods that handle subscripts and bounds to
avoid integer overflows. This is needed to properly handle arrays
with the maximum possible upper bound (INT64_MAX).


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

3 Files Affected:

  • (modified) flang/lib/Evaluate/constant.cpp (+5-5)
  • (modified) flang/test/Evaluate/folding08.f90 (+6)
  • (modified) flang/test/Semantics/reshape.f90 (+5)
diff --git a/flang/lib/Evaluate/constant.cpp b/flang/lib/Evaluate/constant.cpp
index 084836b4ec36773..0e0d412118d3bb2 100644
--- a/flang/lib/Evaluate/constant.cpp
+++ b/flang/lib/Evaluate/constant.cpp
@@ -36,11 +36,11 @@ ConstantSubscripts ConstantBounds::ComputeUbounds(
     std::optional<int> dim) const {
   if (dim) {
     CHECK(*dim < Rank());
-    return {lbounds_[*dim] + shape_[*dim] - 1};
+    return {lbounds_[*dim] + (shape_[*dim] - 1)};
   } else {
     ConstantSubscripts ubounds(Rank());
     for (int i{0}; i < Rank(); ++i) {
-      ubounds[i] = lbounds_[i] + shape_[i] - 1;
+      ubounds[i] = lbounds_[i] + (shape_[i] - 1);
     }
     return ubounds;
   }
@@ -73,7 +73,7 @@ ConstantSubscript ConstantBounds::SubscriptsToOffset(
   for (auto j : index) {
     auto lb{lbounds_[dim]};
     auto extent{shape_[dim++]};
-    CHECK(j >= lb && j < lb + extent);
+    CHECK(j >= lb && j - lb < extent);
     offset += stride * (j - lb);
     stride *= extent;
   }
@@ -93,10 +93,10 @@ bool ConstantBounds::IncrementSubscripts(
     ConstantSubscript k{dimOrder ? (*dimOrder)[j] : j};
     auto lb{lbounds_[k]};
     CHECK(indices[k] >= lb);
-    if (++indices[k] < lb + shape_[k]) {
+    if (++indices[k] - lb < shape_[k]) {
       return true;
     } else {
-      CHECK(indices[k] == lb + std::max<ConstantSubscript>(shape_[k], 1));
+      CHECK(indices[k] - lb == std::max<ConstantSubscript>(shape_[k], 1));
       indices[k] = lb;
     }
   }
diff --git a/flang/test/Evaluate/folding08.f90 b/flang/test/Evaluate/folding08.f90
index 8c5296e88974762..1b2e5605e85d48e 100644
--- a/flang/test/Evaluate/folding08.f90
+++ b/flang/test/Evaluate/folding08.f90
@@ -146,4 +146,10 @@ subroutine test4_bound_parentheses
     logical, parameter :: test_ubpa4_dim = ubound((pa4), 1) == 5 .and. &
          ubound((pa4), 2) == 4
   end
+  subroutine test5_max_ubound
+    ! Test maximum ubound value
+    integer(8), parameter :: I64_MAX = INT(z'7fffffffffffffff', kind=8)
+    integer, parameter :: a5(I64_MAX - 2 : I64_MAX) = [1, 2, 3]
+    logical, parameter :: test_uba5 = ubound(a5, 1, kind=8) == I64_MAX
+  end subroutine
 end
diff --git a/flang/test/Semantics/reshape.f90 b/flang/test/Semantics/reshape.f90
index 2e9b5adf3ff0e50..fb5e0023e2716e8 100644
--- a/flang/test/Semantics/reshape.f90
+++ b/flang/test/Semantics/reshape.f90
@@ -44,6 +44,11 @@ program reshaper
   type(dType), parameter :: array19(*) = [dType::dType(field=[1,2])]
   logical, parameter :: lVar = all(array19(:)%field(1) == [2])
 
+  ! RESHAPE on array with maximum valid upper bound
+  integer(8), parameter :: I64_MAX = INT(z'7fffffffffffffff', kind=8)
+  integer, parameter :: array21(I64_MAX - 2 : I64_MAX) = [1, 2, 3]
+  integer, parameter :: array22(2) = RESHAPE(array21, [2])
+
   !ERROR: Size of 'shape=' argument must not be greater than 15
   CALL ext_sub(RESHAPE([(n, n=1,20)], &
     [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]))

@luporl luporl requested review from FruitClover and klausler October 5, 2023 21:01
@luporl
Copy link
Contributor Author

luporl commented Oct 5, 2023

This PR fixes part of the problem of #63770 (aborting when trying to reshape constant arrays where lower_bound + extent > INT64_MAX).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
flang:semantics flang Flang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants