summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>2005-09-08 16:06:54 +0000
committerrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>2005-09-08 16:06:54 +0000
commit598d8efb2d9a6faeea32d2dee4679fb6e4bbd39e (patch)
tree11a35e0bc52376bedc27a635471ad8c8e20cb028
parentce1d5a679a06ee770c016befcb6324ed685e121a (diff)
downloadgcc-598d8efb2d9a6faeea32d2dee4679fb6e4bbd39e.tar.gz
PR fortran/19928
* trans-array.c (gfc_conv_array_ref): Call gfc_advance_se_ss_chain after handling scalarized references. Make "indexse" inherit from "se" when handling AR_ELEMENTs. (gfc_walk_variable_expr): Add GFC_SS_SCALAR entries for each substring or scalar reference that follows an array section. * trans-expr.c (gfc_conv_variable): When called from within a scalarization loop, start out with "ref" pointing to the scalarized part of the reference. Don't call gfc_advance_se_ss_chain here. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@104035 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/fortran/ChangeLog12
-rw-r--r--gcc/fortran/trans-array.c39
-rw-r--r--gcc/fortran/trans-expr.c6
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gfortran.dg/pr19928-1.f9011
-rw-r--r--gcc/testsuite/gfortran.dg/pr19928-2.f9023
6 files changed, 87 insertions, 9 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index e2afd7c55f0..e8e64addba8 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,15 @@
+2005-09-08 Richard Sandiford <richard@codesourcery.com>
+
+ PR fortran/19928
+ * trans-array.c (gfc_conv_array_ref): Call gfc_advance_se_ss_chain
+ after handling scalarized references. Make "indexse" inherit from
+ "se" when handling AR_ELEMENTs.
+ (gfc_walk_variable_expr): Add GFC_SS_SCALAR entries for each
+ substring or scalar reference that follows an array section.
+ * trans-expr.c (gfc_conv_variable): When called from within a
+ scalarization loop, start out with "ref" pointing to the scalarized
+ part of the reference. Don't call gfc_advance_se_ss_chain here.
+
2005-09-07 Richard Sandiford <richard@codesourcery.com>
PR fortran/23373
diff --git a/gcc/fortran/trans-array.c b/gcc/fortran/trans-array.c
index 3e7b8691dd4..9012a0756a8 100644
--- a/gcc/fortran/trans-array.c
+++ b/gcc/fortran/trans-array.c
@@ -1660,6 +1660,7 @@ gfc_conv_array_ref (gfc_se * se, gfc_array_ref * ar)
if (ar->type != AR_ELEMENT)
{
gfc_conv_scalarized_array_ref (se, ar);
+ gfc_advance_se_ss_chain (se);
return;
}
@@ -1671,7 +1672,7 @@ gfc_conv_array_ref (gfc_se * se, gfc_array_ref * ar)
for (n = 0; n < ar->dimen; n++)
{
/* Calculate the index for this dimension. */
- gfc_init_se (&indexse, NULL);
+ gfc_init_se (&indexse, se);
gfc_conv_expr_type (&indexse, ar->start[n], gfc_array_index_type);
gfc_add_block_to_block (&se->pre, &indexse.pre);
@@ -4082,8 +4083,27 @@ gfc_walk_variable_expr (gfc_ss * ss, gfc_expr * expr)
int n;
for (ref = expr->ref; ref; ref = ref->next)
+ if (ref->type == REF_ARRAY && ref->u.ar.type != AR_ELEMENT)
+ break;
+
+ for (; ref; ref = ref->next)
{
- /* We're only interested in array sections. */
+ if (ref->type == REF_SUBSTRING)
+ {
+ newss = gfc_get_ss ();
+ newss->type = GFC_SS_SCALAR;
+ newss->expr = ref->u.ss.start;
+ newss->next = ss;
+ ss = newss;
+
+ newss = gfc_get_ss ();
+ newss->type = GFC_SS_SCALAR;
+ newss->expr = ref->u.ss.end;
+ newss->next = ss;
+ ss = newss;
+ }
+
+ /* We're only interested in array sections from now on. */
if (ref->type != REF_ARRAY)
continue;
@@ -4091,8 +4111,14 @@ gfc_walk_variable_expr (gfc_ss * ss, gfc_expr * expr)
switch (ar->type)
{
case AR_ELEMENT:
- /* TODO: Take elemental array references out of scalarization
- loop. */
+ for (n = 0; n < ar->dimen; n++)
+ {
+ newss = gfc_get_ss ();
+ newss->type = GFC_SS_SCALAR;
+ newss->expr = ar->start[n];
+ newss->next = ss;
+ ss = newss;
+ }
break;
case AR_FULL:
@@ -4115,7 +4141,8 @@ gfc_walk_variable_expr (gfc_ss * ss, gfc_expr * expr)
gcc_assert (ar->end[n] == NULL);
gcc_assert (ar->stride[n] == NULL);
}
- return newss;
+ ss = newss;
+ break;
case AR_SECTION:
newss = gfc_get_ss ();
@@ -4182,7 +4209,7 @@ gfc_walk_variable_expr (gfc_ss * ss, gfc_expr * expr)
}
/* We should have at least one non-elemental dimension. */
gcc_assert (newss->data.info.dimen > 0);
- return head;
+ ss = newss;
break;
default:
diff --git a/gcc/fortran/trans-expr.c b/gcc/fortran/trans-expr.c
index 0d3cb69bf9e..b20ed13fc86 100644
--- a/gcc/fortran/trans-expr.c
+++ b/gcc/fortran/trans-expr.c
@@ -305,7 +305,9 @@ gfc_conv_variable (gfc_se * se, gfc_expr * expr)
/* A scalarized term. We already know the descriptor. */
se->expr = se->ss->data.info.descriptor;
se->string_length = se->ss->string_length;
- ref = se->ss->data.info.ref;
+ for (ref = se->ss->data.info.ref; ref; ref = ref->next)
+ if (ref->type == REF_ARRAY && ref->u.ar.type != AR_ELEMENT)
+ break;
}
else
{
@@ -444,8 +446,6 @@ gfc_conv_variable (gfc_se * se, gfc_expr * expr)
else
se->expr = gfc_build_addr_expr (NULL, se->expr);
}
- if (se->ss != NULL)
- gfc_advance_se_ss_chain (se);
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 716cd8f187f..f20a57650bf 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2005-09-08 Richard Sandiford <richard@codesourcery.com>
+
+ PR fortran/19928
+ * gfortran.dg/pr19928-1.f90, gfortran.dg/pr19928-2.f90: New tests.
+
2005-09-08 Andrew Pinski <pinskia@physics.uc.edu>
PR obj-c++/16816
diff --git a/gcc/testsuite/gfortran.dg/pr19928-1.f90 b/gcc/testsuite/gfortran.dg/pr19928-1.f90
new file mode 100644
index 00000000000..a8b04d8e5e4
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr19928-1.f90
@@ -0,0 +1,11 @@
+! PR 19928. Check the use of constant substring indexes in a
+! scalarization loop.
+! { dg-do run }
+program main
+ implicit none
+ character (len = 5), dimension (2) :: a
+ character (len = 3), dimension (2) :: b
+ a = (/ 'abcde', 'ghijk' /)
+ b = a(:)(2:4)
+ if (b(1) .ne. 'bcd' .or. b(2) .ne. 'hij') call abort
+end program main
diff --git a/gcc/testsuite/gfortran.dg/pr19928-2.f90 b/gcc/testsuite/gfortran.dg/pr19928-2.f90
new file mode 100644
index 00000000000..6bfdd0f30b2
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr19928-2.f90
@@ -0,0 +1,23 @@
+! Related to PR 19928. Check that foo() is only called once per statement.
+! { dg-do run }
+program main
+ implicit none
+ type t
+ integer, dimension (5) :: field
+ end type t
+ type (t), dimension (2) :: a
+ integer :: calls, i, j
+
+ forall (i = 1:2, j = 1:5) a(i)%field(j) = i * 100 + j
+ calls = 0
+ if (sum (a%field(foo(calls))) .ne. 304) call abort
+ if (calls .ne. 1) call abort
+ if (sum (a(foo(calls))%field) .ne. 1015) call abort
+ if (calls .ne. 2) call abort
+contains
+ function foo (calls)
+ integer :: calls, foo
+ calls = calls + 1
+ foo = 2
+ end function foo
+end program main