[flang-commits] [flang] 15fa287 - [flang] Support for image selectors
Pete Steinfeld via flang-commits
flang-commits at lists.llvm.org
Wed Jul 8 07:32:16 PDT 2020
Author: Pete Steinfeld
Date: 2020-07-08T07:31:54-07:00
New Revision: 15fa287b64d0ef845201339994cdf6eb3e4d51e1
URL: https://github.com/llvm/llvm-project/commit/15fa287b64d0ef845201339994cdf6eb3e4d51e1
DIFF: https://github.com/llvm/llvm-project/commit/15fa287b64d0ef845201339994cdf6eb3e4d51e1.diff
LOG: [flang] Support for image selectors
Summary:
This change implements support for image selectors and image selector
specifications as described in section 9.6.
In check-coarray[.h,cpp] I changed the `Leave()` function for
`parser::ImageSelectorSpec` to take a `parser::ImageSelector`, which
contains a list of image selector specifications. This allows us to
detect when the same specification is used more than once. I also added
code to analyze the expressions for the image selector specifications to
expression.cpp and a test for all of the conditions to check at
compile-time.
Note that we do not check at compile-time to see if the value of the
cosubscripts are within the specified cobounds. We also do not check anything
related to selecting a valid team. We also do not check that the denotation of
the `stat-variable` is not dependent on the evaluation of an entity in the
same statement.
Reviewers: klausler, tskeith, DavidTruby
Subscribers: llvm-commits
Tags: #llvm, #flang
Differential Revision: https://reviews.llvm.org/D83336
Added:
flang/test/Semantics/resolve94.f90
Modified:
flang/include/flang/Parser/tools.h
flang/lib/Parser/tools.cpp
flang/lib/Semantics/check-coarray.cpp
flang/lib/Semantics/check-coarray.h
flang/lib/Semantics/expression.cpp
Removed:
################################################################################
diff --git a/flang/include/flang/Parser/tools.h b/flang/include/flang/Parser/tools.h
index c918425a2978..fa6ecd08a318 100644
--- a/flang/include/flang/Parser/tools.h
+++ b/flang/include/flang/Parser/tools.h
@@ -99,6 +99,8 @@ template <typename A, typename B> A *Unwrap(B &x) {
// Get the CoindexedNamedObject if the entity is a coindexed object.
const CoindexedNamedObject *GetCoindexedNamedObject(const AllocateObject &);
const CoindexedNamedObject *GetCoindexedNamedObject(const DataRef &);
+const CoindexedNamedObject *GetCoindexedNamedObject(const Designator &);
+const CoindexedNamedObject *GetCoindexedNamedObject(const Variable &);
// Detects parse tree nodes with "source" members.
template <typename A, typename = int> struct HasSource : std::false_type {};
diff --git a/flang/lib/Parser/tools.cpp b/flang/lib/Parser/tools.cpp
index 0a21e73839ed..2db832ab715f 100644
--- a/flang/lib/Parser/tools.cpp
+++ b/flang/lib/Parser/tools.cpp
@@ -135,6 +135,30 @@ const CoindexedNamedObject *GetCoindexedNamedObject(const DataRef &base) {
},
base.u);
}
+const CoindexedNamedObject *GetCoindexedNamedObject(
+ const Designator &designator) {
+ return std::visit(common::visitors{
+ [](const DataRef &x) -> const CoindexedNamedObject * {
+ return GetCoindexedNamedObject(x);
+ },
+ [](const Substring &x) -> const CoindexedNamedObject * {
+ return GetCoindexedNamedObject(
+ std::get<DataRef>(x.t));
+ },
+ },
+ designator.u);
+}
+const CoindexedNamedObject *GetCoindexedNamedObject(const Variable &variable) {
+ return std::visit(
+ common::visitors{
+ [](const common::Indirection<Designator> &designator)
+ -> const CoindexedNamedObject * {
+ return GetCoindexedNamedObject(designator.value());
+ },
+ [](const auto &) -> const CoindexedNamedObject * { return nullptr; },
+ },
+ variable.u);
+}
const CoindexedNamedObject *GetCoindexedNamedObject(
const AllocateObject &allocateObject) {
return std::visit(
diff --git a/flang/lib/Semantics/check-coarray.cpp b/flang/lib/Semantics/check-coarray.cpp
index a9d649ffff47..4ce286d0bca1 100644
--- a/flang/lib/Semantics/check-coarray.cpp
+++ b/flang/lib/Semantics/check-coarray.cpp
@@ -72,6 +72,16 @@ static void CheckTeamType(SemanticsContext &context, const T &x) {
}
}
+static void CheckTeamStat(
+ SemanticsContext &context, const parser::ImageSelectorSpec::Stat &stat) {
+ const parser::Variable &var{stat.v.thing.thing.value()};
+ if (parser::GetCoindexedNamedObject(var)) {
+ context.Say(parser::FindSourceLocation(var), // C931
+ "Image selector STAT variable must not be a coindexed "
+ "object"_err_en_US);
+ }
+}
+
void CoarrayChecker::Leave(const parser::ChangeTeamStmt &x) {
CheckNamesAreDistinct(std::get<std::list<parser::CoarrayAssociation>>(x.t));
CheckTeamType(context_, std::get<parser::TeamValue>(x.t));
@@ -81,9 +91,42 @@ void CoarrayChecker::Leave(const parser::SyncTeamStmt &x) {
CheckTeamType(context_, std::get<parser::TeamValue>(x.t));
}
-void CoarrayChecker::Leave(const parser::ImageSelectorSpec &x) {
- if (const auto *team{std::get_if<parser::TeamValue>(&x.u)}) {
- CheckTeamType(context_, *team);
+void CoarrayChecker::Leave(const parser::ImageSelector &imageSelector) {
+ haveStat_ = false;
+ haveTeam_ = false;
+ haveTeamNumber_ = false;
+ for (const auto &imageSelectorSpec :
+ std::get<std::list<parser::ImageSelectorSpec>>(imageSelector.t)) {
+ if (const auto *team{
+ std::get_if<parser::TeamValue>(&imageSelectorSpec.u)}) {
+ if (haveTeam_) {
+ context_.Say(parser::FindSourceLocation(imageSelectorSpec), // C929
+ "TEAM value can only be specified once"_err_en_US);
+ }
+ CheckTeamType(context_, *team);
+ haveTeam_ = true;
+ }
+ if (const auto *stat{std::get_if<parser::ImageSelectorSpec::Stat>(
+ &imageSelectorSpec.u)}) {
+ if (haveStat_) {
+ context_.Say(parser::FindSourceLocation(imageSelectorSpec), // C929
+ "STAT variable can only be specified once"_err_en_US);
+ }
+ CheckTeamStat(context_, *stat);
+ haveStat_ = true;
+ }
+ if (std::get_if<parser::ImageSelectorSpec::Team_Number>(
+ &imageSelectorSpec.u)) {
+ if (haveTeamNumber_) {
+ context_.Say(parser::FindSourceLocation(imageSelectorSpec), // C929
+ "TEAM_NUMBER value can only be specified once"_err_en_US);
+ }
+ haveTeamNumber_ = true;
+ }
+ }
+ if (haveTeam_ && haveTeamNumber_) {
+ context_.Say(parser::FindSourceLocation(imageSelector), // C930
+ "Cannot specify both TEAM and TEAM_NUMBER"_err_en_US);
}
}
diff --git a/flang/lib/Semantics/check-coarray.h b/flang/lib/Semantics/check-coarray.h
index 2e91c7b259d6..5f30dda6b547 100644
--- a/flang/lib/Semantics/check-coarray.h
+++ b/flang/lib/Semantics/check-coarray.h
@@ -18,9 +18,8 @@ class MessageFixedText;
struct ChangeTeamStmt;
struct CoarrayAssociation;
struct FormTeamStmt;
-struct ImageSelectorSpec;
+struct ImageSelector;
struct SyncTeamStmt;
-struct TeamValue;
} // namespace Fortran::parser
namespace Fortran::semantics {
@@ -30,13 +29,16 @@ class CoarrayChecker : public virtual BaseChecker {
CoarrayChecker(SemanticsContext &context) : context_{context} {}
void Leave(const parser::ChangeTeamStmt &);
void Leave(const parser::SyncTeamStmt &);
- void Leave(const parser::ImageSelectorSpec &);
+ void Leave(const parser::ImageSelector &);
void Leave(const parser::FormTeamStmt &);
void Enter(const parser::CriticalConstruct &);
private:
SemanticsContext &context_;
+ bool haveStat_;
+ bool haveTeam_;
+ bool haveTeamNumber_;
void CheckNamesAreDistinct(const std::list<parser::CoarrayAssociation> &);
void Say2(const parser::CharBlock &, parser::MessageFixedText &&,
diff --git a/flang/lib/Semantics/expression.cpp b/flang/lib/Semantics/expression.cpp
index 27fcf5e2db36..71911718c087 100644
--- a/flang/lib/Semantics/expression.cpp
+++ b/flang/lib/Semantics/expression.cpp
@@ -1085,7 +1085,14 @@ MaybeExpr ExpressionAnalyzer::Analyze(const parser::CoindexedNamedObject &x) {
symbol.name(), symbol.Corank(), numCosubscripts);
}
}
- // TODO: stat=/team=/team_number=
+ for (const auto &imageSelSpec :
+ std::get<std::list<parser::ImageSelectorSpec>>(x.imageSelector.t)) {
+ std::visit(
+ common::visitors{
+ [&](const auto &x) {Analyze(x.v); },
+ },
+ imageSelSpec.u);
+ }
// Reverse the chain of symbols so that the base is first and coarray
// ultimate component is last.
return Designate(
diff --git a/flang/test/Semantics/resolve94.f90 b/flang/test/Semantics/resolve94.f90
new file mode 100644
index 000000000000..b38037e2d530
--- /dev/null
+++ b/flang/test/Semantics/resolve94.f90
@@ -0,0 +1,69 @@
+! RUN: %S/test_errors.sh %s %t %f18
+! C929 No specifier shall appear more than once in a given
+! image-selector-spec-list.
+! C930 TEAM and TEAM_NUMBER shall not both appear in the same
+! image-selector-spec-list.
+! C931 A stat-variable in an image-selector shall not be a coindexed object.
+subroutine s1()
+ use ISO_FORTRAN_ENV
+ type(team_type) :: team1, team2
+ real :: rCoarray[10,20,*]
+ real :: rVar1, rVar2
+ integer :: iVar1, iVar2
+ integer, dimension(4) :: intArray
+ integer :: intScalarCoarray[*]
+ integer :: intCoarray[3, 4, *]
+ intCoVar = 343
+ ! OK
+ rVar1 = rCoarray[1,2,3]
+ !ERROR: 'rcoarray' has corank 3, but coindexed reference has 2 cosubscripts
+ rVar1 = rCoarray[1,2]
+ !ERROR: Must have INTEGER type, but is REAL(4)
+ rVar1 = rCoarray[1,2,3.4]
+ !ERROR: Must be a scalar value, but is a rank-1 array
+ rVar1 = rCoarray[1,intArray,3]
+ ! OK
+ rVar1 = rCoarray[1,2,3,STAT=iVar1, TEAM=team2]
+ !ERROR: Team value must be of type TEAM_TYPE from module ISO_FORTRAN_ENV
+ rVar1 = rCoarray[1,2,3,STAT=iVar1, TEAM=2]
+ ! OK
+ rVar1 = rCoarray[1,2,3,STAT=iVar1, TEAM_NUMBER=38]
+ ! OK
+ rVar1 = rCoarray[1,2,3,STAT=iVar1]
+ ! OK
+ rVar1 = rCoarray[1,2,3,STAT=intArray(2)]
+ !ERROR: Must have INTEGER type, but is REAL(4)
+ rVar1 = rCoarray[1,2,3,STAT=rVar2]
+ !ERROR: Must be a scalar value, but is a rank-1 array
+ rVar1 = rCoarray[1,2,3,STAT=intArray]
+ ! Error on C929, no specifier can appear more than once
+ !ERROR: STAT variable can only be specified once
+ rVar1 = rCoarray[1,2,3,STAT=iVar1, STAT=iVar2]
+ ! OK
+ rVar1 = rCoarray[1,2,3,TEAM=team1]
+ ! Error on C929, no specifier can appear more than once
+ !ERROR: TEAM value can only be specified once
+ rVar1 = rCoarray[1,2,3,TEAM=team1, TEAM=team2]
+ ! OK
+ rVar1 = rCoarray[1,2,3,TEAM_NUMBER=37]
+ ! OK
+ rVar1 = rCoarray[1,2,3,TEAM_NUMBER=iVar1]
+ ! Error, team number is a scalar integer expression
+ !ERROR: Must be a scalar value, but is a rank-1 array
+ rVar1 = rCoarray[1,2,3,TEAM_NUMBER=intArray]
+ ! Error, team number is a scalar integer expression
+ !ERROR: Must have INTEGER type, but is REAL(4)
+ rVar1 = rCoarray[1,2,3,TEAM_NUMBER=3.7]
+ ! Error on C929, no specifier can appear more than once
+ !ERROR: TEAM_NUMBER value can only be specified once
+ rVar1 = rCoarray[1,2,3,TEAM_NUMBER=37, TEAM_NUMBER=37]
+ !ERROR: Cannot specify both TEAM and TEAM_NUMBER
+ rVar1 = rCoarray[1,2,3,TEAM=team1, TEAM_NUMBER=37]
+ !ERROR: Cannot specify both TEAM and TEAM_NUMBER
+ rVar1 = rCoarray[1,2,3,TEAM_number=43, TEAM=team1]
+ ! OK for a STAT variable to be a coarray integer
+ rVar1 = rCoarray[1,2,3,stat=intScalarCoarray]
+ ! Error for a STAT variable to be a coindexed object
+ !ERROR: Image selector STAT variable must not be a coindexed object
+ rVar1 = rCoarray[1,2,3,stat=intCoarray[2,3, 4]]
+end subroutine s1
More information about the flang-commits
mailing list