From: Fritz Reese Date: Mon, 25 Jun 2018 18:33:11 +0000 (+0000) Subject: Fix -finit-derived for c_ptr and c_funptr in programs which use X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=d66a58d333eadd07eeb3e86bb8fc06a4ee3158bf;p=gcc.git Fix -finit-derived for c_ptr and c_funptr in programs which use iso_c_binding. gcc/fortran/ChangeLog: 2018-06-25 Fritz Reese PR fortran/82972 PR fortran/83088 PR fortran/85851 * expr.c (component_initializer): Assign init expr to c->initializer. (generate_isocbinding_initializer): New. (gfc_generate_initializer): Call generate_isocbinding_initializer to generate initializers for c_ptr and c_funptr with -finit-derived. gcc/testsuite/ChangeLog: 2018-06-25 Fritz Reese PR fortran/82972 PR fortran/83088 PR fortran/85851 * gfortran.dg/init_flag_17.f90: New testcase. From-SVN: r262104 --- diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index a214863da8c..f052cfed2c8 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,13 @@ +2018-06-25 Fritz Reese + + PR fortran/82972 + PR fortran/83088 + PR fortran/85851 + * expr.c (component_initializer): Assign init expr to c->initializer. + (generate_isocbinding_initializer): New. + (gfc_generate_initializer): Call generate_isocbinding_initializer to + generate initializers for c_ptr and c_funptr with -finit-derived. + 2018-06-23 Jerry DeLisle PR fortran/85983 diff --git a/gcc/fortran/expr.c b/gcc/fortran/expr.c index a1336d27859..a799a497bb8 100644 --- a/gcc/fortran/expr.c +++ b/gcc/fortran/expr.c @@ -4493,7 +4493,7 @@ component_initializer (gfc_typespec *ts, gfc_component *c, bool generate) gfc_apply_init (&c->ts, &c->attr, init); } - return init; + return (c->initializer = init); } @@ -4505,6 +4505,32 @@ gfc_default_initializer (gfc_typespec *ts) return gfc_generate_initializer (ts, false); } +/* Generate an initializer expression for an iso_c_binding type + such as c_[fun]ptr. The appropriate initializer is c_null_[fun]ptr. */ + +static gfc_expr * +generate_isocbinding_initializer (gfc_symbol *derived) +{ + /* The initializers have already been built into the c_null_[fun]ptr symbols + from gen_special_c_interop_ptr. */ + gfc_symtree *npsym = NULL; + if (0 == strcmp (derived->name, "c_ptr")) + gfc_find_sym_tree ("c_null_ptr", gfc_current_ns, true, &npsym); + else if (0 == strcmp (derived->name, "c_funptr")) + gfc_find_sym_tree ("c_null_funptr", gfc_current_ns, true, &npsym); + else + gfc_internal_error ("generate_isocbinding_initializer(): bad iso_c_binding" + " type, expected % or %"); + if (npsym) + { + gfc_expr *init = gfc_copy_expr (npsym->n.sym->value); + init->symtree = npsym; + init->ts.is_iso_c = true; + return init; + } + + return NULL; +} /* Get or generate an expression for a default initializer of a derived type. If -finit-derived is specified, generate default initialization expressions @@ -4515,8 +4541,12 @@ gfc_generate_initializer (gfc_typespec *ts, bool generate) { gfc_expr *init, *tmp; gfc_component *comp; + generate = flag_init_derived && generate; + if (ts->u.derived->ts.is_iso_c && generate) + return generate_isocbinding_initializer (ts->u.derived); + /* See if we have a default initializer in this, but not in nested types (otherwise we could use gfc_has_default_initializer()). We don't need to check if we are going to generate them. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9d3d16e0b03..f2d9caffc0e 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,4 +1,9 @@ -gcc/testsuite/ChangeLog: +2018-06-25 Fritz Reese + + PR fortran/82972 + PR fortran/83088 + PR fortran/85851 + * gfortran.dg/init_flag_17.f90: New testcase. 2018-06-25 Carl Love diff --git a/gcc/testsuite/gfortran.dg/init_flag_17.f90 b/gcc/testsuite/gfortran.dg/init_flag_17.f90 new file mode 100644 index 00000000000..401830fccbc --- /dev/null +++ b/gcc/testsuite/gfortran.dg/init_flag_17.f90 @@ -0,0 +1,28 @@ +! { dg-do compile } +! { dg-options "-finit-derived -finit-local-zero -fdump-tree-original" } +! +! PR fortran/82972 +! +! Make sure we do not ICE when generating initializers for c_ptr and c_funptr +! components of derived types (and make sure they are properly initialized to +! zero). +! + +program init_flag_17 + use iso_c_binding + implicit none + + type :: ty + type(c_ptr) :: ptr ! = c_null_ptr + type(c_funptr) :: fptr ! = c_null_funptr + end type + + type(ty) :: t + + print *, t%ptr + print *, t%fptr + +end program + +! { dg-final { scan-tree-dump "\.ptr=0" "original" } } +! { dg-final { scan-tree-dump "\.fptr=0" "original" } }