-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[flang] Extension: associating polymorphic pointer/allocatable actual… #93211
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
… with monomorphic dummy The relevant standard requires (F'2023 15.5.2.6 p2) that when a pointer or allocatable actual argument is associated with an identically-attributed dummy argument, either both are polymorphic or neither is. We already relax this requirement in the case of an INTENT(IN) dummy argument, since a change of type cannot occur. Further, like other compilers do, we can also relax this requirement in the case of a limited polymorphic actual argument being associated with a monomorphic dummy, as our implementation always passes a reference to the actual descriptor, where any change of type that occurs during the call due to reallocation will be properly recorded.
@llvm/pr-subscribers-flang-semantics Author: Peter Klausler (klausler) Changes… with monomorphic dummy The relevant standard requires (F'2023 15.5.2.6 p2) that when a pointer or allocatable actual argument is associated with an identically-attributed dummy argument, either both are polymorphic or neither is. We already relax this requirement in the case of an INTENT(IN) dummy argument, since a change of type cannot occur. Further, like other compilers do, we can also relax this requirement in the case of a limited polymorphic actual argument being associated with a monomorphic dummy, as our implementation always passes a reference to the actual descriptor, where any change of type that occurs during the call due to reallocation will be properly recorded. Full diff: https://github.com/llvm/llvm-project/pull/93211.diff 4 Files Affected:
diff --git a/flang/docs/Extensions.md b/flang/docs/Extensions.md
index 43ed35e36a6e1..7b872c786c82c 100644
--- a/flang/docs/Extensions.md
+++ b/flang/docs/Extensions.md
@@ -223,6 +223,10 @@ end
* When a dummy argument is `POINTER` or `ALLOCATABLE` and is `INTENT(IN)`, we
relax enforcement of some requirements on actual arguments that must otherwise
hold true for definable arguments.
+* We allow a limited polymorphic `POINTER` or `ALLOCATABLE` actual argument
+ to be associated with a compatible monomorphic dummy argument, as
+ our implementation, like others, supports a reallocation that would
+ change the dynamic type
* Assignment of `LOGICAL` to `INTEGER` and vice versa (but not other types) is
allowed. The values are normalized to canonical `.TRUE.`/`.FALSE.`.
The values are also normalized for assignments of `LOGICAL(KIND=K1)` to
diff --git a/flang/include/flang/Common/Fortran-features.h b/flang/include/flang/Common/Fortran-features.h
index f57fcdc895adc..15c4af63f4be7 100644
--- a/flang/include/flang/Common/Fortran-features.h
+++ b/flang/include/flang/Common/Fortran-features.h
@@ -49,7 +49,8 @@ ENUM_CLASS(LanguageFeature, BackslashEscapes, OldDebugLines,
IndistinguishableSpecifics, SubroutineAndFunctionSpecifics,
EmptySequenceType, NonSequenceCrayPointee, BranchIntoConstruct,
BadBranchTarget, ConvertedArgument, HollerithPolymorphic, ListDirectedSize,
- NonBindCInteroperability, CudaManaged, CudaUnified)
+ NonBindCInteroperability, CudaManaged, CudaUnified,
+ PolymorphicActualAllocatableOrPointerToMonomorphicDummy)
// Portability and suspicious usage warnings
ENUM_CLASS(UsageWarning, Portability, PointerToUndefinable,
diff --git a/flang/lib/Semantics/check-call.cpp b/flang/lib/Semantics/check-call.cpp
index 8f51ef5ebeba3..4f019b376c817 100644
--- a/flang/lib/Semantics/check-call.cpp
+++ b/flang/lib/Semantics/check-call.cpp
@@ -761,7 +761,8 @@ static void CheckExplicitDataArg(const characteristics::DummyDataObject &dummy,
}
// 15.5.2.5 -- actual & dummy are both POINTER or both ALLOCATABLE
- // For INTENT(IN) we relax two checks that are in Fortran to
+ // For INTENT(IN), and for a polymorphic actual being associated with a
+ // monomorphic dummy, we relax two checks that are in Fortran to
// prevent the callee from changing the type or to avoid having
// to use a descriptor.
if (!typesCompatible) {
@@ -770,7 +771,9 @@ static void CheckExplicitDataArg(const characteristics::DummyDataObject &dummy,
(actualIsAllocatable && dummyIsAllocatable)) {
bool actualIsUnlimited{actualType.type().IsUnlimitedPolymorphic()};
bool dummyIsUnlimited{dummy.type.type().IsUnlimitedPolymorphic()};
+ bool checkTypeCompatibility{true};
if (actualIsUnlimited != dummyIsUnlimited) {
+ checkTypeCompatibility = false;
if (dummyIsUnlimited && dummy.intent == common::Intent::In &&
context.IsEnabled(common::LanguageFeature::RelaxedIntentInChecking)) {
if (context.ShouldWarn(
@@ -790,11 +793,21 @@ static void CheckExplicitDataArg(const characteristics::DummyDataObject &dummy,
messages.Say(
"If a POINTER or ALLOCATABLE dummy or actual argument is polymorphic, both should be so"_port_en_US);
}
+ } else if (actualIsPolymorphic &&
+ context.IsEnabled(common::LanguageFeature::
+ PolymorphicActualAllocatableOrPointerToMonomorphicDummy)) {
+ if (context.ShouldWarn(common::LanguageFeature::
+ PolymorphicActualAllocatableOrPointerToMonomorphicDummy)) {
+ messages.Say(
+ "If a POINTER or ALLOCATABLE actual argument is polymorphic, the corresponding dummy argument should also be so"_port_en_US);
+ }
} else {
+ checkTypeCompatibility = false;
messages.Say(
"If a POINTER or ALLOCATABLE dummy or actual argument is polymorphic, both must be so"_err_en_US);
}
- } else if (!actualIsUnlimited) {
+ }
+ if (checkTypeCompatibility && !actualIsUnlimited) {
if (!actualType.type().IsTkCompatibleWith(dummy.type.type())) {
if (dummy.intent == common::Intent::In &&
context.IsEnabled(
diff --git a/flang/test/Semantics/call05.f90 b/flang/test/Semantics/call05.f90
index 66d0a375fa56d..71f2197067f76 100644
--- a/flang/test/Semantics/call05.f90
+++ b/flang/test/Semantics/call05.f90
@@ -1,4 +1,4 @@
-! RUN: %python %S/test_errors.py %s %flang_fc1
+! RUN: %python %S/test_errors.py %s %flang_fc1 -pedantic
! Test 15.5.2.5 constraints and restrictions for POINTER & ALLOCATABLE
! arguments when both sides of the call have the same attributes.
@@ -73,9 +73,9 @@ subroutine test
call sma(ma) ! ok
call spp(pp) ! ok
call spa(pa) ! ok
- !ERROR: If a POINTER or ALLOCATABLE dummy or actual argument is polymorphic, both must be so
+ !PORTABILITY: If a POINTER or ALLOCATABLE actual argument is polymorphic, the corresponding dummy argument should also be so
call smp(pp)
- !ERROR: If a POINTER or ALLOCATABLE dummy or actual argument is polymorphic, both must be so
+ !PORTABILITY: If a POINTER or ALLOCATABLE actual argument is polymorphic, the corresponding dummy argument should also be so
call sma(pa)
!ERROR: If a POINTER or ALLOCATABLE dummy or actual argument is polymorphic, both must be so
call spp(mp)
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
… with monomorphic dummy
The relevant standard requires (F'2023 15.5.2.6 p2) that when a pointer or allocatable actual argument is associated with an identically-attributed dummy argument, either both are polymorphic or neither is. We already relax this requirement in the case of an INTENT(IN) dummy argument, since a change of type cannot occur. Further, like other compilers do, we can also relax this requirement in the case of a limited polymorphic actual argument being associated with a monomorphic dummy, as our implementation always passes a reference to the actual descriptor, where any change of type that occurs during the call due to reallocation will be properly recorded.