Skip to content

Commit f770b1e

Browse files
committed
[flang] Add check for constraints on synchronization-stmts
In the CoarrayChecker, add checks for the constraints C1172 and C1173, which constrain sync-stat-list. Add these checks to sync-all-stmt, sync-images-stmt, sync-memory-stmt, and sync-team-stmt. Also add a check for the constraint C1174 in sync-images-stmt. Update semantics tests for these stmts. Reviewed By: klausler Differential Revision: https://reviews.llvm.org/D136104
1 parent 070f414 commit f770b1e

File tree

6 files changed

+112
-17
lines changed

6 files changed

+112
-17
lines changed

flang/lib/Semantics/check-coarray.cpp

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,13 +82,78 @@ static void CheckTeamStat(
8282
}
8383
}
8484

85+
static void CheckCoindexedStatOrErrmsg(SemanticsContext &context,
86+
const parser::StatOrErrmsg &statOrErrmsg, const std::string &listName) {
87+
auto CoindexedCheck{[&](const auto &statOrErrmsg) {
88+
if (const auto *expr{GetExpr(context, statOrErrmsg)}) {
89+
if (ExtractCoarrayRef(expr)) {
90+
context.Say(parser::FindSourceLocation(statOrErrmsg), // C1173
91+
"The stat-variable or errmsg-variable in a %s may not be a coindexed object"_err_en_US,
92+
listName);
93+
}
94+
}
95+
}};
96+
std::visit(CoindexedCheck, statOrErrmsg.u);
97+
}
98+
99+
static void CheckSyncStatList(
100+
SemanticsContext &context, const std::list<parser::StatOrErrmsg> &list) {
101+
bool gotStat{false}, gotMsg{false};
102+
103+
for (const parser::StatOrErrmsg &statOrErrmsg : list) {
104+
common::visit(
105+
common::visitors{
106+
[&](const parser::StatVariable &stat) {
107+
if (gotStat) {
108+
context.Say( // C1172
109+
"The stat-variable in a sync-stat-list may not be repeated"_err_en_US);
110+
}
111+
gotStat = true;
112+
},
113+
[&](const parser::MsgVariable &errmsg) {
114+
if (gotMsg) {
115+
context.Say( // C1172
116+
"The errmsg-variable in a sync-stat-list may not be repeated"_err_en_US);
117+
}
118+
gotMsg = true;
119+
},
120+
},
121+
statOrErrmsg.u);
122+
123+
CheckCoindexedStatOrErrmsg(context, statOrErrmsg, "sync-stat-list");
124+
}
125+
}
126+
85127
void CoarrayChecker::Leave(const parser::ChangeTeamStmt &x) {
86128
CheckNamesAreDistinct(std::get<std::list<parser::CoarrayAssociation>>(x.t));
87129
CheckTeamType(context_, std::get<parser::TeamValue>(x.t));
88130
}
89131

132+
void CoarrayChecker::Leave(const parser::SyncAllStmt &x) {
133+
CheckSyncStatList(context_, x.v);
134+
}
135+
136+
void CoarrayChecker::Leave(const parser::SyncImagesStmt &x) {
137+
CheckSyncStatList(context_, std::get<std::list<parser::StatOrErrmsg>>(x.t));
138+
139+
const auto &imageSet{std::get<parser::SyncImagesStmt::ImageSet>(x.t)};
140+
if (const auto *intExpr{std::get_if<parser::IntExpr>(&imageSet.u)}) {
141+
if (const auto *expr{GetExpr(context_, *intExpr)}) {
142+
if (expr->Rank() > 1) {
143+
context_.Say(parser::FindSourceLocation(imageSet), // C1174
144+
"An image-set that is an int-expr must be a scalar or a rank-one array"_err_en_US);
145+
}
146+
}
147+
}
148+
}
149+
150+
void CoarrayChecker::Leave(const parser::SyncMemoryStmt &x) {
151+
CheckSyncStatList(context_, x.v);
152+
}
153+
90154
void CoarrayChecker::Leave(const parser::SyncTeamStmt &x) {
91155
CheckTeamType(context_, std::get<parser::TeamValue>(x.t));
156+
CheckSyncStatList(context_, std::get<std::list<parser::StatOrErrmsg>>(x.t));
92157
}
93158

