Skip to content

Commit ffa7b49

Browse files
committed
[flang] Add warnings about undefinable actuals for ASYNCHRONOUS/VOLATILE dummies
There's language in the standard (F'2023 15.5.2.5 p21) disallowing an actual argument with a vector subscript from associating with a dummy argument with either the ASYNCHRONOUS or VOLATILE attributes. This is a bug in the standard, as (1) these attributes are actually relevant only over the scope of the called procedure, (2) they can be applied in nested scopes (internal subprograms and BLOCK) within the called procedure, and (3) can be implicit within the called procedure and its nested scopes in the case of ASYNCHRONOUS as a side effect of using a dummy argument in an asynchronous data transfer statement. So issue a warning. This new warning about undefinable actual arguments being associated with ASYNCHRONOUS and VOLATILE dummy arguments subsumes an existing warning about passing a constant actual to a VOLATILE dummy. Resolves #93600.
1 parent 82bd7ad commit ffa7b49

File tree

5 files changed

+85
-51
lines changed

5 files changed

+85
-51
lines changed

flang/docs/Extensions.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,16 @@ 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+
* A non-definable actual argument, including the case of a vector
122+
subscript, may be associated with an `ASYNCHRONOUS` or `VOLATILE`
123+
dummy argument, F'2023 15.5.2.5 p31 notwithstanding.
124+
The effects of these attributes are scoped over the lifetime of
125+
the procedure reference, and they can by added by internal subprograms
126+
and `BLOCK` constructs within the procedure.
127+
Further, a dummy argument can acquire the `ASYNCHRONOUS` attribute
128+
implicitly simply appearing in an asynchronous data transfer statement,
129+
without the attribute being visible in the procedure's explicit
130+
interface.
121131

122132
## Extensions, deletions, and legacy features supported by default
123133

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,14 +50,14 @@ ENUM_CLASS(LanguageFeature, BackslashEscapes, OldDebugLines,
5050
EmptySequenceType, NonSequenceCrayPointee, BranchIntoConstruct,
5151
BadBranchTarget, ConvertedArgument, HollerithPolymorphic, ListDirectedSize,
5252
NonBindCInteroperability, CudaManaged, CudaUnified,
53-
PolymorphicActualAllocatableOrPointerToMonomorphicDummy)
53+
PolymorphicActualAllocatableOrPointerToMonomorphicDummy,
54+
UndefinableAsynchronousOrVolatileActual)
5455

