Created attachment 29058 [details] Failing test case Another test case by Reinhold Bader. type :: t_ptr class(interior), pointer :: r(:) => null() end type t_ptr ... type(interior), target :: r(3) type(t_ptr) :: o1 ... o1 = t_ptr(r) Gives: o1 = t_ptr(r) ! fine, r has TARGET attribute and can't go away 1 Error: The rank of the element in the structure constructor at (1) does not match that of the component (1/0)
Reduced test case: program construct_poly implicit none type :: interior real :: x end type interior type :: t_ptr class(interior), pointer :: r(:) => null() end type t_ptr type(t_ptr) :: o1 type(interior), target :: r(3) o1 = t_ptr(r) end program This gives me: test.f90:16.13: o1 = t_ptr(r) 1 Error: The rank of the element in the structure constructor at (1) does not match that of the component (1/0) test.f90:16.13: o1 = t_ptr(r) 1 Error: Can't convert TYPE(interior) to CLASS(interior) at (1) For the original test case, I get some more of these errors (on line 38, 52 and 63).
Draft patch: Index: gcc/fortran/resolve.c =================================================================== --- gcc/fortran/resolve.c (revision 194743) +++ gcc/fortran/resolve.c (working copy) @@ -1089,7 +1089,10 @@ resolve_structure_cons (gfc_expr *expr, int init) continue; } - rank = comp->as ? comp->as->rank : 0; + if (comp->ts.type == BT_CLASS) + rank = CLASS_DATA (comp)->as ? CLASS_DATA (comp)->as->rank : 0; + else + rank = comp->as ? comp->as->rank : 0; if (cons->expr->expr_type != EXPR_NULL && rank != cons->expr->rank && (comp->attr.allocatable || cons->expr->rank)) { This gets me past the first error in comment 1, but does not fix the second one.
The second error is fixed by the following: Index: gcc/fortran/intrinsic.c =================================================================== --- gcc/fortran/intrinsic.c (revision 194743) +++ gcc/fortran/intrinsic.c (working copy) @@ -4287,8 +4287,9 @@ gfc_convert_type_warn (gfc_expr *expr, gfc_typespe if (expr->ts.type == BT_UNKNOWN) goto bad; - if (expr->ts.type == BT_DERIVED && ts->type == BT_DERIVED - && gfc_compare_types (&expr->ts, ts)) + if (expr->ts.type == BT_DERIVED + && (ts->type == BT_DERIVED || ts->type == BT_CLASS) + && gfc_compare_types (ts, &expr->ts)) return SUCCESS; sym = find_conv (&expr->ts, ts);
After getting past the error messages with the patches in comment 2 and 3, the test case segfaults with the following backtrace: internal compiler error: Segmentation fault o1 = t_ptr(r) ^ 0xb0a58d crash_signal /home/jweil/gcc48/trunk/gcc/toplev.c:334 0x63466e gfc_conv_scalarized_array_ref /home/jweil/gcc48/trunk/gcc/fortran/trans-array.c:3042 0x634cd6 gfc_conv_array_ref(gfc_se*, gfc_array_ref*, gfc_symbol*, locus*) /home/jweil/gcc48/trunk/gcc/fortran/trans-array.c:3168 0x661b9b gfc_conv_variable /home/jweil/gcc48/trunk/gcc/fortran/trans-expr.c:1795
There are problems with handling CLASS components in gfc_trans_subcomponent_assign: Index: gcc/fortran/trans-expr.c =================================================================== --- gcc/fortran/trans-expr.c (revision 194743) +++ gcc/fortran/trans-expr.c (working copy) @@ -5934,11 +5934,14 @@ gfc_trans_subcomponent_assign (tree dest, gfc_comp gfc_start_block (&block); - if (cm->attr.pointer || cm->attr.proc_pointer) + if (cm->attr.pointer || cm->attr.proc_pointer + || (cm->ts.type == BT_CLASS && CLASS_DATA (cm)->attr.pointer)) { gfc_init_se (&se, NULL); /* Pointer component. */ - if (cm->attr.dimension && !cm->attr.proc_pointer) + if ((cm->attr.dimension + || (cm->ts.type == BT_CLASS && CLASS_DATA (cm)->attr.dimension)) + && !cm->attr.proc_pointer) { /* Array pointer. */ if (expr->expr_type == EXPR_NULL) However, this is not enough. The test case still gives an ICE.