From 88719f2d356c3e932f23fafdad34d9a39c3b8f2f Mon Sep 17 00:00:00 2001 From: Mikael Morin Date: Fri, 14 Mar 2014 21:28:59 +0000 Subject: re PR fortran/60392 (Problem with TRANSPOSE and CONTIGUOUS dummy arguments) fortran/ PR fortran/60392 * trans-array.c (gfc_conv_array_parameter): Don't reuse the descriptor if it has transposed dimensions. testsuite/ PR fortran/60392 * gfortran.dg/transpose_4.f90: New test. From-SVN: r208581 --- gcc/fortran/ChangeLog | 6 ++++++ gcc/fortran/trans-array.c | 45 ++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 50 insertions(+), 1 deletion(-) (limited to 'gcc/fortran') diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 872a4a3..ba4bdf0 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,9 @@ +2014-03-14 Mikael Morin + + PR fortran/60392 + * trans-array.c (gfc_conv_array_parameter): Don't reuse the descriptor + if it has transposed dimensions. + 2014-03-08 Tobias Burnus PR fortran/60447 diff --git a/gcc/fortran/trans-array.c b/gcc/fortran/trans-array.c index 153ef67..dee422c 100644 --- a/gcc/fortran/trans-array.c +++ b/gcc/fortran/trans-array.c @@ -7227,7 +7227,50 @@ gfc_conv_array_parameter (gfc_se * se, gfc_expr * expr, bool g77, else { tmp = build_fold_indirect_ref_loc (input_location, desc); - gfc_conv_descriptor_data_set (&se->pre, tmp, ptr); + + gfc_ss * ss = gfc_walk_expr (expr); + if (!transposed_dims (ss)) + gfc_conv_descriptor_data_set (&se->pre, tmp, ptr); + else + { + tree old_field, new_field; + + /* The original descriptor has transposed dims so we can't reuse + it directly; we have to create a new one. */ + tree old_desc = tmp; + tree new_desc = gfc_create_var (TREE_TYPE (old_desc), "arg_desc"); + + old_field = gfc_conv_descriptor_dtype (old_desc); + new_field = gfc_conv_descriptor_dtype (new_desc); + gfc_add_modify (&se->pre, new_field, old_field); + + old_field = gfc_conv_descriptor_offset (old_desc); + new_field = gfc_conv_descriptor_offset (new_desc); + gfc_add_modify (&se->pre, new_field, old_field); + + for (int i = 0; i < expr->rank; i++) + { + old_field = gfc_conv_descriptor_dimension (old_desc, + gfc_rank_cst[get_array_ref_dim_for_loop_dim (ss, i)]); + new_field = gfc_conv_descriptor_dimension (new_desc, + gfc_rank_cst[i]); + gfc_add_modify (&se->pre, new_field, old_field); + } + + if (gfc_option.coarray == GFC_FCOARRAY_LIB + && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (old_desc)) + && GFC_TYPE_ARRAY_AKIND (TREE_TYPE (old_desc)) + == GFC_ARRAY_ALLOCATABLE) + { + old_field = gfc_conv_descriptor_token (old_desc); + new_field = gfc_conv_descriptor_token (new_desc); + gfc_add_modify (&se->pre, new_field, old_field); + } + + gfc_conv_descriptor_data_set (&se->pre, new_desc, ptr); + se->expr = gfc_build_addr_expr (NULL_TREE, new_desc); + } + gfc_free_ss (ss); } if (gfc_option.rtcheck & GFC_RTCHECK_ARRAY_TEMPS) -- cgit v1.1