-
Notifications
You must be signed in to change notification settings - Fork 12.4k
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
Conversation
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).
@llvm/pr-subscribers-flang-semantics ChangesModify ConstantBounds' methods that handle subscripts and bounds to Full diff: https://github.com/llvm/llvm-project/pull/68352.diff 3 Files Affected:
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]))
|
This PR fixes part of the problem of #63770 (aborting when trying to reshape constant arrays where lower_bound + extent > 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).