Skip to content

Commit c385981

Browse files
authored
[flang] Fix constant subscript operations (#68352)
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).
1 parent 791b890 commit c385981

File tree

3 files changed

+16
-5
lines changed

3 files changed

+16
-5
lines changed

flang/lib/Evaluate/constant.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,11 @@ ConstantSubscripts ConstantBounds::ComputeUbounds(
3636
std::optional<int> dim) const {
3737
if (dim) {
3838
CHECK(*dim < Rank());
39-
return {lbounds_[*dim] + shape_[*dim] - 1};
39+
return {lbounds_[*dim] + (shape_[*dim] - 1)};
4040
} else {
4141
ConstantSubscripts ubounds(Rank());
4242
for (int i{0}; i < Rank(); ++i) {
43-
ubounds[i] = lbounds_[i] + shape_[i] - 1;
43+
ubounds[i] = lbounds_[i] + (shape_[i] - 1);
4444
}
4545
return ubounds;
4646
}
@@ -73,7 +73,7 @@ ConstantSubscript ConstantBounds::SubscriptsToOffset(
7373
for (auto j : index) {
7474
auto lb{lbounds_[dim]};
7575
auto extent{shape_[dim++]};
76-
CHECK(j >= lb && j < lb + extent);
76+
CHECK(j >= lb && j - lb < extent);
7777
offset += stride * (j - lb);
7878
stride *= extent;
7979
}
@@ -93,10 +93,10 @@ bool ConstantBounds::IncrementSubscripts(
9393
ConstantSubscript k{dimOrder ? (*dimOrder)[j] : j};
9494
auto lb{lbounds_[k]};
9595
CHECK(indices[k] >= lb);
96-
if (++indices[k] < lb + shape_[k]) {
96+
if (++indices[k] - lb < shape_[k]) {
9797
return true;
9898
} else {
99-
CHECK(indices[k] == lb + std::max<ConstantSubscript>(shape_[k], 1));
99+
CHECK(indices[k] - lb == std::max<ConstantSubscript>(shape_[k], 1));
100100
indices[k] = lb;
101101
}
102102
}

flang/test/Evaluate/folding08.f90

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,4 +146,10 @@ subroutine test4_bound_parentheses
146146
logical, parameter :: test_ubpa4_dim = ubound((pa4), 1) == 5 .and. &
147147
ubound((pa4), 2) == 4
148148
end
149+
subroutine test5_max_ubound
150+
! Test maximum ubound value
151+
integer(8), parameter :: I64_MAX = INT(z'7fffffffffffffff', kind=8)
152+
integer, parameter :: a5(I64_MAX - 2 : I64_MAX) = [1, 2, 3]
153+
logical, parameter :: test_uba5 = ubound(a5, 1, kind=8) == I64_MAX
154+
end subroutine
149155
end

flang/test/Semantics/reshape.f90

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,11 @@ program reshaper
4444
type(dType), parameter :: array19(*) = [dType::dType(field=[1,2])]
4545
logical, parameter :: lVar = all(array19(:)%field(1) == [2])
4646

47+
! RESHAPE on array with maximum valid upper bound
48+
integer(8), parameter :: I64_MAX = INT(z'7fffffffffffffff', kind=8)
49+
integer, parameter :: array21(I64_MAX - 2 : I64_MAX) = [1, 2, 3]
50+
integer, parameter :: array22(2) = RESHAPE(array21, [2])
51+
4752
!ERROR: Size of 'shape=' argument must not be greater than 15
4853
CALL ext_sub(RESHAPE([(n, n=1,20)], &
4954
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]))

0 commit comments

Comments
 (0)