@@ -63,6 +63,39 @@ class CriticalBodyEnforce {
63
63
parser::CharBlock criticalSourcePosition_;
64
64
};
65
65
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
+
66
99
template <typename T>
67
100
static void CheckTeamType (SemanticsContext &context, const T &x) {
68
101
if (const auto *expr{GetExpr (context, x)}) {
@@ -361,17 +394,29 @@ void CoarrayChecker::Leave(const parser::FormTeamStmt &x) {
361
394
362
395
void CoarrayChecker::Enter (const parser::CriticalConstruct &x) {
363
396
auto &criticalStmt{std::get<parser::Statement<parser::CriticalStmt>>(x.t )};
364
-
365
397
const parser::Block &block{std::get<parser::Block>(x.t )};
366
398
CriticalBodyEnforce criticalBodyEnforce{context_, criticalStmt.source };
367
399
parser::Walk (block, criticalBodyEnforce);
368
-
369
- // C1119
400
+ parser::Walk (std::get<parser::Statement<parser::EndCriticalStmt>>(x. t ),
401
+ criticalBodyEnforce);
370
402
LabelEnforce criticalLabelEnforce{
371
403
context_, criticalBodyEnforce.labels (), criticalStmt.source , " CRITICAL" };
372
404
parser::Walk (block, criticalLabelEnforce);
373
405
}
374
406
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
+
375
420
// Check that coarray names and selector names are all distinct.
376
421
void CoarrayChecker::CheckNamesAreDistinct (
377
422
const std::list<parser::CoarrayAssociation> &list) {
0 commit comments