Skip to content

Commit 164f94f

Browse files
committed
[flang] Allow LOCK_TYPE & al. to associate with INTENT(IN OUT)
We're emitting a bogus semantic error message about an actual argument being undefinable when associating LOCK_TYPE, EVENT_TYPE, and someday NOTIFY_TYPE with an INTENT(IN OUT) dummy argument. These types indeed make many definition contexts invalid, and the actual argument associated with an INTENT(IN OUT) dummy argument must indeed be definable, but the argument association itself is not a problem.
1 parent a77d119 commit 164f94f

File tree

4 files changed

+21
-7
lines changed

4 files changed

+21
-7
lines changed

flang/lib/Semantics/check-call.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -703,12 +703,14 @@ static void CheckExplicitDataArg(const characteristics::DummyDataObject &dummy,
703703
// Problems with polymorphism are caught in the callee's definition.
704704
if (scope) {
705705
std::optional<parser::MessageFixedText> undefinableMessage;
706-
if (dummy.intent == common::Intent::Out) {
707-
undefinableMessage =
708-
"Actual argument associated with INTENT(OUT) %s is not definable"_err_en_US;
709-
} else if (dummy.intent == common::Intent::InOut) {
706+
DefinabilityFlags flags{DefinabilityFlag::PolymorphicOkInPure};
707+
if (dummy.intent == common::Intent::InOut) {
708+
flags.set(DefinabilityFlag::AllowEventLockOrNotifyType);
710709
undefinableMessage =
711710
"Actual argument associated with INTENT(IN OUT) %s is not definable"_err_en_US;
711+
} else if (dummy.intent == common::Intent::Out) {
712+
undefinableMessage =
713+
"Actual argument associated with INTENT(OUT) %s is not definable"_err_en_US;
712714
} else if (context.ShouldWarn(common::LanguageFeature::
713715
UndefinableAsynchronousOrVolatileActual)) {
714716
if (dummy.attrs.test(
@@ -722,7 +724,6 @@ static void CheckExplicitDataArg(const characteristics::DummyDataObject &dummy,
722724
}
723725
}
724726
if (undefinableMessage) {
725-
DefinabilityFlags flags{DefinabilityFlag::PolymorphicOkInPure};
726727
if (isElemental) { // 15.5.2.4(21)
727728
flags.set(DefinabilityFlag::VectorSubscriptIsOk);
728729
}

flang/lib/Semantics/definable.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,8 @@ static std::optional<parser::Message> WhyNotDefinableLast(parser::CharBlock at,
204204
}
205205
return std::nullopt; // pointer assignment - skip following checks
206206
}
207-
if (IsOrContainsEventOrLockComponent(ultimate)) {
207+
if (!flags.test(DefinabilityFlag::AllowEventLockOrNotifyType) &&
208+
IsOrContainsEventOrLockComponent(ultimate)) {
208209
return BlameSymbol(at,
209210
"'%s' is an entity with either an EVENT_TYPE or LOCK_TYPE"_en_US,
210211
original);

flang/lib/Semantics/definable.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ ENUM_CLASS(DefinabilityFlag,
3232
AcceptAllocatable, // treat allocatable as if it were a pointer
3333
SourcedAllocation, // ALLOCATE(a,SOURCE=)
3434
PolymorphicOkInPure, // don't check for polymorphic type in pure subprogram
35-
DoNotNoteDefinition) // context does not imply definition
35+
DoNotNoteDefinition, // context does not imply definition
36+
AllowEventLockOrNotifyType)
3637

3738
using DefinabilityFlags =
3839
common::EnumSet<DefinabilityFlag, DefinabilityFlag_enumSize>;

flang/test/Semantics/definable01.f90

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,3 +113,14 @@ pure subroutine test7(lp)
113113
lp%next%next => null()
114114
end
115115
end module
116+
program main
117+
use iso_fortran_env, only: lock_type
118+
type(lock_type) lock
119+
interface
120+
subroutine inoutlock(lock)
121+
import lock_type
122+
type(lock_type), intent(in out) :: lock
123+
end
124+
end interface
125+
call inoutlock(lock) ! ok
126+
end

0 commit comments

Comments
 (0)