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 | |
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
-rw-r--r-- | gcc/fortran/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/fortran/trans-array.c | 34 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gfortran.dg/internal_pack_12.f90 | 61 |
4 files changed, 99 insertions, 8 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 01f2f3c..a0eaa3a 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,10 @@ +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 Janus Weil <janus@gcc.gnu.org> PR fortran/43169 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) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index cf5b1d6..ba742fd 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2010-03-03 Paul Thomas <pault@gcc.gnu.org> + + PR fortran/43243 + * gfortran.dg/internal_pack_12.f90: New test. + 2010-03-03 H.J. Lu <hongjiu.lu@intel.com> * gcc.dg/pr36997.c: Adjust error message. diff --git a/gcc/testsuite/gfortran.dg/internal_pack_12.f90 b/gcc/testsuite/gfortran.dg/internal_pack_12.f90 new file mode 100644 index 0000000..32bacfa --- /dev/null +++ b/gcc/testsuite/gfortran.dg/internal_pack_12.f90 @@ -0,0 +1,61 @@ +! { dg-do compile } +! { dg-options "-fdump-tree-original" } +! +! Test the fix for PR43243, where unnecessary calls to internal_pack/unpack +! were being produced below. These references are contiguous and so do not +! need a temporary. In addition, the final call to 'bar' required a pack/unpack +! which had been missing since r156680, at least. +! +! Contributed Tobias Burnus <burnus@gcc.gnu.org> +! +module m + type t + integer, allocatable :: a(:) + integer, pointer :: b(:) + integer :: c(5) + end type t +end module m + +subroutine foo(a,d,e,n) + use m + implicit none + integer :: n + type(t) :: a + type(t), allocatable :: d(:) + type(t), pointer :: e(:) + call bar( a%a) ! OK - no array temp needed + call bar( a%c) ! OK - no array temp needed + + call bar( a%a(1:n)) ! Missed: No pack needed + call bar( a%b(1:n)) ! OK: pack needed + call bar( a%c(1:n)) ! Missed: No pack needed + + call bar(d(1)%a(1:n)) ! Missed: No pack needed + call bar(d(1)%b(1:n)) ! OK: pack needed + call bar(d(1)%c(1:n)) ! Missed: No pack needed + + call bar(e(1)%a(1:n)) ! Missed: No pack needed + call bar(e(1)%b(1:n)) ! OK: pack needed + call bar(e(1)%c(1:n)) ! Missed: No pack needed +end subroutine foo + +use m +implicit none +integer :: i +integer, target :: z(6) +type(t) :: y + +z = [(i, i=1,6)] +y%b => z(::2) +call bar(y%b) ! Missed: Pack needed +end + +subroutine bar(x) + integer :: x(1:*) + print *, x(1:3) + if (any (x(1:3) /= [1,3,5])) call abort () +end subroutine bar +! { dg-final { scan-tree-dump-times "unpack" 4 "original" } } +! { dg-final { cleanup-tree-dump "original" } } +! { dg-final { cleanup-modules "m" } } + |