aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran
diff options
context:
space:
mode:
authorPaul Thomas <pault@gcc.gnu.org>2014-04-13 11:58:55 +0000
committerPaul Thomas <pault@gcc.gnu.org>2014-04-13 11:58:55 +0000
commit1cf43a1dbdb4f61d2f9bbfffb2fdc6130aa07781 (patch)
treea0e9223d3fa93775c9210bdc4aade00d42633cb2 /gcc/fortran
parentef3a248fbb9c61d510cdcee3de0476994ae32790 (diff)
downloadgcc-1cf43a1dbdb4f61d2f9bbfffb2fdc6130aa07781.zip
gcc-1cf43a1dbdb4f61d2f9bbfffb2fdc6130aa07781.tar.gz
gcc-1cf43a1dbdb4f61d2f9bbfffb2fdc6130aa07781.tar.bz2
re PR fortran/58085 (Wrong indexing of an array in ASSOCIATE)
2014-04-13 Paul Thomas <pault@gcc.gnu.org> PR fortran/58085 PR fortran/60717 * trans.h: Add 'use_offset' bitfield to gfc_se. * trans-array.c (gfc_conv_expr_descriptor): Use 'use_offset' as a trigger to unconditionally recalculate the offset for array slices and constant arrays. trans-expr.c (gfc_conv_intrinsic_to_class): Use it. trans-stmt.c (trans_associate_var): Ditto. (gfc_conv_procedure_call): Ditto. 2014-04-13 Paul Thomas <pault@gcc.gnu.org> PR fortran/60717 * gfortran.dg/unlimited_polymorphic_17.f90: New test. PR fortran/58085 * gfortran.dg/associate_15.f90: New test. From-SVN: r209347
Diffstat (limited to 'gcc/fortran')
-rw-r--r--gcc/fortran/ChangeLog12
-rw-r--r--gcc/fortran/trans-array.c16
-rw-r--r--gcc/fortran/trans-expr.c2
-rw-r--r--gcc/fortran/trans-stmt.c6
-rw-r--r--gcc/fortran/trans.h8
5 files changed, 33 insertions, 11 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index c14e209..29ea5f7 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,15 @@
+2014-04-13 Paul Thomas <pault@gcc.gnu.org>
+
+ PR fortran/58085
+ PR fortran/60717
+ * trans.h: Add 'use_offset' bitfield to gfc_se.
+ * trans-array.c (gfc_conv_expr_descriptor): Use 'use_offset'
+ as a trigger to unconditionally recalculate the offset for
+ array slices and constant arrays.
+ trans-expr.c (gfc_conv_intrinsic_to_class): Use it.
+ trans-stmt.c (trans_associate_var): Ditto.
+ (gfc_conv_procedure_call): Ditto.
+
2014-04-11 Tobias Burnus <burnus@net-b.de>
PR fortran/58880
diff --git a/gcc/fortran/trans-array.c b/gcc/fortran/trans-array.c
index 8c4afb0..69c47bb 100644
--- a/gcc/fortran/trans-array.c
+++ b/gcc/fortran/trans-array.c
@@ -6807,8 +6807,9 @@ gfc_conv_expr_descriptor (gfc_se *se, gfc_expr *expr)
/* Set offset for assignments to pointer only to zero if it is not
the full array. */
- if (se->direct_byref
- && info->ref && info->ref->u.ar.type != AR_FULL)
+ if ((se->direct_byref || se->use_offset)
+ && ((info->ref && info->ref->u.ar.type != AR_FULL)
+ || (expr->expr_type == EXPR_ARRAY && se->use_offset)))
base = gfc_index_zero_node;
else if (GFC_ARRAY_TYPE_P (TREE_TYPE (desc)))
base = gfc_evaluate_now (gfc_conv_array_offset (desc), &loop.pre);
@@ -6893,13 +6894,13 @@ gfc_conv_expr_descriptor (gfc_se *se, gfc_expr *expr)
stride, info->stride[n]);
if (se->direct_byref
- && info->ref
- && info->ref->u.ar.type != AR_FULL)
+ && ((info->ref && info->ref->u.ar.type != AR_FULL)
+ || (expr->expr_type == EXPR_ARRAY && se->use_offset)))
{
base = fold_build2_loc (input_location, MINUS_EXPR,
TREE_TYPE (base), base, stride);
}
- else if (GFC_ARRAY_TYPE_P (TREE_TYPE (desc)))
+ else if (GFC_ARRAY_TYPE_P (TREE_TYPE (desc)) || se->use_offset)
{
tmp = gfc_conv_array_lbound (desc, n);
tmp = fold_build2_loc (input_location, MINUS_EXPR,
@@ -6935,8 +6936,9 @@ gfc_conv_expr_descriptor (gfc_se *se, gfc_expr *expr)
gfc_get_dataptr_offset (&loop.pre, parm, desc, offset,
subref_array_target, expr);
- if ((se->direct_byref || GFC_ARRAY_TYPE_P (TREE_TYPE (desc)))
- && !se->data_not_needed)
+ if (((se->direct_byref || GFC_ARRAY_TYPE_P (TREE_TYPE (desc)))
+ && !se->data_not_needed)
+ || (se->use_offset && base != NULL_TREE))
{
/* Set the offset. */
gfc_conv_descriptor_offset_set (&loop.pre, parm, base);
diff --git a/gcc/fortran/trans-expr.c b/gcc/fortran/trans-expr.c
index 30931a3..955102b 100644
--- a/gcc/fortran/trans-expr.c
+++ b/gcc/fortran/trans-expr.c
@@ -593,6 +593,7 @@ gfc_conv_intrinsic_to_class (gfc_se *parmse, gfc_expr *e,
else
{
parmse->ss = ss;
+ parmse->use_offset = 1;
gfc_conv_expr_descriptor (parmse, e);
gfc_add_modify (&parmse->pre, ctree, parmse->expr);
}
@@ -4378,6 +4379,7 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
|| CLASS_DATA (fsym)->attr.codimension))
{
/* Pass a class array. */
+ parmse.use_offset = 1;
gfc_conv_expr_descriptor (&parmse, e);
/* If an ALLOCATABLE dummy argument has INTENT(OUT) and is
diff --git a/gcc/fortran/trans-stmt.c b/gcc/fortran/trans-stmt.c
index 1a9068c..00c99fc 100644
--- a/gcc/fortran/trans-stmt.c
+++ b/gcc/fortran/trans-stmt.c
@@ -1170,16 +1170,18 @@ trans_associate_var (gfc_symbol *sym, gfc_wrapped_block *block)
/* If association is to an expression, evaluate it and create temporary.
Otherwise, get descriptor of target for pointer assignment. */
gfc_init_se (&se, NULL);
- if (sym->assoc->variable)
+ if (sym->assoc->variable || e->expr_type == EXPR_ARRAY)
{
se.direct_byref = 1;
+ se.use_offset = 1;
se.expr = desc;
}
+
gfc_conv_expr_descriptor (&se, e);
/* If we didn't already do the pointer assignment, set associate-name
descriptor to the one generated for the temporary. */
- if (!sym->assoc->variable)
+ if (!sym->assoc->variable && e->expr_type != EXPR_ARRAY)
{
int dim;
diff --git a/gcc/fortran/trans.h b/gcc/fortran/trans.h
index 4ae68c6..f8d29ec 100644
--- a/gcc/fortran/trans.h
+++ b/gcc/fortran/trans.h
@@ -87,6 +87,10 @@ typedef struct gfc_se
args alias. */
unsigned force_tmp:1;
+ /* Unconditionally calculate offset for array segments and constant
+ arrays in gfc_conv_expr_descriptor. */
+ unsigned use_offset:1;
+
unsigned want_coarray:1;
/* Scalarization parameters. */
@@ -99,7 +103,7 @@ gfc_se;
/* Denotes different types of coarray.
Please keep in sync with libgfortran/caf/libcaf.h. */
-typedef enum
+typedef enum
{
GFC_CAF_COARRAY_STATIC,
GFC_CAF_COARRAY_ALLOC,
@@ -178,7 +182,7 @@ typedef enum
/* An intrinsic function call. Many intrinsic functions which map directly
to library calls are created as GFC_SS_FUNCTION nodes. */
GFC_SS_INTRINSIC,
-
+
/* A component of a derived type. */
GFC_SS_COMPONENT
}