Skip to content

Commit 4c4604c

Browse files
committed
[flang] Semantic checking of LOCK statement
Add checks for the LOCK statement, and complete and enable their tests.
1 parent f6e8366 commit 4c4604c

File tree

3 files changed

+89
-42
lines changed

3 files changed

+89
-42
lines changed

flang/lib/Semantics/check-coarray.cpp

Lines changed: 63 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -96,34 +96,37 @@ static void CheckCoindexedStatOrErrmsg(SemanticsContext &context,
9696
Fortran::common::visit(CoindexedCheck, statOrErrmsg.u);
9797
}
9898

99+
static void CheckSyncStat(SemanticsContext &context,
100+
const parser::StatOrErrmsg &statOrErrmsg, bool &gotStat, bool &gotMsg) {
101+
common::visit(
102+
common::visitors{
103+
[&](const parser::StatVariable &stat) {
104+
if (gotStat) {
105+
context.Say( // C1172
106+
"The stat-variable in a sync-stat-list may not be repeated"_err_en_US);
107+
}
108+
gotStat = true;
109+
},
110+
[&](const parser::MsgVariable &var) {
111+
WarnOnDeferredLengthCharacterScalar(context, GetExpr(context, var),
112+
var.v.thing.thing.GetSource(), "ERRMSG=");
113+
if (gotMsg) {
114+
context.Say( // C1172
115+
"The errmsg-variable in a sync-stat-list may not be repeated"_err_en_US);
116+
}
117+
gotMsg = true;
118+
},
119+
},
120+
statOrErrmsg.u);
121+
122+
CheckCoindexedStatOrErrmsg(context, statOrErrmsg, "sync-stat-list");
123+
}
124+
99125
static void CheckSyncStatList(
100126
SemanticsContext &context, const std::list<parser::StatOrErrmsg> &list) {
101127
bool gotStat{false}, gotMsg{false};
102-
103128
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 &var) {
114-
WarnOnDeferredLengthCharacterScalar(context,
115-
GetExpr(context, var), var.v.thing.thing.GetSource(),
116-
"ERRMSG=");
117-
if (gotMsg) {
118-
context.Say( // C1172
119-
"The errmsg-variable in a sync-stat-list may not be repeated"_err_en_US);
120-
}
121-
gotMsg = true;
122-
},
123-
},
124-
statOrErrmsg.u);
125-
126-
CheckCoindexedStatOrErrmsg(context, statOrErrmsg, "sync-stat-list");
129+
CheckSyncStat(context, statOrErrmsg, gotStat, gotMsg);
127130
}
128131
}
129132

@@ -260,7 +263,43 @@ void CoarrayChecker::Leave(const parser::EventWaitStmt &x) {
260263
context_, std::get<std::list<parser::EventWaitSpec>>(x.t));
261264
}
262265

266+
static void CheckLockVariable(
267+
SemanticsContext &context, const parser::LockVariable &lockVar) {
268+
if (const SomeExpr * expr{GetExpr(lockVar)}) {
269+
if (auto dyType{expr->GetType()}) {
270+
if (dyType->category() != TypeCategory::Derived ||
271+
dyType->IsUnlimitedPolymorphic() ||
272+
!IsLockType(&dyType->GetDerivedTypeSpec())) {
273+
context.Say(parser::FindSourceLocation(lockVar),
274+
"Lock variable must have type LOCK_TYPE from ISO_FORTRAN_ENV"_err_en_US);
275+
}
276+
}
277+
}
278+
}
279+
280+
void CoarrayChecker::Leave(const parser::LockStmt &x) {
281+
CheckLockVariable(context_, std::get<parser::LockVariable>(x.t));
282+
bool gotAcquired{false}, gotStat{false}, gotMsg{false};
283+
for (const parser::LockStmt::LockStat &lockStat :
284+
std::get<std::list<parser::LockStmt::LockStat>>(x.t)) {
285+
if (const auto *statOrErrmsg{
286+
std::get_if<parser::StatOrErrmsg>(&lockStat.u)}) {
287+
CheckSyncStat(context_, *statOrErrmsg, gotStat, gotMsg);
288+
} else {
289+
CHECK(std::holds_alternative<
290+
parser::Scalar<parser::Logical<parser::Variable>>>(lockStat.u));
291+
if (gotAcquired) {
292+
context_.Say(parser::FindSourceLocation(lockStat),
293+
"Multiple ACQUIRED_LOCK specifiers"_err_en_US);
294+
} else {
295+
gotAcquired = true;
296+
}
297+
}
298+
}
299+
}
300+
263301
void CoarrayChecker::Leave(const parser::UnlockStmt &x) {
302+
CheckLockVariable(context_, std::get<parser::LockVariable>(x.t));
264303
CheckSyncStatList(context_, std::get<std::list<parser::StatOrErrmsg>>(x.t));
265304
}
266305

flang/lib/Semantics/check-coarray.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ struct SyncAllStmt;
2828
struct SyncImagesStmt;
2929
struct SyncMemoryStmt;
3030
struct SyncTeamStmt;
31+
struct LockStmt;
3132
struct UnlockStmt;
3233
} // namespace Fortran::parser
3334

