if (mold == NULL)
return true;
+ if (mold->expr_type == EXPR_NULL)
+ return true;
+
if (!variable_check (mold, 0, true))
return false;
{
*msg = NULL;
- if (expr->expr_type == EXPR_NULL)
+ if (expr->expr_type == EXPR_NULL && expr->ts.type == BT_UNKNOWN)
{
*msg = "NULL() is not interoperable";
return false;
&& a->expr->ts.type != BT_ASSUMED)
gfc_find_vtab (&a->expr->ts);
+ /* Interp J3/22-146:
+ "If the context of the reference to NULL is an <actual argument>
+ corresponding to an <assumed-rank> dummy argument, MOLD shall be
+ present." */
+ if (a->expr->expr_type == EXPR_NULL
+ && a->expr->ts.type == BT_UNKNOWN
+ && f->sym->as
+ && f->sym->as->type == AS_ASSUMED_RANK)
+ {
+ gfc_error ("Intrinsic %<NULL()%> without %<MOLD%> argument at %L "
+ "passed to assumed-rank dummy %qs",
+ &a->expr->where, f->sym->name);
+ ok = false;
+ goto match;
+ }
+
+ if (a->expr->expr_type == EXPR_NULL
+ && a->expr->ts.type == BT_UNKNOWN
+ && f->sym->ts.type == BT_CHARACTER
+ && !f->sym->ts.deferred
+ && f->sym->ts.u.cl
+ && f->sym->ts.u.cl->length == NULL)
+ {
+ gfc_error ("Intrinsic %<NULL()%> without %<MOLD%> argument at %L "
+ "passed to assumed-length dummy %qs",
+ &a->expr->where, f->sym->name);
+ ok = false;
+ goto match;
+ }
+
if (a->expr->expr_type == EXPR_NULL
&& ((f->sym->ts.type != BT_CLASS && !f->sym->attr.pointer
&& (f->sym->attr.allocatable || !f->sym->attr.optional
type(t), target :: y
class(t), allocatable, target :: yac
-
+ type(t), pointer :: ypt
+
y%i = 489
allocate (yac)
yac%i = 489
j = 0
call fc()
- call fc(null())
+ call fc(null(yac))
call fc(y)
call fc(yac)
if (j /= 2) STOP 1
j = 0
- call gc(null())
+! call gc(null(yac)) ! ICE
call gc(y)
call gc(yac)
deallocate (yac)
j = 0
call ft()
- call ft(null())
+ call ft(null(yac))
call ft(y)
call ft(yac)
if (j /= 2) STOP 4
j = 0
- call gt(null())
+ call gt(null(ypt))
+! call gt(null(yac)) ! ICE
call gt(y)
call gt(yac)
deallocate (yac)
yac%i = 489
call ht(yac)
if (j /= 1) STOP 6
+ deallocate (yac)
contains
--- /dev/null
+! { dg-do compile }
+! PR fortran/104819
+!
+! Reject NULL without MOLD as actual to an assumed-rank dummy.
+! See also interpretation request at
+! https://j3-fortran.org/doc/year/22/22-101r1.txt
+!
+! Test nested NULL()
+
+program p
+ implicit none
+ integer, pointer :: a, a3(:,:,:)
+ character(10), pointer :: c
+
+ call foo (a)
+ call foo (a3)
+ call foo (null (a))
+ call foo (null (a3))
+ call foo (null (null (a))) ! Valid: nested NULL()s
+ call foo (null (null (a3))) ! Valid: nested NULL()s
+ call foo (null ()) ! { dg-error "passed to assumed-rank dummy" }
+
+ call str (null (c))
+ call str (null (null (c)))
+ call str (null ()) ! { dg-error "passed to assumed-length dummy" }
+contains
+ subroutine foo (x)
+ integer, pointer, intent(in) :: x(..)
+ print *, rank (x)
+ end
+
+ subroutine str (x)
+ character(len=*), pointer, intent(in) :: x
+ end
+end
integer(c_int64_t), pointer :: ip8
print *, c_sizeof (c_null_ptr) ! valid
print *, c_sizeof (null ()) ! { dg-error "is not interoperable" }
- print *, c_sizeof (null (ip4)) ! { dg-error "is not interoperable" }
- print *, c_sizeof (null (ip8)) ! { dg-error "is not interoperable" }
+ print *, c_sizeof (null (ip4)) ! valid
+ print *, c_sizeof (null (ip8)) ! valid
end