@@ -661,17 +661,34 @@ static void CheckExplicitDataArg(const characteristics::DummyDataObject &dummy,
661
661
dummy.attrs .test (characteristics::DummyDataObject::Attr::Optional)};
662
662
bool actualIsNull{evaluate::IsNullPointer (actual)};
663
663
if (dummyIsAllocatable) {
664
- if (!actualIsAllocatable && !(actualIsNull && dummyIsOptional)) {
664
+ if (actualIsAllocatable) {
665
+ if (actualIsCoindexed && dummy.intent != common::Intent::In) {
666
+ messages.Say (
667
+ " ALLOCATABLE %s must have INTENT(IN) to be associated with a coindexed actual argument" _err_en_US,
668
+ dummyName);
669
+ }
670
+ } else if (actualIsNull) {
671
+ if (dummyIsOptional) {
672
+ } else if (dummy.intent == common::Intent::In) {
673
+ // Extension (Intel, NAG, XLF): a NULL() pointer is an acceptable
674
+ // actual argument for an INTENT(IN) allocatable dummy, and it
675
+ // is treated as an unassociated allocatable.
676
+ if (context.languageFeatures ().ShouldWarn (
677
+ common::LanguageFeature::NullActualForAllocatable)) {
678
+ messages.Say (
679
+ " Allocatable %s is associated with a null pointer" _port_en_US,
680
+ dummyName);
681
+ }
682
+ } else {
683
+ messages.Say (
684
+ " A null pointer may not be associated with allocatable %s without INTENT(IN)" _err_en_US,
685
+ dummyName);
686
+ }
687
+ } else {
665
688
messages.Say (
666
689
" ALLOCATABLE %s must be associated with an ALLOCATABLE actual argument" _err_en_US,
667
690
dummyName);
668
691
}
669
- if (actualIsAllocatable && actualIsCoindexed &&
670
- dummy.intent != common::Intent::In) {
671
- messages.Say (
672
- " ALLOCATABLE %s must have INTENT(IN) to be associated with a coindexed actual argument" _err_en_US,
673
- dummyName);
674
- }
675
692
if (!actualIsCoindexed && actualLastSymbol &&
676
693
actualLastSymbol->Corank () != dummy.type .corank ()) {
677
694
messages.Say (
@@ -791,7 +808,8 @@ static void CheckExplicitDataArg(const characteristics::DummyDataObject &dummy,
791
808
}
792
809
793
810
// NULL(MOLD=) checking for non-intrinsic procedures
794
- if (!intrinsic && !dummyIsPointer && !dummyIsOptional && actualIsNull) {
811
+ if (!intrinsic && !dummyIsAllocatableOrPointer && !dummyIsOptional &&
812
+ actualIsNull) {
795
813
messages.Say (
796
814
" Actual argument associated with %s may not be null pointer %s" _err_en_US,
797
815
dummyName, actual.AsFortran ());
@@ -1083,12 +1101,19 @@ static void CheckExplicitInterfaceArg(evaluate::ActualArgument &arg,
1083
1101
} else if (object.attrs .test (characteristics::DummyDataObject::
1084
1102
Attr::Allocatable) &&
1085
1103
evaluate::IsNullPointer (*expr)) {
1086
- // Unsupported extension that more or less naturally falls
1087
- // out of other Fortran implementations that pass separate
1088
- // base address and descriptor address physical arguments
1089
- messages.Say (
1090
- " Null actual argument '%s' may not be associated with allocatable %s" _err_en_US,
1091
- expr->AsFortran (), dummyName);
1104
+ if (object.intent == common::Intent::In) {
1105
+ // Extension (Intel, NAG, XLF); see CheckExplicitDataArg.
1106
+ if (context.languageFeatures ().ShouldWarn (common::
1107
+ LanguageFeature::NullActualForAllocatable)) {
1108
+ messages.Say (
1109
+ " Allocatable %s is associated with NULL()" _port_en_US,
1110
+ dummyName);
1111
+ }
1112
+ } else {
1113
+ messages.Say (
1114
+ " NULL() actual argument '%s' may not be associated with allocatable %s without INTENT(IN)" _err_en_US,
1115
+ expr->AsFortran (), dummyName);
1116
+ }
1092
1117
} else {
1093
1118
messages.Say (
1094
1119
" Actual argument '%s' associated with %s is not a variable or typed expression" _err_en_US,
0 commit comments