-
Notifications
You must be signed in to change notification settings - Fork 10.8k
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] Produce warning instead of error when bound checking arrays #83011
base: main
Are you sure you want to change the base?
Conversation
@llvm/pr-subscribers-flang-semantics Author: Michael Klemm (mjklemm) ChangesFixes issue #82684. While out-of-bounds accesses are not permitted by the Fortran standard, the compiler should not produce a fatal error but emit a warning. This is inline with other compilers and can easily be turned into an error via Full diff: https://github.com/llvm/llvm-project/pull/83011.diff 2 Files Affected:
diff --git a/flang/lib/Semantics/expression.cpp b/flang/lib/Semantics/expression.cpp
index 8d817f077880b9..48b23f82291e42 100644
--- a/flang/lib/Semantics/expression.cpp
+++ b/flang/lib/Semantics/expression.cpp
@@ -416,12 +416,11 @@ void ExpressionAnalyzer::CheckConstantSubscripts(ArrayRef &ref) {
msg =
"Subscript %jd is greater than upper bound %jd for dimension %d of array"_err_en_US;
bound = *dimUB;
- if (dim + 1 == arraySymbol.Rank() && IsDummy(arraySymbol) &&
- *bound == 1) {
- // Old-school overindexing of a dummy array isn't fatal when
- // it's on the last dimension and the extent is 1.
- msg->set_severity(parser::Severity::Warning);
- }
+ // Even though this constitudes a violation of the Fortran
+ // standard, we should use a warning instead of a fatal error.
+ // This is in line with other compilers and can be turned
+ // into a fatal error using -Werror.
+ msg->set_severity(parser::Severity::Warning);
}
if (msg) {
AttachDeclaration(
diff --git a/flang/test/Semantics/expr-errors06.f90 b/flang/test/Semantics/expr-errors06.f90
index 84872c7fcdbc58..c0293104daf01f 100644
--- a/flang/test/Semantics/expr-errors06.f90
+++ b/flang/test/Semantics/expr-errors06.f90
@@ -7,35 +7,35 @@ subroutine subr(da)
!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./
- !ERROR: Subscript 0 is less than lower bound 1 for dimension 1 of array
+ !WARNING: Subscript 0 is less than lower bound 1 for dimension 1 of array
print *, a(0)
- !ERROR: Subscript 0 is less than lower bound 1 for dimension 1 of array
+ !WARNING: Subscript 0 is less than lower bound 1 for dimension 1 of array
print *, a(1-1)
- !ERROR: Subscript 11 is greater than upper bound 10 for dimension 1 of array
+ !WARNING: Subscript 11 is greater than upper bound 10 for dimension 1 of array
print *, a(11)
- !ERROR: Subscript 11 is greater than upper bound 10 for dimension 1 of array
+ !WARNING: Subscript 11 is greater than upper bound 10 for dimension 1 of array
print *, a(10+1)
- !ERROR: Subscript value (0) is out of range on dimension 1 in reference to a constant array value
+ !WARNING: Subscript value (0) is out of range on dimension 1 in reference to a constant array value
print *, n(0)
- !ERROR: Subscript value (3) is out of range on dimension 1 in reference to a constant array value
+ !WARNING: Subscript value (3) is out of range on dimension 1 in reference to a constant array value
print *, n(4-1)
print *, a(1:12:3) ! ok
- !ERROR: Subscript 13 is greater than upper bound 10 for dimension 1 of array
+ !WARNING: Subscript 13 is greater than upper bound 10 for dimension 1 of array
print *, a(1:13:3)
print *, a(10:-1:-3) ! ok
- !ERROR: Subscript -2 is less than lower bound 1 for dimension 1 of array
+ !WARNING: Subscript -2 is less than lower bound 1 for dimension 1 of array
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
+ !WARNING: 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
+ !WARNING: Subscript 11 is greater than upper bound 10 for dimension 1 of array
print *, a(11:11:unknown) ! lower==upper, can ignore stride
- !ERROR: Subscript 0 is less than lower bound 1 for dimension 1 of array
+ !WARNING: Subscript 0 is less than lower bound 1 for dimension 1 of array
print *, da(0,1)
- !ERROR: Subscript 3 is greater than upper bound 2 for dimension 1 of array
+ !WARNING: Subscript 3 is greater than upper bound 2 for dimension 1 of array
print *, da(3,1)
- !ERROR: Subscript 0 is less than lower bound 1 for dimension 2 of array
+ !WARNING: Subscript 0 is less than lower bound 1 for dimension 2 of array
print *, da(1,0)
!WARNING: Subscript 2 is greater than upper bound 1 for dimension 2 of array
print *, da(1,2)
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What application requires this change?
We have one customer workload that we cannot disclose publicly (it's sort of a cummunity code in Europe), plus NWChem has similar patterns (even though they go undetected). GFortran also just warns and does not error out by default. |
@jeffhammond is this true about nwchem? |
if it's true in NWChem, it's a bug and we will fix it. i want to know about these errors by default. i don't recall this issue when i compiled NWChem with |
It's the usage of Oh yes, these go undetected, as their are based on accesses via variables not constants. But still... |
ugh, if @klausler for context, in theory, we can increase the size by some amount that makes it much harder for the compiler to prove OOB errors (that aren't really errors, thanks to C) but i don't know how well this will work. |
NWChem does not trigger the warning, as the compiler is not smart enough. But that does not mean the problem does not exist. So, yes, the problem is there for NWChem and it is badly UB all over the place.
So, even though the problem does not show up, I'd argue that a less harsh reaction of Flang on case where it can detect that seems useful, given that other compilers are either completely silent about this detectable case (ifort, ifx) or prefer to warn (gfortran). |
It's a fatal error by default with better compilers (NAG & XLF). |
indeed, i agree it should be fatal by default because most of the uses are bad and should be trapped. |
Not really for XLF.
|
I just came across gcc behavior:
So, Flang behavior would be consistent with gcc and g++, too. |
Fortran is neither C nor C++. |
I understand that, even though sometimes I misplace ';' in the code. However, it seems to hint at a certain behavior that users may expect from other compilers and that can make it easier when when moving between compilers and languages. |
Fixes issue #82684.
While out-of-bounds accesses are not permitted by the Fortran standard, the compiler should not produce a fatal error but emit a warning. This is inline with other compilers and can easily be turned into an error via
-Werror
.