diff options
author | Paul Thomas <pault@gcc.gnu.org> | 2010-03-03 17:49:53 +0000 |
---|---|---|
committer | Paul Thomas <pault@gcc.gnu.org> | 2010-03-03 17:49:53 +0000 |
commit | ba4619917b508b212f83883cd1b63fbb7e0e1ca6 (patch) | |
tree | 157d8e212af1fb4a1d54684eb6d052c7cb56e2eb /gcc/fortran/trans-array.c | |
parent | a82ec6aa3c72f6445f0f3add370d9a25d32e61df (diff) | |
download | gcc-ba4619917b508b212f83883cd1b63fbb7e0e1ca6.zip gcc-ba4619917b508b212f83883cd1b63fbb7e0e1ca6.tar.gz gcc-ba4619917b508b212f83883cd1b63fbb7e0e1ca6.tar.bz2 |
re PR fortran/43243 ([4.4 Regression ?] Wrong-code due to missing array temp for DT with pointer component)
2010-03-03 Paul Thomas <pault@gcc.gnu.org>
PR fortran/43243
* trans-array.c (gfc_conv_array_parameter): Contiguous refs to
allocatable ultimate components do not need temporaries, whilst
ultimate pointer components do.
2010-03-03 Paul Thomas <pault@gcc.gnu.org>
PR fortran/43243
* gfortran.dg/internal_pack_12.f90: New test.
From-SVN: r157199
Diffstat (limited to 'gcc/fortran/trans-array.c')
-rw-r--r-- | gcc/fortran/trans-array.c | 34 |
1 files changed, 26 insertions, 8 deletions
diff --git a/gcc/fortran/trans-array.c b/gcc/fortran/trans-array.c index c872889..8eea3ac 100644 --- a/gcc/fortran/trans-array.c +++ b/gcc/fortran/trans-array.c @@ -5474,18 +5474,30 @@ gfc_conv_array_parameter (gfc_se * se, gfc_expr * expr, gfc_ss * ss, bool g77, bool no_pack; bool array_constructor; bool good_allocatable; + bool ultimate_ptr_comp; + bool ultimate_alloc_comp; gfc_symbol *sym; stmtblock_t block; gfc_ref *ref; + ultimate_ptr_comp = false; + ultimate_alloc_comp = false; for (ref = expr->ref; ref; ref = ref->next) - if (ref->next == NULL) - break; + { + if (ref->next == NULL) + break; + + if (ref->type == REF_COMPONENT) + { + ultimate_ptr_comp = ref->u.c.component->attr.pointer; + ultimate_alloc_comp = ref->u.c.component->attr.allocatable; + } + } full_array_var = false; contiguous = false; - if (expr->expr_type == EXPR_VARIABLE && ref) + if (expr->expr_type == EXPR_VARIABLE && ref && !ultimate_ptr_comp) full_array_var = gfc_full_array_ref_p (ref, &contiguous); sym = full_array_var ? expr->symtree->n.sym : NULL; @@ -5552,6 +5564,9 @@ gfc_conv_array_parameter (gfc_se * se, gfc_expr * expr, gfc_ss * ss, bool g77, } } + /* A convenient reduction in scope. */ + contiguous = g77 && !this_array_result && contiguous; + /* There is no need to pack and unpack the array, if it is contiguous and not deferred or assumed shape. */ no_pack = ((sym && sym->as @@ -5563,17 +5578,20 @@ gfc_conv_array_parameter (gfc_se * se, gfc_expr * expr, gfc_ss * ss, bool g77, && ref->u.ar.as->type != AS_DEFERRED && ref->u.ar.as->type != AS_ASSUMED_SHAPE)); - no_pack = g77 && !this_array_result && contiguous && no_pack; + no_pack = contiguous && no_pack; /* Array constructors are always contiguous and do not need packing. */ array_constructor = g77 && !this_array_result && expr->expr_type == EXPR_ARRAY; /* Same is true of contiguous sections from allocatable variables. */ - good_allocatable = (g77 && !this_array_result && contiguous - && expr->symtree - && expr->symtree->n.sym->attr.allocatable); + good_allocatable = contiguous + && expr->symtree + && expr->symtree->n.sym->attr.allocatable; + + /* Or ultimate allocatable components. */ + ultimate_alloc_comp = contiguous && ultimate_alloc_comp; - if (no_pack || array_constructor || good_allocatable) + if (no_pack || array_constructor || good_allocatable || ultimate_alloc_comp) { gfc_conv_expr_descriptor (se, expr, ss); if (expr->ts.type == BT_CHARACTER) |