summaryrefslogtreecommitdiff
path: root/flang/lib/Semantics/check-coarray.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'flang/lib/Semantics/check-coarray.cpp')
-rw-r--r--flang/lib/Semantics/check-coarray.cpp71
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;