@@ -661,17 +661,34 @@ static void CheckExplicitDataArg(const characteristics::DummyDataObject &dummy,
661661 dummy.attrs .test (characteristics::DummyDataObject::Attr::Optional)};
662662 bool actualIsNull{evaluate::IsNullPointer (actual)};
663663 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 {
665688 messages.Say (
666689 " ALLOCATABLE %s must be associated with an ALLOCATABLE actual argument" _err_en_US,
667690 dummyName);
668691 }
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- }
675692 if (!actualIsCoindexed && actualLastSymbol &&
676693 actualLastSymbol->Corank () != dummy.type .corank ()) {
677694 messages.Say (
@@ -791,7 +808,8 @@ static void CheckExplicitDataArg(const characteristics::DummyDataObject &dummy,
791808 }
792809
793810 // NULL(MOLD=) checking for non-intrinsic procedures
794- if (!intrinsic && !dummyIsPointer && !dummyIsOptional && actualIsNull) {
811+ if (!intrinsic && !dummyIsAllocatableOrPointer && !dummyIsOptional &&
812+ actualIsNull) {
795813 messages.Say (
796814 " Actual argument associated with %s may not be null pointer %s" _err_en_US,
797815 dummyName, actual.AsFortran ());
@@ -1083,12 +1101,19 @@ static void CheckExplicitInterfaceArg(evaluate::ActualArgument &arg,
10831101 } else if (object.attrs .test (characteristics::DummyDataObject::
10841102 Attr::Allocatable) &&
10851103 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+ }
10921117 } else {
10931118 messages.Say (
10941119 " Actual argument '%s' associated with %s is not a variable or typed expression" _err_en_US,
0 commit comments