@@ -45,6 +46,7 @@ class CoarrayChecker : public virtual BaseChecker {
4546
void Leave(const parser::NotifyWaitStmt &);
4647
void Leave(const parser::EventPostStmt &);
4748
void Leave(const parser::EventWaitStmt &);
49+
void Leave(const parser::LockStmt &);
4850
void Leave(const parser::UnlockStmt &);
4951
void Leave(const parser::CriticalStmt &);
5052
void Leave(const parser::ImageSelector &);

flang/test/Semantics/lockstmt03.f90

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
! RUN: %python %S/test_errors.py %s %flang_fc1
2-
! XFAIL: *
32
! This test checks for semantic errors in lock statements based on the
43
! statement specification in section 11.6.10 of the Fortran 2018 standard.
54

@@ -10,14 +9,16 @@ program test_lock_stmt
109
character(len=128) error_message, msg_array(10), coindexed_msg[*], repeated_msg
1110
integer status, stat_array(10), coindexed_int[*], non_bool, repeated_stat
1211
logical non_integer, bool, bool_array(10), non_char, coindexed_logical[*], repeated_bool
13-
type(lock_type) :: lock_var[*], lock_array(10)[*], non_coarray_lock
12+
type(lock_type) :: lock_var[*], lock_array(10)[*]
13+
!ERROR: Variable 'non_coarray_lock' with EVENT_TYPE or LOCK_TYPE must be a coarray
14+
type(lock_type) :: non_coarray_lock
1415
type(event_type) :: not_lock_var[*]
1516

1617
!___ non-standard-conforming statements ___
1718

1819
! type mismatches
1920

20-
!ERROR: to be determined
21+
!ERROR: Lock variable must have type LOCK_TYPE from ISO_FORTRAN_ENV
2122
lock(not_lock_var)
2223

2324
!ERROR: Must have LOGICAL type, but is INTEGER(4)
@@ -45,50 +46,55 @@ program test_lock_stmt
4546

4647
! corank mismatch
4748

48-
!ERROR: to be determined
49-
lock(non_coarray_lock)
49+
lock(non_coarray_lock) ! caught above
5050

5151
! C1173 - stat-variable and errmsg-variable shall not be a coindexed object
5252

53-
!ERROR: to be determined
53+
!ERROR: The stat-variable or errmsg-variable in a sync-stat-list may not be a coindexed object
5454
lock(lock_var, stat=coindexed_int[1])
5555

56-
!ERROR: to be determined
56+
!ERROR: The stat-variable or errmsg-variable in a sync-stat-list may not be a coindexed object
5757
lock(lock_var, errmsg=coindexed_msg[1])
5858

59-
!ERROR: to be determined
59+
!ERROR: The stat-variable or errmsg-variable in a sync-stat-list may not be a coindexed object
60+
!ERROR: The stat-variable or errmsg-variable in a sync-stat-list may not be a coindexed object
6061
lock(lock_var, acquired_lock=coindexed_logical[1], stat=coindexed_int[1], errmsg=coindexed_msg[1])
6162

6263
! C1181 - No specifier shall appear more than once in a given lock-stat-list
6364

64-
!ERROR: to be determined
65+
!ERROR: Multiple ACQUIRED_LOCK specifiers
6566
lock(lock_var, acquired_lock=bool, acquired_lock=repeated_bool)
6667

67-
!ERROR: to be determined
68+
!ERROR: The stat-variable in a sync-stat-list may not be repeated
6869
lock(lock_var, stat=status, stat=repeated_stat)
6970

70-
!ERROR: to be determined
71+
!ERROR: The errmsg-variable in a sync-stat-list may not be repeated
7172
lock(lock_var, errmsg=error_message, errmsg=repeated_msg)
7273

73-
!ERROR: to be determined
74+
!ERROR: Multiple ACQUIRED_LOCK specifiers
7475
lock(lock_var, acquired_lock=bool, stat=status, errmsg=error_message, acquired_lock=repeated_bool)
7576

76-
!ERROR: to be determined
77+
!ERROR: The stat-variable in a sync-stat-list may not be repeated
7778
lock(lock_var, acquired_lock=bool, stat=status, errmsg=error_message, stat=repeated_stat)
7879

79-
!ERROR: to be determined
80+
!ERROR: The errmsg-variable in a sync-stat-list may not be repeated
8081
lock(lock_var, acquired_lock=bool, stat=status, errmsg=error_message, errmsg=repeated_msg)
8182

82-
!ERROR: to be determined
83+
!ERROR: The stat-variable in a sync-stat-list may not be repeated
84+
!ERROR: Multiple ACQUIRED_LOCK specifiers
8385
lock(lock_var, acquired_lock=bool, stat=status, errmsg=error_message, acquired_lock=repeated_bool, stat=repeated_stat)
8486

85-
!ERROR: to be determined
87+
!ERROR: The errmsg-variable in a sync-stat-list may not be repeated
88+
!ERROR: Multiple ACQUIRED_LOCK specifiers
8689
lock(lock_var, acquired_lock=bool, stat=status, errmsg=error_message, acquired_lock=repeated_bool, errmsg=repeated_msg)
8790

88-
!ERROR: to be determined
91+
!ERROR: The stat-variable in a sync-stat-list may not be repeated
92+
!ERROR: The errmsg-variable in a sync-stat-list may not be repeated
8993
lock(lock_var, acquired_lock=bool, stat=status, errmsg=error_message, stat=repeated_stat, errmsg=repeated_msg)
9094

91-
!ERROR: to be determined
95+
!ERROR: The stat-variable in a sync-stat-list may not be repeated
96+
!ERROR: The errmsg-variable in a sync-stat-list may not be repeated
97+
!ERROR: Multiple ACQUIRED_LOCK specifiers
9298
lock(lock_var, acquired_lock=bool, stat=status, errmsg=error_message, acquired_lock=repeated_bool, stat=repeated_stat, errmsg=repeated_msg)
9399

94100
end program test_lock_stmt

0 commit comments

Comments
 (0)