Skip to content

Commit 2625510

Browse files
authored
[flang] Refine EVENT_TYPE/LOCK_TYPE usage checks (#123244)
The event variable in an EVENT POST/WAIT statement can be a coarray reference, and need not be an entire coarray. Variables and potential subobject components with EVENT_TYPE/LOCK_TYPE must be coarrays, unless they are potential subobjects nested within coarrays or pointers.
1 parent 512b44d commit 2625510

File tree

10 files changed

+90
-27
lines changed

10 files changed

+90
-27
lines changed

flang/include/flang/Semantics/tools.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -529,6 +529,9 @@ template <ComponentKind componentKind> class ComponentIterator {
529529
// having to check against an end() iterator.
530530
explicit operator bool() const { return !componentPath_.empty(); }
531531

532+
// Returns the current sequence of components, including parent components.
533+
SymbolVector GetComponentPath() const;
534+
532535
// Builds a designator name of the referenced component for messages.
533536
// The designator helps when the component referred to by the iterator
534537
// may be "buried" into other components. This gives the full
@@ -626,7 +629,7 @@ using PotentialAndPointerComponentIterator =
626629
// is returned. Otherwise, the returned iterator casts to true and can be
627630
// dereferenced.
628631
PotentialComponentIterator::const_iterator FindEventOrLockPotentialComponent(
629-
const DerivedTypeSpec &);
632+
const DerivedTypeSpec &, bool ignoreCoarrays = false);
630633
UltimateComponentIterator::const_iterator FindCoarrayUltimateComponent(
631634
const DerivedTypeSpec &);
632635
UltimateComponentIterator::const_iterator FindPointerUltimateComponent(

flang/lib/Semantics/check-coarray.cpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -133,9 +133,6 @@ static void CheckEventVariable(
133133
if (!IsEventType(evaluate::GetDerivedTypeSpec(expr->GetType()))) { // C1176
134134
context.Say(parser::FindSourceLocation(eventVar),
135135
"The event-variable must be of type EVENT_TYPE from module ISO_FORTRAN_ENV"_err_en_US);
136-
} else if (!evaluate::IsCoarray(*expr)) { // C1604
137-
context.Say(parser::FindSourceLocation(eventVar),
138-
"The event-variable must be a coarray"_err_en_US);
139136
}
140137
}
141138
}

flang/lib/Semantics/check-declarations.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -683,7 +683,20 @@ void CheckHelper::CheckObjectEntity(
683683
const DeclTypeSpec *type{details.type()};
684684
const DerivedTypeSpec *derived{type ? type->AsDerived() : nullptr};
685685
bool isComponent{symbol.owner().IsDerivedType()};
686-
if (!details.coshape().empty()) {
686+
if (details.coshape().empty()) { // not a coarray
687+
if (!isComponent && !IsPointer(symbol) && derived) {
688+
if (IsEventTypeOrLockType(derived)) {
689+
messages_.Say(
690+
"Variable '%s' with EVENT_TYPE or LOCK_TYPE must be a coarray"_err_en_US,
691+
symbol.name());
692+
} else if (auto component{FindEventOrLockPotentialComponent(
693+
*derived, /*ignoreCoarrays=*/true)}) {
694+
messages_.Say(
695+
"Variable '%s' with EVENT_TYPE or LOCK_TYPE potential component '%s' must be a coarray"_err_en_US,
696+
symbol.name(), component.BuildResultDesignatorName());
697+
}
698+
}
699+
} else { // it's a coarray
687700
bool isDeferredCoshape{details.coshape().CanBeDeferredShape()};
688701
if (IsAllocatable(symbol)) {
689702
if (!isDeferredCoshape) { // C827

flang/lib/Semantics/tools.cpp

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1364,13 +1364,23 @@ void ComponentIterator<componentKind>::const_iterator::Increment() {
13641364
}
13651365
}
13661366

1367+
template <ComponentKind componentKind>
1368+
SymbolVector
1369+
ComponentIterator<componentKind>::const_iterator::GetComponentPath() const {
1370+
SymbolVector result;
1371+
for (const auto &node : componentPath_) {
1372+
result.push_back(DEREF(node.component()));
1373+
}
1374+
return result;
1375+
}
1376+
13671377
template <ComponentKind componentKind>
13681378
std::string
13691379
ComponentIterator<componentKind>::const_iterator::BuildResultDesignatorName()
13701380
const {
13711381
std::string designator;
1372-
for (const auto &node : componentPath_) {
1373-
designator += "%"s + DEREF(node.component()).name().ToString();
1382+
for (const Symbol &component : GetComponentPath()) {
1383+
designator += "%"s + component.name().ToString();
13741384
}
13751385
return designator;
13761386
}
@@ -1396,16 +1406,29 @@ UltimateComponentIterator::const_iterator FindPointerUltimateComponent(
13961406
}
13971407

13981408
PotentialComponentIterator::const_iterator FindEventOrLockPotentialComponent(
1399-
const DerivedTypeSpec &derived) {
1409+
const DerivedTypeSpec &derived, bool ignoreCoarrays) {
14001410
PotentialComponentIterator potentials{derived};
1401-
return std::find_if(
1402-
potentials.begin(), potentials.end(), [](const Symbol &component) {
1403-
if (const auto *details{component.detailsIf<ObjectEntityDetails>()}) {
1404-
const DeclTypeSpec *type{details->type()};
1405-
return type && IsEventTypeOrLockType(type->AsDerived());
1411+
auto iter{potentials.begin()};
1412+
for (auto end{potentials.end()}; iter != end; ++iter) {
1413+
const Symbol &component{*iter};
1414+
if (const auto *object{component.detailsIf<ObjectEntityDetails>()}) {
1415+
if (const DeclTypeSpec * type{object->type()}) {
1416+
if (IsEventTypeOrLockType(type->AsDerived())) {
1417+
if (!ignoreCoarrays) {
1418+
break; // found one
1419+
}
1420+
auto path{iter.GetComponentPath()};
1421+
path.pop_back();
1422+
if (std::find_if(path.begin(), path.end(), [](const Symbol &sym) {
1423+
return evaluate::IsCoarray(sym);
1424+
}) == path.end()) {
1425+
break; // found one not in a coarray
1426+
}
14061427
}
1407-
return false;
1408-
});
1428+
}
1429+
}
1430+
}
1431+
return iter;
14091432
}
14101433

14111434
UltimateComponentIterator::const_iterator FindAllocatableUltimateComponent(

flang/test/Semantics/call04.f90

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,11 @@ subroutine s05(x) ! C846
5656
subroutine s06(x) ! C847
5757
use ISO_FORTRAN_ENV, only: lock_type
5858
!ERROR: An INTENT(OUT) dummy argument may not be, or contain, EVENT_TYPE or LOCK_TYPE
59-
type(lock_type), intent(out) :: x
59+
type(lock_type), intent(out) :: x[*]
6060
end subroutine
6161

6262
subroutine s07(x) ! C847
6363
use ISO_FORTRAN_ENV, only: event_type
6464
!ERROR: An INTENT(OUT) dummy argument may not be, or contain, EVENT_TYPE or LOCK_TYPE
65-
type(event_type), intent(out) :: x
65+
type(event_type), intent(out) :: x[*]
6666
end subroutine

flang/test/Semantics/critical02.f90

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ end subroutine test8
8282

8383
subroutine test9()
8484
use iso_fortran_env
85-
type(lock_type) :: l
85+
type(lock_type), save :: l[*]
8686

8787
critical
8888
!ERROR: An image control statement is not allowed in a CRITICAL construct

flang/test/Semantics/doconcurrent01.f90

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ end subroutine s3
9797

9898
subroutine s4()
9999
use iso_fortran_env
100-
type(lock_type) :: l
100+
type(lock_type), save :: l[*]
101101

102102
do concurrent (i = 1:n)
103103
!ERROR: An image control statement is not allowed in DO CONCURRENT

flang/test/Semantics/event01b.f90

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,41 @@ program test_event_post
1010
implicit none
1111

1212
! event_type variables must be coarrays
13+
!ERROR: Variable 'non_coarray' with EVENT_TYPE or LOCK_TYPE must be a coarray
1314
type(event_type) non_coarray
1415

16+
! event_type potential object components must be nested in coarrays
17+
type :: has_event
18+
type(event_type) event
19+
end type
20+
type :: bad1
21+
type(has_event) component
22+
end type
23+
type :: bad2
24+
type(has_event), allocatable :: component
25+
end type
26+
type :: good1
27+
type(has_event), pointer :: component
28+
end type
29+
type :: good2
30+
type(has_event), allocatable :: component[:]
31+
end type
32+
!ERROR: Variable 'non_coarray_component1' with EVENT_TYPE or LOCK_TYPE potential component '%event' must be a coarray
33+
type(has_event) non_coarray_component1
34+
!ERROR: Variable 'non_coarray_component2' with EVENT_TYPE or LOCK_TYPE potential component '%component%event' must be a coarray
35+
type(bad1) non_coarray_component2
36+
!ERROR: Variable 'non_coarray_component3' with EVENT_TYPE or LOCK_TYPE potential component '%component%event' must be a coarray
37+
type(bad2) non_coarray_component3
38+
! these are okay
39+
type(has_event) ok_non_coarray_component1[*]
40+
type(has_event), pointer :: ok_non_coarray_component2
41+
type(bad1) :: ok_non_coarray_component3[*]
42+
type(bad1), pointer :: ok_non_coarray_component4
43+
type(bad2) :: ok_non_coarray_component5[*]
44+
type(bad2), pointer :: ok_non_coarray_component6
45+
type(good1) ok_non_coarray_component7
46+
type(good2) ok_non_coarray_component8
47+
1548
type(event_type) concert[*], occurrences(2)[*]
1649
integer non_event[*], sync_status, co_indexed_integer[*], superfluous_stat, non_scalar(1)
1750
character(len=128) error_message, co_indexed_character[*], superfluous_errmsg
@@ -25,10 +58,6 @@ program test_event_post
2558
!ERROR: The event-variable must be of type EVENT_TYPE from module ISO_FORTRAN_ENV
2659
event post(non_event)
2760

28-
! event-variable must be a coarray
29-
!ERROR: The event-variable must be a coarray
30-
event post(non_coarray)
31-
3261
!ERROR: Must be a scalar value, but is a rank-1 array
3362
event post(occurrences)
3463

flang/test/Semantics/event02b.f90

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ program test_event_wait
1010
implicit none
1111

1212
! event_type variables must be coarrays
13+
!ERROR: Variable 'non_coarray' with EVENT_TYPE or LOCK_TYPE must be a coarray
1314
type(event_type) non_coarray
1415

1516
type(event_type) concert[*], occurrences(2)[*]
@@ -24,9 +25,6 @@ program test_event_wait
2425
!ERROR: The event-variable must be of type EVENT_TYPE from module ISO_FORTRAN_ENV
2526
event wait(non_event)
2627

27-
!ERROR: The event-variable must be a coarray
28-
event wait(non_coarray)
29-
3028
!ERROR: A event-variable in a EVENT WAIT statement may not be a coindexed object
3129
event wait(concert[1])
3230

flang/test/Semantics/sync-stat-list.f90

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ program test_sync_stat_list
1616
character(len=128) error_message, superfluous_errmsg, coindexed_character[*]
1717
logical invalid_type
1818
type(team_type) :: home
19-
type(lock_type) :: latch
19+
type(lock_type) :: latch[*]
2020

2121
! valid
2222
change team (home, stat=sync_status, errmsg=error_message)

0 commit comments

Comments
 (0)