Skip to content

Commit 15fa287

Browse files
committed
[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
1 parent 26a2247 commit 15fa287

File tree

6 files changed

+154
-7
lines changed

6 files changed

+154
-7
lines changed

flang/include/flang/Parser/tools.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,8 @@ template <typename A, typename B> A *Unwrap(B &x) {
9999
// Get the CoindexedNamedObject if the entity is a coindexed object.
100100
const CoindexedNamedObject *GetCoindexedNamedObject(const AllocateObject &);
101101
const CoindexedNamedObject *GetCoindexedNamedObject(const DataRef &);
102+
const CoindexedNamedObject *GetCoindexedNamedObject(const Designator &);
103+
const CoindexedNamedObject *GetCoindexedNamedObject(const Variable &);
102104

103105
// Detects parse tree nodes with "source" members.
104106
template <typename A, typename = int> struct HasSource : std::false_type {};

flang/lib/Parser/tools.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,30 @@ const CoindexedNamedObject *GetCoindexedNamedObject(const DataRef &base) {
135135
},
136136
base.u);
137137
}
138+
const CoindexedNamedObject *GetCoindexedNamedObject(
139+
const Designator &designator) {
140+
return std::visit(common::visitors{
141+
[](const DataRef &x) -> const CoindexedNamedObject * {
142+
return GetCoindexedNamedObject(x);
143+
},
144+
[](const Substring &x) -> const CoindexedNamedObject * {
145+
return GetCoindexedNamedObject(
146+
std::get<DataRef>(x.t));
147+
},
148+
},
149+
designator.u);
150+
}
151+
const CoindexedNamedObject *GetCoindexedNamedObject(const Variable &variable) {
152+
return std::visit(
153+
common::visitors{
154+
[](const common::Indirection<Designator> &designator)
155+
-> const CoindexedNamedObject * {
156+
return GetCoindexedNamedObject(designator.value());
157+
},
158+
[](const auto &) -> const CoindexedNamedObject * { return nullptr; },
159+
},
160+
variable.u);
161+
}
138162
const CoindexedNamedObject *GetCoindexedNamedObject(
139163
const AllocateObject &allocateObject) {
140164
return std::visit(

flang/lib/Semantics/check-coarray.cpp

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,16 @@ static void CheckTeamType(SemanticsContext &context, const T &x) {
7272
}
7373
}
7474

75+
static void CheckTeamStat(
76+
SemanticsContext &context, const parser::ImageSelectorSpec::Stat &stat) {
77+
const parser::Variable &var{stat.v.thing.thing.value()};
78+
if (parser::GetCoindexedNamedObject(var)) {
79+
context.Say(parser::FindSourceLocation(var), // C931
80+
"Image selector STAT variable must not be a coindexed "
81+
"object"_err_en_US);
82+
}
83+
}
84+
7585
void CoarrayChecker::Leave(const parser::ChangeTeamStmt &x) {
7686
CheckNamesAreDistinct(std::get<std::list<parser::CoarrayAssociation>>(x.t));
7787
CheckTeamType(context_, std::get<parser::TeamValue>(x.t));
@@ -81,9 +91,42 @@ void CoarrayChecker::Leave(const parser::SyncTeamStmt &x) {
8191
CheckTeamType(context_, std::get<parser::TeamValue>(x.t));
8292
}
8393

84-
void CoarrayChecker::Leave(const parser::ImageSelectorSpec &x) {
85-
if (const auto *team{std::get_if<parser::TeamValue>(&x.u)}) {
86-
CheckTeamType(context_, *team);
94+
void CoarrayChecker::Leave(const parser::ImageSelector &imageSelector) {
95+
haveStat_ = false;
96+
haveTeam_ = false;
97+
haveTeamNumber_ = false;
98+
for (const auto &imageSelectorSpec :
99+
std::get<std::list<parser::ImageSelectorSpec>>(imageSelector.t)) {
100+
if (const auto *team{
101+
std::get_if<parser::TeamValue>(&imageSelectorSpec.u)}) {
102+
if (haveTeam_) {
103+
context_.Say(parser::FindSourceLocation(imageSelectorSpec), // C929
104+
"TEAM value can only be specified once"_err_en_US);
105+
}
106+
CheckTeamType(context_, *team);
107+
haveTeam_ = true;
108+
}
109+
if (const auto *stat{std::get_if<parser::ImageSelectorSpec::Stat>(
110+
&imageSelectorSpec.u)}) {
111+
if (haveStat_) {
112+
context_.Say(parser::FindSourceLocation(imageSelectorSpec), // C929
113+
"STAT variable can only be specified once"_err_en_US);
114+
}
115+
CheckTeamStat(context_, *stat);
116+
haveStat_ = true;
117+
}
118+
if (std::get_if<parser::ImageSelectorSpec::Team_Number>(
119+
&imageSelectorSpec.u)) {
120+
if (haveTeamNumber_) {
121+
context_.Say(parser::FindSourceLocation(imageSelectorSpec), // C929
122+
"TEAM_NUMBER value can only be specified once"_err_en_US);
123+
}
124+
haveTeamNumber_ = true;
125+
}
126+
}
127+
if (haveTeam_ && haveTeamNumber_) {
128+
context_.Say(parser::FindSourceLocation(imageSelector), // C930
129+
"Cannot specify both TEAM and TEAM_NUMBER"_err_en_US);
87130
}
88131
}
89132

flang/lib/Semantics/check-coarray.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,8 @@ class MessageFixedText;
1818
struct ChangeTeamStmt;
1919
struct CoarrayAssociation;
2020
struct FormTeamStmt;
21-
struct ImageSelectorSpec;
21+
struct ImageSelector;
2222
struct SyncTeamStmt;
23-
struct TeamValue;
2423
} // namespace Fortran::parser
2524

2625
namespace Fortran::semantics {
@@ -30,13 +29,16 @@ class CoarrayChecker : public virtual BaseChecker {
3029
CoarrayChecker(SemanticsContext &context) : context_{context} {}
3130
void Leave(const parser::ChangeTeamStmt &);
3231
void Leave(const parser::SyncTeamStmt &);
33-
void Leave(const parser::ImageSelectorSpec &);
32+
void Leave(const parser::ImageSelector &);
3433
void Leave(const parser::FormTeamStmt &);
3534

3635
void Enter(const parser::CriticalConstruct &);
3736

3837
private:
3938
SemanticsContext &context_;
39+
bool haveStat_;
40+
bool haveTeam_;
41+
bool haveTeamNumber_;
4042

4143
void CheckNamesAreDistinct(const std::list<parser::CoarrayAssociation> &);
4244
void Say2(const parser::CharBlock &, parser::MessageFixedText &&,

flang/lib/Semantics/expression.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1085,7 +1085,14 @@ MaybeExpr ExpressionAnalyzer::Analyze(const parser::CoindexedNamedObject &x) {
10851085
symbol.name(), symbol.Corank(), numCosubscripts);
10861086
}
10871087
}
1088-
// TODO: stat=/team=/team_number=
1088+
for (const auto &imageSelSpec :
1089+
std::get<std::list<parser::ImageSelectorSpec>>(x.imageSelector.t)) {
1090+
std::visit(
1091+
common::visitors{
1092+
[&](const auto &x) {Analyze(x.v); },
1093+
},
1094+
imageSelSpec.u);
1095+
}
10891096
// Reverse the chain of symbols so that the base is first and coarray
10901097
// ultimate component is last.
10911098
return Designate(

flang/test/Semantics/resolve94.f90

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
! RUN: %S/test_errors.sh %s %t %f18
2+
! C929 No specifier shall appear more than once in a given
3+
! image-selector-spec-list.
4+
! C930 TEAM and TEAM_NUMBER shall not both appear in the same
5+
! image-selector-spec-list.
6+
! C931 A stat-variable in an image-selector shall not be a coindexed object.
7+
subroutine s1()
8+
use ISO_FORTRAN_ENV
9+
type(team_type) :: team1, team2
10+
real :: rCoarray[10,20,*]
11+
real :: rVar1, rVar2
12+
integer :: iVar1, iVar2
13+
integer, dimension(4) :: intArray
14+
integer :: intScalarCoarray[*]
15+
integer :: intCoarray[3, 4, *]
16+
intCoVar = 343
17+
! OK
18+
rVar1 = rCoarray[1,2,3]
19+
!ERROR: 'rcoarray' has corank 3, but coindexed reference has 2 cosubscripts
20+
rVar1 = rCoarray[1,2]
21+
!ERROR: Must have INTEGER type, but is REAL(4)
22+
rVar1 = rCoarray[1,2,3.4]
23+
!ERROR: Must be a scalar value, but is a rank-1 array
24+
rVar1 = rCoarray[1,intArray,3]
25+
! OK
26+
rVar1 = rCoarray[1,2,3,STAT=iVar1, TEAM=team2]
27+
!ERROR: Team value must be of type TEAM_TYPE from module ISO_FORTRAN_ENV
28+
rVar1 = rCoarray[1,2,3,STAT=iVar1, TEAM=2]
29+
! OK
30+
rVar1 = rCoarray[1,2,3,STAT=iVar1, TEAM_NUMBER=38]
31+
! OK
32+
rVar1 = rCoarray[1,2,3,STAT=iVar1]
33+
! OK
34+
rVar1 = rCoarray[1,2,3,STAT=intArray(2)]
35+
!ERROR: Must have INTEGER type, but is REAL(4)
36+
rVar1 = rCoarray[1,2,3,STAT=rVar2]
37+
!ERROR: Must be a scalar value, but is a rank-1 array
38+
rVar1 = rCoarray[1,2,3,STAT=intArray]
39+
! Error on C929, no specifier can appear more than once
40+
!ERROR: STAT variable can only be specified once
41+
rVar1 = rCoarray[1,2,3,STAT=iVar1, STAT=iVar2]
42+
! OK
43+
rVar1 = rCoarray[1,2,3,TEAM=team1]
44+
! Error on C929, no specifier can appear more than once
45+
!ERROR: TEAM value can only be specified once
46+
rVar1 = rCoarray[1,2,3,TEAM=team1, TEAM=team2]
47+
! OK
48+
rVar1 = rCoarray[1,2,3,TEAM_NUMBER=37]
49+
! OK
50+
rVar1 = rCoarray[1,2,3,TEAM_NUMBER=iVar1]
51+
! Error, team number is a scalar integer expression
52+
!ERROR: Must be a scalar value, but is a rank-1 array
53+
rVar1 = rCoarray[1,2,3,TEAM_NUMBER=intArray]
54+
! Error, team number is a scalar integer expression
55+
!ERROR: Must have INTEGER type, but is REAL(4)
56+
rVar1 = rCoarray[1,2,3,TEAM_NUMBER=3.7]
57+
! Error on C929, no specifier can appear more than once
58+
!ERROR: TEAM_NUMBER value can only be specified once
59+
rVar1 = rCoarray[1,2,3,TEAM_NUMBER=37, TEAM_NUMBER=37]
60+
!ERROR: Cannot specify both TEAM and TEAM_NUMBER
61+
rVar1 = rCoarray[1,2,3,TEAM=team1, TEAM_NUMBER=37]
62+
!ERROR: Cannot specify both TEAM and TEAM_NUMBER
63+
rVar1 = rCoarray[1,2,3,TEAM_number=43, TEAM=team1]
64+
! OK for a STAT variable to be a coarray integer
65+
rVar1 = rCoarray[1,2,3,stat=intScalarCoarray]
66+
! Error for a STAT variable to be a coindexed object
67+
!ERROR: Image selector STAT variable must not be a coindexed object
68+
rVar1 = rCoarray[1,2,3,stat=intCoarray[2,3, 4]]
69+
end subroutine s1

0 commit comments

Comments
 (0)