[flang-commits] [flang] 07b3bba - [flang] Allow LOCK_TYPE & al. to associate with INTENT(IN OUT) (#121413)
via flang-commits
flang-commits at lists.llvm.org
Wed Jan 8 13:14:05 PST 2025
Author: Peter Klausler
Date: 2025-01-08T13:14:02-08:00
New Revision: 07b3bba901e7d51b3173631d6af811eae9d84cda
URL: https://github.com/llvm/llvm-project/commit/07b3bba901e7d51b3173631d6af811eae9d84cda
DIFF: https://github.com/llvm/llvm-project/commit/07b3bba901e7d51b3173631d6af811eae9d84cda.diff
LOG: [flang] Allow LOCK_TYPE & al. to associate with INTENT(IN OUT) (#121413)
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.
Added:
Modified:
flang/lib/Semantics/assignment.cpp
flang/lib/Semantics/check-call.cpp
flang/lib/Semantics/definable.cpp
flang/lib/Semantics/definable.h
flang/test/Semantics/definable01.f90
Removed:
################################################################################
diff --git a/flang/lib/Semantics/assignment.cpp b/flang/lib/Semantics/assignment.cpp
index e69a73c7837ce6..0b57197fb8db8b 100644
--- a/flang/lib/Semantics/assignment.cpp
+++ b/flang/lib/Semantics/assignment.cpp
@@ -66,8 +66,13 @@ void AssignmentContext::Analyze(const parser::AssignmentStmt &stmt) {
const SomeExpr &rhs{assignment->rhs};
auto lhsLoc{std::get<parser::Variable>(stmt.t).GetSource()};
const Scope &scope{context_.FindScope(lhsLoc)};
- if (auto whyNot{WhyNotDefinable(lhsLoc, scope,
- DefinabilityFlags{DefinabilityFlag::VectorSubscriptIsOk}, lhs)}) {
+ DefinabilityFlags flags{DefinabilityFlag::VectorSubscriptIsOk};
+ bool isDefinedAssignment{
+ std::holds_alternative<evaluate::ProcedureRef>(assignment->u)};
+ if (isDefinedAssignment) {
+ flags.set(DefinabilityFlag::AllowEventLockOrNotifyType);
+ }
+ if (auto whyNot{WhyNotDefinable(lhsLoc, scope, flags, lhs)}) {
if (whyNot->IsFatal()) {
if (auto *msg{Say(lhsLoc,
"Left-hand side of assignment is not definable"_err_en_US)}) {
@@ -79,9 +84,7 @@ void AssignmentContext::Analyze(const parser::AssignmentStmt &stmt) {
}
}
auto rhsLoc{std::get<parser::Expr>(stmt.t).source};
- if (std::holds_alternative<evaluate::ProcedureRef>(assignment->u)) {
- // it's a defined ASSIGNMENT(=)
- } else {
+ if (!isDefinedAssignment) {
CheckForPureContext(rhs, rhsLoc);
}
if (whereDepth_ > 0) {
diff --git a/flang/lib/Semantics/check-call.cpp b/flang/lib/Semantics/check-call.cpp
index 597c280a6df8bc..8631789b9f5263 100644
--- a/flang/lib/Semantics/check-call.cpp
+++ b/flang/lib/Semantics/check-call.cpp
@@ -703,12 +703,14 @@ static void CheckExplicitDataArg(const characteristics::DummyDataObject &dummy,
// Problems with polymorphism are caught in the callee's definition.
if (scope) {
std::optional<parser::MessageFixedText> undefinableMessage;
- if (dummy.intent == common::Intent::Out) {
- undefinableMessage =
- "Actual argument associated with INTENT(OUT) %s is not definable"_err_en_US;
- } else if (dummy.intent == common::Intent::InOut) {
+ DefinabilityFlags flags{DefinabilityFlag::PolymorphicOkInPure};
+ if (dummy.intent == common::Intent::InOut) {
+ flags.set(DefinabilityFlag::AllowEventLockOrNotifyType);
undefinableMessage =
"Actual argument associated with INTENT(IN OUT) %s is not definable"_err_en_US;
+ } else if (dummy.intent == common::Intent::Out) {
+ undefinableMessage =
+ "Actual argument associated with INTENT(OUT) %s is not definable"_err_en_US;
} else if (context.ShouldWarn(common::LanguageFeature::
UndefinableAsynchronousOrVolatileActual)) {
if (dummy.attrs.test(
@@ -722,7 +724,6 @@ static void CheckExplicitDataArg(const characteristics::DummyDataObject &dummy,
}
}
if (undefinableMessage) {
- DefinabilityFlags flags{DefinabilityFlag::PolymorphicOkInPure};
if (isElemental) { // 15.5.2.4(21)
flags.set(DefinabilityFlag::VectorSubscriptIsOk);
}
diff --git a/flang/lib/Semantics/definable.cpp b/flang/lib/Semantics/definable.cpp
index 88f9463e35c787..6d0155c24c31ab 100644
--- a/flang/lib/Semantics/definable.cpp
+++ b/flang/lib/Semantics/definable.cpp
@@ -204,7 +204,8 @@ static std::optional<parser::Message> WhyNotDefinableLast(parser::CharBlock at,
}
return std::nullopt; // pointer assignment - skip following checks
}
- if (IsOrContainsEventOrLockComponent(ultimate)) {
+ if (!flags.test(DefinabilityFlag::AllowEventLockOrNotifyType) &&
+ IsOrContainsEventOrLockComponent(ultimate)) {
return BlameSymbol(at,
"'%s' is an entity with either an EVENT_TYPE or LOCK_TYPE"_en_US,
original);
diff --git a/flang/lib/Semantics/definable.h b/flang/lib/Semantics/definable.h
index 709bbba494d10d..902702dbccbf33 100644
--- a/flang/lib/Semantics/definable.h
+++ b/flang/lib/Semantics/definable.h
@@ -32,7 +32,8 @@ ENUM_CLASS(DefinabilityFlag,
AcceptAllocatable, // treat allocatable as if it were a pointer
SourcedAllocation, // ALLOCATE(a,SOURCE=)
PolymorphicOkInPure, // don't check for polymorphic type in pure subprogram
- DoNotNoteDefinition) // context does not imply definition
+ DoNotNoteDefinition, // context does not imply definition
+ AllowEventLockOrNotifyType)
using DefinabilityFlags =
common::EnumSet<DefinabilityFlag, DefinabilityFlag_enumSize>;
diff --git a/flang/test/Semantics/definable01.f90 b/flang/test/Semantics/definable01.f90
index ff71b419fa9713..d3b31ee38b2a3a 100644
--- a/flang/test/Semantics/definable01.f90
+++ b/flang/test/Semantics/definable01.f90
@@ -109,7 +109,29 @@ pure function test6(lp)
end
pure subroutine test7(lp)
type(list), pointer :: lp
- !CHECK-NOT: error:
- lp%next%next => null()
+ lp%next%next => null() ! ok
end
end module
+program main
+ use iso_fortran_env, only: lock_type
+ type(lock_type) lock
+ interface
+ subroutine inlock(lock)
+ import lock_type
+ type(lock_type), intent(in) :: lock
+ end
+ subroutine outlock(lock)
+ import lock_type
+ !CHECK: error: An INTENT(OUT) dummy argument may not be, or contain, EVENT_TYPE or LOCK_TYPE
+ type(lock_type), intent(out) :: lock
+ end
+ subroutine inoutlock(lock)
+ import lock_type
+ type(lock_type), intent(in out) :: lock
+ end
+ end interface
+ call inlock(lock) ! ok
+ call inoutlock(lock) ! ok
+ !CHECK: error: Actual argument associated with INTENT(OUT) dummy argument 'lock=' is not definable
+ call outlock(lock)
+end
More information about the flang-commits
mailing list