Skip to content

Commit 2b46f61

Browse files
committed
[flang] Refine handling of NULL() actual to non-optional allocatable dummy
We presently allow a NULL() actual argument to associate with a non-optional dummy allocatable argument only under INTENT(IN). This is too strict, as it precludes the case of a dummy argument with default intent. Continue to require that the actual argument be definable under INTENT(OUT) and INTENT(IN OUT), and (contra XLF) interpret NULL() as being an expression, not a definable variable, even when it is given an allocatable MOLD. Fixes #115984.
1 parent fef4c8a commit 2b46f61

File tree

4 files changed

+47
-26
lines changed

4 files changed

+47
-26
lines changed

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ ENUM_CLASS(LanguageFeature, BackslashEscapes, OldDebugLines,
3838
DistinguishableSpecifics, DefaultSave, PointerInSeqType, NonCharacterFormat,
3939
SaveMainProgram, SaveBigMainProgramVariables,
4040
DistinctArrayConstructorLengths, PPCVector, RelaxedIntentInChecking,
41-
ForwardRefImplicitNoneData, NullActualForAllocatable,
41+
NullActualForAllocatable, ForwardRefImplicitNoneData,
4242
ActualIntegerConvertedToSmallerKind, HollerithOrCharacterAsBOZ,
4343
BindingAsProcedure, StatementFunctionExtensions,
4444
UseGenericIntrinsicWhenSpecificDoesntMatch, DataStmtExtensions,
@@ -72,7 +72,7 @@ ENUM_CLASS(UsageWarning, Portability, PointerToUndefinable,
7272
PreviousScalarUse, RedeclaredInaccessibleComponent, ImplicitShared,
7373
IndexVarRedefinition, IncompatibleImplicitInterfaces, BadTypeForTarget,
7474
VectorSubscriptFinalization, UndefinedFunctionResult, UselessIomsg,
75-
MismatchingDummyProcedure)
75+
MismatchingDummyProcedure, NullActualForDefaultIntentAllocatable)
7676

7777
using LanguageFeatures = EnumSet<LanguageFeature, LanguageFeature_enumSize>;
7878
using UsageWarnings = EnumSet<UsageWarning, UsageWarning_enumSize>;

flang/lib/Common/Fortran-features.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,10 @@ LanguageFeatureControl::LanguageFeatureControl() {
8080
warnUsage_.set(UsageWarning::VectorSubscriptFinalization);
8181
warnUsage_.set(UsageWarning::UndefinedFunctionResult);
8282
warnUsage_.set(UsageWarning::UselessIomsg);
83+
warnUsage_.set(UsageWarning::NullActualForDefaultIntentAllocatable);
8384
// New warnings, on by default
8485
warnLanguage_.set(LanguageFeature::SavedLocalInSpecExpr);
86+
warnLanguage_.set(LanguageFeature::NullActualForAllocatable);
8587
}
8688

8789
// Ignore case and any inserted punctuation (like '-'/'_')

flang/lib/Semantics/check-call.cpp

