The problem involves a derived type with a character component declared
CHARACTER(NULL()) or CHARACTER(NULL(n)), where mold argument n is an integer
pointer.
I might be missing something, but I'm not sure there's a point to having a
character variable whose length is the target of a null pointer. This program,
for example,
crashes with a SEGV reported at line 10 (with line 11 deleted, the program runs
to completion):
1 program z
2 implicit none
3integer, target :: k = 0
4integer, pointer :: p => k
5nullify(p)
6call s(p)
7 contains
8subroutine s(n)
9 integer, pointer :: n
10 character (len=n) q
11 q = 'a'
12end subroutine
13 end program
What to do with CHARACTER(NULL([mold])), besides fix the ICE? It might have
been possible to generate code to define a null pointer and generate code to
dereference it and get the expected SEGV, but it seemed easier and possibly
more productive to treat CHARACTER(NULL(..)) as an error. I don't know how
what the standard has to say about this. It might have been one of those
things its authors never thought about.
Since this problem is detected at different places in the code, the attached
test case gives the following errors with the attached patch:
! { dg-do compile }
! PR 67806
! 1. Initialize a variable of derived type with a string component having
!a length that is the target of the NULL intrinsic.
! 2. Declare a derived type with a string component having a length that is
!the target of the NULL intrinsic with an integer mold argument.
subroutine s1
type t
character(null()) :: c ! { dg-error "is target of NULL pointer" }
1
Error: Character length of component ācā is target of NULL pointer at (1)
end type
type(t) :: x = t('a')
end subroutine
subroutine s2
integer, pointer :: n
type t
character(null(n)) :: c ! { dg-error "is target of NULL pointer" }
1
Error: Character length is target of NULL pointer at (1)
end type
end subroutine
init_bad_string_comp_1.f90
Description: Binary data
Index: gcc/fortran/resolve.c
===
--- gcc/fortran/resolve.c (revision 228700)
+++ gcc/fortran/resolve.c (working copy)
@@ -1134,7 +1134,8 @@ resolve_structure_cons (gfc_expr *expr, int init)
t = true;
if (expr->ts.type == BT_DERIVED)
-resolve_fl_derived0 (expr->ts.u.derived);
+if (!resolve_fl_derived0 (expr->ts.u.derived))
+ return false;
cons = gfc_constructor_first (expr->value.constructor);
@@ -10882,6 +10883,13 @@ resolve_charlen (gfc_charlen *cl)
}
}
+ if (cl->length && cl->length->expr_type == EXPR_NULL)
+{
+ gfc_error ("Character length is target of NULL pointer at %L",
+>length->where);
+ return false;
+}
+
/* "If the character length parameter value evaluates to a negative
value, the length of character entities declared is zero." */
if (cl->length && !gfc_extract_int (cl->length, ) && i < 0)
@@ -13090,10 +13098,16 @@ resolve_fl_derived0 (gfc_symbol *sym)
|| (!resolve_charlen(c->ts.u.cl))
|| !gfc_is_constant_expr (c->ts.u.cl->length))
{
-gfc_error ("Character length of component %qs needs to "
- "be a constant specification expression at %L",
+gfc_error (c->ts.u.cl->length &&
+ c->ts.u.cl->length->expr_type == EXPR_NULL ?
+ "Character length of component %qs is target of "
+ "NULL pointer at %L"
+ :
+ "Character length of component %qs needs to "
+ "be a constant specification expression at %L",
c->name,
- c->ts.u.cl->length ? >ts.u.cl->length->where :
>loc);
+ c->ts.u.cl->length ?
+ >ts.u.cl->length->where : >loc);
return false;
}
}