diff options
Diffstat (limited to 'flang/lib/Semantics/check-coarray.cpp')
-rw-r--r-- | flang/lib/Semantics/check-coarray.cpp | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/flang/lib/Semantics/check-coarray.cpp b/flang/lib/Semantics/check-coarray.cpp index f291a80a7033..688c3a7c92ad 100644 --- a/flang/lib/Semantics/check-coarray.cpp +++ b/flang/lib/Semantics/check-coarray.cpp @@ -124,6 +124,19 @@ static void CheckSyncStatList( } } +static void CheckEventVariable( + SemanticsContext &context, const parser::EventVariable &eventVar) { + if (const auto *expr{GetExpr(context, eventVar)}) { + if (!IsEventType(evaluate::GetDerivedTypeSpec(expr->GetType()))) { // C1176 + context.Say(parser::FindSourceLocation(eventVar), + "The event-variable must be of type EVENT_TYPE from module ISO_FORTRAN_ENV"_err_en_US); + } else if (!evaluate::IsCoarray(*expr)) { // C1604 + context.Say(parser::FindSourceLocation(eventVar), + "The event-variable must be a coarray"_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)); @@ -156,6 +169,64 @@ void CoarrayChecker::Leave(const parser::SyncTeamStmt &x) { CheckSyncStatList(context_, std::get<std::list<parser::StatOrErrmsg>>(x.t)); } +void CoarrayChecker::Leave(const parser::EventPostStmt &x) { + CheckSyncStatList(context_, std::get<std::list<parser::StatOrErrmsg>>(x.t)); + CheckEventVariable(context_, std::get<parser::EventVariable>(x.t)); +} + +void CoarrayChecker::Leave(const parser::EventWaitStmt &x) { + const auto &eventVar{std::get<parser::EventVariable>(x.t)}; + + if (const auto *expr{GetExpr(context_, eventVar)}) { + if (ExtractCoarrayRef(expr)) { + context_.Say(parser::FindSourceLocation(eventVar), // C1177 + "A event-variable in a EVENT WAIT statement may not be a coindexed object"_err_en_US); + } else { + CheckEventVariable(context_, eventVar); + } + } + + bool gotStat{false}, gotMsg{false}, gotUntil{false}; + using EventWaitSpec = parser::EventWaitStmt::EventWaitSpec; + for (const EventWaitSpec &eventWaitSpec : + std::get<std::list<EventWaitSpec>>(x.t)) { + common::visit( + common::visitors{ + [&](const parser::ScalarIntExpr &untilCount) { + if (gotUntil) { + context_.Say( // C1178 + "Until-spec in a event-wait-spec-list may not be repeated"_err_en_US); + } + gotUntil = true; + }, + [&](const parser::StatOrErrmsg &statOrErrmsg) { + common::visit( + common::visitors{ + [&](const parser::StatVariable &stat) { + if (gotStat) { + context_.Say( // C1178 + "A stat-variable in a event-wait-spec-list may not be repeated"_err_en_US); + } + gotStat = true; + }, + [&](const parser::MsgVariable &errmsg) { + if (gotMsg) { + context_.Say( // C1178 + "A errmsg-variable in a event-wait-spec-list may not be repeated"_err_en_US); + } + gotMsg = true; + }, + }, + statOrErrmsg.u); + CheckCoindexedStatOrErrmsg( + context_, statOrErrmsg, "event-wait-spec-list"); + }, + + }, + eventWaitSpec.u); + } +} + void CoarrayChecker::Leave(const parser::ImageSelector &imageSelector) { haveStat_ = false; haveTeam_ = false; |