5556
// Portability and suspicious usage warnings
5657
ENUM_CLASS(UsageWarning, Portability, PointerToUndefinable,
5758
NonTargetPassedToTarget, PointerToPossibleNoncontiguous,
58-
ShortCharacterActual, ShortArrayActual, ExprPassedToVolatile,
59-
ImplicitInterfaceActual, PolymorphicTransferArg,
60-
PointerComponentTransferArg, TransferSizePresence,
59+
ShortCharacterActual, ShortArrayActual, ImplicitInterfaceActual,
60+
PolymorphicTransferArg, PointerComponentTransferArg, TransferSizePresence,
6161
F202XAllocatableBreakingChange, OptionalMustBePresent, CommonBlockPadding,
6262
LogicalVsCBool, BindCCharLength, ProcDummyArgShapes, ExternalNameConflict,
6363
FoldingException, FoldingAvoidsRuntimeCrash, FoldingValueChecks,

flang/lib/Semantics/check-call.cpp

Lines changed: 35 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -645,40 +645,44 @@ static void CheckExplicitDataArg(const characteristics::DummyDataObject &dummy,
645645

646646
// Definability
647647
bool actualIsVariable{evaluate::IsVariable(actual)};
648-
const char *reason{nullptr};
649-
if (dummy.intent == common::Intent::Out) {
650-
reason = "INTENT(OUT)";
651-
} else if (dummy.intent == common::Intent::InOut) {
652-
reason = "INTENT(IN OUT)";
653-
}
654-
if (reason && scope) {
655-
// Problems with polymorphism are caught in the callee's definition.
656-
DefinabilityFlags flags{DefinabilityFlag::PolymorphicOkInPure};
657-
if (isElemental) { // 15.5.2.4(21)
658-
flags.set(DefinabilityFlag::VectorSubscriptIsOk);
659-
}
660-
if (actualIsPointer && dummyIsPointer) { // 19.6.8
661-
flags.set(DefinabilityFlag::PointerDefinition);
648+
if (scope) {
649+
std::optional<parser::MessageFixedText> undefinableMessage;
650+
if (dummy.intent == common::Intent::Out) {
651+
undefinableMessage =
652+
"Actual argument associated with INTENT(OUT) %s is not definable"_err_en_US;
653+
} else if (dummy.intent == common::Intent::InOut) {
654+
undefinableMessage =
655+
"Actual argument associated with INTENT(IN OUT) %s is not definable"_err_en_US;
656+
} else if (context.ShouldWarn(common::LanguageFeature::
657+
UndefinableAsynchronousOrVolatileActual)) {
658+
if (dummy.attrs.test(
659+
characteristics::DummyDataObject::Attr::Asynchronous)) {
660+
undefinableMessage =
661+
"Actual argument associated with ASYNCHRONOUS %s is not definable"_warn_en_US;
662+
} else if (dummy.attrs.test(
663+
characteristics::DummyDataObject::Attr::Volatile)) {
664+
undefinableMessage =
665+
"Actual argument associated with VOLATILE %s is not definable"_warn_en_US;
666+
}
662667
}
663-
if (auto whyNot{WhyNotDefinable(messages.at(), *scope, flags, actual)}) {
664-
if (auto *msg{messages.Say(
665-
"Actual argument associated with %s %s is not definable"_err_en_US,
666-
reason, dummyName)}) {
667-
msg->Attach(std::move(*whyNot));
668+
if (undefinableMessage) {
669+
// Problems with polymorphism are caught in the callee's definition.
670+
DefinabilityFlags flags{DefinabilityFlag::PolymorphicOkInPure};
671+
if (isElemental) { // 15.5.2.4(21)
672+
flags.set(DefinabilityFlag::VectorSubscriptIsOk);
673+
}
674+
if (actualIsPointer && dummyIsPointer) { // 19.6.8
675+
flags.set(DefinabilityFlag::PointerDefinition);
676+
}
677+
if (auto whyNot{WhyNotDefinable(messages.at(), *scope, flags, actual)}) {
678+
if (auto *msg{
679+
messages.Say(std::move(*undefinableMessage), dummyName)}) {
680+
msg->Attach(std::move(*whyNot));
681+
}
668682
}
669683
}
670684
}
671685

672-
// technically legal but worth emitting a warning
673-
// llvm-project issue #58973: constant actual argument passed in where dummy
674-
// argument is marked volatile
675-
if (dummyIsVolatile && !actualIsVariable &&
676-
context.ShouldWarn(common::UsageWarning::ExprPassedToVolatile)) {
677-
messages.Say(
678-
"actual argument associated with VOLATILE %s is not a variable"_warn_en_US,
679-
dummyName);
680-
}
681-
682686
// Cases when temporaries might be needed but must not be permitted.
683687
bool actualIsContiguous{IsSimplyContiguous(actual, foldingContext)};
684688
bool dummyIsAssumedShape{dummy.type.attrs().test(
@@ -876,7 +880,8 @@ static void CheckExplicitDataArg(const characteristics::DummyDataObject &dummy,
876880
dummyName, actual.AsFortran());
877881
}
878882

879-
// Warn about dubious actual argument association with a TARGET dummy argument
883+
// Warn about dubious actual argument association with a TARGET dummy
884+
// argument
880885
if (dummy.attrs.test(characteristics::DummyDataObject::Attr::Target) &&
881886
context.ShouldWarn(common::UsageWarning::NonTargetPassedToTarget)) {
882887
bool actualIsTemp{!actualIsVariable || HasVectorSubscript(actual) ||

flang/test/Semantics/call03.f90

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -300,8 +300,12 @@ subroutine test12 ! 15.5.2.4(21)
300300
!ERROR: Actual argument associated with INTENT(IN OUT) dummy argument 'x=' is not definable
301301
!BECAUSE: Variable 'a(int(j,kind=8))' has a vector subscript
302302
call intentinout_arr(a(j))
303-
call asynchronous_arr(a(j)) ! ok
304-
call volatile_arr(a(j)) ! ok
303+
!WARNING: Actual argument associated with ASYNCHRONOUS dummy argument 'x=' is not definable
304+
!BECAUSE: Variable 'a(int(j,kind=8))' has a vector subscript
305+
call asynchronous_arr(a(j))
306+
!WARNING: Actual argument associated with VOLATILE dummy argument 'x=' is not definable
307+
!BECAUSE: Variable 'a(int(j,kind=8))' has a vector subscript
308+
call volatile_arr(a(j))
305309
end subroutine
306310

307311
subroutine coarr(x)

flang/test/Semantics/call30.f90

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -23,35 +23,50 @@ subroutine vol_dum_int_arr(my_int_arr)
2323
end subroutine vol_dum_int_arr
2424

2525
subroutine test_all_subprograms()
26-
!WARNING: actual argument associated with VOLATILE dummy argument 'my_int=' is not a variable
26+
!WARNING: Actual argument associated with VOLATILE dummy argument 'my_int=' is not definable
27+
!BECAUSE: '6_4' is not a variable or pointer
2728
call vol_dum_int(6)
28-
!WARNING: actual argument associated with VOLATILE dummy argument 'my_int=' is not a variable
29+
!WARNING: Actual argument associated with VOLATILE dummy argument 'my_int=' is not definable
30+
!BECAUSE: '18_4' is not a variable or pointer
2931
call vol_dum_int(6+12)
30-
!WARNING: actual argument associated with VOLATILE dummy argument 'my_int=' is not a variable
32+
!WARNING: Actual argument associated with VOLATILE dummy argument 'my_int=' is not definable
33+
!BECAUSE: '72_4' is not a variable or pointer
3134
call vol_dum_int(6*12)
32-
!WARNING: actual argument associated with VOLATILE dummy argument 'my_int=' is not a variable
35+
!WARNING: Actual argument associated with VOLATILE dummy argument 'my_int=' is not definable
36+
!BECAUSE: '-3_4' is not a variable or pointer
3337
call vol_dum_int(-6/2)
34-
!WARNING: actual argument associated with VOLATILE dummy argument 'my_real=' is not a variable
38+
!WARNING: Actual argument associated with VOLATILE dummy argument 'my_real=' is not definable
39+
!BECAUSE: '3.1415927410125732421875_4' is not a variable or pointer
3540
call vol_dum_real(3.141592653)
36-
!WARNING: actual argument associated with VOLATILE dummy argument 'my_real=' is not a variable
41+
!WARNING: Actual argument associated with VOLATILE dummy argument 'my_real=' is not definable
42+
!BECAUSE: '3.1415927410125732421875_4' is not a variable or pointer
3743
call vol_dum_real(3.141592653 + (-10.6e-11))
38-
!WARNING: actual argument associated with VOLATILE dummy argument 'my_real=' is not a variable
44+
!WARNING: Actual argument associated with VOLATILE dummy argument 'my_real=' is not definable
45+
!BECAUSE: '3.3300884272335906644002534449100494384765625e-10_4' is not a variable or pointer
3946
call vol_dum_real(3.141592653 * 10.6e-11)
40-
!WARNING: actual argument associated with VOLATILE dummy argument 'my_real=' is not a variable
47+
!WARNING: Actual argument associated with VOLATILE dummy argument 'my_real=' is not definable
48+
!BECAUSE: '-2.9637666816e10_4' is not a variable or pointer
4149
call vol_dum_real(3.141592653 / (-10.6e-11))
42-
!WARNING: actual argument associated with VOLATILE dummy argument 'my_complex=' is not a variable
50+
!WARNING: Actual argument associated with VOLATILE dummy argument 'my_complex=' is not definable
51+
!BECAUSE: '(1._4,3.2000000476837158203125_4)' is not a variable or pointer
4352
call vol_dum_complex((1., 3.2))
44-
!WARNING: actual argument associated with VOLATILE dummy argument 'my_complex=' is not a variable
53+
!WARNING: Actual argument associated with VOLATILE dummy argument 'my_complex=' is not definable
54+
!BECAUSE: '(-1._4,6.340000152587890625_4)' is not a variable or pointer
4555
call vol_dum_complex((1., 3.2) + (-2., 3.14))
46-
!WARNING: actual argument associated with VOLATILE dummy argument 'my_complex=' is not a variable
56+
!WARNING: Actual argument associated with VOLATILE dummy argument 'my_complex=' is not definable
57+
!BECAUSE: '(-1.2048000335693359375e1_4,-3.2599999904632568359375_4)' is not a variable or pointer
4758
call vol_dum_complex((1., 3.2) * (-2., 3.14))
48-
!WARNING: actual argument associated with VOLATILE dummy argument 'my_complex=' is not a variable
59+
!WARNING: Actual argument associated with VOLATILE dummy argument 'my_complex=' is not definable
60+
!BECAUSE: '(5.80680549144744873046875e-1_4,-6.8833148479461669921875e-1_4)' is not a variable or pointer
4961
call vol_dum_complex((1., 3.2) / (-2., 3.14))
50-
!WARNING: actual argument associated with VOLATILE dummy argument 'my_int_arr=' is not a variable
62+
!WARNING: Actual argument associated with VOLATILE dummy argument 'my_int_arr=' is not definable
63+
!BECAUSE: '[INTEGER(4)::1_4,2_4,3_4,4_4]' is not a variable or pointer
5164
call vol_dum_int_arr((/ 1, 2, 3, 4 /))
52-
!WARNING: actual argument associated with VOLATILE dummy argument 'my_int_arr=' is not a variable
65+
!WARNING: Actual argument associated with VOLATILE dummy argument 'my_int_arr=' is not definable
66+
!BECAUSE: 'reshape([INTEGER(4)::1_4,2_4,3_4,4_4],shape=[2,2])' is not a variable or pointer
5367
call vol_dum_int_arr(reshape((/ 1, 2, 3, 4 /), (/ 2, 2/)))
54-
!WARNING: actual argument associated with VOLATILE dummy argument 'my_int_arr=' is not a variable
68+
!WARNING: Actual argument associated with VOLATILE dummy argument 'my_int_arr=' is not definable
69+
!BECAUSE: '[INTEGER(4)::1_4,2_4,3_4,4_4]' is not a variable or pointer
5570
call vol_dum_int_arr((/ 1, 2, 3, 4 /))
5671
end subroutine test_all_subprograms
5772
end module m

0 commit comments

Comments
 (0)