------- Comment #11 from pault at gcc dot gnu dot org 2007-10-01 07:01 ------- (In reply to comment #10) > Yes, the initialization is occurring in the wrong place in > gfc_trans_deferred_vars. It looks to be easily fixable. I'll be onto it > tonight.
I figured out how to do it on the way to work. The patch below fixes the regression and is regtesting (slowly, under Cygwin!). The trick is to make sure that the block doing the initialization is added to the top of the function body, so that it follows all the setting of bounds and offsets. Paul Index: gcc/fortran/trans-decl.c =================================================================== *** gcc/fortran/trans-decl.c (révision 128833) --- gcc/fortran/trans-decl.c (copie de travail) *************** gfc_trans_vla_type_sizes (gfc_symbol *sy *** 2558,2563 **** --- 2558,2600 ---- } + /* Initialize INTENT(OUT) derived type dummies. */ + static tree + init_intent_out_dt (gfc_symbol * proc_sym, tree body) + { + stmtblock_t fnblock; + gfc_init_block (&fnblock); + gfc_formal_arglist *f; + gfc_expr *tmpe; + tree tmp; + tree present; + + for (f = proc_sym->formal; f; f = f->next) + { + if (f->sym && f->sym->attr.intent == INTENT_OUT + && f->sym->ts.type == BT_DERIVED + && !f->sym->ts.derived->attr.alloc_comp + && f->sym->value) + { + gcc_assert (!f->sym->attr.allocatable); + gfc_set_sym_referenced (f->sym); + tmpe = gfc_lval_expr_from_sym (f->sym); + tmp = gfc_trans_assignment (tmpe, f->sym->value, false); + + present = gfc_conv_expr_present (f->sym); + tmp = build3 (COND_EXPR, TREE_TYPE (tmp), present, + tmp, build_empty_stmt ()); + gfc_add_expr_to_block (&fnblock, tmp); + gfc_free_expr (tmpe); + } + } + + gfc_add_expr_to_block (&fnblock, body); + return gfc_finish_block (&fnblock); + } + + + /* Generate function entry and exit code, and add it to the function body. This includes: Allocation and initialization of array variables. *************** gfc_trans_deferred_vars (gfc_symbol * pr *** 2612,2617 **** --- 2649,2659 ---- && proc_sym->ts.type == BT_COMPLEX); } + /* Initialize the INTENT(OUT) derived type dummy arguments. This + should be done here so that the offsets and lbounds of arrays + are available. */ + fnbody = init_intent_out_dt (proc_sym, fnbody); + for (sym = proc_sym->tlink; sym != proc_sym; sym = sym->tlink) { bool sym_has_alloc_comp = (sym->ts.type == BT_DERIVED) *************** gfc_trans_deferred_vars (gfc_symbol * pr *** 2709,2735 **** gcc_assert (f->sym->ts.cl->backend_decl != NULL); if (TREE_CODE (f->sym->ts.cl->backend_decl) == PARM_DECL) gfc_trans_vla_type_sizes (f->sym, &body); - } - - /* If an INTENT(OUT) dummy of derived type has a default - initializer, it must be initialized here. */ - if (f->sym && f->sym->attr.intent == INTENT_OUT - && f->sym->ts.type == BT_DERIVED - && !f->sym->ts.derived->attr.alloc_comp - && f->sym->value) - { - gfc_expr *tmpe; - tree tmp, present; - gcc_assert (!f->sym->attr.allocatable); - gfc_set_sym_referenced (f->sym); - tmpe = gfc_lval_expr_from_sym (f->sym); - tmp = gfc_trans_assignment (tmpe, f->sym->value, false); - - present = gfc_conv_expr_present (f->sym); - tmp = build3 (COND_EXPR, TREE_TYPE (tmp), present, - tmp, build_empty_stmt ()); - gfc_add_expr_to_block (&body, tmp); - gfc_free_expr (tmpe); } } --- 2751,2756 ---- -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33554