[flang-commits] [flang] [flang] Fix constant subscript operations (PR #68352)

via flang-commits flang-commits at lists.llvm.org
Thu Oct 5 13:59:38 PDT 2023


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-flang-semantics

<details>
<summary>Changes</summary>

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
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]))

``````````

</details>


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


More information about the flang-commits mailing list