Skip to content

Commit b61d7ec

Browse files
authored
[flang] Relax constraints on PURE/ELEMENTAL dummy arguments (#93748)
The standard requires that dummy arguments to PURE functions be INTENT(IN) or VALUE, but PURE subroutines are allowed to have modifiable dummy arguments. This makes it impossible to declare atomic operations as PURE functions, which consequently makes such atomic operations ineligible for use in parallel constructs and DO CONCURRENT. This patch downgrades this error to a warning by default, which can be seen with -pedantic & al. and remain an error with -Werror.
1 parent 5cb0078 commit b61d7ec

File tree

5 files changed

+39
-14
lines changed

5 files changed

+39
-14
lines changed

flang/docs/Extensions.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,12 @@ end
118118
procedure interface. This compiler accepts it, since there is otherwise
119119
no way to declare an interoperable dummy procedure with an arbitrary
120120
interface like `void (*)()`.
121+
* `PURE` functions are allowed to have dummy arguments that are
122+
neither `INTENT(IN)` nor `VALUE`, similar to `PURE` subroutines,
123+
with a warning.
124+
This enables atomic memory operations to be naturally represented
125+
as `PURE` functions, which allows their use in parallel constructs
126+
and `DO CONCURRENT`.
121127

122128
## Extensions, deletions, and legacy features supported by default
123129

flang/include/flang/Common/Fortran-features.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ ENUM_CLASS(LanguageFeature, BackslashEscapes, OldDebugLines,
5050
EmptySequenceType, NonSequenceCrayPointee, BranchIntoConstruct,
5151
BadBranchTarget, ConvertedArgument, HollerithPolymorphic, ListDirectedSize,
5252
NonBindCInteroperability, CudaManaged, CudaUnified,
53-
PolymorphicActualAllocatableOrPointerToMonomorphicDummy)
53+
PolymorphicActualAllocatableOrPointerToMonomorphicDummy, RelaxedPureDummy)
5454

5555
// Portability and suspicious usage warnings
5656
ENUM_CLASS(UsageWarning, Portability, PointerToUndefinable,

flang/lib/Semantics/check-declarations.cpp

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -704,29 +704,48 @@ void CheckHelper::CheckObjectEntity(
704704
if (InPure() && !IsStmtFunction(DEREF(innermostSymbol_)) &&
705705
!IsPointer(symbol) && !IsIntentIn(symbol) &&
706706
!symbol.attrs().test(Attr::VALUE)) {
707-
if (InFunction()) { // C1583
708-
messages_.Say(
709-
"non-POINTER dummy argument of pure function must be INTENT(IN) or VALUE"_err_en_US);
710-
} else if (IsIntentOut(symbol)) {
707+
const char *what{InFunction() ? "function" : "subroutine"};
708+
bool ok{true};
709+
if (IsIntentOut(symbol)) {
711710
if (type && type->IsPolymorphic()) { // C1588
712711
messages_.Say(
713-
"An INTENT(OUT) dummy argument of a pure subroutine may not be polymorphic"_err_en_US);
712+
"An INTENT(OUT) dummy argument of a pure %s may not be polymorphic"_err_en_US,
713+
what);
714+
ok = false;
714715
} else if (derived) {
715716
if (FindUltimateComponent(*derived, [](const Symbol &x) {
716717
const DeclTypeSpec *type{x.GetType()};
717718
return type && type->IsPolymorphic();
718719
})) { // C1588
719720
messages_.Say(
720-
"An INTENT(OUT) dummy argument of a pure subroutine may not have a polymorphic ultimate component"_err_en_US);
721+
"An INTENT(OUT) dummy argument of a pure %s may not have a polymorphic ultimate component"_err_en_US,
722+
what);
723+
ok = false;
721724
}
722725
if (HasImpureFinal(symbol)) { // C1587
723726
messages_.Say(
724-
"An INTENT(OUT) dummy argument of a pure subroutine may not have an impure FINAL subroutine"_err_en_US);
727+
"An INTENT(OUT) dummy argument of a pure %s may not have an impure FINAL subroutine"_err_en_US,
728+
what);
729+
ok = false;
725730
}
726731
}
727732
} else if (!IsIntentInOut(symbol)) { // C1586
728733
messages_.Say(
729-
"non-POINTER dummy argument of pure subroutine must have INTENT() or VALUE attribute"_err_en_US);
734+
"non-POINTER dummy argument of pure %s must have INTENT() or VALUE attribute"_warn_en_US,
735+
what);
736+
ok = false;
737+
}
738+
if (ok && InFunction()) {
739+
if (context_.IsEnabled(common::LanguageFeature::RelaxedPureDummy)) {
740+
if (context_.ShouldWarn(common::LanguageFeature::RelaxedPureDummy) &&
741+
!InModuleFile() && !InElemental()) {
742+
messages_.Say(
743+
"non-POINTER dummy argument of pure function should be INTENT(IN) or VALUE"_warn_en_US);
744+
}
745+
} else {
746+
messages_.Say(
747+
"non-POINTER dummy argument of pure function must be INTENT(IN) or VALUE"_err_en_US);
748+
}
730749
}
731750
}
732751
if (auto ignoreTKR{GetIgnoreTKR(symbol)}; !ignoreTKR.empty()) {
@@ -798,7 +817,7 @@ void CheckHelper::CheckObjectEntity(
798817
"A dummy argument of an ELEMENTAL procedure may not be a POINTER"_err_en_US);
799818
}
800819
if (!symbol.attrs().HasAny(Attrs{Attr::VALUE, Attr::INTENT_IN,
801-
Attr::INTENT_INOUT, Attr::INTENT_OUT})) { // C15102
820+
Attr::INTENT_INOUT, Attr::INTENT_OUT})) { // F'2023 C15120
802821
messages_.Say(
803822
"A dummy argument of an ELEMENTAL procedure must have an INTENT() or VALUE attribute"_err_en_US);
804823
}

flang/test/Semantics/call10.f90

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
! RUN: %python %S/test_errors.py %s %flang_fc1
1+
! RUN: %python %S/test_errors.py %s %flang_fc1 -pedantic
22
! Test 15.7 (C1583-C1590, C1592-C1599) constraints and restrictions
33
! for pure procedures.
44
! (C1591 is tested in call11.f90; C1594 in call12.f90.)
@@ -53,14 +53,14 @@ pure real function f02(a)
5353
real, value :: a ! ok
5454
end function
5555
pure real function f03(a) ! C1583
56-
!ERROR: non-POINTER dummy argument of pure function must be INTENT(IN) or VALUE
56+
!ERROR: non-POINTER dummy argument of pure function must have INTENT() or VALUE attribute
5757
real :: a
5858
end function
5959
pure real function f03a(a)
6060
real, pointer :: a ! ok
6161
end function
6262
pure real function f04(a) ! C1583
63-
!ERROR: non-POINTER dummy argument of pure function must be INTENT(IN) or VALUE
63+
!WARNING: non-POINTER dummy argument of pure function should be INTENT(IN) or VALUE
6464
real, intent(out) :: a
6565
end function
6666
pure real function f04a(a)

flang/test/Semantics/elemental01.f90

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
! RUN: %python %S/test_errors.py %s %flang_fc1
1+
! RUN: %python %S/test_errors.py %s %flang_fc1 -pedantic
22
! Tests ELEMENTAL subprogram constraints C15100-15102
33

44
!ERROR: An ELEMENTAL subroutine may not have an alternate return dummy argument

0 commit comments

Comments
 (0)