https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88611
--- Comment #7 from Richard Biener <rguenth at gcc dot gnu.org> --- (In reply to Thomas Koenig from comment #6) > (In reply to Jakub Jelinek from comment #5) > > But given that the right type we want is already passed in type, I'd say: > > --- gcc/trans-expr.c.jj 2019-01-01 12:37:52.000000000 +0100 > > +++ gcc/trans-expr.c 2019-01-07 14:41:02.146885618 +0100 > > @@ -7085,21 +7085,7 @@ gfc_conv_initializer (gfc_expr * expr, g > > the 'expr' to be that for a (void *). */ > > if (expr != NULL && expr->ts.type == BT_DERIVED > > && expr->ts.is_iso_c && expr->ts.u.derived) > > - { > > - gfc_symbol *derived = expr->ts.u.derived; > > - > > - /* The derived symbol has already been converted to a (void *). Use > > - its kind. */ > > - if (derived->ts.kind == 0) > > - derived->ts.kind = gfc_default_integer_kind; > > - expr = gfc_get_int_expr (derived->ts.kind, NULL, 0); > > - expr->ts.f90_type = derived->ts.f90_type; > > - > > - gfc_init_se (&se, NULL); > > - gfc_conv_constant (&se, expr); > > - gcc_assert (TREE_CODE (se.expr) != CONSTRUCTOR); > > - return se.expr; > > - } > > + return build_int_cst (type, 0); > > > > if (array && !procptr) > > { > > is best. > > I regression-tested this, without issues. > > Pre-approved for trunk (or obvious and simple). So unfortunately it doesn't work but ICEs FAIL: gfortran.dg/c_loc_tests_12.f03 -O (internal compiler error) FAIL: gfortran.dg/c_loc_tests_12.f03 -O (test for excess errors) FAIL: gfortran.dg/c_loc_tests_6.f03 -O (internal compiler error) FAIL: gfortran.dg/c_loc_tests_6.f03 -O (test for excess errors) FAIL: gfortran.dg/c_loc_tests_7.f03 -O (internal compiler error) FAIL: gfortran.dg/c_loc_tests_7.f03 -O (test for excess errors) FAIL: gfortran.dg/c_loc_tests_8.f03 -O (internal compiler error) FAIL: gfortran.dg/c_loc_tests_8.f03 -O (test for excess errors) where for example for c_loc_tests_12.f03 we end up with type being an ARRAY_TYPE: (gdb) p debug_tree (type) <array_type 0x7ffff6a45738 type <pointer_type 0x7ffff6896000 type <void_type 0x7ffff688ff18 void VOID align:8 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type 0x7ffff688ff18 pointer_to_this <pointer_type 0x7ffff6896000>> public unsigned DI size <integer_cst 0x7ffff687ab70 constant 64> unit-size <integer_cst 0x7ffff687ab88 constant 8> align:64 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type 0x7ffff6896000 pointer_to_this <pointer_type 0x7ffff689b738> reference_to_this ... (gdb) p expr->ts.u.derived->ts.f90_type $5 = BT_VOID I wonder if in this case we want to return an empty CONSTRUCTOR instead? Can c_null_ptr appear in a struct initialization as well, literally as it seems to be the case for arrays? type(c_ptr), dimension(1), target :: argv = c_null_ptr Thus, amended patch which passes the affected testcases: diff --git a/gcc/fortran/trans-expr.c b/gcc/fortran/trans-expr.c index 27eb2d2ee38..c45752e516a 100644 --- a/gcc/fortran/trans-expr.c +++ b/gcc/fortran/trans-expr.c @@ -7086,19 +7086,12 @@ gfc_conv_initializer (gfc_expr * expr, gfc_typespec * ts, tree type, if (expr != NULL && expr->ts.type == BT_DERIVED && expr->ts.is_iso_c && expr->ts.u.derived) { - gfc_symbol *derived = expr->ts.u.derived; - - /* The derived symbol has already been converted to a (void *). Use - its kind. */ - if (derived->ts.kind == 0) - derived->ts.kind = gfc_default_integer_kind; - expr = gfc_get_int_expr (derived->ts.kind, NULL, 0); - expr->ts.f90_type = derived->ts.f90_type; - - gfc_init_se (&se, NULL); - gfc_conv_constant (&se, expr); - gcc_assert (TREE_CODE (se.expr) != CONSTRUCTOR); - return se.expr; + if (TREE_CODE (type) == ARRAY_TYPE) + return build_constructor (type, NULL); + else if (POINTER_TYPE_P (type)) + return build_int_cst (type, 0); + else + gcc_unreachable (); } if (array && !procptr)