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)