94159
void CoarrayChecker::Leave(const parser::ImageSelector &imageSelector) {

flang/lib/Semantics/check-coarray.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ struct ChangeTeamStmt;
1919
struct CoarrayAssociation;
2020
struct FormTeamStmt;
2121
struct ImageSelector;
22+
struct SyncAllStmt;
23+
struct SyncImagesStmt;
24+
struct SyncMemoryStmt;
2225
struct SyncTeamStmt;
2326
} // namespace Fortran::parser
2427

@@ -28,6 +31,9 @@ class CoarrayChecker : public virtual BaseChecker {
2831
public:
2932
CoarrayChecker(SemanticsContext &context) : context_{context} {}
3033
void Leave(const parser::ChangeTeamStmt &);
34+
void Leave(const parser::SyncAllStmt &);
35+
void Leave(const parser::SyncImagesStmt &);
36+
void Leave(const parser::SyncMemoryStmt &);
3137
void Leave(const parser::SyncTeamStmt &);
3238
void Leave(const parser::ImageSelector &);
3339
void Leave(const parser::FormTeamStmt &);

flang/test/Semantics/synchronization01b.f90

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,22 @@ program test_sync_all
2222
!ERROR: Must have CHARACTER type, but is LOGICAL(4)
2323
sync all(errmsg=invalid_type)
2424

25-
! No specifier shall appear more than once in a given sync-stat-list
25+
!ERROR: The stat-variable in a sync-stat-list may not be repeated
2626
sync all(stat=sync_status, stat=superfluous_stat)
2727

28-
! No specifier shall appear more than once in a given sync-stat-list
28+
!ERROR: The errmsg-variable in a sync-stat-list may not be repeated
2929
sync all(errmsg=error_message, errmsg=superfluous_errmsg)
3030

31-
! Fortran 2018 standard C1173: `stat` shall not be coindexed
31+
!ERROR: The stat-variable in a sync-stat-list may not be repeated
32+
sync all(stat=sync_status, errmsg=error_message, stat=superfluous_stat)
33+
34+
!ERROR: The errmsg-variable in a sync-stat-list may not be repeated
35+
sync all(stat=sync_status, errmsg=error_message, errmsg=superfluous_errmsg)
36+
37+
!ERROR: The stat-variable or errmsg-variable in a sync-stat-list may not be a coindexed object
3238
sync all(stat=co_indexed_integer[1])
3339

34-
! Fortran 2018 standard C1173: `errmsg` shall not be coindexed
40+
!ERROR: The stat-variable or errmsg-variable in a sync-stat-list may not be a coindexed object
3541
sync all(errmsg=co_indexed_character[1])
3642

3743
end program test_sync_all

flang/test/Semantics/synchronization02b.f90

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ program test_sync_images
2020
! Image set shall not depend on the value of errmsg-variable
2121
sync images(len(error_message), errmsg=error_message)
2222

23-
! Image set shall be a scalar or rank-1 array
23+
!ERROR: An image-set that is an int-expr must be a scalar or a rank-one array
2424
sync images(invalid_rank)
2525

2626
!ERROR: Must have INTEGER type, but is LOGICAL(4)
@@ -32,16 +32,22 @@ program test_sync_images
3232
!ERROR: Must have CHARACTER type, but is LOGICAL(4)
3333
sync images(1, errmsg=invalid_type)
3434

35-
! No specifier shall appear more than once in a given sync-stat-list
35+
!ERROR: The stat-variable in a sync-stat-list may not be repeated
3636
sync images(1, stat=sync_status, stat=superfluous_stat)
3737

38-
! No specifier shall appear more than once in a given sync-stat-list
38+
!ERROR: The stat-variable in a sync-stat-list may not be repeated
39+
sync images(1, stat=sync_status, errmsg=error_message, stat=superfluous_stat)
40+
41+
!ERROR: The errmsg-variable in a sync-stat-list may not be repeated
3942
sync images([1], errmsg=error_message, errmsg=superfluous_errmsg)
4043

41-
! Fortran 2018 standard C1173: `stat` shall not be coindexed
44+
!ERROR: The errmsg-variable in a sync-stat-list may not be repeated
45+
sync images([1], stat=sync_status, errmsg=error_message, errmsg=superfluous_errmsg)
46+
47+
!ERROR: The stat-variable or errmsg-variable in a sync-stat-list may not be a coindexed object
4248
sync images(*, stat=coindexed_integer[1])
4349

44-
! Fortran 2018 standard C1173: `errmsg` shall not be coindexed
50+
!ERROR: The stat-variable or errmsg-variable in a sync-stat-list may not be a coindexed object
4551
sync images(1, errmsg=coindexed_character[1])
4652

4753
end program test_sync_images

flang/test/Semantics/synchronization03b.f90

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,22 @@ program test_sync_memory
2222
!ERROR: Must have CHARACTER type, but is LOGICAL(4)
2323
sync memory(errmsg=invalid_type)
2424

25-
! No specifier shall appear more than once in a given sync-stat-list
25+
!ERROR: The stat-variable in a sync-stat-list may not be repeated
2626
sync memory(stat=sync_status, stat=superfluous_stat)
2727

28-
! No specifier shall appear more than once in a given sync-stat-list
28+
!ERROR: The errmsg-variable in a sync-stat-list may not be repeated
2929
sync memory(errmsg=error_message, errmsg=superfluous_errmsg)
3030

31-
! Fortran 2018 standard C1173: `stat` shall not be coindexed
31+
!ERROR: The stat-variable in a sync-stat-list may not be repeated
32+
sync memory(stat=sync_status, errmsg=error_message, stat=superfluous_stat)
33+
34+
!ERROR: The errmsg-variable in a sync-stat-list may not be repeated
35+
sync memory(stat=sync_status, errmsg=error_message, errmsg=superfluous_errmsg)
36+
37+
!ERROR: The stat-variable or errmsg-variable in a sync-stat-list may not be a coindexed object
3238
sync memory(stat=co_indexed_integer[1])
3339

34-
! Fortran 2018 standard C1173: `errmsg` shall not be coindexed
40+
!ERROR: The stat-variable or errmsg-variable in a sync-stat-list may not be a coindexed object
3541
sync memory(errmsg=co_indexed_character[1])
3642

3743
end program test_sync_memory

flang/test/Semantics/synchronization04b.f90

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,16 +27,22 @@ program test_sync_team
2727
!ERROR: Must have CHARACTER type, but is LOGICAL(4)
2828
sync team(warriors, errmsg=invalid_type)
2929

30-
! No specifier shall appear more than once in a given sync-stat-list
30+
!ERROR: The stat-variable in a sync-stat-list may not be repeated
3131
sync team(warriors, stat=sync_status, stat=superfluous_stat)
3232

33-
! No specifier shall appear more than once in a given sync-stat-list
33+
!ERROR: The errmsg-variable in a sync-stat-list may not be repeated
3434
sync team(warriors, errmsg=error_message, errmsg=superfluous_errmsg)
3535

36-
! Fortran 2018 standard C1173: `stat` shall not be coindexed
36+
!ERROR: The stat-variable in a sync-stat-list may not be repeated
37+
sync team(warriors, stat=sync_status, errmsg=error_message, stat=superfluous_stat)
38+
39+
!ERROR: The errmsg-variable in a sync-stat-list may not be repeated
40+
sync team(warriors, stat=sync_status, errmsg=error_message, errmsg=superfluous_errmsg)
41+
42+
!ERROR: The stat-variable or errmsg-variable in a sync-stat-list may not be a coindexed object
3743
sync team(warriors, stat=co_indexed_integer[1])
3844

39-
! Fortran 2018 standard C1173: `errmsg` shall not be coindexed
45+
!ERROR: The stat-variable or errmsg-variable in a sync-stat-list may not be a coindexed object
4046
sync team(warriors, errmsg=co_indexed_character[1])
4147

4248
end program test_sync_team

0 commit comments

Comments
 (0)