// ok
} else if (object.type.type().IsTypelessIntrinsicArgument() &&
evaluate::IsNullObjectPointer(*expr)) {
- // ok, ASSOCIATED(NULL())
+ // ok, ASSOCIATED(NULL(without MOLD=))
} else if ((object.attrs.test(characteristics::DummyDataObject::
Attr::Pointer) ||
object.attrs.test(characteristics::
DummyDataObject::Attr::Optional)) &&
evaluate::IsNullObjectPointer(*expr)) {
- // ok, FOO(NULL())
+ // FOO(NULL(without MOLD=))
+ if (object.type.type().IsAssumedLengthCharacter()) {
+ messages.Say(
+ "Actual argument associated with %s is a NULL() pointer without a MOLD= to provide a character length"_err_en_US,
+ dummyName);
+ } else if (const DerivedTypeSpec *
+ derived{GetDerivedTypeSpec(object.type.type())}) {
+ for (const auto &[pName, pValue] : derived->parameters()) {
+ if (pValue.isAssumed()) {
+ messages.Say(
+ "Actual argument associated with %s is a NULL() pointer without a MOLD= to provide a value for the assumed type parameter '%s'"_err_en_US,
+ dummyName, pName.ToString());
+ break;
+ }
+ }
+ }
} else if (object.attrs.test(characteristics::DummyDataObject::
Attr::Allocatable) &&
evaluate::IsNullPointer(*expr)) {
if (null(lp)) then
end if
end subroutine test
+
+module m
+ type :: pdt(n)
+ integer, len :: n
+ end type
+ contains
+ subroutine s1(x)
+ character(*), pointer, intent(in) :: x
+ end
+ subroutine s2(x)
+ type(pdt(*)), pointer, intent(in) :: x
+ end
+ subroutine test
+ !ERROR: Actual argument associated with dummy argument 'x=' is a NULL() pointer without a MOLD= to provide a character length
+ call s1(null())
+ !ERROR: Actual argument associated with dummy argument 'x=' is a NULL() pointer without a MOLD= to provide a value for the assumed type parameter 'n'
+ call s2(null())
+ end
+end