diff --git a/flang/lib/Semantics/check-data.cpp b/flang/lib/Semantics/check-data.cpp index 955998bedc0c4..f33258ea7c19a 100644 --- a/flang/lib/Semantics/check-data.cpp +++ b/flang/lib/Semantics/check-data.cpp @@ -179,24 +179,27 @@ class DataVarChecker : public evaluate::AllTraverse { bool isFirstSymbol_{true}; }; +static bool IsValidDataObject(const SomeExpr &expr) { // C878, C879 + return !evaluate::IsConstantExpr(expr) && + (evaluate::IsVariable(expr) || evaluate::IsProcedurePointer(expr)); +} + void DataChecker::Leave(const parser::DataIDoObject &object) { if (const auto *designator{ std::get_if>>( &object.u)}) { if (MaybeExpr expr{exprAnalyzer_.Analyze(*designator)}) { auto source{designator->thing.value().source}; - if (evaluate::IsConstantExpr(*expr)) { // C878,C879 - exprAnalyzer_.context().Say( - source, "Data implied do object must be a variable"_err_en_US); - } else { - DataVarChecker checker{exprAnalyzer_.context(), source}; - if (checker(*expr)) { - if (checker.HasComponentWithoutSubscripts()) { // C880 - exprAnalyzer_.context().Say(source, - "Data implied do structure component must be subscripted"_err_en_US); - } else { - return; - } + DataVarChecker checker{exprAnalyzer_.context(), source}; + if (checker(*expr)) { + if (checker.HasComponentWithoutSubscripts()) { // C880 + exprAnalyzer_.context().Say(source, + "Data implied do structure component must be subscripted"_err_en_US); + } else if (!IsValidDataObject(*expr)) { + exprAnalyzer_.context().Say( + source, "Data implied do object must be a variable"_err_en_US); + } else { + return; } } } @@ -211,9 +214,13 @@ void DataChecker::Leave(const parser::DataStmtObject &dataObject) { }, [&](const auto &var) { auto expr{exprAnalyzer_.Analyze(var)}; + auto source{parser::FindSourceLocation(dataObject)}; if (!expr || - !DataVarChecker{exprAnalyzer_.context(), - parser::FindSourceLocation(dataObject)}(*expr)) { + !DataVarChecker{exprAnalyzer_.context(), source}(*expr)) { + currentSetHasFatalErrors_ = true; + } else if (!IsValidDataObject(*expr)) { + exprAnalyzer_.context().Say( + source, "Data statement object must be a variable"_err_en_US); currentSetHasFatalErrors_ = true; } }, diff --git a/flang/test/Semantics/data03.f90 b/flang/test/Semantics/data03.f90 index b3ed3382036f6..d9bead778433b 100644 --- a/flang/test/Semantics/data03.f90 +++ b/flang/test/Semantics/data03.f90 @@ -1,5 +1,5 @@ ! RUN: %python %S/test_errors.py %s %flang_fc1 -!Testing data constraints : C874 - C875, C878 - C881 +!Testing data constraints : C874 - C875, C878 - C881 module m integer, target :: modarray(1) contains @@ -8,7 +8,7 @@ function f(i) integer, pointer :: f f => modarray(i) end - subroutine CheckObject + subroutine CheckObject type specialNumbers integer one integer numbers(5) @@ -34,6 +34,8 @@ subroutine CheckObject integer :: d(10, 10) character :: name(12) integer :: ind = 2 + !ERROR: Data statement object must be a variable + DATA name%len / 666 / !C874 !ERROR: Data object must not be a coindexed variable DATA a[1] / 1 / @@ -77,7 +79,7 @@ subroutine CheckObject !C881 !ERROR: Data object must have constant subscripts DATA(b(x), i = 1, 5) / 5 * 1 / - !C881 + !C881 !OK: Correct use DATA(nums % numbers(i), i = 1, 5) / 5 * 1 / !C881 @@ -86,5 +88,5 @@ subroutine CheckObject !C881 !OK: Correct use DATA(d(i, 1), i = 1, 10) / 10 * 1 / - end + end end