Lines changed: 28 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -766,21 +766,21 @@ static void CheckExplicitDataArg(const characteristics::DummyDataObject &dummy,
766766
}
767767
} else if (actualIsNull) {
768768
if (dummyIsOptional) {
769-
} else if (dummy.intent == common::Intent::In) {
770-
// Extension (Intel, NAG, XLF): a NULL() pointer is an acceptable
771-
// actual argument for an INTENT(IN) allocatable dummy, and it
772-
// is treated as an unassociated allocatable.
773-
if (context.ShouldWarn(
774-
common::LanguageFeature::NullActualForAllocatable)) {
775-
messages.Say(common::LanguageFeature::NullActualForAllocatable,
776-
"Allocatable %s is associated with a null pointer"_port_en_US,
777-
dummyName);
778-
}
779-
} else {
769+
} else if (dummy.intent == common::Intent::Default &&
770+
context.ShouldWarn(
771+
common::UsageWarning::NullActualForDefaultIntentAllocatable)) {
780772
messages.Say(
781-
"A null pointer may not be associated with allocatable %s without INTENT(IN)"_err_en_US,
773+
"A null pointer should not be associated with allocatable %s without INTENT(IN)"_warn_en_US,
774+
dummyName);
775+
} else if (dummy.intent == common::Intent::In &&
776+
context.ShouldWarn(
777+
common::LanguageFeature::NullActualForAllocatable)) {
778+
messages.Say(common::LanguageFeature::NullActualForAllocatable,
779+
"Allocatable %s is associated with a null pointer"_port_en_US,
782780
dummyName);
783781
}
782+
// INTENT(OUT) and INTENT(IN OUT) cases are caught elsewhere as being
783+
// undefinable actual arguments.
784784
} else {
785785
messages.Say(
786786
"ALLOCATABLE %s must be associated with an ALLOCATABLE actual argument"_err_en_US,
@@ -1265,19 +1265,24 @@ static void CheckExplicitInterfaceArg(evaluate::ActualArgument &arg,
12651265
} else if (object.attrs.test(characteristics::DummyDataObject::
12661266
Attr::Allocatable) &&
12671267
evaluate::IsNullPointer(*expr)) {
1268-
if (object.intent == common::Intent::In) {
1269-
// Extension (Intel, NAG, XLF); see CheckExplicitDataArg.
1270-
if (context.ShouldWarn(common::LanguageFeature::
1271-
NullActualForAllocatable)) {
1272-
messages.Say(
1273-
common::LanguageFeature::NullActualForAllocatable,
1274-
"Allocatable %s is associated with NULL()"_port_en_US,
1275-
dummyName);
1276-
}
1277-
} else {
1268+
if (object.intent == common::Intent::Out ||
1269+
object.intent == common::Intent::InOut) {
12781270
messages.Say(
1279-
"NULL() actual argument '%s' may not be associated with allocatable %s without INTENT(IN)"_err_en_US,
1271+
"NULL() actual argument '%s' may not be associated with allocatable dummy argument %s that is INTENT(OUT) or INTENT(IN OUT)"_err_en_US,
12801272
expr->AsFortran(), dummyName);
1273+
} else if (object.intent == common::Intent::Default &&
1274+
context.ShouldWarn(common::UsageWarning::
1275+
NullActualForDefaultIntentAllocatable)) {
1276+
messages.Say(common::UsageWarning::
1277+
NullActualForDefaultIntentAllocatable,
1278+
"NULL() actual argument '%s' should not be associated with allocatable dummy argument %s without INTENT(IN)"_warn_en_US,
1279+
expr->AsFortran(), dummyName);
1280+
} else if (context.ShouldWarn(common::LanguageFeature::
1281+
NullActualForAllocatable)) {
1282+
messages.Say(
1283+
common::LanguageFeature::NullActualForAllocatable,
1284+
"Allocatable %s is associated with %s"_port_en_US,
1285+
dummyName, expr->AsFortran());
12811286
}
12821287
} else {
12831288
messages.Say(

flang/test/Semantics/call27.f90

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,26 @@
11
! RUN: %python %S/test_errors.py %s %flang_fc1 -pedantic
22
! Catch NULL() actual argument association with allocatable dummy argument
33
program test
4-
!ERROR: NULL() actual argument 'NULL()' may not be associated with allocatable dummy argument 'a=' without INTENT(IN)
4+
real, allocatable :: a
5+
!ERROR: NULL() actual argument 'NULL()' may not be associated with allocatable dummy argument dummy argument 'a=' that is INTENT(OUT) or INTENT(IN OUT)
6+
call foo0(null())
7+
!WARNING: NULL() actual argument 'NULL()' should not be associated with allocatable dummy argument dummy argument 'a=' without INTENT(IN)
58
call foo1(null())
69
!PORTABILITY: Allocatable dummy argument 'a=' is associated with NULL()
710
call foo2(null())
811
call foo3(null()) ! ok
12+
!ERROR: Actual argument associated with INTENT(IN OUT) dummy argument 'a=' is not definable
13+
!BECAUSE: 'null(mold=a)' is a null pointer
14+
call foo0(null(mold=a))
15+
!WARNING: A null pointer should not be associated with allocatable dummy argument 'a=' without INTENT(IN)
16+
call foo1(null(mold=a))
17+
!PORTABILITY: Allocatable dummy argument 'a=' is associated with a null pointer
18+
call foo2(null(mold=a))
19+
call foo3(null(mold=a)) ! ok
920
contains
21+
subroutine foo0(a)
22+
real, allocatable, intent(in out) :: a
23+
end subroutine
1024
subroutine foo1(a)
1125
real, allocatable :: a
1226
end subroutine

0 commit comments

Comments
 (0)