Skip to content

Commit a5eb6bd

Browse files
authored
[flang] Relax overindexing error to warning for last dummy dimension (#71725)
Compilation-time subscript value range checking should emit a warning, not an error, when the indexed array is a dummy argument; there's old-school codes out there that should have used assumed-size dummy arguments but didn't.
1 parent 6d9eb31 commit a5eb6bd

File tree

2 files changed

+58
-40
lines changed

2 files changed

+58
-40
lines changed

flang/lib/Semantics/expression.cpp

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -403,19 +403,28 @@ void ExpressionAnalyzer::CheckConstantSubscripts(ArrayRef &ref) {
403403
}
404404
for (int j{0}; j < vals; ++j) {
405405
if (val[j]) {
406+
std::optional<parser::MessageFixedText> msg;
407+
std::optional<ConstantSubscript> bound;
406408
if (dimLB && *val[j] < *dimLB) {
407-
AttachDeclaration(
408-
Say("Subscript %jd is less than lower bound %jd for dimension %d of array"_err_en_US,
409-
static_cast<std::intmax_t>(*val[j]),
410-
static_cast<std::intmax_t>(*dimLB), dim + 1),
411-
ref.base().GetLastSymbol());
409+
msg =
410+
"Subscript %jd is less than lower bound %jd for dimension %d of array"_err_en_US;
411+
bound = *dimLB;
412+
} else if (dimUB && *val[j] > *dimUB) {
413+
msg =
414+
"Subscript %jd is greater than upper bound %jd for dimension %d of array"_err_en_US;
415+
bound = *dimUB;
416+
if (dim + 1 == arraySymbol.Rank() && IsDummy(arraySymbol) &&
417+
*bound == 1) {
418+
// Old-school overindexing of a dummy array isn't fatal when
419+
// it's on the last dimension and the extent is 1.
420+
msg->set_severity(parser::Severity::Warning);
421+
}
412422
}
413-
if (dimUB && *val[j] > *dimUB) {
423+
if (msg) {
414424
AttachDeclaration(
415-
Say("Subscript %jd is greater than upper bound %jd for dimension %d of array"_err_en_US,
416-
static_cast<std::intmax_t>(*val[j]),
417-
static_cast<std::intmax_t>(*dimUB), dim + 1),
418-
ref.base().GetLastSymbol());
425+
Say(std::move(*msg), static_cast<std::intmax_t>(*val[j]),
426+
static_cast<std::intmax_t>(bound.value()), dim + 1),
427+
arraySymbol);
419428
}
420429
}
421430
}
Lines changed: 39 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,42 @@
11
! RUN: %python %S/test_errors.py %s %flang_fc1 -Werror
22
! Check out-of-range subscripts
3-
real a(10)
4-
integer, parameter :: n(2) = [1, 2]
5-
integer unknown
6-
!ERROR: DATA statement designator 'a(0_8)' is out of range
7-
!ERROR: DATA statement designator 'a(11_8)' is out of range
8-
data a(0)/0./, a(10+1)/0./
9-
!ERROR: Subscript 0 is less than lower bound 1 for dimension 1 of array
10-
print *, a(0)
11-
!ERROR: Subscript 0 is less than lower bound 1 for dimension 1 of array
12-
print *, a(1-1)
13-
!ERROR: Subscript 11 is greater than upper bound 10 for dimension 1 of array
14-
print *, a(11)
15-
!ERROR: Subscript 11 is greater than upper bound 10 for dimension 1 of array
16-
print *, a(10+1)
17-
!ERROR: Subscript value (0) is out of range on dimension 1 in reference to a constant array value
18-
print *, n(0)
19-
!ERROR: Subscript value (3) is out of range on dimension 1 in reference to a constant array value
20-
print *, n(4-1)
21-
print *, a(1:12:3) ! ok
22-
!ERROR: Subscript 13 is greater than upper bound 10 for dimension 1 of array
23-
print *, a(1:13:3)
24-
print *, a(10:-1:-3) ! ok
25-
!ERROR: Subscript -2 is less than lower bound 1 for dimension 1 of array
26-
print *, a(10:-2:-3)
27-
print *, a(-1:-2) ! empty section is ok
28-
print *, a(0:11:-1) ! empty section is ok
29-
!ERROR: Subscript 0 is less than lower bound 1 for dimension 1 of array
30-
print *, a(0:0:unknown) ! lower==upper, can ignore stride
31-
!ERROR: Subscript 11 is greater than upper bound 10 for dimension 1 of array
32-
print *, a(11:11:unknown) ! lower==upper, can ignore stride
3+
subroutine subr(da)
4+
real a(10), da(2,1)
5+
integer, parameter :: n(2) = [1, 2]
6+
integer unknown
7+
!ERROR: DATA statement designator 'a(0_8)' is out of range
8+
!ERROR: DATA statement designator 'a(11_8)' is out of range
9+
data a(0)/0./, a(10+1)/0./
10+
!ERROR: Subscript 0 is less than lower bound 1 for dimension 1 of array
11+
print *, a(0)
12+
!ERROR: Subscript 0 is less than lower bound 1 for dimension 1 of array
13+
print *, a(1-1)
14+
!ERROR: Subscript 11 is greater than upper bound 10 for dimension 1 of array
15+
print *, a(11)
16+
!ERROR: Subscript 11 is greater than upper bound 10 for dimension 1 of array
17+
print *, a(10+1)
18+
!ERROR: Subscript value (0) is out of range on dimension 1 in reference to a constant array value
19+
print *, n(0)
20+
!ERROR: Subscript value (3) is out of range on dimension 1 in reference to a constant array value
21+
print *, n(4-1)
22+
print *, a(1:12:3) ! ok
23+
!ERROR: Subscript 13 is greater than upper bound 10 for dimension 1 of array
24+
print *, a(1:13:3)
25+
print *, a(10:-1:-3) ! ok
26+
!ERROR: Subscript -2 is less than lower bound 1 for dimension 1 of array
27+
print *, a(10:-2:-3)
28+
print *, a(-1:-2) ! empty section is ok
29+
print *, a(0:11:-1) ! empty section is ok
30+
!ERROR: Subscript 0 is less than lower bound 1 for dimension 1 of array
31+
print *, a(0:0:unknown) ! lower==upper, can ignore stride
32+
!ERROR: Subscript 11 is greater than upper bound 10 for dimension 1 of array
33+
print *, a(11:11:unknown) ! lower==upper, can ignore stride
34+
!ERROR: Subscript 0 is less than lower bound 1 for dimension 1 of array
35+
print *, da(0,1)
36+
!ERROR: Subscript 3 is greater than upper bound 2 for dimension 1 of array
37+
print *, da(3,1)
38+
!ERROR: Subscript 0 is less than lower bound 1 for dimension 2 of array
39+
print *, da(1,0)
40+
!WARNING: Subscript 2 is greater than upper bound 1 for dimension 2 of array
41+
print *, da(1,2)
3342
end

0 commit comments

Comments
 (0)