forked from OSchip/llvm-project
[flang] Add a check for DO step expressions being zero
This is prohibited by Section 11.1.7.4.1, paragraph 1. Note also that we allow for REAL step expressions. But the check I added only works for INTEGER step expressions. I added a function to tools.cc to test to see if an expression is zero, and I added calls to check-do.cc for regular and CONCURRENT DO statements to this function. I made the regular DO a warning and the DO CONCURRENT message an error. I added tests for the DO CONCURRENT case, including a test that uses an integer constant. Original-commit: flang-compiler/f18@8c4fadfe00 Reviewed-on: https://github.com/flang-compiler/f18/pull/834
This commit is contained in:
parent
b0823c7b69
commit
7139a04e31
|
@ -464,7 +464,6 @@ private:
|
|||
if (isReal && !warn) {
|
||||
// No messages for the default case
|
||||
} else if (isReal && warn) {
|
||||
// TODO: Mark the following message as a warning when we have warnings
|
||||
context_.Say(sourceLocation, "DO controls should be INTEGER"_en_US);
|
||||
} else {
|
||||
SayBadDoControl(sourceLocation);
|
||||
|
@ -510,7 +509,11 @@ private:
|
|||
CheckDoExpression(bounds.lower);
|
||||
CheckDoExpression(bounds.upper);
|
||||
if (bounds.step) {
|
||||
CheckDoExpression(bounds.step.value());
|
||||
CheckDoExpression(*bounds.step);
|
||||
if (IsZero(*bounds.step)) {
|
||||
context_.Say(bounds.step->thing.value().source,
|
||||
"DO step expression should not be zero"_en_US);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -670,6 +673,10 @@ private:
|
|||
if (const auto &expr{
|
||||
std::get<std::optional<parser::ScalarIntExpr>>(c.t)}) {
|
||||
HasNoReferences(indexNames, *expr);
|
||||
if (IsZero(*expr)) {
|
||||
context_.Say(expr->thing.thing.value().source,
|
||||
"DO CONCURRENT step expression should not be zero"_err_en_US);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -272,6 +272,11 @@ template<typename T> std::optional<std::int64_t> GetIntValue(const T &x) {
|
|||
}
|
||||
}
|
||||
|
||||
template<typename T> bool IsZero(const T &expr) {
|
||||
auto value{GetIntValue(expr)};
|
||||
return value && *value == 0;
|
||||
}
|
||||
|
||||
// Derived type component iterator that provides a C++ LegacyForwardIterator
|
||||
// iterator over the Ordered, Direct, Ultimate or Potential components of a
|
||||
// DerivedTypeSpec. These iterators can be used with STL algorithms
|
||||
|
|
|
@ -14,6 +14,9 @@
|
|||
|
||||
! C1121 -- any procedure referenced in a concurrent header must be pure
|
||||
|
||||
! Also, check that the step expressions are not zero. This is prohibited by
|
||||
! Section 11.1.7.4.1, paragraph 1.
|
||||
|
||||
SUBROUTINE do_concurrent_c1121(i,n)
|
||||
IMPLICIT NONE
|
||||
INTEGER :: i, n, flag
|
||||
|
@ -28,3 +31,25 @@ SUBROUTINE do_concurrent_c1121(i,n)
|
|||
i = 35
|
||||
END FUNCTION random
|
||||
END SUBROUTINE do_concurrent_c1121
|
||||
|
||||
SUBROUTINE s1()
|
||||
INTEGER, PARAMETER :: constInt = 0
|
||||
|
||||
! Warn on this one for backwards compatibility
|
||||
DO 10 I = 1, 10, 0
|
||||
10 CONTINUE
|
||||
|
||||
! Warn on this one for backwards compatibility
|
||||
DO 20 I = 1, 10, 5 - 5
|
||||
20 CONTINUE
|
||||
|
||||
! Error, no compatibility requirement for DO CONCURRENT
|
||||
!ERROR: DO CONCURRENT step expression should not be zero
|
||||
DO CONCURRENT (I = 1 : 10 : 0)
|
||||
END DO
|
||||
|
||||
! Error, this time with an integer constant
|
||||
!ERROR: DO CONCURRENT step expression should not be zero
|
||||
DO CONCURRENT (I = 1 : 10 : constInt)
|
||||
END DO
|
||||
end subroutine s1
|
||||
|
|
|
@ -46,7 +46,7 @@ subroutine s1()
|
|||
! References in this DO CONCURRENT are OK since there's no DEFAULT(NONE)
|
||||
! locality-spec
|
||||
associate (avar => ivar)
|
||||
do concurrent (i = 1:2:0) shared(jvar)
|
||||
do concurrent (i = 1:2) shared(jvar)
|
||||
ivar = 3
|
||||
ivar = ivar + i
|
||||
block
|
||||
|
@ -61,6 +61,7 @@ subroutine s1()
|
|||
end associate
|
||||
|
||||
associate (avar => ivar)
|
||||
!ERROR: DO CONCURRENT step expression should not be zero
|
||||
do concurrent (i = 1:2:0) default(none) shared(jvar) local(kvar)
|
||||
!ERROR: Variable 'ivar' from an enclosing scope referenced in DO CONCURRENT with DEFAULT(NONE) must appear in a locality-spec
|
||||
ivar = &
|
||||
|
|
Loading…
Reference in New Issue