Skip to content

Commit caa0a26

Browse files
authored
[flang] Add warnings about undefinable actuals for ASYNCHRONOUS/VOLAT… (#93851)
…ILE 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 c2d061d commit caa0a26

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
@@ -124,6 +124,16 @@ end
124124
This enables atomic memory operations to be naturally represented
125125
as `PURE` functions, which allows their use in parallel constructs
126126
and `DO CONCURRENT`.
127+
* A non-definable actual argument, including the case of a vector
128+
subscript, may be associated with an `ASYNCHRONOUS` or `VOLATILE`
129+
dummy argument, F'2023 15.5.2.5 p31 notwithstanding.
130+
The effects of these attributes are scoped over the lifetime of
131+
the procedure reference, and they can by added by internal subprograms
132+
and `BLOCK` constructs within the procedure.
133+
Further, a dummy argument can acquire the `ASYNCHRONOUS` attribute
134+
implicitly simply appearing in an asynchronous data transfer statement,
135+
without the attribute being visible in the procedure's explicit
136+
interface.
127137

128138
## Extensions, deletions, and legacy features supported by default
129139

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, RelaxedPureDummy)
53+
PolymorphicActualAllocatableOrPointerToMonomorphicDummy, RelaxedPureDummy,
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
@@ -652,40 +652,44 @@ static void CheckExplicitDataArg(const characteristics::DummyDataObject &dummy,
652652

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

679-
// technically legal but worth emitting a warning
680-
// llvm-project issue #58973: constant actual argument passed in where dummy
681-
// argument is marked volatile
682-
if (dummyIsVolatile && !actualIsVariable &&
683-
context.ShouldWarn(common::UsageWarning::ExprPassedToVolatile)) {
684-
messages.Say(
685-
"actual argument associated with VOLATILE %s is not a variable"_warn_en_US,
686-
dummyName);
687-
}
688-
689693
// Cases when temporaries might be needed but must not be permitted.
690694
bool actualIsContiguous{IsSimplyContiguous(actual, foldingContext)};
691695
bool dummyIsAssumedShape{dummy.type.attrs().test(
@@ -883,7 +887,8 @@ static void CheckExplicitDataArg(const characteristics::DummyDataObject &dummy,
883887
dummyName, actual.AsFortran());
884888
}
885889

886-
// Warn about dubious actual argument association with a TARGET dummy argument
890+
// Warn about dubious actual argument association with a TARGET dummy
891+
// argument
887892
if (dummy.attrs.test(characteristics::DummyDataObject::Attr::Target) &&
888893
context.ShouldWarn(common::UsageWarning::NonTargetPassedToTarget)) {
889894
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)