@@ -63,6 +63,39 @@ class CriticalBodyEnforce {
6363 parser::CharBlock criticalSourcePosition_;
6464};
6565
66+ class ChangeTeamBodyEnforce {
67+ public:
68+ ChangeTeamBodyEnforce (
69+ SemanticsContext &context, parser::CharBlock changeTeamSourcePosition)
70+ : context_{context}, changeTeamSourcePosition_{changeTeamSourcePosition} {
71+ }
72+ std::set<parser::Label> labels () { return labels_; }
73+ template <typename T> bool Pre (const T &) { return true ; }
74+ template <typename T> void Post (const T &) {}
75+
76+ template <typename T> bool Pre (const parser::Statement<T> &statement) {
77+ currentStatementSourcePosition_ = statement.source ;
78+ if (statement.label .has_value ()) {
79+ labels_.insert (*statement.label );
80+ }
81+ return true ;
82+ }
83+
84+ void Post (const parser::ReturnStmt &) {
85+ context_
86+ .Say (currentStatementSourcePosition_,
87+ " RETURN statement is not allowed in a CHANGE TEAM construct" _err_en_US)
88+ .Attach (
89+ changeTeamSourcePosition_, " Enclosing CHANGE TEAM construct" _en_US);
90+ }
91+
92+ private:
93+ SemanticsContext &context_;
94+ std::set<parser::Label> labels_;
95+ parser::CharBlock currentStatementSourcePosition_;
96+ parser::CharBlock changeTeamSourcePosition_;
97+ };
98+
6699template <typename T>
67100static void CheckTeamType (SemanticsContext &context, const T &x) {
68101 if (const auto *expr{GetExpr (context, x)}) {
@@ -361,17 +394,29 @@ void CoarrayChecker::Leave(const parser::FormTeamStmt &x) {
361394
362395void CoarrayChecker::Enter (const parser::CriticalConstruct &x) {
363396 auto &criticalStmt{std::get<parser::Statement<parser::CriticalStmt>>(x.t )};
364-
365397 const parser::Block &block{std::get<parser::Block>(x.t )};
366398 CriticalBodyEnforce criticalBodyEnforce{context_, criticalStmt.source };
367399 parser::Walk (block, criticalBodyEnforce);
368-
369- // C1119
400+ parser::Walk (std::get<parser::Statement<parser::EndCriticalStmt>>(x. t ),
401+ criticalBodyEnforce);
370402 LabelEnforce criticalLabelEnforce{
371403 context_, criticalBodyEnforce.labels (), criticalStmt.source , " CRITICAL" };
372404 parser::Walk (block, criticalLabelEnforce);
373405}
374406
407+ void CoarrayChecker::Enter (const parser::ChangeTeamConstruct &x) {
408+ auto &changeTeamStmt{
409+ std::get<parser::Statement<parser::ChangeTeamStmt>>(x.t )};
410+ const parser::Block &block{std::get<parser::Block>(x.t )};
411+ ChangeTeamBodyEnforce changeTeamBodyEnforce{context_, changeTeamStmt.source };
412+ parser::Walk (block, changeTeamBodyEnforce);
413+ parser::Walk (std::get<parser::Statement<parser::EndChangeTeamStmt>>(x.t ),
414+ changeTeamBodyEnforce);
415+ LabelEnforce changeTeamLabelEnforce{context_, changeTeamBodyEnforce.labels (),
416+ changeTeamStmt.source , " CHANGE TEAM" };
417+ parser::Walk (block, changeTeamLabelEnforce);
418+ }
419+
375420// Check that coarray names and selector names are all distinct.
376421void CoarrayChecker::CheckNamesAreDistinct (
377422 const std::list<parser::CoarrayAssociation> &list) {
0 commit comments