diff --git a/flang/lib/Semantics/expression.cpp b/flang/lib/Semantics/expression.cpp index 966884fb4c32a..af6cce3d5b2c3 100644 --- a/flang/lib/Semantics/expression.cpp +++ b/flang/lib/Semantics/expression.cpp @@ -319,26 +319,26 @@ void ExpressionAnalyzer::CheckConstantSubscripts(ArrayRef &ref) { auto expr{Fold(triplet->stride())}; auto stride{ToInt64(expr)}; triplet->set_stride(std::move(expr)); + std::optional lower, upper; + if (auto expr{triplet->lower()}) { + *expr = Fold(std::move(*expr)); + lower = ToInt64(*expr); + triplet->set_lower(std::move(*expr)); + } else { + lower = ToInt64(lb[dim]); + } + if (auto expr{triplet->upper()}) { + *expr = Fold(std::move(*expr)); + upper = ToInt64(*expr); + triplet->set_upper(std::move(*expr)); + } else { + upper = ToInt64(ub[dim]); + } if (stride) { if (*stride == 0) { Say("Stride of triplet must not be zero"_err_en_US); return; } - std::optional lower, upper; - if (auto expr{triplet->lower()}) { - *expr = Fold(std::move(*expr)); - lower = ToInt64(*expr); - triplet->set_lower(std::move(*expr)); - } else { - lower = ToInt64(lb[dim]); - } - if (auto expr{triplet->upper()}) { - *expr = Fold(std::move(*expr)); - upper = ToInt64(*expr); - triplet->set_upper(std::move(*expr)); - } else { - upper = ToInt64(ub[dim]); - } if (lower && upper) { if (*stride > 0) { anyPossiblyEmptyDim |= *lower > *upper; @@ -348,8 +348,12 @@ void ExpressionAnalyzer::CheckConstantSubscripts(ArrayRef &ref) { } else { anyPossiblyEmptyDim = true; } - } else { - anyPossiblyEmptyDim = true; + } else { // non-constant stride + if (lower && upper && *lower == *upper) { + // stride is not relevant + } else { + anyPossiblyEmptyDim = true; + } } } else { // not triplet auto &expr{std::get(ss.u).value()}; @@ -380,12 +384,13 @@ void ExpressionAnalyzer::CheckConstantSubscripts(ArrayRef &ref) { } else if (ub[dim]) { upper = ToInt64(*ub[dim]); } - if (stride && *stride != 0 && lower && upper) { - // Normalize upper bound for non-unit stride - // 1:10:2 -> 1:9:2, 10:1:-2 -> 10:2:-2 - *upper = *lower + *stride * ((*upper - *lower) / *stride); - val[vals++] = lower; - val[vals++] = upper; + if (lower) { + val[vals++] = *lower; + if (upper && *upper != lower && (stride && *stride != 0)) { + // Normalize upper bound for non-unit stride + // 1:10:2 -> 1:9:2, 10:1:-2 -> 10:2:-2 + val[vals++] = *lower + *stride * ((*upper - *lower) / *stride); + } } } else { val[vals++] = diff --git a/flang/test/Semantics/expr-errors06.f90 b/flang/test/Semantics/expr-errors06.f90 index ad5baf708f34c..1168d410b9bd9 100644 --- a/flang/test/Semantics/expr-errors06.f90 +++ b/flang/test/Semantics/expr-errors06.f90 @@ -2,6 +2,7 @@ ! Check out-of-range subscripts real a(10) integer, parameter :: n(2) = [1, 2] +integer unknown !ERROR: DATA statement designator 'a(0_8)' is out of range !ERROR: DATA statement designator 'a(11_8)' is out of range data a(0)/0./, a(10+1)/0./ @@ -25,5 +26,8 @@ print *, a(10:-2:-3) print *, a(-1:-2) ! empty section is ok print *, a(0:11:-1) ! empty section is ok +!ERROR: Subscript 0 is less than lower bound 1 for dimension 1 of array +print *, a(0:0:unknown) ! lower==upper, can ignore stride +!ERROR: Subscript 11 is greater than upper bound 10 for dimension 1 of array +print *, a(11:11:unknown) ! lower==upper, can ignore stride end -