diff options
author | Paul Thomas <pault@gcc.gnu.org> | 2008-04-19 21:55:24 +0000 |
---|---|---|
committer | Paul Thomas <pault@gcc.gnu.org> | 2008-04-19 21:55:24 +0000 |
commit | f40eccb026f46cb33f5f1b7751b0c3b452881a0b (patch) | |
tree | 497527fc5bf28773356dc116b6c7ffad50bcf3c2 /gcc/fortran | |
parent | 476924c9e097b4d5f0179c2835bb34d288f92561 (diff) | |
download | gcc-f40eccb026f46cb33f5f1b7751b0c3b452881a0b.zip gcc-f40eccb026f46cb33f5f1b7751b0c3b452881a0b.tar.gz gcc-f40eccb026f46cb33f5f1b7751b0c3b452881a0b.tar.bz2 |
re PR target/35944 (wrong result for MOD with kind=10 for some array argument values)
2008-04-19 Paul Thomas <pault@gcc.gnu.org>
PR fortran/35944
PR fortran/35946
PR fortran/35947
* trans_array.c (gfc_trans_array_constructor): Temporarily
realign loop, if loop->from is not zero, before creating
the temporary array and provide an offset.
PR fortran/35959
* trans-decl.c (gfc_init_default_dt): Add gfc_ prefix to name
and allow for NULL body. Change all references from
init_default_dt to gfc_init_default_dt.
* trans.h : Add prototype for gfc_init_default_dt.
* trans-array.c (gfc_trans_deferred_vars): After nullification
call gfc_init_default_dt for derived types with allocatable
components.
2008-04-19 Paul Thomas <pault@gcc.gnu.org>
PR fortran/35944
PR fortran/35946
PR fortran/35947
* gfortran.dg/array_constructor_23.f: New test.
PR fortran/35959
* gfortran.dg/alloc_comp_default_init_2.f90: New test.
* gfortran.dg/alloc_comp_basics_1.f90: Change occurrences of
"builtin_free" to 27.
* gfortran.dg/alloc_comp_constructor_1.f90: Change occurrences
of "builtin_free" to 21.
From-SVN: r134472
Diffstat (limited to 'gcc/fortran')
-rw-r--r-- | gcc/fortran/ChangeLog | 18 | ||||
-rw-r--r-- | gcc/fortran/trans-array.c | 31 | ||||
-rw-r--r-- | gcc/fortran/trans-decl.c | 16 | ||||
-rw-r--r-- | gcc/fortran/trans.h | 3 |
4 files changed, 59 insertions, 9 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 763e2f2..abcc336 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,21 @@ +2008-04-19 Paul Thomas <pault@gcc.gnu.org> + + PR fortran/35944 + PR fortran/35946 + PR fortran/35947 + * trans_array.c (gfc_trans_array_constructor): Temporarily + realign loop, if loop->from is not zero, before creating + the temporary array and provide an offset. + + PR fortran/35959 + * trans-decl.c (gfc_init_default_dt): Add gfc_ prefix to name + and allow for NULL body. Change all references from + init_default_dt to gfc_init_default_dt. + * trans.h : Add prototype for gfc_init_default_dt. + * trans-array.c (gfc_trans_deferred_vars): After nullification + call gfc_init_default_dt for derived types with allocatable + components. + 2008-04-18 Jerry DeLisle <jvdelisle@gcc.gnu.org> PR fortran/35892 diff --git a/gcc/fortran/trans-array.c b/gcc/fortran/trans-array.c index 3de1fb71..7bac68d 100644 --- a/gcc/fortran/trans-array.c +++ b/gcc/fortran/trans-array.c @@ -1679,6 +1679,7 @@ gfc_trans_array_constructor (gfc_loopinfo * loop, gfc_ss * ss) tree offsetvar; tree desc; tree type; + tree loopfrom; bool dynamic; if (flag_bounds_check && ss->expr->ts.type == BT_CHARACTER) @@ -1757,9 +1758,34 @@ gfc_trans_array_constructor (gfc_loopinfo * loop, gfc_ss * ss) } } + /* Temporarily reset the loop variables, so that the returned temporary + has the right size and bounds. This seems only to be necessary for + 1D arrays. */ + if (!integer_zerop (loop->from[0]) && loop->dimen == 1) + { + loopfrom = loop->from[0]; + loop->from[0] = gfc_index_zero_node; + loop->to[0] = fold_build2 (MINUS_EXPR, gfc_array_index_type, + loop->to[0], loopfrom); + } + else + loopfrom = NULL_TREE; + gfc_trans_create_temp_array (&loop->pre, &loop->post, loop, &ss->data.info, type, dynamic, true, false); + if (loopfrom != NULL_TREE) + { + loop->from[0] = loopfrom; + loop->to[0] = fold_build2 (PLUS_EXPR, gfc_array_index_type, + loop->to[0], loopfrom); + /* In the case of a non-zero from, the temporary needs an offset + so that subsequent indexing is correct. */ + ss->data.info.offset = fold_build1 (NEGATE_EXPR, + gfc_array_index_type, + loop->from[0]); + } + desc = ss->data.info.descriptor; offset = gfc_index_zero_node; offsetvar = gfc_create_var_np (gfc_array_index_type, "offset"); @@ -5569,6 +5595,11 @@ gfc_trans_deferred_array (gfc_symbol * sym, tree body) rank = sym->as ? sym->as->rank : 0; tmp = gfc_nullify_alloc_comp (sym->ts.derived, descriptor, rank); gfc_add_expr_to_block (&fnblock, tmp); + if (sym->value) + { + tmp = gfc_init_default_dt (sym, NULL); + gfc_add_expr_to_block (&fnblock, tmp); + } } } else if (!GFC_DESCRIPTOR_TYPE_P (type)) diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c index 6f430cb..e693f72 100644 --- a/gcc/fortran/trans-decl.c +++ b/gcc/fortran/trans-decl.c @@ -512,9 +512,6 @@ gfc_finish_var_decl (tree decl, gfc_symbol * sym) SAVE_EXPLICIT. */ if (!sym->attr.use_assoc && (sym->attr.save != SAVE_NONE || sym->attr.data - || (sym->ts.type == BT_DERIVED - && sym->ts.derived->attr.alloc_comp - && sym->value) || (sym->value && sym->ns->proc_name->attr.is_main_program))) TREE_STATIC (decl) = 1; @@ -2532,8 +2529,8 @@ gfc_trans_vla_type_sizes (gfc_symbol *sym, stmtblock_t *body) /* Initialize a derived type by building an lvalue from the symbol and using trans_assignment to do the work. */ -static tree -init_default_dt (gfc_symbol * sym, tree body) +tree +gfc_init_default_dt (gfc_symbol * sym, tree body) { stmtblock_t fnblock; gfc_expr *e; @@ -2553,7 +2550,8 @@ init_default_dt (gfc_symbol * sym, tree body) } gfc_add_expr_to_block (&fnblock, tmp); gfc_free_expr (e); - gfc_add_expr_to_block (&fnblock, body); + if (body) + gfc_add_expr_to_block (&fnblock, body); return gfc_finish_block (&fnblock); } @@ -2571,7 +2569,7 @@ init_intent_out_dt (gfc_symbol * proc_sym, tree body) && f->sym->ts.type == BT_DERIVED && !f->sym->ts.derived->attr.alloc_comp && f->sym->value) - body = init_default_dt (f->sym, body); + body = gfc_init_default_dt (f->sym, body); gfc_add_expr_to_block (&fnblock, body); return gfc_finish_block (&fnblock); @@ -2672,7 +2670,7 @@ gfc_trans_deferred_vars (gfc_symbol * proc_sym, tree fnbody) && sym->value && !sym->attr.data && sym->attr.save == SAVE_NONE) - fnbody = init_default_dt (sym, fnbody); + fnbody = gfc_init_default_dt (sym, fnbody); gfc_get_backend_locus (&loc); gfc_set_backend_locus (&sym->declared_at); @@ -2732,7 +2730,7 @@ gfc_trans_deferred_vars (gfc_symbol * proc_sym, tree fnbody) && sym->value && !sym->attr.data && sym->attr.save == SAVE_NONE) - fnbody = init_default_dt (sym, fnbody); + fnbody = gfc_init_default_dt (sym, fnbody); else gcc_unreachable (); } diff --git a/gcc/fortran/trans.h b/gcc/fortran/trans.h index 4134336..1dfb0a5 100644 --- a/gcc/fortran/trans.h +++ b/gcc/fortran/trans.h @@ -405,6 +405,9 @@ tree gfc_get_symbol_decl (gfc_symbol *); /* Build a static initializer. */ tree gfc_conv_initializer (gfc_expr *, gfc_typespec *, tree, bool, bool); +/* Assign a default initializer to a derived type. */ +tree gfc_init_default_dt (gfc_symbol *, tree); + /* Substitute a temporary variable in place of the real one. */ void gfc_shadow_sym (gfc_symbol *, tree, gfc_saved_var *); |