Skip to content

Commit a2d7af7

Browse files
authored
[flang] Add notify-type and notify-wait-stmt (llvm#76594)
Add `notify-type` to `iso_fortran_env` module. Add `notify-wait-stmt` to the parser and add checks for constraints on the statement, `C1177` and `C1178`, from the Fortran 2023 standard. Add three semantics tests for `notify-wait-stmt`.
1 parent 0d19a89 commit a2d7af7

File tree

18 files changed

+352
-54
lines changed

18 files changed

+352
-54
lines changed

flang/examples/FeatureList/FeatureList.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,7 @@ struct NodeVisitor {
281281
READ_FEATURE(ErrorRecovery)
282282
READ_FEATURE(EventPostStmt)
283283
READ_FEATURE(EventWaitStmt)
284-
READ_FEATURE(EventWaitStmt::EventWaitSpec)
284+
READ_FEATURE(EventWaitSpec)
285285
READ_FEATURE(ExecutableConstruct)
286286
READ_FEATURE(ExecutionPart)
287287
READ_FEATURE(ExecutionPartConstruct)
@@ -438,6 +438,7 @@ struct NodeVisitor {
438438
READ_FEATURE(NamelistStmt::Group)
439439
READ_FEATURE(NonLabelDoStmt)
440440
READ_FEATURE(NoPass)
441+
READ_FEATURE(NotifyWaitStmt)
441442
READ_FEATURE(NullifyStmt)
442443
READ_FEATURE(NullInit)
443444
READ_FEATURE(ObjectDecl)

flang/include/flang/Evaluate/tools.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1232,6 +1232,7 @@ bool IsBuiltinDerivedType(const DerivedTypeSpec *derived, const char *name);
12321232
bool IsBuiltinCPtr(const Symbol &);
12331233
bool IsEventType(const DerivedTypeSpec *);
12341234
bool IsLockType(const DerivedTypeSpec *);
1235+
bool IsNotifyType(const DerivedTypeSpec *);
12351236
// Is this derived type TEAM_TYPE from module ISO_FORTRAN_ENV?
12361237
bool IsTeamType(const DerivedTypeSpec *);
12371238
// Is this derived type TEAM_TYPE, C_PTR, or C_FUNPTR?

flang/include/flang/Lower/PFTBuilder.h

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -100,13 +100,14 @@ using ActionStmts = std::tuple<
100100
parser::EventPostStmt, parser::EventWaitStmt, parser::ExitStmt,
101101
parser::FailImageStmt, parser::FlushStmt, parser::FormTeamStmt,
102102
parser::GotoStmt, parser::IfStmt, parser::InquireStmt, parser::LockStmt,
103-
parser::NullifyStmt, parser::OpenStmt, parser::PointerAssignmentStmt,
104-
parser::PrintStmt, parser::ReadStmt, parser::ReturnStmt, parser::RewindStmt,
105-
parser::StopStmt, parser::SyncAllStmt, parser::SyncImagesStmt,
106-
parser::SyncMemoryStmt, parser::SyncTeamStmt, parser::UnlockStmt,
107-
parser::WaitStmt, parser::WhereStmt, parser::WriteStmt,
108-
parser::ComputedGotoStmt, parser::ForallStmt, parser::ArithmeticIfStmt,
109-
parser::AssignStmt, parser::AssignedGotoStmt, parser::PauseStmt>;
103+
parser::NotifyWaitStmt, parser::NullifyStmt, parser::OpenStmt,
104+
parser::PointerAssignmentStmt, parser::PrintStmt, parser::ReadStmt,
105+
parser::ReturnStmt, parser::RewindStmt, parser::StopStmt,
106+
parser::SyncAllStmt, parser::SyncImagesStmt, parser::SyncMemoryStmt,
107+
parser::SyncTeamStmt, parser::UnlockStmt, parser::WaitStmt,
108+
parser::WhereStmt, parser::WriteStmt, parser::ComputedGotoStmt,
109+
parser::ForallStmt, parser::ArithmeticIfStmt, parser::AssignStmt,
110+
parser::AssignedGotoStmt, parser::PauseStmt>;
110111

111112
using OtherStmts = std::tuple<parser::EntryStmt, parser::FormatStmt>;
112113

flang/include/flang/Lower/Runtime.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ namespace parser {
3434
struct EventPostStmt;
3535
struct EventWaitStmt;
3636
struct LockStmt;
37+
struct NotifyWaitStmt;
3738
struct PauseStmt;
3839
struct StopStmt;
3940
struct SyncAllStmt;
@@ -49,6 +50,8 @@ class AbstractConverter;
4950

5051
// Lowering of Fortran statement related runtime (other than IO and maths)
5152

53+
void genNotifyWaitStatement(AbstractConverter &,
54+
const parser::NotifyWaitStmt &);
5255
void genEventPostStatement(AbstractConverter &, const parser::EventPostStmt &);
5356
void genEventWaitStatement(AbstractConverter &, const parser::EventWaitStmt &);
5457
void genLockStatement(AbstractConverter &, const parser::LockStmt &);

flang/include/flang/Parser/dump-parse-tree.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -301,8 +301,8 @@ class ParseTreeDumper {
301301
NODE(parser, ErrLabel)
302302
NODE(parser, ErrorRecovery)
303303
NODE(parser, EventPostStmt)
304+
NODE(parser, EventWaitSpec)
304305
NODE(parser, EventWaitStmt)
305-
NODE(EventWaitStmt, EventWaitSpec)
306306
NODE(parser, ExecutableConstruct)
307307
NODE(parser, ExecutionPart)
308308
NODE(parser, ExecutionPartConstruct)
@@ -462,6 +462,7 @@ class ParseTreeDumper {
462462
NODE(NamelistStmt, Group)
463463
NODE(parser, NonLabelDoStmt)
464464
NODE(parser, NoPass)
465+
NODE(parser, NotifyWaitStmt)
465466
NODE(parser, NullifyStmt)
466467
NODE(parser, NullInit)
467468
NODE(parser, ObjectDecl)

flang/include/flang/Parser/parse-tree.h

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -209,11 +209,13 @@ struct ExitStmt; // R1156
209209
struct GotoStmt; // R1157
210210
struct ComputedGotoStmt; // R1158
211211
struct StopStmt; // R1160, R1161
212+
struct NotifyWaitStmt; // F2023: R1166
212213
struct SyncAllStmt; // R1164
213214
struct SyncImagesStmt; // R1166
214215
struct SyncMemoryStmt; // R1168
215216
struct SyncTeamStmt; // R1169
216217
struct EventPostStmt; // R1170, R1171
218+
struct EventWaitSpec; // F2023: R1177
217219
struct EventWaitStmt; // R1172, R1173, R1174
218220
struct FormTeamStmt; // R1175, R1176, R1177
219221
struct LockStmt; // R1178
@@ -477,9 +479,9 @@ EMPTY_CLASS(FailImageStmt);
477479
// close-stmt | continue-stmt | cycle-stmt | deallocate-stmt |
478480
// endfile-stmt | error-stop-stmt | event-post-stmt | event-wait-stmt |
479481
// exit-stmt | fail-image-stmt | flush-stmt | form-team-stmt |
480-
// goto-stmt | if-stmt | inquire-stmt | lock-stmt | nullify-stmt |
481-
// open-stmt | pointer-assignment-stmt | print-stmt | read-stmt |
482-
// return-stmt | rewind-stmt | stop-stmt | sync-all-stmt |
482+
// goto-stmt | if-stmt | inquire-stmt | lock-stmt | notify-wait-stmt |
483+
// nullify-stmt | open-stmt | pointer-assignment-stmt | print-stmt |
484+
// read-stmt | return-stmt | rewind-stmt | stop-stmt | sync-all-stmt |
483485
// sync-images-stmt | sync-memory-stmt | sync-team-stmt | unlock-stmt |
484486
// wait-stmt | where-stmt | write-stmt | computed-goto-stmt | forall-stmt
485487
struct ActionStmt {
@@ -494,8 +496,8 @@ struct ActionStmt {
494496
common::Indirection<FlushStmt>, common::Indirection<FormTeamStmt>,
495497
common::Indirection<GotoStmt>, common::Indirection<IfStmt>,
496498
common::Indirection<InquireStmt>, common::Indirection<LockStmt>,
497-
common::Indirection<NullifyStmt>, common::Indirection<OpenStmt>,
498-
common::Indirection<PointerAssignmentStmt>,
499+
common::Indirection<NotifyWaitStmt>, common::Indirection<NullifyStmt>,
500+
common::Indirection<OpenStmt>, common::Indirection<PointerAssignmentStmt>,
499501
common::Indirection<PrintStmt>, common::Indirection<ReadStmt>,
500502
common::Indirection<ReturnStmt>, common::Indirection<RewindStmt>,
501503
common::Indirection<StopStmt>, common::Indirection<SyncAllStmt>,
@@ -2492,6 +2494,13 @@ struct StopStmt {
24922494
std::tuple<Kind, std::optional<StopCode>, std::optional<ScalarLogicalExpr>> t;
24932495
};
24942496

2497+
// F2023: R1166 notify-wait-stmt -> NOTIFY WAIT ( notify-variable [,
2498+
// event-wait-spec-list] )
2499+
struct NotifyWaitStmt {
2500+
TUPLE_CLASS_BOILERPLATE(NotifyWaitStmt);
2501+
std::tuple<Scalar<Variable>, std::list<EventWaitSpec>> t;
2502+
};
2503+
24952504
// R1164 sync-all-stmt -> SYNC ALL [( [sync-stat-list] )]
24962505
WRAPPER_CLASS(SyncAllStmt, std::list<StatOrErrmsg>);
24972506

@@ -2524,15 +2533,16 @@ struct EventPostStmt {
25242533
std::tuple<EventVariable, std::list<StatOrErrmsg>> t;
25252534
};
25262535

2536+
// R1173 event-wait-spec -> until-spec | sync-stat
2537+
struct EventWaitSpec {
2538+
UNION_CLASS_BOILERPLATE(EventWaitSpec);
2539+
std::variant<ScalarIntExpr, StatOrErrmsg> u;
2540+
};
2541+
25272542
// R1172 event-wait-stmt ->
25282543
// EVENT WAIT ( event-variable [, event-wait-spec-list] )
2529-
// R1173 event-wait-spec -> until-spec | sync-stat
25302544
// R1174 until-spec -> UNTIL_COUNT = scalar-int-expr
25312545
struct EventWaitStmt {
2532-
struct EventWaitSpec {
2533-
UNION_CLASS_BOILERPLATE(EventWaitSpec);
2534-
std::variant<ScalarIntExpr, StatOrErrmsg> u;
2535-
};
25362546
TUPLE_CLASS_BOILERPLATE(EventWaitStmt);
25372547
std::tuple<EventVariable, std::list<EventWaitSpec>> t;
25382548
};

flang/lib/Evaluate/tools.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1765,6 +1765,10 @@ bool IsLockType(const DerivedTypeSpec *derived) {
17651765
return IsBuiltinDerivedType(derived, "lock_type");
17661766
}
17671767

1768+
bool IsNotifyType(const DerivedTypeSpec *derived) {
1769+
return IsBuiltinDerivedType(derived, "notify_type");
1770+
}
1771+
17681772
bool IsTeamType(const DerivedTypeSpec *derived) {
17691773
return IsBuiltinDerivedType(derived, "team_type");
17701774
}

flang/lib/Lower/Bridge.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3092,6 +3092,10 @@ class FirConverter : public Fortran::lower::AbstractConverter {
30923092

30933093
//===--------------------------------------------------------------------===//
30943094

3095+
void genFIR(const Fortran::parser::NotifyWaitStmt &stmt) {
3096+
genNotifyWaitStatement(*this, stmt);
3097+
}
3098+
30953099
void genFIR(const Fortran::parser::EventPostStmt &stmt) {
30963100
genEventPostStatement(*this, stmt);
30973101
}

flang/lib/Lower/Runtime.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,12 @@ void Fortran::lower::genFailImageStatement(
137137
genUnreachable(builder, loc);
138138
}
139139

140+
void Fortran::lower::genNotifyWaitStatement(
141+
Fortran::lower::AbstractConverter &converter,
142+
const Fortran::parser::NotifyWaitStmt &) {
143+
TODO(converter.getCurrentLocation(), "coarray: NOTIFY WAIT runtime");
144+
}
145+
140146
void Fortran::lower::genEventPostStatement(
141147
Fortran::lower::AbstractConverter &converter,
142148
const Fortran::parser::EventPostStmt &) {

flang/lib/Parser/executable-parsers.cpp

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -92,9 +92,9 @@ TYPE_CONTEXT_PARSER("execution part"_en_US,
9292
// close-stmt | continue-stmt | cycle-stmt | deallocate-stmt |
9393
// endfile-stmt | error-stop-stmt | event-post-stmt | event-wait-stmt |
9494
// exit-stmt | fail-image-stmt | flush-stmt | form-team-stmt |
95-
// goto-stmt | if-stmt | inquire-stmt | lock-stmt | nullify-stmt |
96-
// open-stmt | pointer-assignment-stmt | print-stmt | read-stmt |
97-
// return-stmt | rewind-stmt | stop-stmt | sync-all-stmt |
95+
// goto-stmt | if-stmt | inquire-stmt | lock-stmt | notify-wait-stmt |
96+
// nullify-stmt | open-stmt | pointer-assignment-stmt | print-stmt |
97+
// read-stmt | return-stmt | rewind-stmt | stop-stmt | sync-all-stmt |
9898
// sync-images-stmt | sync-memory-stmt | sync-team-stmt | unlock-stmt |
9999
// wait-stmt | where-stmt | write-stmt | computed-goto-stmt | forall-stmt
100100
// R1159 continue-stmt -> CONTINUE
@@ -119,6 +119,7 @@ TYPE_PARSER(first(construct<ActionStmt>(indirect(Parser<AllocateStmt>{})),
119119
construct<ActionStmt>(indirect(Parser<IfStmt>{})),
120120
construct<ActionStmt>(indirect(Parser<InquireStmt>{})),
121121
construct<ActionStmt>(indirect(Parser<LockStmt>{})),
122+
construct<ActionStmt>(indirect(Parser<NotifyWaitStmt>{})),
122123
construct<ActionStmt>(indirect(Parser<NullifyStmt>{})),
123124
construct<ActionStmt>(indirect(Parser<OpenStmt>{})),
124125
construct<ActionStmt>(indirect(Parser<PrintStmt>{})),
@@ -453,6 +454,13 @@ TYPE_CONTEXT_PARSER("STOP statement"_en_US,
453454
// parse time.
454455
TYPE_PARSER(construct<StopCode>(scalar(expr)))
455456

457+
// F2030: R1166 notify-wait-stmt ->
458+
// NOTIFY WAIT ( notify-variable [, event-wait-spec-list] )
459+
TYPE_CONTEXT_PARSER("NOTIFY WAIT statement"_en_US,
460+
construct<NotifyWaitStmt>(
461+
"NOTIFY WAIT"_sptok >> "("_tok >> scalar(variable),
462+
defaulted("," >> nonemptyList(Parser<EventWaitSpec>{})) / ")"))
463+
456464
// R1164 sync-all-stmt -> SYNC ALL [( [sync-stat-list] )]
457465
TYPE_CONTEXT_PARSER("SYNC ALL statement"_en_US,
458466
construct<SyncAllStmt>("SYNC ALL"_sptok >>
@@ -486,15 +494,14 @@ TYPE_CONTEXT_PARSER("EVENT POST statement"_en_US,
486494
// EVENT WAIT ( event-variable [, event-wait-spec-list] )
487495
TYPE_CONTEXT_PARSER("EVENT WAIT statement"_en_US,
488496
construct<EventWaitStmt>("EVENT WAIT"_sptok >> "("_tok >> scalar(variable),
489-
defaulted("," >> nonemptyList(Parser<EventWaitStmt::EventWaitSpec>{})) /
490-
")"))
497+
defaulted("," >> nonemptyList(Parser<EventWaitSpec>{})) / ")"))
491498

492499
// R1174 until-spec -> UNTIL_COUNT = scalar-int-expr
493500
constexpr auto untilSpec{"UNTIL_COUNT =" >> scalarIntExpr};
494501

495502
// R1173 event-wait-spec -> until-spec | sync-stat
496-
TYPE_PARSER(construct<EventWaitStmt::EventWaitSpec>(untilSpec) ||
497-
construct<EventWaitStmt::EventWaitSpec>(statOrErrmsg))
503+
TYPE_PARSER(construct<EventWaitSpec>(untilSpec) ||
504+
construct<EventWaitSpec>(statOrErrmsg))
498505

499506
// R1177 team-variable -> scalar-variable
500507
constexpr auto teamVariable{scalar(variable)};

flang/lib/Parser/unparse.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1150,6 +1150,11 @@ class UnparseVisitor {
11501150
void Unparse(const FailImageStmt &) { // R1163
11511151
Word("FAIL IMAGE");
11521152
}
1153+
void Unparse(const NotifyWaitStmt &x) { // F2023: R1166
1154+
Word("NOTIFY WAIT ("), Walk(std::get<Scalar<Variable>>(x.t));
1155+
Walk(", ", std::get<std::list<EventWaitSpec>>(x.t), ", ");
1156+
Put(')');
1157+
}
11531158
void Unparse(const SyncAllStmt &x) { // R1164
11541159
Word("SYNC ALL ("), Walk(x.v, ", "), Put(')');
11551160
}
@@ -1169,7 +1174,7 @@ class UnparseVisitor {
11691174
Word("EVENT POST ("), Walk(std::get<EventVariable>(x.t));
11701175
Walk(", ", std::get<std::list<StatOrErrmsg>>(x.t), ", "), Put(')');
11711176
}
1172-
void Before(const EventWaitStmt::EventWaitSpec &x) { // R1173, R1174
1177+
void Before(const EventWaitSpec &x) { // R1173, R1174
11731178
common::visit(common::visitors{
11741179
[&](const ScalarIntExpr &) { Word("UNTIL_COUNT="); },
11751180
[](const StatOrErrmsg &) {},
@@ -1178,7 +1183,7 @@ class UnparseVisitor {
11781183
}
11791184
void Unparse(const EventWaitStmt &x) { // R1170
11801185
Word("EVENT WAIT ("), Walk(std::get<EventVariable>(x.t));
1181-
Walk(", ", std::get<std::list<EventWaitStmt::EventWaitSpec>>(x.t), ", ");
1186+
Walk(", ", std::get<std::list<EventWaitSpec>>(x.t), ", ");
11821187
Put(')');
11831188
}
11841189
void Unparse(const FormTeamStmt &x) { // R1175, R1177

flang/lib/Semantics/check-coarray.cpp

Lines changed: 51 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -177,32 +177,15 @@ void CoarrayChecker::Leave(const parser::SyncTeamStmt &x) {
177177
CheckSyncStatList(context_, std::get<std::list<parser::StatOrErrmsg>>(x.t));
178178
}
179179

180-
void CoarrayChecker::Leave(const parser::EventPostStmt &x) {
181-
CheckSyncStatList(context_, std::get<std::list<parser::StatOrErrmsg>>(x.t));
182-
CheckEventVariable(context_, std::get<parser::EventVariable>(x.t));
183-
}
184-
185-
void CoarrayChecker::Leave(const parser::EventWaitStmt &x) {
186-
const auto &eventVar{std::get<parser::EventVariable>(x.t)};
187-
188-
if (const auto *expr{GetExpr(context_, eventVar)}) {
189-
if (ExtractCoarrayRef(expr)) {
190-
context_.Say(parser::FindSourceLocation(eventVar), // C1177
191-
"A event-variable in a EVENT WAIT statement may not be a coindexed object"_err_en_US);
192-
} else {
193-
CheckEventVariable(context_, eventVar);
194-
}
195-
}
196-
180+
static void CheckEventWaitSpecList(SemanticsContext &context,
181+
const std::list<parser::EventWaitSpec> &eventWaitSpecList) {
197182
bool gotStat{false}, gotMsg{false}, gotUntil{false};
198-
using EventWaitSpec = parser::EventWaitStmt::EventWaitSpec;
199-
for (const EventWaitSpec &eventWaitSpec :
200-
std::get<std::list<EventWaitSpec>>(x.t)) {
183+
for (const parser::EventWaitSpec &eventWaitSpec : eventWaitSpecList) {
201184
common::visit(
202185
common::visitors{
203186
[&](const parser::ScalarIntExpr &untilCount) {
204187
if (gotUntil) {
205-
context_.Say( // C1178
188+
context.Say( // C1178
206189
"Until-spec in a event-wait-spec-list may not be repeated"_err_en_US);
207190
}
208191
gotUntil = true;
@@ -212,32 +195,74 @@ void CoarrayChecker::Leave(const parser::EventWaitStmt &x) {
212195
common::visitors{
213196
[&](const parser::StatVariable &stat) {
214197
if (gotStat) {
215-
context_.Say( // C1178
198+
context.Say( // C1178
216199
"A stat-variable in a event-wait-spec-list may not be repeated"_err_en_US);
217200
}
218201
gotStat = true;
219202
},
220203
[&](const parser::MsgVariable &var) {
221-
WarnOnDeferredLengthCharacterScalar(context_,
222-
GetExpr(context_, var),
204+
WarnOnDeferredLengthCharacterScalar(context,
205+
GetExpr(context, var),
223206
var.v.thing.thing.GetSource(), "ERRMSG=");
224207
if (gotMsg) {
225-
context_.Say( // C1178
208+
context.Say( // C1178
226209
"A errmsg-variable in a event-wait-spec-list may not be repeated"_err_en_US);
227210
}
228211
gotMsg = true;
229212
},
230213
},
231214
statOrErrmsg.u);
232215
CheckCoindexedStatOrErrmsg(
233-
context_, statOrErrmsg, "event-wait-spec-list");
216+
context, statOrErrmsg, "event-wait-spec-list");
234217
},
235218

236219
},
237220
eventWaitSpec.u);
238221
}
239222
}
240223

224+
void CoarrayChecker::Leave(const parser::NotifyWaitStmt &x) {
225+
const auto &notifyVar{std::get<parser::Scalar<parser::Variable>>(x.t)};
226+
227+
if (const auto *expr{GetExpr(context_, notifyVar)}) {
228+
if (ExtractCoarrayRef(expr)) {
229+
context_.Say(parser::FindSourceLocation(notifyVar), // F2023 - C1178
230+
"A notify-variable in a NOTIFY WAIT statement may not be a coindexed object"_err_en_US);
231+
} else if (!IsNotifyType(evaluate::GetDerivedTypeSpec(
232+
expr->GetType()))) { // F2023 - C1177
233+
context_.Say(parser::FindSourceLocation(notifyVar),
234+
"The notify-variable must be of type NOTIFY_TYPE from module ISO_FORTRAN_ENV"_err_en_US);
235+
} else if (!evaluate::IsCoarray(*expr)) { // F2023 - C1612
236+
context_.Say(parser::FindSourceLocation(notifyVar),
237+
"The notify-variable must be a coarray"_err_en_US);
238+
}
239+
}
240+
241+
CheckEventWaitSpecList(
242+
context_, std::get<std::list<parser::EventWaitSpec>>(x.t));
243+
}
244+
245+
void CoarrayChecker::Leave(const parser::EventPostStmt &x) {
246+
CheckSyncStatList(context_, std::get<std::list<parser::StatOrErrmsg>>(x.t));
247+
CheckEventVariable(context_, std::get<parser::EventVariable>(x.t));
248+
}
249+
250+
void CoarrayChecker::Leave(const parser::EventWaitStmt &x) {
251+
const auto &eventVar{std::get<parser::EventVariable>(x.t)};
252+
253+
if (const auto *expr{GetExpr(context_, eventVar)}) {
254+
if (ExtractCoarrayRef(expr)) {
255+
context_.Say(parser::FindSourceLocation(eventVar), // C1177
256+
"A event-variable in a EVENT WAIT statement may not be a coindexed object"_err_en_US);
257+
} else {
258+
CheckEventVariable(context_, eventVar);
259+
}
260+
}
261+
262+
CheckEventWaitSpecList(
263+
context_, std::get<std::list<parser::EventWaitSpec>>(x.t));
264+
}
265+
241266
void CoarrayChecker::Leave(const parser::UnlockStmt &x) {
242267
CheckSyncStatList(context_, std::get<std::list<parser::StatOrErrmsg>>(x.t));
243268
}

0 commit comments

Comments
 (0)