diff options
author | Fritz Reese <fritzoreese@gmail.com> | 2018-06-25 18:33:11 +0000 |
---|---|---|
committer | Fritz Reese <foreese@gcc.gnu.org> | 2018-06-25 18:33:11 +0000 |
commit | d66a58d333eadd07eeb3e86bb8fc06a4ee3158bf (patch) | |
tree | a9ceb2d95c61470764b8b3df11ffc22f6d358567 /gcc/fortran/expr.c | |
parent | 21925ac173495dad58a5ed0293ceb0203f849a51 (diff) | |
download | gcc-d66a58d333eadd07eeb3e86bb8fc06a4ee3158bf.zip gcc-d66a58d333eadd07eeb3e86bb8fc06a4ee3158bf.tar.gz gcc-d66a58d333eadd07eeb3e86bb8fc06a4ee3158bf.tar.bz2 |
Fix -finit-derived for c_ptr and c_funptr in programs which use
iso_c_binding.
gcc/fortran/ChangeLog:
2018-06-25 Fritz Reese <fritzoreese@gmail.com>
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 <fritzoreese@gmail.com>
PR fortran/82972
PR fortran/83088
PR fortran/85851
* gfortran.dg/init_flag_17.f90: New testcase.
From-SVN: r262104
Diffstat (limited to 'gcc/fortran/expr.c')
-rw-r--r-- | gcc/fortran/expr.c | 32 |
1 files changed, 31 insertions, 1 deletions
diff --git a/gcc/fortran/expr.c b/gcc/fortran/expr.c index a1336d2..a799a49 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 %<c_ptr%> or %<c_funptr%>"); + 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. */ |