Skip to content

Commit e6abfae

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 3c3094b commit e6abfae

File tree

4 files changed

+48
-26
lines changed

4 files changed

+48
-26
lines changed

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

Lines changed: 3 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,
@@ -73,7 +73,8 @@ ENUM_CLASS(UsageWarning, Portability, PointerToUndefinable,
7373
PreviousScalarUse, RedeclaredInaccessibleComponent, ImplicitShared,
7474
IndexVarRedefinition, IncompatibleImplicitInterfaces, BadTypeForTarget,
7575
VectorSubscriptFinalization, UndefinedFunctionResult, UselessIomsg,
76-
MismatchingDummyProcedure, SubscriptedEmptyArray)
76+
MismatchingDummyProcedure, SubscriptedEmptyArray,
77+
NullActualForDefaultIntentAllocatable)
7778

7879
using LanguageFeatures = EnumSet<LanguageFeature, LanguageFeature_enumSize>;
7980
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
@@ -83,8 +83,10 @@ LanguageFeatureControl::LanguageFeatureControl() {
8383
warnUsage_.set(UsageWarning::VectorSubscriptFinalization);
8484
warnUsage_.set(UsageWarning::UndefinedFunctionResult);
8585
warnUsage_.set(UsageWarning::UselessIomsg);
86+
warnUsage_.set(UsageWarning::NullActualForDefaultIntentAllocatable);
8687
// New warnings, on by default
8788
warnLanguage_.set(LanguageFeature::SavedLocalInSpecExpr);
89+
warnLanguage_.set(LanguageFeature::NullActualForAllocatable);
8890
}
8991

9092
// 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
@@ -791,21 +791,21 @@ static void CheckExplicitDataArg(const characteristics::DummyDataObject &dummy,
791791
}
792792
} else if (actualIsNull) {
793793
if (dummyIsOptional) {
794-
} else if (dummy.intent == common::Intent::In) {
795-
// Extension (Intel, NAG, XLF): a NULL() pointer is an acceptable
796-
// actual argument for an INTENT(IN) allocatable dummy, and it
797-
// is treated as an unassociated allocatable.
798-
if (context.ShouldWarn(
799-
common::LanguageFeature::NullActualForAllocatable)) {
800-
messages.Say(common::LanguageFeature::NullActualForAllocatable,
801-
"Allocatable %s is associated with a null pointer"_port_en_US,
802-
dummyName);
803-
}
804-
} else {
794+
} else if (dummy.intent == common::Intent::Default &&
795+
context.ShouldWarn(
796+
common::UsageWarning::NullActualForDefaultIntentAllocatable)) {
805797
messages.Say(
806-
"A null pointer may not be associated with allocatable %s without INTENT(IN)"_err_en_US,
798+
"A null pointer should not be associated with allocatable %s without INTENT(IN)"_warn_en_US,
799+
dummyName);
800+
} else if (dummy.intent == common::Intent::In &&
801+
context.ShouldWarn(
802+
common::LanguageFeature::NullActualForAllocatable)) {
803+
messages.Say(common::LanguageFeature::NullActualForAllocatable,
804+
"Allocatable %s is associated with a null pointer"_port_en_US,
807805
dummyName);
808806
}
807+
// INTENT(OUT) and INTENT(IN OUT) cases are caught elsewhere as being
808+
// undefinable actual arguments.
809809
} else {
810810
messages.Say(
811811
"ALLOCATABLE %s must be associated with an ALLOCATABLE actual argument"_err_en_US,
@@ -1290,19 +1290,24 @@ static void CheckExplicitInterfaceArg(evaluate::ActualArgument &arg,
12901290
} else if (object.attrs.test(characteristics::DummyDataObject::
12911291
Attr::Allocatable) &&
12921292
evaluate::IsNullPointer(*expr)) {
1293-
if (object.intent == common::Intent::In) {
1294-
// Extension (Intel, NAG, XLF); see CheckExplicitDataArg.
1295-
if (context.ShouldWarn(common::LanguageFeature::
1296-
NullActualForAllocatable)) {
1297-
messages.Say(
1298-
common::LanguageFeature::NullActualForAllocatable,
1299-
"Allocatable %s is associated with NULL()"_port_en_US,
1300-
dummyName);
1301-
}
1302-
} else {
1293+
if (object.intent == common::Intent::Out ||
1294+
object.intent == common::Intent::InOut) {
13031295
messages.Say(
1304-
"NULL() actual argument '%s' may not be associated with allocatable %s without INTENT(IN)"_err_en_US,
1296+
"NULL() actual argument '%s' may not be associated with allocatable dummy argument %s that is INTENT(OUT) or INTENT(IN OUT)"_err_en_US,
13051297
expr->AsFortran(), dummyName);
1298+
} else if (object.intent == common::Intent::Default &&
1299+
context.ShouldWarn(common::UsageWarning::
1300+
NullActualForDefaultIntentAllocatable)) {
1301+
messages.Say(common::UsageWarning::
1302+
NullActualForDefaultIntentAllocatable,
1303+
"NULL() actual argument '%s' should not be associated with allocatable dummy argument %s without INTENT(IN)"_warn_en_US,
1304+
expr->AsFortran(), dummyName);
1305+
} else if (context.ShouldWarn(common::LanguageFeature::
1306+
NullActualForAllocatable)) {
1307+
messages.Say(
1308+
common::LanguageFeature::NullActualForAllocatable,
1309+
"Allocatable %s is associated with %s"_port_en_US,
1310+
dummyName, expr->AsFortran());
13061311
}
13071312
} else {
13081313
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)