aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorPaul Thomas <pault@gcc.gnu.org>2010-03-03 17:49:53 +0000
committerPaul Thomas <pault@gcc.gnu.org>2010-03-03 17:49:53 +0000
commitba4619917b508b212f83883cd1b63fbb7e0e1ca6 (patch)
tree157d8e212af1fb4a1d54684eb6d052c7cb56e2eb /gcc
parenta82ec6aa3c72f6445f0f3add370d9a25d32e61df (diff)
downloadgcc-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')
-rw-r--r--gcc/fortran/ChangeLog7
-rw-r--r--gcc/fortran/trans-array.c34
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gfortran.dg/internal_pack_12.f9061
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" } }
+