Skip to content

Commit 1e9b60c

Browse files
authored
[flang] Recognize and check EVENT_QUERY (llvm#123429)
Recognize the intrinsic subroutine EVENT_QUERY and enforce semantic requirements on calls to it.
1 parent 2e5a523 commit 1e9b60c

File tree

3 files changed

+71
-10
lines changed

3 files changed

+71
-10
lines changed

flang/lib/Evaluate/intrinsics.cpp

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ ENUM_CLASS(KindCode, none, defaultIntegerKind,
9696
typeless, // BOZ literals are INTEGER with this kind
9797
ieeeFlagType, // IEEE_FLAG_TYPE from ISO_FORTRAN_EXCEPTION
9898
ieeeRoundType, // IEEE_ROUND_TYPE from ISO_FORTRAN_ARITHMETIC
99+
eventType, // EVENT_TYPE from module ISO_FORTRAN_ENV (for coarrays)
99100
teamType, // TEAM_TYPE from module ISO_FORTRAN_ENV (for coarrays)
100101
kindArg, // this argument is KIND=
101102
effectiveKind, // for function results: "kindArg" value, possibly defaulted
@@ -129,6 +130,7 @@ static constexpr TypePattern DefaultChar{CharType, KindCode::defaultCharKind};
129130
static constexpr TypePattern DefaultLogical{
130131
LogicalType, KindCode::defaultLogicalKind};
131132
static constexpr TypePattern BOZ{IntType, KindCode::typeless};
133+
static constexpr TypePattern EventType{DerivedType, KindCode::eventType};
132134
static constexpr TypePattern IeeeFlagType{DerivedType, KindCode::ieeeFlagType};
133135
static constexpr TypePattern IeeeRoundType{
134136
DerivedType, KindCode::ieeeRoundType};
@@ -1471,6 +1473,13 @@ static const IntrinsicInterface intrinsicSubroutine[]{
14711473
{"time", TypePattern{RealType, KindCode::exactKind, 4},
14721474
Rank::scalar, Optionality::required, common::Intent::Out}},
14731475
{}, Rank::elemental, IntrinsicClass::impureSubroutine},
1476+
{"event_query",
1477+
{{"event", EventType, Rank::scalar},
1478+
{"count", AnyInt, Rank::scalar, Optionality::required,
1479+
common::Intent::Out},
1480+
{"stat", AnyInt, Rank::scalar, Optionality::optional,
1481+
common::Intent::Out}},
1482+
{}, Rank::elemental, IntrinsicClass::impureSubroutine},
14741483
{"execute_command_line",
14751484
{{"command", DefaultChar, Rank::scalar},
14761485
{"wait", AnyLogical, Rank::scalar, Optionality::optional},
@@ -1592,7 +1601,6 @@ static const IntrinsicInterface intrinsicSubroutine[]{
15921601
{}, Rank::elemental, IntrinsicClass::impureSubroutine},
15931602
};
15941603

1595-
// TODO: Intrinsic subroutine EVENT_QUERY
15961604
// TODO: Collective intrinsic subroutines: co_reduce
15971605

15981606
// Finds a built-in derived type and returns it as a DynamicType.
@@ -1968,6 +1976,11 @@ std::optional<SpecificCall> IntrinsicInterface::Match(
19681976
case KindCode::typeless:
19691977
argOk = false;
19701978
break;
1979+
case KindCode::eventType:
1980+
argOk = !type->IsUnlimitedPolymorphic() &&
1981+
type->category() == TypeCategory::Derived &&
1982+
semantics::IsEventType(&type->GetDerivedTypeSpec());
1983+
break;
19711984
case KindCode::ieeeFlagType:
19721985
argOk = !type->IsUnlimitedPolymorphic() &&
19731986
type->category() == TypeCategory::Derived &&
@@ -3239,7 +3252,7 @@ static bool ApplySpecificChecks(SpecificCall &call, FoldingContext &context) {
32393252
"Argument of ALLOCATED() must be an ALLOCATABLE object or component"_err_en_US);
32403253
}
32413254
} else if (name == "atomic_add" || name == "atomic_and" ||
3242-
name == "atomic_or" || name == "atomic_xor") {
3255+
name == "atomic_or" || name == "atomic_xor" || name == "event_query") {
32433256
return CheckForCoindexedObject(
32443257
context.messages(), call.arguments[2], name, "stat");
32453258
} else if (name == "atomic_cas") {

flang/lib/Semantics/check-call.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1616,6 +1616,36 @@ static void CheckAssociated(evaluate::ActualArguments &arguments,
16161616
}
16171617
}
16181618

1619+
// EVENT_QUERY (F'2023 16.9.82)
1620+
static void CheckEvent_Query(evaluate::ActualArguments &arguments,
1621+
evaluate::FoldingContext &foldingContext) {
1622+
if (arguments.size() > 0 && arguments[0] &&
1623+
ExtractCoarrayRef(*arguments[0]).has_value()) {
1624+
foldingContext.messages().Say(arguments[0]->sourceLocation(),
1625+
"EVENT= argument to EVENT_QUERY must not be coindexed"_err_en_US);
1626+
}
1627+
if (arguments.size() > 1 && arguments[1]) {
1628+
if (auto dyType{arguments[1]->GetType()}) {
1629+
int defaultInt{
1630+
foldingContext.defaults().GetDefaultKind(TypeCategory::Integer)};
1631+
if (dyType->category() == TypeCategory::Integer &&
1632+
dyType->kind() < defaultInt) {
1633+
foldingContext.messages().Say(arguments[1]->sourceLocation(),
1634+
"COUNT= argument to EVENT_QUERY must be an integer with kind >= %d"_err_en_US,
1635+
defaultInt);
1636+
}
1637+
}
1638+
}
1639+
if (arguments.size() > 2 && arguments[2]) {
1640+
if (auto dyType{arguments[2]->GetType()}) {
1641+
if (dyType->category() == TypeCategory::Integer && dyType->kind() < 2) {
1642+
foldingContext.messages().Say(arguments[2]->sourceLocation(),
1643+
"STAT= argument to EVENT_QUERY must be an integer with kind >= 2 when present"_err_en_US);
1644+
}
1645+
}
1646+
}
1647+
}
1648+
16191649
// IMAGE_INDEX (F'2023 16.9.107)
16201650
static void CheckImage_Index(evaluate::ActualArguments &arguments,
16211651
parser::ContextualMessages &messages) {
@@ -1952,6 +1982,8 @@ static void CheckSpecificIntrinsic(const characteristics::Procedure &proc,
19521982
const Scope *scope, const evaluate::SpecificIntrinsic &intrinsic) {
19531983
if (intrinsic.name == "associated") {
19541984
CheckAssociated(arguments, context, scope);
1985+
} else if (intrinsic.name == "event_query") {
1986+
CheckEvent_Query(arguments, context.foldingContext());
19551987
} else if (intrinsic.name == "image_index") {
19561988
CheckImage_Index(arguments, context.foldingContext().messages());
19571989
} else if (intrinsic.name == "max" || intrinsic.name == "min") {

flang/test/Semantics/event_query.f90

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,10 @@
11
! RUN: %python %S/test_errors.py %s %flang_fc1
2-
! XFAIL: *
32
! This test checks for semantic errors in event_query() subroutine based on the
43
! statement specification in section 16.9.72 of the Fortran 2018 standard.
54

65
program test_event_query
76
use iso_fortran_env, only : event_type
8-
implicit none
9-
10-
! event_type variables must be coarrays
11-
type(event_type) non_coarray
7+
implicit none(type,external)
128

139
type(event_type) concert[*], occurrences(2)[*]
1410
integer non_event[*], counter, array(1), coarray[*], sync_status, coindexed[*], non_scalar(1)
@@ -33,70 +29,90 @@ program test_event_query
3329
!___ non-standard-conforming calls _______
3430

3531
! event-variable must be event_type
32+
! ERROR: Actual argument for 'event=' has bad type 'INTEGER(4)'
3633
call event_query(non_event, counter)
3734

38-
! event-variable must be a coarray
39-
call event_query(non_coarray, counter)
40-
4135
! event-variable must be a scalar variable
36+
! ERROR: 'event=' argument has unacceptable rank 1
4237
call event_query(occurrences, counter)
4338

4439
! event-variable must not be coindexed
40+
! ERROR: EVENT= argument to EVENT_QUERY must not be coindexed
4541
call event_query(concert[1], counter)
4642

4743
! event-variable has an unknown keyword argument
44+
! ERROR: unknown keyword argument to intrinsic 'event_query'
4845
call event_query(events=concert, count=counter)
4946

5047
! event-variable has an argument mismatch
48+
! ERROR: Actual argument for 'event=' has bad type 'INTEGER(4)'
5149
call event_query(event=non_event, count=counter)
5250

5351
! count must be an integer
52+
! ERROR: Actual argument for 'count=' has bad type 'LOGICAL(4)'
5453
call event_query(concert, non_integer)
5554

5655
! count must be an integer scalar
56+
! ERROR: 'count=' argument has unacceptable rank 1
5757
call event_query(concert, non_scalar)
5858

5959
! count must be have a decimal exponent range
6060
! no smaller than that of default integer
61+
! ERROR: COUNT= argument to EVENT_QUERY must be an integer with kind >= 4
6162
call event_query(concert, non_default)
6263

6364
! count is an intent(out) argument
65+
! ERROR: Actual argument associated with INTENT(OUT) dummy argument 'count=' is not definable
66+
! ERROR: '4_4' is not a variable or pointer
6467
call event_query(concert, 4)
6568

6669
! count has an unknown keyword argument
70+
! ERROR: unknown keyword argument to intrinsic 'event_query'
6771
call event_query(concert, counts=counter)
6872

6973
! count has an argument mismatch
74+
! ERROR: Actual argument for 'count=' has bad type 'LOGICAL(4)'
7075
call event_query(concert, count=non_integer)
7176

7277
! stat must be an integer
78+
! ERROR: Actual argument for 'stat=' has bad type 'LOGICAL(4)'
7379
call event_query(concert, counter, non_integer)
7480

7581
! stat must be an integer scalar
82+
! ERROR: 'stat=' argument has unacceptable rank 1
7683
call event_query(concert, counter, non_scalar)
7784

7885
! stat is an intent(out) argument
86+
! ERROR: Actual argument associated with INTENT(OUT) dummy argument 'stat=' is not definable
87+
! ERROR: '8_4' is not a variable or pointer
7988
call event_query(concert, counter, 8)
8089

8190
! stat has an unknown keyword argument
91+
! ERROR: unknown keyword argument to intrinsic 'event_query'
8292
call event_query(concert, counter, status=sync_status)
8393

8494
! stat has an argument mismatch
95+
! ERROR: Actual argument for 'stat=' has bad type 'LOGICAL(4)'
8596
call event_query(concert, counter, stat=non_integer)
8697

8798
! stat must not be coindexed
99+
! ERROR: 'stat' argument to 'event_query' may not be a coindexed object
88100
call event_query(concert, counter, coindexed[1])
89101

90102
! Too many arguments
103+
! ERROR: too many actual arguments for intrinsic 'event_query'
91104
call event_query(concert, counter, sync_status, array(1))
92105

93106
! Repeated event keyword
107+
! ERROR: repeated keyword argument to intrinsic 'event_query'
94108
call event_query(event=concert, event=occurrences(1), count=counter)
95109

96110
! Repeated count keyword
111+
! ERROR: repeated keyword argument to intrinsic 'event_query'
97112
call event_query(event=concert, count=counter, count=array(1))
98113

99114
! Repeated stat keyword
115+
! ERROR: repeated keyword argument to intrinsic 'event_query'
100116
call event_query(event=concert, count=counter, stat=sync_status, stat=array(1))
101117

102118
end program test_event_query

0 commit comments

Comments
 (0)