Home | History | Annotate | Line # | Download | only in fortran
      1  1.1  mrg /* Expression translation
      2  1.1  mrg    Copyright (C) 2002-2022 Free Software Foundation, Inc.
      3  1.1  mrg    Contributed by Paul Brook <paul (at) nowt.org>
      4  1.1  mrg    and Steven Bosscher <s.bosscher (at) student.tudelft.nl>
      5  1.1  mrg 
      6  1.1  mrg This file is part of GCC.
      7  1.1  mrg 
      8  1.1  mrg GCC is free software; you can redistribute it and/or modify it under
      9  1.1  mrg the terms of the GNU General Public License as published by the Free
     10  1.1  mrg Software Foundation; either version 3, or (at your option) any later
     11  1.1  mrg version.
     12  1.1  mrg 
     13  1.1  mrg GCC is distributed in the hope that it will be useful, but WITHOUT ANY
     14  1.1  mrg WARRANTY; without even the implied warranty of MERCHANTABILITY or
     15  1.1  mrg FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
     16  1.1  mrg for more details.
     17  1.1  mrg 
     18  1.1  mrg You should have received a copy of the GNU General Public License
     19  1.1  mrg along with GCC; see the file COPYING3.  If not see
     20  1.1  mrg <http://www.gnu.org/licenses/>.  */
     21  1.1  mrg 
     22  1.1  mrg /* trans-expr.cc-- generate GENERIC trees for gfc_expr.  */
     23  1.1  mrg 
     24  1.1  mrg #include "config.h"
     25  1.1  mrg #include "system.h"
     26  1.1  mrg #include "coretypes.h"
     27  1.1  mrg #include "options.h"
     28  1.1  mrg #include "tree.h"
     29  1.1  mrg #include "gfortran.h"
     30  1.1  mrg #include "trans.h"
     31  1.1  mrg #include "stringpool.h"
     32  1.1  mrg #include "diagnostic-core.h"	/* For fatal_error.  */
     33  1.1  mrg #include "fold-const.h"
     34  1.1  mrg #include "langhooks.h"
     35  1.1  mrg #include "arith.h"
     36  1.1  mrg #include "constructor.h"
     37  1.1  mrg #include "trans-const.h"
     38  1.1  mrg #include "trans-types.h"
     39  1.1  mrg #include "trans-array.h"
     40  1.1  mrg /* Only for gfc_trans_assign and gfc_trans_pointer_assign.  */
     41  1.1  mrg #include "trans-stmt.h"
     42  1.1  mrg #include "dependency.h"
     43  1.1  mrg #include "gimplify.h"
     44  1.1  mrg #include "tm.h"		/* For CHAR_TYPE_SIZE.  */
     45  1.1  mrg 
     46  1.1  mrg 
     47  1.1  mrg /* Calculate the number of characters in a string.  */
     48  1.1  mrg 
     49  1.1  mrg static tree
     50  1.1  mrg gfc_get_character_len (tree type)
     51  1.1  mrg {
     52  1.1  mrg   tree len;
     53  1.1  mrg 
     54  1.1  mrg   gcc_assert (type && TREE_CODE (type) == ARRAY_TYPE
     55  1.1  mrg 	      && TYPE_STRING_FLAG (type));
     56  1.1  mrg 
     57  1.1  mrg   len = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
     58  1.1  mrg   len = (len) ? (len) : (integer_zero_node);
     59  1.1  mrg   return fold_convert (gfc_charlen_type_node, len);
     60  1.1  mrg }
     61  1.1  mrg 
     62  1.1  mrg 
     63  1.1  mrg 
     64  1.1  mrg /* Calculate the number of bytes in a string.  */
     65  1.1  mrg 
     66  1.1  mrg tree
     67  1.1  mrg gfc_get_character_len_in_bytes (tree type)
     68  1.1  mrg {
     69  1.1  mrg   tree tmp, len;
     70  1.1  mrg 
     71  1.1  mrg   gcc_assert (type && TREE_CODE (type) == ARRAY_TYPE
     72  1.1  mrg 	      && TYPE_STRING_FLAG (type));
     73  1.1  mrg 
     74  1.1  mrg   tmp = TYPE_SIZE_UNIT (TREE_TYPE (type));
     75  1.1  mrg   tmp = (tmp && !integer_zerop (tmp))
     76  1.1  mrg     ? (fold_convert (gfc_charlen_type_node, tmp)) : (NULL_TREE);
     77  1.1  mrg   len = gfc_get_character_len (type);
     78  1.1  mrg   if (tmp && len && !integer_zerop (len))
     79  1.1  mrg     len = fold_build2_loc (input_location, MULT_EXPR,
     80  1.1  mrg 			   gfc_charlen_type_node, len, tmp);
     81  1.1  mrg   return len;
     82  1.1  mrg }
     83  1.1  mrg 
     84  1.1  mrg 
     85  1.1  mrg /* Convert a scalar to an array descriptor. To be used for assumed-rank
     86  1.1  mrg    arrays.  */
     87  1.1  mrg 
     88  1.1  mrg static tree
     89  1.1  mrg get_scalar_to_descriptor_type (tree scalar, symbol_attribute attr)
     90  1.1  mrg {
     91  1.1  mrg   enum gfc_array_kind akind;
     92  1.1  mrg 
     93  1.1  mrg   if (attr.pointer)
     94  1.1  mrg     akind = GFC_ARRAY_POINTER_CONT;
     95  1.1  mrg   else if (attr.allocatable)
     96  1.1  mrg     akind = GFC_ARRAY_ALLOCATABLE;
     97  1.1  mrg   else
     98  1.1  mrg     akind = GFC_ARRAY_ASSUMED_SHAPE_CONT;
     99  1.1  mrg 
    100  1.1  mrg   if (POINTER_TYPE_P (TREE_TYPE (scalar)))
    101  1.1  mrg     scalar = TREE_TYPE (scalar);
    102  1.1  mrg   return gfc_get_array_type_bounds (TREE_TYPE (scalar), 0, 0, NULL, NULL, 1,
    103  1.1  mrg 				    akind, !(attr.pointer || attr.target));
    104  1.1  mrg }
    105  1.1  mrg 
    106  1.1  mrg tree
    107  1.1  mrg gfc_conv_scalar_to_descriptor (gfc_se *se, tree scalar, symbol_attribute attr)
    108  1.1  mrg {
    109  1.1  mrg   tree desc, type, etype;
    110  1.1  mrg 
    111  1.1  mrg   type = get_scalar_to_descriptor_type (scalar, attr);
    112  1.1  mrg   etype = TREE_TYPE (scalar);
    113  1.1  mrg   desc = gfc_create_var (type, "desc");
    114  1.1  mrg   DECL_ARTIFICIAL (desc) = 1;
    115  1.1  mrg 
    116  1.1  mrg   if (CONSTANT_CLASS_P (scalar))
    117  1.1  mrg     {
    118  1.1  mrg       tree tmp;
    119  1.1  mrg       tmp = gfc_create_var (TREE_TYPE (scalar), "scalar");
    120  1.1  mrg       gfc_add_modify (&se->pre, tmp, scalar);
    121  1.1  mrg       scalar = tmp;
    122  1.1  mrg     }
    123  1.1  mrg   if (!POINTER_TYPE_P (TREE_TYPE (scalar)))
    124  1.1  mrg     scalar = gfc_build_addr_expr (NULL_TREE, scalar);
    125  1.1  mrg   else if (TREE_TYPE (etype) && TREE_CODE (TREE_TYPE (etype)) == ARRAY_TYPE)
    126  1.1  mrg     etype = TREE_TYPE (etype);
    127  1.1  mrg   gfc_add_modify (&se->pre, gfc_conv_descriptor_dtype (desc),
    128  1.1  mrg 		  gfc_get_dtype_rank_type (0, etype));
    129  1.1  mrg   gfc_conv_descriptor_data_set (&se->pre, desc, scalar);
    130  1.1  mrg   gfc_conv_descriptor_span_set (&se->pre, desc,
    131  1.1  mrg 				gfc_conv_descriptor_elem_len (desc));
    132  1.1  mrg 
    133  1.1  mrg   /* Copy pointer address back - but only if it could have changed and
    134  1.1  mrg      if the actual argument is a pointer and not, e.g., NULL().  */
    135  1.1  mrg   if ((attr.pointer || attr.allocatable) && attr.intent != INTENT_IN)
    136  1.1  mrg     gfc_add_modify (&se->post, scalar,
    137  1.1  mrg 		    fold_convert (TREE_TYPE (scalar),
    138  1.1  mrg 				  gfc_conv_descriptor_data_get (desc)));
    139  1.1  mrg   return desc;
    140  1.1  mrg }
    141  1.1  mrg 
    142  1.1  mrg 
    143  1.1  mrg /* Get the coarray token from the ultimate array or component ref.
    144  1.1  mrg    Returns a NULL_TREE, when the ref object is not allocatable or pointer.  */
    145  1.1  mrg 
    146  1.1  mrg tree
    147  1.1  mrg gfc_get_ultimate_alloc_ptr_comps_caf_token (gfc_se *outerse, gfc_expr *expr)
    148  1.1  mrg {
    149  1.1  mrg   gfc_symbol *sym = expr->symtree->n.sym;
    150  1.1  mrg   bool is_coarray = sym->attr.codimension;
    151  1.1  mrg   gfc_expr *caf_expr = gfc_copy_expr (expr);
    152  1.1  mrg   gfc_ref *ref = caf_expr->ref, *last_caf_ref = NULL;
    153  1.1  mrg 
    154  1.1  mrg   while (ref)
    155  1.1  mrg     {
    156  1.1  mrg       if (ref->type == REF_COMPONENT
    157  1.1  mrg 	  && (ref->u.c.component->attr.allocatable
    158  1.1  mrg 	      || ref->u.c.component->attr.pointer)
    159  1.1  mrg 	  && (is_coarray || ref->u.c.component->attr.codimension))
    160  1.1  mrg 	  last_caf_ref = ref;
    161  1.1  mrg       ref = ref->next;
    162  1.1  mrg     }
    163  1.1  mrg 
    164  1.1  mrg   if (last_caf_ref == NULL)
    165  1.1  mrg     return NULL_TREE;
    166  1.1  mrg 
    167  1.1  mrg   tree comp = last_caf_ref->u.c.component->caf_token, caf;
    168  1.1  mrg   gfc_se se;
    169  1.1  mrg   bool comp_ref = !last_caf_ref->u.c.component->attr.dimension;
    170  1.1  mrg   if (comp == NULL_TREE && comp_ref)
    171  1.1  mrg     return NULL_TREE;
    172  1.1  mrg   gfc_init_se (&se, outerse);
    173  1.1  mrg   gfc_free_ref_list (last_caf_ref->next);
    174  1.1  mrg   last_caf_ref->next = NULL;
    175  1.1  mrg   caf_expr->rank = comp_ref ? 0 : last_caf_ref->u.c.component->as->rank;
    176  1.1  mrg   se.want_pointer = comp_ref;
    177  1.1  mrg   gfc_conv_expr (&se, caf_expr);
    178  1.1  mrg   gfc_add_block_to_block (&outerse->pre, &se.pre);
    179  1.1  mrg 
    180  1.1  mrg   if (TREE_CODE (se.expr) == COMPONENT_REF && comp_ref)
    181  1.1  mrg     se.expr = TREE_OPERAND (se.expr, 0);
    182  1.1  mrg   gfc_free_expr (caf_expr);
    183  1.1  mrg 
    184  1.1  mrg   if (comp_ref)
    185  1.1  mrg     caf = fold_build3_loc (input_location, COMPONENT_REF,
    186  1.1  mrg 			   TREE_TYPE (comp), se.expr, comp, NULL_TREE);
    187  1.1  mrg   else
    188  1.1  mrg     caf = gfc_conv_descriptor_token (se.expr);
    189  1.1  mrg   return gfc_build_addr_expr (NULL_TREE, caf);
    190  1.1  mrg }
    191  1.1  mrg 
    192  1.1  mrg 
    193  1.1  mrg /* This is the seed for an eventual trans-class.c
    194  1.1  mrg 
    195  1.1  mrg    The following parameters should not be used directly since they might
    196  1.1  mrg    in future implementations.  Use the corresponding APIs.  */
    197  1.1  mrg #define CLASS_DATA_FIELD 0
    198  1.1  mrg #define CLASS_VPTR_FIELD 1
    199  1.1  mrg #define CLASS_LEN_FIELD 2
    200  1.1  mrg #define VTABLE_HASH_FIELD 0
    201  1.1  mrg #define VTABLE_SIZE_FIELD 1
    202  1.1  mrg #define VTABLE_EXTENDS_FIELD 2
    203  1.1  mrg #define VTABLE_DEF_INIT_FIELD 3
    204  1.1  mrg #define VTABLE_COPY_FIELD 4
    205  1.1  mrg #define VTABLE_FINAL_FIELD 5
    206  1.1  mrg #define VTABLE_DEALLOCATE_FIELD 6
    207  1.1  mrg 
    208  1.1  mrg 
    209  1.1  mrg tree
    210  1.1  mrg gfc_class_set_static_fields (tree decl, tree vptr, tree data)
    211  1.1  mrg {
    212  1.1  mrg   tree tmp;
    213  1.1  mrg   tree field;
    214  1.1  mrg   vec<constructor_elt, va_gc> *init = NULL;
    215  1.1  mrg 
    216  1.1  mrg   field = TYPE_FIELDS (TREE_TYPE (decl));
    217  1.1  mrg   tmp = gfc_advance_chain (field, CLASS_DATA_FIELD);
    218  1.1  mrg   CONSTRUCTOR_APPEND_ELT (init, tmp, data);
    219  1.1  mrg 
    220  1.1  mrg   tmp = gfc_advance_chain (field, CLASS_VPTR_FIELD);
    221  1.1  mrg   CONSTRUCTOR_APPEND_ELT (init, tmp, vptr);
    222  1.1  mrg 
    223  1.1  mrg   return build_constructor (TREE_TYPE (decl), init);
    224  1.1  mrg }
    225  1.1  mrg 
    226  1.1  mrg 
    227  1.1  mrg tree
    228  1.1  mrg gfc_class_data_get (tree decl)
    229  1.1  mrg {
    230  1.1  mrg   tree data;
    231  1.1  mrg   if (POINTER_TYPE_P (TREE_TYPE (decl)))
    232  1.1  mrg     decl = build_fold_indirect_ref_loc (input_location, decl);
    233  1.1  mrg   data = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (decl)),
    234  1.1  mrg 			    CLASS_DATA_FIELD);
    235  1.1  mrg   return fold_build3_loc (input_location, COMPONENT_REF,
    236  1.1  mrg 			  TREE_TYPE (data), decl, data,
    237  1.1  mrg 			  NULL_TREE);
    238  1.1  mrg }
    239  1.1  mrg 
    240  1.1  mrg 
    241  1.1  mrg tree
    242  1.1  mrg gfc_class_vptr_get (tree decl)
    243  1.1  mrg {
    244  1.1  mrg   tree vptr;
    245  1.1  mrg   /* For class arrays decl may be a temporary descriptor handle, the vptr is
    246  1.1  mrg      then available through the saved descriptor.  */
    247  1.1  mrg   if (VAR_P (decl) && DECL_LANG_SPECIFIC (decl)
    248  1.1  mrg       && GFC_DECL_SAVED_DESCRIPTOR (decl))
    249  1.1  mrg     decl = GFC_DECL_SAVED_DESCRIPTOR (decl);
    250  1.1  mrg   if (POINTER_TYPE_P (TREE_TYPE (decl)))
    251  1.1  mrg     decl = build_fold_indirect_ref_loc (input_location, decl);
    252  1.1  mrg   vptr = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (decl)),
    253  1.1  mrg 			    CLASS_VPTR_FIELD);
    254  1.1  mrg   return fold_build3_loc (input_location, COMPONENT_REF,
    255  1.1  mrg 			  TREE_TYPE (vptr), decl, vptr,
    256  1.1  mrg 			  NULL_TREE);
    257  1.1  mrg }
    258  1.1  mrg 
    259  1.1  mrg 
    260  1.1  mrg tree
    261  1.1  mrg gfc_class_len_get (tree decl)
    262  1.1  mrg {
    263  1.1  mrg   tree len;
    264  1.1  mrg   /* For class arrays decl may be a temporary descriptor handle, the len is
    265  1.1  mrg      then available through the saved descriptor.  */
    266  1.1  mrg   if (VAR_P (decl) && DECL_LANG_SPECIFIC (decl)
    267  1.1  mrg       && GFC_DECL_SAVED_DESCRIPTOR (decl))
    268  1.1  mrg     decl = GFC_DECL_SAVED_DESCRIPTOR (decl);
    269  1.1  mrg   if (POINTER_TYPE_P (TREE_TYPE (decl)))
    270  1.1  mrg     decl = build_fold_indirect_ref_loc (input_location, decl);
    271  1.1  mrg   len = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (decl)),
    272  1.1  mrg 			   CLASS_LEN_FIELD);
    273  1.1  mrg   return fold_build3_loc (input_location, COMPONENT_REF,
    274  1.1  mrg 			  TREE_TYPE (len), decl, len,
    275  1.1  mrg 			  NULL_TREE);
    276  1.1  mrg }
    277  1.1  mrg 
    278  1.1  mrg 
    279  1.1  mrg /* Try to get the _len component of a class.  When the class is not unlimited
    280  1.1  mrg    poly, i.e. no _len field exists, then return a zero node.  */
    281  1.1  mrg 
    282  1.1  mrg static tree
    283  1.1  mrg gfc_class_len_or_zero_get (tree decl)
    284  1.1  mrg {
    285  1.1  mrg   tree len;
    286  1.1  mrg   /* For class arrays decl may be a temporary descriptor handle, the vptr is
    287  1.1  mrg      then available through the saved descriptor.  */
    288  1.1  mrg   if (VAR_P (decl) && DECL_LANG_SPECIFIC (decl)
    289  1.1  mrg       && GFC_DECL_SAVED_DESCRIPTOR (decl))
    290  1.1  mrg     decl = GFC_DECL_SAVED_DESCRIPTOR (decl);
    291  1.1  mrg   if (POINTER_TYPE_P (TREE_TYPE (decl)))
    292  1.1  mrg     decl = build_fold_indirect_ref_loc (input_location, decl);
    293  1.1  mrg   len = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (decl)),
    294  1.1  mrg 			   CLASS_LEN_FIELD);
    295  1.1  mrg   return len != NULL_TREE ? fold_build3_loc (input_location, COMPONENT_REF,
    296  1.1  mrg 					     TREE_TYPE (len), decl, len,
    297  1.1  mrg 					     NULL_TREE)
    298  1.1  mrg     : build_zero_cst (gfc_charlen_type_node);
    299  1.1  mrg }
    300  1.1  mrg 
    301  1.1  mrg 
    302  1.1  mrg tree
    303  1.1  mrg gfc_resize_class_size_with_len (stmtblock_t * block, tree class_expr, tree size)
    304  1.1  mrg {
    305  1.1  mrg   tree tmp;
    306  1.1  mrg   tree tmp2;
    307  1.1  mrg   tree type;
    308  1.1  mrg 
    309  1.1  mrg   tmp = gfc_class_len_or_zero_get (class_expr);
    310  1.1  mrg 
    311  1.1  mrg   /* Include the len value in the element size if present.  */
    312  1.1  mrg   if (!integer_zerop (tmp))
    313  1.1  mrg     {
    314  1.1  mrg       type = TREE_TYPE (size);
    315  1.1  mrg       if (block)
    316  1.1  mrg 	{
    317  1.1  mrg 	  size = gfc_evaluate_now (size, block);
    318  1.1  mrg 	  tmp = gfc_evaluate_now (fold_convert (type , tmp), block);
    319  1.1  mrg 	}
    320  1.1  mrg       tmp2 = fold_build2_loc (input_location, MULT_EXPR,
    321  1.1  mrg 			      type, size, tmp);
    322  1.1  mrg       tmp = fold_build2_loc (input_location, GT_EXPR,
    323  1.1  mrg 			     logical_type_node, tmp,
    324  1.1  mrg 			     build_zero_cst (type));
    325  1.1  mrg       size = fold_build3_loc (input_location, COND_EXPR,
    326  1.1  mrg 			      type, tmp, tmp2, size);
    327  1.1  mrg     }
    328  1.1  mrg   else
    329  1.1  mrg     return size;
    330  1.1  mrg 
    331  1.1  mrg   if (block)
    332  1.1  mrg     size = gfc_evaluate_now (size, block);
    333  1.1  mrg 
    334  1.1  mrg   return size;
    335  1.1  mrg }
    336  1.1  mrg 
    337  1.1  mrg 
    338  1.1  mrg /* Get the specified FIELD from the VPTR.  */
    339  1.1  mrg 
    340  1.1  mrg static tree
    341  1.1  mrg vptr_field_get (tree vptr, int fieldno)
    342  1.1  mrg {
    343  1.1  mrg   tree field;
    344  1.1  mrg   vptr = build_fold_indirect_ref_loc (input_location, vptr);
    345  1.1  mrg   field = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (vptr)),
    346  1.1  mrg 			     fieldno);
    347  1.1  mrg   field = fold_build3_loc (input_location, COMPONENT_REF,
    348  1.1  mrg 			   TREE_TYPE (field), vptr, field,
    349  1.1  mrg 			   NULL_TREE);
    350  1.1  mrg   gcc_assert (field);
    351  1.1  mrg   return field;
    352  1.1  mrg }
    353  1.1  mrg 
    354  1.1  mrg 
    355  1.1  mrg /* Get the field from the class' vptr.  */
    356  1.1  mrg 
    357  1.1  mrg static tree
    358  1.1  mrg class_vtab_field_get (tree decl, int fieldno)
    359  1.1  mrg {
    360  1.1  mrg   tree vptr;
    361  1.1  mrg   vptr = gfc_class_vptr_get (decl);
    362  1.1  mrg   return vptr_field_get (vptr, fieldno);
    363  1.1  mrg }
    364  1.1  mrg 
    365  1.1  mrg 
    366  1.1  mrg /* Define a macro for creating the class_vtab_* and vptr_* accessors in
    367  1.1  mrg    unison.  */
    368  1.1  mrg #define VTAB_GET_FIELD_GEN(name, field) tree \
    369  1.1  mrg gfc_class_vtab_## name ##_get (tree cl) \
    370  1.1  mrg { \
    371  1.1  mrg   return class_vtab_field_get (cl, field); \
    372  1.1  mrg } \
    373  1.1  mrg  \
    374  1.1  mrg tree \
    375  1.1  mrg gfc_vptr_## name ##_get (tree vptr) \
    376  1.1  mrg { \
    377  1.1  mrg   return vptr_field_get (vptr, field); \
    378  1.1  mrg }
    379  1.1  mrg 
    380  1.1  mrg VTAB_GET_FIELD_GEN (hash, VTABLE_HASH_FIELD)
    381  1.1  mrg VTAB_GET_FIELD_GEN (extends, VTABLE_EXTENDS_FIELD)
    382  1.1  mrg VTAB_GET_FIELD_GEN (def_init, VTABLE_DEF_INIT_FIELD)
    383  1.1  mrg VTAB_GET_FIELD_GEN (copy, VTABLE_COPY_FIELD)
    384  1.1  mrg VTAB_GET_FIELD_GEN (final, VTABLE_FINAL_FIELD)
    385  1.1  mrg VTAB_GET_FIELD_GEN (deallocate, VTABLE_DEALLOCATE_FIELD)
    386  1.1  mrg #undef VTAB_GET_FIELD_GEN
    387  1.1  mrg 
    388  1.1  mrg /* The size field is returned as an array index type.  Therefore treat
    389  1.1  mrg    it and only it specially.  */
    390  1.1  mrg 
    391  1.1  mrg tree
    392  1.1  mrg gfc_class_vtab_size_get (tree cl)
    393  1.1  mrg {
    394  1.1  mrg   tree size;
    395  1.1  mrg   size = class_vtab_field_get (cl, VTABLE_SIZE_FIELD);
    396  1.1  mrg   /* Always return size as an array index type.  */
    397  1.1  mrg   size = fold_convert (gfc_array_index_type, size);
    398  1.1  mrg   gcc_assert (size);
    399  1.1  mrg   return size;
    400  1.1  mrg }
    401  1.1  mrg 
    402  1.1  mrg tree
    403  1.1  mrg gfc_vptr_size_get (tree vptr)
    404  1.1  mrg {
    405  1.1  mrg   tree size;
    406  1.1  mrg   size = vptr_field_get (vptr, VTABLE_SIZE_FIELD);
    407  1.1  mrg   /* Always return size as an array index type.  */
    408  1.1  mrg   size = fold_convert (gfc_array_index_type, size);
    409  1.1  mrg   gcc_assert (size);
    410  1.1  mrg   return size;
    411  1.1  mrg }
    412  1.1  mrg 
    413  1.1  mrg 
    414  1.1  mrg #undef CLASS_DATA_FIELD
    415  1.1  mrg #undef CLASS_VPTR_FIELD
    416  1.1  mrg #undef CLASS_LEN_FIELD
    417  1.1  mrg #undef VTABLE_HASH_FIELD
    418  1.1  mrg #undef VTABLE_SIZE_FIELD
    419  1.1  mrg #undef VTABLE_EXTENDS_FIELD
    420  1.1  mrg #undef VTABLE_DEF_INIT_FIELD
    421  1.1  mrg #undef VTABLE_COPY_FIELD
    422  1.1  mrg #undef VTABLE_FINAL_FIELD
    423  1.1  mrg 
    424  1.1  mrg 
    425  1.1  mrg /* IF ts is null (default), search for the last _class ref in the chain
    426  1.1  mrg    of references of the expression and cut the chain there.  Although
    427  1.1  mrg    this routine is similiar to class.cc:gfc_add_component_ref (), there
    428  1.1  mrg    is a significant difference: gfc_add_component_ref () concentrates
    429  1.1  mrg    on an array ref that is the last ref in the chain and is oblivious
    430  1.1  mrg    to the kind of refs following.
    431  1.1  mrg    ELSE IF ts is non-null the cut is at the class entity or component
    432  1.1  mrg    that is followed by an array reference, which is not an element.
    433  1.1  mrg    These calls come from trans-array.cc:build_class_array_ref, which
    434  1.1  mrg    handles scalarized class array references.*/
    435  1.1  mrg 
    436  1.1  mrg gfc_expr *
    437  1.1  mrg gfc_find_and_cut_at_last_class_ref (gfc_expr *e, bool is_mold,
    438  1.1  mrg 				    gfc_typespec **ts)
    439  1.1  mrg {
    440  1.1  mrg   gfc_expr *base_expr;
    441  1.1  mrg   gfc_ref *ref, *class_ref, *tail = NULL, *array_ref;
    442  1.1  mrg 
    443  1.1  mrg   /* Find the last class reference.  */
    444  1.1  mrg   class_ref = NULL;
    445  1.1  mrg   array_ref = NULL;
    446  1.1  mrg 
    447  1.1  mrg   if (ts)
    448  1.1  mrg     {
    449  1.1  mrg       if (e->symtree
    450  1.1  mrg 	  && e->symtree->n.sym->ts.type == BT_CLASS)
    451  1.1  mrg 	*ts = &e->symtree->n.sym->ts;
    452  1.1  mrg       else
    453  1.1  mrg 	*ts = NULL;
    454  1.1  mrg     }
    455  1.1  mrg 
    456  1.1  mrg   for (ref = e->ref; ref; ref = ref->next)
    457  1.1  mrg     {
    458  1.1  mrg       if (ts)
    459  1.1  mrg 	{
    460  1.1  mrg 	  if (ref->type == REF_COMPONENT
    461  1.1  mrg 	      && ref->u.c.component->ts.type == BT_CLASS
    462  1.1  mrg 	      && ref->next && ref->next->type == REF_COMPONENT
    463  1.1  mrg 	      && !strcmp (ref->next->u.c.component->name, "_data")
    464  1.1  mrg 	      && ref->next->next
    465  1.1  mrg 	      && ref->next->next->type == REF_ARRAY
    466  1.1  mrg 	      && ref->next->next->u.ar.type != AR_ELEMENT)
    467  1.1  mrg 	    {
    468  1.1  mrg 	      *ts = &ref->u.c.component->ts;
    469  1.1  mrg 	      class_ref = ref;
    470  1.1  mrg 	      break;
    471  1.1  mrg 	    }
    472  1.1  mrg 
    473  1.1  mrg 	  if (ref->next == NULL)
    474  1.1  mrg 	    break;
    475  1.1  mrg 	}
    476  1.1  mrg       else
    477  1.1  mrg 	{
    478  1.1  mrg 	  if (ref->type == REF_ARRAY && ref->u.ar.type != AR_ELEMENT)
    479  1.1  mrg 	    array_ref = ref;
    480  1.1  mrg 
    481  1.1  mrg 	  if (ref->type == REF_COMPONENT
    482  1.1  mrg 	      && ref->u.c.component->ts.type == BT_CLASS)
    483  1.1  mrg 	    {
    484  1.1  mrg 	      /* Component to the right of a part reference with nonzero
    485  1.1  mrg 		 rank must not have the ALLOCATABLE attribute.  If attempts
    486  1.1  mrg 		 are made to reference such a component reference, an error
    487  1.1  mrg 		 results followed by an ICE.  */
    488  1.1  mrg 	      if (array_ref
    489  1.1  mrg 		  && CLASS_DATA (ref->u.c.component)->attr.allocatable)
    490  1.1  mrg 		return NULL;
    491  1.1  mrg 	      class_ref = ref;
    492  1.1  mrg 	    }
    493  1.1  mrg 	}
    494  1.1  mrg     }
    495  1.1  mrg 
    496  1.1  mrg   if (ts && *ts == NULL)
    497  1.1  mrg     return NULL;
    498  1.1  mrg 
    499  1.1  mrg   /* Remove and store all subsequent references after the
    500  1.1  mrg      CLASS reference.  */
    501  1.1  mrg   if (class_ref)
    502  1.1  mrg     {
    503  1.1  mrg       tail = class_ref->next;
    504  1.1  mrg       class_ref->next = NULL;
    505  1.1  mrg     }
    506  1.1  mrg   else if (e->symtree && e->symtree->n.sym->ts.type == BT_CLASS)
    507  1.1  mrg     {
    508  1.1  mrg       tail = e->ref;
    509  1.1  mrg       e->ref = NULL;
    510  1.1  mrg     }
    511  1.1  mrg 
    512  1.1  mrg   if (is_mold)
    513  1.1  mrg     base_expr = gfc_expr_to_initialize (e);
    514  1.1  mrg   else
    515  1.1  mrg     base_expr = gfc_copy_expr (e);
    516  1.1  mrg 
    517  1.1  mrg   /* Restore the original tail expression.  */
    518  1.1  mrg   if (class_ref)
    519  1.1  mrg     {
    520  1.1  mrg       gfc_free_ref_list (class_ref->next);
    521  1.1  mrg       class_ref->next = tail;
    522  1.1  mrg     }
    523  1.1  mrg   else if (e->symtree && e->symtree->n.sym->ts.type == BT_CLASS)
    524  1.1  mrg     {
    525  1.1  mrg       gfc_free_ref_list (e->ref);
    526  1.1  mrg       e->ref = tail;
    527  1.1  mrg     }
    528  1.1  mrg   return base_expr;
    529  1.1  mrg }
    530  1.1  mrg 
    531  1.1  mrg 
    532  1.1  mrg /* Reset the vptr to the declared type, e.g. after deallocation.  */
    533  1.1  mrg 
    534  1.1  mrg void
    535  1.1  mrg gfc_reset_vptr (stmtblock_t *block, gfc_expr *e)
    536  1.1  mrg {
    537  1.1  mrg   gfc_symbol *vtab;
    538  1.1  mrg   tree vptr;
    539  1.1  mrg   tree vtable;
    540  1.1  mrg   gfc_se se;
    541  1.1  mrg 
    542  1.1  mrg   /* Evaluate the expression and obtain the vptr from it.  */
    543  1.1  mrg   gfc_init_se (&se, NULL);
    544  1.1  mrg   if (e->rank)
    545  1.1  mrg     gfc_conv_expr_descriptor (&se, e);
    546  1.1  mrg   else
    547  1.1  mrg     gfc_conv_expr (&se, e);
    548  1.1  mrg   gfc_add_block_to_block (block, &se.pre);
    549  1.1  mrg   vptr = gfc_get_vptr_from_expr (se.expr);
    550  1.1  mrg 
    551  1.1  mrg   /* If a vptr is not found, we can do nothing more.  */
    552  1.1  mrg   if (vptr == NULL_TREE)
    553  1.1  mrg     return;
    554  1.1  mrg 
    555  1.1  mrg   if (UNLIMITED_POLY (e))
    556  1.1  mrg     gfc_add_modify (block, vptr, build_int_cst (TREE_TYPE (vptr), 0));
    557  1.1  mrg   else
    558  1.1  mrg     {
    559  1.1  mrg       /* Return the vptr to the address of the declared type.  */
    560  1.1  mrg       vtab = gfc_find_derived_vtab (e->ts.u.derived);
    561  1.1  mrg       vtable = vtab->backend_decl;
    562  1.1  mrg       if (vtable == NULL_TREE)
    563  1.1  mrg 	vtable = gfc_get_symbol_decl (vtab);
    564  1.1  mrg       vtable = gfc_build_addr_expr (NULL, vtable);
    565  1.1  mrg       vtable = fold_convert (TREE_TYPE (vptr), vtable);
    566  1.1  mrg       gfc_add_modify (block, vptr, vtable);
    567  1.1  mrg     }
    568  1.1  mrg }
    569  1.1  mrg 
    570  1.1  mrg 
    571  1.1  mrg /* Reset the len for unlimited polymorphic objects.  */
    572  1.1  mrg 
    573  1.1  mrg void
    574  1.1  mrg gfc_reset_len (stmtblock_t *block, gfc_expr *expr)
    575  1.1  mrg {
    576  1.1  mrg   gfc_expr *e;
    577  1.1  mrg   gfc_se se_len;
    578  1.1  mrg   e = gfc_find_and_cut_at_last_class_ref (expr);
    579  1.1  mrg   if (e == NULL)
    580  1.1  mrg     return;
    581  1.1  mrg   gfc_add_len_component (e);
    582  1.1  mrg   gfc_init_se (&se_len, NULL);
    583  1.1  mrg   gfc_conv_expr (&se_len, e);
    584  1.1  mrg   gfc_add_modify (block, se_len.expr,
    585  1.1  mrg 		  fold_convert (TREE_TYPE (se_len.expr), integer_zero_node));
    586  1.1  mrg   gfc_free_expr (e);
    587  1.1  mrg }
    588  1.1  mrg 
    589  1.1  mrg 
    590  1.1  mrg /* Obtain the last class reference in a gfc_expr. Return NULL_TREE if no class
    591  1.1  mrg    reference is found. Note that it is up to the caller to avoid using this
    592  1.1  mrg    for expressions other than variables.  */
    593  1.1  mrg 
    594  1.1  mrg tree
    595  1.1  mrg gfc_get_class_from_gfc_expr (gfc_expr *e)
    596  1.1  mrg {
    597  1.1  mrg   gfc_expr *class_expr;
    598  1.1  mrg   gfc_se cse;
    599  1.1  mrg   class_expr = gfc_find_and_cut_at_last_class_ref (e);
    600  1.1  mrg   if (class_expr == NULL)
    601  1.1  mrg     return NULL_TREE;
    602  1.1  mrg   gfc_init_se (&cse, NULL);
    603  1.1  mrg   gfc_conv_expr (&cse, class_expr);
    604  1.1  mrg   gfc_free_expr (class_expr);
    605  1.1  mrg   return cse.expr;
    606  1.1  mrg }
    607  1.1  mrg 
    608  1.1  mrg 
    609  1.1  mrg /* Obtain the last class reference in an expression.
    610  1.1  mrg    Return NULL_TREE if no class reference is found.  */
    611  1.1  mrg 
    612  1.1  mrg tree
    613  1.1  mrg gfc_get_class_from_expr (tree expr)
    614  1.1  mrg {
    615  1.1  mrg   tree tmp;
    616  1.1  mrg   tree type;
    617  1.1  mrg 
    618  1.1  mrg   for (tmp = expr; tmp; tmp = TREE_OPERAND (tmp, 0))
    619  1.1  mrg     {
    620  1.1  mrg       if (CONSTANT_CLASS_P (tmp))
    621  1.1  mrg 	return NULL_TREE;
    622  1.1  mrg 
    623  1.1  mrg       type = TREE_TYPE (tmp);
    624  1.1  mrg       while (type)
    625  1.1  mrg 	{
    626  1.1  mrg 	  if (GFC_CLASS_TYPE_P (type))
    627  1.1  mrg 	    return tmp;
    628  1.1  mrg 	  if (type != TYPE_CANONICAL (type))
    629  1.1  mrg 	    type = TYPE_CANONICAL (type);
    630  1.1  mrg 	  else
    631  1.1  mrg 	    type = NULL_TREE;
    632  1.1  mrg 	}
    633  1.1  mrg       if (VAR_P (tmp) || TREE_CODE (tmp) == PARM_DECL)
    634  1.1  mrg 	break;
    635  1.1  mrg     }
    636  1.1  mrg 
    637  1.1  mrg   if (POINTER_TYPE_P (TREE_TYPE (tmp)))
    638  1.1  mrg     tmp = build_fold_indirect_ref_loc (input_location, tmp);
    639  1.1  mrg 
    640  1.1  mrg   if (GFC_CLASS_TYPE_P (TREE_TYPE (tmp)))
    641  1.1  mrg     return tmp;
    642  1.1  mrg 
    643  1.1  mrg   return NULL_TREE;
    644  1.1  mrg }
    645  1.1  mrg 
    646  1.1  mrg 
    647  1.1  mrg /* Obtain the vptr of the last class reference in an expression.
    648  1.1  mrg    Return NULL_TREE if no class reference is found.  */
    649  1.1  mrg 
    650  1.1  mrg tree
    651  1.1  mrg gfc_get_vptr_from_expr (tree expr)
    652  1.1  mrg {
    653  1.1  mrg   tree tmp;
    654  1.1  mrg 
    655  1.1  mrg   tmp = gfc_get_class_from_expr (expr);
    656  1.1  mrg 
    657  1.1  mrg   if (tmp != NULL_TREE)
    658  1.1  mrg     return gfc_class_vptr_get (tmp);
    659  1.1  mrg 
    660  1.1  mrg   return NULL_TREE;
    661  1.1  mrg }
    662  1.1  mrg 
    663  1.1  mrg 
    664  1.1  mrg static void
    665  1.1  mrg class_array_data_assign (stmtblock_t *block, tree lhs_desc, tree rhs_desc,
    666  1.1  mrg 			 bool lhs_type)
    667  1.1  mrg {
    668  1.1  mrg   tree tmp, tmp2, type;
    669  1.1  mrg 
    670  1.1  mrg   gfc_conv_descriptor_data_set (block, lhs_desc,
    671  1.1  mrg 				gfc_conv_descriptor_data_get (rhs_desc));
    672  1.1  mrg   gfc_conv_descriptor_offset_set (block, lhs_desc,
    673  1.1  mrg 				  gfc_conv_descriptor_offset_get (rhs_desc));
    674  1.1  mrg 
    675  1.1  mrg   gfc_add_modify (block, gfc_conv_descriptor_dtype (lhs_desc),
    676  1.1  mrg 		  gfc_conv_descriptor_dtype (rhs_desc));
    677  1.1  mrg 
    678  1.1  mrg   /* Assign the dimension as range-ref.  */
    679  1.1  mrg   tmp = gfc_get_descriptor_dimension (lhs_desc);
    680  1.1  mrg   tmp2 = gfc_get_descriptor_dimension (rhs_desc);
    681  1.1  mrg 
    682  1.1  mrg   type = lhs_type ? TREE_TYPE (tmp) : TREE_TYPE (tmp2);
    683  1.1  mrg   tmp = build4_loc (input_location, ARRAY_RANGE_REF, type, tmp,
    684  1.1  mrg 		    gfc_index_zero_node, NULL_TREE, NULL_TREE);
    685  1.1  mrg   tmp2 = build4_loc (input_location, ARRAY_RANGE_REF, type, tmp2,
    686  1.1  mrg 		     gfc_index_zero_node, NULL_TREE, NULL_TREE);
    687  1.1  mrg   gfc_add_modify (block, tmp, tmp2);
    688  1.1  mrg }
    689  1.1  mrg 
    690  1.1  mrg 
    691  1.1  mrg /* Takes a derived type expression and returns the address of a temporary
    692  1.1  mrg    class object of the 'declared' type.  If vptr is not NULL, this is
    693  1.1  mrg    used for the temporary class object.
    694  1.1  mrg    optional_alloc_ptr is false when the dummy is neither allocatable
    695  1.1  mrg    nor a pointer; that's only relevant for the optional handling.
    696  1.1  mrg    The optional argument 'derived_array' is used to preserve the parmse
    697  1.1  mrg    expression for deallocation of allocatable components. Assumed rank
    698  1.1  mrg    formal arguments made this necessary.  */
    699  1.1  mrg void
    700  1.1  mrg gfc_conv_derived_to_class (gfc_se *parmse, gfc_expr *e,
    701  1.1  mrg 			   gfc_typespec class_ts, tree vptr, bool optional,
    702  1.1  mrg 			   bool optional_alloc_ptr,
    703  1.1  mrg 			   tree *derived_array)
    704  1.1  mrg {
    705  1.1  mrg   gfc_symbol *vtab;
    706  1.1  mrg   tree cond_optional = NULL_TREE;
    707  1.1  mrg   gfc_ss *ss;
    708  1.1  mrg   tree ctree;
    709  1.1  mrg   tree var;
    710  1.1  mrg   tree tmp;
    711  1.1  mrg   int dim;
    712  1.1  mrg 
    713  1.1  mrg   /* The derived type needs to be converted to a temporary
    714  1.1  mrg      CLASS object.  */
    715  1.1  mrg   tmp = gfc_typenode_for_spec (&class_ts);
    716  1.1  mrg   var = gfc_create_var (tmp, "class");
    717  1.1  mrg 
    718  1.1  mrg   /* Set the vptr.  */
    719  1.1  mrg   ctree =  gfc_class_vptr_get (var);
    720  1.1  mrg 
    721  1.1  mrg   if (vptr != NULL_TREE)
    722  1.1  mrg     {
    723  1.1  mrg       /* Use the dynamic vptr.  */
    724  1.1  mrg       tmp = vptr;
    725  1.1  mrg     }
    726  1.1  mrg   else
    727  1.1  mrg     {
    728  1.1  mrg       /* In this case the vtab corresponds to the derived type and the
    729  1.1  mrg 	 vptr must point to it.  */
    730  1.1  mrg       vtab = gfc_find_derived_vtab (e->ts.u.derived);
    731  1.1  mrg       gcc_assert (vtab);
    732  1.1  mrg       tmp = gfc_build_addr_expr (NULL_TREE, gfc_get_symbol_decl (vtab));
    733  1.1  mrg     }
    734  1.1  mrg   gfc_add_modify (&parmse->pre, ctree,
    735  1.1  mrg 		  fold_convert (TREE_TYPE (ctree), tmp));
    736  1.1  mrg 
    737  1.1  mrg   /* Now set the data field.  */
    738  1.1  mrg   ctree =  gfc_class_data_get (var);
    739  1.1  mrg 
    740  1.1  mrg   if (optional)
    741  1.1  mrg     cond_optional = gfc_conv_expr_present (e->symtree->n.sym);
    742  1.1  mrg 
    743  1.1  mrg   if (parmse->expr && POINTER_TYPE_P (TREE_TYPE (parmse->expr)))
    744  1.1  mrg     {
    745  1.1  mrg       /* If there is a ready made pointer to a derived type, use it
    746  1.1  mrg 	 rather than evaluating the expression again.  */
    747  1.1  mrg       tmp = fold_convert (TREE_TYPE (ctree), parmse->expr);
    748  1.1  mrg       gfc_add_modify (&parmse->pre, ctree, tmp);
    749  1.1  mrg     }
    750  1.1  mrg   else if (parmse->ss && parmse->ss->info && parmse->ss->info->useflags)
    751  1.1  mrg     {
    752  1.1  mrg       /* For an array reference in an elemental procedure call we need
    753  1.1  mrg 	 to retain the ss to provide the scalarized array reference.  */
    754  1.1  mrg       gfc_conv_expr_reference (parmse, e);
    755  1.1  mrg       tmp = fold_convert (TREE_TYPE (ctree), parmse->expr);
    756  1.1  mrg       if (optional)
    757  1.1  mrg 	tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp),
    758  1.1  mrg 			  cond_optional, tmp,
    759  1.1  mrg 			  fold_convert (TREE_TYPE (tmp), null_pointer_node));
    760  1.1  mrg       gfc_add_modify (&parmse->pre, ctree, tmp);
    761  1.1  mrg     }
    762  1.1  mrg   else
    763  1.1  mrg     {
    764  1.1  mrg       ss = gfc_walk_expr (e);
    765  1.1  mrg       if (ss == gfc_ss_terminator)
    766  1.1  mrg 	{
    767  1.1  mrg 	  parmse->ss = NULL;
    768  1.1  mrg 	  gfc_conv_expr_reference (parmse, e);
    769  1.1  mrg 
    770  1.1  mrg 	  /* Scalar to an assumed-rank array.  */
    771  1.1  mrg 	  if (class_ts.u.derived->components->as)
    772  1.1  mrg 	    {
    773  1.1  mrg 	      tree type;
    774  1.1  mrg 	      type = get_scalar_to_descriptor_type (parmse->expr,
    775  1.1  mrg 						    gfc_expr_attr (e));
    776  1.1  mrg 	      gfc_add_modify (&parmse->pre, gfc_conv_descriptor_dtype (ctree),
    777  1.1  mrg 			      gfc_get_dtype (type));
    778  1.1  mrg 	      if (optional)
    779  1.1  mrg 		parmse->expr = build3_loc (input_location, COND_EXPR,
    780  1.1  mrg 					   TREE_TYPE (parmse->expr),
    781  1.1  mrg 					   cond_optional, parmse->expr,
    782  1.1  mrg 					   fold_convert (TREE_TYPE (parmse->expr),
    783  1.1  mrg 							 null_pointer_node));
    784  1.1  mrg 	      gfc_conv_descriptor_data_set (&parmse->pre, ctree, parmse->expr);
    785  1.1  mrg 	    }
    786  1.1  mrg           else
    787  1.1  mrg 	    {
    788  1.1  mrg 	      tmp = fold_convert (TREE_TYPE (ctree), parmse->expr);
    789  1.1  mrg 	      if (optional)
    790  1.1  mrg 		tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp),
    791  1.1  mrg 				  cond_optional, tmp,
    792  1.1  mrg 				  fold_convert (TREE_TYPE (tmp),
    793  1.1  mrg 						null_pointer_node));
    794  1.1  mrg 	      gfc_add_modify (&parmse->pre, ctree, tmp);
    795  1.1  mrg 	    }
    796  1.1  mrg 	}
    797  1.1  mrg       else
    798  1.1  mrg 	{
    799  1.1  mrg 	  stmtblock_t block;
    800  1.1  mrg 	  gfc_init_block (&block);
    801  1.1  mrg 	  gfc_ref *ref;
    802  1.1  mrg 
    803  1.1  mrg 	  parmse->ss = ss;
    804  1.1  mrg 	  parmse->use_offset = 1;
    805  1.1  mrg 	  gfc_conv_expr_descriptor (parmse, e);
    806  1.1  mrg 
    807  1.1  mrg 	  /* Detect any array references with vector subscripts.  */
    808  1.1  mrg 	  for (ref = e->ref; ref; ref = ref->next)
    809  1.1  mrg 	    if (ref->type == REF_ARRAY
    810  1.1  mrg 		&& ref->u.ar.type != AR_ELEMENT
    811  1.1  mrg 		&& ref->u.ar.type != AR_FULL)
    812  1.1  mrg 	      {
    813  1.1  mrg 		for (dim = 0; dim < ref->u.ar.dimen; dim++)
    814  1.1  mrg 		  if (ref->u.ar.dimen_type[dim] == DIMEN_VECTOR)
    815  1.1  mrg 		    break;
    816  1.1  mrg 		if (dim < ref->u.ar.dimen)
    817  1.1  mrg 		  break;
    818  1.1  mrg 	      }
    819  1.1  mrg 
    820  1.1  mrg 	  /* Array references with vector subscripts and non-variable expressions
    821  1.1  mrg 	     need be converted to a one-based descriptor.  */
    822  1.1  mrg 	  if (ref || e->expr_type != EXPR_VARIABLE)
    823  1.1  mrg 	    {
    824  1.1  mrg 	      for (dim = 0; dim < e->rank; ++dim)
    825  1.1  mrg 		gfc_conv_shift_descriptor_lbound (&block, parmse->expr, dim,
    826  1.1  mrg 						  gfc_index_one_node);
    827  1.1  mrg 	    }
    828  1.1  mrg 
    829  1.1  mrg 	  if (e->rank != class_ts.u.derived->components->as->rank)
    830  1.1  mrg 	    {
    831  1.1  mrg 	      gcc_assert (class_ts.u.derived->components->as->type
    832  1.1  mrg 			  == AS_ASSUMED_RANK);
    833  1.1  mrg 	      if (derived_array
    834  1.1  mrg 		  && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (parmse->expr)))
    835  1.1  mrg 		{
    836  1.1  mrg 		  *derived_array = gfc_create_var (TREE_TYPE (parmse->expr),
    837  1.1  mrg 						   "array");
    838  1.1  mrg 		  gfc_add_modify (&block, *derived_array , parmse->expr);
    839  1.1  mrg 		}
    840  1.1  mrg 	      class_array_data_assign (&block, ctree, parmse->expr, false);
    841  1.1  mrg 	    }
    842  1.1  mrg 	  else
    843  1.1  mrg 	    {
    844  1.1  mrg 	      if (gfc_expr_attr (e).codimension)
    845  1.1  mrg 		parmse->expr = fold_build1_loc (input_location,
    846  1.1  mrg 						VIEW_CONVERT_EXPR,
    847  1.1  mrg 						TREE_TYPE (ctree),
    848  1.1  mrg 						parmse->expr);
    849  1.1  mrg 	      gfc_add_modify (&block, ctree, parmse->expr);
    850  1.1  mrg 	    }
    851  1.1  mrg 
    852  1.1  mrg 	  if (optional)
    853  1.1  mrg 	    {
    854  1.1  mrg 	      tmp = gfc_finish_block (&block);
    855  1.1  mrg 
    856  1.1  mrg 	      gfc_init_block (&block);
    857  1.1  mrg 	      gfc_conv_descriptor_data_set (&block, ctree, null_pointer_node);
    858  1.1  mrg 	      if (derived_array && *derived_array != NULL_TREE)
    859  1.1  mrg 		gfc_conv_descriptor_data_set (&block, *derived_array,
    860  1.1  mrg 					      null_pointer_node);
    861  1.1  mrg 
    862  1.1  mrg 	      tmp = build3_v (COND_EXPR, cond_optional, tmp,
    863  1.1  mrg 			      gfc_finish_block (&block));
    864  1.1  mrg 	      gfc_add_expr_to_block (&parmse->pre, tmp);
    865  1.1  mrg 	    }
    866  1.1  mrg 	  else
    867  1.1  mrg 	    gfc_add_block_to_block (&parmse->pre, &block);
    868  1.1  mrg 	}
    869  1.1  mrg     }
    870  1.1  mrg 
    871  1.1  mrg   if (class_ts.u.derived->components->ts.type == BT_DERIVED
    872  1.1  mrg       && class_ts.u.derived->components->ts.u.derived
    873  1.1  mrg 		 ->attr.unlimited_polymorphic)
    874  1.1  mrg     {
    875  1.1  mrg       /* Take care about initializing the _len component correctly.  */
    876  1.1  mrg       ctree = gfc_class_len_get (var);
    877  1.1  mrg       if (UNLIMITED_POLY (e))
    878  1.1  mrg 	{
    879  1.1  mrg 	  gfc_expr *len;
    880  1.1  mrg 	  gfc_se se;
    881  1.1  mrg 
    882  1.1  mrg 	  len = gfc_find_and_cut_at_last_class_ref (e);
    883  1.1  mrg 	  gfc_add_len_component (len);
    884  1.1  mrg 	  gfc_init_se (&se, NULL);
    885  1.1  mrg 	  gfc_conv_expr (&se, len);
    886  1.1  mrg 	  if (optional)
    887  1.1  mrg 	    tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (se.expr),
    888  1.1  mrg 			      cond_optional, se.expr,
    889  1.1  mrg 			      fold_convert (TREE_TYPE (se.expr),
    890  1.1  mrg 					    integer_zero_node));
    891  1.1  mrg 	  else
    892  1.1  mrg 	    tmp = se.expr;
    893  1.1  mrg 	  gfc_free_expr (len);
    894  1.1  mrg 	}
    895  1.1  mrg       else
    896  1.1  mrg 	tmp = integer_zero_node;
    897  1.1  mrg       gfc_add_modify (&parmse->pre, ctree, fold_convert (TREE_TYPE (ctree),
    898  1.1  mrg 							  tmp));
    899  1.1  mrg     }
    900  1.1  mrg   /* Pass the address of the class object.  */
    901  1.1  mrg   parmse->expr = gfc_build_addr_expr (NULL_TREE, var);
    902  1.1  mrg 
    903  1.1  mrg   if (optional && optional_alloc_ptr)
    904  1.1  mrg     parmse->expr = build3_loc (input_location, COND_EXPR,
    905  1.1  mrg 			       TREE_TYPE (parmse->expr),
    906  1.1  mrg 			       cond_optional, parmse->expr,
    907  1.1  mrg 			       fold_convert (TREE_TYPE (parmse->expr),
    908  1.1  mrg 					     null_pointer_node));
    909  1.1  mrg }
    910  1.1  mrg 
    911  1.1  mrg 
    912  1.1  mrg /* Create a new class container, which is required as scalar coarrays
    913  1.1  mrg    have an array descriptor while normal scalars haven't. Optionally,
    914  1.1  mrg    NULL pointer checks are added if the argument is OPTIONAL.  */
    915  1.1  mrg 
    916  1.1  mrg static void
    917  1.1  mrg class_scalar_coarray_to_class (gfc_se *parmse, gfc_expr *e,
    918  1.1  mrg 			       gfc_typespec class_ts, bool optional)
    919  1.1  mrg {
    920  1.1  mrg   tree var, ctree, tmp;
    921  1.1  mrg   stmtblock_t block;
    922  1.1  mrg   gfc_ref *ref;
    923  1.1  mrg   gfc_ref *class_ref;
    924  1.1  mrg 
    925  1.1  mrg   gfc_init_block (&block);
    926  1.1  mrg 
    927  1.1  mrg   class_ref = NULL;
    928  1.1  mrg   for (ref = e->ref; ref; ref = ref->next)
    929  1.1  mrg     {
    930  1.1  mrg       if (ref->type == REF_COMPONENT
    931  1.1  mrg 	    && ref->u.c.component->ts.type == BT_CLASS)
    932  1.1  mrg 	class_ref = ref;
    933  1.1  mrg     }
    934  1.1  mrg 
    935  1.1  mrg   if (class_ref == NULL
    936  1.1  mrg 	&& e->symtree && e->symtree->n.sym->ts.type == BT_CLASS)
    937  1.1  mrg     tmp = e->symtree->n.sym->backend_decl;
    938  1.1  mrg   else
    939  1.1  mrg     {
    940  1.1  mrg       /* Remove everything after the last class reference, convert the
    941  1.1  mrg 	 expression and then recover its tailend once more.  */
    942  1.1  mrg       gfc_se tmpse;
    943  1.1  mrg       ref = class_ref->next;
    944  1.1  mrg       class_ref->next = NULL;
    945  1.1  mrg       gfc_init_se (&tmpse, NULL);
    946  1.1  mrg       gfc_conv_expr (&tmpse, e);
    947  1.1  mrg       class_ref->next = ref;
    948  1.1  mrg       tmp = tmpse.expr;
    949  1.1  mrg     }
    950  1.1  mrg 
    951  1.1  mrg   var = gfc_typenode_for_spec (&class_ts);
    952  1.1  mrg   var = gfc_create_var (var, "class");
    953  1.1  mrg 
    954  1.1  mrg   ctree = gfc_class_vptr_get (var);
    955  1.1  mrg   gfc_add_modify (&block, ctree,
    956  1.1  mrg 		  fold_convert (TREE_TYPE (ctree), gfc_class_vptr_get (tmp)));
    957  1.1  mrg 
    958  1.1  mrg   ctree = gfc_class_data_get (var);
    959  1.1  mrg   tmp = gfc_conv_descriptor_data_get (gfc_class_data_get (tmp));
    960  1.1  mrg   gfc_add_modify (&block, ctree, fold_convert (TREE_TYPE (ctree), tmp));
    961  1.1  mrg 
    962  1.1  mrg   /* Pass the address of the class object.  */
    963  1.1  mrg   parmse->expr = gfc_build_addr_expr (NULL_TREE, var);
    964  1.1  mrg 
    965  1.1  mrg   if (optional)
    966  1.1  mrg     {
    967  1.1  mrg       tree cond = gfc_conv_expr_present (e->symtree->n.sym);
    968  1.1  mrg       tree tmp2;
    969  1.1  mrg 
    970  1.1  mrg       tmp = gfc_finish_block (&block);
    971  1.1  mrg 
    972  1.1  mrg       gfc_init_block (&block);
    973  1.1  mrg       tmp2 = gfc_class_data_get (var);
    974  1.1  mrg       gfc_add_modify (&block, tmp2, fold_convert (TREE_TYPE (tmp2),
    975  1.1  mrg 						  null_pointer_node));
    976  1.1  mrg       tmp2 = gfc_finish_block (&block);
    977  1.1  mrg 
    978  1.1  mrg       tmp = build3_loc (input_location, COND_EXPR, void_type_node,
    979  1.1  mrg 			cond, tmp, tmp2);
    980  1.1  mrg       gfc_add_expr_to_block (&parmse->pre, tmp);
    981  1.1  mrg     }
    982  1.1  mrg   else
    983  1.1  mrg     gfc_add_block_to_block (&parmse->pre, &block);
    984  1.1  mrg }
    985  1.1  mrg 
    986  1.1  mrg 
    987  1.1  mrg /* Takes an intrinsic type expression and returns the address of a temporary
    988  1.1  mrg    class object of the 'declared' type.  */
    989  1.1  mrg void
    990  1.1  mrg gfc_conv_intrinsic_to_class (gfc_se *parmse, gfc_expr *e,
    991  1.1  mrg 			     gfc_typespec class_ts)
    992  1.1  mrg {
    993  1.1  mrg   gfc_symbol *vtab;
    994  1.1  mrg   gfc_ss *ss;
    995  1.1  mrg   tree ctree;
    996  1.1  mrg   tree var;
    997  1.1  mrg   tree tmp;
    998  1.1  mrg   int dim;
    999  1.1  mrg 
   1000  1.1  mrg   /* The intrinsic type needs to be converted to a temporary
   1001  1.1  mrg      CLASS object.  */
   1002  1.1  mrg   tmp = gfc_typenode_for_spec (&class_ts);
   1003  1.1  mrg   var = gfc_create_var (tmp, "class");
   1004  1.1  mrg 
   1005  1.1  mrg   /* Set the vptr.  */
   1006  1.1  mrg   ctree = gfc_class_vptr_get (var);
   1007  1.1  mrg 
   1008  1.1  mrg   vtab = gfc_find_vtab (&e->ts);
   1009  1.1  mrg   gcc_assert (vtab);
   1010  1.1  mrg   tmp = gfc_build_addr_expr (NULL_TREE, gfc_get_symbol_decl (vtab));
   1011  1.1  mrg   gfc_add_modify (&parmse->pre, ctree,
   1012  1.1  mrg 		  fold_convert (TREE_TYPE (ctree), tmp));
   1013  1.1  mrg 
   1014  1.1  mrg   /* Now set the data field.  */
   1015  1.1  mrg   ctree = gfc_class_data_get (var);
   1016  1.1  mrg   if (parmse->ss && parmse->ss->info->useflags)
   1017  1.1  mrg     {
   1018  1.1  mrg       /* For an array reference in an elemental procedure call we need
   1019  1.1  mrg 	 to retain the ss to provide the scalarized array reference.  */
   1020  1.1  mrg       gfc_conv_expr_reference (parmse, e);
   1021  1.1  mrg       tmp = fold_convert (TREE_TYPE (ctree), parmse->expr);
   1022  1.1  mrg       gfc_add_modify (&parmse->pre, ctree, tmp);
   1023  1.1  mrg     }
   1024  1.1  mrg   else
   1025  1.1  mrg     {
   1026  1.1  mrg       ss = gfc_walk_expr (e);
   1027  1.1  mrg       if (ss == gfc_ss_terminator)
   1028  1.1  mrg 	{
   1029  1.1  mrg 	  parmse->ss = NULL;
   1030  1.1  mrg 	  gfc_conv_expr_reference (parmse, e);
   1031  1.1  mrg 	  if (class_ts.u.derived->components->as
   1032  1.1  mrg 	      && class_ts.u.derived->components->as->type == AS_ASSUMED_RANK)
   1033  1.1  mrg 	    {
   1034  1.1  mrg 	      tmp = gfc_conv_scalar_to_descriptor (parmse, parmse->expr,
   1035  1.1  mrg 						   gfc_expr_attr (e));
   1036  1.1  mrg 	      tmp = fold_build1_loc (input_location, VIEW_CONVERT_EXPR,
   1037  1.1  mrg 				     TREE_TYPE (ctree), tmp);
   1038  1.1  mrg 	    }
   1039  1.1  mrg 	  else
   1040  1.1  mrg 	      tmp = fold_convert (TREE_TYPE (ctree), parmse->expr);
   1041  1.1  mrg 	  gfc_add_modify (&parmse->pre, ctree, tmp);
   1042  1.1  mrg 	}
   1043  1.1  mrg       else
   1044  1.1  mrg 	{
   1045  1.1  mrg 	  parmse->ss = ss;
   1046  1.1  mrg 	  parmse->use_offset = 1;
   1047  1.1  mrg 	  gfc_conv_expr_descriptor (parmse, e);
   1048  1.1  mrg 
   1049  1.1  mrg 	  /* Array references with vector subscripts and non-variable expressions
   1050  1.1  mrg 	     need be converted to a one-based descriptor.  */
   1051  1.1  mrg 	  if (e->expr_type != EXPR_VARIABLE)
   1052  1.1  mrg 	    {
   1053  1.1  mrg 	      for (dim = 0; dim < e->rank; ++dim)
   1054  1.1  mrg 		gfc_conv_shift_descriptor_lbound (&parmse->pre, parmse->expr,
   1055  1.1  mrg 						  dim, gfc_index_one_node);
   1056  1.1  mrg 	    }
   1057  1.1  mrg 
   1058  1.1  mrg 	  if (class_ts.u.derived->components->as->rank != e->rank)
   1059  1.1  mrg 	    {
   1060  1.1  mrg 	      tmp = fold_build1_loc (input_location, VIEW_CONVERT_EXPR,
   1061  1.1  mrg 				     TREE_TYPE (ctree), parmse->expr);
   1062  1.1  mrg 	      gfc_add_modify (&parmse->pre, ctree, tmp);
   1063  1.1  mrg 	    }
   1064  1.1  mrg 	  else
   1065  1.1  mrg 	    gfc_add_modify (&parmse->pre, ctree, parmse->expr);
   1066  1.1  mrg 	}
   1067  1.1  mrg     }
   1068  1.1  mrg 
   1069  1.1  mrg   gcc_assert (class_ts.type == BT_CLASS);
   1070  1.1  mrg   if (class_ts.u.derived->components->ts.type == BT_DERIVED
   1071  1.1  mrg       && class_ts.u.derived->components->ts.u.derived
   1072  1.1  mrg 		 ->attr.unlimited_polymorphic)
   1073  1.1  mrg     {
   1074  1.1  mrg       ctree = gfc_class_len_get (var);
   1075  1.1  mrg       /* When the actual arg is a char array, then set the _len component of the
   1076  1.1  mrg 	 unlimited polymorphic entity to the length of the string.  */
   1077  1.1  mrg       if (e->ts.type == BT_CHARACTER)
   1078  1.1  mrg 	{
   1079  1.1  mrg 	  /* Start with parmse->string_length because this seems to be set to a
   1080  1.1  mrg 	   correct value more often.  */
   1081  1.1  mrg 	  if (parmse->string_length)
   1082  1.1  mrg 	    tmp = parmse->string_length;
   1083  1.1  mrg 	  /* When the string_length is not yet set, then try the backend_decl of
   1084  1.1  mrg 	   the cl.  */
   1085  1.1  mrg 	  else if (e->ts.u.cl->backend_decl)
   1086  1.1  mrg 	    tmp = e->ts.u.cl->backend_decl;
   1087  1.1  mrg 	  /* If both of the above approaches fail, then try to generate an
   1088  1.1  mrg 	   expression from the input, which is only feasible currently, when the
   1089  1.1  mrg 	   expression can be evaluated to a constant one.  */
   1090  1.1  mrg 	  else
   1091  1.1  mrg 	    {
   1092  1.1  mrg 	      /* Try to simplify the expression.  */
   1093  1.1  mrg 	      gfc_simplify_expr (e, 0);
   1094  1.1  mrg 	      if (e->expr_type == EXPR_CONSTANT && !e->ts.u.cl->resolved)
   1095  1.1  mrg 		{
   1096  1.1  mrg 		  /* Amazingly all data is present to compute the length of a
   1097  1.1  mrg 		   constant string, but the expression is not yet there.  */
   1098  1.1  mrg 		  e->ts.u.cl->length = gfc_get_constant_expr (BT_INTEGER,
   1099  1.1  mrg 							      gfc_charlen_int_kind,
   1100  1.1  mrg 							      &e->where);
   1101  1.1  mrg 		  mpz_set_ui (e->ts.u.cl->length->value.integer,
   1102  1.1  mrg 			      e->value.character.length);
   1103  1.1  mrg 		  gfc_conv_const_charlen (e->ts.u.cl);
   1104  1.1  mrg 		  e->ts.u.cl->resolved = 1;
   1105  1.1  mrg 		  tmp = e->ts.u.cl->backend_decl;
   1106  1.1  mrg 		}
   1107  1.1  mrg 	      else
   1108  1.1  mrg 		{
   1109  1.1  mrg 		  gfc_error ("Cannot compute the length of the char array "
   1110  1.1  mrg 			     "at %L.", &e->where);
   1111  1.1  mrg 		}
   1112  1.1  mrg 	    }
   1113  1.1  mrg 	}
   1114  1.1  mrg       else
   1115  1.1  mrg 	tmp = integer_zero_node;
   1116  1.1  mrg 
   1117  1.1  mrg       gfc_add_modify (&parmse->pre, ctree, fold_convert (TREE_TYPE (ctree), tmp));
   1118  1.1  mrg     }
   1119  1.1  mrg   else if (class_ts.type == BT_CLASS
   1120  1.1  mrg 	   && class_ts.u.derived->components
   1121  1.1  mrg 	   && class_ts.u.derived->components->ts.u
   1122  1.1  mrg 		.derived->attr.unlimited_polymorphic)
   1123  1.1  mrg     {
   1124  1.1  mrg       ctree = gfc_class_len_get (var);
   1125  1.1  mrg       gfc_add_modify (&parmse->pre, ctree,
   1126  1.1  mrg 		      fold_convert (TREE_TYPE (ctree),
   1127  1.1  mrg 				    integer_zero_node));
   1128  1.1  mrg     }
   1129  1.1  mrg   /* Pass the address of the class object.  */
   1130  1.1  mrg   parmse->expr = gfc_build_addr_expr (NULL_TREE, var);
   1131  1.1  mrg }
   1132  1.1  mrg 
   1133  1.1  mrg 
   1134  1.1  mrg /* Takes a scalarized class array expression and returns the
   1135  1.1  mrg    address of a temporary scalar class object of the 'declared'
   1136  1.1  mrg    type.
   1137  1.1  mrg    OOP-TODO: This could be improved by adding code that branched on
   1138  1.1  mrg    the dynamic type being the same as the declared type. In this case
   1139  1.1  mrg    the original class expression can be passed directly.
   1140  1.1  mrg    optional_alloc_ptr is false when the dummy is neither allocatable
   1141  1.1  mrg    nor a pointer; that's relevant for the optional handling.
   1142  1.1  mrg    Set copyback to true if class container's _data and _vtab pointers
   1143  1.1  mrg    might get modified.  */
   1144  1.1  mrg 
   1145  1.1  mrg void
   1146  1.1  mrg gfc_conv_class_to_class (gfc_se *parmse, gfc_expr *e, gfc_typespec class_ts,
   1147  1.1  mrg 			 bool elemental, bool copyback, bool optional,
   1148  1.1  mrg 		         bool optional_alloc_ptr)
   1149  1.1  mrg {
   1150  1.1  mrg   tree ctree;
   1151  1.1  mrg   tree var;
   1152  1.1  mrg   tree tmp;
   1153  1.1  mrg   tree vptr;
   1154  1.1  mrg   tree cond = NULL_TREE;
   1155  1.1  mrg   tree slen = NULL_TREE;
   1156  1.1  mrg   gfc_ref *ref;
   1157  1.1  mrg   gfc_ref *class_ref;
   1158  1.1  mrg   stmtblock_t block;
   1159  1.1  mrg   bool full_array = false;
   1160  1.1  mrg 
   1161  1.1  mrg   gfc_init_block (&block);
   1162  1.1  mrg 
   1163  1.1  mrg   class_ref = NULL;
   1164  1.1  mrg   for (ref = e->ref; ref; ref = ref->next)
   1165  1.1  mrg     {
   1166  1.1  mrg       if (ref->type == REF_COMPONENT
   1167  1.1  mrg 	    && ref->u.c.component->ts.type == BT_CLASS)
   1168  1.1  mrg 	class_ref = ref;
   1169  1.1  mrg 
   1170  1.1  mrg       if (ref->next == NULL)
   1171  1.1  mrg 	break;
   1172  1.1  mrg     }
   1173  1.1  mrg 
   1174  1.1  mrg   if ((ref == NULL || class_ref == ref)
   1175  1.1  mrg       && !(gfc_is_class_array_function (e) && parmse->class_vptr != NULL_TREE)
   1176  1.1  mrg       && (!class_ts.u.derived->components->as
   1177  1.1  mrg 	  || class_ts.u.derived->components->as->rank != -1))
   1178  1.1  mrg     return;
   1179  1.1  mrg 
   1180  1.1  mrg   /* Test for FULL_ARRAY.  */
   1181  1.1  mrg   if (e->rank == 0
   1182  1.1  mrg       && ((gfc_expr_attr (e).codimension && gfc_expr_attr (e).dimension)
   1183  1.1  mrg 	  || (class_ts.u.derived->components->as
   1184  1.1  mrg 	      && class_ts.u.derived->components->as->type == AS_ASSUMED_RANK)))
   1185  1.1  mrg     full_array = true;
   1186  1.1  mrg   else
   1187  1.1  mrg     gfc_is_class_array_ref (e, &full_array);
   1188  1.1  mrg 
   1189  1.1  mrg   /* The derived type needs to be converted to a temporary
   1190  1.1  mrg      CLASS object.  */
   1191  1.1  mrg   tmp = gfc_typenode_for_spec (&class_ts);
   1192  1.1  mrg   var = gfc_create_var (tmp, "class");
   1193  1.1  mrg 
   1194  1.1  mrg   /* Set the data.  */
   1195  1.1  mrg   ctree = gfc_class_data_get (var);
   1196  1.1  mrg   if (class_ts.u.derived->components->as
   1197  1.1  mrg       && e->rank != class_ts.u.derived->components->as->rank)
   1198  1.1  mrg     {
   1199  1.1  mrg       if (e->rank == 0)
   1200  1.1  mrg 	{
   1201  1.1  mrg 	  tree type = get_scalar_to_descriptor_type (parmse->expr,
   1202  1.1  mrg 						     gfc_expr_attr (e));
   1203  1.1  mrg 	  gfc_add_modify (&block, gfc_conv_descriptor_dtype (ctree),
   1204  1.1  mrg 			  gfc_get_dtype (type));
   1205  1.1  mrg 
   1206  1.1  mrg 	  tmp = gfc_class_data_get (parmse->expr);
   1207  1.1  mrg 	  if (!POINTER_TYPE_P (TREE_TYPE (tmp)))
   1208  1.1  mrg 	    tmp = gfc_build_addr_expr (NULL_TREE, tmp);
   1209  1.1  mrg 
   1210  1.1  mrg 	  gfc_conv_descriptor_data_set (&block, ctree, tmp);
   1211  1.1  mrg 	}
   1212  1.1  mrg       else
   1213  1.1  mrg 	class_array_data_assign (&block, ctree, parmse->expr, false);
   1214  1.1  mrg     }
   1215  1.1  mrg   else
   1216  1.1  mrg     {
   1217  1.1  mrg       if (TREE_TYPE (parmse->expr) != TREE_TYPE (ctree))
   1218  1.1  mrg 	parmse->expr = fold_build1_loc (input_location, VIEW_CONVERT_EXPR,
   1219  1.1  mrg 					TREE_TYPE (ctree), parmse->expr);
   1220  1.1  mrg       gfc_add_modify (&block, ctree, parmse->expr);
   1221  1.1  mrg     }
   1222  1.1  mrg 
   1223  1.1  mrg   /* Return the data component, except in the case of scalarized array
   1224  1.1  mrg      references, where nullification of the cannot occur and so there
   1225  1.1  mrg      is no need.  */
   1226  1.1  mrg   if (!elemental && full_array && copyback)
   1227  1.1  mrg     {
   1228  1.1  mrg       if (class_ts.u.derived->components->as
   1229  1.1  mrg 	  && e->rank != class_ts.u.derived->components->as->rank)
   1230  1.1  mrg 	{
   1231  1.1  mrg 	  if (e->rank == 0)
   1232  1.1  mrg 	    {
   1233  1.1  mrg 	      tmp = gfc_class_data_get (parmse->expr);
   1234  1.1  mrg 	      gfc_add_modify (&parmse->post, tmp,
   1235  1.1  mrg 			      fold_convert (TREE_TYPE (tmp),
   1236  1.1  mrg 					 gfc_conv_descriptor_data_get (ctree)));
   1237  1.1  mrg 	    }
   1238  1.1  mrg 	  else
   1239  1.1  mrg 	    class_array_data_assign (&parmse->post, parmse->expr, ctree, true);
   1240  1.1  mrg 	}
   1241  1.1  mrg       else
   1242  1.1  mrg 	gfc_add_modify (&parmse->post, parmse->expr, ctree);
   1243  1.1  mrg     }
   1244  1.1  mrg 
   1245  1.1  mrg   /* Set the vptr.  */
   1246  1.1  mrg   ctree = gfc_class_vptr_get (var);
   1247  1.1  mrg 
   1248  1.1  mrg   /* The vptr is the second field of the actual argument.
   1249  1.1  mrg      First we have to find the corresponding class reference.  */
   1250  1.1  mrg 
   1251  1.1  mrg   tmp = NULL_TREE;
   1252  1.1  mrg   if (gfc_is_class_array_function (e)
   1253  1.1  mrg       && parmse->class_vptr != NULL_TREE)
   1254  1.1  mrg     tmp = parmse->class_vptr;
   1255  1.1  mrg   else if (class_ref == NULL
   1256  1.1  mrg 	   && e->symtree && e->symtree->n.sym->ts.type == BT_CLASS)
   1257  1.1  mrg     {
   1258  1.1  mrg       tmp = e->symtree->n.sym->backend_decl;
   1259  1.1  mrg 
   1260  1.1  mrg       if (TREE_CODE (tmp) == FUNCTION_DECL)
   1261  1.1  mrg 	tmp = gfc_get_fake_result_decl (e->symtree->n.sym, 0);
   1262  1.1  mrg 
   1263  1.1  mrg       if (DECL_LANG_SPECIFIC (tmp) && GFC_DECL_SAVED_DESCRIPTOR (tmp))
   1264  1.1  mrg 	tmp = GFC_DECL_SAVED_DESCRIPTOR (tmp);
   1265  1.1  mrg 
   1266  1.1  mrg       slen = build_zero_cst (size_type_node);
   1267  1.1  mrg     }
   1268  1.1  mrg   else
   1269  1.1  mrg     {
   1270  1.1  mrg       /* Remove everything after the last class reference, convert the
   1271  1.1  mrg 	 expression and then recover its tailend once more.  */
   1272  1.1  mrg       gfc_se tmpse;
   1273  1.1  mrg       ref = class_ref->next;
   1274  1.1  mrg       class_ref->next = NULL;
   1275  1.1  mrg       gfc_init_se (&tmpse, NULL);
   1276  1.1  mrg       gfc_conv_expr (&tmpse, e);
   1277  1.1  mrg       class_ref->next = ref;
   1278  1.1  mrg       tmp = tmpse.expr;
   1279  1.1  mrg       slen = tmpse.string_length;
   1280  1.1  mrg     }
   1281  1.1  mrg 
   1282  1.1  mrg   gcc_assert (tmp != NULL_TREE);
   1283  1.1  mrg 
   1284  1.1  mrg   /* Dereference if needs be.  */
   1285  1.1  mrg   if (TREE_CODE (TREE_TYPE (tmp)) == REFERENCE_TYPE)
   1286  1.1  mrg     tmp = build_fold_indirect_ref_loc (input_location, tmp);
   1287  1.1  mrg 
   1288  1.1  mrg   if (!(gfc_is_class_array_function (e) && parmse->class_vptr))
   1289  1.1  mrg     vptr = gfc_class_vptr_get (tmp);
   1290  1.1  mrg   else
   1291  1.1  mrg     vptr = tmp;
   1292  1.1  mrg 
   1293  1.1  mrg   gfc_add_modify (&block, ctree,
   1294  1.1  mrg 		  fold_convert (TREE_TYPE (ctree), vptr));
   1295  1.1  mrg 
   1296  1.1  mrg   /* Return the vptr component, except in the case of scalarized array
   1297  1.1  mrg      references, where the dynamic type cannot change.  */
   1298  1.1  mrg   if (!elemental && full_array && copyback)
   1299  1.1  mrg     gfc_add_modify (&parmse->post, vptr,
   1300  1.1  mrg 		    fold_convert (TREE_TYPE (vptr), ctree));
   1301  1.1  mrg 
   1302  1.1  mrg   /* For unlimited polymorphic objects also set the _len component.  */
   1303  1.1  mrg   if (class_ts.type == BT_CLASS
   1304  1.1  mrg       && class_ts.u.derived->components
   1305  1.1  mrg       && class_ts.u.derived->components->ts.u
   1306  1.1  mrg 		      .derived->attr.unlimited_polymorphic)
   1307  1.1  mrg     {
   1308  1.1  mrg       ctree = gfc_class_len_get (var);
   1309  1.1  mrg       if (UNLIMITED_POLY (e))
   1310  1.1  mrg 	tmp = gfc_class_len_get (tmp);
   1311  1.1  mrg       else if (e->ts.type == BT_CHARACTER)
   1312  1.1  mrg 	{
   1313  1.1  mrg 	  gcc_assert (slen != NULL_TREE);
   1314  1.1  mrg 	  tmp = slen;
   1315  1.1  mrg 	}
   1316  1.1  mrg       else
   1317  1.1  mrg 	tmp = build_zero_cst (size_type_node);
   1318  1.1  mrg       gfc_add_modify (&parmse->pre, ctree,
   1319  1.1  mrg 		      fold_convert (TREE_TYPE (ctree), tmp));
   1320  1.1  mrg 
   1321  1.1  mrg       /* Return the len component, except in the case of scalarized array
   1322  1.1  mrg 	references, where the dynamic type cannot change.  */
   1323  1.1  mrg       if (!elemental && full_array && copyback
   1324  1.1  mrg 	  && (UNLIMITED_POLY (e) || VAR_P (tmp)))
   1325  1.1  mrg 	  gfc_add_modify (&parmse->post, tmp,
   1326  1.1  mrg 			  fold_convert (TREE_TYPE (tmp), ctree));
   1327  1.1  mrg     }
   1328  1.1  mrg 
   1329  1.1  mrg   if (optional)
   1330  1.1  mrg     {
   1331  1.1  mrg       tree tmp2;
   1332  1.1  mrg 
   1333  1.1  mrg       cond = gfc_conv_expr_present (e->symtree->n.sym);
   1334  1.1  mrg       /* parmse->pre may contain some preparatory instructions for the
   1335  1.1  mrg  	 temporary array descriptor.  Those may only be executed when the
   1336  1.1  mrg 	 optional argument is set, therefore add parmse->pre's instructions
   1337  1.1  mrg 	 to block, which is later guarded by an if (optional_arg_given).  */
   1338  1.1  mrg       gfc_add_block_to_block (&parmse->pre, &block);
   1339  1.1  mrg       block.head = parmse->pre.head;
   1340  1.1  mrg       parmse->pre.head = NULL_TREE;
   1341  1.1  mrg       tmp = gfc_finish_block (&block);
   1342  1.1  mrg 
   1343  1.1  mrg       if (optional_alloc_ptr)
   1344  1.1  mrg 	tmp2 = build_empty_stmt (input_location);
   1345  1.1  mrg       else
   1346  1.1  mrg 	{
   1347  1.1  mrg 	  gfc_init_block (&block);
   1348  1.1  mrg 
   1349  1.1  mrg 	  tmp2 = gfc_conv_descriptor_data_get (gfc_class_data_get (var));
   1350  1.1  mrg 	  gfc_add_modify (&block, tmp2, fold_convert (TREE_TYPE (tmp2),
   1351  1.1  mrg 						      null_pointer_node));
   1352  1.1  mrg 	  tmp2 = gfc_finish_block (&block);
   1353  1.1  mrg 	}
   1354  1.1  mrg 
   1355  1.1  mrg       tmp = build3_loc (input_location, COND_EXPR, void_type_node,
   1356  1.1  mrg 			cond, tmp, tmp2);
   1357  1.1  mrg       gfc_add_expr_to_block (&parmse->pre, tmp);
   1358  1.1  mrg     }
   1359  1.1  mrg   else
   1360  1.1  mrg     gfc_add_block_to_block (&parmse->pre, &block);
   1361  1.1  mrg 
   1362  1.1  mrg   /* Pass the address of the class object.  */
   1363  1.1  mrg   parmse->expr = gfc_build_addr_expr (NULL_TREE, var);
   1364  1.1  mrg 
   1365  1.1  mrg   if (optional && optional_alloc_ptr)
   1366  1.1  mrg     parmse->expr = build3_loc (input_location, COND_EXPR,
   1367  1.1  mrg 			       TREE_TYPE (parmse->expr),
   1368  1.1  mrg 			       cond, parmse->expr,
   1369  1.1  mrg 			       fold_convert (TREE_TYPE (parmse->expr),
   1370  1.1  mrg 					     null_pointer_node));
   1371  1.1  mrg }
   1372  1.1  mrg 
   1373  1.1  mrg 
   1374  1.1  mrg /* Given a class array declaration and an index, returns the address
   1375  1.1  mrg    of the referenced element.  */
   1376  1.1  mrg 
   1377  1.1  mrg static tree
   1378  1.1  mrg gfc_get_class_array_ref (tree index, tree class_decl, tree data_comp,
   1379  1.1  mrg 			 bool unlimited)
   1380  1.1  mrg {
   1381  1.1  mrg   tree data, size, tmp, ctmp, offset, ptr;
   1382  1.1  mrg 
   1383  1.1  mrg   data = data_comp != NULL_TREE ? data_comp :
   1384  1.1  mrg 				  gfc_class_data_get (class_decl);
   1385  1.1  mrg   size = gfc_class_vtab_size_get (class_decl);
   1386  1.1  mrg 
   1387  1.1  mrg   if (unlimited)
   1388  1.1  mrg     {
   1389  1.1  mrg       tmp = fold_convert (gfc_array_index_type,
   1390  1.1  mrg 			  gfc_class_len_get (class_decl));
   1391  1.1  mrg       ctmp = fold_build2_loc (input_location, MULT_EXPR,
   1392  1.1  mrg 			      gfc_array_index_type, size, tmp);
   1393  1.1  mrg       tmp = fold_build2_loc (input_location, GT_EXPR,
   1394  1.1  mrg 			     logical_type_node, tmp,
   1395  1.1  mrg 			     build_zero_cst (TREE_TYPE (tmp)));
   1396  1.1  mrg       size = fold_build3_loc (input_location, COND_EXPR,
   1397  1.1  mrg 			      gfc_array_index_type, tmp, ctmp, size);
   1398  1.1  mrg     }
   1399  1.1  mrg 
   1400  1.1  mrg   offset = fold_build2_loc (input_location, MULT_EXPR,
   1401  1.1  mrg 			    gfc_array_index_type,
   1402  1.1  mrg 			    index, size);
   1403  1.1  mrg 
   1404  1.1  mrg   data = gfc_conv_descriptor_data_get (data);
   1405  1.1  mrg   ptr = fold_convert (pvoid_type_node, data);
   1406  1.1  mrg   ptr = fold_build_pointer_plus_loc (input_location, ptr, offset);
   1407  1.1  mrg   return fold_convert (TREE_TYPE (data), ptr);
   1408  1.1  mrg }
   1409  1.1  mrg 
   1410  1.1  mrg 
   1411  1.1  mrg /* Copies one class expression to another, assuming that if either
   1412  1.1  mrg    'to' or 'from' are arrays they are packed.  Should 'from' be
   1413  1.1  mrg    NULL_TREE, the initialization expression for 'to' is used, assuming
   1414  1.1  mrg    that the _vptr is set.  */
   1415  1.1  mrg 
   1416  1.1  mrg tree
   1417  1.1  mrg gfc_copy_class_to_class (tree from, tree to, tree nelems, bool unlimited)
   1418  1.1  mrg {
   1419  1.1  mrg   tree fcn;
   1420  1.1  mrg   tree fcn_type;
   1421  1.1  mrg   tree from_data;
   1422  1.1  mrg   tree from_len;
   1423  1.1  mrg   tree to_data;
   1424  1.1  mrg   tree to_len;
   1425  1.1  mrg   tree to_ref;
   1426  1.1  mrg   tree from_ref;
   1427  1.1  mrg   vec<tree, va_gc> *args;
   1428  1.1  mrg   tree tmp;
   1429  1.1  mrg   tree stdcopy;
   1430  1.1  mrg   tree extcopy;
   1431  1.1  mrg   tree index;
   1432  1.1  mrg   bool is_from_desc = false, is_to_class = false;
   1433  1.1  mrg 
   1434  1.1  mrg   args = NULL;
   1435  1.1  mrg   /* To prevent warnings on uninitialized variables.  */
   1436  1.1  mrg   from_len = to_len = NULL_TREE;
   1437  1.1  mrg 
   1438  1.1  mrg   if (from != NULL_TREE)
   1439  1.1  mrg     fcn = gfc_class_vtab_copy_get (from);
   1440  1.1  mrg   else
   1441  1.1  mrg     fcn = gfc_class_vtab_copy_get (to);
   1442  1.1  mrg 
   1443  1.1  mrg   fcn_type = TREE_TYPE (TREE_TYPE (fcn));
   1444  1.1  mrg 
   1445  1.1  mrg   if (from != NULL_TREE)
   1446  1.1  mrg     {
   1447  1.1  mrg       is_from_desc = GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (from));
   1448  1.1  mrg       if (is_from_desc)
   1449  1.1  mrg 	{
   1450  1.1  mrg 	  from_data = from;
   1451  1.1  mrg 	  from = GFC_DECL_SAVED_DESCRIPTOR (from);
   1452  1.1  mrg 	}
   1453  1.1  mrg       else
   1454  1.1  mrg 	{
   1455  1.1  mrg 	  /* Check that from is a class.  When the class is part of a coarray,
   1456  1.1  mrg 	     then from is a common pointer and is to be used as is.  */
   1457  1.1  mrg 	  tmp = POINTER_TYPE_P (TREE_TYPE (from))
   1458  1.1  mrg 	      ? build_fold_indirect_ref (from) : from;
   1459  1.1  mrg 	  from_data =
   1460  1.1  mrg 	      (GFC_CLASS_TYPE_P (TREE_TYPE (tmp))
   1461  1.1  mrg 	       || (DECL_P (tmp) && GFC_DECL_CLASS (tmp)))
   1462  1.1  mrg 	      ? gfc_class_data_get (from) : from;
   1463  1.1  mrg 	  is_from_desc = GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (from_data));
   1464  1.1  mrg 	}
   1465  1.1  mrg      }
   1466  1.1  mrg   else
   1467  1.1  mrg     from_data = gfc_class_vtab_def_init_get (to);
   1468  1.1  mrg 
   1469  1.1  mrg   if (unlimited)
   1470  1.1  mrg     {
   1471  1.1  mrg       if (from != NULL_TREE && unlimited)
   1472  1.1  mrg 	from_len = gfc_class_len_or_zero_get (from);
   1473  1.1  mrg       else
   1474  1.1  mrg 	from_len = build_zero_cst (size_type_node);
   1475  1.1  mrg     }
   1476  1.1  mrg 
   1477  1.1  mrg   if (GFC_CLASS_TYPE_P (TREE_TYPE (to)))
   1478  1.1  mrg     {
   1479  1.1  mrg       is_to_class = true;
   1480  1.1  mrg       to_data = gfc_class_data_get (to);
   1481  1.1  mrg       if (unlimited)
   1482  1.1  mrg 	to_len = gfc_class_len_get (to);
   1483  1.1  mrg     }
   1484  1.1  mrg   else
   1485  1.1  mrg     /* When to is a BT_DERIVED and not a BT_CLASS, then to_data == to.  */
   1486  1.1  mrg     to_data = to;
   1487  1.1  mrg 
   1488  1.1  mrg   if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (to_data)))
   1489  1.1  mrg     {
   1490  1.1  mrg       stmtblock_t loopbody;
   1491  1.1  mrg       stmtblock_t body;
   1492  1.1  mrg       stmtblock_t ifbody;
   1493  1.1  mrg       gfc_loopinfo loop;
   1494  1.1  mrg       tree orig_nelems = nelems; /* Needed for bounds check.  */
   1495  1.1  mrg 
   1496  1.1  mrg       gfc_init_block (&body);
   1497  1.1  mrg       tmp = fold_build2_loc (input_location, MINUS_EXPR,
   1498  1.1  mrg 			     gfc_array_index_type, nelems,
   1499  1.1  mrg 			     gfc_index_one_node);
   1500  1.1  mrg       nelems = gfc_evaluate_now (tmp, &body);
   1501  1.1  mrg       index = gfc_create_var (gfc_array_index_type, "S");
   1502  1.1  mrg 
   1503  1.1  mrg       if (is_from_desc)
   1504  1.1  mrg 	{
   1505  1.1  mrg 	  from_ref = gfc_get_class_array_ref (index, from, from_data,
   1506  1.1  mrg 					      unlimited);
   1507  1.1  mrg 	  vec_safe_push (args, from_ref);
   1508  1.1  mrg 	}
   1509  1.1  mrg       else
   1510  1.1  mrg         vec_safe_push (args, from_data);
   1511  1.1  mrg 
   1512  1.1  mrg       if (is_to_class)
   1513  1.1  mrg 	to_ref = gfc_get_class_array_ref (index, to, to_data, unlimited);
   1514  1.1  mrg       else
   1515  1.1  mrg 	{
   1516  1.1  mrg 	  tmp = gfc_conv_array_data (to);
   1517  1.1  mrg 	  tmp = build_fold_indirect_ref_loc (input_location, tmp);
   1518  1.1  mrg 	  to_ref = gfc_build_addr_expr (NULL_TREE,
   1519  1.1  mrg 					gfc_build_array_ref (tmp, index, to));
   1520  1.1  mrg 	}
   1521  1.1  mrg       vec_safe_push (args, to_ref);
   1522  1.1  mrg 
   1523  1.1  mrg       /* Add bounds check.  */
   1524  1.1  mrg       if ((gfc_option.rtcheck & GFC_RTCHECK_BOUNDS) > 0 && is_from_desc)
   1525  1.1  mrg 	{
   1526  1.1  mrg 	  char *msg;
   1527  1.1  mrg 	  const char *name = "<<unknown>>";
   1528  1.1  mrg 	  tree from_len;
   1529  1.1  mrg 
   1530  1.1  mrg 	  if (DECL_P (to))
   1531  1.1  mrg 	    name = (const char *)(DECL_NAME (to)->identifier.id.str);
   1532  1.1  mrg 
   1533  1.1  mrg 	  from_len = gfc_conv_descriptor_size (from_data, 1);
   1534  1.1  mrg 	  from_len = fold_convert (TREE_TYPE (orig_nelems), from_len);
   1535  1.1  mrg 	  tmp = fold_build2_loc (input_location, NE_EXPR,
   1536  1.1  mrg 				  logical_type_node, from_len, orig_nelems);
   1537  1.1  mrg 	  msg = xasprintf ("Array bound mismatch for dimension %d "
   1538  1.1  mrg 			   "of array '%s' (%%ld/%%ld)",
   1539  1.1  mrg 			   1, name);
   1540  1.1  mrg 
   1541  1.1  mrg 	  gfc_trans_runtime_check (true, false, tmp, &body,
   1542  1.1  mrg 				   &gfc_current_locus, msg,
   1543  1.1  mrg 			     fold_convert (long_integer_type_node, orig_nelems),
   1544  1.1  mrg 			       fold_convert (long_integer_type_node, from_len));
   1545  1.1  mrg 
   1546  1.1  mrg 	  free (msg);
   1547  1.1  mrg 	}
   1548  1.1  mrg 
   1549  1.1  mrg       tmp = build_call_vec (fcn_type, fcn, args);
   1550  1.1  mrg 
   1551  1.1  mrg       /* Build the body of the loop.  */
   1552  1.1  mrg       gfc_init_block (&loopbody);
   1553  1.1  mrg       gfc_add_expr_to_block (&loopbody, tmp);
   1554  1.1  mrg 
   1555  1.1  mrg       /* Build the loop and return.  */
   1556  1.1  mrg       gfc_init_loopinfo (&loop);
   1557  1.1  mrg       loop.dimen = 1;
   1558  1.1  mrg       loop.from[0] = gfc_index_zero_node;
   1559  1.1  mrg       loop.loopvar[0] = index;
   1560  1.1  mrg       loop.to[0] = nelems;
   1561  1.1  mrg       gfc_trans_scalarizing_loops (&loop, &loopbody);
   1562  1.1  mrg       gfc_init_block (&ifbody);
   1563  1.1  mrg       gfc_add_block_to_block (&ifbody, &loop.pre);
   1564  1.1  mrg       stdcopy = gfc_finish_block (&ifbody);
   1565  1.1  mrg       /* In initialization mode from_len is a constant zero.  */
   1566  1.1  mrg       if (unlimited && !integer_zerop (from_len))
   1567  1.1  mrg 	{
   1568  1.1  mrg 	  vec_safe_push (args, from_len);
   1569  1.1  mrg 	  vec_safe_push (args, to_len);
   1570  1.1  mrg 	  tmp = build_call_vec (fcn_type, fcn, args);
   1571  1.1  mrg 	  /* Build the body of the loop.  */
   1572  1.1  mrg 	  gfc_init_block (&loopbody);
   1573  1.1  mrg 	  gfc_add_expr_to_block (&loopbody, tmp);
   1574  1.1  mrg 
   1575  1.1  mrg 	  /* Build the loop and return.  */
   1576  1.1  mrg 	  gfc_init_loopinfo (&loop);
   1577  1.1  mrg 	  loop.dimen = 1;
   1578  1.1  mrg 	  loop.from[0] = gfc_index_zero_node;
   1579  1.1  mrg 	  loop.loopvar[0] = index;
   1580  1.1  mrg 	  loop.to[0] = nelems;
   1581  1.1  mrg 	  gfc_trans_scalarizing_loops (&loop, &loopbody);
   1582  1.1  mrg 	  gfc_init_block (&ifbody);
   1583  1.1  mrg 	  gfc_add_block_to_block (&ifbody, &loop.pre);
   1584  1.1  mrg 	  extcopy = gfc_finish_block (&ifbody);
   1585  1.1  mrg 
   1586  1.1  mrg 	  tmp = fold_build2_loc (input_location, GT_EXPR,
   1587  1.1  mrg 				 logical_type_node, from_len,
   1588  1.1  mrg 				 build_zero_cst (TREE_TYPE (from_len)));
   1589  1.1  mrg 	  tmp = fold_build3_loc (input_location, COND_EXPR,
   1590  1.1  mrg 				 void_type_node, tmp, extcopy, stdcopy);
   1591  1.1  mrg 	  gfc_add_expr_to_block (&body, tmp);
   1592  1.1  mrg 	  tmp = gfc_finish_block (&body);
   1593  1.1  mrg 	}
   1594  1.1  mrg       else
   1595  1.1  mrg 	{
   1596  1.1  mrg 	  gfc_add_expr_to_block (&body, stdcopy);
   1597  1.1  mrg 	  tmp = gfc_finish_block (&body);
   1598  1.1  mrg 	}
   1599  1.1  mrg       gfc_cleanup_loop (&loop);
   1600  1.1  mrg     }
   1601  1.1  mrg   else
   1602  1.1  mrg     {
   1603  1.1  mrg       gcc_assert (!is_from_desc);
   1604  1.1  mrg       vec_safe_push (args, from_data);
   1605  1.1  mrg       vec_safe_push (args, to_data);
   1606  1.1  mrg       stdcopy = build_call_vec (fcn_type, fcn, args);
   1607  1.1  mrg 
   1608  1.1  mrg       /* In initialization mode from_len is a constant zero.  */
   1609  1.1  mrg       if (unlimited && !integer_zerop (from_len))
   1610  1.1  mrg 	{
   1611  1.1  mrg 	  vec_safe_push (args, from_len);
   1612  1.1  mrg 	  vec_safe_push (args, to_len);
   1613  1.1  mrg 	  extcopy = build_call_vec (fcn_type, unshare_expr (fcn), args);
   1614  1.1  mrg 	  tmp = fold_build2_loc (input_location, GT_EXPR,
   1615  1.1  mrg 				 logical_type_node, from_len,
   1616  1.1  mrg 				 build_zero_cst (TREE_TYPE (from_len)));
   1617  1.1  mrg 	  tmp = fold_build3_loc (input_location, COND_EXPR,
   1618  1.1  mrg 				 void_type_node, tmp, extcopy, stdcopy);
   1619  1.1  mrg 	}
   1620  1.1  mrg       else
   1621  1.1  mrg 	tmp = stdcopy;
   1622  1.1  mrg     }
   1623  1.1  mrg 
   1624  1.1  mrg   /* Only copy _def_init to to_data, when it is not a NULL-pointer.  */
   1625  1.1  mrg   if (from == NULL_TREE)
   1626  1.1  mrg     {
   1627  1.1  mrg       tree cond;
   1628  1.1  mrg       cond = fold_build2_loc (input_location, NE_EXPR,
   1629  1.1  mrg 			      logical_type_node,
   1630  1.1  mrg 			      from_data, null_pointer_node);
   1631  1.1  mrg       tmp = fold_build3_loc (input_location, COND_EXPR,
   1632  1.1  mrg 			     void_type_node, cond,
   1633  1.1  mrg 			     tmp, build_empty_stmt (input_location));
   1634  1.1  mrg     }
   1635  1.1  mrg 
   1636  1.1  mrg   return tmp;
   1637  1.1  mrg }
   1638  1.1  mrg 
   1639  1.1  mrg 
   1640  1.1  mrg static tree
   1641  1.1  mrg gfc_trans_class_array_init_assign (gfc_expr *rhs, gfc_expr *lhs, gfc_expr *obj)
   1642  1.1  mrg {
   1643  1.1  mrg   gfc_actual_arglist *actual;
   1644  1.1  mrg   gfc_expr *ppc;
   1645  1.1  mrg   gfc_code *ppc_code;
   1646  1.1  mrg   tree res;
   1647  1.1  mrg 
   1648  1.1  mrg   actual = gfc_get_actual_arglist ();
   1649  1.1  mrg   actual->expr = gfc_copy_expr (rhs);
   1650  1.1  mrg   actual->next = gfc_get_actual_arglist ();
   1651  1.1  mrg   actual->next->expr = gfc_copy_expr (lhs);
   1652  1.1  mrg   ppc = gfc_copy_expr (obj);
   1653  1.1  mrg   gfc_add_vptr_component (ppc);
   1654  1.1  mrg   gfc_add_component_ref (ppc, "_copy");
   1655  1.1  mrg   ppc_code = gfc_get_code (EXEC_CALL);
   1656  1.1  mrg   ppc_code->resolved_sym = ppc->symtree->n.sym;
   1657  1.1  mrg   /* Although '_copy' is set to be elemental in class.cc, it is
   1658  1.1  mrg      not staying that way.  Find out why, sometime....  */
   1659  1.1  mrg   ppc_code->resolved_sym->attr.elemental = 1;
   1660  1.1  mrg   ppc_code->ext.actual = actual;
   1661  1.1  mrg   ppc_code->expr1 = ppc;
   1662  1.1  mrg   /* Since '_copy' is elemental, the scalarizer will take care
   1663  1.1  mrg      of arrays in gfc_trans_call.  */
   1664  1.1  mrg   res = gfc_trans_call (ppc_code, false, NULL, NULL, false);
   1665  1.1  mrg   gfc_free_statements (ppc_code);
   1666  1.1  mrg 
   1667  1.1  mrg   if (UNLIMITED_POLY(obj))
   1668  1.1  mrg     {
   1669  1.1  mrg       /* Check if rhs is non-NULL. */
   1670  1.1  mrg       gfc_se src;
   1671  1.1  mrg       gfc_init_se (&src, NULL);
   1672  1.1  mrg       gfc_conv_expr (&src, rhs);
   1673  1.1  mrg       src.expr = gfc_build_addr_expr (NULL_TREE, src.expr);
   1674  1.1  mrg       tree cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
   1675  1.1  mrg 				   src.expr, fold_convert (TREE_TYPE (src.expr),
   1676  1.1  mrg 							   null_pointer_node));
   1677  1.1  mrg       res = build3_loc (input_location, COND_EXPR, TREE_TYPE (res), cond, res,
   1678  1.1  mrg 			build_empty_stmt (input_location));
   1679  1.1  mrg     }
   1680  1.1  mrg 
   1681  1.1  mrg   return res;
   1682  1.1  mrg }
   1683  1.1  mrg 
   1684  1.1  mrg /* Special case for initializing a polymorphic dummy with INTENT(OUT).
   1685  1.1  mrg    A MEMCPY is needed to copy the full data from the default initializer
   1686  1.1  mrg    of the dynamic type.  */
   1687  1.1  mrg 
   1688  1.1  mrg tree
   1689  1.1  mrg gfc_trans_class_init_assign (gfc_code *code)
   1690  1.1  mrg {
   1691  1.1  mrg   stmtblock_t block;
   1692  1.1  mrg   tree tmp;
   1693  1.1  mrg   gfc_se dst,src,memsz;
   1694  1.1  mrg   gfc_expr *lhs, *rhs, *sz;
   1695  1.1  mrg 
   1696  1.1  mrg   gfc_start_block (&block);
   1697  1.1  mrg 
   1698  1.1  mrg   lhs = gfc_copy_expr (code->expr1);
   1699  1.1  mrg 
   1700  1.1  mrg   rhs = gfc_copy_expr (code->expr1);
   1701  1.1  mrg   gfc_add_vptr_component (rhs);
   1702  1.1  mrg 
   1703  1.1  mrg   /* Make sure that the component backend_decls have been built, which
   1704  1.1  mrg      will not have happened if the derived types concerned have not
   1705  1.1  mrg      been referenced.  */
   1706  1.1  mrg   gfc_get_derived_type (rhs->ts.u.derived);
   1707  1.1  mrg   gfc_add_def_init_component (rhs);
   1708  1.1  mrg   /* The _def_init is always scalar.  */
   1709  1.1  mrg   rhs->rank = 0;
   1710  1.1  mrg 
   1711  1.1  mrg   if (code->expr1->ts.type == BT_CLASS
   1712  1.1  mrg       && CLASS_DATA (code->expr1)->attr.dimension)
   1713  1.1  mrg     {
   1714  1.1  mrg       gfc_array_spec *tmparr = gfc_get_array_spec ();
   1715  1.1  mrg       *tmparr = *CLASS_DATA (code->expr1)->as;
   1716  1.1  mrg       /* Adding the array ref to the class expression results in correct
   1717  1.1  mrg 	 indexing to the dynamic type.  */
   1718  1.1  mrg       gfc_add_full_array_ref (lhs, tmparr);
   1719  1.1  mrg       tmp = gfc_trans_class_array_init_assign (rhs, lhs, code->expr1);
   1720  1.1  mrg     }
   1721  1.1  mrg   else
   1722  1.1  mrg     {
   1723  1.1  mrg       /* Scalar initialization needs the _data component.  */
   1724  1.1  mrg       gfc_add_data_component (lhs);
   1725  1.1  mrg       sz = gfc_copy_expr (code->expr1);
   1726  1.1  mrg       gfc_add_vptr_component (sz);
   1727  1.1  mrg       gfc_add_size_component (sz);
   1728  1.1  mrg 
   1729  1.1  mrg       gfc_init_se (&dst, NULL);
   1730  1.1  mrg       gfc_init_se (&src, NULL);
   1731  1.1  mrg       gfc_init_se (&memsz, NULL);
   1732  1.1  mrg       gfc_conv_expr (&dst, lhs);
   1733  1.1  mrg       gfc_conv_expr (&src, rhs);
   1734  1.1  mrg       gfc_conv_expr (&memsz, sz);
   1735  1.1  mrg       gfc_add_block_to_block (&block, &src.pre);
   1736  1.1  mrg       src.expr = gfc_build_addr_expr (NULL_TREE, src.expr);
   1737  1.1  mrg 
   1738  1.1  mrg       tmp = gfc_build_memcpy_call (dst.expr, src.expr, memsz.expr);
   1739  1.1  mrg 
   1740  1.1  mrg       if (UNLIMITED_POLY(code->expr1))
   1741  1.1  mrg 	{
   1742  1.1  mrg 	  /* Check if _def_init is non-NULL. */
   1743  1.1  mrg 	  tree cond = fold_build2_loc (input_location, NE_EXPR,
   1744  1.1  mrg 				       logical_type_node, src.expr,
   1745  1.1  mrg 				       fold_convert (TREE_TYPE (src.expr),
   1746  1.1  mrg 						     null_pointer_node));
   1747  1.1  mrg 	  tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp), cond,
   1748  1.1  mrg 			    tmp, build_empty_stmt (input_location));
   1749  1.1  mrg 	}
   1750  1.1  mrg     }
   1751  1.1  mrg 
   1752  1.1  mrg   if (code->expr1->symtree->n.sym->attr.dummy
   1753  1.1  mrg       && (code->expr1->symtree->n.sym->attr.optional
   1754  1.1  mrg 	  || code->expr1->symtree->n.sym->ns->proc_name->attr.entry_master))
   1755  1.1  mrg     {
   1756  1.1  mrg       tree present = gfc_conv_expr_present (code->expr1->symtree->n.sym);
   1757  1.1  mrg       tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp),
   1758  1.1  mrg 			present, tmp,
   1759  1.1  mrg 			build_empty_stmt (input_location));
   1760  1.1  mrg     }
   1761  1.1  mrg 
   1762  1.1  mrg   gfc_add_expr_to_block (&block, tmp);
   1763  1.1  mrg 
   1764  1.1  mrg   return gfc_finish_block (&block);
   1765  1.1  mrg }
   1766  1.1  mrg 
   1767  1.1  mrg 
   1768  1.1  mrg /* Class valued elemental function calls or class array elements arriving
   1769  1.1  mrg    in gfc_trans_scalar_assign come here.  Wherever possible the vptr copy
   1770  1.1  mrg    is used to ensure that the rhs dynamic type is assigned to the lhs.  */
   1771  1.1  mrg 
   1772  1.1  mrg static bool
   1773  1.1  mrg trans_scalar_class_assign (stmtblock_t *block, gfc_se *lse, gfc_se *rse)
   1774  1.1  mrg {
   1775  1.1  mrg   tree fcn;
   1776  1.1  mrg   tree rse_expr;
   1777  1.1  mrg   tree class_data;
   1778  1.1  mrg   tree tmp;
   1779  1.1  mrg   tree zero;
   1780  1.1  mrg   tree cond;
   1781  1.1  mrg   tree final_cond;
   1782  1.1  mrg   stmtblock_t inner_block;
   1783  1.1  mrg   bool is_descriptor;
   1784  1.1  mrg   bool not_call_expr = TREE_CODE (rse->expr) != CALL_EXPR;
   1785  1.1  mrg   bool not_lhs_array_type;
   1786  1.1  mrg 
   1787  1.1  mrg   /* Temporaries arising from dependencies in assignment get cast as a
   1788  1.1  mrg      character type of the dynamic size of the rhs. Use the vptr copy
   1789  1.1  mrg      for this case.  */
   1790  1.1  mrg   tmp = TREE_TYPE (lse->expr);
   1791  1.1  mrg   not_lhs_array_type = !(tmp && TREE_CODE (tmp) == ARRAY_TYPE
   1792  1.1  mrg 			 && TYPE_MAX_VALUE (TYPE_DOMAIN (tmp)) != NULL_TREE);
   1793  1.1  mrg 
   1794  1.1  mrg   /* Use ordinary assignment if the rhs is not a call expression or
   1795  1.1  mrg      the lhs is not a class entity or an array(ie. character) type.  */
   1796  1.1  mrg   if ((not_call_expr && gfc_get_class_from_expr (lse->expr) == NULL_TREE)
   1797  1.1  mrg       && not_lhs_array_type)
   1798  1.1  mrg     return false;
   1799  1.1  mrg 
   1800  1.1  mrg   /* Ordinary assignment can be used if both sides are class expressions
   1801  1.1  mrg      since the dynamic type is preserved by copying the vptr.  This
   1802  1.1  mrg      should only occur, where temporaries are involved.  */
   1803  1.1  mrg   if (GFC_CLASS_TYPE_P (TREE_TYPE (lse->expr))
   1804  1.1  mrg       && GFC_CLASS_TYPE_P (TREE_TYPE (rse->expr)))
   1805  1.1  mrg     return false;
   1806  1.1  mrg 
   1807  1.1  mrg   /* Fix the class expression and the class data of the rhs.  */
   1808  1.1  mrg   if (!GFC_CLASS_TYPE_P (TREE_TYPE (rse->expr))
   1809  1.1  mrg       || not_call_expr)
   1810  1.1  mrg     {
   1811  1.1  mrg       tmp = gfc_get_class_from_expr (rse->expr);
   1812  1.1  mrg       if (tmp == NULL_TREE)
   1813  1.1  mrg 	return false;
   1814  1.1  mrg       rse_expr = gfc_evaluate_now (tmp, block);
   1815  1.1  mrg     }
   1816  1.1  mrg   else
   1817  1.1  mrg     rse_expr = gfc_evaluate_now (rse->expr, block);
   1818  1.1  mrg 
   1819  1.1  mrg   class_data = gfc_class_data_get (rse_expr);
   1820  1.1  mrg 
   1821  1.1  mrg   /* Check that the rhs data is not null.  */
   1822  1.1  mrg   is_descriptor = GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (class_data));
   1823  1.1  mrg   if (is_descriptor)
   1824  1.1  mrg     class_data = gfc_conv_descriptor_data_get (class_data);
   1825  1.1  mrg   class_data = gfc_evaluate_now (class_data, block);
   1826  1.1  mrg 
   1827  1.1  mrg   zero = build_int_cst (TREE_TYPE (class_data), 0);
   1828  1.1  mrg   cond = fold_build2_loc (input_location, NE_EXPR,
   1829  1.1  mrg 			  logical_type_node,
   1830  1.1  mrg 			  class_data, zero);
   1831  1.1  mrg 
   1832  1.1  mrg   /* Copy the rhs to the lhs.  */
   1833  1.1  mrg   fcn = gfc_vptr_copy_get (gfc_class_vptr_get (rse_expr));
   1834  1.1  mrg   fcn = build_fold_indirect_ref_loc (input_location, fcn);
   1835  1.1  mrg   tmp = gfc_evaluate_now (gfc_build_addr_expr (NULL, rse->expr), block);
   1836  1.1  mrg   tmp = is_descriptor ? tmp : class_data;
   1837  1.1  mrg   tmp = build_call_expr_loc (input_location, fcn, 2, tmp,
   1838  1.1  mrg 			     gfc_build_addr_expr (NULL, lse->expr));
   1839  1.1  mrg   gfc_add_expr_to_block (block, tmp);
   1840  1.1  mrg 
   1841  1.1  mrg   /* Only elemental function results need to be finalised and freed.  */
   1842  1.1  mrg   if (not_call_expr)
   1843  1.1  mrg     return true;
   1844  1.1  mrg 
   1845  1.1  mrg   /* Finalize the class data if needed.  */
   1846  1.1  mrg   gfc_init_block (&inner_block);
   1847  1.1  mrg   fcn = gfc_vptr_final_get (gfc_class_vptr_get (rse_expr));
   1848  1.1  mrg   zero = build_int_cst (TREE_TYPE (fcn), 0);
   1849  1.1  mrg   final_cond = fold_build2_loc (input_location, NE_EXPR,
   1850  1.1  mrg 				logical_type_node, fcn, zero);
   1851  1.1  mrg   fcn = build_fold_indirect_ref_loc (input_location, fcn);
   1852  1.1  mrg   tmp = build_call_expr_loc (input_location, fcn, 1, class_data);
   1853  1.1  mrg   tmp = build3_v (COND_EXPR, final_cond,
   1854  1.1  mrg 		  tmp, build_empty_stmt (input_location));
   1855  1.1  mrg   gfc_add_expr_to_block (&inner_block, tmp);
   1856  1.1  mrg 
   1857  1.1  mrg   /* Free the class data.  */
   1858  1.1  mrg   tmp = gfc_call_free (class_data);
   1859  1.1  mrg   tmp = build3_v (COND_EXPR, cond, tmp,
   1860  1.1  mrg 		  build_empty_stmt (input_location));
   1861  1.1  mrg   gfc_add_expr_to_block (&inner_block, tmp);
   1862  1.1  mrg 
   1863  1.1  mrg   /* Finish the inner block and subject it to the condition on the
   1864  1.1  mrg      class data being non-zero.  */
   1865  1.1  mrg   tmp = gfc_finish_block (&inner_block);
   1866  1.1  mrg   tmp = build3_v (COND_EXPR, cond, tmp,
   1867  1.1  mrg 		  build_empty_stmt (input_location));
   1868  1.1  mrg   gfc_add_expr_to_block (block, tmp);
   1869  1.1  mrg 
   1870  1.1  mrg   return true;
   1871  1.1  mrg }
   1872  1.1  mrg 
   1873  1.1  mrg /* End of prototype trans-class.c  */
   1874  1.1  mrg 
   1875  1.1  mrg 
   1876  1.1  mrg static void
   1877  1.1  mrg realloc_lhs_warning (bt type, bool array, locus *where)
   1878  1.1  mrg {
   1879  1.1  mrg   if (array && type != BT_CLASS && type != BT_DERIVED && warn_realloc_lhs)
   1880  1.1  mrg     gfc_warning (OPT_Wrealloc_lhs,
   1881  1.1  mrg 		 "Code for reallocating the allocatable array at %L will "
   1882  1.1  mrg 		 "be added", where);
   1883  1.1  mrg   else if (warn_realloc_lhs_all)
   1884  1.1  mrg     gfc_warning (OPT_Wrealloc_lhs_all,
   1885  1.1  mrg 		 "Code for reallocating the allocatable variable at %L "
   1886  1.1  mrg 		 "will be added", where);
   1887  1.1  mrg }
   1888  1.1  mrg 
   1889  1.1  mrg 
   1890  1.1  mrg static void gfc_apply_interface_mapping_to_expr (gfc_interface_mapping *,
   1891  1.1  mrg 						 gfc_expr *);
   1892  1.1  mrg 
   1893  1.1  mrg /* Copy the scalarization loop variables.  */
   1894  1.1  mrg 
   1895  1.1  mrg static void
   1896  1.1  mrg gfc_copy_se_loopvars (gfc_se * dest, gfc_se * src)
   1897  1.1  mrg {
   1898  1.1  mrg   dest->ss = src->ss;
   1899  1.1  mrg   dest->loop = src->loop;
   1900  1.1  mrg }
   1901  1.1  mrg 
   1902  1.1  mrg 
   1903  1.1  mrg /* Initialize a simple expression holder.
   1904  1.1  mrg 
   1905  1.1  mrg    Care must be taken when multiple se are created with the same parent.
   1906  1.1  mrg    The child se must be kept in sync.  The easiest way is to delay creation
   1907  1.1  mrg    of a child se until after the previous se has been translated.  */
   1908  1.1  mrg 
   1909  1.1  mrg void
   1910  1.1  mrg gfc_init_se (gfc_se * se, gfc_se * parent)
   1911  1.1  mrg {
   1912  1.1  mrg   memset (se, 0, sizeof (gfc_se));
   1913  1.1  mrg   gfc_init_block (&se->pre);
   1914  1.1  mrg   gfc_init_block (&se->post);
   1915  1.1  mrg 
   1916  1.1  mrg   se->parent = parent;
   1917  1.1  mrg 
   1918  1.1  mrg   if (parent)
   1919  1.1  mrg     gfc_copy_se_loopvars (se, parent);
   1920  1.1  mrg }
   1921  1.1  mrg 
   1922  1.1  mrg 
   1923  1.1  mrg /* Advances to the next SS in the chain.  Use this rather than setting
   1924  1.1  mrg    se->ss = se->ss->next because all the parents needs to be kept in sync.
   1925  1.1  mrg    See gfc_init_se.  */
   1926  1.1  mrg 
   1927  1.1  mrg void
   1928  1.1  mrg gfc_advance_se_ss_chain (gfc_se * se)
   1929  1.1  mrg {
   1930  1.1  mrg   gfc_se *p;
   1931  1.1  mrg   gfc_ss *ss;
   1932  1.1  mrg 
   1933  1.1  mrg   gcc_assert (se != NULL && se->ss != NULL && se->ss != gfc_ss_terminator);
   1934  1.1  mrg 
   1935  1.1  mrg   p = se;
   1936  1.1  mrg   /* Walk down the parent chain.  */
   1937  1.1  mrg   while (p != NULL)
   1938  1.1  mrg     {
   1939  1.1  mrg       /* Simple consistency check.  */
   1940  1.1  mrg       gcc_assert (p->parent == NULL || p->parent->ss == p->ss
   1941  1.1  mrg 		  || p->parent->ss->nested_ss == p->ss);
   1942  1.1  mrg 
   1943  1.1  mrg       /* If we were in a nested loop, the next scalarized expression can be
   1944  1.1  mrg 	 on the parent ss' next pointer.  Thus we should not take the next
   1945  1.1  mrg 	 pointer blindly, but rather go up one nest level as long as next
   1946  1.1  mrg 	 is the end of chain.  */
   1947  1.1  mrg       ss = p->ss;
   1948  1.1  mrg       while (ss->next == gfc_ss_terminator && ss->parent != NULL)
   1949  1.1  mrg 	ss = ss->parent;
   1950  1.1  mrg 
   1951  1.1  mrg       p->ss = ss->next;
   1952  1.1  mrg 
   1953  1.1  mrg       p = p->parent;
   1954  1.1  mrg     }
   1955  1.1  mrg }
   1956  1.1  mrg 
   1957  1.1  mrg 
   1958  1.1  mrg /* Ensures the result of the expression as either a temporary variable
   1959  1.1  mrg    or a constant so that it can be used repeatedly.  */
   1960  1.1  mrg 
   1961  1.1  mrg void
   1962  1.1  mrg gfc_make_safe_expr (gfc_se * se)
   1963  1.1  mrg {
   1964  1.1  mrg   tree var;
   1965  1.1  mrg 
   1966  1.1  mrg   if (CONSTANT_CLASS_P (se->expr))
   1967  1.1  mrg     return;
   1968  1.1  mrg 
   1969  1.1  mrg   /* We need a temporary for this result.  */
   1970  1.1  mrg   var = gfc_create_var (TREE_TYPE (se->expr), NULL);
   1971  1.1  mrg   gfc_add_modify (&se->pre, var, se->expr);
   1972  1.1  mrg   se->expr = var;
   1973  1.1  mrg }
   1974  1.1  mrg 
   1975  1.1  mrg 
   1976  1.1  mrg /* Return an expression which determines if a dummy parameter is present.
   1977  1.1  mrg    Also used for arguments to procedures with multiple entry points.  */
   1978  1.1  mrg 
   1979  1.1  mrg tree
   1980  1.1  mrg gfc_conv_expr_present (gfc_symbol * sym, bool use_saved_desc)
   1981  1.1  mrg {
   1982  1.1  mrg   tree decl, orig_decl, cond;
   1983  1.1  mrg 
   1984  1.1  mrg   gcc_assert (sym->attr.dummy);
   1985  1.1  mrg   orig_decl = decl = gfc_get_symbol_decl (sym);
   1986  1.1  mrg 
   1987  1.1  mrg   /* Intrinsic scalars with VALUE attribute which are passed by value
   1988  1.1  mrg      use a hidden argument to denote the present status.  */
   1989  1.1  mrg   if (sym->attr.value && sym->ts.type != BT_CHARACTER
   1990  1.1  mrg       && sym->ts.type != BT_CLASS && sym->ts.type != BT_DERIVED
   1991  1.1  mrg       && !sym->attr.dimension)
   1992  1.1  mrg     {
   1993  1.1  mrg       char name[GFC_MAX_SYMBOL_LEN + 2];
   1994  1.1  mrg       tree tree_name;
   1995  1.1  mrg 
   1996  1.1  mrg       gcc_assert (TREE_CODE (decl) == PARM_DECL);
   1997  1.1  mrg       name[0] = '_';
   1998  1.1  mrg       strcpy (&name[1], sym->name);
   1999  1.1  mrg       tree_name = get_identifier (name);
   2000  1.1  mrg 
   2001  1.1  mrg       /* Walk function argument list to find hidden arg.  */
   2002  1.1  mrg       cond = DECL_ARGUMENTS (DECL_CONTEXT (decl));
   2003  1.1  mrg       for ( ; cond != NULL_TREE; cond = TREE_CHAIN (cond))
   2004  1.1  mrg 	if (DECL_NAME (cond) == tree_name
   2005  1.1  mrg 	    && DECL_ARTIFICIAL (cond))
   2006  1.1  mrg 	  break;
   2007  1.1  mrg 
   2008  1.1  mrg       gcc_assert (cond);
   2009  1.1  mrg       return cond;
   2010  1.1  mrg     }
   2011  1.1  mrg 
   2012  1.1  mrg   /* Assumed-shape arrays use a local variable for the array data;
   2013  1.1  mrg      the actual PARAM_DECL is in a saved decl.  As the local variable
   2014  1.1  mrg      is NULL, it can be checked instead, unless use_saved_desc is
   2015  1.1  mrg      requested.  */
   2016  1.1  mrg 
   2017  1.1  mrg   if (use_saved_desc && TREE_CODE (decl) != PARM_DECL)
   2018  1.1  mrg     {
   2019  1.1  mrg       gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl))
   2020  1.1  mrg              || GFC_ARRAY_TYPE_P (TREE_TYPE (decl)));
   2021  1.1  mrg       decl = GFC_DECL_SAVED_DESCRIPTOR (decl);
   2022  1.1  mrg     }
   2023  1.1  mrg 
   2024  1.1  mrg   cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node, decl,
   2025  1.1  mrg 			  fold_convert (TREE_TYPE (decl), null_pointer_node));
   2026  1.1  mrg 
   2027  1.1  mrg   /* Fortran 2008 allows to pass null pointers and non-associated pointers
   2028  1.1  mrg      as actual argument to denote absent dummies. For array descriptors,
   2029  1.1  mrg      we thus also need to check the array descriptor.  For BT_CLASS, it
   2030  1.1  mrg      can also occur for scalars and F2003 due to type->class wrapping and
   2031  1.1  mrg      class->class wrapping.  Note further that BT_CLASS always uses an
   2032  1.1  mrg      array descriptor for arrays, also for explicit-shape/assumed-size.
   2033  1.1  mrg      For assumed-rank arrays, no local variable is generated, hence,
   2034  1.1  mrg      the following also applies with !use_saved_desc.  */
   2035  1.1  mrg 
   2036  1.1  mrg   if ((use_saved_desc || TREE_CODE (orig_decl) == PARM_DECL)
   2037  1.1  mrg       && !sym->attr.allocatable
   2038  1.1  mrg       && ((sym->ts.type != BT_CLASS && !sym->attr.pointer)
   2039  1.1  mrg 	  || (sym->ts.type == BT_CLASS
   2040  1.1  mrg 	      && !CLASS_DATA (sym)->attr.allocatable
   2041  1.1  mrg 	      && !CLASS_DATA (sym)->attr.class_pointer))
   2042  1.1  mrg       && ((gfc_option.allow_std & GFC_STD_F2008) != 0
   2043  1.1  mrg 	  || sym->ts.type == BT_CLASS))
   2044  1.1  mrg     {
   2045  1.1  mrg       tree tmp;
   2046  1.1  mrg 
   2047  1.1  mrg       if ((sym->as && (sym->as->type == AS_ASSUMED_SHAPE
   2048  1.1  mrg 		       || sym->as->type == AS_ASSUMED_RANK
   2049  1.1  mrg 		       || sym->attr.codimension))
   2050  1.1  mrg 	  || (sym->ts.type == BT_CLASS && CLASS_DATA (sym)->as))
   2051  1.1  mrg 	{
   2052  1.1  mrg 	  tmp = build_fold_indirect_ref_loc (input_location, decl);
   2053  1.1  mrg 	  if (sym->ts.type == BT_CLASS)
   2054  1.1  mrg 	    tmp = gfc_class_data_get (tmp);
   2055  1.1  mrg 	  tmp = gfc_conv_array_data (tmp);
   2056  1.1  mrg 	}
   2057  1.1  mrg       else if (sym->ts.type == BT_CLASS)
   2058  1.1  mrg 	tmp = gfc_class_data_get (decl);
   2059  1.1  mrg       else
   2060  1.1  mrg 	tmp = NULL_TREE;
   2061  1.1  mrg 
   2062  1.1  mrg       if (tmp != NULL_TREE)
   2063  1.1  mrg 	{
   2064  1.1  mrg 	  tmp = fold_build2_loc (input_location, NE_EXPR, logical_type_node, tmp,
   2065  1.1  mrg 				 fold_convert (TREE_TYPE (tmp), null_pointer_node));
   2066  1.1  mrg 	  cond = fold_build2_loc (input_location, TRUTH_ANDIF_EXPR,
   2067  1.1  mrg 				  logical_type_node, cond, tmp);
   2068  1.1  mrg 	}
   2069  1.1  mrg     }
   2070  1.1  mrg 
   2071  1.1  mrg   return cond;
   2072  1.1  mrg }
   2073  1.1  mrg 
   2074  1.1  mrg 
   2075  1.1  mrg /* Converts a missing, dummy argument into a null or zero.  */
   2076  1.1  mrg 
   2077  1.1  mrg void
   2078  1.1  mrg gfc_conv_missing_dummy (gfc_se * se, gfc_expr * arg, gfc_typespec ts, int kind)
   2079  1.1  mrg {
   2080  1.1  mrg   tree present;
   2081  1.1  mrg   tree tmp;
   2082  1.1  mrg 
   2083  1.1  mrg   present = gfc_conv_expr_present (arg->symtree->n.sym);
   2084  1.1  mrg 
   2085  1.1  mrg   if (kind > 0)
   2086  1.1  mrg     {
   2087  1.1  mrg       /* Create a temporary and convert it to the correct type.  */
   2088  1.1  mrg       tmp = gfc_get_int_type (kind);
   2089  1.1  mrg       tmp = fold_convert (tmp, build_fold_indirect_ref_loc (input_location,
   2090  1.1  mrg 							se->expr));
   2091  1.1  mrg 
   2092  1.1  mrg       /* Test for a NULL value.  */
   2093  1.1  mrg       tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp), present,
   2094  1.1  mrg 			tmp, fold_convert (TREE_TYPE (tmp), integer_one_node));
   2095  1.1  mrg       tmp = gfc_evaluate_now (tmp, &se->pre);
   2096  1.1  mrg       se->expr = gfc_build_addr_expr (NULL_TREE, tmp);
   2097  1.1  mrg     }
   2098  1.1  mrg   else
   2099  1.1  mrg     {
   2100  1.1  mrg       tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (se->expr),
   2101  1.1  mrg 			present, se->expr,
   2102  1.1  mrg 			build_zero_cst (TREE_TYPE (se->expr)));
   2103  1.1  mrg       tmp = gfc_evaluate_now (tmp, &se->pre);
   2104  1.1  mrg       se->expr = tmp;
   2105  1.1  mrg     }
   2106  1.1  mrg 
   2107  1.1  mrg   if (ts.type == BT_CHARACTER)
   2108  1.1  mrg     {
   2109  1.1  mrg       tmp = build_int_cst (gfc_charlen_type_node, 0);
   2110  1.1  mrg       tmp = fold_build3_loc (input_location, COND_EXPR, gfc_charlen_type_node,
   2111  1.1  mrg 			     present, se->string_length, tmp);
   2112  1.1  mrg       tmp = gfc_evaluate_now (tmp, &se->pre);
   2113  1.1  mrg       se->string_length = tmp;
   2114  1.1  mrg     }
   2115  1.1  mrg   return;
   2116  1.1  mrg }
   2117  1.1  mrg 
   2118  1.1  mrg 
   2119  1.1  mrg /* Get the character length of an expression, looking through gfc_refs
   2120  1.1  mrg    if necessary.  */
   2121  1.1  mrg 
   2122  1.1  mrg tree
   2123  1.1  mrg gfc_get_expr_charlen (gfc_expr *e)
   2124  1.1  mrg {
   2125  1.1  mrg   gfc_ref *r;
   2126  1.1  mrg   tree length;
   2127  1.1  mrg   gfc_se se;
   2128  1.1  mrg 
   2129  1.1  mrg   gcc_assert (e->expr_type == EXPR_VARIABLE
   2130  1.1  mrg 	      && e->ts.type == BT_CHARACTER);
   2131  1.1  mrg 
   2132  1.1  mrg   length = NULL; /* To silence compiler warning.  */
   2133  1.1  mrg 
   2134  1.1  mrg   if (is_subref_array (e) && e->ts.u.cl->length)
   2135  1.1  mrg     {
   2136  1.1  mrg       gfc_se tmpse;
   2137  1.1  mrg       gfc_init_se (&tmpse, NULL);
   2138  1.1  mrg       gfc_conv_expr_type (&tmpse, e->ts.u.cl->length, gfc_charlen_type_node);
   2139  1.1  mrg       e->ts.u.cl->backend_decl = tmpse.expr;
   2140  1.1  mrg       return tmpse.expr;
   2141  1.1  mrg     }
   2142  1.1  mrg 
   2143  1.1  mrg   /* First candidate: if the variable is of type CHARACTER, the
   2144  1.1  mrg      expression's length could be the length of the character
   2145  1.1  mrg      variable.  */
   2146  1.1  mrg   if (e->symtree->n.sym->ts.type == BT_CHARACTER)
   2147  1.1  mrg     length = e->symtree->n.sym->ts.u.cl->backend_decl;
   2148  1.1  mrg 
   2149  1.1  mrg   /* Look through the reference chain for component references.  */
   2150  1.1  mrg   for (r = e->ref; r; r = r->next)
   2151  1.1  mrg     {
   2152  1.1  mrg       switch (r->type)
   2153  1.1  mrg 	{
   2154  1.1  mrg 	case REF_COMPONENT:
   2155  1.1  mrg 	  if (r->u.c.component->ts.type == BT_CHARACTER)
   2156  1.1  mrg 	    length = r->u.c.component->ts.u.cl->backend_decl;
   2157  1.1  mrg 	  break;
   2158  1.1  mrg 
   2159  1.1  mrg 	case REF_ARRAY:
   2160  1.1  mrg 	  /* Do nothing.  */
   2161  1.1  mrg 	  break;
   2162  1.1  mrg 
   2163  1.1  mrg 	case REF_SUBSTRING:
   2164  1.1  mrg 	  gfc_init_se (&se, NULL);
   2165  1.1  mrg 	  gfc_conv_expr_type (&se, r->u.ss.start, gfc_charlen_type_node);
   2166  1.1  mrg 	  length = se.expr;
   2167  1.1  mrg 	  gfc_conv_expr_type (&se, r->u.ss.end, gfc_charlen_type_node);
   2168  1.1  mrg 	  length = fold_build2_loc (input_location, MINUS_EXPR,
   2169  1.1  mrg 				    gfc_charlen_type_node,
   2170  1.1  mrg 				    se.expr, length);
   2171  1.1  mrg 	  length = fold_build2_loc (input_location, PLUS_EXPR,
   2172  1.1  mrg 				    gfc_charlen_type_node, length,
   2173  1.1  mrg 				    gfc_index_one_node);
   2174  1.1  mrg 	  break;
   2175  1.1  mrg 
   2176  1.1  mrg 	default:
   2177  1.1  mrg 	  gcc_unreachable ();
   2178  1.1  mrg 	  break;
   2179  1.1  mrg 	}
   2180  1.1  mrg     }
   2181  1.1  mrg 
   2182  1.1  mrg   gcc_assert (length != NULL);
   2183  1.1  mrg   return length;
   2184  1.1  mrg }
   2185  1.1  mrg 
   2186  1.1  mrg 
   2187  1.1  mrg /* Return for an expression the backend decl of the coarray.  */
   2188  1.1  mrg 
   2189  1.1  mrg tree
   2190  1.1  mrg gfc_get_tree_for_caf_expr (gfc_expr *expr)
   2191  1.1  mrg {
   2192  1.1  mrg   tree caf_decl;
   2193  1.1  mrg   bool found = false;
   2194  1.1  mrg   gfc_ref *ref;
   2195  1.1  mrg 
   2196  1.1  mrg   gcc_assert (expr && expr->expr_type == EXPR_VARIABLE);
   2197  1.1  mrg 
   2198  1.1  mrg   /* Not-implemented diagnostic.  */
   2199  1.1  mrg   if (expr->symtree->n.sym->ts.type == BT_CLASS
   2200  1.1  mrg       && UNLIMITED_POLY (expr->symtree->n.sym)
   2201  1.1  mrg       && CLASS_DATA (expr->symtree->n.sym)->attr.codimension)
   2202  1.1  mrg     gfc_error ("Sorry, coindexed access to an unlimited polymorphic object at "
   2203  1.1  mrg 	       "%L is not supported", &expr->where);
   2204  1.1  mrg 
   2205  1.1  mrg   for (ref = expr->ref; ref; ref = ref->next)
   2206  1.1  mrg     if (ref->type == REF_COMPONENT)
   2207  1.1  mrg       {
   2208  1.1  mrg 	if (ref->u.c.component->ts.type == BT_CLASS
   2209  1.1  mrg 	    && UNLIMITED_POLY (ref->u.c.component)
   2210  1.1  mrg 	    && CLASS_DATA (ref->u.c.component)->attr.codimension)
   2211  1.1  mrg 	  gfc_error ("Sorry, coindexed access to an unlimited polymorphic "
   2212  1.1  mrg 		     "component at %L is not supported", &expr->where);
   2213  1.1  mrg       }
   2214  1.1  mrg 
   2215  1.1  mrg   /* Make sure the backend_decl is present before accessing it.  */
   2216  1.1  mrg   caf_decl = expr->symtree->n.sym->backend_decl == NULL_TREE
   2217  1.1  mrg       ? gfc_get_symbol_decl (expr->symtree->n.sym)
   2218  1.1  mrg       : expr->symtree->n.sym->backend_decl;
   2219  1.1  mrg 
   2220  1.1  mrg   if (expr->symtree->n.sym->ts.type == BT_CLASS)
   2221  1.1  mrg     {
   2222  1.1  mrg       if (expr->ref && expr->ref->type == REF_ARRAY)
   2223  1.1  mrg 	{
   2224  1.1  mrg 	  caf_decl = gfc_class_data_get (caf_decl);
   2225  1.1  mrg 	  if (CLASS_DATA (expr->symtree->n.sym)->attr.codimension)
   2226  1.1  mrg 	    return caf_decl;
   2227  1.1  mrg 	}
   2228  1.1  mrg       for (ref = expr->ref; ref; ref = ref->next)
   2229  1.1  mrg 	{
   2230  1.1  mrg 	  if (ref->type == REF_COMPONENT
   2231  1.1  mrg 	      && strcmp (ref->u.c.component->name, "_data") != 0)
   2232  1.1  mrg 	    {
   2233  1.1  mrg 	      caf_decl = gfc_class_data_get (caf_decl);
   2234  1.1  mrg 	      if (CLASS_DATA (expr->symtree->n.sym)->attr.codimension)
   2235  1.1  mrg 		return caf_decl;
   2236  1.1  mrg 	      break;
   2237  1.1  mrg 	    }
   2238  1.1  mrg 	  else if (ref->type == REF_ARRAY && ref->u.ar.dimen)
   2239  1.1  mrg 	    break;
   2240  1.1  mrg 	}
   2241  1.1  mrg     }
   2242  1.1  mrg   if (expr->symtree->n.sym->attr.codimension)
   2243  1.1  mrg     return caf_decl;
   2244  1.1  mrg 
   2245  1.1  mrg   /* The following code assumes that the coarray is a component reachable via
   2246  1.1  mrg      only scalar components/variables; the Fortran standard guarantees this.  */
   2247  1.1  mrg 
   2248  1.1  mrg   for (ref = expr->ref; ref; ref = ref->next)
   2249  1.1  mrg     if (ref->type == REF_COMPONENT)
   2250  1.1  mrg       {
   2251  1.1  mrg 	gfc_component *comp = ref->u.c.component;
   2252  1.1  mrg 
   2253  1.1  mrg 	if (POINTER_TYPE_P (TREE_TYPE (caf_decl)))
   2254  1.1  mrg 	  caf_decl = build_fold_indirect_ref_loc (input_location, caf_decl);
   2255  1.1  mrg 	caf_decl = fold_build3_loc (input_location, COMPONENT_REF,
   2256  1.1  mrg 				    TREE_TYPE (comp->backend_decl), caf_decl,
   2257  1.1  mrg 				    comp->backend_decl, NULL_TREE);
   2258  1.1  mrg 	if (comp->ts.type == BT_CLASS)
   2259  1.1  mrg 	  {
   2260  1.1  mrg 	    caf_decl = gfc_class_data_get (caf_decl);
   2261  1.1  mrg 	    if (CLASS_DATA (comp)->attr.codimension)
   2262  1.1  mrg 	      {
   2263  1.1  mrg 		found = true;
   2264  1.1  mrg 		break;
   2265  1.1  mrg 	      }
   2266  1.1  mrg 	  }
   2267  1.1  mrg 	if (comp->attr.codimension)
   2268  1.1  mrg 	  {
   2269  1.1  mrg 	    found = true;
   2270  1.1  mrg 	    break;
   2271  1.1  mrg 	  }
   2272  1.1  mrg       }
   2273  1.1  mrg   gcc_assert (found && caf_decl);
   2274  1.1  mrg   return caf_decl;
   2275  1.1  mrg }
   2276  1.1  mrg 
   2277  1.1  mrg 
   2278  1.1  mrg /* Obtain the Coarray token - and optionally also the offset.  */
   2279  1.1  mrg 
   2280  1.1  mrg void
   2281  1.1  mrg gfc_get_caf_token_offset (gfc_se *se, tree *token, tree *offset, tree caf_decl,
   2282  1.1  mrg 			  tree se_expr, gfc_expr *expr)
   2283  1.1  mrg {
   2284  1.1  mrg   tree tmp;
   2285  1.1  mrg 
   2286  1.1  mrg   /* Coarray token.  */
   2287  1.1  mrg   if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (caf_decl)))
   2288  1.1  mrg     {
   2289  1.1  mrg       gcc_assert (GFC_TYPE_ARRAY_AKIND (TREE_TYPE (caf_decl))
   2290  1.1  mrg 		    == GFC_ARRAY_ALLOCATABLE
   2291  1.1  mrg 		  || expr->symtree->n.sym->attr.select_type_temporary);
   2292  1.1  mrg       *token = gfc_conv_descriptor_token (caf_decl);
   2293  1.1  mrg     }
   2294  1.1  mrg   else if (DECL_LANG_SPECIFIC (caf_decl)
   2295  1.1  mrg 	   && GFC_DECL_TOKEN (caf_decl) != NULL_TREE)
   2296  1.1  mrg     *token = GFC_DECL_TOKEN (caf_decl);
   2297  1.1  mrg   else
   2298  1.1  mrg     {
   2299  1.1  mrg       gcc_assert (GFC_ARRAY_TYPE_P (TREE_TYPE (caf_decl))
   2300  1.1  mrg 		  && GFC_TYPE_ARRAY_CAF_TOKEN (TREE_TYPE (caf_decl)) != NULL_TREE);
   2301  1.1  mrg       *token = GFC_TYPE_ARRAY_CAF_TOKEN (TREE_TYPE (caf_decl));
   2302  1.1  mrg     }
   2303  1.1  mrg 
   2304  1.1  mrg   if (offset == NULL)
   2305  1.1  mrg     return;
   2306  1.1  mrg 
   2307  1.1  mrg   /* Offset between the coarray base address and the address wanted.  */
   2308  1.1  mrg   if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (caf_decl))
   2309  1.1  mrg       && (GFC_TYPE_ARRAY_AKIND (TREE_TYPE (caf_decl)) == GFC_ARRAY_ALLOCATABLE
   2310  1.1  mrg 	  || GFC_TYPE_ARRAY_AKIND (TREE_TYPE (caf_decl)) == GFC_ARRAY_POINTER))
   2311  1.1  mrg     *offset = build_int_cst (gfc_array_index_type, 0);
   2312  1.1  mrg   else if (DECL_LANG_SPECIFIC (caf_decl)
   2313  1.1  mrg 	   && GFC_DECL_CAF_OFFSET (caf_decl) != NULL_TREE)
   2314  1.1  mrg     *offset = GFC_DECL_CAF_OFFSET (caf_decl);
   2315  1.1  mrg   else if (GFC_TYPE_ARRAY_CAF_OFFSET (TREE_TYPE (caf_decl)) != NULL_TREE)
   2316  1.1  mrg     *offset = GFC_TYPE_ARRAY_CAF_OFFSET (TREE_TYPE (caf_decl));
   2317  1.1  mrg   else
   2318  1.1  mrg     *offset = build_int_cst (gfc_array_index_type, 0);
   2319  1.1  mrg 
   2320  1.1  mrg   if (POINTER_TYPE_P (TREE_TYPE (se_expr))
   2321  1.1  mrg       && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (TREE_TYPE (se_expr))))
   2322  1.1  mrg     {
   2323  1.1  mrg       tmp = build_fold_indirect_ref_loc (input_location, se_expr);
   2324  1.1  mrg       tmp = gfc_conv_descriptor_data_get (tmp);
   2325  1.1  mrg     }
   2326  1.1  mrg   else if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se_expr)))
   2327  1.1  mrg     tmp = gfc_conv_descriptor_data_get (se_expr);
   2328  1.1  mrg   else
   2329  1.1  mrg     {
   2330  1.1  mrg       gcc_assert (POINTER_TYPE_P (TREE_TYPE (se_expr)));
   2331  1.1  mrg       tmp = se_expr;
   2332  1.1  mrg     }
   2333  1.1  mrg 
   2334  1.1  mrg   *offset = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
   2335  1.1  mrg 			     *offset, fold_convert (gfc_array_index_type, tmp));
   2336  1.1  mrg 
   2337  1.1  mrg   if (expr->symtree->n.sym->ts.type == BT_DERIVED
   2338  1.1  mrg       && expr->symtree->n.sym->attr.codimension
   2339  1.1  mrg       && expr->symtree->n.sym->ts.u.derived->attr.alloc_comp)
   2340  1.1  mrg     {
   2341  1.1  mrg       gfc_expr *base_expr = gfc_copy_expr (expr);
   2342  1.1  mrg       gfc_ref *ref = base_expr->ref;
   2343  1.1  mrg       gfc_se base_se;
   2344  1.1  mrg 
   2345  1.1  mrg       // Iterate through the refs until the last one.
   2346  1.1  mrg       while (ref->next)
   2347  1.1  mrg 	  ref = ref->next;
   2348  1.1  mrg 
   2349  1.1  mrg       if (ref->type == REF_ARRAY
   2350  1.1  mrg 	  && ref->u.ar.type != AR_FULL)
   2351  1.1  mrg 	{
   2352  1.1  mrg 	  const int ranksum = ref->u.ar.dimen + ref->u.ar.codimen;
   2353  1.1  mrg 	  int i;
   2354  1.1  mrg 	  for (i = 0; i < ranksum; ++i)
   2355  1.1  mrg 	    {
   2356  1.1  mrg 	      ref->u.ar.start[i] = NULL;
   2357  1.1  mrg 	      ref->u.ar.end[i] = NULL;
   2358  1.1  mrg 	    }
   2359  1.1  mrg 	  ref->u.ar.type = AR_FULL;
   2360  1.1  mrg 	}
   2361  1.1  mrg       gfc_init_se (&base_se, NULL);
   2362  1.1  mrg       if (gfc_caf_attr (base_expr).dimension)
   2363  1.1  mrg 	{
   2364  1.1  mrg 	  gfc_conv_expr_descriptor (&base_se, base_expr);
   2365  1.1  mrg 	  tmp = gfc_conv_descriptor_data_get (base_se.expr);
   2366  1.1  mrg 	}
   2367  1.1  mrg       else
   2368  1.1  mrg 	{
   2369  1.1  mrg 	  gfc_conv_expr (&base_se, base_expr);
   2370  1.1  mrg 	  tmp = base_se.expr;
   2371  1.1  mrg 	}
   2372  1.1  mrg 
   2373  1.1  mrg       gfc_free_expr (base_expr);
   2374  1.1  mrg       gfc_add_block_to_block (&se->pre, &base_se.pre);
   2375  1.1  mrg       gfc_add_block_to_block (&se->post, &base_se.post);
   2376  1.1  mrg     }
   2377  1.1  mrg   else if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (caf_decl)))
   2378  1.1  mrg     tmp = gfc_conv_descriptor_data_get (caf_decl);
   2379  1.1  mrg   else
   2380  1.1  mrg    {
   2381  1.1  mrg      gcc_assert (POINTER_TYPE_P (TREE_TYPE (caf_decl)));
   2382  1.1  mrg      tmp = caf_decl;
   2383  1.1  mrg    }
   2384  1.1  mrg 
   2385  1.1  mrg   *offset = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
   2386  1.1  mrg 			    fold_convert (gfc_array_index_type, *offset),
   2387  1.1  mrg 			    fold_convert (gfc_array_index_type, tmp));
   2388  1.1  mrg }
   2389  1.1  mrg 
   2390  1.1  mrg 
   2391  1.1  mrg /* Convert the coindex of a coarray into an image index; the result is
   2392  1.1  mrg    image_num =  (idx(1)-lcobound(1)+1) + (idx(2)-lcobound(2))*extent(1)
   2393  1.1  mrg               + (idx(3)-lcobound(3))*extend(1)*extent(2) + ...  */
   2394  1.1  mrg 
   2395  1.1  mrg tree
   2396  1.1  mrg gfc_caf_get_image_index (stmtblock_t *block, gfc_expr *e, tree desc)
   2397  1.1  mrg {
   2398  1.1  mrg   gfc_ref *ref;
   2399  1.1  mrg   tree lbound, ubound, extent, tmp, img_idx;
   2400  1.1  mrg   gfc_se se;
   2401  1.1  mrg   int i;
   2402  1.1  mrg 
   2403  1.1  mrg   for (ref = e->ref; ref; ref = ref->next)
   2404  1.1  mrg     if (ref->type == REF_ARRAY && ref->u.ar.codimen > 0)
   2405  1.1  mrg       break;
   2406  1.1  mrg   gcc_assert (ref != NULL);
   2407  1.1  mrg 
   2408  1.1  mrg   if (ref->u.ar.dimen_type[ref->u.ar.dimen] == DIMEN_THIS_IMAGE)
   2409  1.1  mrg     {
   2410  1.1  mrg       return build_call_expr_loc (input_location, gfor_fndecl_caf_this_image, 1,
   2411  1.1  mrg 				  integer_zero_node);
   2412  1.1  mrg     }
   2413  1.1  mrg 
   2414  1.1  mrg   img_idx = build_zero_cst (gfc_array_index_type);
   2415  1.1  mrg   extent = build_one_cst (gfc_array_index_type);
   2416  1.1  mrg   if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (desc)))
   2417  1.1  mrg     for (i = ref->u.ar.dimen; i < ref->u.ar.dimen + ref->u.ar.codimen; i++)
   2418  1.1  mrg       {
   2419  1.1  mrg 	gfc_init_se (&se, NULL);
   2420  1.1  mrg 	gfc_conv_expr_type (&se, ref->u.ar.start[i], gfc_array_index_type);
   2421  1.1  mrg 	gfc_add_block_to_block (block, &se.pre);
   2422  1.1  mrg 	lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[i]);
   2423  1.1  mrg 	tmp = fold_build2_loc (input_location, MINUS_EXPR,
   2424  1.1  mrg 			       TREE_TYPE (lbound), se.expr, lbound);
   2425  1.1  mrg 	tmp = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (tmp),
   2426  1.1  mrg 			       extent, tmp);
   2427  1.1  mrg 	img_idx = fold_build2_loc (input_location, PLUS_EXPR,
   2428  1.1  mrg 				   TREE_TYPE (tmp), img_idx, tmp);
   2429  1.1  mrg 	if (i < ref->u.ar.dimen + ref->u.ar.codimen - 1)
   2430  1.1  mrg 	  {
   2431  1.1  mrg 	    ubound = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[i]);
   2432  1.1  mrg 	    tmp = gfc_conv_array_extent_dim (lbound, ubound, NULL);
   2433  1.1  mrg 	    extent = fold_build2_loc (input_location, MULT_EXPR,
   2434  1.1  mrg 				      TREE_TYPE (tmp), extent, tmp);
   2435  1.1  mrg 	  }
   2436  1.1  mrg       }
   2437  1.1  mrg   else
   2438  1.1  mrg     for (i = ref->u.ar.dimen; i < ref->u.ar.dimen + ref->u.ar.codimen; i++)
   2439  1.1  mrg       {
   2440  1.1  mrg 	gfc_init_se (&se, NULL);
   2441  1.1  mrg 	gfc_conv_expr_type (&se, ref->u.ar.start[i], gfc_array_index_type);
   2442  1.1  mrg 	gfc_add_block_to_block (block, &se.pre);
   2443  1.1  mrg 	lbound = GFC_TYPE_ARRAY_LBOUND (TREE_TYPE (desc), i);
   2444  1.1  mrg 	tmp = fold_build2_loc (input_location, MINUS_EXPR,
   2445  1.1  mrg 			       TREE_TYPE (lbound), se.expr, lbound);
   2446  1.1  mrg 	tmp = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (tmp),
   2447  1.1  mrg 			       extent, tmp);
   2448  1.1  mrg 	img_idx = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (tmp),
   2449  1.1  mrg 				   img_idx, tmp);
   2450  1.1  mrg 	if (i < ref->u.ar.dimen + ref->u.ar.codimen - 1)
   2451  1.1  mrg 	  {
   2452  1.1  mrg 	    ubound = GFC_TYPE_ARRAY_UBOUND (TREE_TYPE (desc), i);
   2453  1.1  mrg 	    tmp = fold_build2_loc (input_location, MINUS_EXPR,
   2454  1.1  mrg 				   TREE_TYPE (ubound), ubound, lbound);
   2455  1.1  mrg 	    tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (tmp),
   2456  1.1  mrg 				   tmp, build_one_cst (TREE_TYPE (tmp)));
   2457  1.1  mrg 	    extent = fold_build2_loc (input_location, MULT_EXPR,
   2458  1.1  mrg 				      TREE_TYPE (tmp), extent, tmp);
   2459  1.1  mrg 	  }
   2460  1.1  mrg       }
   2461  1.1  mrg   img_idx = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (img_idx),
   2462  1.1  mrg 			     img_idx, build_one_cst (TREE_TYPE (img_idx)));
   2463  1.1  mrg   return fold_convert (integer_type_node, img_idx);
   2464  1.1  mrg }
   2465  1.1  mrg 
   2466  1.1  mrg 
   2467  1.1  mrg /* For each character array constructor subexpression without a ts.u.cl->length,
   2468  1.1  mrg    replace it by its first element (if there aren't any elements, the length
   2469  1.1  mrg    should already be set to zero).  */
   2470  1.1  mrg 
   2471  1.1  mrg static void
   2472  1.1  mrg flatten_array_ctors_without_strlen (gfc_expr* e)
   2473  1.1  mrg {
   2474  1.1  mrg   gfc_actual_arglist* arg;
   2475  1.1  mrg   gfc_constructor* c;
   2476  1.1  mrg 
   2477  1.1  mrg   if (!e)
   2478  1.1  mrg     return;
   2479  1.1  mrg 
   2480  1.1  mrg   switch (e->expr_type)
   2481  1.1  mrg     {
   2482  1.1  mrg 
   2483  1.1  mrg     case EXPR_OP:
   2484  1.1  mrg       flatten_array_ctors_without_strlen (e->value.op.op1);
   2485  1.1  mrg       flatten_array_ctors_without_strlen (e->value.op.op2);
   2486  1.1  mrg       break;
   2487  1.1  mrg 
   2488  1.1  mrg     case EXPR_COMPCALL:
   2489  1.1  mrg       /* TODO: Implement as with EXPR_FUNCTION when needed.  */
   2490  1.1  mrg       gcc_unreachable ();
   2491  1.1  mrg 
   2492  1.1  mrg     case EXPR_FUNCTION:
   2493  1.1  mrg       for (arg = e->value.function.actual; arg; arg = arg->next)
   2494  1.1  mrg 	flatten_array_ctors_without_strlen (arg->expr);
   2495  1.1  mrg       break;
   2496  1.1  mrg 
   2497  1.1  mrg     case EXPR_ARRAY:
   2498  1.1  mrg 
   2499  1.1  mrg       /* We've found what we're looking for.  */
   2500  1.1  mrg       if (e->ts.type == BT_CHARACTER && !e->ts.u.cl->length)
   2501  1.1  mrg 	{
   2502  1.1  mrg 	  gfc_constructor *c;
   2503  1.1  mrg 	  gfc_expr* new_expr;
   2504  1.1  mrg 
   2505  1.1  mrg 	  gcc_assert (e->value.constructor);
   2506  1.1  mrg 
   2507  1.1  mrg 	  c = gfc_constructor_first (e->value.constructor);
   2508  1.1  mrg 	  new_expr = c->expr;
   2509  1.1  mrg 	  c->expr = NULL;
   2510  1.1  mrg 
   2511  1.1  mrg 	  flatten_array_ctors_without_strlen (new_expr);
   2512  1.1  mrg 	  gfc_replace_expr (e, new_expr);
   2513  1.1  mrg 	  break;
   2514  1.1  mrg 	}
   2515  1.1  mrg 
   2516  1.1  mrg       /* Otherwise, fall through to handle constructor elements.  */
   2517  1.1  mrg       gcc_fallthrough ();
   2518  1.1  mrg     case EXPR_STRUCTURE:
   2519  1.1  mrg       for (c = gfc_constructor_first (e->value.constructor);
   2520  1.1  mrg 	   c; c = gfc_constructor_next (c))
   2521  1.1  mrg 	flatten_array_ctors_without_strlen (c->expr);
   2522  1.1  mrg       break;
   2523  1.1  mrg 
   2524  1.1  mrg     default:
   2525  1.1  mrg       break;
   2526  1.1  mrg 
   2527  1.1  mrg     }
   2528  1.1  mrg }
   2529  1.1  mrg 
   2530  1.1  mrg 
   2531  1.1  mrg /* Generate code to initialize a string length variable. Returns the
   2532  1.1  mrg    value.  For array constructors, cl->length might be NULL and in this case,
   2533  1.1  mrg    the first element of the constructor is needed.  expr is the original
   2534  1.1  mrg    expression so we can access it but can be NULL if this is not needed.  */
   2535  1.1  mrg 
   2536  1.1  mrg void
   2537  1.1  mrg gfc_conv_string_length (gfc_charlen * cl, gfc_expr * expr, stmtblock_t * pblock)
   2538  1.1  mrg {
   2539  1.1  mrg   gfc_se se;
   2540  1.1  mrg 
   2541  1.1  mrg   gfc_init_se (&se, NULL);
   2542  1.1  mrg 
   2543  1.1  mrg   if (!cl->length && cl->backend_decl && VAR_P (cl->backend_decl))
   2544  1.1  mrg     return;
   2545  1.1  mrg 
   2546  1.1  mrg   /* If cl->length is NULL, use gfc_conv_expr to obtain the string length but
   2547  1.1  mrg      "flatten" array constructors by taking their first element; all elements
   2548  1.1  mrg      should be the same length or a cl->length should be present.  */
   2549  1.1  mrg   if (!cl->length)
   2550  1.1  mrg     {
   2551  1.1  mrg       gfc_expr* expr_flat;
   2552  1.1  mrg       if (!expr)
   2553  1.1  mrg 	return;
   2554  1.1  mrg       expr_flat = gfc_copy_expr (expr);
   2555  1.1  mrg       flatten_array_ctors_without_strlen (expr_flat);
   2556  1.1  mrg       gfc_resolve_expr (expr_flat);
   2557  1.1  mrg 
   2558  1.1  mrg       gfc_conv_expr (&se, expr_flat);
   2559  1.1  mrg       gfc_add_block_to_block (pblock, &se.pre);
   2560  1.1  mrg       cl->backend_decl = convert (gfc_charlen_type_node, se.string_length);
   2561  1.1  mrg 
   2562  1.1  mrg       gfc_free_expr (expr_flat);
   2563  1.1  mrg       return;
   2564  1.1  mrg     }
   2565  1.1  mrg 
   2566  1.1  mrg   /* Convert cl->length.  */
   2567  1.1  mrg 
   2568  1.1  mrg   gcc_assert (cl->length);
   2569  1.1  mrg 
   2570  1.1  mrg   gfc_conv_expr_type (&se, cl->length, gfc_charlen_type_node);
   2571  1.1  mrg   se.expr = fold_build2_loc (input_location, MAX_EXPR, gfc_charlen_type_node,
   2572  1.1  mrg 			     se.expr, build_zero_cst (TREE_TYPE (se.expr)));
   2573  1.1  mrg   gfc_add_block_to_block (pblock, &se.pre);
   2574  1.1  mrg 
   2575  1.1  mrg   if (cl->backend_decl && VAR_P (cl->backend_decl))
   2576  1.1  mrg     gfc_add_modify (pblock, cl->backend_decl, se.expr);
   2577  1.1  mrg   else
   2578  1.1  mrg     cl->backend_decl = gfc_evaluate_now (se.expr, pblock);
   2579  1.1  mrg }
   2580  1.1  mrg 
   2581  1.1  mrg 
   2582  1.1  mrg static void
   2583  1.1  mrg gfc_conv_substring (gfc_se * se, gfc_ref * ref, int kind,
   2584  1.1  mrg 		    const char *name, locus *where)
   2585  1.1  mrg {
   2586  1.1  mrg   tree tmp;
   2587  1.1  mrg   tree type;
   2588  1.1  mrg   tree fault;
   2589  1.1  mrg   gfc_se start;
   2590  1.1  mrg   gfc_se end;
   2591  1.1  mrg   char *msg;
   2592  1.1  mrg   mpz_t length;
   2593  1.1  mrg 
   2594  1.1  mrg   type = gfc_get_character_type (kind, ref->u.ss.length);
   2595  1.1  mrg   type = build_pointer_type (type);
   2596  1.1  mrg 
   2597  1.1  mrg   gfc_init_se (&start, se);
   2598  1.1  mrg   gfc_conv_expr_type (&start, ref->u.ss.start, gfc_charlen_type_node);
   2599  1.1  mrg   gfc_add_block_to_block (&se->pre, &start.pre);
   2600  1.1  mrg 
   2601  1.1  mrg   if (integer_onep (start.expr))
   2602  1.1  mrg     gfc_conv_string_parameter (se);
   2603  1.1  mrg   else
   2604  1.1  mrg     {
   2605  1.1  mrg       tmp = start.expr;
   2606  1.1  mrg       STRIP_NOPS (tmp);
   2607  1.1  mrg       /* Avoid multiple evaluation of substring start.  */
   2608  1.1  mrg       if (!CONSTANT_CLASS_P (tmp) && !DECL_P (tmp))
   2609  1.1  mrg 	start.expr = gfc_evaluate_now (start.expr, &se->pre);
   2610  1.1  mrg 
   2611  1.1  mrg       /* Change the start of the string.  */
   2612  1.1  mrg       if ((TREE_CODE (TREE_TYPE (se->expr)) == ARRAY_TYPE
   2613  1.1  mrg 	   || TREE_CODE (TREE_TYPE (se->expr)) == INTEGER_TYPE)
   2614  1.1  mrg 	  && TYPE_STRING_FLAG (TREE_TYPE (se->expr)))
   2615  1.1  mrg 	tmp = se->expr;
   2616  1.1  mrg       else
   2617  1.1  mrg 	tmp = build_fold_indirect_ref_loc (input_location,
   2618  1.1  mrg 				       se->expr);
   2619  1.1  mrg       /* For BIND(C), a BT_CHARACTER is not an ARRAY_TYPE.  */
   2620  1.1  mrg       if (TREE_CODE (TREE_TYPE (tmp)) == ARRAY_TYPE)
   2621  1.1  mrg 	{
   2622  1.1  mrg 	  tmp = gfc_build_array_ref (tmp, start.expr, NULL_TREE, true);
   2623  1.1  mrg 	  se->expr = gfc_build_addr_expr (type, tmp);
   2624  1.1  mrg 	}
   2625  1.1  mrg     }
   2626  1.1  mrg 
   2627  1.1  mrg   /* Length = end + 1 - start.  */
   2628  1.1  mrg   gfc_init_se (&end, se);
   2629  1.1  mrg   if (ref->u.ss.end == NULL)
   2630  1.1  mrg     end.expr = se->string_length;
   2631  1.1  mrg   else
   2632  1.1  mrg     {
   2633  1.1  mrg       gfc_conv_expr_type (&end, ref->u.ss.end, gfc_charlen_type_node);
   2634  1.1  mrg       gfc_add_block_to_block (&se->pre, &end.pre);
   2635  1.1  mrg     }
   2636  1.1  mrg   tmp = end.expr;
   2637  1.1  mrg   STRIP_NOPS (tmp);
   2638  1.1  mrg   if (!CONSTANT_CLASS_P (tmp) && !DECL_P (tmp))
   2639  1.1  mrg     end.expr = gfc_evaluate_now (end.expr, &se->pre);
   2640  1.1  mrg 
   2641  1.1  mrg   if ((gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
   2642  1.1  mrg       && (ref->u.ss.start->symtree
   2643  1.1  mrg 	  && !ref->u.ss.start->symtree->n.sym->attr.implied_index))
   2644  1.1  mrg     {
   2645  1.1  mrg       tree nonempty = fold_build2_loc (input_location, LE_EXPR,
   2646  1.1  mrg 				       logical_type_node, start.expr,
   2647  1.1  mrg 				       end.expr);
   2648  1.1  mrg 
   2649  1.1  mrg       /* Check lower bound.  */
   2650  1.1  mrg       fault = fold_build2_loc (input_location, LT_EXPR, logical_type_node,
   2651  1.1  mrg 			       start.expr,
   2652  1.1  mrg 			       build_one_cst (TREE_TYPE (start.expr)));
   2653  1.1  mrg       fault = fold_build2_loc (input_location, TRUTH_ANDIF_EXPR,
   2654  1.1  mrg 			       logical_type_node, nonempty, fault);
   2655  1.1  mrg       if (name)
   2656  1.1  mrg 	msg = xasprintf ("Substring out of bounds: lower bound (%%ld) of '%s' "
   2657  1.1  mrg 			 "is less than one", name);
   2658  1.1  mrg       else
   2659  1.1  mrg 	msg = xasprintf ("Substring out of bounds: lower bound (%%ld) "
   2660  1.1  mrg 			 "is less than one");
   2661  1.1  mrg       gfc_trans_runtime_check (true, false, fault, &se->pre, where, msg,
   2662  1.1  mrg 			       fold_convert (long_integer_type_node,
   2663  1.1  mrg 					     start.expr));
   2664  1.1  mrg       free (msg);
   2665  1.1  mrg 
   2666  1.1  mrg       /* Check upper bound.  */
   2667  1.1  mrg       fault = fold_build2_loc (input_location, GT_EXPR, logical_type_node,
   2668  1.1  mrg 			       end.expr, se->string_length);
   2669  1.1  mrg       fault = fold_build2_loc (input_location, TRUTH_ANDIF_EXPR,
   2670  1.1  mrg 			       logical_type_node, nonempty, fault);
   2671  1.1  mrg       if (name)
   2672  1.1  mrg 	msg = xasprintf ("Substring out of bounds: upper bound (%%ld) of '%s' "
   2673  1.1  mrg 			 "exceeds string length (%%ld)", name);
   2674  1.1  mrg       else
   2675  1.1  mrg 	msg = xasprintf ("Substring out of bounds: upper bound (%%ld) "
   2676  1.1  mrg 			 "exceeds string length (%%ld)");
   2677  1.1  mrg       gfc_trans_runtime_check (true, false, fault, &se->pre, where, msg,
   2678  1.1  mrg 			       fold_convert (long_integer_type_node, end.expr),
   2679  1.1  mrg 			       fold_convert (long_integer_type_node,
   2680  1.1  mrg 					     se->string_length));
   2681  1.1  mrg       free (msg);
   2682  1.1  mrg     }
   2683  1.1  mrg 
   2684  1.1  mrg   /* Try to calculate the length from the start and end expressions.  */
   2685  1.1  mrg   if (ref->u.ss.end
   2686  1.1  mrg       && gfc_dep_difference (ref->u.ss.end, ref->u.ss.start, &length))
   2687  1.1  mrg     {
   2688  1.1  mrg       HOST_WIDE_INT i_len;
   2689  1.1  mrg 
   2690  1.1  mrg       i_len = gfc_mpz_get_hwi (length) + 1;
   2691  1.1  mrg       if (i_len < 0)
   2692  1.1  mrg 	i_len = 0;
   2693  1.1  mrg 
   2694  1.1  mrg       tmp = build_int_cst (gfc_charlen_type_node, i_len);
   2695  1.1  mrg       mpz_clear (length);  /* Was initialized by gfc_dep_difference.  */
   2696  1.1  mrg     }
   2697  1.1  mrg   else
   2698  1.1  mrg     {
   2699  1.1  mrg       tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_charlen_type_node,
   2700  1.1  mrg 			     fold_convert (gfc_charlen_type_node, end.expr),
   2701  1.1  mrg 			     fold_convert (gfc_charlen_type_node, start.expr));
   2702  1.1  mrg       tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_charlen_type_node,
   2703  1.1  mrg 			     build_int_cst (gfc_charlen_type_node, 1), tmp);
   2704  1.1  mrg       tmp = fold_build2_loc (input_location, MAX_EXPR, gfc_charlen_type_node,
   2705  1.1  mrg 			     tmp, build_int_cst (gfc_charlen_type_node, 0));
   2706  1.1  mrg     }
   2707  1.1  mrg 
   2708  1.1  mrg   se->string_length = tmp;
   2709  1.1  mrg }
   2710  1.1  mrg 
   2711  1.1  mrg 
   2712  1.1  mrg /* Convert a derived type component reference.  */
   2713  1.1  mrg 
   2714  1.1  mrg void
   2715  1.1  mrg gfc_conv_component_ref (gfc_se * se, gfc_ref * ref)
   2716  1.1  mrg {
   2717  1.1  mrg   gfc_component *c;
   2718  1.1  mrg   tree tmp;
   2719  1.1  mrg   tree decl;
   2720  1.1  mrg   tree field;
   2721  1.1  mrg   tree context;
   2722  1.1  mrg 
   2723  1.1  mrg   c = ref->u.c.component;
   2724  1.1  mrg 
   2725  1.1  mrg   if (c->backend_decl == NULL_TREE
   2726  1.1  mrg       && ref->u.c.sym != NULL)
   2727  1.1  mrg     gfc_get_derived_type (ref->u.c.sym);
   2728  1.1  mrg 
   2729  1.1  mrg   field = c->backend_decl;
   2730  1.1  mrg   gcc_assert (field && TREE_CODE (field) == FIELD_DECL);
   2731  1.1  mrg   decl = se->expr;
   2732  1.1  mrg   context = DECL_FIELD_CONTEXT (field);
   2733  1.1  mrg 
   2734  1.1  mrg   /* Components can correspond to fields of different containing
   2735  1.1  mrg      types, as components are created without context, whereas
   2736  1.1  mrg      a concrete use of a component has the type of decl as context.
   2737  1.1  mrg      So, if the type doesn't match, we search the corresponding
   2738  1.1  mrg      FIELD_DECL in the parent type.  To not waste too much time
   2739  1.1  mrg      we cache this result in norestrict_decl.
   2740  1.1  mrg      On the other hand, if the context is a UNION or a MAP (a
   2741  1.1  mrg      RECORD_TYPE within a UNION_TYPE) always use the given FIELD_DECL.  */
   2742  1.1  mrg 
   2743  1.1  mrg   if (context != TREE_TYPE (decl)
   2744  1.1  mrg       && !(   TREE_CODE (TREE_TYPE (field)) == UNION_TYPE /* Field is union */
   2745  1.1  mrg            || TREE_CODE (context) == UNION_TYPE))         /* Field is map */
   2746  1.1  mrg     {
   2747  1.1  mrg       tree f2 = c->norestrict_decl;
   2748  1.1  mrg       if (!f2 || DECL_FIELD_CONTEXT (f2) != TREE_TYPE (decl))
   2749  1.1  mrg 	for (f2 = TYPE_FIELDS (TREE_TYPE (decl)); f2; f2 = DECL_CHAIN (f2))
   2750  1.1  mrg 	  if (TREE_CODE (f2) == FIELD_DECL
   2751  1.1  mrg 	      && DECL_NAME (f2) == DECL_NAME (field))
   2752  1.1  mrg 	    break;
   2753  1.1  mrg       gcc_assert (f2);
   2754  1.1  mrg       c->norestrict_decl = f2;
   2755  1.1  mrg       field = f2;
   2756  1.1  mrg     }
   2757  1.1  mrg 
   2758  1.1  mrg   if (ref->u.c.sym && ref->u.c.sym->ts.type == BT_CLASS
   2759  1.1  mrg       && strcmp ("_data", c->name) == 0)
   2760  1.1  mrg     {
   2761  1.1  mrg       /* Found a ref to the _data component.  Store the associated ref to
   2762  1.1  mrg 	 the vptr in se->class_vptr.  */
   2763  1.1  mrg       se->class_vptr = gfc_class_vptr_get (decl);
   2764  1.1  mrg     }
   2765  1.1  mrg   else
   2766  1.1  mrg     se->class_vptr = NULL_TREE;
   2767  1.1  mrg 
   2768  1.1  mrg   tmp = fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field),
   2769  1.1  mrg 			 decl, field, NULL_TREE);
   2770  1.1  mrg 
   2771  1.1  mrg   se->expr = tmp;
   2772  1.1  mrg 
   2773  1.1  mrg   /* Allocatable deferred char arrays are to be handled by the gfc_deferred_
   2774  1.1  mrg      strlen () conditional below.  */
   2775  1.1  mrg   if (c->ts.type == BT_CHARACTER && !c->attr.proc_pointer
   2776  1.1  mrg       && !c->ts.deferred
   2777  1.1  mrg       && !c->attr.pdt_string)
   2778  1.1  mrg     {
   2779  1.1  mrg       tmp = c->ts.u.cl->backend_decl;
   2780  1.1  mrg       /* Components must always be constant length.  */
   2781  1.1  mrg       gcc_assert (tmp && INTEGER_CST_P (tmp));
   2782  1.1  mrg       se->string_length = tmp;
   2783  1.1  mrg     }
   2784  1.1  mrg 
   2785  1.1  mrg   if (gfc_deferred_strlen (c, &field))
   2786  1.1  mrg     {
   2787  1.1  mrg       tmp = fold_build3_loc (input_location, COMPONENT_REF,
   2788  1.1  mrg 			     TREE_TYPE (field),
   2789  1.1  mrg 			     decl, field, NULL_TREE);
   2790  1.1  mrg       se->string_length = tmp;
   2791  1.1  mrg     }
   2792  1.1  mrg 
   2793  1.1  mrg   if (((c->attr.pointer || c->attr.allocatable)
   2794  1.1  mrg        && (!c->attr.dimension && !c->attr.codimension)
   2795  1.1  mrg        && c->ts.type != BT_CHARACTER)
   2796  1.1  mrg       || c->attr.proc_pointer)
   2797  1.1  mrg     se->expr = build_fold_indirect_ref_loc (input_location,
   2798  1.1  mrg 					se->expr);
   2799  1.1  mrg }
   2800  1.1  mrg 
   2801  1.1  mrg 
   2802  1.1  mrg /* This function deals with component references to components of the
   2803  1.1  mrg    parent type for derived type extensions.  */
   2804  1.1  mrg void
   2805  1.1  mrg conv_parent_component_references (gfc_se * se, gfc_ref * ref)
   2806  1.1  mrg {
   2807  1.1  mrg   gfc_component *c;
   2808  1.1  mrg   gfc_component *cmp;
   2809  1.1  mrg   gfc_symbol *dt;
   2810  1.1  mrg   gfc_ref parent;
   2811  1.1  mrg 
   2812  1.1  mrg   dt = ref->u.c.sym;
   2813  1.1  mrg   c = ref->u.c.component;
   2814  1.1  mrg 
   2815  1.1  mrg   /* Return if the component is in this type, i.e. not in the parent type.  */
   2816  1.1  mrg   for (cmp = dt->components; cmp; cmp = cmp->next)
   2817  1.1  mrg     if (c == cmp)
   2818  1.1  mrg       return;
   2819  1.1  mrg 
   2820  1.1  mrg   /* Build a gfc_ref to recursively call gfc_conv_component_ref.  */
   2821  1.1  mrg   parent.type = REF_COMPONENT;
   2822  1.1  mrg   parent.next = NULL;
   2823  1.1  mrg   parent.u.c.sym = dt;
   2824  1.1  mrg   parent.u.c.component = dt->components;
   2825  1.1  mrg 
   2826  1.1  mrg   if (dt->backend_decl == NULL)
   2827  1.1  mrg     gfc_get_derived_type (dt);
   2828  1.1  mrg 
   2829  1.1  mrg   /* Build the reference and call self.  */
   2830  1.1  mrg   gfc_conv_component_ref (se, &parent);
   2831  1.1  mrg   parent.u.c.sym = dt->components->ts.u.derived;
   2832  1.1  mrg   parent.u.c.component = c;
   2833  1.1  mrg   conv_parent_component_references (se, &parent);
   2834  1.1  mrg }
   2835  1.1  mrg 
   2836  1.1  mrg 
   2837  1.1  mrg static void
   2838  1.1  mrg conv_inquiry (gfc_se * se, gfc_ref * ref, gfc_expr *expr, gfc_typespec *ts)
   2839  1.1  mrg {
   2840  1.1  mrg   tree res = se->expr;
   2841  1.1  mrg 
   2842  1.1  mrg   switch (ref->u.i)
   2843  1.1  mrg     {
   2844  1.1  mrg     case INQUIRY_RE:
   2845  1.1  mrg       res = fold_build1_loc (input_location, REALPART_EXPR,
   2846  1.1  mrg 			     TREE_TYPE (TREE_TYPE (res)), res);
   2847  1.1  mrg       break;
   2848  1.1  mrg 
   2849  1.1  mrg     case INQUIRY_IM:
   2850  1.1  mrg       res = fold_build1_loc (input_location, IMAGPART_EXPR,
   2851  1.1  mrg 			     TREE_TYPE (TREE_TYPE (res)), res);
   2852  1.1  mrg       break;
   2853  1.1  mrg 
   2854  1.1  mrg     case INQUIRY_KIND:
   2855  1.1  mrg       res = build_int_cst (gfc_typenode_for_spec (&expr->ts),
   2856  1.1  mrg 			   ts->kind);
   2857  1.1  mrg       se->string_length = NULL_TREE;
   2858  1.1  mrg       break;
   2859  1.1  mrg 
   2860  1.1  mrg     case INQUIRY_LEN:
   2861  1.1  mrg       res = fold_convert (gfc_typenode_for_spec (&expr->ts),
   2862  1.1  mrg 			  se->string_length);
   2863  1.1  mrg       se->string_length = NULL_TREE;
   2864  1.1  mrg       break;
   2865  1.1  mrg 
   2866  1.1  mrg     default:
   2867  1.1  mrg       gcc_unreachable ();
   2868  1.1  mrg     }
   2869  1.1  mrg   se->expr = res;
   2870  1.1  mrg }
   2871  1.1  mrg 
   2872  1.1  mrg /* Dereference VAR where needed if it is a pointer, reference, etc.
   2873  1.1  mrg    according to Fortran semantics.  */
   2874  1.1  mrg 
   2875  1.1  mrg tree
   2876  1.1  mrg gfc_maybe_dereference_var (gfc_symbol *sym, tree var, bool descriptor_only_p,
   2877  1.1  mrg 			   bool is_classarray)
   2878  1.1  mrg {
   2879  1.1  mrg   if (!POINTER_TYPE_P (TREE_TYPE (var)))
   2880  1.1  mrg     return var;
   2881  1.1  mrg   if (is_CFI_desc (sym, NULL))
   2882  1.1  mrg     return build_fold_indirect_ref_loc (input_location, var);
   2883  1.1  mrg 
   2884  1.1  mrg   /* Characters are entirely different from other types, they are treated
   2885  1.1  mrg      separately.  */
   2886  1.1  mrg   if (sym->ts.type == BT_CHARACTER)
   2887  1.1  mrg     {
   2888  1.1  mrg       /* Dereference character pointer dummy arguments
   2889  1.1  mrg 	 or results.  */
   2890  1.1  mrg       if ((sym->attr.pointer || sym->attr.allocatable
   2891  1.1  mrg 	   || (sym->as && sym->as->type == AS_ASSUMED_RANK))
   2892  1.1  mrg 	  && (sym->attr.dummy
   2893  1.1  mrg 	      || sym->attr.function
   2894  1.1  mrg 	      || sym->attr.result))
   2895  1.1  mrg 	var = build_fold_indirect_ref_loc (input_location, var);
   2896  1.1  mrg     }
   2897  1.1  mrg   else if (!sym->attr.value)
   2898  1.1  mrg     {
   2899  1.1  mrg       /* Dereference temporaries for class array dummy arguments.  */
   2900  1.1  mrg       if (sym->attr.dummy && is_classarray
   2901  1.1  mrg 	  && GFC_ARRAY_TYPE_P (TREE_TYPE (var)))
   2902  1.1  mrg 	{
   2903  1.1  mrg 	  if (!descriptor_only_p)
   2904  1.1  mrg 	    var = GFC_DECL_SAVED_DESCRIPTOR (var);
   2905  1.1  mrg 
   2906  1.1  mrg 	  var = build_fold_indirect_ref_loc (input_location, var);
   2907  1.1  mrg 	}
   2908  1.1  mrg 
   2909  1.1  mrg       /* Dereference non-character scalar dummy arguments.  */
   2910  1.1  mrg       if (sym->attr.dummy && !sym->attr.dimension
   2911  1.1  mrg 	  && !(sym->attr.codimension && sym->attr.allocatable)
   2912  1.1  mrg 	  && (sym->ts.type != BT_CLASS
   2913  1.1  mrg 	      || (!CLASS_DATA (sym)->attr.dimension
   2914  1.1  mrg 		  && !(CLASS_DATA (sym)->attr.codimension
   2915  1.1  mrg 		       && CLASS_DATA (sym)->attr.allocatable))))
   2916  1.1  mrg 	var = build_fold_indirect_ref_loc (input_location, var);
   2917  1.1  mrg 
   2918  1.1  mrg       /* Dereference scalar hidden result.  */
   2919  1.1  mrg       if (flag_f2c && sym->ts.type == BT_COMPLEX
   2920  1.1  mrg 	  && (sym->attr.function || sym->attr.result)
   2921  1.1  mrg 	  && !sym->attr.dimension && !sym->attr.pointer
   2922  1.1  mrg 	  && !sym->attr.always_explicit)
   2923  1.1  mrg 	var = build_fold_indirect_ref_loc (input_location, var);
   2924  1.1  mrg 
   2925  1.1  mrg       /* Dereference non-character, non-class pointer variables.
   2926  1.1  mrg 	 These must be dummies, results, or scalars.  */
   2927  1.1  mrg       if (!is_classarray
   2928  1.1  mrg 	  && (sym->attr.pointer || sym->attr.allocatable
   2929  1.1  mrg 	      || gfc_is_associate_pointer (sym)
   2930  1.1  mrg 	      || (sym->as && sym->as->type == AS_ASSUMED_RANK))
   2931  1.1  mrg 	  && (sym->attr.dummy
   2932  1.1  mrg 	      || sym->attr.function
   2933  1.1  mrg 	      || sym->attr.result
   2934  1.1  mrg 	      || (!sym->attr.dimension
   2935  1.1  mrg 		  && (!sym->attr.codimension || !sym->attr.allocatable))))
   2936  1.1  mrg 	var = build_fold_indirect_ref_loc (input_location, var);
   2937  1.1  mrg       /* Now treat the class array pointer variables accordingly.  */
   2938  1.1  mrg       else if (sym->ts.type == BT_CLASS
   2939  1.1  mrg 	       && sym->attr.dummy
   2940  1.1  mrg 	       && (CLASS_DATA (sym)->attr.dimension
   2941  1.1  mrg 		   || CLASS_DATA (sym)->attr.codimension)
   2942  1.1  mrg 	       && ((CLASS_DATA (sym)->as
   2943  1.1  mrg 		    && CLASS_DATA (sym)->as->type == AS_ASSUMED_RANK)
   2944  1.1  mrg 		   || CLASS_DATA (sym)->attr.allocatable
   2945  1.1  mrg 		   || CLASS_DATA (sym)->attr.class_pointer))
   2946  1.1  mrg 	var = build_fold_indirect_ref_loc (input_location, var);
   2947  1.1  mrg       /* And the case where a non-dummy, non-result, non-function,
   2948  1.1  mrg 	 non-allocable and non-pointer classarray is present.  This case was
   2949  1.1  mrg 	 previously covered by the first if, but with introducing the
   2950  1.1  mrg 	 condition !is_classarray there, that case has to be covered
   2951  1.1  mrg 	 explicitly.  */
   2952  1.1  mrg       else if (sym->ts.type == BT_CLASS
   2953  1.1  mrg 	       && !sym->attr.dummy
   2954  1.1  mrg 	       && !sym->attr.function
   2955  1.1  mrg 	       && !sym->attr.result
   2956  1.1  mrg 	       && (CLASS_DATA (sym)->attr.dimension
   2957  1.1  mrg 		   || CLASS_DATA (sym)->attr.codimension)
   2958  1.1  mrg 	       && (sym->assoc
   2959  1.1  mrg 		   || !CLASS_DATA (sym)->attr.allocatable)
   2960  1.1  mrg 	       && !CLASS_DATA (sym)->attr.class_pointer)
   2961  1.1  mrg 	var = build_fold_indirect_ref_loc (input_location, var);
   2962  1.1  mrg     }
   2963  1.1  mrg 
   2964  1.1  mrg   return var;
   2965  1.1  mrg }
   2966  1.1  mrg 
   2967  1.1  mrg /* Return the contents of a variable. Also handles reference/pointer
   2968  1.1  mrg    variables (all Fortran pointer references are implicit).  */
   2969  1.1  mrg 
   2970  1.1  mrg static void
   2971  1.1  mrg gfc_conv_variable (gfc_se * se, gfc_expr * expr)
   2972  1.1  mrg {
   2973  1.1  mrg   gfc_ss *ss;
   2974  1.1  mrg   gfc_ref *ref;
   2975  1.1  mrg   gfc_symbol *sym;
   2976  1.1  mrg   tree parent_decl = NULL_TREE;
   2977  1.1  mrg   int parent_flag;
   2978  1.1  mrg   bool return_value;
   2979  1.1  mrg   bool alternate_entry;
   2980  1.1  mrg   bool entry_master;
   2981  1.1  mrg   bool is_classarray;
   2982  1.1  mrg   bool first_time = true;
   2983  1.1  mrg 
   2984  1.1  mrg   sym = expr->symtree->n.sym;
   2985  1.1  mrg   is_classarray = IS_CLASS_ARRAY (sym);
   2986  1.1  mrg   ss = se->ss;
   2987  1.1  mrg   if (ss != NULL)
   2988  1.1  mrg     {
   2989  1.1  mrg       gfc_ss_info *ss_info = ss->info;
   2990  1.1  mrg 
   2991  1.1  mrg       /* Check that something hasn't gone horribly wrong.  */
   2992  1.1  mrg       gcc_assert (ss != gfc_ss_terminator);
   2993  1.1  mrg       gcc_assert (ss_info->expr == expr);
   2994  1.1  mrg 
   2995  1.1  mrg       /* A scalarized term.  We already know the descriptor.  */
   2996  1.1  mrg       se->expr = ss_info->data.array.descriptor;
   2997  1.1  mrg       se->string_length = ss_info->string_length;
   2998  1.1  mrg       ref = ss_info->data.array.ref;
   2999  1.1  mrg       if (ref)
   3000  1.1  mrg 	gcc_assert (ref->type == REF_ARRAY
   3001  1.1  mrg 		    && ref->u.ar.type != AR_ELEMENT);
   3002  1.1  mrg       else
   3003  1.1  mrg 	gfc_conv_tmp_array_ref (se);
   3004  1.1  mrg     }
   3005  1.1  mrg   else
   3006  1.1  mrg     {
   3007  1.1  mrg       tree se_expr = NULL_TREE;
   3008  1.1  mrg 
   3009  1.1  mrg       se->expr = gfc_get_symbol_decl (sym);
   3010  1.1  mrg 
   3011  1.1  mrg       /* Deal with references to a parent results or entries by storing
   3012  1.1  mrg 	 the current_function_decl and moving to the parent_decl.  */
   3013  1.1  mrg       return_value = sym->attr.function && sym->result == sym;
   3014  1.1  mrg       alternate_entry = sym->attr.function && sym->attr.entry
   3015  1.1  mrg 			&& sym->result == sym;
   3016  1.1  mrg       entry_master = sym->attr.result
   3017  1.1  mrg 		     && sym->ns->proc_name->attr.entry_master
   3018  1.1  mrg 		     && !gfc_return_by_reference (sym->ns->proc_name);
   3019  1.1  mrg       if (current_function_decl)
   3020  1.1  mrg 	parent_decl = DECL_CONTEXT (current_function_decl);
   3021  1.1  mrg 
   3022  1.1  mrg       if ((se->expr == parent_decl && return_value)
   3023  1.1  mrg 	   || (sym->ns && sym->ns->proc_name
   3024  1.1  mrg 	       && parent_decl
   3025  1.1  mrg 	       && sym->ns->proc_name->backend_decl == parent_decl
   3026  1.1  mrg 	       && (alternate_entry || entry_master)))
   3027  1.1  mrg 	parent_flag = 1;
   3028  1.1  mrg       else
   3029  1.1  mrg 	parent_flag = 0;
   3030  1.1  mrg 
   3031  1.1  mrg       /* Special case for assigning the return value of a function.
   3032  1.1  mrg 	 Self recursive functions must have an explicit return value.  */
   3033  1.1  mrg       if (return_value && (se->expr == current_function_decl || parent_flag))
   3034  1.1  mrg 	se_expr = gfc_get_fake_result_decl (sym, parent_flag);
   3035  1.1  mrg 
   3036  1.1  mrg       /* Similarly for alternate entry points.  */
   3037  1.1  mrg       else if (alternate_entry
   3038  1.1  mrg 	       && (sym->ns->proc_name->backend_decl == current_function_decl
   3039  1.1  mrg 		   || parent_flag))
   3040  1.1  mrg 	{
   3041  1.1  mrg 	  gfc_entry_list *el = NULL;
   3042  1.1  mrg 
   3043  1.1  mrg 	  for (el = sym->ns->entries; el; el = el->next)
   3044  1.1  mrg 	    if (sym == el->sym)
   3045  1.1  mrg 	      {
   3046  1.1  mrg 		se_expr = gfc_get_fake_result_decl (sym, parent_flag);
   3047  1.1  mrg 		break;
   3048  1.1  mrg 	      }
   3049  1.1  mrg 	}
   3050  1.1  mrg 
   3051  1.1  mrg       else if (entry_master
   3052  1.1  mrg 	       && (sym->ns->proc_name->backend_decl == current_function_decl
   3053  1.1  mrg 		   || parent_flag))
   3054  1.1  mrg 	se_expr = gfc_get_fake_result_decl (sym, parent_flag);
   3055  1.1  mrg 
   3056  1.1  mrg       if (se_expr)
   3057  1.1  mrg 	se->expr = se_expr;
   3058  1.1  mrg 
   3059  1.1  mrg       /* Procedure actual arguments.  Look out for temporary variables
   3060  1.1  mrg 	 with the same attributes as function values.  */
   3061  1.1  mrg       else if (!sym->attr.temporary
   3062  1.1  mrg 	       && sym->attr.flavor == FL_PROCEDURE
   3063  1.1  mrg 	       && se->expr != current_function_decl)
   3064  1.1  mrg 	{
   3065  1.1  mrg 	  if (!sym->attr.dummy && !sym->attr.proc_pointer)
   3066  1.1  mrg 	    {
   3067  1.1  mrg 	      gcc_assert (TREE_CODE (se->expr) == FUNCTION_DECL);
   3068  1.1  mrg 	      se->expr = gfc_build_addr_expr (NULL_TREE, se->expr);
   3069  1.1  mrg 	    }
   3070  1.1  mrg 	  return;
   3071  1.1  mrg 	}
   3072  1.1  mrg 
   3073  1.1  mrg       /* Dereference the expression, where needed.  */
   3074  1.1  mrg       se->expr = gfc_maybe_dereference_var (sym, se->expr, se->descriptor_only,
   3075  1.1  mrg 					    is_classarray);
   3076  1.1  mrg 
   3077  1.1  mrg       ref = expr->ref;
   3078  1.1  mrg     }
   3079  1.1  mrg 
   3080  1.1  mrg   /* For character variables, also get the length.  */
   3081  1.1  mrg   if (sym->ts.type == BT_CHARACTER)
   3082  1.1  mrg     {
   3083  1.1  mrg       /* If the character length of an entry isn't set, get the length from
   3084  1.1  mrg          the master function instead.  */
   3085  1.1  mrg       if (sym->attr.entry && !sym->ts.u.cl->backend_decl)
   3086  1.1  mrg         se->string_length = sym->ns->proc_name->ts.u.cl->backend_decl;
   3087  1.1  mrg       else
   3088  1.1  mrg         se->string_length = sym->ts.u.cl->backend_decl;
   3089  1.1  mrg       gcc_assert (se->string_length);
   3090  1.1  mrg     }
   3091  1.1  mrg 
   3092  1.1  mrg   gfc_typespec *ts = &sym->ts;
   3093  1.1  mrg   while (ref)
   3094  1.1  mrg     {
   3095  1.1  mrg       switch (ref->type)
   3096  1.1  mrg 	{
   3097  1.1  mrg 	case REF_ARRAY:
   3098  1.1  mrg 	  /* Return the descriptor if that's what we want and this is an array
   3099  1.1  mrg 	     section reference.  */
   3100  1.1  mrg 	  if (se->descriptor_only && ref->u.ar.type != AR_ELEMENT)
   3101  1.1  mrg 	    return;
   3102  1.1  mrg /* TODO: Pointers to single elements of array sections, eg elemental subs.  */
   3103  1.1  mrg 	  /* Return the descriptor for array pointers and allocations.  */
   3104  1.1  mrg 	  if (se->want_pointer
   3105  1.1  mrg 	      && ref->next == NULL && (se->descriptor_only))
   3106  1.1  mrg 	    return;
   3107  1.1  mrg 
   3108  1.1  mrg 	  gfc_conv_array_ref (se, &ref->u.ar, expr, &expr->where);
   3109  1.1  mrg 	  /* Return a pointer to an element.  */
   3110  1.1  mrg 	  break;
   3111  1.1  mrg 
   3112  1.1  mrg 	case REF_COMPONENT:
   3113  1.1  mrg 	  ts = &ref->u.c.component->ts;
   3114  1.1  mrg 	  if (first_time && is_classarray && sym->attr.dummy
   3115  1.1  mrg 	      && se->descriptor_only
   3116  1.1  mrg 	      && !CLASS_DATA (sym)->attr.allocatable
   3117  1.1  mrg 	      && !CLASS_DATA (sym)->attr.class_pointer
   3118  1.1  mrg 	      && CLASS_DATA (sym)->as
   3119  1.1  mrg 	      && CLASS_DATA (sym)->as->type != AS_ASSUMED_RANK
   3120  1.1  mrg 	      && strcmp ("_data", ref->u.c.component->name) == 0)
   3121  1.1  mrg 	    /* Skip the first ref of a _data component, because for class
   3122  1.1  mrg 	       arrays that one is already done by introducing a temporary
   3123  1.1  mrg 	       array descriptor.  */
   3124  1.1  mrg 	    break;
   3125  1.1  mrg 
   3126  1.1  mrg 	  if (ref->u.c.sym->attr.extension)
   3127  1.1  mrg 	    conv_parent_component_references (se, ref);
   3128  1.1  mrg 
   3129  1.1  mrg 	  gfc_conv_component_ref (se, ref);
   3130  1.1  mrg 	  if (!ref->next && ref->u.c.sym->attr.codimension
   3131  1.1  mrg 	      && se->want_pointer && se->descriptor_only)
   3132  1.1  mrg 	    return;
   3133  1.1  mrg 
   3134  1.1  mrg 	  break;
   3135  1.1  mrg 
   3136  1.1  mrg 	case REF_SUBSTRING:
   3137  1.1  mrg 	  gfc_conv_substring (se, ref, expr->ts.kind,
   3138  1.1  mrg 			      expr->symtree->name, &expr->where);
   3139  1.1  mrg 	  break;
   3140  1.1  mrg 
   3141  1.1  mrg 	case REF_INQUIRY:
   3142  1.1  mrg 	  conv_inquiry (se, ref, expr, ts);
   3143  1.1  mrg 	  break;
   3144  1.1  mrg 
   3145  1.1  mrg 	default:
   3146  1.1  mrg 	  gcc_unreachable ();
   3147  1.1  mrg 	  break;
   3148  1.1  mrg 	}
   3149  1.1  mrg       first_time = false;
   3150  1.1  mrg       ref = ref->next;
   3151  1.1  mrg     }
   3152  1.1  mrg   /* Pointer assignment, allocation or pass by reference.  Arrays are handled
   3153  1.1  mrg      separately.  */
   3154  1.1  mrg   if (se->want_pointer)
   3155  1.1  mrg     {
   3156  1.1  mrg       if (expr->ts.type == BT_CHARACTER && !gfc_is_proc_ptr_comp (expr))
   3157  1.1  mrg 	gfc_conv_string_parameter (se);
   3158  1.1  mrg       else
   3159  1.1  mrg 	se->expr = gfc_build_addr_expr (NULL_TREE, se->expr);
   3160  1.1  mrg     }
   3161  1.1  mrg }
   3162  1.1  mrg 
   3163  1.1  mrg 
   3164  1.1  mrg /* Unary ops are easy... Or they would be if ! was a valid op.  */
   3165  1.1  mrg 
   3166  1.1  mrg static void
   3167  1.1  mrg gfc_conv_unary_op (enum tree_code code, gfc_se * se, gfc_expr * expr)
   3168  1.1  mrg {
   3169  1.1  mrg   gfc_se operand;
   3170  1.1  mrg   tree type;
   3171  1.1  mrg 
   3172  1.1  mrg   gcc_assert (expr->ts.type != BT_CHARACTER);
   3173  1.1  mrg   /* Initialize the operand.  */
   3174  1.1  mrg   gfc_init_se (&operand, se);
   3175  1.1  mrg   gfc_conv_expr_val (&operand, expr->value.op.op1);
   3176  1.1  mrg   gfc_add_block_to_block (&se->pre, &operand.pre);
   3177  1.1  mrg 
   3178  1.1  mrg   type = gfc_typenode_for_spec (&expr->ts);
   3179  1.1  mrg 
   3180  1.1  mrg   /* TRUTH_NOT_EXPR is not a "true" unary operator in GCC.
   3181  1.1  mrg      We must convert it to a compare to 0 (e.g. EQ_EXPR (op1, 0)).
   3182  1.1  mrg      All other unary operators have an equivalent GIMPLE unary operator.  */
   3183  1.1  mrg   if (code == TRUTH_NOT_EXPR)
   3184  1.1  mrg     se->expr = fold_build2_loc (input_location, EQ_EXPR, type, operand.expr,
   3185  1.1  mrg 				build_int_cst (type, 0));
   3186  1.1  mrg   else
   3187  1.1  mrg     se->expr = fold_build1_loc (input_location, code, type, operand.expr);
   3188  1.1  mrg 
   3189  1.1  mrg }
   3190  1.1  mrg 
   3191  1.1  mrg /* Expand power operator to optimal multiplications when a value is raised
   3192  1.1  mrg    to a constant integer n. See section 4.6.3, "Evaluation of Powers" of
   3193  1.1  mrg    Donald E. Knuth, "Seminumerical Algorithms", Vol. 2, "The Art of Computer
   3194  1.1  mrg    Programming", 3rd Edition, 1998.  */
   3195  1.1  mrg 
   3196  1.1  mrg /* This code is mostly duplicated from expand_powi in the backend.
   3197  1.1  mrg    We establish the "optimal power tree" lookup table with the defined size.
   3198  1.1  mrg    The items in the table are the exponents used to calculate the index
   3199  1.1  mrg    exponents. Any integer n less than the value can get an "addition chain",
   3200  1.1  mrg    with the first node being one.  */
   3201  1.1  mrg #define POWI_TABLE_SIZE 256
   3202  1.1  mrg 
   3203  1.1  mrg /* The table is from builtins.cc.  */
   3204  1.1  mrg static const unsigned char powi_table[POWI_TABLE_SIZE] =
   3205  1.1  mrg   {
   3206  1.1  mrg       0,   1,   1,   2,   2,   3,   3,   4,  /*   0 -   7 */
   3207  1.1  mrg       4,   6,   5,   6,   6,  10,   7,   9,  /*   8 -  15 */
   3208  1.1  mrg       8,  16,   9,  16,  10,  12,  11,  13,  /*  16 -  23 */
   3209  1.1  mrg      12,  17,  13,  18,  14,  24,  15,  26,  /*  24 -  31 */
   3210  1.1  mrg      16,  17,  17,  19,  18,  33,  19,  26,  /*  32 -  39 */
   3211  1.1  mrg      20,  25,  21,  40,  22,  27,  23,  44,  /*  40 -  47 */
   3212  1.1  mrg      24,  32,  25,  34,  26,  29,  27,  44,  /*  48 -  55 */
   3213  1.1  mrg      28,  31,  29,  34,  30,  60,  31,  36,  /*  56 -  63 */
   3214  1.1  mrg      32,  64,  33,  34,  34,  46,  35,  37,  /*  64 -  71 */
   3215  1.1  mrg      36,  65,  37,  50,  38,  48,  39,  69,  /*  72 -  79 */
   3216  1.1  mrg      40,  49,  41,  43,  42,  51,  43,  58,  /*  80 -  87 */
   3217  1.1  mrg      44,  64,  45,  47,  46,  59,  47,  76,  /*  88 -  95 */
   3218  1.1  mrg      48,  65,  49,  66,  50,  67,  51,  66,  /*  96 - 103 */
   3219  1.1  mrg      52,  70,  53,  74,  54, 104,  55,  74,  /* 104 - 111 */
   3220  1.1  mrg      56,  64,  57,  69,  58,  78,  59,  68,  /* 112 - 119 */
   3221  1.1  mrg      60,  61,  61,  80,  62,  75,  63,  68,  /* 120 - 127 */
   3222  1.1  mrg      64,  65,  65, 128,  66, 129,  67,  90,  /* 128 - 135 */
   3223  1.1  mrg      68,  73,  69, 131,  70,  94,  71,  88,  /* 136 - 143 */
   3224  1.1  mrg      72, 128,  73,  98,  74, 132,  75, 121,  /* 144 - 151 */
   3225  1.1  mrg      76, 102,  77, 124,  78, 132,  79, 106,  /* 152 - 159 */
   3226  1.1  mrg      80,  97,  81, 160,  82,  99,  83, 134,  /* 160 - 167 */
   3227  1.1  mrg      84,  86,  85,  95,  86, 160,  87, 100,  /* 168 - 175 */
   3228  1.1  mrg      88, 113,  89,  98,  90, 107,  91, 122,  /* 176 - 183 */
   3229  1.1  mrg      92, 111,  93, 102,  94, 126,  95, 150,  /* 184 - 191 */
   3230  1.1  mrg      96, 128,  97, 130,  98, 133,  99, 195,  /* 192 - 199 */
   3231  1.1  mrg     100, 128, 101, 123, 102, 164, 103, 138,  /* 200 - 207 */
   3232  1.1  mrg     104, 145, 105, 146, 106, 109, 107, 149,  /* 208 - 215 */
   3233  1.1  mrg     108, 200, 109, 146, 110, 170, 111, 157,  /* 216 - 223 */
   3234  1.1  mrg     112, 128, 113, 130, 114, 182, 115, 132,  /* 224 - 231 */
   3235  1.1  mrg     116, 200, 117, 132, 118, 158, 119, 206,  /* 232 - 239 */
   3236  1.1  mrg     120, 240, 121, 162, 122, 147, 123, 152,  /* 240 - 247 */
   3237  1.1  mrg     124, 166, 125, 214, 126, 138, 127, 153,  /* 248 - 255 */
   3238  1.1  mrg   };
   3239  1.1  mrg 
   3240  1.1  mrg /* If n is larger than lookup table's max index, we use the "window
   3241  1.1  mrg    method".  */
   3242  1.1  mrg #define POWI_WINDOW_SIZE 3
   3243  1.1  mrg 
   3244  1.1  mrg /* Recursive function to expand the power operator. The temporary
   3245  1.1  mrg    values are put in tmpvar. The function returns tmpvar[1] ** n.  */
   3246  1.1  mrg static tree
   3247  1.1  mrg gfc_conv_powi (gfc_se * se, unsigned HOST_WIDE_INT n, tree * tmpvar)
   3248  1.1  mrg {
   3249  1.1  mrg   tree op0;
   3250  1.1  mrg   tree op1;
   3251  1.1  mrg   tree tmp;
   3252  1.1  mrg   int digit;
   3253  1.1  mrg 
   3254  1.1  mrg   if (n < POWI_TABLE_SIZE)
   3255  1.1  mrg     {
   3256  1.1  mrg       if (tmpvar[n])
   3257  1.1  mrg         return tmpvar[n];
   3258  1.1  mrg 
   3259  1.1  mrg       op0 = gfc_conv_powi (se, n - powi_table[n], tmpvar);
   3260  1.1  mrg       op1 = gfc_conv_powi (se, powi_table[n], tmpvar);
   3261  1.1  mrg     }
   3262  1.1  mrg   else if (n & 1)
   3263  1.1  mrg     {
   3264  1.1  mrg       digit = n & ((1 << POWI_WINDOW_SIZE) - 1);
   3265  1.1  mrg       op0 = gfc_conv_powi (se, n - digit, tmpvar);
   3266  1.1  mrg       op1 = gfc_conv_powi (se, digit, tmpvar);
   3267  1.1  mrg     }
   3268  1.1  mrg   else
   3269  1.1  mrg     {
   3270  1.1  mrg       op0 = gfc_conv_powi (se, n >> 1, tmpvar);
   3271  1.1  mrg       op1 = op0;
   3272  1.1  mrg     }
   3273  1.1  mrg 
   3274  1.1  mrg   tmp = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (op0), op0, op1);
   3275  1.1  mrg   tmp = gfc_evaluate_now (tmp, &se->pre);
   3276  1.1  mrg 
   3277  1.1  mrg   if (n < POWI_TABLE_SIZE)
   3278  1.1  mrg     tmpvar[n] = tmp;
   3279  1.1  mrg 
   3280  1.1  mrg   return tmp;
   3281  1.1  mrg }
   3282  1.1  mrg 
   3283  1.1  mrg 
   3284  1.1  mrg /* Expand lhs ** rhs. rhs is a constant integer. If it expands successfully,
   3285  1.1  mrg    return 1. Else return 0 and a call to runtime library functions
   3286  1.1  mrg    will have to be built.  */
   3287  1.1  mrg static int
   3288  1.1  mrg gfc_conv_cst_int_power (gfc_se * se, tree lhs, tree rhs)
   3289  1.1  mrg {
   3290  1.1  mrg   tree cond;
   3291  1.1  mrg   tree tmp;
   3292  1.1  mrg   tree type;
   3293  1.1  mrg   tree vartmp[POWI_TABLE_SIZE];
   3294  1.1  mrg   HOST_WIDE_INT m;
   3295  1.1  mrg   unsigned HOST_WIDE_INT n;
   3296  1.1  mrg   int sgn;
   3297  1.1  mrg   wi::tree_to_wide_ref wrhs = wi::to_wide (rhs);
   3298  1.1  mrg 
   3299  1.1  mrg   /* If exponent is too large, we won't expand it anyway, so don't bother
   3300  1.1  mrg      with large integer values.  */
   3301  1.1  mrg   if (!wi::fits_shwi_p (wrhs))
   3302  1.1  mrg     return 0;
   3303  1.1  mrg 
   3304  1.1  mrg   m = wrhs.to_shwi ();
   3305  1.1  mrg   /* Use the wide_int's routine to reliably get the absolute value on all
   3306  1.1  mrg      platforms.  Then convert it to a HOST_WIDE_INT like above.  */
   3307  1.1  mrg   n = wi::abs (wrhs).to_shwi ();
   3308  1.1  mrg 
   3309  1.1  mrg   type = TREE_TYPE (lhs);
   3310  1.1  mrg   sgn = tree_int_cst_sgn (rhs);
   3311  1.1  mrg 
   3312  1.1  mrg   if (((FLOAT_TYPE_P (type) && !flag_unsafe_math_optimizations)
   3313  1.1  mrg        || optimize_size) && (m > 2 || m < -1))
   3314  1.1  mrg     return 0;
   3315  1.1  mrg 
   3316  1.1  mrg   /* rhs == 0  */
   3317  1.1  mrg   if (sgn == 0)
   3318  1.1  mrg     {
   3319  1.1  mrg       se->expr = gfc_build_const (type, integer_one_node);
   3320  1.1  mrg       return 1;
   3321  1.1  mrg     }
   3322  1.1  mrg 
   3323  1.1  mrg   /* If rhs < 0 and lhs is an integer, the result is -1, 0 or 1.  */
   3324  1.1  mrg   if ((sgn == -1) && (TREE_CODE (type) == INTEGER_TYPE))
   3325  1.1  mrg     {
   3326  1.1  mrg       tmp = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
   3327  1.1  mrg 			     lhs, build_int_cst (TREE_TYPE (lhs), -1));
   3328  1.1  mrg       cond = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
   3329  1.1  mrg 			      lhs, build_int_cst (TREE_TYPE (lhs), 1));
   3330  1.1  mrg 
   3331  1.1  mrg       /* If rhs is even,
   3332  1.1  mrg 	 result = (lhs == 1 || lhs == -1) ? 1 : 0.  */
   3333  1.1  mrg       if ((n & 1) == 0)
   3334  1.1  mrg         {
   3335  1.1  mrg 	  tmp = fold_build2_loc (input_location, TRUTH_OR_EXPR,
   3336  1.1  mrg 				 logical_type_node, tmp, cond);
   3337  1.1  mrg 	  se->expr = fold_build3_loc (input_location, COND_EXPR, type,
   3338  1.1  mrg 				      tmp, build_int_cst (type, 1),
   3339  1.1  mrg 				      build_int_cst (type, 0));
   3340  1.1  mrg 	  return 1;
   3341  1.1  mrg 	}
   3342  1.1  mrg       /* If rhs is odd,
   3343  1.1  mrg 	 result = (lhs == 1) ? 1 : (lhs == -1) ? -1 : 0.  */
   3344  1.1  mrg       tmp = fold_build3_loc (input_location, COND_EXPR, type, tmp,
   3345  1.1  mrg 			     build_int_cst (type, -1),
   3346  1.1  mrg 			     build_int_cst (type, 0));
   3347  1.1  mrg       se->expr = fold_build3_loc (input_location, COND_EXPR, type,
   3348  1.1  mrg 				  cond, build_int_cst (type, 1), tmp);
   3349  1.1  mrg       return 1;
   3350  1.1  mrg     }
   3351  1.1  mrg 
   3352  1.1  mrg   memset (vartmp, 0, sizeof (vartmp));
   3353  1.1  mrg   vartmp[1] = lhs;
   3354  1.1  mrg   if (sgn == -1)
   3355  1.1  mrg     {
   3356  1.1  mrg       tmp = gfc_build_const (type, integer_one_node);
   3357  1.1  mrg       vartmp[1] = fold_build2_loc (input_location, RDIV_EXPR, type, tmp,
   3358  1.1  mrg 				   vartmp[1]);
   3359  1.1  mrg     }
   3360  1.1  mrg 
   3361  1.1  mrg   se->expr = gfc_conv_powi (se, n, vartmp);
   3362  1.1  mrg 
   3363  1.1  mrg   return 1;
   3364  1.1  mrg }
   3365  1.1  mrg 
   3366  1.1  mrg 
   3367  1.1  mrg /* Power op (**).  Constant integer exponent has special handling.  */
   3368  1.1  mrg 
   3369  1.1  mrg static void
   3370  1.1  mrg gfc_conv_power_op (gfc_se * se, gfc_expr * expr)
   3371  1.1  mrg {
   3372  1.1  mrg   tree gfc_int4_type_node;
   3373  1.1  mrg   int kind;
   3374  1.1  mrg   int ikind;
   3375  1.1  mrg   int res_ikind_1, res_ikind_2;
   3376  1.1  mrg   gfc_se lse;
   3377  1.1  mrg   gfc_se rse;
   3378  1.1  mrg   tree fndecl = NULL;
   3379  1.1  mrg 
   3380  1.1  mrg   gfc_init_se (&lse, se);
   3381  1.1  mrg   gfc_conv_expr_val (&lse, expr->value.op.op1);
   3382  1.1  mrg   lse.expr = gfc_evaluate_now (lse.expr, &lse.pre);
   3383  1.1  mrg   gfc_add_block_to_block (&se->pre, &lse.pre);
   3384  1.1  mrg 
   3385  1.1  mrg   gfc_init_se (&rse, se);
   3386  1.1  mrg   gfc_conv_expr_val (&rse, expr->value.op.op2);
   3387  1.1  mrg   gfc_add_block_to_block (&se->pre, &rse.pre);
   3388  1.1  mrg 
   3389  1.1  mrg   if (expr->value.op.op2->ts.type == BT_INTEGER
   3390  1.1  mrg       && expr->value.op.op2->expr_type == EXPR_CONSTANT)
   3391  1.1  mrg     if (gfc_conv_cst_int_power (se, lse.expr, rse.expr))
   3392  1.1  mrg       return;
   3393  1.1  mrg 
   3394  1.1  mrg   if (INTEGER_CST_P (lse.expr)
   3395  1.1  mrg       && TREE_CODE (TREE_TYPE (rse.expr)) == INTEGER_TYPE)
   3396  1.1  mrg     {
   3397  1.1  mrg       wi::tree_to_wide_ref wlhs = wi::to_wide (lse.expr);
   3398  1.1  mrg       HOST_WIDE_INT v, w;
   3399  1.1  mrg       int kind, ikind, bit_size;
   3400  1.1  mrg 
   3401  1.1  mrg       v = wlhs.to_shwi ();
   3402  1.1  mrg       w = abs (v);
   3403  1.1  mrg 
   3404  1.1  mrg       kind = expr->value.op.op1->ts.kind;
   3405  1.1  mrg       ikind = gfc_validate_kind (BT_INTEGER, kind, false);
   3406  1.1  mrg       bit_size = gfc_integer_kinds[ikind].bit_size;
   3407  1.1  mrg 
   3408  1.1  mrg       if (v == 1)
   3409  1.1  mrg 	{
   3410  1.1  mrg 	  /* 1**something is always 1.  */
   3411  1.1  mrg 	  se->expr = build_int_cst (TREE_TYPE (lse.expr), 1);
   3412  1.1  mrg 	  return;
   3413  1.1  mrg 	}
   3414  1.1  mrg       else if (v == -1)
   3415  1.1  mrg 	{
   3416  1.1  mrg 	  /* (-1)**n is 1 - ((n & 1) << 1) */
   3417  1.1  mrg 	  tree type;
   3418  1.1  mrg 	  tree tmp;
   3419  1.1  mrg 
   3420  1.1  mrg 	  type = TREE_TYPE (lse.expr);
   3421  1.1  mrg 	  tmp = fold_build2_loc (input_location, BIT_AND_EXPR, type,
   3422  1.1  mrg 				 rse.expr, build_int_cst (type, 1));
   3423  1.1  mrg 	  tmp = fold_build2_loc (input_location, LSHIFT_EXPR, type,
   3424  1.1  mrg 				 tmp, build_int_cst (type, 1));
   3425  1.1  mrg 	  tmp = fold_build2_loc (input_location, MINUS_EXPR, type,
   3426  1.1  mrg 				 build_int_cst (type, 1), tmp);
   3427  1.1  mrg 	  se->expr = tmp;
   3428  1.1  mrg 	  return;
   3429  1.1  mrg 	}
   3430  1.1  mrg       else if (w > 0 && ((w & (w-1)) == 0) && ((w >> (bit_size-1)) == 0))
   3431  1.1  mrg 	{
   3432  1.1  mrg 	  /* Here v is +/- 2**e.  The further simplification uses
   3433  1.1  mrg 	     2**n = 1<<n, 4**n = 1<<(n+n), 8**n = 1 <<(3*n), 16**n =
   3434  1.1  mrg 	     1<<(4*n), etc., but we have to make sure to return zero
   3435  1.1  mrg 	     if the number of bits is too large. */
   3436  1.1  mrg 	  tree lshift;
   3437  1.1  mrg 	  tree type;
   3438  1.1  mrg 	  tree shift;
   3439  1.1  mrg 	  tree ge;
   3440  1.1  mrg 	  tree cond;
   3441  1.1  mrg 	  tree num_bits;
   3442  1.1  mrg 	  tree cond2;
   3443  1.1  mrg 	  tree tmp1;
   3444  1.1  mrg 
   3445  1.1  mrg 	  type = TREE_TYPE (lse.expr);
   3446  1.1  mrg 
   3447  1.1  mrg 	  if (w == 2)
   3448  1.1  mrg 	    shift = rse.expr;
   3449  1.1  mrg 	  else if (w == 4)
   3450  1.1  mrg 	    shift = fold_build2_loc (input_location, PLUS_EXPR,
   3451  1.1  mrg 				     TREE_TYPE (rse.expr),
   3452  1.1  mrg 				       rse.expr, rse.expr);
   3453  1.1  mrg 	  else
   3454  1.1  mrg 	    {
   3455  1.1  mrg 	      /* use popcount for fast log2(w) */
   3456  1.1  mrg 	      int e = wi::popcount (w-1);
   3457  1.1  mrg 	      shift = fold_build2_loc (input_location, MULT_EXPR,
   3458  1.1  mrg 				       TREE_TYPE (rse.expr),
   3459  1.1  mrg 				       build_int_cst (TREE_TYPE (rse.expr), e),
   3460  1.1  mrg 				       rse.expr);
   3461  1.1  mrg 	    }
   3462  1.1  mrg 
   3463  1.1  mrg 	  lshift = fold_build2_loc (input_location, LSHIFT_EXPR, type,
   3464  1.1  mrg 				    build_int_cst (type, 1), shift);
   3465  1.1  mrg 	  ge = fold_build2_loc (input_location, GE_EXPR, logical_type_node,
   3466  1.1  mrg 				rse.expr, build_int_cst (type, 0));
   3467  1.1  mrg 	  cond = fold_build3_loc (input_location, COND_EXPR, type, ge, lshift,
   3468  1.1  mrg 				 build_int_cst (type, 0));
   3469  1.1  mrg 	  num_bits = build_int_cst (TREE_TYPE (rse.expr), TYPE_PRECISION (type));
   3470  1.1  mrg 	  cond2 = fold_build2_loc (input_location, GE_EXPR, logical_type_node,
   3471  1.1  mrg 				   rse.expr, num_bits);
   3472  1.1  mrg 	  tmp1 = fold_build3_loc (input_location, COND_EXPR, type, cond2,
   3473  1.1  mrg 				  build_int_cst (type, 0), cond);
   3474  1.1  mrg 	  if (v > 0)
   3475  1.1  mrg 	    {
   3476  1.1  mrg 	      se->expr = tmp1;
   3477  1.1  mrg 	    }
   3478  1.1  mrg 	  else
   3479  1.1  mrg 	    {
   3480  1.1  mrg 	      /* for v < 0, calculate v**n = |v|**n * (-1)**n */
   3481  1.1  mrg 	      tree tmp2;
   3482  1.1  mrg 	      tmp2 = fold_build2_loc (input_location, BIT_AND_EXPR, type,
   3483  1.1  mrg 				      rse.expr, build_int_cst (type, 1));
   3484  1.1  mrg 	      tmp2 = fold_build2_loc (input_location, LSHIFT_EXPR, type,
   3485  1.1  mrg 				      tmp2, build_int_cst (type, 1));
   3486  1.1  mrg 	      tmp2 = fold_build2_loc (input_location, MINUS_EXPR, type,
   3487  1.1  mrg 				      build_int_cst (type, 1), tmp2);
   3488  1.1  mrg 	      se->expr = fold_build2_loc (input_location, MULT_EXPR, type,
   3489  1.1  mrg 					  tmp1, tmp2);
   3490  1.1  mrg 	    }
   3491  1.1  mrg 	  return;
   3492  1.1  mrg 	}
   3493  1.1  mrg     }
   3494  1.1  mrg 
   3495  1.1  mrg   gfc_int4_type_node = gfc_get_int_type (4);
   3496  1.1  mrg 
   3497  1.1  mrg   /* In case of integer operands with kinds 1 or 2, we call the integer kind 4
   3498  1.1  mrg      library routine.  But in the end, we have to convert the result back
   3499  1.1  mrg      if this case applies -- with res_ikind_K, we keep track whether operand K
   3500  1.1  mrg      falls into this case.  */
   3501  1.1  mrg   res_ikind_1 = -1;
   3502  1.1  mrg   res_ikind_2 = -1;
   3503  1.1  mrg 
   3504  1.1  mrg   kind = expr->value.op.op1->ts.kind;
   3505  1.1  mrg   switch (expr->value.op.op2->ts.type)
   3506  1.1  mrg     {
   3507  1.1  mrg     case BT_INTEGER:
   3508  1.1  mrg       ikind = expr->value.op.op2->ts.kind;
   3509  1.1  mrg       switch (ikind)
   3510  1.1  mrg 	{
   3511  1.1  mrg 	case 1:
   3512  1.1  mrg 	case 2:
   3513  1.1  mrg 	  rse.expr = convert (gfc_int4_type_node, rse.expr);
   3514  1.1  mrg 	  res_ikind_2 = ikind;
   3515  1.1  mrg 	  /* Fall through.  */
   3516  1.1  mrg 
   3517  1.1  mrg 	case 4:
   3518  1.1  mrg 	  ikind = 0;
   3519  1.1  mrg 	  break;
   3520  1.1  mrg 
   3521  1.1  mrg 	case 8:
   3522  1.1  mrg 	  ikind = 1;
   3523  1.1  mrg 	  break;
   3524  1.1  mrg 
   3525  1.1  mrg 	case 16:
   3526  1.1  mrg 	  ikind = 2;
   3527  1.1  mrg 	  break;
   3528  1.1  mrg 
   3529  1.1  mrg 	default:
   3530  1.1  mrg 	  gcc_unreachable ();
   3531  1.1  mrg 	}
   3532  1.1  mrg       switch (kind)
   3533  1.1  mrg 	{
   3534  1.1  mrg 	case 1:
   3535  1.1  mrg 	case 2:
   3536  1.1  mrg 	  if (expr->value.op.op1->ts.type == BT_INTEGER)
   3537  1.1  mrg 	    {
   3538  1.1  mrg 	      lse.expr = convert (gfc_int4_type_node, lse.expr);
   3539  1.1  mrg 	      res_ikind_1 = kind;
   3540  1.1  mrg 	    }
   3541  1.1  mrg 	  else
   3542  1.1  mrg 	    gcc_unreachable ();
   3543  1.1  mrg 	  /* Fall through.  */
   3544  1.1  mrg 
   3545  1.1  mrg 	case 4:
   3546  1.1  mrg 	  kind = 0;
   3547  1.1  mrg 	  break;
   3548  1.1  mrg 
   3549  1.1  mrg 	case 8:
   3550  1.1  mrg 	  kind = 1;
   3551  1.1  mrg 	  break;
   3552  1.1  mrg 
   3553  1.1  mrg 	case 10:
   3554  1.1  mrg 	  kind = 2;
   3555  1.1  mrg 	  break;
   3556  1.1  mrg 
   3557  1.1  mrg 	case 16:
   3558  1.1  mrg 	  kind = 3;
   3559  1.1  mrg 	  break;
   3560  1.1  mrg 
   3561  1.1  mrg 	default:
   3562  1.1  mrg 	  gcc_unreachable ();
   3563  1.1  mrg 	}
   3564  1.1  mrg 
   3565  1.1  mrg       switch (expr->value.op.op1->ts.type)
   3566  1.1  mrg 	{
   3567  1.1  mrg 	case BT_INTEGER:
   3568  1.1  mrg 	  if (kind == 3) /* Case 16 was not handled properly above.  */
   3569  1.1  mrg 	    kind = 2;
   3570  1.1  mrg 	  fndecl = gfor_fndecl_math_powi[kind][ikind].integer;
   3571  1.1  mrg 	  break;
   3572  1.1  mrg 
   3573  1.1  mrg 	case BT_REAL:
   3574  1.1  mrg 	  /* Use builtins for real ** int4.  */
   3575  1.1  mrg 	  if (ikind == 0)
   3576  1.1  mrg 	    {
   3577  1.1  mrg 	      switch (kind)
   3578  1.1  mrg 		{
   3579  1.1  mrg 		case 0:
   3580  1.1  mrg 		  fndecl = builtin_decl_explicit (BUILT_IN_POWIF);
   3581  1.1  mrg 		  break;
   3582  1.1  mrg 
   3583  1.1  mrg 		case 1:
   3584  1.1  mrg 		  fndecl = builtin_decl_explicit (BUILT_IN_POWI);
   3585  1.1  mrg 		  break;
   3586  1.1  mrg 
   3587  1.1  mrg 		case 2:
   3588  1.1  mrg 		  fndecl = builtin_decl_explicit (BUILT_IN_POWIL);
   3589  1.1  mrg 		  break;
   3590  1.1  mrg 
   3591  1.1  mrg 		case 3:
   3592  1.1  mrg 		  /* Use the __builtin_powil() only if real(kind=16) is
   3593  1.1  mrg 		     actually the C long double type.  */
   3594  1.1  mrg 		  if (!gfc_real16_is_float128)
   3595  1.1  mrg 		    fndecl = builtin_decl_explicit (BUILT_IN_POWIL);
   3596  1.1  mrg 		  break;
   3597  1.1  mrg 
   3598  1.1  mrg 		default:
   3599  1.1  mrg 		  gcc_unreachable ();
   3600  1.1  mrg 		}
   3601  1.1  mrg 	    }
   3602  1.1  mrg 
   3603  1.1  mrg 	  /* If we don't have a good builtin for this, go for the
   3604  1.1  mrg 	     library function.  */
   3605  1.1  mrg 	  if (!fndecl)
   3606  1.1  mrg 	    fndecl = gfor_fndecl_math_powi[kind][ikind].real;
   3607  1.1  mrg 	  break;
   3608  1.1  mrg 
   3609  1.1  mrg 	case BT_COMPLEX:
   3610  1.1  mrg 	  fndecl = gfor_fndecl_math_powi[kind][ikind].cmplx;
   3611  1.1  mrg 	  break;
   3612  1.1  mrg 
   3613  1.1  mrg 	default:
   3614  1.1  mrg 	  gcc_unreachable ();
   3615  1.1  mrg  	}
   3616  1.1  mrg       break;
   3617  1.1  mrg 
   3618  1.1  mrg     case BT_REAL:
   3619  1.1  mrg       fndecl = gfc_builtin_decl_for_float_kind (BUILT_IN_POW, kind);
   3620  1.1  mrg       break;
   3621  1.1  mrg 
   3622  1.1  mrg     case BT_COMPLEX:
   3623  1.1  mrg       fndecl = gfc_builtin_decl_for_float_kind (BUILT_IN_CPOW, kind);
   3624  1.1  mrg       break;
   3625  1.1  mrg 
   3626  1.1  mrg     default:
   3627  1.1  mrg       gcc_unreachable ();
   3628  1.1  mrg       break;
   3629  1.1  mrg     }
   3630  1.1  mrg 
   3631  1.1  mrg   se->expr = build_call_expr_loc (input_location,
   3632  1.1  mrg 			      fndecl, 2, lse.expr, rse.expr);
   3633  1.1  mrg 
   3634  1.1  mrg   /* Convert the result back if it is of wrong integer kind.  */
   3635  1.1  mrg   if (res_ikind_1 != -1 && res_ikind_2 != -1)
   3636  1.1  mrg     {
   3637  1.1  mrg       /* We want the maximum of both operand kinds as result.  */
   3638  1.1  mrg       if (res_ikind_1 < res_ikind_2)
   3639  1.1  mrg 	res_ikind_1 = res_ikind_2;
   3640  1.1  mrg       se->expr = convert (gfc_get_int_type (res_ikind_1), se->expr);
   3641  1.1  mrg     }
   3642  1.1  mrg }
   3643  1.1  mrg 
   3644  1.1  mrg 
   3645  1.1  mrg /* Generate code to allocate a string temporary.  */
   3646  1.1  mrg 
   3647  1.1  mrg tree
   3648  1.1  mrg gfc_conv_string_tmp (gfc_se * se, tree type, tree len)
   3649  1.1  mrg {
   3650  1.1  mrg   tree var;
   3651  1.1  mrg   tree tmp;
   3652  1.1  mrg 
   3653  1.1  mrg   if (gfc_can_put_var_on_stack (len))
   3654  1.1  mrg     {
   3655  1.1  mrg       /* Create a temporary variable to hold the result.  */
   3656  1.1  mrg       tmp = fold_build2_loc (input_location, MINUS_EXPR,
   3657  1.1  mrg 			     TREE_TYPE (len), len,
   3658  1.1  mrg 			     build_int_cst (TREE_TYPE (len), 1));
   3659  1.1  mrg       tmp = build_range_type (gfc_charlen_type_node, size_zero_node, tmp);
   3660  1.1  mrg 
   3661  1.1  mrg       if (TREE_CODE (TREE_TYPE (type)) == ARRAY_TYPE)
   3662  1.1  mrg 	tmp = build_array_type (TREE_TYPE (TREE_TYPE (type)), tmp);
   3663  1.1  mrg       else
   3664  1.1  mrg 	tmp = build_array_type (TREE_TYPE (type), tmp);
   3665  1.1  mrg 
   3666  1.1  mrg       var = gfc_create_var (tmp, "str");
   3667  1.1  mrg       var = gfc_build_addr_expr (type, var);
   3668  1.1  mrg     }
   3669  1.1  mrg   else
   3670  1.1  mrg     {
   3671  1.1  mrg       /* Allocate a temporary to hold the result.  */
   3672  1.1  mrg       var = gfc_create_var (type, "pstr");
   3673  1.1  mrg       gcc_assert (POINTER_TYPE_P (type));
   3674  1.1  mrg       tmp = TREE_TYPE (type);
   3675  1.1  mrg       if (TREE_CODE (tmp) == ARRAY_TYPE)
   3676  1.1  mrg         tmp = TREE_TYPE (tmp);
   3677  1.1  mrg       tmp = TYPE_SIZE_UNIT (tmp);
   3678  1.1  mrg       tmp = fold_build2_loc (input_location, MULT_EXPR, size_type_node,
   3679  1.1  mrg 			    fold_convert (size_type_node, len),
   3680  1.1  mrg 			    fold_convert (size_type_node, tmp));
   3681  1.1  mrg       tmp = gfc_call_malloc (&se->pre, type, tmp);
   3682  1.1  mrg       gfc_add_modify (&se->pre, var, tmp);
   3683  1.1  mrg 
   3684  1.1  mrg       /* Free the temporary afterwards.  */
   3685  1.1  mrg       tmp = gfc_call_free (var);
   3686  1.1  mrg       gfc_add_expr_to_block (&se->post, tmp);
   3687  1.1  mrg     }
   3688  1.1  mrg 
   3689  1.1  mrg   return var;
   3690  1.1  mrg }
   3691  1.1  mrg 
   3692  1.1  mrg 
   3693  1.1  mrg /* Handle a string concatenation operation.  A temporary will be allocated to
   3694  1.1  mrg    hold the result.  */
   3695  1.1  mrg 
   3696  1.1  mrg static void
   3697  1.1  mrg gfc_conv_concat_op (gfc_se * se, gfc_expr * expr)
   3698  1.1  mrg {
   3699  1.1  mrg   gfc_se lse, rse;
   3700  1.1  mrg   tree len, type, var, tmp, fndecl;
   3701  1.1  mrg 
   3702  1.1  mrg   gcc_assert (expr->value.op.op1->ts.type == BT_CHARACTER
   3703  1.1  mrg 	      && expr->value.op.op2->ts.type == BT_CHARACTER);
   3704  1.1  mrg   gcc_assert (expr->value.op.op1->ts.kind == expr->value.op.op2->ts.kind);
   3705  1.1  mrg 
   3706  1.1  mrg   gfc_init_se (&lse, se);
   3707  1.1  mrg   gfc_conv_expr (&lse, expr->value.op.op1);
   3708  1.1  mrg   gfc_conv_string_parameter (&lse);
   3709  1.1  mrg   gfc_init_se (&rse, se);
   3710  1.1  mrg   gfc_conv_expr (&rse, expr->value.op.op2);
   3711  1.1  mrg   gfc_conv_string_parameter (&rse);
   3712  1.1  mrg 
   3713  1.1  mrg   gfc_add_block_to_block (&se->pre, &lse.pre);
   3714  1.1  mrg   gfc_add_block_to_block (&se->pre, &rse.pre);
   3715  1.1  mrg 
   3716  1.1  mrg   type = gfc_get_character_type (expr->ts.kind, expr->ts.u.cl);
   3717  1.1  mrg   len = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
   3718  1.1  mrg   if (len == NULL_TREE)
   3719  1.1  mrg     {
   3720  1.1  mrg       len = fold_build2_loc (input_location, PLUS_EXPR,
   3721  1.1  mrg 			     gfc_charlen_type_node,
   3722  1.1  mrg 			     fold_convert (gfc_charlen_type_node,
   3723  1.1  mrg 					   lse.string_length),
   3724  1.1  mrg 			     fold_convert (gfc_charlen_type_node,
   3725  1.1  mrg 					   rse.string_length));
   3726  1.1  mrg     }
   3727  1.1  mrg 
   3728  1.1  mrg   type = build_pointer_type (type);
   3729  1.1  mrg 
   3730  1.1  mrg   var = gfc_conv_string_tmp (se, type, len);
   3731  1.1  mrg 
   3732  1.1  mrg   /* Do the actual concatenation.  */
   3733  1.1  mrg   if (expr->ts.kind == 1)
   3734  1.1  mrg     fndecl = gfor_fndecl_concat_string;
   3735  1.1  mrg   else if (expr->ts.kind == 4)
   3736  1.1  mrg     fndecl = gfor_fndecl_concat_string_char4;
   3737  1.1  mrg   else
   3738  1.1  mrg     gcc_unreachable ();
   3739  1.1  mrg 
   3740  1.1  mrg   tmp = build_call_expr_loc (input_location,
   3741  1.1  mrg 			 fndecl, 6, len, var, lse.string_length, lse.expr,
   3742  1.1  mrg 			 rse.string_length, rse.expr);
   3743  1.1  mrg   gfc_add_expr_to_block (&se->pre, tmp);
   3744  1.1  mrg 
   3745  1.1  mrg   /* Add the cleanup for the operands.  */
   3746  1.1  mrg   gfc_add_block_to_block (&se->pre, &rse.post);
   3747  1.1  mrg   gfc_add_block_to_block (&se->pre, &lse.post);
   3748  1.1  mrg 
   3749  1.1  mrg   se->expr = var;
   3750  1.1  mrg   se->string_length = len;
   3751  1.1  mrg }
   3752  1.1  mrg 
   3753  1.1  mrg /* Translates an op expression. Common (binary) cases are handled by this
   3754  1.1  mrg    function, others are passed on. Recursion is used in either case.
   3755  1.1  mrg    We use the fact that (op1.ts == op2.ts) (except for the power
   3756  1.1  mrg    operator **).
   3757  1.1  mrg    Operators need no special handling for scalarized expressions as long as
   3758  1.1  mrg    they call gfc_conv_simple_val to get their operands.
   3759  1.1  mrg    Character strings get special handling.  */
   3760  1.1  mrg 
   3761  1.1  mrg static void
   3762  1.1  mrg gfc_conv_expr_op (gfc_se * se, gfc_expr * expr)
   3763  1.1  mrg {
   3764  1.1  mrg   enum tree_code code;
   3765  1.1  mrg   gfc_se lse;
   3766  1.1  mrg   gfc_se rse;
   3767  1.1  mrg   tree tmp, type;
   3768  1.1  mrg   int lop;
   3769  1.1  mrg   int checkstring;
   3770  1.1  mrg 
   3771  1.1  mrg   checkstring = 0;
   3772  1.1  mrg   lop = 0;
   3773  1.1  mrg   switch (expr->value.op.op)
   3774  1.1  mrg     {
   3775  1.1  mrg     case INTRINSIC_PARENTHESES:
   3776  1.1  mrg       if ((expr->ts.type == BT_REAL || expr->ts.type == BT_COMPLEX)
   3777  1.1  mrg 	  && flag_protect_parens)
   3778  1.1  mrg 	{
   3779  1.1  mrg 	  gfc_conv_unary_op (PAREN_EXPR, se, expr);
   3780  1.1  mrg 	  gcc_assert (FLOAT_TYPE_P (TREE_TYPE (se->expr)));
   3781  1.1  mrg 	  return;
   3782  1.1  mrg 	}
   3783  1.1  mrg 
   3784  1.1  mrg       /* Fallthrough.  */
   3785  1.1  mrg     case INTRINSIC_UPLUS:
   3786  1.1  mrg       gfc_conv_expr (se, expr->value.op.op1);
   3787  1.1  mrg       return;
   3788  1.1  mrg 
   3789  1.1  mrg     case INTRINSIC_UMINUS:
   3790  1.1  mrg       gfc_conv_unary_op (NEGATE_EXPR, se, expr);
   3791  1.1  mrg       return;
   3792  1.1  mrg 
   3793  1.1  mrg     case INTRINSIC_NOT:
   3794  1.1  mrg       gfc_conv_unary_op (TRUTH_NOT_EXPR, se, expr);
   3795  1.1  mrg       return;
   3796  1.1  mrg 
   3797  1.1  mrg     case INTRINSIC_PLUS:
   3798  1.1  mrg       code = PLUS_EXPR;
   3799  1.1  mrg       break;
   3800  1.1  mrg 
   3801  1.1  mrg     case INTRINSIC_MINUS:
   3802  1.1  mrg       code = MINUS_EXPR;
   3803  1.1  mrg       break;
   3804  1.1  mrg 
   3805  1.1  mrg     case INTRINSIC_TIMES:
   3806  1.1  mrg       code = MULT_EXPR;
   3807  1.1  mrg       break;
   3808  1.1  mrg 
   3809  1.1  mrg     case INTRINSIC_DIVIDE:
   3810  1.1  mrg       /* If expr is a real or complex expr, use an RDIV_EXPR. If op1 is
   3811  1.1  mrg          an integer, we must round towards zero, so we use a
   3812  1.1  mrg          TRUNC_DIV_EXPR.  */
   3813  1.1  mrg       if (expr->ts.type == BT_INTEGER)
   3814  1.1  mrg 	code = TRUNC_DIV_EXPR;
   3815  1.1  mrg       else
   3816  1.1  mrg 	code = RDIV_EXPR;
   3817  1.1  mrg       break;
   3818  1.1  mrg 
   3819  1.1  mrg     case INTRINSIC_POWER:
   3820  1.1  mrg       gfc_conv_power_op (se, expr);
   3821  1.1  mrg       return;
   3822  1.1  mrg 
   3823  1.1  mrg     case INTRINSIC_CONCAT:
   3824  1.1  mrg       gfc_conv_concat_op (se, expr);
   3825  1.1  mrg       return;
   3826  1.1  mrg 
   3827  1.1  mrg     case INTRINSIC_AND:
   3828  1.1  mrg       code = flag_frontend_optimize ? TRUTH_ANDIF_EXPR : TRUTH_AND_EXPR;
   3829  1.1  mrg       lop = 1;
   3830  1.1  mrg       break;
   3831  1.1  mrg 
   3832  1.1  mrg     case INTRINSIC_OR:
   3833  1.1  mrg       code = flag_frontend_optimize ? TRUTH_ORIF_EXPR : TRUTH_OR_EXPR;
   3834  1.1  mrg       lop = 1;
   3835  1.1  mrg       break;
   3836  1.1  mrg 
   3837  1.1  mrg       /* EQV and NEQV only work on logicals, but since we represent them
   3838  1.1  mrg          as integers, we can use EQ_EXPR and NE_EXPR for them in GIMPLE.  */
   3839  1.1  mrg     case INTRINSIC_EQ:
   3840  1.1  mrg     case INTRINSIC_EQ_OS:
   3841  1.1  mrg     case INTRINSIC_EQV:
   3842  1.1  mrg       code = EQ_EXPR;
   3843  1.1  mrg       checkstring = 1;
   3844  1.1  mrg       lop = 1;
   3845  1.1  mrg       break;
   3846  1.1  mrg 
   3847  1.1  mrg     case INTRINSIC_NE:
   3848  1.1  mrg     case INTRINSIC_NE_OS:
   3849  1.1  mrg     case INTRINSIC_NEQV:
   3850  1.1  mrg       code = NE_EXPR;
   3851  1.1  mrg       checkstring = 1;
   3852  1.1  mrg       lop = 1;
   3853  1.1  mrg       break;
   3854  1.1  mrg 
   3855  1.1  mrg     case INTRINSIC_GT:
   3856  1.1  mrg     case INTRINSIC_GT_OS:
   3857  1.1  mrg       code = GT_EXPR;
   3858  1.1  mrg       checkstring = 1;
   3859  1.1  mrg       lop = 1;
   3860  1.1  mrg       break;
   3861  1.1  mrg 
   3862  1.1  mrg     case INTRINSIC_GE:
   3863  1.1  mrg     case INTRINSIC_GE_OS:
   3864  1.1  mrg       code = GE_EXPR;
   3865  1.1  mrg       checkstring = 1;
   3866  1.1  mrg       lop = 1;
   3867  1.1  mrg       break;
   3868  1.1  mrg 
   3869  1.1  mrg     case INTRINSIC_LT:
   3870  1.1  mrg     case INTRINSIC_LT_OS:
   3871  1.1  mrg       code = LT_EXPR;
   3872  1.1  mrg       checkstring = 1;
   3873  1.1  mrg       lop = 1;
   3874  1.1  mrg       break;
   3875  1.1  mrg 
   3876  1.1  mrg     case INTRINSIC_LE:
   3877  1.1  mrg     case INTRINSIC_LE_OS:
   3878  1.1  mrg       code = LE_EXPR;
   3879  1.1  mrg       checkstring = 1;
   3880  1.1  mrg       lop = 1;
   3881  1.1  mrg       break;
   3882  1.1  mrg 
   3883  1.1  mrg     case INTRINSIC_USER:
   3884  1.1  mrg     case INTRINSIC_ASSIGN:
   3885  1.1  mrg       /* These should be converted into function calls by the frontend.  */
   3886  1.1  mrg       gcc_unreachable ();
   3887  1.1  mrg 
   3888  1.1  mrg     default:
   3889  1.1  mrg       fatal_error (input_location, "Unknown intrinsic op");
   3890  1.1  mrg       return;
   3891  1.1  mrg     }
   3892  1.1  mrg 
   3893  1.1  mrg   /* The only exception to this is **, which is handled separately anyway.  */
   3894  1.1  mrg   gcc_assert (expr->value.op.op1->ts.type == expr->value.op.op2->ts.type);
   3895  1.1  mrg 
   3896  1.1  mrg   if (checkstring && expr->value.op.op1->ts.type != BT_CHARACTER)
   3897  1.1  mrg     checkstring = 0;
   3898  1.1  mrg 
   3899  1.1  mrg   /* lhs */
   3900  1.1  mrg   gfc_init_se (&lse, se);
   3901  1.1  mrg   gfc_conv_expr (&lse, expr->value.op.op1);
   3902  1.1  mrg   gfc_add_block_to_block (&se->pre, &lse.pre);
   3903  1.1  mrg 
   3904  1.1  mrg   /* rhs */
   3905  1.1  mrg   gfc_init_se (&rse, se);
   3906  1.1  mrg   gfc_conv_expr (&rse, expr->value.op.op2);
   3907  1.1  mrg   gfc_add_block_to_block (&se->pre, &rse.pre);
   3908  1.1  mrg 
   3909  1.1  mrg   if (checkstring)
   3910  1.1  mrg     {
   3911  1.1  mrg       gfc_conv_string_parameter (&lse);
   3912  1.1  mrg       gfc_conv_string_parameter (&rse);
   3913  1.1  mrg 
   3914  1.1  mrg       lse.expr = gfc_build_compare_string (lse.string_length, lse.expr,
   3915  1.1  mrg 					   rse.string_length, rse.expr,
   3916  1.1  mrg 					   expr->value.op.op1->ts.kind,
   3917  1.1  mrg 					   code);
   3918  1.1  mrg       rse.expr = build_int_cst (TREE_TYPE (lse.expr), 0);
   3919  1.1  mrg       gfc_add_block_to_block (&lse.post, &rse.post);
   3920  1.1  mrg     }
   3921  1.1  mrg 
   3922  1.1  mrg   type = gfc_typenode_for_spec (&expr->ts);
   3923  1.1  mrg 
   3924  1.1  mrg   if (lop)
   3925  1.1  mrg     {
   3926  1.1  mrg       // Inhibit overeager optimization of Cray pointer comparisons (PR106692).
   3927  1.1  mrg       if (expr->value.op.op1->expr_type == EXPR_VARIABLE
   3928  1.1  mrg 	  && expr->value.op.op1->ts.type == BT_INTEGER
   3929  1.1  mrg 	  && expr->value.op.op1->symtree
   3930  1.1  mrg 	  && expr->value.op.op1->symtree->n.sym->attr.cray_pointer)
   3931  1.1  mrg 	TREE_THIS_VOLATILE (lse.expr) = 1;
   3932  1.1  mrg 
   3933  1.1  mrg       if (expr->value.op.op2->expr_type == EXPR_VARIABLE
   3934  1.1  mrg 	  && expr->value.op.op2->ts.type == BT_INTEGER
   3935  1.1  mrg 	  && expr->value.op.op2->symtree
   3936  1.1  mrg 	  && expr->value.op.op2->symtree->n.sym->attr.cray_pointer)
   3937  1.1  mrg 	TREE_THIS_VOLATILE (rse.expr) = 1;
   3938  1.1  mrg 
   3939  1.1  mrg       /* The result of logical ops is always logical_type_node.  */
   3940  1.1  mrg       tmp = fold_build2_loc (input_location, code, logical_type_node,
   3941  1.1  mrg 			     lse.expr, rse.expr);
   3942  1.1  mrg       se->expr = convert (type, tmp);
   3943  1.1  mrg     }
   3944  1.1  mrg   else
   3945  1.1  mrg     se->expr = fold_build2_loc (input_location, code, type, lse.expr, rse.expr);
   3946  1.1  mrg 
   3947  1.1  mrg   /* Add the post blocks.  */
   3948  1.1  mrg   gfc_add_block_to_block (&se->post, &rse.post);
   3949  1.1  mrg   gfc_add_block_to_block (&se->post, &lse.post);
   3950  1.1  mrg }
   3951  1.1  mrg 
   3952  1.1  mrg /* If a string's length is one, we convert it to a single character.  */
   3953  1.1  mrg 
   3954  1.1  mrg tree
   3955  1.1  mrg gfc_string_to_single_character (tree len, tree str, int kind)
   3956  1.1  mrg {
   3957  1.1  mrg 
   3958  1.1  mrg   if (len == NULL
   3959  1.1  mrg       || !tree_fits_uhwi_p (len)
   3960  1.1  mrg       || !POINTER_TYPE_P (TREE_TYPE (str)))
   3961  1.1  mrg     return NULL_TREE;
   3962  1.1  mrg 
   3963  1.1  mrg   if (TREE_INT_CST_LOW (len) == 1)
   3964  1.1  mrg     {
   3965  1.1  mrg       str = fold_convert (gfc_get_pchar_type (kind), str);
   3966  1.1  mrg       return build_fold_indirect_ref_loc (input_location, str);
   3967  1.1  mrg     }
   3968  1.1  mrg 
   3969  1.1  mrg   if (kind == 1
   3970  1.1  mrg       && TREE_CODE (str) == ADDR_EXPR
   3971  1.1  mrg       && TREE_CODE (TREE_OPERAND (str, 0)) == ARRAY_REF
   3972  1.1  mrg       && TREE_CODE (TREE_OPERAND (TREE_OPERAND (str, 0), 0)) == STRING_CST
   3973  1.1  mrg       && array_ref_low_bound (TREE_OPERAND (str, 0))
   3974  1.1  mrg 	 == TREE_OPERAND (TREE_OPERAND (str, 0), 1)
   3975  1.1  mrg       && TREE_INT_CST_LOW (len) > 1
   3976  1.1  mrg       && TREE_INT_CST_LOW (len)
   3977  1.1  mrg 	 == (unsigned HOST_WIDE_INT)
   3978  1.1  mrg 	    TREE_STRING_LENGTH (TREE_OPERAND (TREE_OPERAND (str, 0), 0)))
   3979  1.1  mrg     {
   3980  1.1  mrg       tree ret = fold_convert (gfc_get_pchar_type (kind), str);
   3981  1.1  mrg       ret = build_fold_indirect_ref_loc (input_location, ret);
   3982  1.1  mrg       if (TREE_CODE (ret) == INTEGER_CST)
   3983  1.1  mrg 	{
   3984  1.1  mrg 	  tree string_cst = TREE_OPERAND (TREE_OPERAND (str, 0), 0);
   3985  1.1  mrg 	  int i, length = TREE_STRING_LENGTH (string_cst);
   3986  1.1  mrg 	  const char *ptr = TREE_STRING_POINTER (string_cst);
   3987  1.1  mrg 
   3988  1.1  mrg 	  for (i = 1; i < length; i++)
   3989  1.1  mrg 	    if (ptr[i] != ' ')
   3990  1.1  mrg 	      return NULL_TREE;
   3991  1.1  mrg 
   3992  1.1  mrg 	  return ret;
   3993  1.1  mrg 	}
   3994  1.1  mrg     }
   3995  1.1  mrg 
   3996  1.1  mrg   return NULL_TREE;
   3997  1.1  mrg }
   3998  1.1  mrg 
   3999  1.1  mrg 
   4000  1.1  mrg static void
   4001  1.1  mrg conv_scalar_char_value (gfc_symbol *sym, gfc_se *se, gfc_expr **expr)
   4002  1.1  mrg {
   4003  1.1  mrg   gcc_assert (expr);
   4004  1.1  mrg 
   4005  1.1  mrg   /* We used to modify the tree here. Now it is done earlier in
   4006  1.1  mrg      the front-end, so we only check it here to avoid regressions.  */
   4007  1.1  mrg   if (sym->backend_decl)
   4008  1.1  mrg     {
   4009  1.1  mrg       gcc_assert (TREE_CODE (TREE_TYPE (sym->backend_decl)) == INTEGER_TYPE);
   4010  1.1  mrg       gcc_assert (TYPE_UNSIGNED (TREE_TYPE (sym->backend_decl)) == 1);
   4011  1.1  mrg       gcc_assert (TYPE_PRECISION (TREE_TYPE (sym->backend_decl)) == CHAR_TYPE_SIZE);
   4012  1.1  mrg       gcc_assert (DECL_BY_REFERENCE (sym->backend_decl) == 0);
   4013  1.1  mrg     }
   4014  1.1  mrg 
   4015  1.1  mrg   /* If we have a constant character expression, make it into an
   4016  1.1  mrg       integer of type C char.  */
   4017  1.1  mrg   if ((*expr)->expr_type == EXPR_CONSTANT)
   4018  1.1  mrg     {
   4019  1.1  mrg       gfc_typespec ts;
   4020  1.1  mrg       gfc_clear_ts (&ts);
   4021  1.1  mrg 
   4022  1.1  mrg       *expr = gfc_get_int_expr (gfc_default_character_kind, NULL,
   4023  1.1  mrg 				(*expr)->value.character.string[0]);
   4024  1.1  mrg     }
   4025  1.1  mrg   else if (se != NULL && (*expr)->expr_type == EXPR_VARIABLE)
   4026  1.1  mrg     {
   4027  1.1  mrg       if ((*expr)->ref == NULL)
   4028  1.1  mrg 	{
   4029  1.1  mrg 	  se->expr = gfc_string_to_single_character
   4030  1.1  mrg 	    (build_int_cst (integer_type_node, 1),
   4031  1.1  mrg 	      gfc_build_addr_expr (gfc_get_pchar_type ((*expr)->ts.kind),
   4032  1.1  mrg 				  gfc_get_symbol_decl
   4033  1.1  mrg 				  ((*expr)->symtree->n.sym)),
   4034  1.1  mrg 	      (*expr)->ts.kind);
   4035  1.1  mrg 	}
   4036  1.1  mrg       else
   4037  1.1  mrg 	{
   4038  1.1  mrg 	  gfc_conv_variable (se, *expr);
   4039  1.1  mrg 	  se->expr = gfc_string_to_single_character
   4040  1.1  mrg 	    (build_int_cst (integer_type_node, 1),
   4041  1.1  mrg 	      gfc_build_addr_expr (gfc_get_pchar_type ((*expr)->ts.kind),
   4042  1.1  mrg 				  se->expr),
   4043  1.1  mrg 	      (*expr)->ts.kind);
   4044  1.1  mrg 	}
   4045  1.1  mrg     }
   4046  1.1  mrg }
   4047  1.1  mrg 
   4048  1.1  mrg /* Helper function for gfc_build_compare_string.  Return LEN_TRIM value
   4049  1.1  mrg    if STR is a string literal, otherwise return -1.  */
   4050  1.1  mrg 
   4051  1.1  mrg static int
   4052  1.1  mrg gfc_optimize_len_trim (tree len, tree str, int kind)
   4053  1.1  mrg {
   4054  1.1  mrg   if (kind == 1
   4055  1.1  mrg       && TREE_CODE (str) == ADDR_EXPR
   4056  1.1  mrg       && TREE_CODE (TREE_OPERAND (str, 0)) == ARRAY_REF
   4057  1.1  mrg       && TREE_CODE (TREE_OPERAND (TREE_OPERAND (str, 0), 0)) == STRING_CST
   4058  1.1  mrg       && array_ref_low_bound (TREE_OPERAND (str, 0))
   4059  1.1  mrg 	 == TREE_OPERAND (TREE_OPERAND (str, 0), 1)
   4060  1.1  mrg       && tree_fits_uhwi_p (len)
   4061  1.1  mrg       && tree_to_uhwi (len) >= 1
   4062  1.1  mrg       && tree_to_uhwi (len)
   4063  1.1  mrg 	 == (unsigned HOST_WIDE_INT)
   4064  1.1  mrg 	    TREE_STRING_LENGTH (TREE_OPERAND (TREE_OPERAND (str, 0), 0)))
   4065  1.1  mrg     {
   4066  1.1  mrg       tree folded = fold_convert (gfc_get_pchar_type (kind), str);
   4067  1.1  mrg       folded = build_fold_indirect_ref_loc (input_location, folded);
   4068  1.1  mrg       if (TREE_CODE (folded) == INTEGER_CST)
   4069  1.1  mrg 	{
   4070  1.1  mrg 	  tree string_cst = TREE_OPERAND (TREE_OPERAND (str, 0), 0);
   4071  1.1  mrg 	  int length = TREE_STRING_LENGTH (string_cst);
   4072  1.1  mrg 	  const char *ptr = TREE_STRING_POINTER (string_cst);
   4073  1.1  mrg 
   4074  1.1  mrg 	  for (; length > 0; length--)
   4075  1.1  mrg 	    if (ptr[length - 1] != ' ')
   4076  1.1  mrg 	      break;
   4077  1.1  mrg 
   4078  1.1  mrg 	  return length;
   4079  1.1  mrg 	}
   4080  1.1  mrg     }
   4081  1.1  mrg   return -1;
   4082  1.1  mrg }
   4083  1.1  mrg 
   4084  1.1  mrg /* Helper to build a call to memcmp.  */
   4085  1.1  mrg 
   4086  1.1  mrg static tree
   4087  1.1  mrg build_memcmp_call (tree s1, tree s2, tree n)
   4088  1.1  mrg {
   4089  1.1  mrg   tree tmp;
   4090  1.1  mrg 
   4091  1.1  mrg   if (!POINTER_TYPE_P (TREE_TYPE (s1)))
   4092  1.1  mrg     s1 = gfc_build_addr_expr (pvoid_type_node, s1);
   4093  1.1  mrg   else
   4094  1.1  mrg     s1 = fold_convert (pvoid_type_node, s1);
   4095  1.1  mrg 
   4096  1.1  mrg   if (!POINTER_TYPE_P (TREE_TYPE (s2)))
   4097  1.1  mrg     s2 = gfc_build_addr_expr (pvoid_type_node, s2);
   4098  1.1  mrg   else
   4099  1.1  mrg     s2 = fold_convert (pvoid_type_node, s2);
   4100  1.1  mrg 
   4101  1.1  mrg   n = fold_convert (size_type_node, n);
   4102  1.1  mrg 
   4103  1.1  mrg   tmp = build_call_expr_loc (input_location,
   4104  1.1  mrg 			     builtin_decl_explicit (BUILT_IN_MEMCMP),
   4105  1.1  mrg 			     3, s1, s2, n);
   4106  1.1  mrg 
   4107  1.1  mrg   return fold_convert (integer_type_node, tmp);
   4108  1.1  mrg }
   4109  1.1  mrg 
   4110  1.1  mrg /* Compare two strings. If they are all single characters, the result is the
   4111  1.1  mrg    subtraction of them. Otherwise, we build a library call.  */
   4112  1.1  mrg 
   4113  1.1  mrg tree
   4114  1.1  mrg gfc_build_compare_string (tree len1, tree str1, tree len2, tree str2, int kind,
   4115  1.1  mrg 			  enum tree_code code)
   4116  1.1  mrg {
   4117  1.1  mrg   tree sc1;
   4118  1.1  mrg   tree sc2;
   4119  1.1  mrg   tree fndecl;
   4120  1.1  mrg 
   4121  1.1  mrg   gcc_assert (POINTER_TYPE_P (TREE_TYPE (str1)));
   4122  1.1  mrg   gcc_assert (POINTER_TYPE_P (TREE_TYPE (str2)));
   4123  1.1  mrg 
   4124  1.1  mrg   sc1 = gfc_string_to_single_character (len1, str1, kind);
   4125  1.1  mrg   sc2 = gfc_string_to_single_character (len2, str2, kind);
   4126  1.1  mrg 
   4127  1.1  mrg   if (sc1 != NULL_TREE && sc2 != NULL_TREE)
   4128  1.1  mrg     {
   4129  1.1  mrg       /* Deal with single character specially.  */
   4130  1.1  mrg       sc1 = fold_convert (integer_type_node, sc1);
   4131  1.1  mrg       sc2 = fold_convert (integer_type_node, sc2);
   4132  1.1  mrg       return fold_build2_loc (input_location, MINUS_EXPR, integer_type_node,
   4133  1.1  mrg 			      sc1, sc2);
   4134  1.1  mrg     }
   4135  1.1  mrg 
   4136  1.1  mrg   if ((code == EQ_EXPR || code == NE_EXPR)
   4137  1.1  mrg       && optimize
   4138  1.1  mrg       && INTEGER_CST_P (len1) && INTEGER_CST_P (len2))
   4139  1.1  mrg     {
   4140  1.1  mrg       /* If one string is a string literal with LEN_TRIM longer
   4141  1.1  mrg 	 than the length of the second string, the strings
   4142  1.1  mrg 	 compare unequal.  */
   4143  1.1  mrg       int len = gfc_optimize_len_trim (len1, str1, kind);
   4144  1.1  mrg       if (len > 0 && compare_tree_int (len2, len) < 0)
   4145  1.1  mrg 	return integer_one_node;
   4146  1.1  mrg       len = gfc_optimize_len_trim (len2, str2, kind);
   4147  1.1  mrg       if (len > 0 && compare_tree_int (len1, len) < 0)
   4148  1.1  mrg 	return integer_one_node;
   4149  1.1  mrg     }
   4150  1.1  mrg 
   4151  1.1  mrg   /* We can compare via memcpy if the strings are known to be equal
   4152  1.1  mrg      in length and they are
   4153  1.1  mrg      - kind=1
   4154  1.1  mrg      - kind=4 and the comparison is for (in)equality.  */
   4155  1.1  mrg 
   4156  1.1  mrg   if (INTEGER_CST_P (len1) && INTEGER_CST_P (len2)
   4157  1.1  mrg       && tree_int_cst_equal (len1, len2)
   4158  1.1  mrg       && (kind == 1 || code == EQ_EXPR || code == NE_EXPR))
   4159  1.1  mrg     {
   4160  1.1  mrg       tree tmp;
   4161  1.1  mrg       tree chartype;
   4162  1.1  mrg 
   4163  1.1  mrg       chartype = gfc_get_char_type (kind);
   4164  1.1  mrg       tmp = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE(len1),
   4165  1.1  mrg 			     fold_convert (TREE_TYPE(len1),
   4166  1.1  mrg 					   TYPE_SIZE_UNIT(chartype)),
   4167  1.1  mrg 			     len1);
   4168  1.1  mrg       return build_memcmp_call (str1, str2, tmp);
   4169  1.1  mrg     }
   4170  1.1  mrg 
   4171  1.1  mrg   /* Build a call for the comparison.  */
   4172  1.1  mrg   if (kind == 1)
   4173  1.1  mrg     fndecl = gfor_fndecl_compare_string;
   4174  1.1  mrg   else if (kind == 4)
   4175  1.1  mrg     fndecl = gfor_fndecl_compare_string_char4;
   4176  1.1  mrg   else
   4177  1.1  mrg     gcc_unreachable ();
   4178  1.1  mrg 
   4179  1.1  mrg   return build_call_expr_loc (input_location, fndecl, 4,
   4180  1.1  mrg 			      len1, str1, len2, str2);
   4181  1.1  mrg }
   4182  1.1  mrg 
   4183  1.1  mrg 
   4184  1.1  mrg /* Return the backend_decl for a procedure pointer component.  */
   4185  1.1  mrg 
   4186  1.1  mrg static tree
   4187  1.1  mrg get_proc_ptr_comp (gfc_expr *e)
   4188  1.1  mrg {
   4189  1.1  mrg   gfc_se comp_se;
   4190  1.1  mrg   gfc_expr *e2;
   4191  1.1  mrg   expr_t old_type;
   4192  1.1  mrg 
   4193  1.1  mrg   gfc_init_se (&comp_se, NULL);
   4194  1.1  mrg   e2 = gfc_copy_expr (e);
   4195  1.1  mrg   /* We have to restore the expr type later so that gfc_free_expr frees
   4196  1.1  mrg      the exact same thing that was allocated.
   4197  1.1  mrg      TODO: This is ugly.  */
   4198  1.1  mrg   old_type = e2->expr_type;
   4199  1.1  mrg   e2->expr_type = EXPR_VARIABLE;
   4200  1.1  mrg   gfc_conv_expr (&comp_se, e2);
   4201  1.1  mrg   e2->expr_type = old_type;
   4202  1.1  mrg   gfc_free_expr (e2);
   4203  1.1  mrg   return build_fold_addr_expr_loc (input_location, comp_se.expr);
   4204  1.1  mrg }
   4205  1.1  mrg 
   4206  1.1  mrg 
   4207  1.1  mrg /* Convert a typebound function reference from a class object.  */
   4208  1.1  mrg static void
   4209  1.1  mrg conv_base_obj_fcn_val (gfc_se * se, tree base_object, gfc_expr * expr)
   4210  1.1  mrg {
   4211  1.1  mrg   gfc_ref *ref;
   4212  1.1  mrg   tree var;
   4213  1.1  mrg 
   4214  1.1  mrg   if (!VAR_P (base_object))
   4215  1.1  mrg     {
   4216  1.1  mrg       var = gfc_create_var (TREE_TYPE (base_object), NULL);
   4217  1.1  mrg       gfc_add_modify (&se->pre, var, base_object);
   4218  1.1  mrg     }
   4219  1.1  mrg   se->expr = gfc_class_vptr_get (base_object);
   4220  1.1  mrg   se->expr = build_fold_indirect_ref_loc (input_location, se->expr);
   4221  1.1  mrg   ref = expr->ref;
   4222  1.1  mrg   while (ref && ref->next)
   4223  1.1  mrg     ref = ref->next;
   4224  1.1  mrg   gcc_assert (ref && ref->type == REF_COMPONENT);
   4225  1.1  mrg   if (ref->u.c.sym->attr.extension)
   4226  1.1  mrg     conv_parent_component_references (se, ref);
   4227  1.1  mrg   gfc_conv_component_ref (se, ref);
   4228  1.1  mrg   se->expr = build_fold_addr_expr_loc (input_location, se->expr);
   4229  1.1  mrg }
   4230  1.1  mrg 
   4231  1.1  mrg 
   4232  1.1  mrg static void
   4233  1.1  mrg conv_function_val (gfc_se * se, gfc_symbol * sym, gfc_expr * expr,
   4234  1.1  mrg 		   gfc_actual_arglist *actual_args)
   4235  1.1  mrg {
   4236  1.1  mrg   tree tmp;
   4237  1.1  mrg 
   4238  1.1  mrg   if (gfc_is_proc_ptr_comp (expr))
   4239  1.1  mrg     tmp = get_proc_ptr_comp (expr);
   4240  1.1  mrg   else if (sym->attr.dummy)
   4241  1.1  mrg     {
   4242  1.1  mrg       tmp = gfc_get_symbol_decl (sym);
   4243  1.1  mrg       if (sym->attr.proc_pointer)
   4244  1.1  mrg         tmp = build_fold_indirect_ref_loc (input_location,
   4245  1.1  mrg 				       tmp);
   4246  1.1  mrg       gcc_assert (TREE_CODE (TREE_TYPE (tmp)) == POINTER_TYPE
   4247  1.1  mrg 	      && TREE_CODE (TREE_TYPE (TREE_TYPE (tmp))) == FUNCTION_TYPE);
   4248  1.1  mrg     }
   4249  1.1  mrg   else
   4250  1.1  mrg     {
   4251  1.1  mrg       if (!sym->backend_decl)
   4252  1.1  mrg 	sym->backend_decl = gfc_get_extern_function_decl (sym, actual_args);
   4253  1.1  mrg 
   4254  1.1  mrg       TREE_USED (sym->backend_decl) = 1;
   4255  1.1  mrg 
   4256  1.1  mrg       tmp = sym->backend_decl;
   4257  1.1  mrg 
   4258  1.1  mrg       if (sym->attr.cray_pointee)
   4259  1.1  mrg 	{
   4260  1.1  mrg 	  /* TODO - make the cray pointee a pointer to a procedure,
   4261  1.1  mrg 	     assign the pointer to it and use it for the call.  This
   4262  1.1  mrg 	     will do for now!  */
   4263  1.1  mrg 	  tmp = convert (build_pointer_type (TREE_TYPE (tmp)),
   4264  1.1  mrg 			 gfc_get_symbol_decl (sym->cp_pointer));
   4265  1.1  mrg 	  tmp = gfc_evaluate_now (tmp, &se->pre);
   4266  1.1  mrg 	}
   4267  1.1  mrg 
   4268  1.1  mrg       if (!POINTER_TYPE_P (TREE_TYPE (tmp)))
   4269  1.1  mrg 	{
   4270  1.1  mrg 	  gcc_assert (TREE_CODE (tmp) == FUNCTION_DECL);
   4271  1.1  mrg 	  tmp = gfc_build_addr_expr (NULL_TREE, tmp);
   4272  1.1  mrg 	}
   4273  1.1  mrg     }
   4274  1.1  mrg   se->expr = tmp;
   4275  1.1  mrg }
   4276  1.1  mrg 
   4277  1.1  mrg 
   4278  1.1  mrg /* Initialize MAPPING.  */
   4279  1.1  mrg 
   4280  1.1  mrg void
   4281  1.1  mrg gfc_init_interface_mapping (gfc_interface_mapping * mapping)
   4282  1.1  mrg {
   4283  1.1  mrg   mapping->syms = NULL;
   4284  1.1  mrg   mapping->charlens = NULL;
   4285  1.1  mrg }
   4286  1.1  mrg 
   4287  1.1  mrg 
   4288  1.1  mrg /* Free all memory held by MAPPING (but not MAPPING itself).  */
   4289  1.1  mrg 
   4290  1.1  mrg void
   4291  1.1  mrg gfc_free_interface_mapping (gfc_interface_mapping * mapping)
   4292  1.1  mrg {
   4293  1.1  mrg   gfc_interface_sym_mapping *sym;
   4294  1.1  mrg   gfc_interface_sym_mapping *nextsym;
   4295  1.1  mrg   gfc_charlen *cl;
   4296  1.1  mrg   gfc_charlen *nextcl;
   4297  1.1  mrg 
   4298  1.1  mrg   for (sym = mapping->syms; sym; sym = nextsym)
   4299  1.1  mrg     {
   4300  1.1  mrg       nextsym = sym->next;
   4301  1.1  mrg       sym->new_sym->n.sym->formal = NULL;
   4302  1.1  mrg       gfc_free_symbol (sym->new_sym->n.sym);
   4303  1.1  mrg       gfc_free_expr (sym->expr);
   4304  1.1  mrg       free (sym->new_sym);
   4305  1.1  mrg       free (sym);
   4306  1.1  mrg     }
   4307  1.1  mrg   for (cl = mapping->charlens; cl; cl = nextcl)
   4308  1.1  mrg     {
   4309  1.1  mrg       nextcl = cl->next;
   4310  1.1  mrg       gfc_free_expr (cl->length);
   4311  1.1  mrg       free (cl);
   4312  1.1  mrg     }
   4313  1.1  mrg }
   4314  1.1  mrg 
   4315  1.1  mrg 
   4316  1.1  mrg /* Return a copy of gfc_charlen CL.  Add the returned structure to
   4317  1.1  mrg    MAPPING so that it will be freed by gfc_free_interface_mapping.  */
   4318  1.1  mrg 
   4319  1.1  mrg static gfc_charlen *
   4320  1.1  mrg gfc_get_interface_mapping_charlen (gfc_interface_mapping * mapping,
   4321  1.1  mrg 				   gfc_charlen * cl)
   4322  1.1  mrg {
   4323  1.1  mrg   gfc_charlen *new_charlen;
   4324  1.1  mrg 
   4325  1.1  mrg   new_charlen = gfc_get_charlen ();
   4326  1.1  mrg   new_charlen->next = mapping->charlens;
   4327  1.1  mrg   new_charlen->length = gfc_copy_expr (cl->length);
   4328  1.1  mrg 
   4329  1.1  mrg   mapping->charlens = new_charlen;
   4330  1.1  mrg   return new_charlen;
   4331  1.1  mrg }
   4332  1.1  mrg 
   4333  1.1  mrg 
   4334  1.1  mrg /* A subroutine of gfc_add_interface_mapping.  Return a descriptorless
   4335  1.1  mrg    array variable that can be used as the actual argument for dummy
   4336  1.1  mrg    argument SYM.  Add any initialization code to BLOCK.  PACKED is as
   4337  1.1  mrg    for gfc_get_nodesc_array_type and DATA points to the first element
   4338  1.1  mrg    in the passed array.  */
   4339  1.1  mrg 
   4340  1.1  mrg static tree
   4341  1.1  mrg gfc_get_interface_mapping_array (stmtblock_t * block, gfc_symbol * sym,
   4342  1.1  mrg 				 gfc_packed packed, tree data, tree len)
   4343  1.1  mrg {
   4344  1.1  mrg   tree type;
   4345  1.1  mrg   tree var;
   4346  1.1  mrg 
   4347  1.1  mrg   if (len != NULL_TREE && (TREE_CONSTANT (len) || VAR_P (len)))
   4348  1.1  mrg     type = gfc_get_character_type_len (sym->ts.kind, len);
   4349  1.1  mrg   else
   4350  1.1  mrg     type = gfc_typenode_for_spec (&sym->ts);
   4351  1.1  mrg   type = gfc_get_nodesc_array_type (type, sym->as, packed,
   4352  1.1  mrg 				    !sym->attr.target && !sym->attr.pointer
   4353  1.1  mrg 				    && !sym->attr.proc_pointer);
   4354  1.1  mrg 
   4355  1.1  mrg   var = gfc_create_var (type, "ifm");
   4356  1.1  mrg   gfc_add_modify (block, var, fold_convert (type, data));
   4357  1.1  mrg 
   4358  1.1  mrg   return var;
   4359  1.1  mrg }
   4360  1.1  mrg 
   4361  1.1  mrg 
   4362  1.1  mrg /* A subroutine of gfc_add_interface_mapping.  Set the stride, upper bounds
   4363  1.1  mrg    and offset of descriptorless array type TYPE given that it has the same
   4364  1.1  mrg    size as DESC.  Add any set-up code to BLOCK.  */
   4365  1.1  mrg 
   4366  1.1  mrg static void
   4367  1.1  mrg gfc_set_interface_mapping_bounds (stmtblock_t * block, tree type, tree desc)
   4368  1.1  mrg {
   4369  1.1  mrg   int n;
   4370  1.1  mrg   tree dim;
   4371  1.1  mrg   tree offset;
   4372  1.1  mrg   tree tmp;
   4373  1.1  mrg 
   4374  1.1  mrg   offset = gfc_index_zero_node;
   4375  1.1  mrg   for (n = 0; n < GFC_TYPE_ARRAY_RANK (type); n++)
   4376  1.1  mrg     {
   4377  1.1  mrg       dim = gfc_rank_cst[n];
   4378  1.1  mrg       GFC_TYPE_ARRAY_STRIDE (type, n) = gfc_conv_array_stride (desc, n);
   4379  1.1  mrg       if (GFC_TYPE_ARRAY_LBOUND (type, n) == NULL_TREE)
   4380  1.1  mrg 	{
   4381  1.1  mrg 	  GFC_TYPE_ARRAY_LBOUND (type, n)
   4382  1.1  mrg 		= gfc_conv_descriptor_lbound_get (desc, dim);
   4383  1.1  mrg 	  GFC_TYPE_ARRAY_UBOUND (type, n)
   4384  1.1  mrg 		= gfc_conv_descriptor_ubound_get (desc, dim);
   4385  1.1  mrg 	}
   4386  1.1  mrg       else if (GFC_TYPE_ARRAY_UBOUND (type, n) == NULL_TREE)
   4387  1.1  mrg 	{
   4388  1.1  mrg 	  tmp = fold_build2_loc (input_location, MINUS_EXPR,
   4389  1.1  mrg 				 gfc_array_index_type,
   4390  1.1  mrg 				 gfc_conv_descriptor_ubound_get (desc, dim),
   4391  1.1  mrg 				 gfc_conv_descriptor_lbound_get (desc, dim));
   4392  1.1  mrg 	  tmp = fold_build2_loc (input_location, PLUS_EXPR,
   4393  1.1  mrg 				 gfc_array_index_type,
   4394  1.1  mrg 				 GFC_TYPE_ARRAY_LBOUND (type, n), tmp);
   4395  1.1  mrg 	  tmp = gfc_evaluate_now (tmp, block);
   4396  1.1  mrg 	  GFC_TYPE_ARRAY_UBOUND (type, n) = tmp;
   4397  1.1  mrg 	}
   4398  1.1  mrg       tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
   4399  1.1  mrg 			     GFC_TYPE_ARRAY_LBOUND (type, n),
   4400  1.1  mrg 			     GFC_TYPE_ARRAY_STRIDE (type, n));
   4401  1.1  mrg       offset = fold_build2_loc (input_location, MINUS_EXPR,
   4402  1.1  mrg 				gfc_array_index_type, offset, tmp);
   4403  1.1  mrg     }
   4404  1.1  mrg   offset = gfc_evaluate_now (offset, block);
   4405  1.1  mrg   GFC_TYPE_ARRAY_OFFSET (type) = offset;
   4406  1.1  mrg }
   4407  1.1  mrg 
   4408  1.1  mrg 
   4409  1.1  mrg /* Extend MAPPING so that it maps dummy argument SYM to the value stored
   4410  1.1  mrg    in SE.  The caller may still use se->expr and se->string_length after
   4411  1.1  mrg    calling this function.  */
   4412  1.1  mrg 
   4413  1.1  mrg void
   4414  1.1  mrg gfc_add_interface_mapping (gfc_interface_mapping * mapping,
   4415  1.1  mrg 			   gfc_symbol * sym, gfc_se * se,
   4416  1.1  mrg 			   gfc_expr *expr)
   4417  1.1  mrg {
   4418  1.1  mrg   gfc_interface_sym_mapping *sm;
   4419  1.1  mrg   tree desc;
   4420  1.1  mrg   tree tmp;
   4421  1.1  mrg   tree value;
   4422  1.1  mrg   gfc_symbol *new_sym;
   4423  1.1  mrg   gfc_symtree *root;
   4424  1.1  mrg   gfc_symtree *new_symtree;
   4425  1.1  mrg 
   4426  1.1  mrg   /* Create a new symbol to represent the actual argument.  */
   4427  1.1  mrg   new_sym = gfc_new_symbol (sym->name, NULL);
   4428  1.1  mrg   new_sym->ts = sym->ts;
   4429  1.1  mrg   new_sym->as = gfc_copy_array_spec (sym->as);
   4430  1.1  mrg   new_sym->attr.referenced = 1;
   4431  1.1  mrg   new_sym->attr.dimension = sym->attr.dimension;
   4432  1.1  mrg   new_sym->attr.contiguous = sym->attr.contiguous;
   4433  1.1  mrg   new_sym->attr.codimension = sym->attr.codimension;
   4434  1.1  mrg   new_sym->attr.pointer = sym->attr.pointer;
   4435  1.1  mrg   new_sym->attr.allocatable = sym->attr.allocatable;
   4436  1.1  mrg   new_sym->attr.flavor = sym->attr.flavor;
   4437  1.1  mrg   new_sym->attr.function = sym->attr.function;
   4438  1.1  mrg 
   4439  1.1  mrg   /* Ensure that the interface is available and that
   4440  1.1  mrg      descriptors are passed for array actual arguments.  */
   4441  1.1  mrg   if (sym->attr.flavor == FL_PROCEDURE)
   4442  1.1  mrg     {
   4443  1.1  mrg       new_sym->formal = expr->symtree->n.sym->formal;
   4444  1.1  mrg       new_sym->attr.always_explicit
   4445  1.1  mrg 	    = expr->symtree->n.sym->attr.always_explicit;
   4446  1.1  mrg     }
   4447  1.1  mrg 
   4448  1.1  mrg   /* Create a fake symtree for it.  */
   4449  1.1  mrg   root = NULL;
   4450  1.1  mrg   new_symtree = gfc_new_symtree (&root, sym->name);
   4451  1.1  mrg   new_symtree->n.sym = new_sym;
   4452  1.1  mrg   gcc_assert (new_symtree == root);
   4453  1.1  mrg 
   4454  1.1  mrg   /* Create a dummy->actual mapping.  */
   4455  1.1  mrg   sm = XCNEW (gfc_interface_sym_mapping);
   4456  1.1  mrg   sm->next = mapping->syms;
   4457  1.1  mrg   sm->old = sym;
   4458  1.1  mrg   sm->new_sym = new_symtree;
   4459  1.1  mrg   sm->expr = gfc_copy_expr (expr);
   4460  1.1  mrg   mapping->syms = sm;
   4461  1.1  mrg 
   4462  1.1  mrg   /* Stabilize the argument's value.  */
   4463  1.1  mrg   if (!sym->attr.function && se)
   4464  1.1  mrg     se->expr = gfc_evaluate_now (se->expr, &se->pre);
   4465  1.1  mrg 
   4466  1.1  mrg   if (sym->ts.type == BT_CHARACTER)
   4467  1.1  mrg     {
   4468  1.1  mrg       /* Create a copy of the dummy argument's length.  */
   4469  1.1  mrg       new_sym->ts.u.cl = gfc_get_interface_mapping_charlen (mapping, sym->ts.u.cl);
   4470  1.1  mrg       sm->expr->ts.u.cl = new_sym->ts.u.cl;
   4471  1.1  mrg 
   4472  1.1  mrg       /* If the length is specified as "*", record the length that
   4473  1.1  mrg 	 the caller is passing.  We should use the callee's length
   4474  1.1  mrg 	 in all other cases.  */
   4475  1.1  mrg       if (!new_sym->ts.u.cl->length && se)
   4476  1.1  mrg 	{
   4477  1.1  mrg 	  se->string_length = gfc_evaluate_now (se->string_length, &se->pre);
   4478  1.1  mrg 	  new_sym->ts.u.cl->backend_decl = se->string_length;
   4479  1.1  mrg 	}
   4480  1.1  mrg     }
   4481  1.1  mrg 
   4482  1.1  mrg   if (!se)
   4483  1.1  mrg     return;
   4484  1.1  mrg 
   4485  1.1  mrg   /* Use the passed value as-is if the argument is a function.  */
   4486  1.1  mrg   if (sym->attr.flavor == FL_PROCEDURE)
   4487  1.1  mrg     value = se->expr;
   4488  1.1  mrg 
   4489  1.1  mrg   /* If the argument is a pass-by-value scalar, use the value as is.  */
   4490  1.1  mrg   else if (!sym->attr.dimension && sym->attr.value)
   4491  1.1  mrg     value = se->expr;
   4492  1.1  mrg 
   4493  1.1  mrg   /* If the argument is either a string or a pointer to a string,
   4494  1.1  mrg      convert it to a boundless character type.  */
   4495  1.1  mrg   else if (!sym->attr.dimension && sym->ts.type == BT_CHARACTER)
   4496  1.1  mrg     {
   4497  1.1  mrg       se->string_length = gfc_evaluate_now (se->string_length, &se->pre);
   4498  1.1  mrg       tmp = gfc_get_character_type_len (sym->ts.kind, se->string_length);
   4499  1.1  mrg       tmp = build_pointer_type (tmp);
   4500  1.1  mrg       if (sym->attr.pointer)
   4501  1.1  mrg         value = build_fold_indirect_ref_loc (input_location,
   4502  1.1  mrg 					 se->expr);
   4503  1.1  mrg       else
   4504  1.1  mrg         value = se->expr;
   4505  1.1  mrg       value = fold_convert (tmp, value);
   4506  1.1  mrg     }
   4507  1.1  mrg 
   4508  1.1  mrg   /* If the argument is a scalar, a pointer to an array or an allocatable,
   4509  1.1  mrg      dereference it.  */
   4510  1.1  mrg   else if (!sym->attr.dimension || sym->attr.pointer || sym->attr.allocatable)
   4511  1.1  mrg     value = build_fold_indirect_ref_loc (input_location,
   4512  1.1  mrg 				     se->expr);
   4513  1.1  mrg 
   4514  1.1  mrg   /* For character(*), use the actual argument's descriptor.  */
   4515  1.1  mrg   else if (sym->ts.type == BT_CHARACTER && !new_sym->ts.u.cl->length)
   4516  1.1  mrg     value = build_fold_indirect_ref_loc (input_location,
   4517  1.1  mrg 					 se->expr);
   4518  1.1  mrg 
   4519  1.1  mrg   /* If the argument is an array descriptor, use it to determine
   4520  1.1  mrg      information about the actual argument's shape.  */
   4521  1.1  mrg   else if (POINTER_TYPE_P (TREE_TYPE (se->expr))
   4522  1.1  mrg 	   && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (TREE_TYPE (se->expr))))
   4523  1.1  mrg     {
   4524  1.1  mrg       /* Get the actual argument's descriptor.  */
   4525  1.1  mrg       desc = build_fold_indirect_ref_loc (input_location,
   4526  1.1  mrg 				      se->expr);
   4527  1.1  mrg 
   4528  1.1  mrg       /* Create the replacement variable.  */
   4529  1.1  mrg       tmp = gfc_conv_descriptor_data_get (desc);
   4530  1.1  mrg       value = gfc_get_interface_mapping_array (&se->pre, sym,
   4531  1.1  mrg 					       PACKED_NO, tmp,
   4532  1.1  mrg 					       se->string_length);
   4533  1.1  mrg 
   4534  1.1  mrg       /* Use DESC to work out the upper bounds, strides and offset.  */
   4535  1.1  mrg       gfc_set_interface_mapping_bounds (&se->pre, TREE_TYPE (value), desc);
   4536  1.1  mrg     }
   4537  1.1  mrg   else
   4538  1.1  mrg     /* Otherwise we have a packed array.  */
   4539  1.1  mrg     value = gfc_get_interface_mapping_array (&se->pre, sym,
   4540  1.1  mrg 					     PACKED_FULL, se->expr,
   4541  1.1  mrg 					     se->string_length);
   4542  1.1  mrg 
   4543  1.1  mrg   new_sym->backend_decl = value;
   4544  1.1  mrg }
   4545  1.1  mrg 
   4546  1.1  mrg 
   4547  1.1  mrg /* Called once all dummy argument mappings have been added to MAPPING,
   4548  1.1  mrg    but before the mapping is used to evaluate expressions.  Pre-evaluate
   4549  1.1  mrg    the length of each argument, adding any initialization code to PRE and
   4550  1.1  mrg    any finalization code to POST.  */
   4551  1.1  mrg 
   4552  1.1  mrg static void
   4553  1.1  mrg gfc_finish_interface_mapping (gfc_interface_mapping * mapping,
   4554  1.1  mrg 			      stmtblock_t * pre, stmtblock_t * post)
   4555  1.1  mrg {
   4556  1.1  mrg   gfc_interface_sym_mapping *sym;
   4557  1.1  mrg   gfc_expr *expr;
   4558  1.1  mrg   gfc_se se;
   4559  1.1  mrg 
   4560  1.1  mrg   for (sym = mapping->syms; sym; sym = sym->next)
   4561  1.1  mrg     if (sym->new_sym->n.sym->ts.type == BT_CHARACTER
   4562  1.1  mrg 	&& !sym->new_sym->n.sym->ts.u.cl->backend_decl)
   4563  1.1  mrg       {
   4564  1.1  mrg 	expr = sym->new_sym->n.sym->ts.u.cl->length;
   4565  1.1  mrg 	gfc_apply_interface_mapping_to_expr (mapping, expr);
   4566  1.1  mrg 	gfc_init_se (&se, NULL);
   4567  1.1  mrg 	gfc_conv_expr (&se, expr);
   4568  1.1  mrg 	se.expr = fold_convert (gfc_charlen_type_node, se.expr);
   4569  1.1  mrg 	se.expr = gfc_evaluate_now (se.expr, &se.pre);
   4570  1.1  mrg 	gfc_add_block_to_block (pre, &se.pre);
   4571  1.1  mrg 	gfc_add_block_to_block (post, &se.post);
   4572  1.1  mrg 
   4573  1.1  mrg 	sym->new_sym->n.sym->ts.u.cl->backend_decl = se.expr;
   4574  1.1  mrg       }
   4575  1.1  mrg }
   4576  1.1  mrg 
   4577  1.1  mrg 
   4578  1.1  mrg /* Like gfc_apply_interface_mapping_to_expr, but applied to
   4579  1.1  mrg    constructor C.  */
   4580  1.1  mrg 
   4581  1.1  mrg static void
   4582  1.1  mrg gfc_apply_interface_mapping_to_cons (gfc_interface_mapping * mapping,
   4583  1.1  mrg 				     gfc_constructor_base base)
   4584  1.1  mrg {
   4585  1.1  mrg   gfc_constructor *c;
   4586  1.1  mrg   for (c = gfc_constructor_first (base); c; c = gfc_constructor_next (c))
   4587  1.1  mrg     {
   4588  1.1  mrg       gfc_apply_interface_mapping_to_expr (mapping, c->expr);
   4589  1.1  mrg       if (c->iterator)
   4590  1.1  mrg 	{
   4591  1.1  mrg 	  gfc_apply_interface_mapping_to_expr (mapping, c->iterator->start);
   4592  1.1  mrg 	  gfc_apply_interface_mapping_to_expr (mapping, c->iterator->end);
   4593  1.1  mrg 	  gfc_apply_interface_mapping_to_expr (mapping, c->iterator->step);
   4594  1.1  mrg 	}
   4595  1.1  mrg     }
   4596  1.1  mrg }
   4597  1.1  mrg 
   4598  1.1  mrg 
   4599  1.1  mrg /* Like gfc_apply_interface_mapping_to_expr, but applied to
   4600  1.1  mrg    reference REF.  */
   4601  1.1  mrg 
   4602  1.1  mrg static void
   4603  1.1  mrg gfc_apply_interface_mapping_to_ref (gfc_interface_mapping * mapping,
   4604  1.1  mrg 				    gfc_ref * ref)
   4605  1.1  mrg {
   4606  1.1  mrg   int n;
   4607  1.1  mrg 
   4608  1.1  mrg   for (; ref; ref = ref->next)
   4609  1.1  mrg     switch (ref->type)
   4610  1.1  mrg       {
   4611  1.1  mrg       case REF_ARRAY:
   4612  1.1  mrg 	for (n = 0; n < ref->u.ar.dimen; n++)
   4613  1.1  mrg 	  {
   4614  1.1  mrg 	    gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.start[n]);
   4615  1.1  mrg 	    gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.end[n]);
   4616  1.1  mrg 	    gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.stride[n]);
   4617  1.1  mrg 	  }
   4618  1.1  mrg 	break;
   4619  1.1  mrg 
   4620  1.1  mrg       case REF_COMPONENT:
   4621  1.1  mrg       case REF_INQUIRY:
   4622  1.1  mrg 	break;
   4623  1.1  mrg 
   4624  1.1  mrg       case REF_SUBSTRING:
   4625  1.1  mrg 	gfc_apply_interface_mapping_to_expr (mapping, ref->u.ss.start);
   4626  1.1  mrg 	gfc_apply_interface_mapping_to_expr (mapping, ref->u.ss.end);
   4627  1.1  mrg 	break;
   4628  1.1  mrg       }
   4629  1.1  mrg }
   4630  1.1  mrg 
   4631  1.1  mrg 
   4632  1.1  mrg /* Convert intrinsic function calls into result expressions.  */
   4633  1.1  mrg 
   4634  1.1  mrg static bool
   4635  1.1  mrg gfc_map_intrinsic_function (gfc_expr *expr, gfc_interface_mapping *mapping)
   4636  1.1  mrg {
   4637  1.1  mrg   gfc_symbol *sym;
   4638  1.1  mrg   gfc_expr *new_expr;
   4639  1.1  mrg   gfc_expr *arg1;
   4640  1.1  mrg   gfc_expr *arg2;
   4641  1.1  mrg   int d, dup;
   4642  1.1  mrg 
   4643  1.1  mrg   arg1 = expr->value.function.actual->expr;
   4644  1.1  mrg   if (expr->value.function.actual->next)
   4645  1.1  mrg     arg2 = expr->value.function.actual->next->expr;
   4646  1.1  mrg   else
   4647  1.1  mrg     arg2 = NULL;
   4648  1.1  mrg 
   4649  1.1  mrg   sym = arg1->symtree->n.sym;
   4650  1.1  mrg 
   4651  1.1  mrg   if (sym->attr.dummy)
   4652  1.1  mrg     return false;
   4653  1.1  mrg 
   4654  1.1  mrg   new_expr = NULL;
   4655  1.1  mrg 
   4656  1.1  mrg   switch (expr->value.function.isym->id)
   4657  1.1  mrg     {
   4658  1.1  mrg     case GFC_ISYM_LEN:
   4659  1.1  mrg       /* TODO figure out why this condition is necessary.  */
   4660  1.1  mrg       if (sym->attr.function
   4661  1.1  mrg 	  && (arg1->ts.u.cl->length == NULL
   4662  1.1  mrg 	      || (arg1->ts.u.cl->length->expr_type != EXPR_CONSTANT
   4663  1.1  mrg 		  && arg1->ts.u.cl->length->expr_type != EXPR_VARIABLE)))
   4664  1.1  mrg 	return false;
   4665  1.1  mrg 
   4666  1.1  mrg       new_expr = gfc_copy_expr (arg1->ts.u.cl->length);
   4667  1.1  mrg       break;
   4668  1.1  mrg 
   4669  1.1  mrg     case GFC_ISYM_LEN_TRIM:
   4670  1.1  mrg       new_expr = gfc_copy_expr (arg1);
   4671  1.1  mrg       gfc_apply_interface_mapping_to_expr (mapping, new_expr);
   4672  1.1  mrg 
   4673  1.1  mrg       if (!new_expr)
   4674  1.1  mrg 	return false;
   4675  1.1  mrg 
   4676  1.1  mrg       gfc_replace_expr (arg1, new_expr);
   4677  1.1  mrg       return true;
   4678  1.1  mrg 
   4679  1.1  mrg     case GFC_ISYM_SIZE:
   4680  1.1  mrg       if (!sym->as || sym->as->rank == 0)
   4681  1.1  mrg 	return false;
   4682  1.1  mrg 
   4683  1.1  mrg       if (arg2 && arg2->expr_type == EXPR_CONSTANT)
   4684  1.1  mrg 	{
   4685  1.1  mrg 	  dup = mpz_get_si (arg2->value.integer);
   4686  1.1  mrg 	  d = dup - 1;
   4687  1.1  mrg 	}
   4688  1.1  mrg       else
   4689  1.1  mrg 	{
   4690  1.1  mrg 	  dup = sym->as->rank;
   4691  1.1  mrg 	  d = 0;
   4692  1.1  mrg 	}
   4693  1.1  mrg 
   4694  1.1  mrg       for (; d < dup; d++)
   4695  1.1  mrg 	{
   4696  1.1  mrg 	  gfc_expr *tmp;
   4697  1.1  mrg 
   4698  1.1  mrg 	  if (!sym->as->upper[d] || !sym->as->lower[d])
   4699  1.1  mrg 	    {
   4700  1.1  mrg 	      gfc_free_expr (new_expr);
   4701  1.1  mrg 	      return false;
   4702  1.1  mrg 	    }
   4703  1.1  mrg 
   4704  1.1  mrg 	  tmp = gfc_add (gfc_copy_expr (sym->as->upper[d]),
   4705  1.1  mrg 					gfc_get_int_expr (gfc_default_integer_kind,
   4706  1.1  mrg 							  NULL, 1));
   4707  1.1  mrg 	  tmp = gfc_subtract (tmp, gfc_copy_expr (sym->as->lower[d]));
   4708  1.1  mrg 	  if (new_expr)
   4709  1.1  mrg 	    new_expr = gfc_multiply (new_expr, tmp);
   4710  1.1  mrg 	  else
   4711  1.1  mrg 	    new_expr = tmp;
   4712  1.1  mrg 	}
   4713  1.1  mrg       break;
   4714  1.1  mrg 
   4715  1.1  mrg     case GFC_ISYM_LBOUND:
   4716  1.1  mrg     case GFC_ISYM_UBOUND:
   4717  1.1  mrg 	/* TODO These implementations of lbound and ubound do not limit if
   4718  1.1  mrg 	   the size < 0, according to F95's 13.14.53 and 13.14.113.  */
   4719  1.1  mrg 
   4720  1.1  mrg       if (!sym->as || sym->as->rank == 0)
   4721  1.1  mrg 	return false;
   4722  1.1  mrg 
   4723  1.1  mrg       if (arg2 && arg2->expr_type == EXPR_CONSTANT)
   4724  1.1  mrg 	d = mpz_get_si (arg2->value.integer) - 1;
   4725  1.1  mrg       else
   4726  1.1  mrg 	return false;
   4727  1.1  mrg 
   4728  1.1  mrg       if (expr->value.function.isym->id == GFC_ISYM_LBOUND)
   4729  1.1  mrg 	{
   4730  1.1  mrg 	  if (sym->as->lower[d])
   4731  1.1  mrg 	    new_expr = gfc_copy_expr (sym->as->lower[d]);
   4732  1.1  mrg 	}
   4733  1.1  mrg       else
   4734  1.1  mrg 	{
   4735  1.1  mrg 	  if (sym->as->upper[d])
   4736  1.1  mrg 	    new_expr = gfc_copy_expr (sym->as->upper[d]);
   4737  1.1  mrg 	}
   4738  1.1  mrg       break;
   4739  1.1  mrg 
   4740  1.1  mrg     default:
   4741  1.1  mrg       break;
   4742  1.1  mrg     }
   4743  1.1  mrg 
   4744  1.1  mrg   gfc_apply_interface_mapping_to_expr (mapping, new_expr);
   4745  1.1  mrg   if (!new_expr)
   4746  1.1  mrg     return false;
   4747  1.1  mrg 
   4748  1.1  mrg   gfc_replace_expr (expr, new_expr);
   4749  1.1  mrg   return true;
   4750  1.1  mrg }
   4751  1.1  mrg 
   4752  1.1  mrg 
   4753  1.1  mrg static void
   4754  1.1  mrg gfc_map_fcn_formal_to_actual (gfc_expr *expr, gfc_expr *map_expr,
   4755  1.1  mrg 			      gfc_interface_mapping * mapping)
   4756  1.1  mrg {
   4757  1.1  mrg   gfc_formal_arglist *f;
   4758  1.1  mrg   gfc_actual_arglist *actual;
   4759  1.1  mrg 
   4760  1.1  mrg   actual = expr->value.function.actual;
   4761  1.1  mrg   f = gfc_sym_get_dummy_args (map_expr->symtree->n.sym);
   4762  1.1  mrg 
   4763  1.1  mrg   for (; f && actual; f = f->next, actual = actual->next)
   4764  1.1  mrg     {
   4765  1.1  mrg       if (!actual->expr)
   4766  1.1  mrg 	continue;
   4767  1.1  mrg 
   4768  1.1  mrg       gfc_add_interface_mapping (mapping, f->sym, NULL, actual->expr);
   4769  1.1  mrg     }
   4770  1.1  mrg 
   4771  1.1  mrg   if (map_expr->symtree->n.sym->attr.dimension)
   4772  1.1  mrg     {
   4773  1.1  mrg       int d;
   4774  1.1  mrg       gfc_array_spec *as;
   4775  1.1  mrg 
   4776  1.1  mrg       as = gfc_copy_array_spec (map_expr->symtree->n.sym->as);
   4777  1.1  mrg 
   4778  1.1  mrg       for (d = 0; d < as->rank; d++)
   4779  1.1  mrg 	{
   4780  1.1  mrg 	  gfc_apply_interface_mapping_to_expr (mapping, as->lower[d]);
   4781  1.1  mrg 	  gfc_apply_interface_mapping_to_expr (mapping, as->upper[d]);
   4782  1.1  mrg 	}
   4783  1.1  mrg 
   4784  1.1  mrg       expr->value.function.esym->as = as;
   4785  1.1  mrg     }
   4786  1.1  mrg 
   4787  1.1  mrg   if (map_expr->symtree->n.sym->ts.type == BT_CHARACTER)
   4788  1.1  mrg     {
   4789  1.1  mrg       expr->value.function.esym->ts.u.cl->length
   4790  1.1  mrg 	= gfc_copy_expr (map_expr->symtree->n.sym->ts.u.cl->length);
   4791  1.1  mrg 
   4792  1.1  mrg       gfc_apply_interface_mapping_to_expr (mapping,
   4793  1.1  mrg 			expr->value.function.esym->ts.u.cl->length);
   4794  1.1  mrg     }
   4795  1.1  mrg }
   4796  1.1  mrg 
   4797  1.1  mrg 
   4798  1.1  mrg /* EXPR is a copy of an expression that appeared in the interface
   4799  1.1  mrg    associated with MAPPING.  Walk it recursively looking for references to
   4800  1.1  mrg    dummy arguments that MAPPING maps to actual arguments.  Replace each such
   4801  1.1  mrg    reference with a reference to the associated actual argument.  */
   4802  1.1  mrg 
   4803  1.1  mrg static void
   4804  1.1  mrg gfc_apply_interface_mapping_to_expr (gfc_interface_mapping * mapping,
   4805  1.1  mrg 				     gfc_expr * expr)
   4806  1.1  mrg {
   4807  1.1  mrg   gfc_interface_sym_mapping *sym;
   4808  1.1  mrg   gfc_actual_arglist *actual;
   4809  1.1  mrg 
   4810  1.1  mrg   if (!expr)
   4811  1.1  mrg     return;
   4812  1.1  mrg 
   4813  1.1  mrg   /* Copying an expression does not copy its length, so do that here.  */
   4814  1.1  mrg   if (expr->ts.type == BT_CHARACTER && expr->ts.u.cl)
   4815  1.1  mrg     {
   4816  1.1  mrg       expr->ts.u.cl = gfc_get_interface_mapping_charlen (mapping, expr->ts.u.cl);
   4817  1.1  mrg       gfc_apply_interface_mapping_to_expr (mapping, expr->ts.u.cl->length);
   4818  1.1  mrg     }
   4819  1.1  mrg 
   4820  1.1  mrg   /* Apply the mapping to any references.  */
   4821  1.1  mrg   gfc_apply_interface_mapping_to_ref (mapping, expr->ref);
   4822  1.1  mrg 
   4823  1.1  mrg   /* ...and to the expression's symbol, if it has one.  */
   4824  1.1  mrg   /* TODO Find out why the condition on expr->symtree had to be moved into
   4825  1.1  mrg      the loop rather than being outside it, as originally.  */
   4826  1.1  mrg   for (sym = mapping->syms; sym; sym = sym->next)
   4827  1.1  mrg     if (expr->symtree && sym->old == expr->symtree->n.sym)
   4828  1.1  mrg       {
   4829  1.1  mrg 	if (sym->new_sym->n.sym->backend_decl)
   4830  1.1  mrg 	  expr->symtree = sym->new_sym;
   4831  1.1  mrg 	else if (sym->expr)
   4832  1.1  mrg 	  gfc_replace_expr (expr, gfc_copy_expr (sym->expr));
   4833  1.1  mrg       }
   4834  1.1  mrg 
   4835  1.1  mrg       /* ...and to subexpressions in expr->value.  */
   4836  1.1  mrg   switch (expr->expr_type)
   4837  1.1  mrg     {
   4838  1.1  mrg     case EXPR_VARIABLE:
   4839  1.1  mrg     case EXPR_CONSTANT:
   4840  1.1  mrg     case EXPR_NULL:
   4841  1.1  mrg     case EXPR_SUBSTRING:
   4842  1.1  mrg       break;
   4843  1.1  mrg 
   4844  1.1  mrg     case EXPR_OP:
   4845  1.1  mrg       gfc_apply_interface_mapping_to_expr (mapping, expr->value.op.op1);
   4846  1.1  mrg       gfc_apply_interface_mapping_to_expr (mapping, expr->value.op.op2);
   4847  1.1  mrg       break;
   4848  1.1  mrg 
   4849  1.1  mrg     case EXPR_FUNCTION:
   4850  1.1  mrg       for (actual = expr->value.function.actual; actual; actual = actual->next)
   4851  1.1  mrg 	gfc_apply_interface_mapping_to_expr (mapping, actual->expr);
   4852  1.1  mrg 
   4853  1.1  mrg       if (expr->value.function.esym == NULL
   4854  1.1  mrg 	    && expr->value.function.isym != NULL
   4855  1.1  mrg 	    && expr->value.function.actual
   4856  1.1  mrg 	    && expr->value.function.actual->expr
   4857  1.1  mrg 	    && expr->value.function.actual->expr->symtree
   4858  1.1  mrg 	    && gfc_map_intrinsic_function (expr, mapping))
   4859  1.1  mrg 	break;
   4860  1.1  mrg 
   4861  1.1  mrg       for (sym = mapping->syms; sym; sym = sym->next)
   4862  1.1  mrg 	if (sym->old == expr->value.function.esym)
   4863  1.1  mrg 	  {
   4864  1.1  mrg 	    expr->value.function.esym = sym->new_sym->n.sym;
   4865  1.1  mrg 	    gfc_map_fcn_formal_to_actual (expr, sym->expr, mapping);
   4866  1.1  mrg 	    expr->value.function.esym->result = sym->new_sym->n.sym;
   4867  1.1  mrg 	  }
   4868  1.1  mrg       break;
   4869  1.1  mrg 
   4870  1.1  mrg     case EXPR_ARRAY:
   4871  1.1  mrg     case EXPR_STRUCTURE:
   4872  1.1  mrg       gfc_apply_interface_mapping_to_cons (mapping, expr->value.constructor);
   4873  1.1  mrg       break;
   4874  1.1  mrg 
   4875  1.1  mrg     case EXPR_COMPCALL:
   4876  1.1  mrg     case EXPR_PPC:
   4877  1.1  mrg     case EXPR_UNKNOWN:
   4878  1.1  mrg       gcc_unreachable ();
   4879  1.1  mrg       break;
   4880  1.1  mrg     }
   4881  1.1  mrg 
   4882  1.1  mrg   return;
   4883  1.1  mrg }
   4884  1.1  mrg 
   4885  1.1  mrg 
   4886  1.1  mrg /* Evaluate interface expression EXPR using MAPPING.  Store the result
   4887  1.1  mrg    in SE.  */
   4888  1.1  mrg 
   4889  1.1  mrg void
   4890  1.1  mrg gfc_apply_interface_mapping (gfc_interface_mapping * mapping,
   4891  1.1  mrg 			     gfc_se * se, gfc_expr * expr)
   4892  1.1  mrg {
   4893  1.1  mrg   expr = gfc_copy_expr (expr);
   4894  1.1  mrg   gfc_apply_interface_mapping_to_expr (mapping, expr);
   4895  1.1  mrg   gfc_conv_expr (se, expr);
   4896  1.1  mrg   se->expr = gfc_evaluate_now (se->expr, &se->pre);
   4897  1.1  mrg   gfc_free_expr (expr);
   4898  1.1  mrg }
   4899  1.1  mrg 
   4900  1.1  mrg 
   4901  1.1  mrg /* Returns a reference to a temporary array into which a component of
   4902  1.1  mrg    an actual argument derived type array is copied and then returned
   4903  1.1  mrg    after the function call.  */
   4904  1.1  mrg void
   4905  1.1  mrg gfc_conv_subref_array_arg (gfc_se *se, gfc_expr * expr, int g77,
   4906  1.1  mrg 			   sym_intent intent, bool formal_ptr,
   4907  1.1  mrg 			   const gfc_symbol *fsym, const char *proc_name,
   4908  1.1  mrg 			   gfc_symbol *sym, bool check_contiguous)
   4909  1.1  mrg {
   4910  1.1  mrg   gfc_se lse;
   4911  1.1  mrg   gfc_se rse;
   4912  1.1  mrg   gfc_ss *lss;
   4913  1.1  mrg   gfc_ss *rss;
   4914  1.1  mrg   gfc_loopinfo loop;
   4915  1.1  mrg   gfc_loopinfo loop2;
   4916  1.1  mrg   gfc_array_info *info;
   4917  1.1  mrg   tree offset;
   4918  1.1  mrg   tree tmp_index;
   4919  1.1  mrg   tree tmp;
   4920  1.1  mrg   tree base_type;
   4921  1.1  mrg   tree size;
   4922  1.1  mrg   stmtblock_t body;
   4923  1.1  mrg   int n;
   4924  1.1  mrg   int dimen;
   4925  1.1  mrg   gfc_se work_se;
   4926  1.1  mrg   gfc_se *parmse;
   4927  1.1  mrg   bool pass_optional;
   4928  1.1  mrg 
   4929  1.1  mrg   pass_optional = fsym && fsym->attr.optional && sym && sym->attr.optional;
   4930  1.1  mrg 
   4931  1.1  mrg   if (pass_optional || check_contiguous)
   4932  1.1  mrg     {
   4933  1.1  mrg       gfc_init_se (&work_se, NULL);
   4934  1.1  mrg       parmse = &work_se;
   4935  1.1  mrg     }
   4936  1.1  mrg   else
   4937  1.1  mrg     parmse = se;
   4938  1.1  mrg 
   4939  1.1  mrg   if (gfc_option.rtcheck & GFC_RTCHECK_ARRAY_TEMPS)
   4940  1.1  mrg     {
   4941  1.1  mrg       /* We will create a temporary array, so let us warn.  */
   4942  1.1  mrg       char * msg;
   4943  1.1  mrg 
   4944  1.1  mrg       if (fsym && proc_name)
   4945  1.1  mrg 	msg = xasprintf ("An array temporary was created for argument "
   4946  1.1  mrg 			 "'%s' of procedure '%s'", fsym->name, proc_name);
   4947  1.1  mrg       else
   4948  1.1  mrg 	msg = xasprintf ("An array temporary was created");
   4949  1.1  mrg 
   4950  1.1  mrg       tmp = build_int_cst (logical_type_node, 1);
   4951  1.1  mrg       gfc_trans_runtime_check (false, true, tmp, &parmse->pre,
   4952  1.1  mrg 			       &expr->where, msg);
   4953  1.1  mrg       free (msg);
   4954  1.1  mrg     }
   4955  1.1  mrg 
   4956  1.1  mrg   gfc_init_se (&lse, NULL);
   4957  1.1  mrg   gfc_init_se (&rse, NULL);
   4958  1.1  mrg 
   4959  1.1  mrg   /* Walk the argument expression.  */
   4960  1.1  mrg   rss = gfc_walk_expr (expr);
   4961  1.1  mrg 
   4962  1.1  mrg   gcc_assert (rss != gfc_ss_terminator);
   4963  1.1  mrg 
   4964  1.1  mrg   /* Initialize the scalarizer.  */
   4965  1.1  mrg   gfc_init_loopinfo (&loop);
   4966  1.1  mrg   gfc_add_ss_to_loop (&loop, rss);
   4967  1.1  mrg 
   4968  1.1  mrg   /* Calculate the bounds of the scalarization.  */
   4969  1.1  mrg   gfc_conv_ss_startstride (&loop);
   4970  1.1  mrg 
   4971  1.1  mrg   /* Build an ss for the temporary.  */
   4972  1.1  mrg   if (expr->ts.type == BT_CHARACTER && !expr->ts.u.cl->backend_decl)
   4973  1.1  mrg     gfc_conv_string_length (expr->ts.u.cl, expr, &parmse->pre);
   4974  1.1  mrg 
   4975  1.1  mrg   base_type = gfc_typenode_for_spec (&expr->ts);
   4976  1.1  mrg   if (GFC_ARRAY_TYPE_P (base_type)
   4977  1.1  mrg 		|| GFC_DESCRIPTOR_TYPE_P (base_type))
   4978  1.1  mrg     base_type = gfc_get_element_type (base_type);
   4979  1.1  mrg 
   4980  1.1  mrg   if (expr->ts.type == BT_CLASS)
   4981  1.1  mrg     base_type = gfc_typenode_for_spec (&CLASS_DATA (expr)->ts);
   4982  1.1  mrg 
   4983  1.1  mrg   loop.temp_ss = gfc_get_temp_ss (base_type, ((expr->ts.type == BT_CHARACTER)
   4984  1.1  mrg 					      ? expr->ts.u.cl->backend_decl
   4985  1.1  mrg 					      : NULL),
   4986  1.1  mrg 				  loop.dimen);
   4987  1.1  mrg 
   4988  1.1  mrg   parmse->string_length = loop.temp_ss->info->string_length;
   4989  1.1  mrg 
   4990  1.1  mrg   /* Associate the SS with the loop.  */
   4991  1.1  mrg   gfc_add_ss_to_loop (&loop, loop.temp_ss);
   4992  1.1  mrg 
   4993  1.1  mrg   /* Setup the scalarizing loops.  */
   4994  1.1  mrg   gfc_conv_loop_setup (&loop, &expr->where);
   4995  1.1  mrg 
   4996  1.1  mrg   /* Pass the temporary descriptor back to the caller.  */
   4997  1.1  mrg   info = &loop.temp_ss->info->data.array;
   4998  1.1  mrg   parmse->expr = info->descriptor;
   4999  1.1  mrg 
   5000  1.1  mrg   /* Setup the gfc_se structures.  */
   5001  1.1  mrg   gfc_copy_loopinfo_to_se (&lse, &loop);
   5002  1.1  mrg   gfc_copy_loopinfo_to_se (&rse, &loop);
   5003  1.1  mrg 
   5004  1.1  mrg   rse.ss = rss;
   5005  1.1  mrg   lse.ss = loop.temp_ss;
   5006  1.1  mrg   gfc_mark_ss_chain_used (rss, 1);
   5007  1.1  mrg   gfc_mark_ss_chain_used (loop.temp_ss, 1);
   5008  1.1  mrg 
   5009  1.1  mrg   /* Start the scalarized loop body.  */
   5010  1.1  mrg   gfc_start_scalarized_body (&loop, &body);
   5011  1.1  mrg 
   5012  1.1  mrg   /* Translate the expression.  */
   5013  1.1  mrg   gfc_conv_expr (&rse, expr);
   5014  1.1  mrg 
   5015  1.1  mrg   /* Reset the offset for the function call since the loop
   5016  1.1  mrg      is zero based on the data pointer.  Note that the temp
   5017  1.1  mrg      comes first in the loop chain since it is added second.  */
   5018  1.1  mrg   if (gfc_is_class_array_function (expr))
   5019  1.1  mrg     {
   5020  1.1  mrg       tmp = loop.ss->loop_chain->info->data.array.descriptor;
   5021  1.1  mrg       gfc_conv_descriptor_offset_set (&loop.pre, tmp,
   5022  1.1  mrg 				      gfc_index_zero_node);
   5023  1.1  mrg     }
   5024  1.1  mrg 
   5025  1.1  mrg   gfc_conv_tmp_array_ref (&lse);
   5026  1.1  mrg 
   5027  1.1  mrg   if (intent != INTENT_OUT)
   5028  1.1  mrg     {
   5029  1.1  mrg       tmp = gfc_trans_scalar_assign (&lse, &rse, expr->ts, false, false);
   5030  1.1  mrg       gfc_add_expr_to_block (&body, tmp);
   5031  1.1  mrg       gcc_assert (rse.ss == gfc_ss_terminator);
   5032  1.1  mrg       gfc_trans_scalarizing_loops (&loop, &body);
   5033  1.1  mrg     }
   5034  1.1  mrg   else
   5035  1.1  mrg     {
   5036  1.1  mrg       /* Make sure that the temporary declaration survives by merging
   5037  1.1  mrg        all the loop declarations into the current context.  */
   5038  1.1  mrg       for (n = 0; n < loop.dimen; n++)
   5039  1.1  mrg 	{
   5040  1.1  mrg 	  gfc_merge_block_scope (&body);
   5041  1.1  mrg 	  body = loop.code[loop.order[n]];
   5042  1.1  mrg 	}
   5043  1.1  mrg       gfc_merge_block_scope (&body);
   5044  1.1  mrg     }
   5045  1.1  mrg 
   5046  1.1  mrg   /* Add the post block after the second loop, so that any
   5047  1.1  mrg      freeing of allocated memory is done at the right time.  */
   5048  1.1  mrg   gfc_add_block_to_block (&parmse->pre, &loop.pre);
   5049  1.1  mrg 
   5050  1.1  mrg   /**********Copy the temporary back again.*********/
   5051  1.1  mrg 
   5052  1.1  mrg   gfc_init_se (&lse, NULL);
   5053  1.1  mrg   gfc_init_se (&rse, NULL);
   5054  1.1  mrg 
   5055  1.1  mrg   /* Walk the argument expression.  */
   5056  1.1  mrg   lss = gfc_walk_expr (expr);
   5057  1.1  mrg   rse.ss = loop.temp_ss;
   5058  1.1  mrg   lse.ss = lss;
   5059  1.1  mrg 
   5060  1.1  mrg   /* Initialize the scalarizer.  */
   5061  1.1  mrg   gfc_init_loopinfo (&loop2);
   5062  1.1  mrg   gfc_add_ss_to_loop (&loop2, lss);
   5063  1.1  mrg 
   5064  1.1  mrg   dimen = rse.ss->dimen;
   5065  1.1  mrg 
   5066  1.1  mrg   /* Skip the write-out loop for this case.  */
   5067  1.1  mrg   if (gfc_is_class_array_function (expr))
   5068  1.1  mrg     goto class_array_fcn;
   5069  1.1  mrg 
   5070  1.1  mrg   /* Calculate the bounds of the scalarization.  */
   5071  1.1  mrg   gfc_conv_ss_startstride (&loop2);
   5072  1.1  mrg 
   5073  1.1  mrg   /* Setup the scalarizing loops.  */
   5074  1.1  mrg   gfc_conv_loop_setup (&loop2, &expr->where);
   5075  1.1  mrg 
   5076  1.1  mrg   gfc_copy_loopinfo_to_se (&lse, &loop2);
   5077  1.1  mrg   gfc_copy_loopinfo_to_se (&rse, &loop2);
   5078  1.1  mrg 
   5079  1.1  mrg   gfc_mark_ss_chain_used (lss, 1);
   5080  1.1  mrg   gfc_mark_ss_chain_used (loop.temp_ss, 1);
   5081  1.1  mrg 
   5082  1.1  mrg   /* Declare the variable to hold the temporary offset and start the
   5083  1.1  mrg      scalarized loop body.  */
   5084  1.1  mrg   offset = gfc_create_var (gfc_array_index_type, NULL);
   5085  1.1  mrg   gfc_start_scalarized_body (&loop2, &body);
   5086  1.1  mrg 
   5087  1.1  mrg   /* Build the offsets for the temporary from the loop variables.  The
   5088  1.1  mrg      temporary array has lbounds of zero and strides of one in all
   5089  1.1  mrg      dimensions, so this is very simple.  The offset is only computed
   5090  1.1  mrg      outside the innermost loop, so the overall transfer could be
   5091  1.1  mrg      optimized further.  */
   5092  1.1  mrg   info = &rse.ss->info->data.array;
   5093  1.1  mrg 
   5094  1.1  mrg   tmp_index = gfc_index_zero_node;
   5095  1.1  mrg   for (n = dimen - 1; n > 0; n--)
   5096  1.1  mrg     {
   5097  1.1  mrg       tree tmp_str;
   5098  1.1  mrg       tmp = rse.loop->loopvar[n];
   5099  1.1  mrg       tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
   5100  1.1  mrg 			     tmp, rse.loop->from[n]);
   5101  1.1  mrg       tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
   5102  1.1  mrg 			     tmp, tmp_index);
   5103  1.1  mrg 
   5104  1.1  mrg       tmp_str = fold_build2_loc (input_location, MINUS_EXPR,
   5105  1.1  mrg 				 gfc_array_index_type,
   5106  1.1  mrg 				 rse.loop->to[n-1], rse.loop->from[n-1]);
   5107  1.1  mrg       tmp_str = fold_build2_loc (input_location, PLUS_EXPR,
   5108  1.1  mrg 				 gfc_array_index_type,
   5109  1.1  mrg 				 tmp_str, gfc_index_one_node);
   5110  1.1  mrg 
   5111  1.1  mrg       tmp_index = fold_build2_loc (input_location, MULT_EXPR,
   5112  1.1  mrg 				   gfc_array_index_type, tmp, tmp_str);
   5113  1.1  mrg     }
   5114  1.1  mrg 
   5115  1.1  mrg   tmp_index = fold_build2_loc (input_location, MINUS_EXPR,
   5116  1.1  mrg 			       gfc_array_index_type,
   5117  1.1  mrg 			       tmp_index, rse.loop->from[0]);
   5118  1.1  mrg   gfc_add_modify (&rse.loop->code[0], offset, tmp_index);
   5119  1.1  mrg 
   5120  1.1  mrg   tmp_index = fold_build2_loc (input_location, PLUS_EXPR,
   5121  1.1  mrg 			       gfc_array_index_type,
   5122  1.1  mrg 			       rse.loop->loopvar[0], offset);
   5123  1.1  mrg 
   5124  1.1  mrg   /* Now use the offset for the reference.  */
   5125  1.1  mrg   tmp = build_fold_indirect_ref_loc (input_location,
   5126  1.1  mrg 				 info->data);
   5127  1.1  mrg   rse.expr = gfc_build_array_ref (tmp, tmp_index, NULL);
   5128  1.1  mrg 
   5129  1.1  mrg   if (expr->ts.type == BT_CHARACTER)
   5130  1.1  mrg     rse.string_length = expr->ts.u.cl->backend_decl;
   5131  1.1  mrg 
   5132  1.1  mrg   gfc_conv_expr (&lse, expr);
   5133  1.1  mrg 
   5134  1.1  mrg   gcc_assert (lse.ss == gfc_ss_terminator);
   5135  1.1  mrg 
   5136  1.1  mrg   tmp = gfc_trans_scalar_assign (&lse, &rse, expr->ts, false, true);
   5137  1.1  mrg   gfc_add_expr_to_block (&body, tmp);
   5138  1.1  mrg 
   5139  1.1  mrg   /* Generate the copying loops.  */
   5140  1.1  mrg   gfc_trans_scalarizing_loops (&loop2, &body);
   5141  1.1  mrg 
   5142  1.1  mrg   /* Wrap the whole thing up by adding the second loop to the post-block
   5143  1.1  mrg      and following it by the post-block of the first loop.  In this way,
   5144  1.1  mrg      if the temporary needs freeing, it is done after use!  */
   5145  1.1  mrg   if (intent != INTENT_IN)
   5146  1.1  mrg     {
   5147  1.1  mrg       gfc_add_block_to_block (&parmse->post, &loop2.pre);
   5148  1.1  mrg       gfc_add_block_to_block (&parmse->post, &loop2.post);
   5149  1.1  mrg     }
   5150  1.1  mrg 
   5151  1.1  mrg class_array_fcn:
   5152  1.1  mrg 
   5153  1.1  mrg   gfc_add_block_to_block (&parmse->post, &loop.post);
   5154  1.1  mrg 
   5155  1.1  mrg   gfc_cleanup_loop (&loop);
   5156  1.1  mrg   gfc_cleanup_loop (&loop2);
   5157  1.1  mrg 
   5158  1.1  mrg   /* Pass the string length to the argument expression.  */
   5159  1.1  mrg   if (expr->ts.type == BT_CHARACTER)
   5160  1.1  mrg     parmse->string_length = expr->ts.u.cl->backend_decl;
   5161  1.1  mrg 
   5162  1.1  mrg   /* Determine the offset for pointer formal arguments and set the
   5163  1.1  mrg      lbounds to one.  */
   5164  1.1  mrg   if (formal_ptr)
   5165  1.1  mrg     {
   5166  1.1  mrg       size = gfc_index_one_node;
   5167  1.1  mrg       offset = gfc_index_zero_node;
   5168  1.1  mrg       for (n = 0; n < dimen; n++)
   5169  1.1  mrg 	{
   5170  1.1  mrg 	  tmp = gfc_conv_descriptor_ubound_get (parmse->expr,
   5171  1.1  mrg 						gfc_rank_cst[n]);
   5172  1.1  mrg 	  tmp = fold_build2_loc (input_location, PLUS_EXPR,
   5173  1.1  mrg 				 gfc_array_index_type, tmp,
   5174  1.1  mrg 				 gfc_index_one_node);
   5175  1.1  mrg 	  gfc_conv_descriptor_ubound_set (&parmse->pre,
   5176  1.1  mrg 					  parmse->expr,
   5177  1.1  mrg 					  gfc_rank_cst[n],
   5178  1.1  mrg 					  tmp);
   5179  1.1  mrg 	  gfc_conv_descriptor_lbound_set (&parmse->pre,
   5180  1.1  mrg 					  parmse->expr,
   5181  1.1  mrg 					  gfc_rank_cst[n],
   5182  1.1  mrg 					  gfc_index_one_node);
   5183  1.1  mrg 	  size = gfc_evaluate_now (size, &parmse->pre);
   5184  1.1  mrg 	  offset = fold_build2_loc (input_location, MINUS_EXPR,
   5185  1.1  mrg 				    gfc_array_index_type,
   5186  1.1  mrg 				    offset, size);
   5187  1.1  mrg 	  offset = gfc_evaluate_now (offset, &parmse->pre);
   5188  1.1  mrg 	  tmp = fold_build2_loc (input_location, MINUS_EXPR,
   5189  1.1  mrg 				 gfc_array_index_type,
   5190  1.1  mrg 				 rse.loop->to[n], rse.loop->from[n]);
   5191  1.1  mrg 	  tmp = fold_build2_loc (input_location, PLUS_EXPR,
   5192  1.1  mrg 				 gfc_array_index_type,
   5193  1.1  mrg 				 tmp, gfc_index_one_node);
   5194  1.1  mrg 	  size = fold_build2_loc (input_location, MULT_EXPR,
   5195  1.1  mrg 				  gfc_array_index_type, size, tmp);
   5196  1.1  mrg 	}
   5197  1.1  mrg 
   5198  1.1  mrg       gfc_conv_descriptor_offset_set (&parmse->pre, parmse->expr,
   5199  1.1  mrg 				      offset);
   5200  1.1  mrg     }
   5201  1.1  mrg 
   5202  1.1  mrg   /* We want either the address for the data or the address of the descriptor,
   5203  1.1  mrg      depending on the mode of passing array arguments.  */
   5204  1.1  mrg   if (g77)
   5205  1.1  mrg     parmse->expr = gfc_conv_descriptor_data_get (parmse->expr);
   5206  1.1  mrg   else
   5207  1.1  mrg     parmse->expr = gfc_build_addr_expr (NULL_TREE, parmse->expr);
   5208  1.1  mrg 
   5209  1.1  mrg   /* Basically make this into
   5210  1.1  mrg 
   5211  1.1  mrg      if (present)
   5212  1.1  mrg        {
   5213  1.1  mrg 	 if (contiguous)
   5214  1.1  mrg 	   {
   5215  1.1  mrg 	     pointer = a;
   5216  1.1  mrg 	   }
   5217  1.1  mrg 	 else
   5218  1.1  mrg 	   {
   5219  1.1  mrg 	     parmse->pre();
   5220  1.1  mrg 	     pointer = parmse->expr;
   5221  1.1  mrg 	   }
   5222  1.1  mrg        }
   5223  1.1  mrg      else
   5224  1.1  mrg        pointer = NULL;
   5225  1.1  mrg 
   5226  1.1  mrg      foo (pointer);
   5227  1.1  mrg      if (present && !contiguous)
   5228  1.1  mrg 	   se->post();
   5229  1.1  mrg 
   5230  1.1  mrg      */
   5231  1.1  mrg 
   5232  1.1  mrg   if (pass_optional || check_contiguous)
   5233  1.1  mrg     {
   5234  1.1  mrg       tree type;
   5235  1.1  mrg       stmtblock_t else_block;
   5236  1.1  mrg       tree pre_stmts, post_stmts;
   5237  1.1  mrg       tree pointer;
   5238  1.1  mrg       tree else_stmt;
   5239  1.1  mrg       tree present_var = NULL_TREE;
   5240  1.1  mrg       tree cont_var = NULL_TREE;
   5241  1.1  mrg       tree post_cond;
   5242  1.1  mrg 
   5243  1.1  mrg       type = TREE_TYPE (parmse->expr);
   5244  1.1  mrg       if (POINTER_TYPE_P (type) && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (type)))
   5245  1.1  mrg 	type = TREE_TYPE (type);
   5246  1.1  mrg       pointer = gfc_create_var (type, "arg_ptr");
   5247  1.1  mrg 
   5248  1.1  mrg       if (check_contiguous)
   5249  1.1  mrg 	{
   5250  1.1  mrg 	  gfc_se cont_se, array_se;
   5251  1.1  mrg 	  stmtblock_t if_block, else_block;
   5252  1.1  mrg 	  tree if_stmt, else_stmt;
   5253  1.1  mrg 	  mpz_t size;
   5254  1.1  mrg 	  bool size_set;
   5255  1.1  mrg 
   5256  1.1  mrg 	  cont_var = gfc_create_var (boolean_type_node, "contiguous");
   5257  1.1  mrg 
   5258  1.1  mrg 	  /* If the size is known to be one at compile-time, set
   5259  1.1  mrg 	     cont_var to true unconditionally.  This may look
   5260  1.1  mrg 	     inelegant, but we're only doing this during
   5261  1.1  mrg 	     optimization, so the statements will be optimized away,
   5262  1.1  mrg 	     and this saves complexity here.  */
   5263  1.1  mrg 
   5264  1.1  mrg 	  size_set = gfc_array_size (expr, &size);
   5265  1.1  mrg 	  if (size_set && mpz_cmp_ui (size, 1) == 0)
   5266  1.1  mrg 	    {
   5267  1.1  mrg 	      gfc_add_modify (&se->pre, cont_var,
   5268  1.1  mrg 			      build_one_cst (boolean_type_node));
   5269  1.1  mrg 	    }
   5270  1.1  mrg 	  else
   5271  1.1  mrg 	    {
   5272  1.1  mrg 	      /* cont_var = is_contiguous (expr); .  */
   5273  1.1  mrg 	      gfc_init_se (&cont_se, parmse);
   5274  1.1  mrg 	      gfc_conv_is_contiguous_expr (&cont_se, expr);
   5275  1.1  mrg 	      gfc_add_block_to_block (&se->pre, &(&cont_se)->pre);
   5276  1.1  mrg 	      gfc_add_modify (&se->pre, cont_var, cont_se.expr);
   5277  1.1  mrg 	      gfc_add_block_to_block (&se->pre, &(&cont_se)->post);
   5278  1.1  mrg 	    }
   5279  1.1  mrg 
   5280  1.1  mrg 	  if (size_set)
   5281  1.1  mrg 	    mpz_clear (size);
   5282  1.1  mrg 
   5283  1.1  mrg 	  /* arrayse->expr = descriptor of a.  */
   5284  1.1  mrg 	  gfc_init_se (&array_se, se);
   5285  1.1  mrg 	  gfc_conv_expr_descriptor (&array_se, expr);
   5286  1.1  mrg 	  gfc_add_block_to_block (&se->pre, &(&array_se)->pre);
   5287  1.1  mrg 	  gfc_add_block_to_block (&se->pre, &(&array_se)->post);
   5288  1.1  mrg 
   5289  1.1  mrg 	  /* if_stmt = { descriptor ? pointer = a : pointer = &a[0]; } .  */
   5290  1.1  mrg 	  gfc_init_block (&if_block);
   5291  1.1  mrg 	  if (GFC_DESCRIPTOR_TYPE_P (type))
   5292  1.1  mrg 	    gfc_add_modify (&if_block, pointer, array_se.expr);
   5293  1.1  mrg 	  else
   5294  1.1  mrg 	    {
   5295  1.1  mrg 	      tmp = gfc_conv_array_data (array_se.expr);
   5296  1.1  mrg 	      tmp = fold_convert (type, tmp);
   5297  1.1  mrg 	      gfc_add_modify (&if_block, pointer, tmp);
   5298  1.1  mrg 	    }
   5299  1.1  mrg 	  if_stmt = gfc_finish_block (&if_block);
   5300  1.1  mrg 
   5301  1.1  mrg 	  /* else_stmt = { parmse->pre(); pointer = parmse->expr; } .  */
   5302  1.1  mrg 	  gfc_init_block (&else_block);
   5303  1.1  mrg 	  gfc_add_block_to_block (&else_block, &parmse->pre);
   5304  1.1  mrg 	  tmp = (GFC_DESCRIPTOR_TYPE_P (type)
   5305  1.1  mrg 		 ? build_fold_indirect_ref_loc (input_location, parmse->expr)
   5306  1.1  mrg 		 : parmse->expr);
   5307  1.1  mrg 	  gfc_add_modify (&else_block, pointer, tmp);
   5308  1.1  mrg 	  else_stmt = gfc_finish_block (&else_block);
   5309  1.1  mrg 
   5310  1.1  mrg 	  /* And put the above into an if statement.  */
   5311  1.1  mrg 	  pre_stmts = fold_build3_loc (input_location, COND_EXPR, void_type_node,
   5312  1.1  mrg 				       gfc_likely (cont_var,
   5313  1.1  mrg 						   PRED_FORTRAN_CONTIGUOUS),
   5314  1.1  mrg 				       if_stmt, else_stmt);
   5315  1.1  mrg 	}
   5316  1.1  mrg       else
   5317  1.1  mrg 	{
   5318  1.1  mrg 	  /* pointer = pramse->expr;  .  */
   5319  1.1  mrg 	  gfc_add_modify (&parmse->pre, pointer, parmse->expr);
   5320  1.1  mrg 	  pre_stmts = gfc_finish_block (&parmse->pre);
   5321  1.1  mrg 	}
   5322  1.1  mrg 
   5323  1.1  mrg       if (pass_optional)
   5324  1.1  mrg 	{
   5325  1.1  mrg 	  present_var = gfc_create_var (boolean_type_node, "present");
   5326  1.1  mrg 
   5327  1.1  mrg 	  /* present_var = present(sym); .  */
   5328  1.1  mrg 	  tmp = gfc_conv_expr_present (sym);
   5329  1.1  mrg 	  tmp = fold_convert (boolean_type_node, tmp);
   5330  1.1  mrg 	  gfc_add_modify (&se->pre, present_var, tmp);
   5331  1.1  mrg 
   5332  1.1  mrg 	  /* else_stmt = { pointer = NULL; } .  */
   5333  1.1  mrg 	  gfc_init_block (&else_block);
   5334  1.1  mrg 	  if (GFC_DESCRIPTOR_TYPE_P (type))
   5335  1.1  mrg 	    gfc_conv_descriptor_data_set (&else_block, pointer,
   5336  1.1  mrg 					  null_pointer_node);
   5337  1.1  mrg 	  else
   5338  1.1  mrg 	    gfc_add_modify (&else_block, pointer, build_int_cst (type, 0));
   5339  1.1  mrg 	  else_stmt = gfc_finish_block (&else_block);
   5340  1.1  mrg 
   5341  1.1  mrg 	  tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
   5342  1.1  mrg 				 gfc_likely (present_var,
   5343  1.1  mrg 					     PRED_FORTRAN_ABSENT_DUMMY),
   5344  1.1  mrg 				 pre_stmts, else_stmt);
   5345  1.1  mrg 	  gfc_add_expr_to_block (&se->pre, tmp);
   5346  1.1  mrg 	}
   5347  1.1  mrg       else
   5348  1.1  mrg 	gfc_add_expr_to_block (&se->pre, pre_stmts);
   5349  1.1  mrg 
   5350  1.1  mrg       post_stmts = gfc_finish_block (&parmse->post);
   5351  1.1  mrg 
   5352  1.1  mrg       /* Put together the post stuff, plus the optional
   5353  1.1  mrg 	 deallocation.  */
   5354  1.1  mrg       if (check_contiguous)
   5355  1.1  mrg 	{
   5356  1.1  mrg 	  /* !cont_var.  */
   5357  1.1  mrg 	  tmp = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
   5358  1.1  mrg 				 cont_var,
   5359  1.1  mrg 				 build_zero_cst (boolean_type_node));
   5360  1.1  mrg 	  tmp = gfc_unlikely (tmp, PRED_FORTRAN_CONTIGUOUS);
   5361  1.1  mrg 
   5362  1.1  mrg 	  if (pass_optional)
   5363  1.1  mrg 	    {
   5364  1.1  mrg 	      tree present_likely = gfc_likely (present_var,
   5365  1.1  mrg 						PRED_FORTRAN_ABSENT_DUMMY);
   5366  1.1  mrg 	      post_cond = fold_build2_loc (input_location, TRUTH_ANDIF_EXPR,
   5367  1.1  mrg 					   boolean_type_node, present_likely,
   5368  1.1  mrg 					   tmp);
   5369  1.1  mrg 	    }
   5370  1.1  mrg 	  else
   5371  1.1  mrg 	    post_cond = tmp;
   5372  1.1  mrg 	}
   5373  1.1  mrg       else
   5374  1.1  mrg 	{
   5375  1.1  mrg 	  gcc_assert (pass_optional);
   5376  1.1  mrg 	  post_cond = present_var;
   5377  1.1  mrg 	}
   5378  1.1  mrg 
   5379  1.1  mrg       tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, post_cond,
   5380  1.1  mrg 			     post_stmts, build_empty_stmt (input_location));
   5381  1.1  mrg       gfc_add_expr_to_block (&se->post, tmp);
   5382  1.1  mrg       if (GFC_DESCRIPTOR_TYPE_P (type))
   5383  1.1  mrg 	{
   5384  1.1  mrg 	  type = TREE_TYPE (parmse->expr);
   5385  1.1  mrg 	  if (POINTER_TYPE_P (type))
   5386  1.1  mrg 	    {
   5387  1.1  mrg 	      pointer = gfc_build_addr_expr (type, pointer);
   5388  1.1  mrg 	      if (pass_optional)
   5389  1.1  mrg 		{
   5390  1.1  mrg 		  tmp = gfc_likely (present_var, PRED_FORTRAN_ABSENT_DUMMY);
   5391  1.1  mrg 		  pointer = fold_build3_loc (input_location, COND_EXPR, type,
   5392  1.1  mrg 					     tmp, pointer,
   5393  1.1  mrg 					     fold_convert (type,
   5394  1.1  mrg 							   null_pointer_node));
   5395  1.1  mrg 		}
   5396  1.1  mrg 	    }
   5397  1.1  mrg 	  else
   5398  1.1  mrg 	    gcc_assert (!pass_optional);
   5399  1.1  mrg 	}
   5400  1.1  mrg       se->expr = pointer;
   5401  1.1  mrg     }
   5402  1.1  mrg 
   5403  1.1  mrg   return;
   5404  1.1  mrg }
   5405  1.1  mrg 
   5406  1.1  mrg 
   5407  1.1  mrg /* Generate the code for argument list functions.  */
   5408  1.1  mrg 
   5409  1.1  mrg static void
   5410  1.1  mrg conv_arglist_function (gfc_se *se, gfc_expr *expr, const char *name)
   5411  1.1  mrg {
   5412  1.1  mrg   /* Pass by value for g77 %VAL(arg), pass the address
   5413  1.1  mrg      indirectly for %LOC, else by reference.  Thus %REF
   5414  1.1  mrg      is a "do-nothing" and %LOC is the same as an F95
   5415  1.1  mrg      pointer.  */
   5416  1.1  mrg   if (strcmp (name, "%VAL") == 0)
   5417  1.1  mrg     gfc_conv_expr (se, expr);
   5418  1.1  mrg   else if (strcmp (name, "%LOC") == 0)
   5419  1.1  mrg     {
   5420  1.1  mrg       gfc_conv_expr_reference (se, expr);
   5421  1.1  mrg       se->expr = gfc_build_addr_expr (NULL, se->expr);
   5422  1.1  mrg     }
   5423  1.1  mrg   else if (strcmp (name, "%REF") == 0)
   5424  1.1  mrg     gfc_conv_expr_reference (se, expr);
   5425  1.1  mrg   else
   5426  1.1  mrg     gfc_error ("Unknown argument list function at %L", &expr->where);
   5427  1.1  mrg }
   5428  1.1  mrg 
   5429  1.1  mrg 
   5430  1.1  mrg /* This function tells whether the middle-end representation of the expression
   5431  1.1  mrg    E given as input may point to data otherwise accessible through a variable
   5432  1.1  mrg    (sub-)reference.
   5433  1.1  mrg    It is assumed that the only expressions that may alias are variables,
   5434  1.1  mrg    and array constructors if ARRAY_MAY_ALIAS is true and some of its elements
   5435  1.1  mrg    may alias.
   5436  1.1  mrg    This function is used to decide whether freeing an expression's allocatable
   5437  1.1  mrg    components is safe or should be avoided.
   5438  1.1  mrg 
   5439  1.1  mrg    If ARRAY_MAY_ALIAS is true, an array constructor may alias if some of
   5440  1.1  mrg    its elements are copied from a variable.  This ARRAY_MAY_ALIAS trick
   5441  1.1  mrg    is necessary because for array constructors, aliasing depends on how
   5442  1.1  mrg    the array is used:
   5443  1.1  mrg     - If E is an array constructor used as argument to an elemental procedure,
   5444  1.1  mrg       the array, which is generated through shallow copy by the scalarizer,
   5445  1.1  mrg       is used directly and can alias the expressions it was copied from.
   5446  1.1  mrg     - If E is an array constructor used as argument to a non-elemental
   5447  1.1  mrg       procedure,the scalarizer is used in gfc_conv_expr_descriptor to generate
   5448  1.1  mrg       the array as in the previous case, but then that array is used
   5449  1.1  mrg       to initialize a new descriptor through deep copy.  There is no alias
   5450  1.1  mrg       possible in that case.
   5451  1.1  mrg    Thus, the ARRAY_MAY_ALIAS flag is necessary to distinguish the two cases
   5452  1.1  mrg    above.  */
   5453  1.1  mrg 
   5454  1.1  mrg static bool
   5455  1.1  mrg expr_may_alias_variables (gfc_expr *e, bool array_may_alias)
   5456  1.1  mrg {
   5457  1.1  mrg   gfc_constructor *c;
   5458  1.1  mrg 
   5459  1.1  mrg   if (e->expr_type == EXPR_VARIABLE)
   5460  1.1  mrg     return true;
   5461  1.1  mrg   else if (e->expr_type == EXPR_FUNCTION)
   5462  1.1  mrg     {
   5463  1.1  mrg       gfc_symbol *proc_ifc = gfc_get_proc_ifc_for_expr (e);
   5464  1.1  mrg 
   5465  1.1  mrg       if (proc_ifc->result != NULL
   5466  1.1  mrg 	  && ((proc_ifc->result->ts.type == BT_CLASS
   5467  1.1  mrg 	       && proc_ifc->result->ts.u.derived->attr.is_class
   5468  1.1  mrg 	       && CLASS_DATA (proc_ifc->result)->attr.class_pointer)
   5469  1.1  mrg 	      || proc_ifc->result->attr.pointer))
   5470  1.1  mrg 	return true;
   5471  1.1  mrg       else
   5472  1.1  mrg 	return false;
   5473  1.1  mrg     }
   5474  1.1  mrg   else if (e->expr_type != EXPR_ARRAY || !array_may_alias)
   5475  1.1  mrg     return false;
   5476  1.1  mrg 
   5477  1.1  mrg   for (c = gfc_constructor_first (e->value.constructor);
   5478  1.1  mrg        c; c = gfc_constructor_next (c))
   5479  1.1  mrg     if (c->expr
   5480  1.1  mrg 	&& expr_may_alias_variables (c->expr, array_may_alias))
   5481  1.1  mrg       return true;
   5482  1.1  mrg 
   5483  1.1  mrg   return false;
   5484  1.1  mrg }
   5485  1.1  mrg 
   5486  1.1  mrg 
   5487  1.1  mrg /* A helper function to set the dtype for unallocated or unassociated
   5488  1.1  mrg    entities.  */
   5489  1.1  mrg 
   5490  1.1  mrg static void
   5491  1.1  mrg set_dtype_for_unallocated (gfc_se *parmse, gfc_expr *e)
   5492  1.1  mrg {
   5493  1.1  mrg   tree tmp;
   5494  1.1  mrg   tree desc;
   5495  1.1  mrg   tree cond;
   5496  1.1  mrg   tree type;
   5497  1.1  mrg   stmtblock_t block;
   5498  1.1  mrg 
   5499  1.1  mrg   /* TODO Figure out how to handle optional dummies.  */
   5500  1.1  mrg   if (e && e->expr_type == EXPR_VARIABLE
   5501  1.1  mrg       && e->symtree->n.sym->attr.optional)
   5502  1.1  mrg     return;
   5503  1.1  mrg 
   5504  1.1  mrg   desc = parmse->expr;
   5505  1.1  mrg   if (desc == NULL_TREE)
   5506  1.1  mrg     return;
   5507  1.1  mrg 
   5508  1.1  mrg   if (POINTER_TYPE_P (TREE_TYPE (desc)))
   5509  1.1  mrg     desc = build_fold_indirect_ref_loc (input_location, desc);
   5510  1.1  mrg   if (GFC_CLASS_TYPE_P (TREE_TYPE (desc)))
   5511  1.1  mrg     desc = gfc_class_data_get (desc);
   5512  1.1  mrg   if (!GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (desc)))
   5513  1.1  mrg     return;
   5514  1.1  mrg 
   5515  1.1  mrg   gfc_init_block (&block);
   5516  1.1  mrg   tmp = gfc_conv_descriptor_data_get (desc);
   5517  1.1  mrg   cond = fold_build2_loc (input_location, EQ_EXPR,
   5518  1.1  mrg 			  logical_type_node, tmp,
   5519  1.1  mrg 			  build_int_cst (TREE_TYPE (tmp), 0));
   5520  1.1  mrg   tmp = gfc_conv_descriptor_dtype (desc);
   5521  1.1  mrg   type = gfc_get_element_type (TREE_TYPE (desc));
   5522  1.1  mrg   tmp = fold_build2_loc (input_location, MODIFY_EXPR,
   5523  1.1  mrg 			 TREE_TYPE (tmp), tmp,
   5524  1.1  mrg 			 gfc_get_dtype_rank_type (e->rank, type));
   5525  1.1  mrg   gfc_add_expr_to_block (&block, tmp);
   5526  1.1  mrg   cond = build3_v (COND_EXPR, cond,
   5527  1.1  mrg 		   gfc_finish_block (&block),
   5528  1.1  mrg 		   build_empty_stmt (input_location));
   5529  1.1  mrg   gfc_add_expr_to_block (&parmse->pre, cond);
   5530  1.1  mrg }
   5531  1.1  mrg 
   5532  1.1  mrg 
   5533  1.1  mrg 
   5534  1.1  mrg /* Provide an interface between gfortran array descriptors and the F2018:18.4
   5535  1.1  mrg    ISO_Fortran_binding array descriptors. */
   5536  1.1  mrg 
   5537  1.1  mrg static void
   5538  1.1  mrg gfc_conv_gfc_desc_to_cfi_desc (gfc_se *parmse, gfc_expr *e, gfc_symbol *fsym)
   5539  1.1  mrg {
   5540  1.1  mrg   stmtblock_t block, block2;
   5541  1.1  mrg   tree cfi, gfc, tmp, tmp2;
   5542  1.1  mrg   tree present = NULL;
   5543  1.1  mrg   tree gfc_strlen = NULL;
   5544  1.1  mrg   tree rank;
   5545  1.1  mrg   gfc_se se;
   5546  1.1  mrg 
   5547  1.1  mrg   if (fsym->attr.optional
   5548  1.1  mrg       && e->expr_type == EXPR_VARIABLE
   5549  1.1  mrg       && e->symtree->n.sym->attr.optional)
   5550  1.1  mrg     present = gfc_conv_expr_present (e->symtree->n.sym);
   5551  1.1  mrg 
   5552  1.1  mrg   gfc_init_block (&block);
   5553  1.1  mrg 
   5554  1.1  mrg   /* Convert original argument to a tree. */
   5555  1.1  mrg   gfc_init_se (&se, NULL);
   5556  1.1  mrg   if (e->rank == 0)
   5557  1.1  mrg     {
   5558  1.1  mrg       se.want_pointer = 1;
   5559  1.1  mrg       gfc_conv_expr (&se, e);
   5560  1.1  mrg       gfc = se.expr;
   5561  1.1  mrg       /* gfc_conv_constant ignores se.want_poiner, e.g. for string_cst.  */
   5562  1.1  mrg       if (!POINTER_TYPE_P (TREE_TYPE (gfc)))
   5563  1.1  mrg 	gfc = gfc_build_addr_expr (NULL, gfc);
   5564  1.1  mrg     }
   5565  1.1  mrg   else
   5566  1.1  mrg     {
   5567  1.1  mrg       /* If the actual argument can be noncontiguous, copy-in/out is required,
   5568  1.1  mrg 	 if the dummy has either the CONTIGUOUS attribute or is an assumed-
   5569  1.1  mrg 	 length assumed-length/assumed-size CHARACTER array.  This only
   5570  1.1  mrg 	 applies if the actual argument is a "variable"; if it's some
   5571  1.1  mrg 	 non-lvalue expression, we are going to evaluate it to a
   5572  1.1  mrg 	 temporary below anyway.  */
   5573  1.1  mrg       se.force_no_tmp = 1;
   5574  1.1  mrg       if ((fsym->attr.contiguous
   5575  1.1  mrg 	   || (fsym->ts.type == BT_CHARACTER && !fsym->ts.u.cl->length
   5576  1.1  mrg 	       && (fsym->as->type == AS_ASSUMED_SIZE
   5577  1.1  mrg 		   || fsym->as->type == AS_EXPLICIT)))
   5578  1.1  mrg 	  && !gfc_is_simply_contiguous (e, false, true)
   5579  1.1  mrg 	  && gfc_expr_is_variable (e))
   5580  1.1  mrg 	{
   5581  1.1  mrg 	  bool optional = fsym->attr.optional;
   5582  1.1  mrg 	  fsym->attr.optional = 0;
   5583  1.1  mrg 	  gfc_conv_subref_array_arg (&se, e, false, fsym->attr.intent,
   5584  1.1  mrg 				     fsym->attr.pointer, fsym,
   5585  1.1  mrg 				     fsym->ns->proc_name->name, NULL,
   5586  1.1  mrg 				     /* check_contiguous= */ true);
   5587  1.1  mrg 	  fsym->attr.optional = optional;
   5588  1.1  mrg 	}
   5589  1.1  mrg       else
   5590  1.1  mrg 	gfc_conv_expr_descriptor (&se, e);
   5591  1.1  mrg       gfc = se.expr;
   5592  1.1  mrg       /* For dt(:)%var the elem_len*stride != sm, hence, GFC uses
   5593  1.1  mrg 	 elem_len = sizeof(dt) and base_addr = dt(lb) instead.
   5594  1.1  mrg 	 gfc_get_dataptr_offset fixes the base_addr; for elem_len, see below.
   5595  1.1  mrg 	 While sm is fine as it uses span*stride and not elem_len.  */
   5596  1.1  mrg       if (POINTER_TYPE_P (TREE_TYPE (gfc)))
   5597  1.1  mrg 	gfc = build_fold_indirect_ref_loc (input_location, gfc);
   5598  1.1  mrg       else if (is_subref_array (e) && e->ts.type != BT_CHARACTER)
   5599  1.1  mrg 	 gfc_get_dataptr_offset (&se.pre, gfc, gfc, NULL, true, e);
   5600  1.1  mrg     }
   5601  1.1  mrg   if (e->ts.type == BT_CHARACTER)
   5602  1.1  mrg     {
   5603  1.1  mrg       if (se.string_length)
   5604  1.1  mrg 	gfc_strlen = se.string_length;
   5605  1.1  mrg       else if (e->ts.u.cl->backend_decl)
   5606  1.1  mrg 	gfc_strlen = e->ts.u.cl->backend_decl;
   5607  1.1  mrg       else
   5608  1.1  mrg 	gcc_unreachable ();
   5609  1.1  mrg     }
   5610  1.1  mrg   gfc_add_block_to_block (&block, &se.pre);
   5611  1.1  mrg 
   5612  1.1  mrg   /* Create array decriptor and set version, rank, attribute, type. */
   5613  1.1  mrg   cfi = gfc_create_var (gfc_get_cfi_type (e->rank < 0
   5614  1.1  mrg 					  ? GFC_MAX_DIMENSIONS : e->rank,
   5615  1.1  mrg 					  false), "cfi");
   5616  1.1  mrg   /* Convert to CFI_cdesc_t, which has dim[] to avoid TBAA issues,*/
   5617  1.1  mrg   if (fsym->attr.dimension && fsym->as->type == AS_ASSUMED_RANK)
   5618  1.1  mrg     {
   5619  1.1  mrg       tmp = gfc_get_cfi_type (-1, !fsym->attr.pointer && !fsym->attr.target);
   5620  1.1  mrg       tmp = build_pointer_type (tmp);
   5621  1.1  mrg       parmse->expr = cfi = gfc_build_addr_expr (tmp, cfi);
   5622  1.1  mrg       cfi = build_fold_indirect_ref_loc (input_location, cfi);
   5623  1.1  mrg     }
   5624  1.1  mrg   else
   5625  1.1  mrg     parmse->expr = gfc_build_addr_expr (NULL, cfi);
   5626  1.1  mrg 
   5627  1.1  mrg   tmp = gfc_get_cfi_desc_version (cfi);
   5628  1.1  mrg   gfc_add_modify (&block, tmp,
   5629  1.1  mrg 		  build_int_cst (TREE_TYPE (tmp), CFI_VERSION));
   5630  1.1  mrg   if (e->rank < 0)
   5631  1.1  mrg     rank = fold_convert (signed_char_type_node, gfc_conv_descriptor_rank (gfc));
   5632  1.1  mrg   else
   5633  1.1  mrg     rank = build_int_cst (signed_char_type_node, e->rank);
   5634  1.1  mrg   tmp = gfc_get_cfi_desc_rank (cfi);
   5635  1.1  mrg   gfc_add_modify (&block, tmp, rank);
   5636  1.1  mrg   int itype = CFI_type_other;
   5637  1.1  mrg   if (e->ts.f90_type == BT_VOID)
   5638  1.1  mrg     itype = (e->ts.u.derived->intmod_sym_id == ISOCBINDING_FUNPTR
   5639  1.1  mrg 	     ? CFI_type_cfunptr : CFI_type_cptr);
   5640  1.1  mrg   else
   5641  1.1  mrg     {
   5642  1.1  mrg       if (e->expr_type == EXPR_NULL && e->ts.type == BT_UNKNOWN)
   5643  1.1  mrg 	e->ts = fsym->ts;
   5644  1.1  mrg       switch (e->ts.type)
   5645  1.1  mrg 	{
   5646  1.1  mrg 	case BT_INTEGER:
   5647  1.1  mrg 	case BT_LOGICAL:
   5648  1.1  mrg 	case BT_REAL:
   5649  1.1  mrg 	case BT_COMPLEX:
   5650  1.1  mrg 	  itype = CFI_type_from_type_kind (e->ts.type, e->ts.kind);
   5651  1.1  mrg 	  break;
   5652  1.1  mrg 	case BT_CHARACTER:
   5653  1.1  mrg 	  itype = CFI_type_from_type_kind (CFI_type_Character, e->ts.kind);
   5654  1.1  mrg 	  break;
   5655  1.1  mrg 	case BT_DERIVED:
   5656  1.1  mrg 	  itype = CFI_type_struct;
   5657  1.1  mrg 	  break;
   5658  1.1  mrg 	case BT_VOID:
   5659  1.1  mrg 	  itype = (e->ts.u.derived->intmod_sym_id == ISOCBINDING_FUNPTR
   5660  1.1  mrg 		   ? CFI_type_cfunptr : CFI_type_cptr);
   5661  1.1  mrg 	  break;
   5662  1.1  mrg 	case BT_ASSUMED:
   5663  1.1  mrg 	  itype = CFI_type_other;  // FIXME: Or CFI_type_cptr ?
   5664  1.1  mrg 	  break;
   5665  1.1  mrg 	case BT_CLASS:
   5666  1.1  mrg 	  if (UNLIMITED_POLY (e) && fsym->ts.type == BT_ASSUMED)
   5667  1.1  mrg 	    {
   5668  1.1  mrg 	      // F2017: 7.3.2.2: "An entity that is declared using the TYPE(*)
   5669  1.1  mrg 	      // type specifier is assumed-type and is an unlimited polymorphic
   5670  1.1  mrg 	      //  entity." The actual argument _data component is passed.
   5671  1.1  mrg 	      itype = CFI_type_other;  // FIXME: Or CFI_type_cptr ?
   5672  1.1  mrg 	      break;
   5673  1.1  mrg 	    }
   5674  1.1  mrg 	  else
   5675  1.1  mrg 	    gcc_unreachable ();
   5676  1.1  mrg 	case BT_PROCEDURE:
   5677  1.1  mrg 	case BT_HOLLERITH:
   5678  1.1  mrg 	case BT_UNION:
   5679  1.1  mrg 	case BT_BOZ:
   5680  1.1  mrg 	case BT_UNKNOWN:
   5681  1.1  mrg 	  // FIXME: Really unreachable? Or reachable for type(*) ? If so, CFI_type_other?
   5682  1.1  mrg 	  gcc_unreachable ();
   5683  1.1  mrg 	}
   5684  1.1  mrg     }
   5685  1.1  mrg 
   5686  1.1  mrg   tmp = gfc_get_cfi_desc_type (cfi);
   5687  1.1  mrg   gfc_add_modify (&block, tmp,
   5688  1.1  mrg 		  build_int_cst (TREE_TYPE (tmp), itype));
   5689  1.1  mrg 
   5690  1.1  mrg   int attr = CFI_attribute_other;
   5691  1.1  mrg   if (fsym->attr.pointer)
   5692  1.1  mrg     attr = CFI_attribute_pointer;
   5693  1.1  mrg   else if (fsym->attr.allocatable)
   5694  1.1  mrg     attr = CFI_attribute_allocatable;
   5695  1.1  mrg   tmp = gfc_get_cfi_desc_attribute (cfi);
   5696  1.1  mrg   gfc_add_modify (&block, tmp,
   5697  1.1  mrg 		  build_int_cst (TREE_TYPE (tmp), attr));
   5698  1.1  mrg 
   5699  1.1  mrg   if (e->rank == 0)
   5700  1.1  mrg     {
   5701  1.1  mrg       tmp = gfc_get_cfi_desc_base_addr (cfi);
   5702  1.1  mrg       gfc_add_modify (&block, tmp, fold_convert (TREE_TYPE (tmp), gfc));
   5703  1.1  mrg     }
   5704  1.1  mrg   else
   5705  1.1  mrg     {
   5706  1.1  mrg       tmp = gfc_get_cfi_desc_base_addr (cfi);
   5707  1.1  mrg       tmp2 = gfc_conv_descriptor_data_get (gfc);
   5708  1.1  mrg       gfc_add_modify (&block, tmp, fold_convert (TREE_TYPE (tmp), tmp2));
   5709  1.1  mrg     }
   5710  1.1  mrg 
   5711  1.1  mrg   /* Set elem_len if known - must be before the next if block.
   5712  1.1  mrg      Note that allocatable implies 'len=:'.  */
   5713  1.1  mrg   if (e->ts.type != BT_ASSUMED && e->ts.type != BT_CHARACTER )
   5714  1.1  mrg     {
   5715  1.1  mrg       /* Length is known at compile time; use 'block' for it.  */
   5716  1.1  mrg       tmp = size_in_bytes (gfc_typenode_for_spec (&e->ts));
   5717  1.1  mrg       tmp2 = gfc_get_cfi_desc_elem_len (cfi);
   5718  1.1  mrg       gfc_add_modify (&block, tmp2, fold_convert (TREE_TYPE (tmp2), tmp));
   5719  1.1  mrg     }
   5720  1.1  mrg 
   5721  1.1  mrg   /* When allocatable + intent out, free the cfi descriptor.  */
   5722  1.1  mrg   if (fsym->attr.allocatable && fsym->attr.intent == INTENT_OUT)
   5723  1.1  mrg     {
   5724  1.1  mrg       tmp = gfc_get_cfi_desc_base_addr (cfi);
   5725  1.1  mrg       tree call = builtin_decl_explicit (BUILT_IN_FREE);
   5726  1.1  mrg       call = build_call_expr_loc (input_location, call, 1, tmp);
   5727  1.1  mrg       gfc_add_expr_to_block (&block, fold_convert (void_type_node, call));
   5728  1.1  mrg       gfc_add_modify (&block, tmp,
   5729  1.1  mrg 		      fold_convert (TREE_TYPE (tmp), null_pointer_node));
   5730  1.1  mrg       goto done;
   5731  1.1  mrg     }
   5732  1.1  mrg 
   5733  1.1  mrg   /* If not unallocated/unassociated. */
   5734  1.1  mrg   gfc_init_block (&block2);
   5735  1.1  mrg 
   5736  1.1  mrg   /* Set elem_len, which may be only known at run time. */
   5737  1.1  mrg   if (e->ts.type == BT_CHARACTER
   5738  1.1  mrg       && (e->expr_type != EXPR_NULL || gfc_strlen != NULL_TREE))
   5739  1.1  mrg     {
   5740  1.1  mrg       gcc_assert (gfc_strlen);
   5741  1.1  mrg       tmp = gfc_strlen;
   5742  1.1  mrg       if (e->ts.kind != 1)
   5743  1.1  mrg 	tmp = fold_build2_loc (input_location, MULT_EXPR,
   5744  1.1  mrg 			       gfc_charlen_type_node, tmp,
   5745  1.1  mrg 			       build_int_cst (gfc_charlen_type_node,
   5746  1.1  mrg 					      e->ts.kind));
   5747  1.1  mrg       tmp2 = gfc_get_cfi_desc_elem_len (cfi);
   5748  1.1  mrg       gfc_add_modify (&block2, tmp2, fold_convert (TREE_TYPE (tmp2), tmp));
   5749  1.1  mrg     }
   5750  1.1  mrg   else if (e->ts.type == BT_ASSUMED)
   5751  1.1  mrg     {
   5752  1.1  mrg       tmp = gfc_conv_descriptor_elem_len (gfc);
   5753  1.1  mrg       tmp2 = gfc_get_cfi_desc_elem_len (cfi);
   5754  1.1  mrg       gfc_add_modify (&block2, tmp2, fold_convert (TREE_TYPE (tmp2), tmp));
   5755  1.1  mrg     }
   5756  1.1  mrg 
   5757  1.1  mrg   if (e->ts.type == BT_ASSUMED)
   5758  1.1  mrg     {
   5759  1.1  mrg       /* Note: type(*) implies assumed-shape/assumed-rank if fsym requires
   5760  1.1  mrg 	 an CFI descriptor.  Use the type in the descritor as it provide
   5761  1.1  mrg 	 mode information. (Quality of implementation feature.)  */
   5762  1.1  mrg       tree cond;
   5763  1.1  mrg       tree ctype = gfc_get_cfi_desc_type (cfi);
   5764  1.1  mrg       tree type = fold_convert (TREE_TYPE (ctype),
   5765  1.1  mrg 				gfc_conv_descriptor_type (gfc));
   5766  1.1  mrg       tree kind = fold_convert (TREE_TYPE (ctype),
   5767  1.1  mrg 				gfc_conv_descriptor_elem_len (gfc));
   5768  1.1  mrg       kind = fold_build2_loc (input_location, LSHIFT_EXPR, TREE_TYPE (type),
   5769  1.1  mrg 			      kind, build_int_cst (TREE_TYPE (type),
   5770  1.1  mrg 						   CFI_type_kind_shift));
   5771  1.1  mrg 
   5772  1.1  mrg       /* if (BT_VOID) CFI_type_cptr else CFI_type_other  */
   5773  1.1  mrg       /* Note: BT_VOID is could also be CFI_type_funcptr, but assume c_ptr. */
   5774  1.1  mrg       cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, type,
   5775  1.1  mrg 			      build_int_cst (TREE_TYPE (type), BT_VOID));
   5776  1.1  mrg       tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node, ctype,
   5777  1.1  mrg 			     build_int_cst (TREE_TYPE (type), CFI_type_cptr));
   5778  1.1  mrg       tmp2 = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node,
   5779  1.1  mrg 			      ctype,
   5780  1.1  mrg 			      build_int_cst (TREE_TYPE (type), CFI_type_other));
   5781  1.1  mrg       tmp2 = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond,
   5782  1.1  mrg 			      tmp, tmp2);
   5783  1.1  mrg       /* if (BT_DERIVED) CFI_type_struct else  < tmp2 >  */
   5784  1.1  mrg       cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, type,
   5785  1.1  mrg 			      build_int_cst (TREE_TYPE (type), BT_DERIVED));
   5786  1.1  mrg       tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node, ctype,
   5787  1.1  mrg 			     build_int_cst (TREE_TYPE (type), CFI_type_struct));
   5788  1.1  mrg       tmp2 = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond,
   5789  1.1  mrg 			      tmp, tmp2);
   5790  1.1  mrg       /* if (BT_CHARACTER) CFI_type_Character + kind=1 else  < tmp2 >  */
   5791  1.1  mrg       /* Note: could also be kind=4, with cfi->elem_len = gfc->elem_len*4.  */
   5792  1.1  mrg       cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, type,
   5793  1.1  mrg 			      build_int_cst (TREE_TYPE (type), BT_CHARACTER));
   5794  1.1  mrg       tmp = build_int_cst (TREE_TYPE (type),
   5795  1.1  mrg 			   CFI_type_from_type_kind (CFI_type_Character, 1));
   5796  1.1  mrg       tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node,
   5797  1.1  mrg 			     ctype, tmp);
   5798  1.1  mrg       tmp2 = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond,
   5799  1.1  mrg 			      tmp, tmp2);
   5800  1.1  mrg       /* if (BT_COMPLEX) CFI_type_Complex + kind/2 else  < tmp2 >  */
   5801  1.1  mrg       cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, type,
   5802  1.1  mrg 			      build_int_cst (TREE_TYPE (type), BT_COMPLEX));
   5803  1.1  mrg       tmp = fold_build2_loc (input_location, TRUNC_DIV_EXPR, TREE_TYPE (type),
   5804  1.1  mrg 			     kind, build_int_cst (TREE_TYPE (type), 2));
   5805  1.1  mrg       tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (type), tmp,
   5806  1.1  mrg 			     build_int_cst (TREE_TYPE (type),
   5807  1.1  mrg 					    CFI_type_Complex));
   5808  1.1  mrg       tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node,
   5809  1.1  mrg 			     ctype, tmp);
   5810  1.1  mrg       tmp2 = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond,
   5811  1.1  mrg 			      tmp, tmp2);
   5812  1.1  mrg       /* if (BT_INTEGER || BT_LOGICAL || BT_REAL) type + kind else  <tmp2>  */
   5813  1.1  mrg       cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, type,
   5814  1.1  mrg 			      build_int_cst (TREE_TYPE (type), BT_INTEGER));
   5815  1.1  mrg       tmp = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, type,
   5816  1.1  mrg 			      build_int_cst (TREE_TYPE (type), BT_LOGICAL));
   5817  1.1  mrg       cond = fold_build2_loc (input_location, TRUTH_OR_EXPR, boolean_type_node,
   5818  1.1  mrg 			      cond, tmp);
   5819  1.1  mrg       tmp = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, type,
   5820  1.1  mrg 			      build_int_cst (TREE_TYPE (type), BT_REAL));
   5821  1.1  mrg       cond = fold_build2_loc (input_location, TRUTH_OR_EXPR, boolean_type_node,
   5822  1.1  mrg 			      cond, tmp);
   5823  1.1  mrg       tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (type),
   5824  1.1  mrg 			     type, kind);
   5825  1.1  mrg       tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node,
   5826  1.1  mrg 			     ctype, tmp);
   5827  1.1  mrg       tmp2 = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond,
   5828  1.1  mrg 			      tmp, tmp2);
   5829  1.1  mrg       gfc_add_expr_to_block (&block2, tmp2);
   5830  1.1  mrg     }
   5831  1.1  mrg 
   5832  1.1  mrg   if (e->rank != 0)
   5833  1.1  mrg     {
   5834  1.1  mrg       /* Loop: for (i = 0; i < rank; ++i).  */
   5835  1.1  mrg       tree idx = gfc_create_var (TREE_TYPE (rank), "idx");
   5836  1.1  mrg       /* Loop body.  */
   5837  1.1  mrg       stmtblock_t loop_body;
   5838  1.1  mrg       gfc_init_block (&loop_body);
   5839  1.1  mrg       /* cfi->dim[i].lower_bound = (allocatable/pointer)
   5840  1.1  mrg 				   ? gfc->dim[i].lbound : 0 */
   5841  1.1  mrg       if (fsym->attr.pointer || fsym->attr.allocatable)
   5842  1.1  mrg 	tmp = gfc_conv_descriptor_lbound_get (gfc, idx);
   5843  1.1  mrg       else
   5844  1.1  mrg 	tmp = gfc_index_zero_node;
   5845  1.1  mrg       gfc_add_modify (&loop_body, gfc_get_cfi_dim_lbound (cfi, idx), tmp);
   5846  1.1  mrg       /* cfi->dim[i].extent = gfc->dim[i].ubound - gfc->dim[i].lbound + 1.  */
   5847  1.1  mrg       tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
   5848  1.1  mrg 			     gfc_conv_descriptor_ubound_get (gfc, idx),
   5849  1.1  mrg 			     gfc_conv_descriptor_lbound_get (gfc, idx));
   5850  1.1  mrg       tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
   5851  1.1  mrg 			     tmp, gfc_index_one_node);
   5852  1.1  mrg       gfc_add_modify (&loop_body, gfc_get_cfi_dim_extent (cfi, idx), tmp);
   5853  1.1  mrg       /* d->dim[n].sm = gfc->dim[i].stride  * gfc->span); */
   5854  1.1  mrg       tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
   5855  1.1  mrg 			     gfc_conv_descriptor_stride_get (gfc, idx),
   5856  1.1  mrg 			     gfc_conv_descriptor_span_get (gfc));
   5857  1.1  mrg       gfc_add_modify (&loop_body, gfc_get_cfi_dim_sm (cfi, idx), tmp);
   5858  1.1  mrg 
   5859  1.1  mrg       /* Generate loop.  */
   5860  1.1  mrg       gfc_simple_for_loop (&block2, idx, build_int_cst (TREE_TYPE (idx), 0),
   5861  1.1  mrg 			   rank, LT_EXPR, build_int_cst (TREE_TYPE (idx), 1),
   5862  1.1  mrg 			   gfc_finish_block (&loop_body));
   5863  1.1  mrg 
   5864  1.1  mrg       if (e->expr_type == EXPR_VARIABLE
   5865  1.1  mrg 	  && e->ref
   5866  1.1  mrg 	  && e->ref->u.ar.type == AR_FULL
   5867  1.1  mrg 	  && e->symtree->n.sym->attr.dummy
   5868  1.1  mrg 	  && e->symtree->n.sym->as
   5869  1.1  mrg 	  && e->symtree->n.sym->as->type == AS_ASSUMED_SIZE)
   5870  1.1  mrg 	{
   5871  1.1  mrg 	  tmp = gfc_get_cfi_dim_extent (cfi, gfc_rank_cst[e->rank-1]),
   5872  1.1  mrg 	  gfc_add_modify (&block2, tmp, build_int_cst (TREE_TYPE (tmp), -1));
   5873  1.1  mrg 	}
   5874  1.1  mrg     }
   5875  1.1  mrg 
   5876  1.1  mrg   if (fsym->attr.allocatable || fsym->attr.pointer)
   5877  1.1  mrg     {
   5878  1.1  mrg       tmp = gfc_get_cfi_desc_base_addr (cfi),
   5879  1.1  mrg       tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
   5880  1.1  mrg 			     tmp, null_pointer_node);
   5881  1.1  mrg       tmp = build3_v (COND_EXPR, tmp, gfc_finish_block (&block2),
   5882  1.1  mrg 		      build_empty_stmt (input_location));
   5883  1.1  mrg       gfc_add_expr_to_block (&block, tmp);
   5884  1.1  mrg     }
   5885  1.1  mrg   else
   5886  1.1  mrg     gfc_add_block_to_block (&block, &block2);
   5887  1.1  mrg 
   5888  1.1  mrg 
   5889  1.1  mrg done:
   5890  1.1  mrg   if (present)
   5891  1.1  mrg     {
   5892  1.1  mrg       parmse->expr = build3_loc (input_location, COND_EXPR,
   5893  1.1  mrg 				 TREE_TYPE (parmse->expr),
   5894  1.1  mrg 				 present, parmse->expr, null_pointer_node);
   5895  1.1  mrg       tmp = build3_v (COND_EXPR, present, gfc_finish_block (&block),
   5896  1.1  mrg 		      build_empty_stmt (input_location));
   5897  1.1  mrg       gfc_add_expr_to_block (&parmse->pre, tmp);
   5898  1.1  mrg     }
   5899  1.1  mrg   else
   5900  1.1  mrg     gfc_add_block_to_block (&parmse->pre, &block);
   5901  1.1  mrg 
   5902  1.1  mrg   gfc_init_block (&block);
   5903  1.1  mrg 
   5904  1.1  mrg   if ((!fsym->attr.allocatable && !fsym->attr.pointer)
   5905  1.1  mrg       || fsym->attr.intent == INTENT_IN)
   5906  1.1  mrg     goto post_call;
   5907  1.1  mrg 
   5908  1.1  mrg   gfc_init_block (&block2);
   5909  1.1  mrg   if (e->rank == 0)
   5910  1.1  mrg     {
   5911  1.1  mrg       tmp = gfc_get_cfi_desc_base_addr (cfi);
   5912  1.1  mrg       gfc_add_modify (&block, gfc, fold_convert (TREE_TYPE (gfc), tmp));
   5913  1.1  mrg     }
   5914  1.1  mrg   else
   5915  1.1  mrg     {
   5916  1.1  mrg       tmp = gfc_get_cfi_desc_base_addr (cfi);
   5917  1.1  mrg       gfc_conv_descriptor_data_set (&block, gfc, tmp);
   5918  1.1  mrg 
   5919  1.1  mrg       if (fsym->attr.allocatable)
   5920  1.1  mrg 	{
   5921  1.1  mrg 	  /* gfc->span = cfi->elem_len.  */
   5922  1.1  mrg 	  tmp = fold_convert (gfc_array_index_type,
   5923  1.1  mrg 			      gfc_get_cfi_dim_sm (cfi, gfc_rank_cst[0]));
   5924  1.1  mrg 	}
   5925  1.1  mrg       else
   5926  1.1  mrg 	{
   5927  1.1  mrg 	  /* gfc->span = ((cfi->dim[0].sm % cfi->elem_len)
   5928  1.1  mrg 			  ? cfi->dim[0].sm : cfi->elem_len).  */
   5929  1.1  mrg 	  tmp = gfc_get_cfi_dim_sm (cfi, gfc_rank_cst[0]);
   5930  1.1  mrg 	  tmp2 = fold_convert (gfc_array_index_type,
   5931  1.1  mrg 			       gfc_get_cfi_desc_elem_len (cfi));
   5932  1.1  mrg 	  tmp = fold_build2_loc (input_location, TRUNC_MOD_EXPR,
   5933  1.1  mrg 				 gfc_array_index_type, tmp, tmp2);
   5934  1.1  mrg 	  tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
   5935  1.1  mrg 			     tmp, gfc_index_zero_node);
   5936  1.1  mrg 	  tmp = build3_loc (input_location, COND_EXPR, gfc_array_index_type, tmp,
   5937  1.1  mrg 			    gfc_get_cfi_dim_sm (cfi, gfc_rank_cst[0]), tmp2);
   5938  1.1  mrg 	}
   5939  1.1  mrg       gfc_conv_descriptor_span_set (&block2, gfc, tmp);
   5940  1.1  mrg 
   5941  1.1  mrg       /* Calculate offset + set lbound, ubound and stride.  */
   5942  1.1  mrg       gfc_conv_descriptor_offset_set (&block2, gfc, gfc_index_zero_node);
   5943  1.1  mrg       /* Loop: for (i = 0; i < rank; ++i).  */
   5944  1.1  mrg       tree idx = gfc_create_var (TREE_TYPE (rank), "idx");
   5945  1.1  mrg       /* Loop body.  */
   5946  1.1  mrg       stmtblock_t loop_body;
   5947  1.1  mrg       gfc_init_block (&loop_body);
   5948  1.1  mrg       /* gfc->dim[i].lbound = ... */
   5949  1.1  mrg       tmp = gfc_get_cfi_dim_lbound (cfi, idx);
   5950  1.1  mrg       gfc_conv_descriptor_lbound_set (&loop_body, gfc, idx, tmp);
   5951  1.1  mrg 
   5952  1.1  mrg       /* gfc->dim[i].ubound = gfc->dim[i].lbound + cfi->dim[i].extent - 1. */
   5953  1.1  mrg       tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
   5954  1.1  mrg 			     gfc_conv_descriptor_lbound_get (gfc, idx),
   5955  1.1  mrg 			     gfc_index_one_node);
   5956  1.1  mrg       tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
   5957  1.1  mrg 			     gfc_get_cfi_dim_extent (cfi, idx), tmp);
   5958  1.1  mrg       gfc_conv_descriptor_ubound_set (&loop_body, gfc, idx, tmp);
   5959  1.1  mrg 
   5960  1.1  mrg       /* gfc->dim[i].stride = cfi->dim[i].sm / cfi>elem_len */
   5961  1.1  mrg       tmp = gfc_get_cfi_dim_sm (cfi, idx);
   5962  1.1  mrg       tmp = fold_build2_loc (input_location, TRUNC_DIV_EXPR,
   5963  1.1  mrg 			     gfc_array_index_type, tmp,
   5964  1.1  mrg 			     fold_convert (gfc_array_index_type,
   5965  1.1  mrg 					   gfc_get_cfi_desc_elem_len (cfi)));
   5966  1.1  mrg       gfc_conv_descriptor_stride_set (&loop_body, gfc, idx, tmp);
   5967  1.1  mrg 
   5968  1.1  mrg       /* gfc->offset -= gfc->dim[i].stride * gfc->dim[i].lbound. */
   5969  1.1  mrg       tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
   5970  1.1  mrg 			     gfc_conv_descriptor_stride_get (gfc, idx),
   5971  1.1  mrg 			     gfc_conv_descriptor_lbound_get (gfc, idx));
   5972  1.1  mrg       tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
   5973  1.1  mrg 			     gfc_conv_descriptor_offset_get (gfc), tmp);
   5974  1.1  mrg       gfc_conv_descriptor_offset_set (&loop_body, gfc, tmp);
   5975  1.1  mrg       /* Generate loop.  */
   5976  1.1  mrg       gfc_simple_for_loop (&block2, idx, build_int_cst (TREE_TYPE (idx), 0),
   5977  1.1  mrg 			   rank, LT_EXPR, build_int_cst (TREE_TYPE (idx), 1),
   5978  1.1  mrg 			   gfc_finish_block (&loop_body));
   5979  1.1  mrg     }
   5980  1.1  mrg 
   5981  1.1  mrg   if (e->ts.type == BT_CHARACTER && !e->ts.u.cl->length)
   5982  1.1  mrg     {
   5983  1.1  mrg       tmp = fold_convert (gfc_charlen_type_node,
   5984  1.1  mrg 			  gfc_get_cfi_desc_elem_len (cfi));
   5985  1.1  mrg       if (e->ts.kind != 1)
   5986  1.1  mrg 	tmp = fold_build2_loc (input_location, TRUNC_DIV_EXPR,
   5987  1.1  mrg 			       gfc_charlen_type_node, tmp,
   5988  1.1  mrg 			       build_int_cst (gfc_charlen_type_node,
   5989  1.1  mrg 					      e->ts.kind));
   5990  1.1  mrg       gfc_add_modify (&block2, gfc_strlen, tmp);
   5991  1.1  mrg     }
   5992  1.1  mrg 
   5993  1.1  mrg   tmp = gfc_get_cfi_desc_base_addr (cfi),
   5994  1.1  mrg   tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
   5995  1.1  mrg 			 tmp, null_pointer_node);
   5996  1.1  mrg   tmp = build3_v (COND_EXPR, tmp, gfc_finish_block (&block2),
   5997  1.1  mrg 		  build_empty_stmt (input_location));
   5998  1.1  mrg   gfc_add_expr_to_block (&block, tmp);
   5999  1.1  mrg 
   6000  1.1  mrg post_call:
   6001  1.1  mrg   gfc_add_block_to_block (&block, &se.post);
   6002  1.1  mrg   if (present && block.head)
   6003  1.1  mrg     {
   6004  1.1  mrg       tmp = build3_v (COND_EXPR, present, gfc_finish_block (&block),
   6005  1.1  mrg 		      build_empty_stmt (input_location));
   6006  1.1  mrg       gfc_add_expr_to_block (&parmse->post, tmp);
   6007  1.1  mrg     }
   6008  1.1  mrg   else if (block.head)
   6009  1.1  mrg     gfc_add_block_to_block (&parmse->post, &block);
   6010  1.1  mrg }
   6011  1.1  mrg 
   6012  1.1  mrg 
   6013  1.1  mrg /* Generate code for a procedure call.  Note can return se->post != NULL.
   6014  1.1  mrg    If se->direct_byref is set then se->expr contains the return parameter.
   6015  1.1  mrg    Return nonzero, if the call has alternate specifiers.
   6016  1.1  mrg    'expr' is only needed for procedure pointer components.  */
   6017  1.1  mrg 
   6018  1.1  mrg int
   6019  1.1  mrg gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
   6020  1.1  mrg 			 gfc_actual_arglist * args, gfc_expr * expr,
   6021  1.1  mrg 			 vec<tree, va_gc> *append_args)
   6022  1.1  mrg {
   6023  1.1  mrg   gfc_interface_mapping mapping;
   6024  1.1  mrg   vec<tree, va_gc> *arglist;
   6025  1.1  mrg   vec<tree, va_gc> *retargs;
   6026  1.1  mrg   tree tmp;
   6027  1.1  mrg   tree fntype;
   6028  1.1  mrg   gfc_se parmse;
   6029  1.1  mrg   gfc_array_info *info;
   6030  1.1  mrg   int byref;
   6031  1.1  mrg   int parm_kind;
   6032  1.1  mrg   tree type;
   6033  1.1  mrg   tree var;
   6034  1.1  mrg   tree len;
   6035  1.1  mrg   tree base_object;
   6036  1.1  mrg   vec<tree, va_gc> *stringargs;
   6037  1.1  mrg   vec<tree, va_gc> *optionalargs;
   6038  1.1  mrg   tree result = NULL;
   6039  1.1  mrg   gfc_formal_arglist *formal;
   6040  1.1  mrg   gfc_actual_arglist *arg;
   6041  1.1  mrg   int has_alternate_specifier = 0;
   6042  1.1  mrg   bool need_interface_mapping;
   6043  1.1  mrg   bool callee_alloc;
   6044  1.1  mrg   bool ulim_copy;
   6045  1.1  mrg   gfc_typespec ts;
   6046  1.1  mrg   gfc_charlen cl;
   6047  1.1  mrg   gfc_expr *e;
   6048  1.1  mrg   gfc_symbol *fsym;
   6049  1.1  mrg   enum {MISSING = 0, ELEMENTAL, SCALAR, SCALAR_POINTER, ARRAY};
   6050  1.1  mrg   gfc_component *comp = NULL;
   6051  1.1  mrg   int arglen;
   6052  1.1  mrg   unsigned int argc;
   6053  1.1  mrg 
   6054  1.1  mrg   arglist = NULL;
   6055  1.1  mrg   retargs = NULL;
   6056  1.1  mrg   stringargs = NULL;
   6057  1.1  mrg   optionalargs = NULL;
   6058  1.1  mrg   var = NULL_TREE;
   6059  1.1  mrg   len = NULL_TREE;
   6060  1.1  mrg   gfc_clear_ts (&ts);
   6061  1.1  mrg 
   6062  1.1  mrg   comp = gfc_get_proc_ptr_comp (expr);
   6063  1.1  mrg 
   6064  1.1  mrg   bool elemental_proc = (comp
   6065  1.1  mrg 			 && comp->ts.interface
   6066  1.1  mrg 			 && comp->ts.interface->attr.elemental)
   6067  1.1  mrg 			|| (comp && comp->attr.elemental)
   6068  1.1  mrg 			|| sym->attr.elemental;
   6069  1.1  mrg 
   6070  1.1  mrg   if (se->ss != NULL)
   6071  1.1  mrg     {
   6072  1.1  mrg       if (!elemental_proc)
   6073  1.1  mrg 	{
   6074  1.1  mrg 	  gcc_assert (se->ss->info->type == GFC_SS_FUNCTION);
   6075  1.1  mrg 	  if (se->ss->info->useflags)
   6076  1.1  mrg 	    {
   6077  1.1  mrg 	      gcc_assert ((!comp && gfc_return_by_reference (sym)
   6078  1.1  mrg 			   && sym->result->attr.dimension)
   6079  1.1  mrg 			  || (comp && comp->attr.dimension)
   6080  1.1  mrg 			  || gfc_is_class_array_function (expr));
   6081  1.1  mrg 	      gcc_assert (se->loop != NULL);
   6082  1.1  mrg 	      /* Access the previously obtained result.  */
   6083  1.1  mrg 	      gfc_conv_tmp_array_ref (se);
   6084  1.1  mrg 	      return 0;
   6085  1.1  mrg 	    }
   6086  1.1  mrg 	}
   6087  1.1  mrg       info = &se->ss->info->data.array;
   6088  1.1  mrg     }
   6089  1.1  mrg   else
   6090  1.1  mrg     info = NULL;
   6091  1.1  mrg 
   6092  1.1  mrg   stmtblock_t post, clobbers;
   6093  1.1  mrg   gfc_init_block (&post);
   6094  1.1  mrg   gfc_init_block (&clobbers);
   6095  1.1  mrg   gfc_init_interface_mapping (&mapping);
   6096  1.1  mrg   if (!comp)
   6097  1.1  mrg     {
   6098  1.1  mrg       formal = gfc_sym_get_dummy_args (sym);
   6099  1.1  mrg       need_interface_mapping = sym->attr.dimension ||
   6100  1.1  mrg 			       (sym->ts.type == BT_CHARACTER
   6101  1.1  mrg 				&& sym->ts.u.cl->length
   6102  1.1  mrg 				&& sym->ts.u.cl->length->expr_type
   6103  1.1  mrg 				   != EXPR_CONSTANT);
   6104  1.1  mrg     }
   6105  1.1  mrg   else
   6106  1.1  mrg     {
   6107  1.1  mrg       formal = comp->ts.interface ? comp->ts.interface->formal : NULL;
   6108  1.1  mrg       need_interface_mapping = comp->attr.dimension ||
   6109  1.1  mrg 			       (comp->ts.type == BT_CHARACTER
   6110  1.1  mrg 				&& comp->ts.u.cl->length
   6111  1.1  mrg 				&& comp->ts.u.cl->length->expr_type
   6112  1.1  mrg 				   != EXPR_CONSTANT);
   6113  1.1  mrg     }
   6114  1.1  mrg 
   6115  1.1  mrg   base_object = NULL_TREE;
   6116  1.1  mrg   /* For _vprt->_copy () routines no formal symbol is present.  Nevertheless
   6117  1.1  mrg      is the third and fourth argument to such a function call a value
   6118  1.1  mrg      denoting the number of elements to copy (i.e., most of the time the
   6119  1.1  mrg      length of a deferred length string).  */
   6120  1.1  mrg   ulim_copy = (formal == NULL)
   6121  1.1  mrg 	       && UNLIMITED_POLY (sym)
   6122  1.1  mrg 	       && comp && (strcmp ("_copy", comp->name) == 0);
   6123  1.1  mrg 
   6124  1.1  mrg   /* Evaluate the arguments.  */
   6125  1.1  mrg   for (arg = args, argc = 0; arg != NULL;
   6126  1.1  mrg        arg = arg->next, formal = formal ? formal->next : NULL, ++argc)
   6127  1.1  mrg     {
   6128  1.1  mrg       bool finalized = false;
   6129  1.1  mrg       tree derived_array = NULL_TREE;
   6130  1.1  mrg 
   6131  1.1  mrg       e = arg->expr;
   6132  1.1  mrg       fsym = formal ? formal->sym : NULL;
   6133  1.1  mrg       parm_kind = MISSING;
   6134  1.1  mrg 
   6135  1.1  mrg       /* If the procedure requires an explicit interface, the actual
   6136  1.1  mrg 	 argument is passed according to the corresponding formal
   6137  1.1  mrg 	 argument.  If the corresponding formal argument is a POINTER,
   6138  1.1  mrg 	 ALLOCATABLE or assumed shape, we do not use g77's calling
   6139  1.1  mrg 	 convention, and pass the address of the array descriptor
   6140  1.1  mrg 	 instead.  Otherwise we use g77's calling convention, in other words
   6141  1.1  mrg 	 pass the array data pointer without descriptor.  */
   6142  1.1  mrg       bool nodesc_arg = fsym != NULL
   6143  1.1  mrg 			&& !(fsym->attr.pointer || fsym->attr.allocatable)
   6144  1.1  mrg 			&& fsym->as
   6145  1.1  mrg 			&& fsym->as->type != AS_ASSUMED_SHAPE
   6146  1.1  mrg 			&& fsym->as->type != AS_ASSUMED_RANK;
   6147  1.1  mrg       if (comp)
   6148  1.1  mrg 	nodesc_arg = nodesc_arg || !comp->attr.always_explicit;
   6149  1.1  mrg       else
   6150  1.1  mrg 	nodesc_arg = nodesc_arg || !sym->attr.always_explicit;
   6151  1.1  mrg 
   6152  1.1  mrg       /* Class array expressions are sometimes coming completely unadorned
   6153  1.1  mrg 	 with either arrayspec or _data component.  Correct that here.
   6154  1.1  mrg 	 OOP-TODO: Move this to the frontend.  */
   6155  1.1  mrg       if (e && e->expr_type == EXPR_VARIABLE
   6156  1.1  mrg 	    && !e->ref
   6157  1.1  mrg 	    && e->ts.type == BT_CLASS
   6158  1.1  mrg 	    && (CLASS_DATA (e)->attr.codimension
   6159  1.1  mrg 		|| CLASS_DATA (e)->attr.dimension))
   6160  1.1  mrg 	{
   6161  1.1  mrg 	  gfc_typespec temp_ts = e->ts;
   6162  1.1  mrg 	  gfc_add_class_array_ref (e);
   6163  1.1  mrg 	  e->ts = temp_ts;
   6164  1.1  mrg 	}
   6165  1.1  mrg 
   6166  1.1  mrg       if (e == NULL)
   6167  1.1  mrg 	{
   6168  1.1  mrg 	  if (se->ignore_optional)
   6169  1.1  mrg 	    {
   6170  1.1  mrg 	      /* Some intrinsics have already been resolved to the correct
   6171  1.1  mrg 	         parameters.  */
   6172  1.1  mrg 	      continue;
   6173  1.1  mrg 	    }
   6174  1.1  mrg 	  else if (arg->label)
   6175  1.1  mrg 	    {
   6176  1.1  mrg 	      has_alternate_specifier = 1;
   6177  1.1  mrg 	      continue;
   6178  1.1  mrg 	    }
   6179  1.1  mrg 	  else
   6180  1.1  mrg 	    {
   6181  1.1  mrg 	      gfc_init_se (&parmse, NULL);
   6182  1.1  mrg 
   6183  1.1  mrg 	      /* For scalar arguments with VALUE attribute which are passed by
   6184  1.1  mrg 		 value, pass "0" and a hidden argument gives the optional
   6185  1.1  mrg 		 status.  */
   6186  1.1  mrg 	      if (fsym && fsym->attr.optional && fsym->attr.value
   6187  1.1  mrg 		  && !fsym->attr.dimension && fsym->ts.type != BT_CHARACTER
   6188  1.1  mrg 		  && fsym->ts.type != BT_CLASS && fsym->ts.type != BT_DERIVED)
   6189  1.1  mrg 		{
   6190  1.1  mrg 		  parmse.expr = fold_convert (gfc_sym_type (fsym),
   6191  1.1  mrg 					      integer_zero_node);
   6192  1.1  mrg 		  vec_safe_push (optionalargs, boolean_false_node);
   6193  1.1  mrg 		}
   6194  1.1  mrg 	      else
   6195  1.1  mrg 		{
   6196  1.1  mrg 		  /* Pass a NULL pointer for an absent arg.  */
   6197  1.1  mrg 		  parmse.expr = null_pointer_node;
   6198  1.1  mrg 
   6199  1.1  mrg 		  /* Is it an absent character dummy?  */
   6200  1.1  mrg 		  bool absent_char = false;
   6201  1.1  mrg 		  gfc_dummy_arg * const dummy_arg = arg->associated_dummy;
   6202  1.1  mrg 
   6203  1.1  mrg 		  /* Fall back to inferred type only if no formal.  */
   6204  1.1  mrg 		  if (fsym)
   6205  1.1  mrg 		    absent_char = (fsym->ts.type == BT_CHARACTER);
   6206  1.1  mrg 		  else if (dummy_arg)
   6207  1.1  mrg 		    absent_char = (gfc_dummy_arg_get_typespec (*dummy_arg).type
   6208  1.1  mrg 				   == BT_CHARACTER);
   6209  1.1  mrg 		  if (absent_char)
   6210  1.1  mrg 		    parmse.string_length = build_int_cst (gfc_charlen_type_node,
   6211  1.1  mrg 							  0);
   6212  1.1  mrg 		}
   6213  1.1  mrg 	    }
   6214  1.1  mrg 	}
   6215  1.1  mrg       else if (arg->expr->expr_type == EXPR_NULL
   6216  1.1  mrg 	       && fsym && !fsym->attr.pointer
   6217  1.1  mrg 	       && (fsym->ts.type != BT_CLASS
   6218  1.1  mrg 		   || !CLASS_DATA (fsym)->attr.class_pointer))
   6219  1.1  mrg 	{
   6220  1.1  mrg 	  /* Pass a NULL pointer to denote an absent arg.  */
   6221  1.1  mrg 	  gcc_assert (fsym->attr.optional && !fsym->attr.allocatable
   6222  1.1  mrg 		      && (fsym->ts.type != BT_CLASS
   6223  1.1  mrg 			  || !CLASS_DATA (fsym)->attr.allocatable));
   6224  1.1  mrg 	  gfc_init_se (&parmse, NULL);
   6225  1.1  mrg 	  parmse.expr = null_pointer_node;
   6226  1.1  mrg 	  if (fsym->ts.type == BT_CHARACTER)
   6227  1.1  mrg 	    parmse.string_length = build_int_cst (gfc_charlen_type_node, 0);
   6228  1.1  mrg 	}
   6229  1.1  mrg       else if (fsym && fsym->ts.type == BT_CLASS
   6230  1.1  mrg 		 && e->ts.type == BT_DERIVED)
   6231  1.1  mrg 	{
   6232  1.1  mrg 	  /* The derived type needs to be converted to a temporary
   6233  1.1  mrg 	     CLASS object.  */
   6234  1.1  mrg 	  gfc_init_se (&parmse, se);
   6235  1.1  mrg 	  gfc_conv_derived_to_class (&parmse, e, fsym->ts, NULL,
   6236  1.1  mrg 				     fsym->attr.optional
   6237  1.1  mrg 				     && e->expr_type == EXPR_VARIABLE
   6238  1.1  mrg 				     && e->symtree->n.sym->attr.optional,
   6239  1.1  mrg 				     CLASS_DATA (fsym)->attr.class_pointer
   6240  1.1  mrg 				     || CLASS_DATA (fsym)->attr.allocatable,
   6241  1.1  mrg 				     &derived_array);
   6242  1.1  mrg 	}
   6243  1.1  mrg       else if (UNLIMITED_POLY (fsym) && e->ts.type != BT_CLASS
   6244  1.1  mrg 	       && e->ts.type != BT_PROCEDURE
   6245  1.1  mrg 	       && (gfc_expr_attr (e).flavor != FL_PROCEDURE
   6246  1.1  mrg 		   || gfc_expr_attr (e).proc != PROC_UNKNOWN))
   6247  1.1  mrg 	{
   6248  1.1  mrg 	  /* The intrinsic type needs to be converted to a temporary
   6249  1.1  mrg 	     CLASS object for the unlimited polymorphic formal.  */
   6250  1.1  mrg 	  gfc_find_vtab (&e->ts);
   6251  1.1  mrg 	  gfc_init_se (&parmse, se);
   6252  1.1  mrg 	  gfc_conv_intrinsic_to_class (&parmse, e, fsym->ts);
   6253  1.1  mrg 
   6254  1.1  mrg 	}
   6255  1.1  mrg       else if (se->ss && se->ss->info->useflags)
   6256  1.1  mrg 	{
   6257  1.1  mrg 	  gfc_ss *ss;
   6258  1.1  mrg 
   6259  1.1  mrg 	  ss = se->ss;
   6260  1.1  mrg 
   6261  1.1  mrg 	  /* An elemental function inside a scalarized loop.  */
   6262  1.1  mrg 	  gfc_init_se (&parmse, se);
   6263  1.1  mrg 	  parm_kind = ELEMENTAL;
   6264  1.1  mrg 
   6265  1.1  mrg 	  /* When no fsym is present, ulim_copy is set and this is a third or
   6266  1.1  mrg 	     fourth argument, use call-by-value instead of by reference to
   6267  1.1  mrg 	     hand the length properties to the copy routine (i.e., most of the
   6268  1.1  mrg 	     time this will be a call to a __copy_character_* routine where the
   6269  1.1  mrg 	     third and fourth arguments are the lengths of a deferred length
   6270  1.1  mrg 	     char array).  */
   6271  1.1  mrg 	  if ((fsym && fsym->attr.value)
   6272  1.1  mrg 	      || (ulim_copy && (argc == 2 || argc == 3)))
   6273  1.1  mrg 	    gfc_conv_expr (&parmse, e);
   6274  1.1  mrg 	  else
   6275  1.1  mrg 	    gfc_conv_expr_reference (&parmse, e);
   6276  1.1  mrg 
   6277  1.1  mrg 	  if (e->ts.type == BT_CHARACTER && !e->rank
   6278  1.1  mrg 	      && e->expr_type == EXPR_FUNCTION)
   6279  1.1  mrg 	    parmse.expr = build_fold_indirect_ref_loc (input_location,
   6280  1.1  mrg 						       parmse.expr);
   6281  1.1  mrg 
   6282  1.1  mrg 	  if (fsym && fsym->ts.type == BT_DERIVED
   6283  1.1  mrg 	      && gfc_is_class_container_ref (e))
   6284  1.1  mrg 	    {
   6285  1.1  mrg 	      parmse.expr = gfc_class_data_get (parmse.expr);
   6286  1.1  mrg 
   6287  1.1  mrg 	      if (fsym->attr.optional && e->expr_type == EXPR_VARIABLE
   6288  1.1  mrg 		  && e->symtree->n.sym->attr.optional)
   6289  1.1  mrg 		{
   6290  1.1  mrg 		  tree cond = gfc_conv_expr_present (e->symtree->n.sym);
   6291  1.1  mrg 		  parmse.expr = build3_loc (input_location, COND_EXPR,
   6292  1.1  mrg 					TREE_TYPE (parmse.expr),
   6293  1.1  mrg 					cond, parmse.expr,
   6294  1.1  mrg 					fold_convert (TREE_TYPE (parmse.expr),
   6295  1.1  mrg 						      null_pointer_node));
   6296  1.1  mrg 		}
   6297  1.1  mrg 	    }
   6298  1.1  mrg 
   6299  1.1  mrg 	  /* If we are passing an absent array as optional dummy to an
   6300  1.1  mrg 	     elemental procedure, make sure that we pass NULL when the data
   6301  1.1  mrg 	     pointer is NULL.  We need this extra conditional because of
   6302  1.1  mrg 	     scalarization which passes arrays elements to the procedure,
   6303  1.1  mrg 	     ignoring the fact that the array can be absent/unallocated/...  */
   6304  1.1  mrg 	  if (ss->info->can_be_null_ref && ss->info->type != GFC_SS_REFERENCE)
   6305  1.1  mrg 	    {
   6306  1.1  mrg 	      tree descriptor_data;
   6307  1.1  mrg 
   6308  1.1  mrg 	      descriptor_data = ss->info->data.array.data;
   6309  1.1  mrg 	      tmp = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
   6310  1.1  mrg 				     descriptor_data,
   6311  1.1  mrg 				     fold_convert (TREE_TYPE (descriptor_data),
   6312  1.1  mrg 						   null_pointer_node));
   6313  1.1  mrg 	      parmse.expr
   6314  1.1  mrg 		= fold_build3_loc (input_location, COND_EXPR,
   6315  1.1  mrg 				   TREE_TYPE (parmse.expr),
   6316  1.1  mrg 				   gfc_unlikely (tmp, PRED_FORTRAN_ABSENT_DUMMY),
   6317  1.1  mrg 				   fold_convert (TREE_TYPE (parmse.expr),
   6318  1.1  mrg 						 null_pointer_node),
   6319  1.1  mrg 				   parmse.expr);
   6320  1.1  mrg 	    }
   6321  1.1  mrg 
   6322  1.1  mrg 	  /* The scalarizer does not repackage the reference to a class
   6323  1.1  mrg 	     array - instead it returns a pointer to the data element.  */
   6324  1.1  mrg 	  if (fsym && fsym->ts.type == BT_CLASS && e->ts.type == BT_CLASS)
   6325  1.1  mrg 	    gfc_conv_class_to_class (&parmse, e, fsym->ts, true,
   6326  1.1  mrg 				     fsym->attr.intent != INTENT_IN
   6327  1.1  mrg 				     && (CLASS_DATA (fsym)->attr.class_pointer
   6328  1.1  mrg 					 || CLASS_DATA (fsym)->attr.allocatable),
   6329  1.1  mrg 				     fsym->attr.optional
   6330  1.1  mrg 				     && e->expr_type == EXPR_VARIABLE
   6331  1.1  mrg 				     && e->symtree->n.sym->attr.optional,
   6332  1.1  mrg 				     CLASS_DATA (fsym)->attr.class_pointer
   6333  1.1  mrg 				     || CLASS_DATA (fsym)->attr.allocatable);
   6334  1.1  mrg 	}
   6335  1.1  mrg       else
   6336  1.1  mrg 	{
   6337  1.1  mrg 	  bool scalar;
   6338  1.1  mrg 	  gfc_ss *argss;
   6339  1.1  mrg 
   6340  1.1  mrg 	  gfc_init_se (&parmse, NULL);
   6341  1.1  mrg 
   6342  1.1  mrg 	  /* Check whether the expression is a scalar or not; we cannot use
   6343  1.1  mrg 	     e->rank as it can be nonzero for functions arguments.  */
   6344  1.1  mrg 	  argss = gfc_walk_expr (e);
   6345  1.1  mrg 	  scalar = argss == gfc_ss_terminator;
   6346  1.1  mrg 	  if (!scalar)
   6347  1.1  mrg 	    gfc_free_ss_chain (argss);
   6348  1.1  mrg 
   6349  1.1  mrg 	  /* Special handling for passing scalar polymorphic coarrays;
   6350  1.1  mrg 	     otherwise one passes "class->_data.data" instead of "&class".  */
   6351  1.1  mrg 	  if (e->rank == 0 && e->ts.type == BT_CLASS
   6352  1.1  mrg 	      && fsym && fsym->ts.type == BT_CLASS
   6353  1.1  mrg 	      && CLASS_DATA (fsym)->attr.codimension
   6354  1.1  mrg 	      && !CLASS_DATA (fsym)->attr.dimension)
   6355  1.1  mrg 	    {
   6356  1.1  mrg 	      gfc_add_class_array_ref (e);
   6357  1.1  mrg               parmse.want_coarray = 1;
   6358  1.1  mrg 	      scalar = false;
   6359  1.1  mrg 	    }
   6360  1.1  mrg 
   6361  1.1  mrg 	  /* A scalar or transformational function.  */
   6362  1.1  mrg 	  if (scalar)
   6363  1.1  mrg 	    {
   6364  1.1  mrg 	      if (e->expr_type == EXPR_VARIABLE
   6365  1.1  mrg 		    && e->symtree->n.sym->attr.cray_pointee
   6366  1.1  mrg 		    && fsym && fsym->attr.flavor == FL_PROCEDURE)
   6367  1.1  mrg 		{
   6368  1.1  mrg 		    /* The Cray pointer needs to be converted to a pointer to
   6369  1.1  mrg 		       a type given by the expression.  */
   6370  1.1  mrg 		    gfc_conv_expr (&parmse, e);
   6371  1.1  mrg 		    type = build_pointer_type (TREE_TYPE (parmse.expr));
   6372  1.1  mrg 		    tmp = gfc_get_symbol_decl (e->symtree->n.sym->cp_pointer);
   6373  1.1  mrg 		    parmse.expr = convert (type, tmp);
   6374  1.1  mrg 		}
   6375  1.1  mrg 
   6376  1.1  mrg 	      else if (sym->attr.is_bind_c && e && is_CFI_desc (fsym, NULL))
   6377  1.1  mrg 		/* Implement F2018, 18.3.6, list item (5), bullet point 2.  */
   6378  1.1  mrg 		gfc_conv_gfc_desc_to_cfi_desc (&parmse, e, fsym);
   6379  1.1  mrg 
   6380  1.1  mrg 	      else if (fsym && fsym->attr.value)
   6381  1.1  mrg 		{
   6382  1.1  mrg 		  if (fsym->ts.type == BT_CHARACTER
   6383  1.1  mrg 		      && fsym->ts.is_c_interop
   6384  1.1  mrg 		      && fsym->ns->proc_name != NULL
   6385  1.1  mrg 		      && fsym->ns->proc_name->attr.is_bind_c)
   6386  1.1  mrg 		    {
   6387  1.1  mrg 		      parmse.expr = NULL;
   6388  1.1  mrg 		      conv_scalar_char_value (fsym, &parmse, &e);
   6389  1.1  mrg 		      if (parmse.expr == NULL)
   6390  1.1  mrg 			gfc_conv_expr (&parmse, e);
   6391  1.1  mrg 		    }
   6392  1.1  mrg 		  else
   6393  1.1  mrg 		    {
   6394  1.1  mrg 		    gfc_conv_expr (&parmse, e);
   6395  1.1  mrg 		    if (fsym->attr.optional
   6396  1.1  mrg 			&& fsym->ts.type != BT_CLASS
   6397  1.1  mrg 			&& fsym->ts.type != BT_DERIVED)
   6398  1.1  mrg 		      {
   6399  1.1  mrg 			if (e->expr_type != EXPR_VARIABLE
   6400  1.1  mrg 			    || !e->symtree->n.sym->attr.optional
   6401  1.1  mrg 			    || e->ref != NULL)
   6402  1.1  mrg 			  vec_safe_push (optionalargs, boolean_true_node);
   6403  1.1  mrg 			else
   6404  1.1  mrg 			  {
   6405  1.1  mrg 			    tmp = gfc_conv_expr_present (e->symtree->n.sym);
   6406  1.1  mrg 			    if (!e->symtree->n.sym->attr.value)
   6407  1.1  mrg 			      parmse.expr
   6408  1.1  mrg 				= fold_build3_loc (input_location, COND_EXPR,
   6409  1.1  mrg 					TREE_TYPE (parmse.expr),
   6410  1.1  mrg 					tmp, parmse.expr,
   6411  1.1  mrg 					fold_convert (TREE_TYPE (parmse.expr),
   6412  1.1  mrg 						      integer_zero_node));
   6413  1.1  mrg 
   6414  1.1  mrg 			    vec_safe_push (optionalargs,
   6415  1.1  mrg 					   fold_convert (boolean_type_node,
   6416  1.1  mrg 							 tmp));
   6417  1.1  mrg 			  }
   6418  1.1  mrg 		      }
   6419  1.1  mrg 		    }
   6420  1.1  mrg 		}
   6421  1.1  mrg 
   6422  1.1  mrg 	      else if (arg->name && arg->name[0] == '%')
   6423  1.1  mrg 		/* Argument list functions %VAL, %LOC and %REF are signalled
   6424  1.1  mrg 		   through arg->name.  */
   6425  1.1  mrg 		conv_arglist_function (&parmse, arg->expr, arg->name);
   6426  1.1  mrg 	      else if ((e->expr_type == EXPR_FUNCTION)
   6427  1.1  mrg 			&& ((e->value.function.esym
   6428  1.1  mrg 			     && e->value.function.esym->result->attr.pointer)
   6429  1.1  mrg 			    || (!e->value.function.esym
   6430  1.1  mrg 				&& e->symtree->n.sym->attr.pointer))
   6431  1.1  mrg 			&& fsym && fsym->attr.target)
   6432  1.1  mrg 		/* Make sure the function only gets called once.  */
   6433  1.1  mrg 		gfc_conv_expr_reference (&parmse, e);
   6434  1.1  mrg 	      else if (e->expr_type == EXPR_FUNCTION
   6435  1.1  mrg 		       && e->symtree->n.sym->result
   6436  1.1  mrg 		       && e->symtree->n.sym->result != e->symtree->n.sym
   6437  1.1  mrg 		       && e->symtree->n.sym->result->attr.proc_pointer)
   6438  1.1  mrg 		{
   6439  1.1  mrg 		  /* Functions returning procedure pointers.  */
   6440  1.1  mrg 		  gfc_conv_expr (&parmse, e);
   6441  1.1  mrg 		  if (fsym && fsym->attr.proc_pointer)
   6442  1.1  mrg 		    parmse.expr = gfc_build_addr_expr (NULL_TREE, parmse.expr);
   6443  1.1  mrg 		}
   6444  1.1  mrg 
   6445  1.1  mrg 	      else
   6446  1.1  mrg 		{
   6447  1.1  mrg 		  if (e->ts.type == BT_CLASS && fsym
   6448  1.1  mrg 		      && fsym->ts.type == BT_CLASS
   6449  1.1  mrg 		      && (!CLASS_DATA (fsym)->as
   6450  1.1  mrg 			  || CLASS_DATA (fsym)->as->type != AS_ASSUMED_RANK)
   6451  1.1  mrg 		      && CLASS_DATA (e)->attr.codimension)
   6452  1.1  mrg 		    {
   6453  1.1  mrg 		      gcc_assert (!CLASS_DATA (fsym)->attr.codimension);
   6454  1.1  mrg 		      gcc_assert (!CLASS_DATA (fsym)->as);
   6455  1.1  mrg 		      gfc_add_class_array_ref (e);
   6456  1.1  mrg 		      parmse.want_coarray = 1;
   6457  1.1  mrg 		      gfc_conv_expr_reference (&parmse, e);
   6458  1.1  mrg 		      class_scalar_coarray_to_class (&parmse, e, fsym->ts,
   6459  1.1  mrg 				     fsym->attr.optional
   6460  1.1  mrg 				     && e->expr_type == EXPR_VARIABLE);
   6461  1.1  mrg 		    }
   6462  1.1  mrg 		  else if (e->ts.type == BT_CLASS && fsym
   6463  1.1  mrg 			   && fsym->ts.type == BT_CLASS
   6464  1.1  mrg 			   && !CLASS_DATA (fsym)->as
   6465  1.1  mrg 			   && !CLASS_DATA (e)->as
   6466  1.1  mrg 			   && strcmp (fsym->ts.u.derived->name,
   6467  1.1  mrg 				      e->ts.u.derived->name))
   6468  1.1  mrg 		    {
   6469  1.1  mrg 		      type = gfc_typenode_for_spec (&fsym->ts);
   6470  1.1  mrg 		      var = gfc_create_var (type, fsym->name);
   6471  1.1  mrg 		      gfc_conv_expr (&parmse, e);
   6472  1.1  mrg 		      if (fsym->attr.optional
   6473  1.1  mrg 			  && e->expr_type == EXPR_VARIABLE
   6474  1.1  mrg 			  && e->symtree->n.sym->attr.optional)
   6475  1.1  mrg 			{
   6476  1.1  mrg 			  stmtblock_t block;
   6477  1.1  mrg 			  tree cond;
   6478  1.1  mrg 			  tmp = gfc_build_addr_expr (NULL_TREE, parmse.expr);
   6479  1.1  mrg 			  cond = fold_build2_loc (input_location, NE_EXPR,
   6480  1.1  mrg 						  logical_type_node, tmp,
   6481  1.1  mrg 						  fold_convert (TREE_TYPE (tmp),
   6482  1.1  mrg 							    null_pointer_node));
   6483  1.1  mrg 			  gfc_start_block (&block);
   6484  1.1  mrg 			  gfc_add_modify (&block, var,
   6485  1.1  mrg 					  fold_build1_loc (input_location,
   6486  1.1  mrg 							   VIEW_CONVERT_EXPR,
   6487  1.1  mrg 							   type, parmse.expr));
   6488  1.1  mrg 			  gfc_add_expr_to_block (&parmse.pre,
   6489  1.1  mrg 				 fold_build3_loc (input_location,
   6490  1.1  mrg 					 COND_EXPR, void_type_node,
   6491  1.1  mrg 					 cond, gfc_finish_block (&block),
   6492  1.1  mrg 					 build_empty_stmt (input_location)));
   6493  1.1  mrg 			  parmse.expr = gfc_build_addr_expr (NULL_TREE, var);
   6494  1.1  mrg 			  parmse.expr = build3_loc (input_location, COND_EXPR,
   6495  1.1  mrg 					 TREE_TYPE (parmse.expr),
   6496  1.1  mrg 					 cond, parmse.expr,
   6497  1.1  mrg 					 fold_convert (TREE_TYPE (parmse.expr),
   6498  1.1  mrg 						       null_pointer_node));
   6499  1.1  mrg 			}
   6500  1.1  mrg 		      else
   6501  1.1  mrg 			{
   6502  1.1  mrg 			  /* Since the internal representation of unlimited
   6503  1.1  mrg 			     polymorphic expressions includes an extra field
   6504  1.1  mrg 			     that other class objects do not, a cast to the
   6505  1.1  mrg 			     formal type does not work.  */
   6506  1.1  mrg 			  if (!UNLIMITED_POLY (e) && UNLIMITED_POLY (fsym))
   6507  1.1  mrg 			    {
   6508  1.1  mrg 			      tree efield;
   6509  1.1  mrg 
   6510  1.1  mrg 			      /* Set the _data field.  */
   6511  1.1  mrg 			      tmp = gfc_class_data_get (var);
   6512  1.1  mrg 			      efield = fold_convert (TREE_TYPE (tmp),
   6513  1.1  mrg 					gfc_class_data_get (parmse.expr));
   6514  1.1  mrg 			      gfc_add_modify (&parmse.pre, tmp, efield);
   6515  1.1  mrg 
   6516  1.1  mrg 			      /* Set the _vptr field.  */
   6517  1.1  mrg 			      tmp = gfc_class_vptr_get (var);
   6518  1.1  mrg 			      efield = fold_convert (TREE_TYPE (tmp),
   6519  1.1  mrg 					gfc_class_vptr_get (parmse.expr));
   6520  1.1  mrg 			      gfc_add_modify (&parmse.pre, tmp, efield);
   6521  1.1  mrg 
   6522  1.1  mrg 			      /* Set the _len field.  */
   6523  1.1  mrg 			      tmp = gfc_class_len_get (var);
   6524  1.1  mrg 			      gfc_add_modify (&parmse.pre, tmp,
   6525  1.1  mrg 					      build_int_cst (TREE_TYPE (tmp), 0));
   6526  1.1  mrg 			    }
   6527  1.1  mrg 			  else
   6528  1.1  mrg 			    {
   6529  1.1  mrg 			      tmp = fold_build1_loc (input_location,
   6530  1.1  mrg 						     VIEW_CONVERT_EXPR,
   6531  1.1  mrg 						     type, parmse.expr);
   6532  1.1  mrg 			      gfc_add_modify (&parmse.pre, var, tmp);
   6533  1.1  mrg 					      ;
   6534  1.1  mrg 			    }
   6535  1.1  mrg 			  parmse.expr = gfc_build_addr_expr (NULL_TREE, var);
   6536  1.1  mrg 			}
   6537  1.1  mrg 		    }
   6538  1.1  mrg 		  else
   6539  1.1  mrg 		    {
   6540  1.1  mrg 		      gfc_conv_expr_reference (&parmse, e);
   6541  1.1  mrg 
   6542  1.1  mrg 		      if (fsym
   6543  1.1  mrg 			  && fsym->attr.intent == INTENT_OUT
   6544  1.1  mrg 			  && !fsym->attr.allocatable
   6545  1.1  mrg 			  && !fsym->attr.pointer
   6546  1.1  mrg 			  && e->expr_type == EXPR_VARIABLE
   6547  1.1  mrg 			  && e->ref == NULL
   6548  1.1  mrg 			  && e->symtree
   6549  1.1  mrg 			  && e->symtree->n.sym
   6550  1.1  mrg 			  && !e->symtree->n.sym->attr.dimension
   6551  1.1  mrg 			  && !e->symtree->n.sym->attr.pointer
   6552  1.1  mrg 			  && !e->symtree->n.sym->attr.allocatable
   6553  1.1  mrg 			  /* See PR 41453.  */
   6554  1.1  mrg 			  && !e->symtree->n.sym->attr.dummy
   6555  1.1  mrg 			  /* FIXME - PR 87395 and PR 41453  */
   6556  1.1  mrg 			  && e->symtree->n.sym->attr.save == SAVE_NONE
   6557  1.1  mrg 			  && !e->symtree->n.sym->attr.associate_var
   6558  1.1  mrg 			  && e->ts.type != BT_CHARACTER
   6559  1.1  mrg 			  && e->ts.type != BT_DERIVED
   6560  1.1  mrg 			  && e->ts.type != BT_CLASS
   6561  1.1  mrg 			  && !sym->attr.elemental)
   6562  1.1  mrg 			{
   6563  1.1  mrg 			  tree var;
   6564  1.1  mrg 			  /* FIXME: This fails if var is passed by reference, see PR
   6565  1.1  mrg 			     41453.  */
   6566  1.1  mrg 			  var = build_fold_indirect_ref_loc (input_location,
   6567  1.1  mrg 							     parmse.expr);
   6568  1.1  mrg 			  tree clobber = build_clobber (TREE_TYPE (var));
   6569  1.1  mrg 			  gfc_add_modify (&clobbers, var, clobber);
   6570  1.1  mrg 			}
   6571  1.1  mrg 		    }
   6572  1.1  mrg 		  /* Catch base objects that are not variables.  */
   6573  1.1  mrg 		  if (e->ts.type == BT_CLASS
   6574  1.1  mrg 			&& e->expr_type != EXPR_VARIABLE
   6575  1.1  mrg 			&& expr && e == expr->base_expr)
   6576  1.1  mrg 		    base_object = build_fold_indirect_ref_loc (input_location,
   6577  1.1  mrg 							       parmse.expr);
   6578  1.1  mrg 
   6579  1.1  mrg 		  /* If an ALLOCATABLE dummy argument has INTENT(OUT) and is
   6580  1.1  mrg 		     allocated on entry, it must be deallocated.  */
   6581  1.1  mrg 		  if (fsym && fsym->attr.intent == INTENT_OUT
   6582  1.1  mrg 		      && (fsym->attr.allocatable
   6583  1.1  mrg 			  || (fsym->ts.type == BT_CLASS
   6584  1.1  mrg 			      && CLASS_DATA (fsym)->attr.allocatable))
   6585  1.1  mrg 		      && !is_CFI_desc (fsym, NULL))
   6586  1.1  mrg 		    {
   6587  1.1  mrg 		      stmtblock_t block;
   6588  1.1  mrg 		      tree ptr;
   6589  1.1  mrg 
   6590  1.1  mrg 		      gfc_init_block  (&block);
   6591  1.1  mrg 		      ptr = parmse.expr;
   6592  1.1  mrg 		      if (e->ts.type == BT_CLASS)
   6593  1.1  mrg 			ptr = gfc_class_data_get (ptr);
   6594  1.1  mrg 
   6595  1.1  mrg 		      tmp = gfc_deallocate_scalar_with_status (ptr, NULL_TREE,
   6596  1.1  mrg 							       NULL_TREE, true,
   6597  1.1  mrg 							       e, e->ts);
   6598  1.1  mrg 		      gfc_add_expr_to_block (&block, tmp);
   6599  1.1  mrg 		      tmp = fold_build2_loc (input_location, MODIFY_EXPR,
   6600  1.1  mrg 					     void_type_node, ptr,
   6601  1.1  mrg 					     null_pointer_node);
   6602  1.1  mrg 		      gfc_add_expr_to_block (&block, tmp);
   6603  1.1  mrg 
   6604  1.1  mrg 		      if (fsym->ts.type == BT_CLASS && UNLIMITED_POLY (fsym))
   6605  1.1  mrg 			{
   6606  1.1  mrg 			  gfc_add_modify (&block, ptr,
   6607  1.1  mrg 					  fold_convert (TREE_TYPE (ptr),
   6608  1.1  mrg 							null_pointer_node));
   6609  1.1  mrg 			  gfc_add_expr_to_block (&block, tmp);
   6610  1.1  mrg 			}
   6611  1.1  mrg 		      else if (fsym->ts.type == BT_CLASS)
   6612  1.1  mrg 			{
   6613  1.1  mrg 			  gfc_symbol *vtab;
   6614  1.1  mrg 			  vtab = gfc_find_derived_vtab (fsym->ts.u.derived);
   6615  1.1  mrg 			  tmp = gfc_get_symbol_decl (vtab);
   6616  1.1  mrg 			  tmp = gfc_build_addr_expr (NULL_TREE, tmp);
   6617  1.1  mrg 			  ptr = gfc_class_vptr_get (parmse.expr);
   6618  1.1  mrg 			  gfc_add_modify (&block, ptr,
   6619  1.1  mrg 					  fold_convert (TREE_TYPE (ptr), tmp));
   6620  1.1  mrg 			  gfc_add_expr_to_block (&block, tmp);
   6621  1.1  mrg 			}
   6622  1.1  mrg 
   6623  1.1  mrg 		      if (fsym->attr.optional
   6624  1.1  mrg 			  && e->expr_type == EXPR_VARIABLE
   6625  1.1  mrg 			  && e->symtree->n.sym->attr.optional)
   6626  1.1  mrg 			{
   6627  1.1  mrg 			  tmp = fold_build3_loc (input_location, COND_EXPR,
   6628  1.1  mrg 				     void_type_node,
   6629  1.1  mrg 				     gfc_conv_expr_present (e->symtree->n.sym),
   6630  1.1  mrg 					    gfc_finish_block (&block),
   6631  1.1  mrg 					    build_empty_stmt (input_location));
   6632  1.1  mrg 			}
   6633  1.1  mrg 		      else
   6634  1.1  mrg 			tmp = gfc_finish_block (&block);
   6635  1.1  mrg 
   6636  1.1  mrg 		      gfc_add_expr_to_block (&se->pre, tmp);
   6637  1.1  mrg 		    }
   6638  1.1  mrg 
   6639  1.1  mrg 		  /* A class array element needs converting back to be a
   6640  1.1  mrg 		     class object, if the formal argument is a class object.  */
   6641  1.1  mrg 		  if (fsym && fsym->ts.type == BT_CLASS
   6642  1.1  mrg 			&& e->ts.type == BT_CLASS
   6643  1.1  mrg 			&& ((CLASS_DATA (fsym)->as
   6644  1.1  mrg 			     && CLASS_DATA (fsym)->as->type == AS_ASSUMED_RANK)
   6645  1.1  mrg 			    || CLASS_DATA (e)->attr.dimension))
   6646  1.1  mrg 		    gfc_conv_class_to_class (&parmse, e, fsym->ts, false,
   6647  1.1  mrg 				     fsym->attr.intent != INTENT_IN
   6648  1.1  mrg 				     && (CLASS_DATA (fsym)->attr.class_pointer
   6649  1.1  mrg 					 || CLASS_DATA (fsym)->attr.allocatable),
   6650  1.1  mrg 				     fsym->attr.optional
   6651  1.1  mrg 				     && e->expr_type == EXPR_VARIABLE
   6652  1.1  mrg 				     && e->symtree->n.sym->attr.optional,
   6653  1.1  mrg 				     CLASS_DATA (fsym)->attr.class_pointer
   6654  1.1  mrg 				     || CLASS_DATA (fsym)->attr.allocatable);
   6655  1.1  mrg 
   6656  1.1  mrg 		  if (fsym && (fsym->ts.type == BT_DERIVED
   6657  1.1  mrg 			       || fsym->ts.type == BT_ASSUMED)
   6658  1.1  mrg 		      && e->ts.type == BT_CLASS
   6659  1.1  mrg 		      && !CLASS_DATA (e)->attr.dimension
   6660  1.1  mrg 		      && !CLASS_DATA (e)->attr.codimension)
   6661  1.1  mrg 		    {
   6662  1.1  mrg 		      parmse.expr = gfc_class_data_get (parmse.expr);
   6663  1.1  mrg 		      /* The result is a class temporary, whose _data component
   6664  1.1  mrg 			 must be freed to avoid a memory leak.  */
   6665  1.1  mrg 		      if (e->expr_type == EXPR_FUNCTION
   6666  1.1  mrg 			  && CLASS_DATA (e)->attr.allocatable)
   6667  1.1  mrg 			{
   6668  1.1  mrg 			  tree zero;
   6669  1.1  mrg 
   6670  1.1  mrg 			  gfc_expr *var;
   6671  1.1  mrg 
   6672  1.1  mrg 			  /* Borrow the function symbol to make a call to
   6673  1.1  mrg 			     gfc_add_finalizer_call and then restore it.  */
   6674  1.1  mrg 			  tmp = e->symtree->n.sym->backend_decl;
   6675  1.1  mrg 			  e->symtree->n.sym->backend_decl
   6676  1.1  mrg 					= TREE_OPERAND (parmse.expr, 0);
   6677  1.1  mrg 			  e->symtree->n.sym->attr.flavor = FL_VARIABLE;
   6678  1.1  mrg 			  var = gfc_lval_expr_from_sym (e->symtree->n.sym);
   6679  1.1  mrg 			  finalized = gfc_add_finalizer_call (&parmse.post,
   6680  1.1  mrg 							      var);
   6681  1.1  mrg 			  gfc_free_expr (var);
   6682  1.1  mrg 			  e->symtree->n.sym->backend_decl = tmp;
   6683  1.1  mrg 			  e->symtree->n.sym->attr.flavor = FL_PROCEDURE;
   6684  1.1  mrg 
   6685  1.1  mrg 			  /* Then free the class _data.  */
   6686  1.1  mrg 			  zero = build_int_cst (TREE_TYPE (parmse.expr), 0);
   6687  1.1  mrg 			  tmp = fold_build2_loc (input_location, NE_EXPR,
   6688  1.1  mrg 						 logical_type_node,
   6689  1.1  mrg 						 parmse.expr, zero);
   6690  1.1  mrg 			  tmp = build3_v (COND_EXPR, tmp,
   6691  1.1  mrg 					  gfc_call_free (parmse.expr),
   6692  1.1  mrg 					  build_empty_stmt (input_location));
   6693  1.1  mrg 			  gfc_add_expr_to_block (&parmse.post, tmp);
   6694  1.1  mrg 			  gfc_add_modify (&parmse.post, parmse.expr, zero);
   6695  1.1  mrg 			}
   6696  1.1  mrg 		    }
   6697  1.1  mrg 
   6698  1.1  mrg 		  /* Wrap scalar variable in a descriptor. We need to convert
   6699  1.1  mrg 		     the address of a pointer back to the pointer itself before,
   6700  1.1  mrg 		     we can assign it to the data field.  */
   6701  1.1  mrg 
   6702  1.1  mrg 		  if (fsym && fsym->as && fsym->as->type == AS_ASSUMED_RANK
   6703  1.1  mrg 		      && fsym->ts.type != BT_CLASS && e->expr_type != EXPR_NULL)
   6704  1.1  mrg 		    {
   6705  1.1  mrg 		      tmp = parmse.expr;
   6706  1.1  mrg 		      if (TREE_CODE (tmp) == ADDR_EXPR)
   6707  1.1  mrg 			tmp = TREE_OPERAND (tmp, 0);
   6708  1.1  mrg 		      parmse.expr = gfc_conv_scalar_to_descriptor (&parmse, tmp,
   6709  1.1  mrg 								   fsym->attr);
   6710  1.1  mrg 		      parmse.expr = gfc_build_addr_expr (NULL_TREE,
   6711  1.1  mrg 							 parmse.expr);
   6712  1.1  mrg 		    }
   6713  1.1  mrg 		  else if (fsym && e->expr_type != EXPR_NULL
   6714  1.1  mrg 		      && ((fsym->attr.pointer
   6715  1.1  mrg 			   && fsym->attr.flavor != FL_PROCEDURE)
   6716  1.1  mrg 			  || (fsym->attr.proc_pointer
   6717  1.1  mrg 			      && !(e->expr_type == EXPR_VARIABLE
   6718  1.1  mrg 				   && e->symtree->n.sym->attr.dummy))
   6719  1.1  mrg 			  || (fsym->attr.proc_pointer
   6720  1.1  mrg 			      && e->expr_type == EXPR_VARIABLE
   6721  1.1  mrg 			      && gfc_is_proc_ptr_comp (e))
   6722  1.1  mrg 			  || (fsym->attr.allocatable
   6723  1.1  mrg 			      && fsym->attr.flavor != FL_PROCEDURE)))
   6724  1.1  mrg 		    {
   6725  1.1  mrg 		      /* Scalar pointer dummy args require an extra level of
   6726  1.1  mrg 			 indirection. The null pointer already contains
   6727  1.1  mrg 			 this level of indirection.  */
   6728  1.1  mrg 		      parm_kind = SCALAR_POINTER;
   6729  1.1  mrg 		      parmse.expr = gfc_build_addr_expr (NULL_TREE, parmse.expr);
   6730  1.1  mrg 		    }
   6731  1.1  mrg 		}
   6732  1.1  mrg 	    }
   6733  1.1  mrg 	  else if (e->ts.type == BT_CLASS
   6734  1.1  mrg 		    && fsym && fsym->ts.type == BT_CLASS
   6735  1.1  mrg 		    && (CLASS_DATA (fsym)->attr.dimension
   6736  1.1  mrg 			|| CLASS_DATA (fsym)->attr.codimension))
   6737  1.1  mrg 	    {
   6738  1.1  mrg 	      /* Pass a class array.  */
   6739  1.1  mrg 	      parmse.use_offset = 1;
   6740  1.1  mrg 	      gfc_conv_expr_descriptor (&parmse, e);
   6741  1.1  mrg 
   6742  1.1  mrg 	      /* If an ALLOCATABLE dummy argument has INTENT(OUT) and is
   6743  1.1  mrg 		 allocated on entry, it must be deallocated.  */
   6744  1.1  mrg 	      if (fsym->attr.intent == INTENT_OUT
   6745  1.1  mrg 		  && CLASS_DATA (fsym)->attr.allocatable)
   6746  1.1  mrg 		{
   6747  1.1  mrg 		  stmtblock_t block;
   6748  1.1  mrg 		  tree ptr;
   6749  1.1  mrg 
   6750  1.1  mrg 		  gfc_init_block  (&block);
   6751  1.1  mrg 		  ptr = parmse.expr;
   6752  1.1  mrg 		  ptr = gfc_class_data_get (ptr);
   6753  1.1  mrg 
   6754  1.1  mrg 		  tmp = gfc_deallocate_with_status (ptr, NULL_TREE,
   6755  1.1  mrg 						    NULL_TREE, NULL_TREE,
   6756  1.1  mrg 						    NULL_TREE, true, e,
   6757  1.1  mrg 						    GFC_CAF_COARRAY_NOCOARRAY);
   6758  1.1  mrg 		  gfc_add_expr_to_block (&block, tmp);
   6759  1.1  mrg 		  tmp = fold_build2_loc (input_location, MODIFY_EXPR,
   6760  1.1  mrg 					 void_type_node, ptr,
   6761  1.1  mrg 					 null_pointer_node);
   6762  1.1  mrg 		  gfc_add_expr_to_block (&block, tmp);
   6763  1.1  mrg 		  gfc_reset_vptr (&block, e);
   6764  1.1  mrg 
   6765  1.1  mrg 		  if (fsym->attr.optional
   6766  1.1  mrg 		      && e->expr_type == EXPR_VARIABLE
   6767  1.1  mrg 		      && (!e->ref
   6768  1.1  mrg 			  || (e->ref->type == REF_ARRAY
   6769  1.1  mrg 			      && e->ref->u.ar.type != AR_FULL))
   6770  1.1  mrg 		      && e->symtree->n.sym->attr.optional)
   6771  1.1  mrg 		    {
   6772  1.1  mrg 		      tmp = fold_build3_loc (input_location, COND_EXPR,
   6773  1.1  mrg 				    void_type_node,
   6774  1.1  mrg 				    gfc_conv_expr_present (e->symtree->n.sym),
   6775  1.1  mrg 				    gfc_finish_block (&block),
   6776  1.1  mrg 				    build_empty_stmt (input_location));
   6777  1.1  mrg 		    }
   6778  1.1  mrg 		  else
   6779  1.1  mrg 		    tmp = gfc_finish_block (&block);
   6780  1.1  mrg 
   6781  1.1  mrg 		  gfc_add_expr_to_block (&se->pre, tmp);
   6782  1.1  mrg 		}
   6783  1.1  mrg 
   6784  1.1  mrg 	      /* The conversion does not repackage the reference to a class
   6785  1.1  mrg 	         array - _data descriptor.  */
   6786  1.1  mrg 	      gfc_conv_class_to_class (&parmse, e, fsym->ts, false,
   6787  1.1  mrg 				     fsym->attr.intent != INTENT_IN
   6788  1.1  mrg 				     && (CLASS_DATA (fsym)->attr.class_pointer
   6789  1.1  mrg 					 || CLASS_DATA (fsym)->attr.allocatable),
   6790  1.1  mrg 				     fsym->attr.optional
   6791  1.1  mrg 				     && e->expr_type == EXPR_VARIABLE
   6792  1.1  mrg 				     && e->symtree->n.sym->attr.optional,
   6793  1.1  mrg 				     CLASS_DATA (fsym)->attr.class_pointer
   6794  1.1  mrg 				     || CLASS_DATA (fsym)->attr.allocatable);
   6795  1.1  mrg 	    }
   6796  1.1  mrg 	  else
   6797  1.1  mrg 	    {
   6798  1.1  mrg 	      /* If the argument is a function call that may not create
   6799  1.1  mrg 		 a temporary for the result, we have to check that we
   6800  1.1  mrg 		 can do it, i.e. that there is no alias between this
   6801  1.1  mrg 		 argument and another one.  */
   6802  1.1  mrg 	      if (gfc_get_noncopying_intrinsic_argument (e) != NULL)
   6803  1.1  mrg 		{
   6804  1.1  mrg 		  gfc_expr *iarg;
   6805  1.1  mrg 		  sym_intent intent;
   6806  1.1  mrg 
   6807  1.1  mrg 		  if (fsym != NULL)
   6808  1.1  mrg 		    intent = fsym->attr.intent;
   6809  1.1  mrg 		  else
   6810  1.1  mrg 		    intent = INTENT_UNKNOWN;
   6811  1.1  mrg 
   6812  1.1  mrg 		  if (gfc_check_fncall_dependency (e, intent, sym, args,
   6813  1.1  mrg 						   NOT_ELEMENTAL))
   6814  1.1  mrg 		    parmse.force_tmp = 1;
   6815  1.1  mrg 
   6816  1.1  mrg 		  iarg = e->value.function.actual->expr;
   6817  1.1  mrg 
   6818  1.1  mrg 		  /* Temporary needed if aliasing due to host association.  */
   6819  1.1  mrg 		  if (sym->attr.contained
   6820  1.1  mrg 			&& !sym->attr.pure
   6821  1.1  mrg 			&& !sym->attr.implicit_pure
   6822  1.1  mrg 			&& !sym->attr.use_assoc
   6823  1.1  mrg 			&& iarg->expr_type == EXPR_VARIABLE
   6824  1.1  mrg 			&& sym->ns == iarg->symtree->n.sym->ns)
   6825  1.1  mrg 		    parmse.force_tmp = 1;
   6826  1.1  mrg 
   6827  1.1  mrg 		  /* Ditto within module.  */
   6828  1.1  mrg 		  if (sym->attr.use_assoc
   6829  1.1  mrg 			&& !sym->attr.pure
   6830  1.1  mrg 			&& !sym->attr.implicit_pure
   6831  1.1  mrg 			&& iarg->expr_type == EXPR_VARIABLE
   6832  1.1  mrg 			&& sym->module == iarg->symtree->n.sym->module)
   6833  1.1  mrg 		    parmse.force_tmp = 1;
   6834  1.1  mrg 		}
   6835  1.1  mrg 
   6836  1.1  mrg 	      /* Special case for assumed-rank arrays: when passing an
   6837  1.1  mrg 		 argument to a nonallocatable/nonpointer dummy, the bounds have
   6838  1.1  mrg 		 to be reset as otherwise a last-dim ubound of -1 is
   6839  1.1  mrg 		 indistinguishable from an assumed-size array in the callee.  */
   6840  1.1  mrg 	      if (!sym->attr.is_bind_c && e && fsym && fsym->as
   6841  1.1  mrg 		  && fsym->as->type == AS_ASSUMED_RANK
   6842  1.1  mrg 		  && e->rank != -1
   6843  1.1  mrg 		  && e->expr_type == EXPR_VARIABLE
   6844  1.1  mrg 		  && ((fsym->ts.type == BT_CLASS
   6845  1.1  mrg 		       && !CLASS_DATA (fsym)->attr.class_pointer
   6846  1.1  mrg 		       && !CLASS_DATA (fsym)->attr.allocatable)
   6847  1.1  mrg 		      || (fsym->ts.type != BT_CLASS
   6848  1.1  mrg 			  && !fsym->attr.pointer && !fsym->attr.allocatable)))
   6849  1.1  mrg 		{
   6850  1.1  mrg 		  /* Change AR_FULL to a (:,:,:) ref to force bounds update. */
   6851  1.1  mrg 		  gfc_ref *ref;
   6852  1.1  mrg 		  for (ref = e->ref; ref->next; ref = ref->next)
   6853  1.1  mrg 		    ;
   6854  1.1  mrg 		  if (ref->u.ar.type == AR_FULL
   6855  1.1  mrg 		      && ref->u.ar.as->type != AS_ASSUMED_SIZE)
   6856  1.1  mrg 		    ref->u.ar.type = AR_SECTION;
   6857  1.1  mrg 		}
   6858  1.1  mrg 
   6859  1.1  mrg 	      if (sym->attr.is_bind_c && e && is_CFI_desc (fsym, NULL))
   6860  1.1  mrg 		/* Implement F2018, 18.3.6, list item (5), bullet point 2.  */
   6861  1.1  mrg 		gfc_conv_gfc_desc_to_cfi_desc (&parmse, e, fsym);
   6862  1.1  mrg 
   6863  1.1  mrg 	      else if (e->expr_type == EXPR_VARIABLE
   6864  1.1  mrg 		    && is_subref_array (e)
   6865  1.1  mrg 		    && !(fsym && fsym->attr.pointer))
   6866  1.1  mrg 		/* The actual argument is a component reference to an
   6867  1.1  mrg 		   array of derived types.  In this case, the argument
   6868  1.1  mrg 		   is converted to a temporary, which is passed and then
   6869  1.1  mrg 		   written back after the procedure call.  */
   6870  1.1  mrg 		gfc_conv_subref_array_arg (&parmse, e, nodesc_arg,
   6871  1.1  mrg 				fsym ? fsym->attr.intent : INTENT_INOUT,
   6872  1.1  mrg 				fsym && fsym->attr.pointer);
   6873  1.1  mrg 
   6874  1.1  mrg 	      else if (e->ts.type == BT_CLASS && CLASS_DATA (e)->as
   6875  1.1  mrg 		       && CLASS_DATA (e)->as->type == AS_ASSUMED_SIZE
   6876  1.1  mrg 		       && nodesc_arg && fsym->ts.type == BT_DERIVED)
   6877  1.1  mrg 		/* An assumed size class actual argument being passed to
   6878  1.1  mrg 		   a 'no descriptor' formal argument just requires the
   6879  1.1  mrg 		   data pointer to be passed. For class dummy arguments
   6880  1.1  mrg 		   this is stored in the symbol backend decl..  */
   6881  1.1  mrg 		parmse.expr = e->symtree->n.sym->backend_decl;
   6882  1.1  mrg 
   6883  1.1  mrg 	      else if (gfc_is_class_array_ref (e, NULL)
   6884  1.1  mrg 		       && fsym && fsym->ts.type == BT_DERIVED)
   6885  1.1  mrg 		/* The actual argument is a component reference to an
   6886  1.1  mrg 		   array of derived types.  In this case, the argument
   6887  1.1  mrg 		   is converted to a temporary, which is passed and then
   6888  1.1  mrg 		   written back after the procedure call.
   6889  1.1  mrg 		   OOP-TODO: Insert code so that if the dynamic type is
   6890  1.1  mrg 		   the same as the declared type, copy-in/copy-out does
   6891  1.1  mrg 		   not occur.  */
   6892  1.1  mrg 		gfc_conv_subref_array_arg (&parmse, e, nodesc_arg,
   6893  1.1  mrg 					   fsym->attr.intent,
   6894  1.1  mrg 					   fsym->attr.pointer);
   6895  1.1  mrg 
   6896  1.1  mrg 	      else if (gfc_is_class_array_function (e)
   6897  1.1  mrg 		       && fsym && fsym->ts.type == BT_DERIVED)
   6898  1.1  mrg 		/* See previous comment.  For function actual argument,
   6899  1.1  mrg 		   the write out is not needed so the intent is set as
   6900  1.1  mrg 		   intent in.  */
   6901  1.1  mrg 		{
   6902  1.1  mrg 		  e->must_finalize = 1;
   6903  1.1  mrg 		  gfc_conv_subref_array_arg (&parmse, e, nodesc_arg,
   6904  1.1  mrg 					     INTENT_IN, fsym->attr.pointer);
   6905  1.1  mrg 		}
   6906  1.1  mrg 	      else if (fsym && fsym->attr.contiguous
   6907  1.1  mrg 		       && !gfc_is_simply_contiguous (e, false, true)
   6908  1.1  mrg 		       && gfc_expr_is_variable (e))
   6909  1.1  mrg 		{
   6910  1.1  mrg 		  gfc_conv_subref_array_arg (&parmse, e, nodesc_arg,
   6911  1.1  mrg 					     fsym->attr.intent,
   6912  1.1  mrg 					     fsym->attr.pointer);
   6913  1.1  mrg 		}
   6914  1.1  mrg 	      else
   6915  1.1  mrg 		/* This is where we introduce a temporary to store the
   6916  1.1  mrg 		   result of a non-lvalue array expression.  */
   6917  1.1  mrg 		gfc_conv_array_parameter (&parmse, e, nodesc_arg, fsym,
   6918  1.1  mrg 					  sym->name, NULL);
   6919  1.1  mrg 
   6920  1.1  mrg 	      /* If an ALLOCATABLE dummy argument has INTENT(OUT) and is
   6921  1.1  mrg 		 allocated on entry, it must be deallocated.
   6922  1.1  mrg 		 CFI descriptors are handled elsewhere.  */
   6923  1.1  mrg 	      if (fsym && fsym->attr.allocatable
   6924  1.1  mrg 		  && fsym->attr.intent == INTENT_OUT
   6925  1.1  mrg 		  && !is_CFI_desc (fsym, NULL))
   6926  1.1  mrg 		{
   6927  1.1  mrg 		  if (fsym->ts.type == BT_DERIVED
   6928  1.1  mrg 		      && fsym->ts.u.derived->attr.alloc_comp)
   6929  1.1  mrg 		  {
   6930  1.1  mrg 		    // deallocate the components first
   6931  1.1  mrg 		    tmp = gfc_deallocate_alloc_comp (fsym->ts.u.derived,
   6932  1.1  mrg 						     parmse.expr, e->rank);
   6933  1.1  mrg 		    /* But check whether dummy argument is optional.  */
   6934  1.1  mrg 		    if (tmp != NULL_TREE
   6935  1.1  mrg 			&& fsym->attr.optional
   6936  1.1  mrg 			&& e->expr_type == EXPR_VARIABLE
   6937  1.1  mrg 			&& e->symtree->n.sym->attr.optional)
   6938  1.1  mrg 		      {
   6939  1.1  mrg 			tree present;
   6940  1.1  mrg 			present = gfc_conv_expr_present (e->symtree->n.sym);
   6941  1.1  mrg 			tmp = build3_v (COND_EXPR, present, tmp,
   6942  1.1  mrg 					build_empty_stmt (input_location));
   6943  1.1  mrg 		      }
   6944  1.1  mrg 		    if (tmp != NULL_TREE)
   6945  1.1  mrg 		      gfc_add_expr_to_block (&se->pre, tmp);
   6946  1.1  mrg 		  }
   6947  1.1  mrg 
   6948  1.1  mrg 		  tmp = parmse.expr;
   6949  1.1  mrg 		  /* With bind(C), the actual argument is replaced by a bind-C
   6950  1.1  mrg 		     descriptor; in this case, the data component arrives here,
   6951  1.1  mrg 		     which shall not be dereferenced, but still freed and
   6952  1.1  mrg 		     nullified.  */
   6953  1.1  mrg 		  if  (TREE_TYPE(tmp) != pvoid_type_node)
   6954  1.1  mrg 		    tmp = build_fold_indirect_ref_loc (input_location,
   6955  1.1  mrg 						       parmse.expr);
   6956  1.1  mrg 		  if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp)))
   6957  1.1  mrg 		    tmp = gfc_conv_descriptor_data_get (tmp);
   6958  1.1  mrg 		  tmp = gfc_deallocate_with_status (tmp, NULL_TREE, NULL_TREE,
   6959  1.1  mrg 						    NULL_TREE, NULL_TREE, true,
   6960  1.1  mrg 						    e,
   6961  1.1  mrg 						    GFC_CAF_COARRAY_NOCOARRAY);
   6962  1.1  mrg 		  if (fsym->attr.optional
   6963  1.1  mrg 		      && e->expr_type == EXPR_VARIABLE
   6964  1.1  mrg 		      && e->symtree->n.sym->attr.optional)
   6965  1.1  mrg 		    tmp = fold_build3_loc (input_location, COND_EXPR,
   6966  1.1  mrg 				     void_type_node,
   6967  1.1  mrg 				     gfc_conv_expr_present (e->symtree->n.sym),
   6968  1.1  mrg 				       tmp, build_empty_stmt (input_location));
   6969  1.1  mrg 		  gfc_add_expr_to_block (&se->pre, tmp);
   6970  1.1  mrg 		}
   6971  1.1  mrg 	    }
   6972  1.1  mrg 	}
   6973  1.1  mrg       /* Special case for an assumed-rank dummy argument. */
   6974  1.1  mrg       if (!sym->attr.is_bind_c && e && fsym && e->rank > 0
   6975  1.1  mrg 	  && (fsym->ts.type == BT_CLASS
   6976  1.1  mrg 	      ? (CLASS_DATA (fsym)->as
   6977  1.1  mrg 		 && CLASS_DATA (fsym)->as->type == AS_ASSUMED_RANK)
   6978  1.1  mrg 	      : (fsym->as && fsym->as->type == AS_ASSUMED_RANK)))
   6979  1.1  mrg 	{
   6980  1.1  mrg 	  if (fsym->ts.type == BT_CLASS
   6981  1.1  mrg 	      ? (CLASS_DATA (fsym)->attr.class_pointer
   6982  1.1  mrg 		 || CLASS_DATA (fsym)->attr.allocatable)
   6983  1.1  mrg 	      : (fsym->attr.pointer || fsym->attr.allocatable))
   6984  1.1  mrg 	    {
   6985  1.1  mrg 	      /* Unallocated allocatable arrays and unassociated pointer
   6986  1.1  mrg 		 arrays need their dtype setting if they are argument
   6987  1.1  mrg 		 associated with assumed rank dummies to set the rank.  */
   6988  1.1  mrg 	      set_dtype_for_unallocated (&parmse, e);
   6989  1.1  mrg 	    }
   6990  1.1  mrg 	  else if (e->expr_type == EXPR_VARIABLE
   6991  1.1  mrg 		   && e->symtree->n.sym->attr.dummy
   6992  1.1  mrg 		   && (e->ts.type == BT_CLASS
   6993  1.1  mrg 		       ? (e->ref && e->ref->next
   6994  1.1  mrg 			  && e->ref->next->type == REF_ARRAY
   6995  1.1  mrg 			  && e->ref->next->u.ar.type == AR_FULL
   6996  1.1  mrg 			  && e->ref->next->u.ar.as->type == AS_ASSUMED_SIZE)
   6997  1.1  mrg 		       : (e->ref && e->ref->type == REF_ARRAY
   6998  1.1  mrg 			  && e->ref->u.ar.type == AR_FULL
   6999  1.1  mrg 			  && e->ref->u.ar.as->type == AS_ASSUMED_SIZE)))
   7000  1.1  mrg 	    {
   7001  1.1  mrg 	      /* Assumed-size actual to assumed-rank dummy requires
   7002  1.1  mrg 		 dim[rank-1].ubound = -1. */
   7003  1.1  mrg 	      tree minus_one;
   7004  1.1  mrg 	      tmp = build_fold_indirect_ref_loc (input_location, parmse.expr);
   7005  1.1  mrg 	      if (fsym->ts.type == BT_CLASS)
   7006  1.1  mrg 		tmp = gfc_class_data_get (tmp);
   7007  1.1  mrg 	      minus_one = build_int_cst (gfc_array_index_type, -1);
   7008  1.1  mrg 	      gfc_conv_descriptor_ubound_set (&parmse.pre, tmp,
   7009  1.1  mrg 					      gfc_rank_cst[e->rank - 1],
   7010  1.1  mrg 					      minus_one);
   7011  1.1  mrg 	    }
   7012  1.1  mrg 	}
   7013  1.1  mrg 
   7014  1.1  mrg       /* The case with fsym->attr.optional is that of a user subroutine
   7015  1.1  mrg 	 with an interface indicating an optional argument.  When we call
   7016  1.1  mrg 	 an intrinsic subroutine, however, fsym is NULL, but we might still
   7017  1.1  mrg 	 have an optional argument, so we proceed to the substitution
   7018  1.1  mrg 	 just in case.  */
   7019  1.1  mrg       if (e && (fsym == NULL || fsym->attr.optional))
   7020  1.1  mrg 	{
   7021  1.1  mrg 	  /* If an optional argument is itself an optional dummy argument,
   7022  1.1  mrg 	     check its presence and substitute a null if absent.  This is
   7023  1.1  mrg 	     only needed when passing an array to an elemental procedure
   7024  1.1  mrg 	     as then array elements are accessed - or no NULL pointer is
   7025  1.1  mrg 	     allowed and a "1" or "0" should be passed if not present.
   7026  1.1  mrg 	     When passing a non-array-descriptor full array to a
   7027  1.1  mrg 	     non-array-descriptor dummy, no check is needed. For
   7028  1.1  mrg 	     array-descriptor actual to array-descriptor dummy, see
   7029  1.1  mrg 	     PR 41911 for why a check has to be inserted.
   7030  1.1  mrg 	     fsym == NULL is checked as intrinsics required the descriptor
   7031  1.1  mrg 	     but do not always set fsym.
   7032  1.1  mrg 	     Also, it is necessary to pass a NULL pointer to library routines
   7033  1.1  mrg 	     which usually ignore optional arguments, so they can handle
   7034  1.1  mrg 	     these themselves.  */
   7035  1.1  mrg 	  if (e->expr_type == EXPR_VARIABLE
   7036  1.1  mrg 	      && e->symtree->n.sym->attr.optional
   7037  1.1  mrg 	      && (((e->rank != 0 && elemental_proc)
   7038  1.1  mrg 		   || e->representation.length || e->ts.type == BT_CHARACTER
   7039  1.1  mrg 		   || (e->rank != 0
   7040  1.1  mrg 		       && (fsym == NULL
   7041  1.1  mrg 			   || (fsym->as
   7042  1.1  mrg 			       && (fsym->as->type == AS_ASSUMED_SHAPE
   7043  1.1  mrg 				   || fsym->as->type == AS_ASSUMED_RANK
   7044  1.1  mrg 				   || fsym->as->type == AS_DEFERRED)))))
   7045  1.1  mrg 		  || se->ignore_optional))
   7046  1.1  mrg 	    gfc_conv_missing_dummy (&parmse, e, fsym ? fsym->ts : e->ts,
   7047  1.1  mrg 				    e->representation.length);
   7048  1.1  mrg 	}
   7049  1.1  mrg 
   7050  1.1  mrg       if (fsym && e)
   7051  1.1  mrg 	{
   7052  1.1  mrg 	  /* Obtain the character length of an assumed character length
   7053  1.1  mrg 	     length procedure from the typespec.  */
   7054  1.1  mrg 	  if (fsym->ts.type == BT_CHARACTER
   7055  1.1  mrg 	      && parmse.string_length == NULL_TREE
   7056  1.1  mrg 	      && e->ts.type == BT_PROCEDURE
   7057  1.1  mrg 	      && e->symtree->n.sym->ts.type == BT_CHARACTER
   7058  1.1  mrg 	      && e->symtree->n.sym->ts.u.cl->length != NULL
   7059  1.1  mrg 	      && e->symtree->n.sym->ts.u.cl->length->expr_type == EXPR_CONSTANT)
   7060  1.1  mrg 	    {
   7061  1.1  mrg 	      gfc_conv_const_charlen (e->symtree->n.sym->ts.u.cl);
   7062  1.1  mrg 	      parmse.string_length = e->symtree->n.sym->ts.u.cl->backend_decl;
   7063  1.1  mrg 	    }
   7064  1.1  mrg 	}
   7065  1.1  mrg 
   7066  1.1  mrg       if (fsym && need_interface_mapping && e)
   7067  1.1  mrg 	gfc_add_interface_mapping (&mapping, fsym, &parmse, e);
   7068  1.1  mrg 
   7069  1.1  mrg       gfc_add_block_to_block (&se->pre, &parmse.pre);
   7070  1.1  mrg       gfc_add_block_to_block (&post, &parmse.post);
   7071  1.1  mrg 
   7072  1.1  mrg       /* Allocated allocatable components of derived types must be
   7073  1.1  mrg 	 deallocated for non-variable scalars, array arguments to elemental
   7074  1.1  mrg 	 procedures, and array arguments with descriptor to non-elemental
   7075  1.1  mrg 	 procedures.  As bounds information for descriptorless arrays is no
   7076  1.1  mrg 	 longer available here, they are dealt with in trans-array.cc
   7077  1.1  mrg 	 (gfc_conv_array_parameter).  */
   7078  1.1  mrg       if (e && (e->ts.type == BT_DERIVED || e->ts.type == BT_CLASS)
   7079  1.1  mrg 	    && e->ts.u.derived->attr.alloc_comp
   7080  1.1  mrg 	    && (e->rank == 0 || elemental_proc || !nodesc_arg)
   7081  1.1  mrg 	    && !expr_may_alias_variables (e, elemental_proc))
   7082  1.1  mrg 	{
   7083  1.1  mrg 	  int parm_rank;
   7084  1.1  mrg 	  /* It is known the e returns a structure type with at least one
   7085  1.1  mrg 	     allocatable component.  When e is a function, ensure that the
   7086  1.1  mrg 	     function is called once only by using a temporary variable.  */
   7087  1.1  mrg 	  if (!DECL_P (parmse.expr))
   7088  1.1  mrg 	    parmse.expr = gfc_evaluate_now_loc (input_location,
   7089  1.1  mrg 						parmse.expr, &se->pre);
   7090  1.1  mrg 
   7091  1.1  mrg 	  if (fsym && fsym->attr.value)
   7092  1.1  mrg 	    tmp = parmse.expr;
   7093  1.1  mrg 	  else
   7094  1.1  mrg 	    tmp = build_fold_indirect_ref_loc (input_location,
   7095  1.1  mrg 					       parmse.expr);
   7096  1.1  mrg 
   7097  1.1  mrg 	  parm_rank = e->rank;
   7098  1.1  mrg 	  switch (parm_kind)
   7099  1.1  mrg 	    {
   7100  1.1  mrg 	    case (ELEMENTAL):
   7101  1.1  mrg 	    case (SCALAR):
   7102  1.1  mrg 	      parm_rank = 0;
   7103  1.1  mrg 	      break;
   7104  1.1  mrg 
   7105  1.1  mrg 	    case (SCALAR_POINTER):
   7106  1.1  mrg               tmp = build_fold_indirect_ref_loc (input_location,
   7107  1.1  mrg 					     tmp);
   7108  1.1  mrg 	      break;
   7109  1.1  mrg 	    }
   7110  1.1  mrg 
   7111  1.1  mrg 	  if (e->ts.type == BT_DERIVED && fsym && fsym->ts.type == BT_CLASS)
   7112  1.1  mrg 	    {
   7113  1.1  mrg 	      /* The derived type is passed to gfc_deallocate_alloc_comp.
   7114  1.1  mrg 		 Therefore, class actuals can be handled correctly but derived
   7115  1.1  mrg 		 types passed to class formals need the _data component.  */
   7116  1.1  mrg 	      tmp = gfc_class_data_get (tmp);
   7117  1.1  mrg 	      if (!CLASS_DATA (fsym)->attr.dimension)
   7118  1.1  mrg 		tmp = build_fold_indirect_ref_loc (input_location, tmp);
   7119  1.1  mrg 	    }
   7120  1.1  mrg 
   7121  1.1  mrg 	  if (e->expr_type == EXPR_OP
   7122  1.1  mrg 		&& e->value.op.op == INTRINSIC_PARENTHESES
   7123  1.1  mrg 		&& e->value.op.op1->expr_type == EXPR_VARIABLE)
   7124  1.1  mrg 	    {
   7125  1.1  mrg 	      tree local_tmp;
   7126  1.1  mrg 	      local_tmp = gfc_evaluate_now (tmp, &se->pre);
   7127  1.1  mrg 	      local_tmp = gfc_copy_alloc_comp (e->ts.u.derived, local_tmp, tmp,
   7128  1.1  mrg 					       parm_rank, 0);
   7129  1.1  mrg 	      gfc_add_expr_to_block (&se->post, local_tmp);
   7130  1.1  mrg 	    }
   7131  1.1  mrg 
   7132  1.1  mrg 	  if (!finalized && !e->must_finalize)
   7133  1.1  mrg 	    {
   7134  1.1  mrg 	      bool scalar_res_outside_loop;
   7135  1.1  mrg 	      scalar_res_outside_loop = e->expr_type == EXPR_FUNCTION
   7136  1.1  mrg 					&& parm_rank == 0
   7137  1.1  mrg 					&& parmse.loop;
   7138  1.1  mrg 
   7139  1.1  mrg 	      /* Scalars passed to an assumed rank argument are converted to
   7140  1.1  mrg 		 a descriptor. Obtain the data field before deallocating any
   7141  1.1  mrg 		 allocatable components.  */
   7142  1.1  mrg 	      if (parm_rank == 0 && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp)))
   7143  1.1  mrg 		tmp = gfc_conv_descriptor_data_get (tmp);
   7144  1.1  mrg 
   7145  1.1  mrg 	      if (scalar_res_outside_loop)
   7146  1.1  mrg 		{
   7147  1.1  mrg 		  /* Go through the ss chain to find the argument and use
   7148  1.1  mrg 		     the stored value.  */
   7149  1.1  mrg 		  gfc_ss *tmp_ss = parmse.loop->ss;
   7150  1.1  mrg 		  for (; tmp_ss; tmp_ss = tmp_ss->next)
   7151  1.1  mrg 		    if (tmp_ss->info
   7152  1.1  mrg 			&& tmp_ss->info->expr == e
   7153  1.1  mrg 			&& tmp_ss->info->data.scalar.value != NULL_TREE)
   7154  1.1  mrg 		      {
   7155  1.1  mrg 			tmp = tmp_ss->info->data.scalar.value;
   7156  1.1  mrg 			break;
   7157  1.1  mrg 		      }
   7158  1.1  mrg 		}
   7159  1.1  mrg 
   7160  1.1  mrg 	      STRIP_NOPS (tmp);
   7161  1.1  mrg 
   7162  1.1  mrg 	      if (derived_array != NULL_TREE)
   7163  1.1  mrg 		tmp = gfc_deallocate_alloc_comp (e->ts.u.derived,
   7164  1.1  mrg 						 derived_array,
   7165  1.1  mrg 						 parm_rank);
   7166  1.1  mrg 	      else if ((e->ts.type == BT_CLASS
   7167  1.1  mrg 			&& GFC_CLASS_TYPE_P (TREE_TYPE (tmp)))
   7168  1.1  mrg 		       || e->ts.type == BT_DERIVED)
   7169  1.1  mrg 		tmp = gfc_deallocate_alloc_comp (e->ts.u.derived, tmp,
   7170  1.1  mrg 						 parm_rank);
   7171  1.1  mrg 	      else if (e->ts.type == BT_CLASS)
   7172  1.1  mrg 		tmp = gfc_deallocate_alloc_comp (CLASS_DATA (e)->ts.u.derived,
   7173  1.1  mrg 						 tmp, parm_rank);
   7174  1.1  mrg 
   7175  1.1  mrg 	      if (scalar_res_outside_loop)
   7176  1.1  mrg 		gfc_add_expr_to_block (&parmse.loop->post, tmp);
   7177  1.1  mrg 	      else
   7178  1.1  mrg 		gfc_prepend_expr_to_block (&post, tmp);
   7179  1.1  mrg 	    }
   7180  1.1  mrg         }
   7181  1.1  mrg 
   7182  1.1  mrg       /* Add argument checking of passing an unallocated/NULL actual to
   7183  1.1  mrg          a nonallocatable/nonpointer dummy.  */
   7184  1.1  mrg 
   7185  1.1  mrg       if (gfc_option.rtcheck & GFC_RTCHECK_POINTER && e != NULL)
   7186  1.1  mrg         {
   7187  1.1  mrg 	  symbol_attribute attr;
   7188  1.1  mrg 	  char *msg;
   7189  1.1  mrg 	  tree cond;
   7190  1.1  mrg 	  tree tmp;
   7191  1.1  mrg 	  symbol_attribute fsym_attr;
   7192  1.1  mrg 
   7193  1.1  mrg 	  if (fsym)
   7194  1.1  mrg 	    {
   7195  1.1  mrg 	      if (fsym->ts.type == BT_CLASS)
   7196  1.1  mrg 		{
   7197  1.1  mrg 		  fsym_attr = CLASS_DATA (fsym)->attr;
   7198  1.1  mrg 		  fsym_attr.pointer = fsym_attr.class_pointer;
   7199  1.1  mrg 		}
   7200  1.1  mrg 	      else
   7201  1.1  mrg 		fsym_attr = fsym->attr;
   7202  1.1  mrg 	    }
   7203  1.1  mrg 
   7204  1.1  mrg 	  if (e->expr_type == EXPR_VARIABLE || e->expr_type == EXPR_FUNCTION)
   7205  1.1  mrg 	    attr = gfc_expr_attr (e);
   7206  1.1  mrg 	  else
   7207  1.1  mrg 	    goto end_pointer_check;
   7208  1.1  mrg 
   7209  1.1  mrg 	  /*  In Fortran 2008 it's allowed to pass a NULL pointer/nonallocated
   7210  1.1  mrg 	      allocatable to an optional dummy, cf. 12.5.2.12.  */
   7211  1.1  mrg 	  if (fsym != NULL && fsym->attr.optional && !attr.proc_pointer
   7212  1.1  mrg 	      && (gfc_option.allow_std & GFC_STD_F2008) != 0)
   7213  1.1  mrg 	    goto end_pointer_check;
   7214  1.1  mrg 
   7215  1.1  mrg           if (attr.optional)
   7216  1.1  mrg 	    {
   7217  1.1  mrg               /* If the actual argument is an optional pointer/allocatable and
   7218  1.1  mrg 		 the formal argument takes an nonpointer optional value,
   7219  1.1  mrg 		 it is invalid to pass a non-present argument on, even
   7220  1.1  mrg 		 though there is no technical reason for this in gfortran.
   7221  1.1  mrg 		 See Fortran 2003, Section 12.4.1.6 item (7)+(8).  */
   7222  1.1  mrg 	      tree present, null_ptr, type;
   7223  1.1  mrg 
   7224  1.1  mrg 	      if (attr.allocatable
   7225  1.1  mrg 		  && (fsym == NULL || !fsym_attr.allocatable))
   7226  1.1  mrg 		msg = xasprintf ("Allocatable actual argument '%s' is not "
   7227  1.1  mrg 				 "allocated or not present",
   7228  1.1  mrg 				 e->symtree->n.sym->name);
   7229  1.1  mrg 	      else if (attr.pointer
   7230  1.1  mrg 		       && (fsym == NULL || !fsym_attr.pointer))
   7231  1.1  mrg 		msg = xasprintf ("Pointer actual argument '%s' is not "
   7232  1.1  mrg 				 "associated or not present",
   7233  1.1  mrg 				 e->symtree->n.sym->name);
   7234  1.1  mrg 	      else if (attr.proc_pointer && !e->value.function.actual
   7235  1.1  mrg 		       && (fsym == NULL || !fsym_attr.proc_pointer))
   7236  1.1  mrg 		msg = xasprintf ("Proc-pointer actual argument '%s' is not "
   7237  1.1  mrg 				 "associated or not present",
   7238  1.1  mrg 				 e->symtree->n.sym->name);
   7239  1.1  mrg 	      else
   7240  1.1  mrg 		goto end_pointer_check;
   7241  1.1  mrg 
   7242  1.1  mrg 	      present = gfc_conv_expr_present (e->symtree->n.sym);
   7243  1.1  mrg 	      type = TREE_TYPE (present);
   7244  1.1  mrg 	      present = fold_build2_loc (input_location, EQ_EXPR,
   7245  1.1  mrg 					 logical_type_node, present,
   7246  1.1  mrg 					 fold_convert (type,
   7247  1.1  mrg 						       null_pointer_node));
   7248  1.1  mrg 	      type = TREE_TYPE (parmse.expr);
   7249  1.1  mrg 	      null_ptr = fold_build2_loc (input_location, EQ_EXPR,
   7250  1.1  mrg 					  logical_type_node, parmse.expr,
   7251  1.1  mrg 					  fold_convert (type,
   7252  1.1  mrg 							null_pointer_node));
   7253  1.1  mrg 	      cond = fold_build2_loc (input_location, TRUTH_ORIF_EXPR,
   7254  1.1  mrg 				      logical_type_node, present, null_ptr);
   7255  1.1  mrg 	    }
   7256  1.1  mrg           else
   7257  1.1  mrg 	    {
   7258  1.1  mrg 	      if (attr.allocatable
   7259  1.1  mrg 		  && (fsym == NULL || !fsym_attr.allocatable))
   7260  1.1  mrg 		msg = xasprintf ("Allocatable actual argument '%s' is not "
   7261  1.1  mrg 				 "allocated", e->symtree->n.sym->name);
   7262  1.1  mrg 	      else if (attr.pointer
   7263  1.1  mrg 		       && (fsym == NULL || !fsym_attr.pointer))
   7264  1.1  mrg 		msg = xasprintf ("Pointer actual argument '%s' is not "
   7265  1.1  mrg 				 "associated", e->symtree->n.sym->name);
   7266  1.1  mrg 	      else if (attr.proc_pointer && !e->value.function.actual
   7267  1.1  mrg 		       && (fsym == NULL || !fsym_attr.proc_pointer))
   7268  1.1  mrg 		msg = xasprintf ("Proc-pointer actual argument '%s' is not "
   7269  1.1  mrg 				 "associated", e->symtree->n.sym->name);
   7270  1.1  mrg 	      else
   7271  1.1  mrg 		goto end_pointer_check;
   7272  1.1  mrg 
   7273  1.1  mrg 	      tmp = parmse.expr;
   7274  1.1  mrg 	      if (fsym && fsym->ts.type == BT_CLASS)
   7275  1.1  mrg 		{
   7276  1.1  mrg 		  if (POINTER_TYPE_P (TREE_TYPE (tmp)))
   7277  1.1  mrg 		    tmp = build_fold_indirect_ref_loc (input_location, tmp);
   7278  1.1  mrg 		  tmp = gfc_class_data_get (tmp);
   7279  1.1  mrg 		  if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp)))
   7280  1.1  mrg 		    tmp = gfc_conv_descriptor_data_get (tmp);
   7281  1.1  mrg 		}
   7282  1.1  mrg 
   7283  1.1  mrg 	      /* If the argument is passed by value, we need to strip the
   7284  1.1  mrg 		 INDIRECT_REF.  */
   7285  1.1  mrg 	      if (!POINTER_TYPE_P (TREE_TYPE (tmp)))
   7286  1.1  mrg 		tmp = gfc_build_addr_expr (NULL_TREE, tmp);
   7287  1.1  mrg 
   7288  1.1  mrg 	      cond = fold_build2_loc (input_location, EQ_EXPR,
   7289  1.1  mrg 				      logical_type_node, tmp,
   7290  1.1  mrg 				      fold_convert (TREE_TYPE (tmp),
   7291  1.1  mrg 						    null_pointer_node));
   7292  1.1  mrg 	    }
   7293  1.1  mrg 
   7294  1.1  mrg 	  gfc_trans_runtime_check (true, false, cond, &se->pre, &e->where,
   7295  1.1  mrg 				   msg);
   7296  1.1  mrg 	  free (msg);
   7297  1.1  mrg         }
   7298  1.1  mrg       end_pointer_check:
   7299  1.1  mrg 
   7300  1.1  mrg       /* Deferred length dummies pass the character length by reference
   7301  1.1  mrg 	 so that the value can be returned.  */
   7302  1.1  mrg       if (parmse.string_length && fsym && fsym->ts.deferred)
   7303  1.1  mrg 	{
   7304  1.1  mrg 	  if (INDIRECT_REF_P (parmse.string_length))
   7305  1.1  mrg 	    /* In chains of functions/procedure calls the string_length already
   7306  1.1  mrg 	       is a pointer to the variable holding the length.  Therefore
   7307  1.1  mrg 	       remove the deref on call.  */
   7308  1.1  mrg 	    parmse.string_length = TREE_OPERAND (parmse.string_length, 0);
   7309  1.1  mrg 	  else
   7310  1.1  mrg 	    {
   7311  1.1  mrg 	      tmp = parmse.string_length;
   7312  1.1  mrg 	      if (!VAR_P (tmp) && TREE_CODE (tmp) != COMPONENT_REF)
   7313  1.1  mrg 		tmp = gfc_evaluate_now (parmse.string_length, &se->pre);
   7314  1.1  mrg 	      parmse.string_length = gfc_build_addr_expr (NULL_TREE, tmp);
   7315  1.1  mrg 	    }
   7316  1.1  mrg 	}
   7317  1.1  mrg 
   7318  1.1  mrg       /* Character strings are passed as two parameters, a length and a
   7319  1.1  mrg 	 pointer - except for Bind(c) which only passes the pointer.
   7320  1.1  mrg 	 An unlimited polymorphic formal argument likewise does not
   7321  1.1  mrg 	 need the length.  */
   7322  1.1  mrg       if (parmse.string_length != NULL_TREE
   7323  1.1  mrg 	  && !sym->attr.is_bind_c
   7324  1.1  mrg 	  && !(fsym && UNLIMITED_POLY (fsym)))
   7325  1.1  mrg 	vec_safe_push (stringargs, parmse.string_length);
   7326  1.1  mrg 
   7327  1.1  mrg       /* When calling __copy for character expressions to unlimited
   7328  1.1  mrg 	 polymorphic entities, the dst argument needs a string length.  */
   7329  1.1  mrg       if (sym->name[0] == '_' && e && e->ts.type == BT_CHARACTER
   7330  1.1  mrg 	  && startswith (sym->name, "__vtab_CHARACTER")
   7331  1.1  mrg 	  && arg->next && arg->next->expr
   7332  1.1  mrg 	  && (arg->next->expr->ts.type == BT_DERIVED
   7333  1.1  mrg 	      || arg->next->expr->ts.type == BT_CLASS)
   7334  1.1  mrg 	  && arg->next->expr->ts.u.derived->attr.unlimited_polymorphic)
   7335  1.1  mrg 	vec_safe_push (stringargs, parmse.string_length);
   7336  1.1  mrg 
   7337  1.1  mrg       /* For descriptorless coarrays and assumed-shape coarray dummies, we
   7338  1.1  mrg 	 pass the token and the offset as additional arguments.  */
   7339  1.1  mrg       if (fsym && e == NULL && flag_coarray == GFC_FCOARRAY_LIB
   7340  1.1  mrg 	  && ((fsym->ts.type != BT_CLASS && fsym->attr.codimension
   7341  1.1  mrg 	       && !fsym->attr.allocatable)
   7342  1.1  mrg 	      || (fsym->ts.type == BT_CLASS
   7343  1.1  mrg 		  && CLASS_DATA (fsym)->attr.codimension
   7344  1.1  mrg 		  && !CLASS_DATA (fsym)->attr.allocatable)))
   7345  1.1  mrg 	{
   7346  1.1  mrg 	  /* Token and offset.  */
   7347  1.1  mrg 	  vec_safe_push (stringargs, null_pointer_node);
   7348  1.1  mrg 	  vec_safe_push (stringargs, build_int_cst (gfc_array_index_type, 0));
   7349  1.1  mrg 	  gcc_assert (fsym->attr.optional);
   7350  1.1  mrg 	}
   7351  1.1  mrg       else if (fsym && flag_coarray == GFC_FCOARRAY_LIB
   7352  1.1  mrg 	       && ((fsym->ts.type != BT_CLASS && fsym->attr.codimension
   7353  1.1  mrg 		    && !fsym->attr.allocatable)
   7354  1.1  mrg 		   || (fsym->ts.type == BT_CLASS
   7355  1.1  mrg 		       && CLASS_DATA (fsym)->attr.codimension
   7356  1.1  mrg 		       && !CLASS_DATA (fsym)->attr.allocatable)))
   7357  1.1  mrg 	{
   7358  1.1  mrg 	  tree caf_decl, caf_type;
   7359  1.1  mrg 	  tree offset, tmp2;
   7360  1.1  mrg 
   7361  1.1  mrg 	  caf_decl = gfc_get_tree_for_caf_expr (e);
   7362  1.1  mrg 	  caf_type = TREE_TYPE (caf_decl);
   7363  1.1  mrg 
   7364  1.1  mrg 	  if (GFC_DESCRIPTOR_TYPE_P (caf_type)
   7365  1.1  mrg 	      && (GFC_TYPE_ARRAY_AKIND (caf_type) == GFC_ARRAY_ALLOCATABLE
   7366  1.1  mrg 		  || GFC_TYPE_ARRAY_AKIND (caf_type) == GFC_ARRAY_POINTER))
   7367  1.1  mrg 	    tmp = gfc_conv_descriptor_token (caf_decl);
   7368  1.1  mrg 	  else if (DECL_LANG_SPECIFIC (caf_decl)
   7369  1.1  mrg 		   && GFC_DECL_TOKEN (caf_decl) != NULL_TREE)
   7370  1.1  mrg 	    tmp = GFC_DECL_TOKEN (caf_decl);
   7371  1.1  mrg 	  else
   7372  1.1  mrg 	    {
   7373  1.1  mrg 	      gcc_assert (GFC_ARRAY_TYPE_P (caf_type)
   7374  1.1  mrg 			  && GFC_TYPE_ARRAY_CAF_TOKEN (caf_type) != NULL_TREE);
   7375  1.1  mrg 	      tmp = GFC_TYPE_ARRAY_CAF_TOKEN (caf_type);
   7376  1.1  mrg 	    }
   7377  1.1  mrg 
   7378  1.1  mrg 	  vec_safe_push (stringargs, tmp);
   7379  1.1  mrg 
   7380  1.1  mrg 	  if (GFC_DESCRIPTOR_TYPE_P (caf_type)
   7381  1.1  mrg 	      && GFC_TYPE_ARRAY_AKIND (caf_type) == GFC_ARRAY_ALLOCATABLE)
   7382  1.1  mrg 	    offset = build_int_cst (gfc_array_index_type, 0);
   7383  1.1  mrg 	  else if (DECL_LANG_SPECIFIC (caf_decl)
   7384  1.1  mrg 		   && GFC_DECL_CAF_OFFSET (caf_decl) != NULL_TREE)
   7385  1.1  mrg 	    offset = GFC_DECL_CAF_OFFSET (caf_decl);
   7386  1.1  mrg 	  else if (GFC_TYPE_ARRAY_CAF_OFFSET (caf_type) != NULL_TREE)
   7387  1.1  mrg 	    offset = GFC_TYPE_ARRAY_CAF_OFFSET (caf_type);
   7388  1.1  mrg 	  else
   7389  1.1  mrg 	    offset = build_int_cst (gfc_array_index_type, 0);
   7390  1.1  mrg 
   7391  1.1  mrg 	  if (GFC_DESCRIPTOR_TYPE_P (caf_type))
   7392  1.1  mrg 	    tmp = gfc_conv_descriptor_data_get (caf_decl);
   7393  1.1  mrg 	  else
   7394  1.1  mrg 	    {
   7395  1.1  mrg 	      gcc_assert (POINTER_TYPE_P (caf_type));
   7396  1.1  mrg 	      tmp = caf_decl;
   7397  1.1  mrg 	    }
   7398  1.1  mrg 
   7399  1.1  mrg           tmp2 = fsym->ts.type == BT_CLASS
   7400  1.1  mrg 		 ? gfc_class_data_get (parmse.expr) : parmse.expr;
   7401  1.1  mrg           if ((fsym->ts.type != BT_CLASS
   7402  1.1  mrg 	       && (fsym->as->type == AS_ASSUMED_SHAPE
   7403  1.1  mrg 		   || fsym->as->type == AS_ASSUMED_RANK))
   7404  1.1  mrg 	      || (fsym->ts.type == BT_CLASS
   7405  1.1  mrg 		  && (CLASS_DATA (fsym)->as->type == AS_ASSUMED_SHAPE
   7406  1.1  mrg 		      || CLASS_DATA (fsym)->as->type == AS_ASSUMED_RANK)))
   7407  1.1  mrg 	    {
   7408  1.1  mrg 	      if (fsym->ts.type == BT_CLASS)
   7409  1.1  mrg 		gcc_assert (!POINTER_TYPE_P (TREE_TYPE (tmp2)));
   7410  1.1  mrg 	      else
   7411  1.1  mrg 		{
   7412  1.1  mrg 		  gcc_assert (POINTER_TYPE_P (TREE_TYPE (tmp2)));
   7413  1.1  mrg 		  tmp2 = build_fold_indirect_ref_loc (input_location, tmp2);
   7414  1.1  mrg 		}
   7415  1.1  mrg 	      gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp2)));
   7416  1.1  mrg 	      tmp2 = gfc_conv_descriptor_data_get (tmp2);
   7417  1.1  mrg 	    }
   7418  1.1  mrg 	  else if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp2)))
   7419  1.1  mrg 	    tmp2 = gfc_conv_descriptor_data_get (tmp2);
   7420  1.1  mrg 	  else
   7421  1.1  mrg 	    {
   7422  1.1  mrg 	      gcc_assert (POINTER_TYPE_P (TREE_TYPE (tmp2)));
   7423  1.1  mrg 	    }
   7424  1.1  mrg 
   7425  1.1  mrg 	  tmp = fold_build2_loc (input_location, MINUS_EXPR,
   7426  1.1  mrg                                  gfc_array_index_type,
   7427  1.1  mrg                                  fold_convert (gfc_array_index_type, tmp2),
   7428  1.1  mrg                                  fold_convert (gfc_array_index_type, tmp));
   7429  1.1  mrg 	  offset = fold_build2_loc (input_location, PLUS_EXPR,
   7430  1.1  mrg 				    gfc_array_index_type, offset, tmp);
   7431  1.1  mrg 
   7432  1.1  mrg 	  vec_safe_push (stringargs, offset);
   7433  1.1  mrg 	}
   7434  1.1  mrg 
   7435  1.1  mrg       vec_safe_push (arglist, parmse.expr);
   7436  1.1  mrg     }
   7437  1.1  mrg   gfc_add_block_to_block (&se->pre, &clobbers);
   7438  1.1  mrg   gfc_finish_interface_mapping (&mapping, &se->pre, &se->post);
   7439  1.1  mrg 
   7440  1.1  mrg   if (comp)
   7441  1.1  mrg     ts = comp->ts;
   7442  1.1  mrg   else if (sym->ts.type == BT_CLASS)
   7443  1.1  mrg     ts = CLASS_DATA (sym)->ts;
   7444  1.1  mrg   else
   7445  1.1  mrg     ts = sym->ts;
   7446  1.1  mrg 
   7447  1.1  mrg   if (ts.type == BT_CHARACTER && sym->attr.is_bind_c)
   7448  1.1  mrg     se->string_length = build_int_cst (gfc_charlen_type_node, 1);
   7449  1.1  mrg   else if (ts.type == BT_CHARACTER)
   7450  1.1  mrg     {
   7451  1.1  mrg       if (ts.u.cl->length == NULL)
   7452  1.1  mrg 	{
   7453  1.1  mrg 	  /* Assumed character length results are not allowed by C418 of the 2003
   7454  1.1  mrg 	     standard and are trapped in resolve.cc; except in the case of SPREAD
   7455  1.1  mrg 	     (and other intrinsics?) and dummy functions.  In the case of SPREAD,
   7456  1.1  mrg 	     we take the character length of the first argument for the result.
   7457  1.1  mrg 	     For dummies, we have to look through the formal argument list for
   7458  1.1  mrg 	     this function and use the character length found there.
   7459  1.1  mrg 	     Likewise, we handle the case of deferred-length character dummy
   7460  1.1  mrg 	     arguments to intrinsics that determine the characteristics of
   7461  1.1  mrg 	     the result, which cannot be deferred-length.  */
   7462  1.1  mrg 	  if (expr->value.function.isym)
   7463  1.1  mrg 	    ts.deferred = false;
   7464  1.1  mrg 	  if (ts.deferred)
   7465  1.1  mrg 	    cl.backend_decl = gfc_create_var (gfc_charlen_type_node, "slen");
   7466  1.1  mrg 	  else if (!sym->attr.dummy)
   7467  1.1  mrg 	    cl.backend_decl = (*stringargs)[0];
   7468  1.1  mrg 	  else
   7469  1.1  mrg 	    {
   7470  1.1  mrg 	      formal = gfc_sym_get_dummy_args (sym->ns->proc_name);
   7471  1.1  mrg 	      for (; formal; formal = formal->next)
   7472  1.1  mrg 		if (strcmp (formal->sym->name, sym->name) == 0)
   7473  1.1  mrg 		  cl.backend_decl = formal->sym->ts.u.cl->backend_decl;
   7474  1.1  mrg 	    }
   7475  1.1  mrg 	  len = cl.backend_decl;
   7476  1.1  mrg         }
   7477  1.1  mrg       else
   7478  1.1  mrg         {
   7479  1.1  mrg 	  tree tmp;
   7480  1.1  mrg 
   7481  1.1  mrg 	  /* Calculate the length of the returned string.  */
   7482  1.1  mrg 	  gfc_init_se (&parmse, NULL);
   7483  1.1  mrg 	  if (need_interface_mapping)
   7484  1.1  mrg 	    gfc_apply_interface_mapping (&mapping, &parmse, ts.u.cl->length);
   7485  1.1  mrg 	  else
   7486  1.1  mrg 	    gfc_conv_expr (&parmse, ts.u.cl->length);
   7487  1.1  mrg 	  gfc_add_block_to_block (&se->pre, &parmse.pre);
   7488  1.1  mrg 	  gfc_add_block_to_block (&se->post, &parmse.post);
   7489  1.1  mrg 	  tmp = parmse.expr;
   7490  1.1  mrg 	  /* TODO: It would be better to have the charlens as
   7491  1.1  mrg 	     gfc_charlen_type_node already when the interface is
   7492  1.1  mrg 	     created instead of converting it here (see PR 84615).  */
   7493  1.1  mrg 	  tmp = fold_build2_loc (input_location, MAX_EXPR,
   7494  1.1  mrg 				 gfc_charlen_type_node,
   7495  1.1  mrg 				 fold_convert (gfc_charlen_type_node, tmp),
   7496  1.1  mrg 				 build_zero_cst (gfc_charlen_type_node));
   7497  1.1  mrg 	  cl.backend_decl = tmp;
   7498  1.1  mrg 	}
   7499  1.1  mrg 
   7500  1.1  mrg       /* Set up a charlen structure for it.  */
   7501  1.1  mrg       cl.next = NULL;
   7502  1.1  mrg       cl.length = NULL;
   7503  1.1  mrg       ts.u.cl = &cl;
   7504  1.1  mrg 
   7505  1.1  mrg       len = cl.backend_decl;
   7506  1.1  mrg     }
   7507  1.1  mrg 
   7508  1.1  mrg   byref = (comp && (comp->attr.dimension
   7509  1.1  mrg 	   || (comp->ts.type == BT_CHARACTER && !sym->attr.is_bind_c)))
   7510  1.1  mrg 	   || (!comp && gfc_return_by_reference (sym));
   7511  1.1  mrg   if (byref)
   7512  1.1  mrg     {
   7513  1.1  mrg       if (se->direct_byref)
   7514  1.1  mrg 	{
   7515  1.1  mrg 	  /* Sometimes, too much indirection can be applied; e.g. for
   7516  1.1  mrg 	     function_result = array_valued_recursive_function.  */
   7517  1.1  mrg 	  if (TREE_TYPE (TREE_TYPE (se->expr))
   7518  1.1  mrg 		&& TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr)))
   7519  1.1  mrg 		&& GFC_DESCRIPTOR_TYPE_P
   7520  1.1  mrg 			(TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr)))))
   7521  1.1  mrg 	    se->expr = build_fold_indirect_ref_loc (input_location,
   7522  1.1  mrg 						    se->expr);
   7523  1.1  mrg 
   7524  1.1  mrg 	  /* If the lhs of an assignment x = f(..) is allocatable and
   7525  1.1  mrg 	     f2003 is allowed, we must do the automatic reallocation.
   7526  1.1  mrg 	     TODO - deal with intrinsics, without using a temporary.  */
   7527  1.1  mrg 	  if (flag_realloc_lhs
   7528  1.1  mrg 		&& se->ss && se->ss->loop_chain
   7529  1.1  mrg 		&& se->ss->loop_chain->is_alloc_lhs
   7530  1.1  mrg 		&& !expr->value.function.isym
   7531  1.1  mrg 		&& sym->result->as != NULL)
   7532  1.1  mrg 	    {
   7533  1.1  mrg 	      /* Evaluate the bounds of the result, if known.  */
   7534  1.1  mrg 	      gfc_set_loop_bounds_from_array_spec (&mapping, se,
   7535  1.1  mrg 						   sym->result->as);
   7536  1.1  mrg 
   7537  1.1  mrg 	      /* Perform the automatic reallocation.  */
   7538  1.1  mrg 	      tmp = gfc_alloc_allocatable_for_assignment (se->loop,
   7539  1.1  mrg 							  expr, NULL);
   7540  1.1  mrg 	      gfc_add_expr_to_block (&se->pre, tmp);
   7541  1.1  mrg 
   7542  1.1  mrg 	      /* Pass the temporary as the first argument.  */
   7543  1.1  mrg 	      result = info->descriptor;
   7544  1.1  mrg 	    }
   7545  1.1  mrg 	  else
   7546  1.1  mrg 	    result = build_fold_indirect_ref_loc (input_location,
   7547  1.1  mrg 						  se->expr);
   7548  1.1  mrg 	  vec_safe_push (retargs, se->expr);
   7549  1.1  mrg 	}
   7550  1.1  mrg       else if (comp && comp->attr.dimension)
   7551  1.1  mrg 	{
   7552  1.1  mrg 	  gcc_assert (se->loop && info);
   7553  1.1  mrg 
   7554  1.1  mrg 	  /* Set the type of the array.  */
   7555  1.1  mrg 	  tmp = gfc_typenode_for_spec (&comp->ts);
   7556  1.1  mrg 	  gcc_assert (se->ss->dimen == se->loop->dimen);
   7557  1.1  mrg 
   7558  1.1  mrg 	  /* Evaluate the bounds of the result, if known.  */
   7559  1.1  mrg 	  gfc_set_loop_bounds_from_array_spec (&mapping, se, comp->as);
   7560  1.1  mrg 
   7561  1.1  mrg 	  /* If the lhs of an assignment x = f(..) is allocatable and
   7562  1.1  mrg 	     f2003 is allowed, we must not generate the function call
   7563  1.1  mrg 	     here but should just send back the results of the mapping.
   7564  1.1  mrg 	     This is signalled by the function ss being flagged.  */
   7565  1.1  mrg 	  if (flag_realloc_lhs && se->ss && se->ss->is_alloc_lhs)
   7566  1.1  mrg 	    {
   7567  1.1  mrg 	      gfc_free_interface_mapping (&mapping);
   7568  1.1  mrg 	      return has_alternate_specifier;
   7569  1.1  mrg 	    }
   7570  1.1  mrg 
   7571  1.1  mrg 	  /* Create a temporary to store the result.  In case the function
   7572  1.1  mrg 	     returns a pointer, the temporary will be a shallow copy and
   7573  1.1  mrg 	     mustn't be deallocated.  */
   7574  1.1  mrg 	  callee_alloc = comp->attr.allocatable || comp->attr.pointer;
   7575  1.1  mrg 	  gfc_trans_create_temp_array (&se->pre, &se->post, se->ss,
   7576  1.1  mrg 				       tmp, NULL_TREE, false,
   7577  1.1  mrg 				       !comp->attr.pointer, callee_alloc,
   7578  1.1  mrg 				       &se->ss->info->expr->where);
   7579  1.1  mrg 
   7580  1.1  mrg 	  /* Pass the temporary as the first argument.  */
   7581  1.1  mrg 	  result = info->descriptor;
   7582  1.1  mrg 	  tmp = gfc_build_addr_expr (NULL_TREE, result);
   7583  1.1  mrg 	  vec_safe_push (retargs, tmp);
   7584  1.1  mrg 	}
   7585  1.1  mrg       else if (!comp && sym->result->attr.dimension)
   7586  1.1  mrg 	{
   7587  1.1  mrg 	  gcc_assert (se->loop && info);
   7588  1.1  mrg 
   7589  1.1  mrg 	  /* Set the type of the array.  */
   7590  1.1  mrg 	  tmp = gfc_typenode_for_spec (&ts);
   7591  1.1  mrg 	  gcc_assert (se->ss->dimen == se->loop->dimen);
   7592  1.1  mrg 
   7593  1.1  mrg 	  /* Evaluate the bounds of the result, if known.  */
   7594  1.1  mrg 	  gfc_set_loop_bounds_from_array_spec (&mapping, se, sym->result->as);
   7595  1.1  mrg 
   7596  1.1  mrg 	  /* If the lhs of an assignment x = f(..) is allocatable and
   7597  1.1  mrg 	     f2003 is allowed, we must not generate the function call
   7598  1.1  mrg 	     here but should just send back the results of the mapping.
   7599  1.1  mrg 	     This is signalled by the function ss being flagged.  */
   7600  1.1  mrg 	  if (flag_realloc_lhs && se->ss && se->ss->is_alloc_lhs)
   7601  1.1  mrg 	    {
   7602  1.1  mrg 	      gfc_free_interface_mapping (&mapping);
   7603  1.1  mrg 	      return has_alternate_specifier;
   7604  1.1  mrg 	    }
   7605  1.1  mrg 
   7606  1.1  mrg 	  /* Create a temporary to store the result.  In case the function
   7607  1.1  mrg 	     returns a pointer, the temporary will be a shallow copy and
   7608  1.1  mrg 	     mustn't be deallocated.  */
   7609  1.1  mrg 	  callee_alloc = sym->attr.allocatable || sym->attr.pointer;
   7610  1.1  mrg 	  gfc_trans_create_temp_array (&se->pre, &se->post, se->ss,
   7611  1.1  mrg 				       tmp, NULL_TREE, false,
   7612  1.1  mrg 				       !sym->attr.pointer, callee_alloc,
   7613  1.1  mrg 				       &se->ss->info->expr->where);
   7614  1.1  mrg 
   7615  1.1  mrg 	  /* Pass the temporary as the first argument.  */
   7616  1.1  mrg 	  result = info->descriptor;
   7617  1.1  mrg 	  tmp = gfc_build_addr_expr (NULL_TREE, result);
   7618  1.1  mrg 	  vec_safe_push (retargs, tmp);
   7619  1.1  mrg 	}
   7620  1.1  mrg       else if (ts.type == BT_CHARACTER)
   7621  1.1  mrg 	{
   7622  1.1  mrg 	  /* Pass the string length.  */
   7623  1.1  mrg 	  type = gfc_get_character_type (ts.kind, ts.u.cl);
   7624  1.1  mrg 	  type = build_pointer_type (type);
   7625  1.1  mrg 
   7626  1.1  mrg 	  /* Emit a DECL_EXPR for the VLA type.  */
   7627  1.1  mrg 	  tmp = TREE_TYPE (type);
   7628  1.1  mrg 	  if (TYPE_SIZE (tmp)
   7629  1.1  mrg 	      && TREE_CODE (TYPE_SIZE (tmp)) != INTEGER_CST)
   7630  1.1  mrg 	    {
   7631  1.1  mrg 	      tmp = build_decl (input_location, TYPE_DECL, NULL_TREE, tmp);
   7632  1.1  mrg 	      DECL_ARTIFICIAL (tmp) = 1;
   7633  1.1  mrg 	      DECL_IGNORED_P (tmp) = 1;
   7634  1.1  mrg 	      tmp = fold_build1_loc (input_location, DECL_EXPR,
   7635  1.1  mrg 				     TREE_TYPE (tmp), tmp);
   7636  1.1  mrg 	      gfc_add_expr_to_block (&se->pre, tmp);
   7637  1.1  mrg 	    }
   7638  1.1  mrg 
   7639  1.1  mrg 	  /* Return an address to a char[0:len-1]* temporary for
   7640  1.1  mrg 	     character pointers.  */
   7641  1.1  mrg 	  if ((!comp && (sym->attr.pointer || sym->attr.allocatable))
   7642  1.1  mrg 	       || (comp && (comp->attr.pointer || comp->attr.allocatable)))
   7643  1.1  mrg 	    {
   7644  1.1  mrg 	      var = gfc_create_var (type, "pstr");
   7645  1.1  mrg 
   7646  1.1  mrg 	      if ((!comp && sym->attr.allocatable)
   7647  1.1  mrg 		  || (comp && comp->attr.allocatable))
   7648  1.1  mrg 		{
   7649  1.1  mrg 		  gfc_add_modify (&se->pre, var,
   7650  1.1  mrg 				  fold_convert (TREE_TYPE (var),
   7651  1.1  mrg 						null_pointer_node));
   7652  1.1  mrg 		  tmp = gfc_call_free (var);
   7653  1.1  mrg 		  gfc_add_expr_to_block (&se->post, tmp);
   7654  1.1  mrg 		}
   7655  1.1  mrg 
   7656  1.1  mrg 	      /* Provide an address expression for the function arguments.  */
   7657  1.1  mrg 	      var = gfc_build_addr_expr (NULL_TREE, var);
   7658  1.1  mrg 	    }
   7659  1.1  mrg 	  else
   7660  1.1  mrg 	    var = gfc_conv_string_tmp (se, type, len);
   7661  1.1  mrg 
   7662  1.1  mrg 	  vec_safe_push (retargs, var);
   7663  1.1  mrg 	}
   7664  1.1  mrg       else
   7665  1.1  mrg 	{
   7666  1.1  mrg 	  gcc_assert (flag_f2c && ts.type == BT_COMPLEX);
   7667  1.1  mrg 
   7668  1.1  mrg 	  type = gfc_get_complex_type (ts.kind);
   7669  1.1  mrg 	  var = gfc_build_addr_expr (NULL_TREE, gfc_create_var (type, "cmplx"));
   7670  1.1  mrg 	  vec_safe_push (retargs, var);
   7671  1.1  mrg 	}
   7672  1.1  mrg 
   7673  1.1  mrg       /* Add the string length to the argument list.  */
   7674  1.1  mrg       if (ts.type == BT_CHARACTER && ts.deferred)
   7675  1.1  mrg 	{
   7676  1.1  mrg 	  tmp = len;
   7677  1.1  mrg 	  if (!VAR_P (tmp))
   7678  1.1  mrg 	    tmp = gfc_evaluate_now (len, &se->pre);
   7679  1.1  mrg 	  TREE_STATIC (tmp) = 1;
   7680  1.1  mrg 	  gfc_add_modify (&se->pre, tmp,
   7681  1.1  mrg 			  build_int_cst (TREE_TYPE (tmp), 0));
   7682  1.1  mrg 	  tmp = gfc_build_addr_expr (NULL_TREE, tmp);
   7683  1.1  mrg 	  vec_safe_push (retargs, tmp);
   7684  1.1  mrg 	}
   7685  1.1  mrg       else if (ts.type == BT_CHARACTER)
   7686  1.1  mrg 	vec_safe_push (retargs, len);
   7687  1.1  mrg     }
   7688  1.1  mrg   gfc_free_interface_mapping (&mapping);
   7689  1.1  mrg 
   7690  1.1  mrg   /* We need to glom RETARGS + ARGLIST + STRINGARGS + APPEND_ARGS.  */
   7691  1.1  mrg   arglen = (vec_safe_length (arglist) + vec_safe_length (optionalargs)
   7692  1.1  mrg 	    + vec_safe_length (stringargs) + vec_safe_length (append_args));
   7693  1.1  mrg   vec_safe_reserve (retargs, arglen);
   7694  1.1  mrg 
   7695  1.1  mrg   /* Add the return arguments.  */
   7696  1.1  mrg   vec_safe_splice (retargs, arglist);
   7697  1.1  mrg 
   7698  1.1  mrg   /* Add the hidden present status for optional+value to the arguments.  */
   7699  1.1  mrg   vec_safe_splice (retargs, optionalargs);
   7700  1.1  mrg 
   7701  1.1  mrg   /* Add the hidden string length parameters to the arguments.  */
   7702  1.1  mrg   vec_safe_splice (retargs, stringargs);
   7703  1.1  mrg 
   7704  1.1  mrg   /* We may want to append extra arguments here.  This is used e.g. for
   7705  1.1  mrg      calls to libgfortran_matmul_??, which need extra information.  */
   7706  1.1  mrg   vec_safe_splice (retargs, append_args);
   7707  1.1  mrg 
   7708  1.1  mrg   arglist = retargs;
   7709  1.1  mrg 
   7710  1.1  mrg   /* Generate the actual call.  */
   7711  1.1  mrg   if (base_object == NULL_TREE)
   7712  1.1  mrg     conv_function_val (se, sym, expr, args);
   7713  1.1  mrg   else
   7714  1.1  mrg     conv_base_obj_fcn_val (se, base_object, expr);
   7715  1.1  mrg 
   7716  1.1  mrg   /* If there are alternate return labels, function type should be
   7717  1.1  mrg      integer.  Can't modify the type in place though, since it can be shared
   7718  1.1  mrg      with other functions.  For dummy arguments, the typing is done to
   7719  1.1  mrg      this result, even if it has to be repeated for each call.  */
   7720  1.1  mrg   if (has_alternate_specifier
   7721  1.1  mrg       && TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr))) != integer_type_node)
   7722  1.1  mrg     {
   7723  1.1  mrg       if (!sym->attr.dummy)
   7724  1.1  mrg 	{
   7725  1.1  mrg 	  TREE_TYPE (sym->backend_decl)
   7726  1.1  mrg 		= build_function_type (integer_type_node,
   7727  1.1  mrg 		      TYPE_ARG_TYPES (TREE_TYPE (sym->backend_decl)));
   7728  1.1  mrg 	  se->expr = gfc_build_addr_expr (NULL_TREE, sym->backend_decl);
   7729  1.1  mrg 	}
   7730  1.1  mrg       else
   7731  1.1  mrg 	TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr))) = integer_type_node;
   7732  1.1  mrg     }
   7733  1.1  mrg 
   7734  1.1  mrg   fntype = TREE_TYPE (TREE_TYPE (se->expr));
   7735  1.1  mrg   se->expr = build_call_vec (TREE_TYPE (fntype), se->expr, arglist);
   7736  1.1  mrg 
   7737  1.1  mrg   /* Allocatable scalar function results must be freed and nullified
   7738  1.1  mrg      after use. This necessitates the creation of a temporary to
   7739  1.1  mrg      hold the result to prevent duplicate calls.  */
   7740  1.1  mrg   if (!byref && sym->ts.type != BT_CHARACTER
   7741  1.1  mrg       && ((sym->attr.allocatable && !sym->attr.dimension && !comp)
   7742  1.1  mrg 	  || (comp && comp->attr.allocatable && !comp->attr.dimension)))
   7743  1.1  mrg     {
   7744  1.1  mrg       tmp = gfc_create_var (TREE_TYPE (se->expr), NULL);
   7745  1.1  mrg       gfc_add_modify (&se->pre, tmp, se->expr);
   7746  1.1  mrg       se->expr = tmp;
   7747  1.1  mrg       tmp = gfc_call_free (tmp);
   7748  1.1  mrg       gfc_add_expr_to_block (&post, tmp);
   7749  1.1  mrg       gfc_add_modify (&post, se->expr, build_int_cst (TREE_TYPE (se->expr), 0));
   7750  1.1  mrg     }
   7751  1.1  mrg 
   7752  1.1  mrg   /* If we have a pointer function, but we don't want a pointer, e.g.
   7753  1.1  mrg      something like
   7754  1.1  mrg         x = f()
   7755  1.1  mrg      where f is pointer valued, we have to dereference the result.  */
   7756  1.1  mrg   if (!se->want_pointer && !byref
   7757  1.1  mrg       && ((!comp && (sym->attr.pointer || sym->attr.allocatable))
   7758  1.1  mrg 	  || (comp && (comp->attr.pointer || comp->attr.allocatable))))
   7759  1.1  mrg     se->expr = build_fold_indirect_ref_loc (input_location, se->expr);
   7760  1.1  mrg 
   7761  1.1  mrg   /* f2c calling conventions require a scalar default real function to
   7762  1.1  mrg      return a double precision result.  Convert this back to default
   7763  1.1  mrg      real.  We only care about the cases that can happen in Fortran 77.
   7764  1.1  mrg   */
   7765  1.1  mrg   if (flag_f2c && sym->ts.type == BT_REAL
   7766  1.1  mrg       && sym->ts.kind == gfc_default_real_kind
   7767  1.1  mrg       && !sym->attr.always_explicit)
   7768  1.1  mrg     se->expr = fold_convert (gfc_get_real_type (sym->ts.kind), se->expr);
   7769  1.1  mrg 
   7770  1.1  mrg   /* A pure function may still have side-effects - it may modify its
   7771  1.1  mrg      parameters.  */
   7772  1.1  mrg   TREE_SIDE_EFFECTS (se->expr) = 1;
   7773  1.1  mrg #if 0
   7774  1.1  mrg   if (!sym->attr.pure)
   7775  1.1  mrg     TREE_SIDE_EFFECTS (se->expr) = 1;
   7776  1.1  mrg #endif
   7777  1.1  mrg 
   7778  1.1  mrg   if (byref)
   7779  1.1  mrg     {
   7780  1.1  mrg       /* Add the function call to the pre chain.  There is no expression.  */
   7781  1.1  mrg       gfc_add_expr_to_block (&se->pre, se->expr);
   7782  1.1  mrg       se->expr = NULL_TREE;
   7783  1.1  mrg 
   7784  1.1  mrg       if (!se->direct_byref)
   7785  1.1  mrg 	{
   7786  1.1  mrg 	  if ((sym->attr.dimension && !comp) || (comp && comp->attr.dimension))
   7787  1.1  mrg 	    {
   7788  1.1  mrg 	      if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
   7789  1.1  mrg 		{
   7790  1.1  mrg 		  /* Check the data pointer hasn't been modified.  This would
   7791  1.1  mrg 		     happen in a function returning a pointer.  */
   7792  1.1  mrg 		  tmp = gfc_conv_descriptor_data_get (info->descriptor);
   7793  1.1  mrg 		  tmp = fold_build2_loc (input_location, NE_EXPR,
   7794  1.1  mrg 					 logical_type_node,
   7795  1.1  mrg 					 tmp, info->data);
   7796  1.1  mrg 		  gfc_trans_runtime_check (true, false, tmp, &se->pre, NULL,
   7797  1.1  mrg 					   gfc_msg_fault);
   7798  1.1  mrg 		}
   7799  1.1  mrg 	      se->expr = info->descriptor;
   7800  1.1  mrg 	      /* Bundle in the string length.  */
   7801  1.1  mrg 	      se->string_length = len;
   7802  1.1  mrg 	    }
   7803  1.1  mrg 	  else if (ts.type == BT_CHARACTER)
   7804  1.1  mrg 	    {
   7805  1.1  mrg 	      /* Dereference for character pointer results.  */
   7806  1.1  mrg 	      if ((!comp && (sym->attr.pointer || sym->attr.allocatable))
   7807  1.1  mrg 		  || (comp && (comp->attr.pointer || comp->attr.allocatable)))
   7808  1.1  mrg 		se->expr = build_fold_indirect_ref_loc (input_location, var);
   7809  1.1  mrg 	      else
   7810  1.1  mrg 	        se->expr = var;
   7811  1.1  mrg 
   7812  1.1  mrg 	      se->string_length = len;
   7813  1.1  mrg 	    }
   7814  1.1  mrg 	  else
   7815  1.1  mrg 	    {
   7816  1.1  mrg 	      gcc_assert (ts.type == BT_COMPLEX && flag_f2c);
   7817  1.1  mrg 	      se->expr = build_fold_indirect_ref_loc (input_location, var);
   7818  1.1  mrg 	    }
   7819  1.1  mrg 	}
   7820  1.1  mrg     }
   7821  1.1  mrg 
   7822  1.1  mrg   /* Associate the rhs class object's meta-data with the result, when the
   7823  1.1  mrg      result is a temporary.  */
   7824  1.1  mrg   if (args && args->expr && args->expr->ts.type == BT_CLASS
   7825  1.1  mrg       && sym->ts.type == BT_CLASS && result != NULL_TREE && DECL_P (result)
   7826  1.1  mrg       && !GFC_CLASS_TYPE_P (TREE_TYPE (result)))
   7827  1.1  mrg     {
   7828  1.1  mrg       gfc_se parmse;
   7829  1.1  mrg       gfc_expr *class_expr = gfc_find_and_cut_at_last_class_ref (args->expr);
   7830  1.1  mrg 
   7831  1.1  mrg       gfc_init_se (&parmse, NULL);
   7832  1.1  mrg       parmse.data_not_needed = 1;
   7833  1.1  mrg       gfc_conv_expr (&parmse, class_expr);
   7834  1.1  mrg       if (!DECL_LANG_SPECIFIC (result))
   7835  1.1  mrg 	gfc_allocate_lang_decl (result);
   7836  1.1  mrg       GFC_DECL_SAVED_DESCRIPTOR (result) = parmse.expr;
   7837  1.1  mrg       gfc_free_expr (class_expr);
   7838  1.1  mrg       /* -fcheck= can add diagnostic code, which has to be placed before
   7839  1.1  mrg 	 the call. */
   7840  1.1  mrg       if (parmse.pre.head != NULL)
   7841  1.1  mrg 	  gfc_add_expr_to_block (&se->pre, parmse.pre.head);
   7842  1.1  mrg       gcc_assert (parmse.post.head == NULL_TREE);
   7843  1.1  mrg     }
   7844  1.1  mrg 
   7845  1.1  mrg   /* Follow the function call with the argument post block.  */
   7846  1.1  mrg   if (byref)
   7847  1.1  mrg     {
   7848  1.1  mrg       gfc_add_block_to_block (&se->pre, &post);
   7849  1.1  mrg 
   7850  1.1  mrg       /* Transformational functions of derived types with allocatable
   7851  1.1  mrg 	 components must have the result allocatable components copied when the
   7852  1.1  mrg 	 argument is actually given.  */
   7853  1.1  mrg       arg = expr->value.function.actual;
   7854  1.1  mrg       if (result && arg && expr->rank
   7855  1.1  mrg 	  && expr->value.function.isym
   7856  1.1  mrg 	  && expr->value.function.isym->transformational
   7857  1.1  mrg 	  && arg->expr
   7858  1.1  mrg 	  && arg->expr->ts.type == BT_DERIVED
   7859  1.1  mrg 	  && arg->expr->ts.u.derived->attr.alloc_comp)
   7860  1.1  mrg 	{
   7861  1.1  mrg 	  tree tmp2;
   7862  1.1  mrg 	  /* Copy the allocatable components.  We have to use a
   7863  1.1  mrg 	     temporary here to prevent source allocatable components
   7864  1.1  mrg 	     from being corrupted.  */
   7865  1.1  mrg 	  tmp2 = gfc_evaluate_now (result, &se->pre);
   7866  1.1  mrg 	  tmp = gfc_copy_alloc_comp (arg->expr->ts.u.derived,
   7867  1.1  mrg 				     result, tmp2, expr->rank, 0);
   7868  1.1  mrg 	  gfc_add_expr_to_block (&se->pre, tmp);
   7869  1.1  mrg 	  tmp = gfc_copy_allocatable_data (result, tmp2, TREE_TYPE(tmp2),
   7870  1.1  mrg 				           expr->rank);
   7871  1.1  mrg 	  gfc_add_expr_to_block (&se->pre, tmp);
   7872  1.1  mrg 
   7873  1.1  mrg 	  /* Finally free the temporary's data field.  */
   7874  1.1  mrg 	  tmp = gfc_conv_descriptor_data_get (tmp2);
   7875  1.1  mrg 	  tmp = gfc_deallocate_with_status (tmp, NULL_TREE, NULL_TREE,
   7876  1.1  mrg 					    NULL_TREE, NULL_TREE, true,
   7877  1.1  mrg 					    NULL, GFC_CAF_COARRAY_NOCOARRAY);
   7878  1.1  mrg 	  gfc_add_expr_to_block (&se->pre, tmp);
   7879  1.1  mrg 	}
   7880  1.1  mrg     }
   7881  1.1  mrg   else
   7882  1.1  mrg     {
   7883  1.1  mrg       /* For a function with a class array result, save the result as
   7884  1.1  mrg 	 a temporary, set the info fields needed by the scalarizer and
   7885  1.1  mrg 	 call the finalization function of the temporary. Note that the
   7886  1.1  mrg 	 nullification of allocatable components needed by the result
   7887  1.1  mrg 	 is done in gfc_trans_assignment_1.  */
   7888  1.1  mrg       if (expr && ((gfc_is_class_array_function (expr)
   7889  1.1  mrg 		    && se->ss && se->ss->loop)
   7890  1.1  mrg 		   || gfc_is_alloc_class_scalar_function (expr))
   7891  1.1  mrg 	  && se->expr && GFC_CLASS_TYPE_P (TREE_TYPE (se->expr))
   7892  1.1  mrg 	  && expr->must_finalize)
   7893  1.1  mrg 	{
   7894  1.1  mrg 	  tree final_fndecl;
   7895  1.1  mrg 	  tree is_final;
   7896  1.1  mrg 	  int n;
   7897  1.1  mrg 	  if (se->ss && se->ss->loop)
   7898  1.1  mrg 	    {
   7899  1.1  mrg 	      gfc_add_block_to_block (&se->ss->loop->pre, &se->pre);
   7900  1.1  mrg 	      se->expr = gfc_evaluate_now (se->expr, &se->ss->loop->pre);
   7901  1.1  mrg 	      tmp = gfc_class_data_get (se->expr);
   7902  1.1  mrg 	      info->descriptor = tmp;
   7903  1.1  mrg 	      info->data = gfc_conv_descriptor_data_get (tmp);
   7904  1.1  mrg 	      info->offset = gfc_conv_descriptor_offset_get (tmp);
   7905  1.1  mrg 	      for (n = 0; n < se->ss->loop->dimen; n++)
   7906  1.1  mrg 		{
   7907  1.1  mrg 		  tree dim = gfc_rank_cst[n];
   7908  1.1  mrg 		  se->ss->loop->to[n] = gfc_conv_descriptor_ubound_get (tmp, dim);
   7909  1.1  mrg 		  se->ss->loop->from[n] = gfc_conv_descriptor_lbound_get (tmp, dim);
   7910  1.1  mrg 		}
   7911  1.1  mrg 	    }
   7912  1.1  mrg 	  else
   7913  1.1  mrg 	    {
   7914  1.1  mrg 	      /* TODO Eliminate the doubling of temporaries. This
   7915  1.1  mrg 		 one is necessary to ensure no memory leakage.  */
   7916  1.1  mrg 	      se->expr = gfc_evaluate_now (se->expr, &se->pre);
   7917  1.1  mrg 	      tmp = gfc_class_data_get (se->expr);
   7918  1.1  mrg 	      tmp = gfc_conv_scalar_to_descriptor (se, tmp,
   7919  1.1  mrg 			CLASS_DATA (expr->value.function.esym->result)->attr);
   7920  1.1  mrg 	    }
   7921  1.1  mrg 
   7922  1.1  mrg 	  if ((gfc_is_class_array_function (expr)
   7923  1.1  mrg 	       || gfc_is_alloc_class_scalar_function (expr))
   7924  1.1  mrg 	      && CLASS_DATA (expr->value.function.esym->result)->attr.pointer)
   7925  1.1  mrg 	    goto no_finalization;
   7926  1.1  mrg 
   7927  1.1  mrg 	  final_fndecl = gfc_class_vtab_final_get (se->expr);
   7928  1.1  mrg 	  is_final = fold_build2_loc (input_location, NE_EXPR,
   7929  1.1  mrg 				      logical_type_node,
   7930  1.1  mrg 				      final_fndecl,
   7931  1.1  mrg 				      fold_convert (TREE_TYPE (final_fndecl),
   7932  1.1  mrg 					   	    null_pointer_node));
   7933  1.1  mrg 	  final_fndecl = build_fold_indirect_ref_loc (input_location,
   7934  1.1  mrg 						      final_fndecl);
   7935  1.1  mrg  	  tmp = build_call_expr_loc (input_location,
   7936  1.1  mrg 				     final_fndecl, 3,
   7937  1.1  mrg 				     gfc_build_addr_expr (NULL, tmp),
   7938  1.1  mrg 				     gfc_class_vtab_size_get (se->expr),
   7939  1.1  mrg 				     boolean_false_node);
   7940  1.1  mrg 	  tmp = fold_build3_loc (input_location, COND_EXPR,
   7941  1.1  mrg 				 void_type_node, is_final, tmp,
   7942  1.1  mrg 				 build_empty_stmt (input_location));
   7943  1.1  mrg 
   7944  1.1  mrg 	  if (se->ss && se->ss->loop)
   7945  1.1  mrg 	    {
   7946  1.1  mrg 	      gfc_prepend_expr_to_block (&se->ss->loop->post, tmp);
   7947  1.1  mrg 	      tmp = fold_build2_loc (input_location, NE_EXPR,
   7948  1.1  mrg 				     logical_type_node,
   7949  1.1  mrg 				     info->data,
   7950  1.1  mrg 				     fold_convert (TREE_TYPE (info->data),
   7951  1.1  mrg 					   	    null_pointer_node));
   7952  1.1  mrg 	      tmp = fold_build3_loc (input_location, COND_EXPR,
   7953  1.1  mrg 				     void_type_node, tmp,
   7954  1.1  mrg 				     gfc_call_free (info->data),
   7955  1.1  mrg 				     build_empty_stmt (input_location));
   7956  1.1  mrg 	      gfc_add_expr_to_block (&se->ss->loop->post, tmp);
   7957  1.1  mrg 	    }
   7958  1.1  mrg 	  else
   7959  1.1  mrg 	    {
   7960  1.1  mrg 	      tree classdata;
   7961  1.1  mrg 	      gfc_prepend_expr_to_block (&se->post, tmp);
   7962  1.1  mrg 	      classdata = gfc_class_data_get (se->expr);
   7963  1.1  mrg 	      tmp = fold_build2_loc (input_location, NE_EXPR,
   7964  1.1  mrg 				     logical_type_node,
   7965  1.1  mrg 				     classdata,
   7966  1.1  mrg 				     fold_convert (TREE_TYPE (classdata),
   7967  1.1  mrg 					   	    null_pointer_node));
   7968  1.1  mrg 	      tmp = fold_build3_loc (input_location, COND_EXPR,
   7969  1.1  mrg 				     void_type_node, tmp,
   7970  1.1  mrg 				     gfc_call_free (classdata),
   7971  1.1  mrg 				     build_empty_stmt (input_location));
   7972  1.1  mrg 	      gfc_add_expr_to_block (&se->post, tmp);
   7973  1.1  mrg 	    }
   7974  1.1  mrg 	}
   7975  1.1  mrg 
   7976  1.1  mrg no_finalization:
   7977  1.1  mrg       gfc_add_block_to_block (&se->post, &post);
   7978  1.1  mrg     }
   7979  1.1  mrg 
   7980  1.1  mrg   return has_alternate_specifier;
   7981  1.1  mrg }
   7982  1.1  mrg 
   7983  1.1  mrg 
   7984  1.1  mrg /* Fill a character string with spaces.  */
   7985  1.1  mrg 
   7986  1.1  mrg static tree
   7987  1.1  mrg fill_with_spaces (tree start, tree type, tree size)
   7988  1.1  mrg {
   7989  1.1  mrg   stmtblock_t block, loop;
   7990  1.1  mrg   tree i, el, exit_label, cond, tmp;
   7991  1.1  mrg 
   7992  1.1  mrg   /* For a simple char type, we can call memset().  */
   7993  1.1  mrg   if (compare_tree_int (TYPE_SIZE_UNIT (type), 1) == 0)
   7994  1.1  mrg     return build_call_expr_loc (input_location,
   7995  1.1  mrg 			    builtin_decl_explicit (BUILT_IN_MEMSET),
   7996  1.1  mrg 			    3, start,
   7997  1.1  mrg 			    build_int_cst (gfc_get_int_type (gfc_c_int_kind),
   7998  1.1  mrg 					   lang_hooks.to_target_charset (' ')),
   7999  1.1  mrg 				fold_convert (size_type_node, size));
   8000  1.1  mrg 
   8001  1.1  mrg   /* Otherwise, we use a loop:
   8002  1.1  mrg 	for (el = start, i = size; i > 0; el--, i+= TYPE_SIZE_UNIT (type))
   8003  1.1  mrg 	  *el = (type) ' ';
   8004  1.1  mrg    */
   8005  1.1  mrg 
   8006  1.1  mrg   /* Initialize variables.  */
   8007  1.1  mrg   gfc_init_block (&block);
   8008  1.1  mrg   i = gfc_create_var (sizetype, "i");
   8009  1.1  mrg   gfc_add_modify (&block, i, fold_convert (sizetype, size));
   8010  1.1  mrg   el = gfc_create_var (build_pointer_type (type), "el");
   8011  1.1  mrg   gfc_add_modify (&block, el, fold_convert (TREE_TYPE (el), start));
   8012  1.1  mrg   exit_label = gfc_build_label_decl (NULL_TREE);
   8013  1.1  mrg   TREE_USED (exit_label) = 1;
   8014  1.1  mrg 
   8015  1.1  mrg 
   8016  1.1  mrg   /* Loop body.  */
   8017  1.1  mrg   gfc_init_block (&loop);
   8018  1.1  mrg 
   8019  1.1  mrg   /* Exit condition.  */
   8020  1.1  mrg   cond = fold_build2_loc (input_location, LE_EXPR, logical_type_node, i,
   8021  1.1  mrg 			  build_zero_cst (sizetype));
   8022  1.1  mrg   tmp = build1_v (GOTO_EXPR, exit_label);
   8023  1.1  mrg   tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond, tmp,
   8024  1.1  mrg 			 build_empty_stmt (input_location));
   8025  1.1  mrg   gfc_add_expr_to_block (&loop, tmp);
   8026  1.1  mrg 
   8027  1.1  mrg   /* Assignment.  */
   8028  1.1  mrg   gfc_add_modify (&loop,
   8029  1.1  mrg 		  fold_build1_loc (input_location, INDIRECT_REF, type, el),
   8030  1.1  mrg 		  build_int_cst (type, lang_hooks.to_target_charset (' ')));
   8031  1.1  mrg 
   8032  1.1  mrg   /* Increment loop variables.  */
   8033  1.1  mrg   gfc_add_modify (&loop, i,
   8034  1.1  mrg 		  fold_build2_loc (input_location, MINUS_EXPR, sizetype, i,
   8035  1.1  mrg 				   TYPE_SIZE_UNIT (type)));
   8036  1.1  mrg   gfc_add_modify (&loop, el,
   8037  1.1  mrg 		  fold_build_pointer_plus_loc (input_location,
   8038  1.1  mrg 					       el, TYPE_SIZE_UNIT (type)));
   8039  1.1  mrg 
   8040  1.1  mrg   /* Making the loop... actually loop!  */
   8041  1.1  mrg   tmp = gfc_finish_block (&loop);
   8042  1.1  mrg   tmp = build1_v (LOOP_EXPR, tmp);
   8043  1.1  mrg   gfc_add_expr_to_block (&block, tmp);
   8044  1.1  mrg 
   8045  1.1  mrg   /* The exit label.  */
   8046  1.1  mrg   tmp = build1_v (LABEL_EXPR, exit_label);
   8047  1.1  mrg   gfc_add_expr_to_block (&block, tmp);
   8048  1.1  mrg 
   8049  1.1  mrg 
   8050  1.1  mrg   return gfc_finish_block (&block);
   8051  1.1  mrg }
   8052  1.1  mrg 
   8053  1.1  mrg 
   8054  1.1  mrg /* Generate code to copy a string.  */
   8055  1.1  mrg 
   8056  1.1  mrg void
   8057  1.1  mrg gfc_trans_string_copy (stmtblock_t * block, tree dlength, tree dest,
   8058  1.1  mrg 		       int dkind, tree slength, tree src, int skind)
   8059  1.1  mrg {
   8060  1.1  mrg   tree tmp, dlen, slen;
   8061  1.1  mrg   tree dsc;
   8062  1.1  mrg   tree ssc;
   8063  1.1  mrg   tree cond;
   8064  1.1  mrg   tree cond2;
   8065  1.1  mrg   tree tmp2;
   8066  1.1  mrg   tree tmp3;
   8067  1.1  mrg   tree tmp4;
   8068  1.1  mrg   tree chartype;
   8069  1.1  mrg   stmtblock_t tempblock;
   8070  1.1  mrg 
   8071  1.1  mrg   gcc_assert (dkind == skind);
   8072  1.1  mrg 
   8073  1.1  mrg   if (slength != NULL_TREE)
   8074  1.1  mrg     {
   8075  1.1  mrg       slen = gfc_evaluate_now (fold_convert (gfc_charlen_type_node, slength), block);
   8076  1.1  mrg       ssc = gfc_string_to_single_character (slen, src, skind);
   8077  1.1  mrg     }
   8078  1.1  mrg   else
   8079  1.1  mrg     {
   8080  1.1  mrg       slen = build_one_cst (gfc_charlen_type_node);
   8081  1.1  mrg       ssc =  src;
   8082  1.1  mrg     }
   8083  1.1  mrg 
   8084  1.1  mrg   if (dlength != NULL_TREE)
   8085  1.1  mrg     {
   8086  1.1  mrg       dlen = gfc_evaluate_now (fold_convert (gfc_charlen_type_node, dlength), block);
   8087  1.1  mrg       dsc = gfc_string_to_single_character (dlen, dest, dkind);
   8088  1.1  mrg     }
   8089  1.1  mrg   else
   8090  1.1  mrg     {
   8091  1.1  mrg       dlen = build_one_cst (gfc_charlen_type_node);
   8092  1.1  mrg       dsc =  dest;
   8093  1.1  mrg     }
   8094  1.1  mrg 
   8095  1.1  mrg   /* Assign directly if the types are compatible.  */
   8096  1.1  mrg   if (dsc != NULL_TREE && ssc != NULL_TREE
   8097  1.1  mrg       && TREE_TYPE (dsc) == TREE_TYPE (ssc))
   8098  1.1  mrg     {
   8099  1.1  mrg       gfc_add_modify (block, dsc, ssc);
   8100  1.1  mrg       return;
   8101  1.1  mrg     }
   8102  1.1  mrg 
   8103  1.1  mrg   /* The string copy algorithm below generates code like
   8104  1.1  mrg 
   8105  1.1  mrg      if (destlen > 0)
   8106  1.1  mrg        {
   8107  1.1  mrg          if (srclen < destlen)
   8108  1.1  mrg            {
   8109  1.1  mrg              memmove (dest, src, srclen);
   8110  1.1  mrg              // Pad with spaces.
   8111  1.1  mrg              memset (&dest[srclen], ' ', destlen - srclen);
   8112  1.1  mrg            }
   8113  1.1  mrg          else
   8114  1.1  mrg            {
   8115  1.1  mrg              // Truncate if too long.
   8116  1.1  mrg              memmove (dest, src, destlen);
   8117  1.1  mrg            }
   8118  1.1  mrg        }
   8119  1.1  mrg   */
   8120  1.1  mrg 
   8121  1.1  mrg   /* Do nothing if the destination length is zero.  */
   8122  1.1  mrg   cond = fold_build2_loc (input_location, GT_EXPR, logical_type_node, dlen,
   8123  1.1  mrg 			  build_zero_cst (TREE_TYPE (dlen)));
   8124  1.1  mrg 
   8125  1.1  mrg   /* For non-default character kinds, we have to multiply the string
   8126  1.1  mrg      length by the base type size.  */
   8127  1.1  mrg   chartype = gfc_get_char_type (dkind);
   8128  1.1  mrg   slen = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (slen),
   8129  1.1  mrg 			  slen,
   8130  1.1  mrg 			  fold_convert (TREE_TYPE (slen),
   8131  1.1  mrg 					TYPE_SIZE_UNIT (chartype)));
   8132  1.1  mrg   dlen = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (dlen),
   8133  1.1  mrg 			  dlen,
   8134  1.1  mrg 			  fold_convert (TREE_TYPE (dlen),
   8135  1.1  mrg 					TYPE_SIZE_UNIT (chartype)));
   8136  1.1  mrg 
   8137  1.1  mrg   if (dlength && POINTER_TYPE_P (TREE_TYPE (dest)))
   8138  1.1  mrg     dest = fold_convert (pvoid_type_node, dest);
   8139  1.1  mrg   else
   8140  1.1  mrg     dest = gfc_build_addr_expr (pvoid_type_node, dest);
   8141  1.1  mrg 
   8142  1.1  mrg   if (slength && POINTER_TYPE_P (TREE_TYPE (src)))
   8143  1.1  mrg     src = fold_convert (pvoid_type_node, src);
   8144  1.1  mrg   else
   8145  1.1  mrg     src = gfc_build_addr_expr (pvoid_type_node, src);
   8146  1.1  mrg 
   8147  1.1  mrg   /* Truncate string if source is too long.  */
   8148  1.1  mrg   cond2 = fold_build2_loc (input_location, LT_EXPR, logical_type_node, slen,
   8149  1.1  mrg 			   dlen);
   8150  1.1  mrg 
   8151  1.1  mrg   /* Pre-evaluate pointers unless one of the IF arms will be optimized away.  */
   8152  1.1  mrg   if (!CONSTANT_CLASS_P (cond2))
   8153  1.1  mrg     {
   8154  1.1  mrg       dest = gfc_evaluate_now (dest, block);
   8155  1.1  mrg       src = gfc_evaluate_now (src, block);
   8156  1.1  mrg     }
   8157  1.1  mrg 
   8158  1.1  mrg   /* Copy and pad with spaces.  */
   8159  1.1  mrg   tmp3 = build_call_expr_loc (input_location,
   8160  1.1  mrg 			      builtin_decl_explicit (BUILT_IN_MEMMOVE),
   8161  1.1  mrg 			      3, dest, src,
   8162  1.1  mrg 			      fold_convert (size_type_node, slen));
   8163  1.1  mrg 
   8164  1.1  mrg   /* Wstringop-overflow appears at -O3 even though this warning is not
   8165  1.1  mrg      explicitly available in fortran nor can it be switched off. If the
   8166  1.1  mrg      source length is a constant, its negative appears as a very large
   8167  1.1  mrg      postive number and triggers the warning in BUILTIN_MEMSET. Fixing
   8168  1.1  mrg      the result of the MINUS_EXPR suppresses this spurious warning.  */
   8169  1.1  mrg   tmp = fold_build2_loc (input_location, MINUS_EXPR,
   8170  1.1  mrg 			 TREE_TYPE(dlen), dlen, slen);
   8171  1.1  mrg   if (slength && TREE_CONSTANT (slength))
   8172  1.1  mrg     tmp = gfc_evaluate_now (tmp, block);
   8173  1.1  mrg 
   8174  1.1  mrg   tmp4 = fold_build_pointer_plus_loc (input_location, dest, slen);
   8175  1.1  mrg   tmp4 = fill_with_spaces (tmp4, chartype, tmp);
   8176  1.1  mrg 
   8177  1.1  mrg   gfc_init_block (&tempblock);
   8178  1.1  mrg   gfc_add_expr_to_block (&tempblock, tmp3);
   8179  1.1  mrg   gfc_add_expr_to_block (&tempblock, tmp4);
   8180  1.1  mrg   tmp3 = gfc_finish_block (&tempblock);
   8181  1.1  mrg 
   8182  1.1  mrg   /* The truncated memmove if the slen >= dlen.  */
   8183  1.1  mrg   tmp2 = build_call_expr_loc (input_location,
   8184  1.1  mrg 			      builtin_decl_explicit (BUILT_IN_MEMMOVE),
   8185  1.1  mrg 			      3, dest, src,
   8186  1.1  mrg 			      fold_convert (size_type_node, dlen));
   8187  1.1  mrg 
   8188  1.1  mrg   /* The whole copy_string function is there.  */
   8189  1.1  mrg   tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond2,
   8190  1.1  mrg 			 tmp3, tmp2);
   8191  1.1  mrg   tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond, tmp,
   8192  1.1  mrg 			 build_empty_stmt (input_location));
   8193  1.1  mrg   gfc_add_expr_to_block (block, tmp);
   8194  1.1  mrg }
   8195  1.1  mrg 
   8196  1.1  mrg 
   8197  1.1  mrg /* Translate a statement function.
   8198  1.1  mrg    The value of a statement function reference is obtained by evaluating the
   8199  1.1  mrg    expression using the values of the actual arguments for the values of the
   8200  1.1  mrg    corresponding dummy arguments.  */
   8201  1.1  mrg 
   8202  1.1  mrg static void
   8203  1.1  mrg gfc_conv_statement_function (gfc_se * se, gfc_expr * expr)
   8204  1.1  mrg {
   8205  1.1  mrg   gfc_symbol *sym;
   8206  1.1  mrg   gfc_symbol *fsym;
   8207  1.1  mrg   gfc_formal_arglist *fargs;
   8208  1.1  mrg   gfc_actual_arglist *args;
   8209  1.1  mrg   gfc_se lse;
   8210  1.1  mrg   gfc_se rse;
   8211  1.1  mrg   gfc_saved_var *saved_vars;
   8212  1.1  mrg   tree *temp_vars;
   8213  1.1  mrg   tree type;
   8214  1.1  mrg   tree tmp;
   8215  1.1  mrg   int n;
   8216  1.1  mrg 
   8217  1.1  mrg   sym = expr->symtree->n.sym;
   8218  1.1  mrg   args = expr->value.function.actual;
   8219  1.1  mrg   gfc_init_se (&lse, NULL);
   8220  1.1  mrg   gfc_init_se (&rse, NULL);
   8221  1.1  mrg 
   8222  1.1  mrg   n = 0;
   8223  1.1  mrg   for (fargs = gfc_sym_get_dummy_args (sym); fargs; fargs = fargs->next)
   8224  1.1  mrg     n++;
   8225  1.1  mrg   saved_vars = XCNEWVEC (gfc_saved_var, n);
   8226  1.1  mrg   temp_vars = XCNEWVEC (tree, n);
   8227  1.1  mrg 
   8228  1.1  mrg   for (fargs = gfc_sym_get_dummy_args (sym), n = 0; fargs;
   8229  1.1  mrg        fargs = fargs->next, n++)
   8230  1.1  mrg     {
   8231  1.1  mrg       /* Each dummy shall be specified, explicitly or implicitly, to be
   8232  1.1  mrg          scalar.  */
   8233  1.1  mrg       gcc_assert (fargs->sym->attr.dimension == 0);
   8234  1.1  mrg       fsym = fargs->sym;
   8235  1.1  mrg 
   8236  1.1  mrg       if (fsym->ts.type == BT_CHARACTER)
   8237  1.1  mrg         {
   8238  1.1  mrg 	  /* Copy string arguments.  */
   8239  1.1  mrg 	  tree arglen;
   8240  1.1  mrg 
   8241  1.1  mrg 	  gcc_assert (fsym->ts.u.cl && fsym->ts.u.cl->length
   8242  1.1  mrg 		      && fsym->ts.u.cl->length->expr_type == EXPR_CONSTANT);
   8243  1.1  mrg 
   8244  1.1  mrg 	  /* Create a temporary to hold the value.  */
   8245  1.1  mrg           if (fsym->ts.u.cl->backend_decl == NULL_TREE)
   8246  1.1  mrg 	     fsym->ts.u.cl->backend_decl
   8247  1.1  mrg 		= gfc_conv_constant_to_tree (fsym->ts.u.cl->length);
   8248  1.1  mrg 
   8249  1.1  mrg 	  type = gfc_get_character_type (fsym->ts.kind, fsym->ts.u.cl);
   8250  1.1  mrg 	  temp_vars[n] = gfc_create_var (type, fsym->name);
   8251  1.1  mrg 
   8252  1.1  mrg 	  arglen = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
   8253  1.1  mrg 
   8254  1.1  mrg 	  gfc_conv_expr (&rse, args->expr);
   8255  1.1  mrg 	  gfc_conv_string_parameter (&rse);
   8256  1.1  mrg 	  gfc_add_block_to_block (&se->pre, &lse.pre);
   8257  1.1  mrg 	  gfc_add_block_to_block (&se->pre, &rse.pre);
   8258  1.1  mrg 
   8259  1.1  mrg 	  gfc_trans_string_copy (&se->pre, arglen, temp_vars[n], fsym->ts.kind,
   8260  1.1  mrg 				 rse.string_length, rse.expr, fsym->ts.kind);
   8261  1.1  mrg 	  gfc_add_block_to_block (&se->pre, &lse.post);
   8262  1.1  mrg 	  gfc_add_block_to_block (&se->pre, &rse.post);
   8263  1.1  mrg         }
   8264  1.1  mrg       else
   8265  1.1  mrg         {
   8266  1.1  mrg           /* For everything else, just evaluate the expression.  */
   8267  1.1  mrg 
   8268  1.1  mrg 	  /* Create a temporary to hold the value.  */
   8269  1.1  mrg 	  type = gfc_typenode_for_spec (&fsym->ts);
   8270  1.1  mrg 	  temp_vars[n] = gfc_create_var (type, fsym->name);
   8271  1.1  mrg 
   8272  1.1  mrg           gfc_conv_expr (&lse, args->expr);
   8273  1.1  mrg 
   8274  1.1  mrg           gfc_add_block_to_block (&se->pre, &lse.pre);
   8275  1.1  mrg           gfc_add_modify (&se->pre, temp_vars[n], lse.expr);
   8276  1.1  mrg           gfc_add_block_to_block (&se->pre, &lse.post);
   8277  1.1  mrg         }
   8278  1.1  mrg 
   8279  1.1  mrg       args = args->next;
   8280  1.1  mrg     }
   8281  1.1  mrg 
   8282  1.1  mrg   /* Use the temporary variables in place of the real ones.  */
   8283  1.1  mrg   for (fargs = gfc_sym_get_dummy_args (sym), n = 0; fargs;
   8284  1.1  mrg        fargs = fargs->next, n++)
   8285  1.1  mrg     gfc_shadow_sym (fargs->sym, temp_vars[n], &saved_vars[n]);
   8286  1.1  mrg 
   8287  1.1  mrg   gfc_conv_expr (se, sym->value);
   8288  1.1  mrg 
   8289  1.1  mrg   if (sym->ts.type == BT_CHARACTER)
   8290  1.1  mrg     {
   8291  1.1  mrg       gfc_conv_const_charlen (sym->ts.u.cl);
   8292  1.1  mrg 
   8293  1.1  mrg       /* Force the expression to the correct length.  */
   8294  1.1  mrg       if (!INTEGER_CST_P (se->string_length)
   8295  1.1  mrg 	  || tree_int_cst_lt (se->string_length,
   8296  1.1  mrg 			      sym->ts.u.cl->backend_decl))
   8297  1.1  mrg 	{
   8298  1.1  mrg 	  type = gfc_get_character_type (sym->ts.kind, sym->ts.u.cl);
   8299  1.1  mrg 	  tmp = gfc_create_var (type, sym->name);
   8300  1.1  mrg 	  tmp = gfc_build_addr_expr (build_pointer_type (type), tmp);
   8301  1.1  mrg 	  gfc_trans_string_copy (&se->pre, sym->ts.u.cl->backend_decl, tmp,
   8302  1.1  mrg 				 sym->ts.kind, se->string_length, se->expr,
   8303  1.1  mrg 				 sym->ts.kind);
   8304  1.1  mrg 	  se->expr = tmp;
   8305  1.1  mrg 	}
   8306  1.1  mrg       se->string_length = sym->ts.u.cl->backend_decl;
   8307  1.1  mrg     }
   8308  1.1  mrg 
   8309  1.1  mrg   /* Restore the original variables.  */
   8310  1.1  mrg   for (fargs = gfc_sym_get_dummy_args (sym), n = 0; fargs;
   8311  1.1  mrg        fargs = fargs->next, n++)
   8312  1.1  mrg     gfc_restore_sym (fargs->sym, &saved_vars[n]);
   8313  1.1  mrg   free (temp_vars);
   8314  1.1  mrg   free (saved_vars);
   8315  1.1  mrg }
   8316  1.1  mrg 
   8317  1.1  mrg 
   8318  1.1  mrg /* Translate a function expression.  */
   8319  1.1  mrg 
   8320  1.1  mrg static void
   8321  1.1  mrg gfc_conv_function_expr (gfc_se * se, gfc_expr * expr)
   8322  1.1  mrg {
   8323  1.1  mrg   gfc_symbol *sym;
   8324  1.1  mrg 
   8325  1.1  mrg   if (expr->value.function.isym)
   8326  1.1  mrg     {
   8327  1.1  mrg       gfc_conv_intrinsic_function (se, expr);
   8328  1.1  mrg       return;
   8329  1.1  mrg     }
   8330  1.1  mrg 
   8331  1.1  mrg   /* expr.value.function.esym is the resolved (specific) function symbol for
   8332  1.1  mrg      most functions.  However this isn't set for dummy procedures.  */
   8333  1.1  mrg   sym = expr->value.function.esym;
   8334  1.1  mrg   if (!sym)
   8335  1.1  mrg     sym = expr->symtree->n.sym;
   8336  1.1  mrg 
   8337  1.1  mrg   /* The IEEE_ARITHMETIC functions are caught here. */
   8338  1.1  mrg   if (sym->from_intmod == INTMOD_IEEE_ARITHMETIC)
   8339  1.1  mrg     if (gfc_conv_ieee_arithmetic_function (se, expr))
   8340  1.1  mrg       return;
   8341  1.1  mrg 
   8342  1.1  mrg   /* We distinguish statement functions from general functions to improve
   8343  1.1  mrg      runtime performance.  */
   8344  1.1  mrg   if (sym->attr.proc == PROC_ST_FUNCTION)
   8345  1.1  mrg     {
   8346  1.1  mrg       gfc_conv_statement_function (se, expr);
   8347  1.1  mrg       return;
   8348  1.1  mrg     }
   8349  1.1  mrg 
   8350  1.1  mrg   gfc_conv_procedure_call (se, sym, expr->value.function.actual, expr,
   8351  1.1  mrg 			   NULL);
   8352  1.1  mrg }
   8353  1.1  mrg 
   8354  1.1  mrg 
   8355  1.1  mrg /* Determine whether the given EXPR_CONSTANT is a zero initializer.  */
   8356  1.1  mrg 
   8357  1.1  mrg static bool
   8358  1.1  mrg is_zero_initializer_p (gfc_expr * expr)
   8359  1.1  mrg {
   8360  1.1  mrg   if (expr->expr_type != EXPR_CONSTANT)
   8361  1.1  mrg     return false;
   8362  1.1  mrg 
   8363  1.1  mrg   /* We ignore constants with prescribed memory representations for now.  */
   8364  1.1  mrg   if (expr->representation.string)
   8365  1.1  mrg     return false;
   8366  1.1  mrg 
   8367  1.1  mrg   switch (expr->ts.type)
   8368  1.1  mrg     {
   8369  1.1  mrg     case BT_INTEGER:
   8370  1.1  mrg       return mpz_cmp_si (expr->value.integer, 0) == 0;
   8371  1.1  mrg 
   8372  1.1  mrg     case BT_REAL:
   8373  1.1  mrg       return mpfr_zero_p (expr->value.real)
   8374  1.1  mrg 	     && MPFR_SIGN (expr->value.real) >= 0;
   8375  1.1  mrg 
   8376  1.1  mrg     case BT_LOGICAL:
   8377  1.1  mrg       return expr->value.logical == 0;
   8378  1.1  mrg 
   8379  1.1  mrg     case BT_COMPLEX:
   8380  1.1  mrg       return mpfr_zero_p (mpc_realref (expr->value.complex))
   8381  1.1  mrg 	     && MPFR_SIGN (mpc_realref (expr->value.complex)) >= 0
   8382  1.1  mrg              && mpfr_zero_p (mpc_imagref (expr->value.complex))
   8383  1.1  mrg 	     && MPFR_SIGN (mpc_imagref (expr->value.complex)) >= 0;
   8384  1.1  mrg 
   8385  1.1  mrg     default:
   8386  1.1  mrg       break;
   8387  1.1  mrg     }
   8388  1.1  mrg   return false;
   8389  1.1  mrg }
   8390  1.1  mrg 
   8391  1.1  mrg 
   8392  1.1  mrg static void
   8393  1.1  mrg gfc_conv_array_constructor_expr (gfc_se * se, gfc_expr * expr)
   8394  1.1  mrg {
   8395  1.1  mrg   gfc_ss *ss;
   8396  1.1  mrg 
   8397  1.1  mrg   ss = se->ss;
   8398  1.1  mrg   gcc_assert (ss != NULL && ss != gfc_ss_terminator);
   8399  1.1  mrg   gcc_assert (ss->info->expr == expr && ss->info->type == GFC_SS_CONSTRUCTOR);
   8400  1.1  mrg 
   8401  1.1  mrg   gfc_conv_tmp_array_ref (se);
   8402  1.1  mrg }
   8403  1.1  mrg 
   8404  1.1  mrg 
   8405  1.1  mrg /* Build a static initializer.  EXPR is the expression for the initial value.
   8406  1.1  mrg    The other parameters describe the variable of the component being
   8407  1.1  mrg    initialized. EXPR may be null.  */
   8408  1.1  mrg 
   8409  1.1  mrg tree
   8410  1.1  mrg gfc_conv_initializer (gfc_expr * expr, gfc_typespec * ts, tree type,
   8411  1.1  mrg 		      bool array, bool pointer, bool procptr)
   8412  1.1  mrg {
   8413  1.1  mrg   gfc_se se;
   8414  1.1  mrg 
   8415  1.1  mrg   if (flag_coarray != GFC_FCOARRAY_LIB && ts->type == BT_DERIVED
   8416  1.1  mrg       && ts->u.derived->from_intmod == INTMOD_ISO_FORTRAN_ENV
   8417  1.1  mrg       && ts->u.derived->intmod_sym_id == ISOFORTRAN_EVENT_TYPE)
   8418  1.1  mrg     return build_constructor (type, NULL);
   8419  1.1  mrg 
   8420  1.1  mrg   if (!(expr || pointer || procptr))
   8421  1.1  mrg     return NULL_TREE;
   8422  1.1  mrg 
   8423  1.1  mrg   /* Check if we have ISOCBINDING_NULL_PTR or ISOCBINDING_NULL_FUNPTR
   8424  1.1  mrg      (these are the only two iso_c_binding derived types that can be
   8425  1.1  mrg      used as initialization expressions).  If so, we need to modify
   8426  1.1  mrg      the 'expr' to be that for a (void *).  */
   8427  1.1  mrg   if (expr != NULL && expr->ts.type == BT_DERIVED
   8428  1.1  mrg       && expr->ts.is_iso_c && expr->ts.u.derived)
   8429  1.1  mrg     {
   8430  1.1  mrg       if (TREE_CODE (type) == ARRAY_TYPE)
   8431  1.1  mrg 	return build_constructor (type, NULL);
   8432  1.1  mrg       else if (POINTER_TYPE_P (type))
   8433  1.1  mrg 	return build_int_cst (type, 0);
   8434  1.1  mrg       else
   8435  1.1  mrg 	gcc_unreachable ();
   8436  1.1  mrg     }
   8437  1.1  mrg 
   8438  1.1  mrg   if (array && !procptr)
   8439  1.1  mrg     {
   8440  1.1  mrg       tree ctor;
   8441  1.1  mrg       /* Arrays need special handling.  */
   8442  1.1  mrg       if (pointer)
   8443  1.1  mrg 	ctor = gfc_build_null_descriptor (type);
   8444  1.1  mrg       /* Special case assigning an array to zero.  */
   8445  1.1  mrg       else if (is_zero_initializer_p (expr))
   8446  1.1  mrg         ctor = build_constructor (type, NULL);
   8447  1.1  mrg       else
   8448  1.1  mrg 	ctor = gfc_conv_array_initializer (type, expr);
   8449  1.1  mrg       TREE_STATIC (ctor) = 1;
   8450  1.1  mrg       return ctor;
   8451  1.1  mrg     }
   8452  1.1  mrg   else if (pointer || procptr)
   8453  1.1  mrg     {
   8454  1.1  mrg       if (ts->type == BT_CLASS && !procptr)
   8455  1.1  mrg 	{
   8456  1.1  mrg 	  gfc_init_se (&se, NULL);
   8457  1.1  mrg 	  gfc_conv_structure (&se, gfc_class_initializer (ts, expr), 1);
   8458  1.1  mrg 	  gcc_assert (TREE_CODE (se.expr) == CONSTRUCTOR);
   8459  1.1  mrg 	  TREE_STATIC (se.expr) = 1;
   8460  1.1  mrg 	  return se.expr;
   8461  1.1  mrg 	}
   8462  1.1  mrg       else if (!expr || expr->expr_type == EXPR_NULL)
   8463  1.1  mrg 	return fold_convert (type, null_pointer_node);
   8464  1.1  mrg       else
   8465  1.1  mrg 	{
   8466  1.1  mrg 	  gfc_init_se (&se, NULL);
   8467  1.1  mrg 	  se.want_pointer = 1;
   8468  1.1  mrg 	  gfc_conv_expr (&se, expr);
   8469  1.1  mrg           gcc_assert (TREE_CODE (se.expr) != CONSTRUCTOR);
   8470  1.1  mrg 	  return se.expr;
   8471  1.1  mrg 	}
   8472  1.1  mrg     }
   8473  1.1  mrg   else
   8474  1.1  mrg     {
   8475  1.1  mrg       switch (ts->type)
   8476  1.1  mrg 	{
   8477  1.1  mrg 	case_bt_struct:
   8478  1.1  mrg 	case BT_CLASS:
   8479  1.1  mrg 	  gfc_init_se (&se, NULL);
   8480  1.1  mrg 	  if (ts->type == BT_CLASS && expr->expr_type == EXPR_NULL)
   8481  1.1  mrg 	    gfc_conv_structure (&se, gfc_class_initializer (ts, expr), 1);
   8482  1.1  mrg 	  else
   8483  1.1  mrg 	    gfc_conv_structure (&se, expr, 1);
   8484  1.1  mrg 	  gcc_assert (TREE_CODE (se.expr) == CONSTRUCTOR);
   8485  1.1  mrg 	  TREE_STATIC (se.expr) = 1;
   8486  1.1  mrg 	  return se.expr;
   8487  1.1  mrg 
   8488  1.1  mrg 	case BT_CHARACTER:
   8489  1.1  mrg 	  if (expr->expr_type == EXPR_CONSTANT)
   8490  1.1  mrg 	    {
   8491  1.1  mrg 	      tree ctor = gfc_conv_string_init (ts->u.cl->backend_decl, expr);
   8492  1.1  mrg 	      TREE_STATIC (ctor) = 1;
   8493  1.1  mrg 	      return ctor;
   8494  1.1  mrg 	    }
   8495  1.1  mrg 
   8496  1.1  mrg 	  /* Fallthrough.  */
   8497  1.1  mrg 	default:
   8498  1.1  mrg 	  gfc_init_se (&se, NULL);
   8499  1.1  mrg 	  gfc_conv_constant (&se, expr);
   8500  1.1  mrg 	  gcc_assert (TREE_CODE (se.expr) != CONSTRUCTOR);
   8501  1.1  mrg 	  return se.expr;
   8502  1.1  mrg 	}
   8503  1.1  mrg     }
   8504  1.1  mrg }
   8505  1.1  mrg 
   8506  1.1  mrg static tree
   8507  1.1  mrg gfc_trans_subarray_assign (tree dest, gfc_component * cm, gfc_expr * expr)
   8508  1.1  mrg {
   8509  1.1  mrg   gfc_se rse;
   8510  1.1  mrg   gfc_se lse;
   8511  1.1  mrg   gfc_ss *rss;
   8512  1.1  mrg   gfc_ss *lss;
   8513  1.1  mrg   gfc_array_info *lss_array;
   8514  1.1  mrg   stmtblock_t body;
   8515  1.1  mrg   stmtblock_t block;
   8516  1.1  mrg   gfc_loopinfo loop;
   8517  1.1  mrg   int n;
   8518  1.1  mrg   tree tmp;
   8519  1.1  mrg 
   8520  1.1  mrg   gfc_start_block (&block);
   8521  1.1  mrg 
   8522  1.1  mrg   /* Initialize the scalarizer.  */
   8523  1.1  mrg   gfc_init_loopinfo (&loop);
   8524  1.1  mrg 
   8525  1.1  mrg   gfc_init_se (&lse, NULL);
   8526  1.1  mrg   gfc_init_se (&rse, NULL);
   8527  1.1  mrg 
   8528  1.1  mrg   /* Walk the rhs.  */
   8529  1.1  mrg   rss = gfc_walk_expr (expr);
   8530  1.1  mrg   if (rss == gfc_ss_terminator)
   8531  1.1  mrg     /* The rhs is scalar.  Add a ss for the expression.  */
   8532  1.1  mrg     rss = gfc_get_scalar_ss (gfc_ss_terminator, expr);
   8533  1.1  mrg 
   8534  1.1  mrg   /* Create a SS for the destination.  */
   8535  1.1  mrg   lss = gfc_get_array_ss (gfc_ss_terminator, NULL, cm->as->rank,
   8536  1.1  mrg 			  GFC_SS_COMPONENT);
   8537  1.1  mrg   lss_array = &lss->info->data.array;
   8538  1.1  mrg   lss_array->shape = gfc_get_shape (cm->as->rank);
   8539  1.1  mrg   lss_array->descriptor = dest;
   8540  1.1  mrg   lss_array->data = gfc_conv_array_data (dest);
   8541  1.1  mrg   lss_array->offset = gfc_conv_array_offset (dest);
   8542  1.1  mrg   for (n = 0; n < cm->as->rank; n++)
   8543  1.1  mrg     {
   8544  1.1  mrg       lss_array->start[n] = gfc_conv_array_lbound (dest, n);
   8545  1.1  mrg       lss_array->stride[n] = gfc_index_one_node;
   8546  1.1  mrg 
   8547  1.1  mrg       mpz_init (lss_array->shape[n]);
   8548  1.1  mrg       mpz_sub (lss_array->shape[n], cm->as->upper[n]->value.integer,
   8549  1.1  mrg 	       cm->as->lower[n]->value.integer);
   8550  1.1  mrg       mpz_add_ui (lss_array->shape[n], lss_array->shape[n], 1);
   8551  1.1  mrg     }
   8552  1.1  mrg 
   8553  1.1  mrg   /* Associate the SS with the loop.  */
   8554  1.1  mrg   gfc_add_ss_to_loop (&loop, lss);
   8555  1.1  mrg   gfc_add_ss_to_loop (&loop, rss);
   8556  1.1  mrg 
   8557  1.1  mrg   /* Calculate the bounds of the scalarization.  */
   8558  1.1  mrg   gfc_conv_ss_startstride (&loop);
   8559  1.1  mrg 
   8560  1.1  mrg   /* Setup the scalarizing loops.  */
   8561  1.1  mrg   gfc_conv_loop_setup (&loop, &expr->where);
   8562  1.1  mrg 
   8563  1.1  mrg   /* Setup the gfc_se structures.  */
   8564  1.1  mrg   gfc_copy_loopinfo_to_se (&lse, &loop);
   8565  1.1  mrg   gfc_copy_loopinfo_to_se (&rse, &loop);
   8566  1.1  mrg 
   8567  1.1  mrg   rse.ss = rss;
   8568  1.1  mrg   gfc_mark_ss_chain_used (rss, 1);
   8569  1.1  mrg   lse.ss = lss;
   8570  1.1  mrg   gfc_mark_ss_chain_used (lss, 1);
   8571  1.1  mrg 
   8572  1.1  mrg   /* Start the scalarized loop body.  */
   8573  1.1  mrg   gfc_start_scalarized_body (&loop, &body);
   8574  1.1  mrg 
   8575  1.1  mrg   gfc_conv_tmp_array_ref (&lse);
   8576  1.1  mrg   if (cm->ts.type == BT_CHARACTER)
   8577  1.1  mrg     lse.string_length = cm->ts.u.cl->backend_decl;
   8578  1.1  mrg 
   8579  1.1  mrg   gfc_conv_expr (&rse, expr);
   8580  1.1  mrg 
   8581  1.1  mrg   tmp = gfc_trans_scalar_assign (&lse, &rse, cm->ts, true, false);
   8582  1.1  mrg   gfc_add_expr_to_block (&body, tmp);
   8583  1.1  mrg 
   8584  1.1  mrg   gcc_assert (rse.ss == gfc_ss_terminator);
   8585  1.1  mrg 
   8586  1.1  mrg   /* Generate the copying loops.  */
   8587  1.1  mrg   gfc_trans_scalarizing_loops (&loop, &body);
   8588  1.1  mrg 
   8589  1.1  mrg   /* Wrap the whole thing up.  */
   8590  1.1  mrg   gfc_add_block_to_block (&block, &loop.pre);
   8591  1.1  mrg   gfc_add_block_to_block (&block, &loop.post);
   8592  1.1  mrg 
   8593  1.1  mrg   gcc_assert (lss_array->shape != NULL);
   8594  1.1  mrg   gfc_free_shape (&lss_array->shape, cm->as->rank);
   8595  1.1  mrg   gfc_cleanup_loop (&loop);
   8596  1.1  mrg 
   8597  1.1  mrg   return gfc_finish_block (&block);
   8598  1.1  mrg }
   8599  1.1  mrg 
   8600  1.1  mrg 
   8601  1.1  mrg static tree
   8602  1.1  mrg gfc_trans_alloc_subarray_assign (tree dest, gfc_component * cm,
   8603  1.1  mrg 				 gfc_expr * expr)
   8604  1.1  mrg {
   8605  1.1  mrg   gfc_se se;
   8606  1.1  mrg   stmtblock_t block;
   8607  1.1  mrg   tree offset;
   8608  1.1  mrg   int n;
   8609  1.1  mrg   tree tmp;
   8610  1.1  mrg   tree tmp2;
   8611  1.1  mrg   gfc_array_spec *as;
   8612  1.1  mrg   gfc_expr *arg = NULL;
   8613  1.1  mrg 
   8614  1.1  mrg   gfc_start_block (&block);
   8615  1.1  mrg   gfc_init_se (&se, NULL);
   8616  1.1  mrg 
   8617  1.1  mrg   /* Get the descriptor for the expressions.  */
   8618  1.1  mrg   se.want_pointer = 0;
   8619  1.1  mrg   gfc_conv_expr_descriptor (&se, expr);
   8620  1.1  mrg   gfc_add_block_to_block (&block, &se.pre);
   8621  1.1  mrg   gfc_add_modify (&block, dest, se.expr);
   8622  1.1  mrg 
   8623  1.1  mrg   /* Deal with arrays of derived types with allocatable components.  */
   8624  1.1  mrg   if (gfc_bt_struct (cm->ts.type)
   8625  1.1  mrg 	&& cm->ts.u.derived->attr.alloc_comp)
   8626  1.1  mrg     // TODO: Fix caf_mode
   8627  1.1  mrg     tmp = gfc_copy_alloc_comp (cm->ts.u.derived,
   8628  1.1  mrg 			       se.expr, dest,
   8629  1.1  mrg 			       cm->as->rank, 0);
   8630  1.1  mrg   else if (cm->ts.type == BT_CLASS && expr->ts.type == BT_DERIVED
   8631  1.1  mrg 	   && CLASS_DATA(cm)->attr.allocatable)
   8632  1.1  mrg     {
   8633  1.1  mrg       if (cm->ts.u.derived->attr.alloc_comp)
   8634  1.1  mrg 	// TODO: Fix caf_mode
   8635  1.1  mrg 	tmp = gfc_copy_alloc_comp (expr->ts.u.derived,
   8636  1.1  mrg 				   se.expr, dest,
   8637  1.1  mrg 				   expr->rank, 0);
   8638  1.1  mrg       else
   8639  1.1  mrg 	{
   8640  1.1  mrg 	  tmp = TREE_TYPE (dest);
   8641  1.1  mrg 	  tmp = gfc_duplicate_allocatable (dest, se.expr,
   8642  1.1  mrg 					   tmp, expr->rank, NULL_TREE);
   8643  1.1  mrg 	}
   8644  1.1  mrg     }
   8645  1.1  mrg   else
   8646  1.1  mrg     tmp = gfc_duplicate_allocatable (dest, se.expr,
   8647  1.1  mrg 				     TREE_TYPE(cm->backend_decl),
   8648  1.1  mrg 				     cm->as->rank, NULL_TREE);
   8649  1.1  mrg 
   8650  1.1  mrg   gfc_add_expr_to_block (&block, tmp);
   8651  1.1  mrg   gfc_add_block_to_block (&block, &se.post);
   8652  1.1  mrg 
   8653  1.1  mrg   if (expr->expr_type != EXPR_VARIABLE)
   8654  1.1  mrg     gfc_conv_descriptor_data_set (&block, se.expr,
   8655  1.1  mrg 				  null_pointer_node);
   8656  1.1  mrg 
   8657  1.1  mrg   /* We need to know if the argument of a conversion function is a
   8658  1.1  mrg      variable, so that the correct lower bound can be used.  */
   8659  1.1  mrg   if (expr->expr_type == EXPR_FUNCTION
   8660  1.1  mrg 	&& expr->value.function.isym
   8661  1.1  mrg 	&& expr->value.function.isym->conversion
   8662  1.1  mrg 	&& expr->value.function.actual->expr
   8663  1.1  mrg 	&& expr->value.function.actual->expr->expr_type == EXPR_VARIABLE)
   8664  1.1  mrg     arg = expr->value.function.actual->expr;
   8665  1.1  mrg 
   8666  1.1  mrg   /* Obtain the array spec of full array references.  */
   8667  1.1  mrg   if (arg)
   8668  1.1  mrg     as = gfc_get_full_arrayspec_from_expr (arg);
   8669  1.1  mrg   else
   8670  1.1  mrg     as = gfc_get_full_arrayspec_from_expr (expr);
   8671  1.1  mrg 
   8672  1.1  mrg   /* Shift the lbound and ubound of temporaries to being unity,
   8673  1.1  mrg      rather than zero, based. Always calculate the offset.  */
   8674  1.1  mrg   offset = gfc_conv_descriptor_offset_get (dest);
   8675  1.1  mrg   gfc_add_modify (&block, offset, gfc_index_zero_node);
   8676  1.1  mrg   tmp2 =gfc_create_var (gfc_array_index_type, NULL);
   8677  1.1  mrg 
   8678  1.1  mrg   for (n = 0; n < expr->rank; n++)
   8679  1.1  mrg     {
   8680  1.1  mrg       tree span;
   8681  1.1  mrg       tree lbound;
   8682  1.1  mrg 
   8683  1.1  mrg       /* Obtain the correct lbound - ISO/IEC TR 15581:2001 page 9.
   8684  1.1  mrg 	 TODO It looks as if gfc_conv_expr_descriptor should return
   8685  1.1  mrg 	 the correct bounds and that the following should not be
   8686  1.1  mrg 	 necessary.  This would simplify gfc_conv_intrinsic_bound
   8687  1.1  mrg 	 as well.  */
   8688  1.1  mrg       if (as && as->lower[n])
   8689  1.1  mrg 	{
   8690  1.1  mrg 	  gfc_se lbse;
   8691  1.1  mrg 	  gfc_init_se (&lbse, NULL);
   8692  1.1  mrg 	  gfc_conv_expr (&lbse, as->lower[n]);
   8693  1.1  mrg 	  gfc_add_block_to_block (&block, &lbse.pre);
   8694  1.1  mrg 	  lbound = gfc_evaluate_now (lbse.expr, &block);
   8695  1.1  mrg 	}
   8696  1.1  mrg       else if (as && arg)
   8697  1.1  mrg 	{
   8698  1.1  mrg 	  tmp = gfc_get_symbol_decl (arg->symtree->n.sym);
   8699  1.1  mrg 	  lbound = gfc_conv_descriptor_lbound_get (tmp,
   8700  1.1  mrg 					gfc_rank_cst[n]);
   8701  1.1  mrg 	}
   8702  1.1  mrg       else if (as)
   8703  1.1  mrg 	lbound = gfc_conv_descriptor_lbound_get (dest,
   8704  1.1  mrg 						gfc_rank_cst[n]);
   8705  1.1  mrg       else
   8706  1.1  mrg 	lbound = gfc_index_one_node;
   8707  1.1  mrg 
   8708  1.1  mrg       lbound = fold_convert (gfc_array_index_type, lbound);
   8709  1.1  mrg 
   8710  1.1  mrg       /* Shift the bounds and set the offset accordingly.  */
   8711  1.1  mrg       tmp = gfc_conv_descriptor_ubound_get (dest, gfc_rank_cst[n]);
   8712  1.1  mrg       span = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
   8713  1.1  mrg 		tmp, gfc_conv_descriptor_lbound_get (dest, gfc_rank_cst[n]));
   8714  1.1  mrg       tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
   8715  1.1  mrg 			     span, lbound);
   8716  1.1  mrg       gfc_conv_descriptor_ubound_set (&block, dest,
   8717  1.1  mrg 				      gfc_rank_cst[n], tmp);
   8718  1.1  mrg       gfc_conv_descriptor_lbound_set (&block, dest,
   8719  1.1  mrg 				      gfc_rank_cst[n], lbound);
   8720  1.1  mrg 
   8721  1.1  mrg       tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
   8722  1.1  mrg 			 gfc_conv_descriptor_lbound_get (dest,
   8723  1.1  mrg 							 gfc_rank_cst[n]),
   8724  1.1  mrg 			 gfc_conv_descriptor_stride_get (dest,
   8725  1.1  mrg 							 gfc_rank_cst[n]));
   8726  1.1  mrg       gfc_add_modify (&block, tmp2, tmp);
   8727  1.1  mrg       tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
   8728  1.1  mrg 			     offset, tmp2);
   8729  1.1  mrg       gfc_conv_descriptor_offset_set (&block, dest, tmp);
   8730  1.1  mrg     }
   8731  1.1  mrg 
   8732  1.1  mrg   if (arg)
   8733  1.1  mrg     {
   8734  1.1  mrg       /* If a conversion expression has a null data pointer
   8735  1.1  mrg 	 argument, nullify the allocatable component.  */
   8736  1.1  mrg       tree non_null_expr;
   8737  1.1  mrg       tree null_expr;
   8738  1.1  mrg 
   8739  1.1  mrg       if (arg->symtree->n.sym->attr.allocatable
   8740  1.1  mrg 	    || arg->symtree->n.sym->attr.pointer)
   8741  1.1  mrg 	{
   8742  1.1  mrg 	  non_null_expr = gfc_finish_block (&block);
   8743  1.1  mrg 	  gfc_start_block (&block);
   8744  1.1  mrg 	  gfc_conv_descriptor_data_set (&block, dest,
   8745  1.1  mrg 					null_pointer_node);
   8746  1.1  mrg 	  null_expr = gfc_finish_block (&block);
   8747  1.1  mrg 	  tmp = gfc_conv_descriptor_data_get (arg->symtree->n.sym->backend_decl);
   8748  1.1  mrg 	  tmp = build2_loc (input_location, EQ_EXPR, logical_type_node, tmp,
   8749  1.1  mrg 			    fold_convert (TREE_TYPE (tmp), null_pointer_node));
   8750  1.1  mrg 	  return build3_v (COND_EXPR, tmp,
   8751  1.1  mrg 			   null_expr, non_null_expr);
   8752  1.1  mrg 	}
   8753  1.1  mrg     }
   8754  1.1  mrg 
   8755  1.1  mrg   return gfc_finish_block (&block);
   8756  1.1  mrg }
   8757  1.1  mrg 
   8758  1.1  mrg 
   8759  1.1  mrg /* Allocate or reallocate scalar component, as necessary.  */
   8760  1.1  mrg 
   8761  1.1  mrg static void
   8762  1.1  mrg alloc_scalar_allocatable_for_subcomponent_assignment (stmtblock_t *block,
   8763  1.1  mrg 						      tree comp,
   8764  1.1  mrg 						      gfc_component *cm,
   8765  1.1  mrg 						      gfc_expr *expr2,
   8766  1.1  mrg 						      gfc_symbol *sym)
   8767  1.1  mrg {
   8768  1.1  mrg   tree tmp;
   8769  1.1  mrg   tree ptr;
   8770  1.1  mrg   tree size;
   8771  1.1  mrg   tree size_in_bytes;
   8772  1.1  mrg   tree lhs_cl_size = NULL_TREE;
   8773  1.1  mrg 
   8774  1.1  mrg   if (!comp)
   8775  1.1  mrg     return;
   8776  1.1  mrg 
   8777  1.1  mrg   if (!expr2 || expr2->rank)
   8778  1.1  mrg     return;
   8779  1.1  mrg 
   8780  1.1  mrg   realloc_lhs_warning (expr2->ts.type, false, &expr2->where);
   8781  1.1  mrg 
   8782  1.1  mrg   if (cm->ts.type == BT_CHARACTER && cm->ts.deferred)
   8783  1.1  mrg     {
   8784  1.1  mrg       char name[GFC_MAX_SYMBOL_LEN+9];
   8785  1.1  mrg       gfc_component *strlen;
   8786  1.1  mrg       /* Use the rhs string length and the lhs element size.  */
   8787  1.1  mrg       gcc_assert (expr2->ts.type == BT_CHARACTER);
   8788  1.1  mrg       if (!expr2->ts.u.cl->backend_decl)
   8789  1.1  mrg 	{
   8790  1.1  mrg 	  gfc_conv_string_length (expr2->ts.u.cl, expr2, block);
   8791  1.1  mrg 	  gcc_assert (expr2->ts.u.cl->backend_decl);
   8792  1.1  mrg 	}
   8793  1.1  mrg 
   8794  1.1  mrg       size = expr2->ts.u.cl->backend_decl;
   8795  1.1  mrg 
   8796  1.1  mrg       /* Ensure that cm->ts.u.cl->backend_decl is a componentref to _%s_length
   8797  1.1  mrg 	 component.  */
   8798  1.1  mrg       sprintf (name, "_%s_length", cm->name);
   8799  1.1  mrg       strlen = gfc_find_component (sym, name, true, true, NULL);
   8800  1.1  mrg       lhs_cl_size = fold_build3_loc (input_location, COMPONENT_REF,
   8801  1.1  mrg 				     gfc_charlen_type_node,
   8802  1.1  mrg 				     TREE_OPERAND (comp, 0),
   8803  1.1  mrg 				     strlen->backend_decl, NULL_TREE);
   8804  1.1  mrg 
   8805  1.1  mrg       tmp = TREE_TYPE (gfc_typenode_for_spec (&cm->ts));
   8806  1.1  mrg       tmp = TYPE_SIZE_UNIT (tmp);
   8807  1.1  mrg       size_in_bytes = fold_build2_loc (input_location, MULT_EXPR,
   8808  1.1  mrg 				       TREE_TYPE (tmp), tmp,
   8809  1.1  mrg 				       fold_convert (TREE_TYPE (tmp), size));
   8810  1.1  mrg     }
   8811  1.1  mrg   else if (cm->ts.type == BT_CLASS)
   8812  1.1  mrg     {
   8813  1.1  mrg       gcc_assert (expr2->ts.type == BT_CLASS || expr2->ts.type == BT_DERIVED);
   8814  1.1  mrg       if (expr2->ts.type == BT_DERIVED)
   8815  1.1  mrg 	{
   8816  1.1  mrg 	  tmp = gfc_get_symbol_decl (expr2->ts.u.derived);
   8817  1.1  mrg 	  size = TYPE_SIZE_UNIT (tmp);
   8818  1.1  mrg 	}
   8819  1.1  mrg       else
   8820  1.1  mrg 	{
   8821  1.1  mrg 	  gfc_expr *e2vtab;
   8822  1.1  mrg 	  gfc_se se;
   8823  1.1  mrg 	  e2vtab = gfc_find_and_cut_at_last_class_ref (expr2);
   8824  1.1  mrg 	  gfc_add_vptr_component (e2vtab);
   8825  1.1  mrg 	  gfc_add_size_component (e2vtab);
   8826  1.1  mrg 	  gfc_init_se (&se, NULL);
   8827  1.1  mrg 	  gfc_conv_expr (&se, e2vtab);
   8828  1.1  mrg 	  gfc_add_block_to_block (block, &se.pre);
   8829  1.1  mrg 	  size = fold_convert (size_type_node, se.expr);
   8830  1.1  mrg 	  gfc_free_expr (e2vtab);
   8831  1.1  mrg 	}
   8832  1.1  mrg       size_in_bytes = size;
   8833  1.1  mrg     }
   8834  1.1  mrg   else
   8835  1.1  mrg     {
   8836  1.1  mrg       /* Otherwise use the length in bytes of the rhs.  */
   8837  1.1  mrg       size = TYPE_SIZE_UNIT (gfc_typenode_for_spec (&cm->ts));
   8838  1.1  mrg       size_in_bytes = size;
   8839  1.1  mrg     }
   8840  1.1  mrg 
   8841  1.1  mrg   size_in_bytes = fold_build2_loc (input_location, MAX_EXPR, size_type_node,
   8842  1.1  mrg 				   size_in_bytes, size_one_node);
   8843  1.1  mrg 
   8844  1.1  mrg   if (cm->ts.type == BT_DERIVED && cm->ts.u.derived->attr.alloc_comp)
   8845  1.1  mrg     {
   8846  1.1  mrg       tmp = build_call_expr_loc (input_location,
   8847  1.1  mrg 				 builtin_decl_explicit (BUILT_IN_CALLOC),
   8848  1.1  mrg 				 2, build_one_cst (size_type_node),
   8849  1.1  mrg 				 size_in_bytes);
   8850  1.1  mrg       tmp = fold_convert (TREE_TYPE (comp), tmp);
   8851  1.1  mrg       gfc_add_modify (block, comp, tmp);
   8852  1.1  mrg     }
   8853  1.1  mrg   else
   8854  1.1  mrg     {
   8855  1.1  mrg       tmp = build_call_expr_loc (input_location,
   8856  1.1  mrg 				 builtin_decl_explicit (BUILT_IN_MALLOC),
   8857  1.1  mrg 				 1, size_in_bytes);
   8858  1.1  mrg       if (GFC_CLASS_TYPE_P (TREE_TYPE (comp)))
   8859  1.1  mrg 	ptr = gfc_class_data_get (comp);
   8860  1.1  mrg       else
   8861  1.1  mrg 	ptr = comp;
   8862  1.1  mrg       tmp = fold_convert (TREE_TYPE (ptr), tmp);
   8863  1.1  mrg       gfc_add_modify (block, ptr, tmp);
   8864  1.1  mrg     }
   8865  1.1  mrg 
   8866  1.1  mrg   if (cm->ts.type == BT_CHARACTER && cm->ts.deferred)
   8867  1.1  mrg     /* Update the lhs character length.  */
   8868  1.1  mrg     gfc_add_modify (block, lhs_cl_size,
   8869  1.1  mrg 		    fold_convert (TREE_TYPE (lhs_cl_size), size));
   8870  1.1  mrg }
   8871  1.1  mrg 
   8872  1.1  mrg 
   8873  1.1  mrg /* Assign a single component of a derived type constructor.  */
   8874  1.1  mrg 
   8875  1.1  mrg static tree
   8876  1.1  mrg gfc_trans_subcomponent_assign (tree dest, gfc_component * cm, gfc_expr * expr,
   8877  1.1  mrg 			       gfc_symbol *sym, bool init)
   8878  1.1  mrg {
   8879  1.1  mrg   gfc_se se;
   8880  1.1  mrg   gfc_se lse;
   8881  1.1  mrg   stmtblock_t block;
   8882  1.1  mrg   tree tmp;
   8883  1.1  mrg   tree vtab;
   8884  1.1  mrg 
   8885  1.1  mrg   gfc_start_block (&block);
   8886  1.1  mrg 
   8887  1.1  mrg   if (cm->attr.pointer || cm->attr.proc_pointer)
   8888  1.1  mrg     {
   8889  1.1  mrg       /* Only care about pointers here, not about allocatables.  */
   8890  1.1  mrg       gfc_init_se (&se, NULL);
   8891  1.1  mrg       /* Pointer component.  */
   8892  1.1  mrg       if ((cm->attr.dimension || cm->attr.codimension)
   8893  1.1  mrg 	  && !cm->attr.proc_pointer)
   8894  1.1  mrg 	{
   8895  1.1  mrg 	  /* Array pointer.  */
   8896  1.1  mrg 	  if (expr->expr_type == EXPR_NULL)
   8897  1.1  mrg 	    gfc_conv_descriptor_data_set (&block, dest, null_pointer_node);
   8898  1.1  mrg 	  else
   8899  1.1  mrg 	    {
   8900  1.1  mrg 	      se.direct_byref = 1;
   8901  1.1  mrg 	      se.expr = dest;
   8902  1.1  mrg 	      gfc_conv_expr_descriptor (&se, expr);
   8903  1.1  mrg 	      gfc_add_block_to_block (&block, &se.pre);
   8904  1.1  mrg 	      gfc_add_block_to_block (&block, &se.post);
   8905  1.1  mrg 	    }
   8906  1.1  mrg 	}
   8907  1.1  mrg       else
   8908  1.1  mrg 	{
   8909  1.1  mrg 	  /* Scalar pointers.  */
   8910  1.1  mrg 	  se.want_pointer = 1;
   8911  1.1  mrg 	  gfc_conv_expr (&se, expr);
   8912  1.1  mrg 	  gfc_add_block_to_block (&block, &se.pre);
   8913  1.1  mrg 
   8914  1.1  mrg 	  if (expr->symtree && expr->symtree->n.sym->attr.proc_pointer
   8915  1.1  mrg 	      && expr->symtree->n.sym->attr.dummy)
   8916  1.1  mrg 	    se.expr = build_fold_indirect_ref_loc (input_location, se.expr);
   8917  1.1  mrg 
   8918  1.1  mrg 	  gfc_add_modify (&block, dest,
   8919  1.1  mrg 			       fold_convert (TREE_TYPE (dest), se.expr));
   8920  1.1  mrg 	  gfc_add_block_to_block (&block, &se.post);
   8921  1.1  mrg 	}
   8922  1.1  mrg     }
   8923  1.1  mrg   else if (cm->ts.type == BT_CLASS && expr->expr_type == EXPR_NULL)
   8924  1.1  mrg     {
   8925  1.1  mrg       /* NULL initialization for CLASS components.  */
   8926  1.1  mrg       tmp = gfc_trans_structure_assign (dest,
   8927  1.1  mrg 					gfc_class_initializer (&cm->ts, expr),
   8928  1.1  mrg 					false);
   8929  1.1  mrg       gfc_add_expr_to_block (&block, tmp);
   8930  1.1  mrg     }
   8931  1.1  mrg   else if ((cm->attr.dimension || cm->attr.codimension)
   8932  1.1  mrg 	   && !cm->attr.proc_pointer)
   8933  1.1  mrg     {
   8934  1.1  mrg       if (cm->attr.allocatable && expr->expr_type == EXPR_NULL)
   8935  1.1  mrg  	gfc_conv_descriptor_data_set (&block, dest, null_pointer_node);
   8936  1.1  mrg       else if (cm->attr.allocatable || cm->attr.pdt_array)
   8937  1.1  mrg 	{
   8938  1.1  mrg 	  tmp = gfc_trans_alloc_subarray_assign (dest, cm, expr);
   8939  1.1  mrg 	  gfc_add_expr_to_block (&block, tmp);
   8940  1.1  mrg 	}
   8941  1.1  mrg       else
   8942  1.1  mrg 	{
   8943  1.1  mrg 	  tmp = gfc_trans_subarray_assign (dest, cm, expr);
   8944  1.1  mrg 	  gfc_add_expr_to_block (&block, tmp);
   8945  1.1  mrg 	}
   8946  1.1  mrg     }
   8947  1.1  mrg   else if (cm->ts.type == BT_CLASS
   8948  1.1  mrg 	   && CLASS_DATA (cm)->attr.dimension
   8949  1.1  mrg 	   && CLASS_DATA (cm)->attr.allocatable
   8950  1.1  mrg 	   && expr->ts.type == BT_DERIVED)
   8951  1.1  mrg     {
   8952  1.1  mrg       vtab = gfc_get_symbol_decl (gfc_find_vtab (&expr->ts));
   8953  1.1  mrg       vtab = gfc_build_addr_expr (NULL_TREE, vtab);
   8954  1.1  mrg       tmp = gfc_class_vptr_get (dest);
   8955  1.1  mrg       gfc_add_modify (&block, tmp,
   8956  1.1  mrg 		      fold_convert (TREE_TYPE (tmp), vtab));
   8957  1.1  mrg       tmp = gfc_class_data_get (dest);
   8958  1.1  mrg       tmp = gfc_trans_alloc_subarray_assign (tmp, cm, expr);
   8959  1.1  mrg       gfc_add_expr_to_block (&block, tmp);
   8960  1.1  mrg     }
   8961  1.1  mrg   else if (init && cm->attr.allocatable && expr->expr_type == EXPR_NULL)
   8962  1.1  mrg     {
   8963  1.1  mrg       /* NULL initialization for allocatable components.  */
   8964  1.1  mrg       gfc_add_modify (&block, dest, fold_convert (TREE_TYPE (dest),
   8965  1.1  mrg 						  null_pointer_node));
   8966  1.1  mrg     }
   8967  1.1  mrg   else if (init && (cm->attr.allocatable
   8968  1.1  mrg 	   || (cm->ts.type == BT_CLASS && CLASS_DATA (cm)->attr.allocatable
   8969  1.1  mrg 	       && expr->ts.type != BT_CLASS)))
   8970  1.1  mrg     {
   8971  1.1  mrg       /* Take care about non-array allocatable components here.  The alloc_*
   8972  1.1  mrg 	 routine below is motivated by the alloc_scalar_allocatable_for_
   8973  1.1  mrg 	 assignment() routine, but with the realloc portions removed and
   8974  1.1  mrg 	 different input.  */
   8975  1.1  mrg       alloc_scalar_allocatable_for_subcomponent_assignment (&block,
   8976  1.1  mrg 							    dest,
   8977  1.1  mrg 							    cm,
   8978  1.1  mrg 							    expr,
   8979  1.1  mrg 							    sym);
   8980  1.1  mrg       /* The remainder of these instructions follow the if (cm->attr.pointer)
   8981  1.1  mrg 	 if (!cm->attr.dimension) part above.  */
   8982  1.1  mrg       gfc_init_se (&se, NULL);
   8983  1.1  mrg       gfc_conv_expr (&se, expr);
   8984  1.1  mrg       gfc_add_block_to_block (&block, &se.pre);
   8985  1.1  mrg 
   8986  1.1  mrg       if (expr->symtree && expr->symtree->n.sym->attr.proc_pointer
   8987  1.1  mrg 	  && expr->symtree->n.sym->attr.dummy)
   8988  1.1  mrg 	se.expr = build_fold_indirect_ref_loc (input_location, se.expr);
   8989  1.1  mrg 
   8990  1.1  mrg       if (cm->ts.type == BT_CLASS && expr->ts.type == BT_DERIVED)
   8991  1.1  mrg 	{
   8992  1.1  mrg 	  tmp = gfc_class_data_get (dest);
   8993  1.1  mrg 	  tmp = build_fold_indirect_ref_loc (input_location, tmp);
   8994  1.1  mrg 	  vtab = gfc_get_symbol_decl (gfc_find_vtab (&expr->ts));
   8995  1.1  mrg 	  vtab = gfc_build_addr_expr (NULL_TREE, vtab);
   8996  1.1  mrg 	  gfc_add_modify (&block, gfc_class_vptr_get (dest),
   8997  1.1  mrg 		 fold_convert (TREE_TYPE (gfc_class_vptr_get (dest)), vtab));
   8998  1.1  mrg 	}
   8999  1.1  mrg       else
   9000  1.1  mrg 	tmp = build_fold_indirect_ref_loc (input_location, dest);
   9001  1.1  mrg 
   9002  1.1  mrg       /* For deferred strings insert a memcpy.  */
   9003  1.1  mrg       if (cm->ts.type == BT_CHARACTER && cm->ts.deferred)
   9004  1.1  mrg 	{
   9005  1.1  mrg 	  tree size;
   9006  1.1  mrg 	  gcc_assert (se.string_length || expr->ts.u.cl->backend_decl);
   9007  1.1  mrg 	  size = size_of_string_in_bytes (cm->ts.kind, se.string_length
   9008  1.1  mrg 						? se.string_length
   9009  1.1  mrg 						: expr->ts.u.cl->backend_decl);
   9010  1.1  mrg 	  tmp = gfc_build_memcpy_call (tmp, se.expr, size);
   9011  1.1  mrg 	  gfc_add_expr_to_block (&block, tmp);
   9012  1.1  mrg 	}
   9013  1.1  mrg       else
   9014  1.1  mrg 	gfc_add_modify (&block, tmp,
   9015  1.1  mrg 			fold_convert (TREE_TYPE (tmp), se.expr));
   9016  1.1  mrg       gfc_add_block_to_block (&block, &se.post);
   9017  1.1  mrg     }
   9018  1.1  mrg   else if (expr->ts.type == BT_UNION)
   9019  1.1  mrg     {
   9020  1.1  mrg       tree tmp;
   9021  1.1  mrg       gfc_constructor *c = gfc_constructor_first (expr->value.constructor);
   9022  1.1  mrg       /* We mark that the entire union should be initialized with a contrived
   9023  1.1  mrg          EXPR_NULL expression at the beginning.  */
   9024  1.1  mrg       if (c != NULL && c->n.component == NULL
   9025  1.1  mrg 	  && c->expr != NULL && c->expr->expr_type == EXPR_NULL)
   9026  1.1  mrg         {
   9027  1.1  mrg           tmp = build2_loc (input_location, MODIFY_EXPR, void_type_node,
   9028  1.1  mrg 		            dest, build_constructor (TREE_TYPE (dest), NULL));
   9029  1.1  mrg 	  gfc_add_expr_to_block (&block, tmp);
   9030  1.1  mrg           c = gfc_constructor_next (c);
   9031  1.1  mrg         }
   9032  1.1  mrg       /* The following constructor expression, if any, represents a specific
   9033  1.1  mrg          map intializer, as given by the user.  */
   9034  1.1  mrg       if (c != NULL && c->expr != NULL)
   9035  1.1  mrg         {
   9036  1.1  mrg           gcc_assert (expr->expr_type == EXPR_STRUCTURE);
   9037  1.1  mrg 	  tmp = gfc_trans_structure_assign (dest, expr, expr->symtree != NULL);
   9038  1.1  mrg 	  gfc_add_expr_to_block (&block, tmp);
   9039  1.1  mrg         }
   9040  1.1  mrg     }
   9041  1.1  mrg   else if (expr->ts.type == BT_DERIVED && expr->ts.f90_type != BT_VOID)
   9042  1.1  mrg     {
   9043  1.1  mrg       if (expr->expr_type != EXPR_STRUCTURE)
   9044  1.1  mrg 	{
   9045  1.1  mrg 	  tree dealloc = NULL_TREE;
   9046  1.1  mrg 	  gfc_init_se (&se, NULL);
   9047  1.1  mrg 	  gfc_conv_expr (&se, expr);
   9048  1.1  mrg 	  gfc_add_block_to_block (&block, &se.pre);
   9049  1.1  mrg 	  /* Prevent repeat evaluations in gfc_copy_alloc_comp by fixing the
   9050  1.1  mrg 	     expression in  a temporary variable and deallocate the allocatable
   9051  1.1  mrg 	     components. Then we can the copy the expression to the result.  */
   9052  1.1  mrg 	  if (cm->ts.u.derived->attr.alloc_comp
   9053  1.1  mrg 	      && expr->expr_type != EXPR_VARIABLE)
   9054  1.1  mrg 	    {
   9055  1.1  mrg 	      se.expr = gfc_evaluate_now (se.expr, &block);
   9056  1.1  mrg 	      dealloc = gfc_deallocate_alloc_comp (cm->ts.u.derived, se.expr,
   9057  1.1  mrg 						   expr->rank);
   9058  1.1  mrg 	    }
   9059  1.1  mrg 	  gfc_add_modify (&block, dest,
   9060  1.1  mrg 			  fold_convert (TREE_TYPE (dest), se.expr));
   9061  1.1  mrg 	  if (cm->ts.u.derived->attr.alloc_comp
   9062  1.1  mrg 	      && expr->expr_type != EXPR_NULL)
   9063  1.1  mrg 	    {
   9064  1.1  mrg 	      // TODO: Fix caf_mode
   9065  1.1  mrg 	      tmp = gfc_copy_alloc_comp (cm->ts.u.derived, se.expr,
   9066  1.1  mrg 					 dest, expr->rank, 0);
   9067  1.1  mrg 	      gfc_add_expr_to_block (&block, tmp);
   9068  1.1  mrg 	      if (dealloc != NULL_TREE)
   9069  1.1  mrg 		gfc_add_expr_to_block (&block, dealloc);
   9070  1.1  mrg 	    }
   9071  1.1  mrg 	  gfc_add_block_to_block (&block, &se.post);
   9072  1.1  mrg 	}
   9073  1.1  mrg       else
   9074  1.1  mrg 	{
   9075  1.1  mrg 	  /* Nested constructors.  */
   9076  1.1  mrg 	  tmp = gfc_trans_structure_assign (dest, expr, expr->symtree != NULL);
   9077  1.1  mrg 	  gfc_add_expr_to_block (&block, tmp);
   9078  1.1  mrg 	}
   9079  1.1  mrg     }
   9080  1.1  mrg   else if (gfc_deferred_strlen (cm, &tmp))
   9081  1.1  mrg     {
   9082  1.1  mrg       tree strlen;
   9083  1.1  mrg       strlen = tmp;
   9084  1.1  mrg       gcc_assert (strlen);
   9085  1.1  mrg       strlen = fold_build3_loc (input_location, COMPONENT_REF,
   9086  1.1  mrg 				TREE_TYPE (strlen),
   9087  1.1  mrg 				TREE_OPERAND (dest, 0),
   9088  1.1  mrg 				strlen, NULL_TREE);
   9089  1.1  mrg 
   9090  1.1  mrg       if (expr->expr_type == EXPR_NULL)
   9091  1.1  mrg 	{
   9092  1.1  mrg 	  tmp = build_int_cst (TREE_TYPE (cm->backend_decl), 0);
   9093  1.1  mrg 	  gfc_add_modify (&block, dest, tmp);
   9094  1.1  mrg 	  tmp = build_int_cst (TREE_TYPE (strlen), 0);
   9095  1.1  mrg 	  gfc_add_modify (&block, strlen, tmp);
   9096  1.1  mrg 	}
   9097  1.1  mrg       else
   9098  1.1  mrg 	{
   9099  1.1  mrg 	  tree size;
   9100  1.1  mrg 	  gfc_init_se (&se, NULL);
   9101  1.1  mrg 	  gfc_conv_expr (&se, expr);
   9102  1.1  mrg 	  size = size_of_string_in_bytes (cm->ts.kind, se.string_length);
   9103  1.1  mrg 	  tmp = build_call_expr_loc (input_location,
   9104  1.1  mrg 				     builtin_decl_explicit (BUILT_IN_MALLOC),
   9105  1.1  mrg 				     1, size);
   9106  1.1  mrg 	  gfc_add_modify (&block, dest,
   9107  1.1  mrg 			  fold_convert (TREE_TYPE (dest), tmp));
   9108  1.1  mrg 	  gfc_add_modify (&block, strlen,
   9109  1.1  mrg 			  fold_convert (TREE_TYPE (strlen), se.string_length));
   9110  1.1  mrg 	  tmp = gfc_build_memcpy_call (dest, se.expr, size);
   9111  1.1  mrg 	  gfc_add_expr_to_block (&block, tmp);
   9112  1.1  mrg 	}
   9113  1.1  mrg     }
   9114  1.1  mrg   else if (!cm->attr.artificial)
   9115  1.1  mrg     {
   9116  1.1  mrg       /* Scalar component (excluding deferred parameters).  */
   9117  1.1  mrg       gfc_init_se (&se, NULL);
   9118  1.1  mrg       gfc_init_se (&lse, NULL);
   9119  1.1  mrg 
   9120  1.1  mrg       gfc_conv_expr (&se, expr);
   9121  1.1  mrg       if (cm->ts.type == BT_CHARACTER)
   9122  1.1  mrg 	lse.string_length = cm->ts.u.cl->backend_decl;
   9123  1.1  mrg       lse.expr = dest;
   9124  1.1  mrg       tmp = gfc_trans_scalar_assign (&lse, &se, cm->ts, false, false);
   9125  1.1  mrg       gfc_add_expr_to_block (&block, tmp);
   9126  1.1  mrg     }
   9127  1.1  mrg   return gfc_finish_block (&block);
   9128  1.1  mrg }
   9129  1.1  mrg 
   9130  1.1  mrg /* Assign a derived type constructor to a variable.  */
   9131  1.1  mrg 
   9132  1.1  mrg tree
   9133  1.1  mrg gfc_trans_structure_assign (tree dest, gfc_expr * expr, bool init, bool coarray)
   9134  1.1  mrg {
   9135  1.1  mrg   gfc_constructor *c;
   9136  1.1  mrg   gfc_component *cm;
   9137  1.1  mrg   stmtblock_t block;
   9138  1.1  mrg   tree field;
   9139  1.1  mrg   tree tmp;
   9140  1.1  mrg   gfc_se se;
   9141  1.1  mrg 
   9142  1.1  mrg   gfc_start_block (&block);
   9143  1.1  mrg 
   9144  1.1  mrg   if (expr->ts.u.derived->from_intmod == INTMOD_ISO_C_BINDING
   9145  1.1  mrg       && (expr->ts.u.derived->intmod_sym_id == ISOCBINDING_PTR
   9146  1.1  mrg           || expr->ts.u.derived->intmod_sym_id == ISOCBINDING_FUNPTR))
   9147  1.1  mrg     {
   9148  1.1  mrg       gfc_se lse;
   9149  1.1  mrg 
   9150  1.1  mrg       gfc_init_se (&se, NULL);
   9151  1.1  mrg       gfc_init_se (&lse, NULL);
   9152  1.1  mrg       gfc_conv_expr (&se, gfc_constructor_first (expr->value.constructor)->expr);
   9153  1.1  mrg       lse.expr = dest;
   9154  1.1  mrg       gfc_add_modify (&block, lse.expr,
   9155  1.1  mrg 		      fold_convert (TREE_TYPE (lse.expr), se.expr));
   9156  1.1  mrg 
   9157  1.1  mrg       return gfc_finish_block (&block);
   9158  1.1  mrg     }
   9159  1.1  mrg 
   9160  1.1  mrg   /* Make sure that the derived type has been completely built.  */
   9161  1.1  mrg   if (!expr->ts.u.derived->backend_decl
   9162  1.1  mrg       || !TYPE_FIELDS (expr->ts.u.derived->backend_decl))
   9163  1.1  mrg     {
   9164  1.1  mrg       tmp = gfc_typenode_for_spec (&expr->ts);
   9165  1.1  mrg       gcc_assert (tmp);
   9166  1.1  mrg     }
   9167  1.1  mrg 
   9168  1.1  mrg   cm = expr->ts.u.derived->components;
   9169  1.1  mrg 
   9170  1.1  mrg 
   9171  1.1  mrg   if (coarray)
   9172  1.1  mrg     gfc_init_se (&se, NULL);
   9173  1.1  mrg 
   9174  1.1  mrg   for (c = gfc_constructor_first (expr->value.constructor);
   9175  1.1  mrg        c; c = gfc_constructor_next (c), cm = cm->next)
   9176  1.1  mrg     {
   9177  1.1  mrg       /* Skip absent members in default initializers.  */
   9178  1.1  mrg       if (!c->expr && !cm->attr.allocatable)
   9179  1.1  mrg 	continue;
   9180  1.1  mrg 
   9181  1.1  mrg       /* Register the component with the caf-lib before it is initialized.
   9182  1.1  mrg 	 Register only allocatable components, that are not coarray'ed
   9183  1.1  mrg 	 components (%comp[*]).  Only register when the constructor is not the
   9184  1.1  mrg 	 null-expression.  */
   9185  1.1  mrg       if (coarray && !cm->attr.codimension
   9186  1.1  mrg 	  && (cm->attr.allocatable || cm->attr.pointer)
   9187  1.1  mrg 	  && (!c->expr || c->expr->expr_type == EXPR_NULL))
   9188  1.1  mrg 	{
   9189  1.1  mrg 	  tree token, desc, size;
   9190  1.1  mrg 	  bool is_array = cm->ts.type == BT_CLASS
   9191  1.1  mrg 	      ? CLASS_DATA (cm)->attr.dimension : cm->attr.dimension;
   9192  1.1  mrg 
   9193  1.1  mrg 	  field = cm->backend_decl;
   9194  1.1  mrg 	  field = fold_build3_loc (input_location, COMPONENT_REF,
   9195  1.1  mrg 				   TREE_TYPE (field), dest, field, NULL_TREE);
   9196  1.1  mrg 	  if (cm->ts.type == BT_CLASS)
   9197  1.1  mrg 	    field = gfc_class_data_get (field);
   9198  1.1  mrg 
   9199  1.1  mrg 	  token = is_array ? gfc_conv_descriptor_token (field)
   9200  1.1  mrg 			   : fold_build3_loc (input_location, COMPONENT_REF,
   9201  1.1  mrg 					      TREE_TYPE (cm->caf_token), dest,
   9202  1.1  mrg 					      cm->caf_token, NULL_TREE);
   9203  1.1  mrg 
   9204  1.1  mrg 	  if (is_array)
   9205  1.1  mrg 	    {
   9206  1.1  mrg 	      /* The _caf_register routine looks at the rank of the array
   9207  1.1  mrg 		 descriptor to decide whether the data registered is an array
   9208  1.1  mrg 		 or not.  */
   9209  1.1  mrg 	      int rank = cm->ts.type == BT_CLASS ? CLASS_DATA (cm)->as->rank
   9210  1.1  mrg 						 : cm->as->rank;
   9211  1.1  mrg 	      /* When the rank is not known just set a positive rank, which
   9212  1.1  mrg 		 suffices to recognize the data as array.  */
   9213  1.1  mrg 	      if (rank < 0)
   9214  1.1  mrg 		rank = 1;
   9215  1.1  mrg 	      size = build_zero_cst (size_type_node);
   9216  1.1  mrg 	      desc = field;
   9217  1.1  mrg 	      gfc_add_modify (&block, gfc_conv_descriptor_rank (desc),
   9218  1.1  mrg 			      build_int_cst (signed_char_type_node, rank));
   9219  1.1  mrg 	    }
   9220  1.1  mrg 	  else
   9221  1.1  mrg 	    {
   9222  1.1  mrg 	      desc = gfc_conv_scalar_to_descriptor (&se, field,
   9223  1.1  mrg 						    cm->ts.type == BT_CLASS
   9224  1.1  mrg 						    ? CLASS_DATA (cm)->attr
   9225  1.1  mrg 						    : cm->attr);
   9226  1.1  mrg 	      size = TYPE_SIZE_UNIT (TREE_TYPE (field));
   9227  1.1  mrg 	    }
   9228  1.1  mrg 	  gfc_add_block_to_block (&block, &se.pre);
   9229  1.1  mrg 	  tmp =  build_call_expr_loc (input_location, gfor_fndecl_caf_register,
   9230  1.1  mrg 				      7, size, build_int_cst (
   9231  1.1  mrg 					integer_type_node,
   9232  1.1  mrg 					GFC_CAF_COARRAY_ALLOC_REGISTER_ONLY),
   9233  1.1  mrg 				      gfc_build_addr_expr (pvoid_type_node,
   9234  1.1  mrg 							   token),
   9235  1.1  mrg 				      gfc_build_addr_expr (NULL_TREE, desc),
   9236  1.1  mrg 				      null_pointer_node, null_pointer_node,
   9237  1.1  mrg 				      integer_zero_node);
   9238  1.1  mrg 	  gfc_add_expr_to_block (&block, tmp);
   9239  1.1  mrg 	}
   9240  1.1  mrg       field = cm->backend_decl;
   9241  1.1  mrg       gcc_assert(field);
   9242  1.1  mrg       tmp = fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field),
   9243  1.1  mrg 			     dest, field, NULL_TREE);
   9244  1.1  mrg       if (!c->expr)
   9245  1.1  mrg 	{
   9246  1.1  mrg 	  gfc_expr *e = gfc_get_null_expr (NULL);
   9247  1.1  mrg 	  tmp = gfc_trans_subcomponent_assign (tmp, cm, e, expr->ts.u.derived,
   9248  1.1  mrg 					       init);
   9249  1.1  mrg 	  gfc_free_expr (e);
   9250  1.1  mrg 	}
   9251  1.1  mrg       else
   9252  1.1  mrg         tmp = gfc_trans_subcomponent_assign (tmp, cm, c->expr,
   9253  1.1  mrg                                              expr->ts.u.derived, init);
   9254  1.1  mrg       gfc_add_expr_to_block (&block, tmp);
   9255  1.1  mrg     }
   9256  1.1  mrg   return gfc_finish_block (&block);
   9257  1.1  mrg }
   9258  1.1  mrg 
   9259  1.1  mrg static void
   9260  1.1  mrg gfc_conv_union_initializer (vec<constructor_elt, va_gc> *&v,
   9261  1.1  mrg                             gfc_component *un, gfc_expr *init)
   9262  1.1  mrg {
   9263  1.1  mrg   gfc_constructor *ctor;
   9264  1.1  mrg 
   9265  1.1  mrg   if (un->ts.type != BT_UNION || un == NULL || init == NULL)
   9266  1.1  mrg     return;
   9267  1.1  mrg 
   9268  1.1  mrg   ctor = gfc_constructor_first (init->value.constructor);
   9269  1.1  mrg 
   9270  1.1  mrg   if (ctor == NULL || ctor->expr == NULL)
   9271  1.1  mrg     return;
   9272  1.1  mrg 
   9273  1.1  mrg   gcc_assert (init->expr_type == EXPR_STRUCTURE);
   9274  1.1  mrg 
   9275  1.1  mrg   /* If we have an 'initialize all' constructor, do it first.  */
   9276  1.1  mrg   if (ctor->expr->expr_type == EXPR_NULL)
   9277  1.1  mrg     {
   9278  1.1  mrg       tree union_type = TREE_TYPE (un->backend_decl);
   9279  1.1  mrg       tree val = build_constructor (union_type, NULL);
   9280  1.1  mrg       CONSTRUCTOR_APPEND_ELT (v, un->backend_decl, val);
   9281  1.1  mrg       ctor = gfc_constructor_next (ctor);
   9282  1.1  mrg     }
   9283  1.1  mrg 
   9284  1.1  mrg   /* Add the map initializer on top.  */
   9285  1.1  mrg   if (ctor != NULL && ctor->expr != NULL)
   9286  1.1  mrg     {
   9287  1.1  mrg       gcc_assert (ctor->expr->expr_type == EXPR_STRUCTURE);
   9288  1.1  mrg       tree val = gfc_conv_initializer (ctor->expr, &un->ts,
   9289  1.1  mrg                                        TREE_TYPE (un->backend_decl),
   9290  1.1  mrg                                        un->attr.dimension, un->attr.pointer,
   9291  1.1  mrg                                        un->attr.proc_pointer);
   9292  1.1  mrg       CONSTRUCTOR_APPEND_ELT (v, un->backend_decl, val);
   9293  1.1  mrg     }
   9294  1.1  mrg }
   9295  1.1  mrg 
   9296  1.1  mrg /* Build an expression for a constructor. If init is nonzero then
   9297  1.1  mrg    this is part of a static variable initializer.  */
   9298  1.1  mrg 
   9299  1.1  mrg void
   9300  1.1  mrg gfc_conv_structure (gfc_se * se, gfc_expr * expr, int init)
   9301  1.1  mrg {
   9302  1.1  mrg   gfc_constructor *c;
   9303  1.1  mrg   gfc_component *cm;
   9304  1.1  mrg   tree val;
   9305  1.1  mrg   tree type;
   9306  1.1  mrg   tree tmp;
   9307  1.1  mrg   vec<constructor_elt, va_gc> *v = NULL;
   9308  1.1  mrg 
   9309  1.1  mrg   gcc_assert (se->ss == NULL);
   9310  1.1  mrg   gcc_assert (expr->expr_type == EXPR_STRUCTURE);
   9311  1.1  mrg   type = gfc_typenode_for_spec (&expr->ts);
   9312  1.1  mrg 
   9313  1.1  mrg   if (!init)
   9314  1.1  mrg     {
   9315  1.1  mrg       /* Create a temporary variable and fill it in.  */
   9316  1.1  mrg       se->expr = gfc_create_var (type, expr->ts.u.derived->name);
   9317  1.1  mrg       /* The symtree in expr is NULL, if the code to generate is for
   9318  1.1  mrg 	 initializing the static members only.  */
   9319  1.1  mrg       tmp = gfc_trans_structure_assign (se->expr, expr, expr->symtree != NULL,
   9320  1.1  mrg 					se->want_coarray);
   9321  1.1  mrg       gfc_add_expr_to_block (&se->pre, tmp);
   9322  1.1  mrg       return;
   9323  1.1  mrg     }
   9324  1.1  mrg 
   9325  1.1  mrg   cm = expr->ts.u.derived->components;
   9326  1.1  mrg 
   9327  1.1  mrg   for (c = gfc_constructor_first (expr->value.constructor);
   9328  1.1  mrg        c && cm; c = gfc_constructor_next (c), cm = cm->next)
   9329  1.1  mrg     {
   9330  1.1  mrg       /* Skip absent members in default initializers and allocatable
   9331  1.1  mrg 	 components.  Although the latter have a default initializer
   9332  1.1  mrg 	 of EXPR_NULL,... by default, the static nullify is not needed
   9333  1.1  mrg 	 since this is done every time we come into scope.  */
   9334  1.1  mrg       if (!c->expr || (cm->attr.allocatable && cm->attr.flavor != FL_PROCEDURE))
   9335  1.1  mrg 	continue;
   9336  1.1  mrg 
   9337  1.1  mrg       if (cm->initializer && cm->initializer->expr_type != EXPR_NULL
   9338  1.1  mrg 	  && strcmp (cm->name, "_extends") == 0
   9339  1.1  mrg 	  && cm->initializer->symtree)
   9340  1.1  mrg 	{
   9341  1.1  mrg 	  tree vtab;
   9342  1.1  mrg 	  gfc_symbol *vtabs;
   9343  1.1  mrg 	  vtabs = cm->initializer->symtree->n.sym;
   9344  1.1  mrg 	  vtab = gfc_build_addr_expr (NULL_TREE, gfc_get_symbol_decl (vtabs));
   9345  1.1  mrg 	  vtab = unshare_expr_without_location (vtab);
   9346  1.1  mrg 	  CONSTRUCTOR_APPEND_ELT (v, cm->backend_decl, vtab);
   9347  1.1  mrg 	}
   9348  1.1  mrg       else if (cm->ts.u.derived && strcmp (cm->name, "_size") == 0)
   9349  1.1  mrg 	{
   9350  1.1  mrg 	  val = TYPE_SIZE_UNIT (gfc_get_derived_type (cm->ts.u.derived));
   9351  1.1  mrg 	  CONSTRUCTOR_APPEND_ELT (v, cm->backend_decl,
   9352  1.1  mrg 				  fold_convert (TREE_TYPE (cm->backend_decl),
   9353  1.1  mrg 						val));
   9354  1.1  mrg 	}
   9355  1.1  mrg       else if (cm->ts.type == BT_INTEGER && strcmp (cm->name, "_len") == 0)
   9356  1.1  mrg 	CONSTRUCTOR_APPEND_ELT (v, cm->backend_decl,
   9357  1.1  mrg 				fold_convert (TREE_TYPE (cm->backend_decl),
   9358  1.1  mrg 					      integer_zero_node));
   9359  1.1  mrg       else if (cm->ts.type == BT_UNION)
   9360  1.1  mrg         gfc_conv_union_initializer (v, cm, c->expr);
   9361  1.1  mrg       else
   9362  1.1  mrg 	{
   9363  1.1  mrg 	  val = gfc_conv_initializer (c->expr, &cm->ts,
   9364  1.1  mrg 				      TREE_TYPE (cm->backend_decl),
   9365  1.1  mrg 				      cm->attr.dimension, cm->attr.pointer,
   9366  1.1  mrg 				      cm->attr.proc_pointer);
   9367  1.1  mrg 	  val = unshare_expr_without_location (val);
   9368  1.1  mrg 
   9369  1.1  mrg 	  /* Append it to the constructor list.  */
   9370  1.1  mrg 	  CONSTRUCTOR_APPEND_ELT (v, cm->backend_decl, val);
   9371  1.1  mrg 	}
   9372  1.1  mrg     }
   9373  1.1  mrg 
   9374  1.1  mrg   se->expr = build_constructor (type, v);
   9375  1.1  mrg   if (init)
   9376  1.1  mrg     TREE_CONSTANT (se->expr) = 1;
   9377  1.1  mrg }
   9378  1.1  mrg 
   9379  1.1  mrg 
   9380  1.1  mrg /* Translate a substring expression.  */
   9381  1.1  mrg 
   9382  1.1  mrg static void
   9383  1.1  mrg gfc_conv_substring_expr (gfc_se * se, gfc_expr * expr)
   9384  1.1  mrg {
   9385  1.1  mrg   gfc_ref *ref;
   9386  1.1  mrg 
   9387  1.1  mrg   ref = expr->ref;
   9388  1.1  mrg 
   9389  1.1  mrg   gcc_assert (ref == NULL || ref->type == REF_SUBSTRING);
   9390  1.1  mrg 
   9391  1.1  mrg   se->expr = gfc_build_wide_string_const (expr->ts.kind,
   9392  1.1  mrg 					  expr->value.character.length,
   9393  1.1  mrg 					  expr->value.character.string);
   9394  1.1  mrg 
   9395  1.1  mrg   se->string_length = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (se->expr)));
   9396  1.1  mrg   TYPE_STRING_FLAG (TREE_TYPE (se->expr)) = 1;
   9397  1.1  mrg 
   9398  1.1  mrg   if (ref)
   9399  1.1  mrg     gfc_conv_substring (se, ref, expr->ts.kind, NULL, &expr->where);
   9400  1.1  mrg }
   9401  1.1  mrg 
   9402  1.1  mrg 
   9403  1.1  mrg /* Entry point for expression translation.  Evaluates a scalar quantity.
   9404  1.1  mrg    EXPR is the expression to be translated, and SE is the state structure if
   9405  1.1  mrg    called from within the scalarized.  */
   9406  1.1  mrg 
   9407  1.1  mrg void
   9408  1.1  mrg gfc_conv_expr (gfc_se * se, gfc_expr * expr)
   9409  1.1  mrg {
   9410  1.1  mrg   gfc_ss *ss;
   9411  1.1  mrg 
   9412  1.1  mrg   ss = se->ss;
   9413  1.1  mrg   if (ss && ss->info->expr == expr
   9414  1.1  mrg       && (ss->info->type == GFC_SS_SCALAR
   9415  1.1  mrg 	  || ss->info->type == GFC_SS_REFERENCE))
   9416  1.1  mrg     {
   9417  1.1  mrg       gfc_ss_info *ss_info;
   9418  1.1  mrg 
   9419  1.1  mrg       ss_info = ss->info;
   9420  1.1  mrg       /* Substitute a scalar expression evaluated outside the scalarization
   9421  1.1  mrg 	 loop.  */
   9422  1.1  mrg       se->expr = ss_info->data.scalar.value;
   9423  1.1  mrg       if (gfc_scalar_elemental_arg_saved_as_reference (ss_info))
   9424  1.1  mrg 	se->expr = build_fold_indirect_ref_loc (input_location, se->expr);
   9425  1.1  mrg 
   9426  1.1  mrg       se->string_length = ss_info->string_length;
   9427  1.1  mrg       gfc_advance_se_ss_chain (se);
   9428  1.1  mrg       return;
   9429  1.1  mrg     }
   9430  1.1  mrg 
   9431  1.1  mrg   /* We need to convert the expressions for the iso_c_binding derived types.
   9432  1.1  mrg      C_NULL_PTR and C_NULL_FUNPTR will be made EXPR_NULL, which evaluates to
   9433  1.1  mrg      null_pointer_node.  C_PTR and C_FUNPTR are converted to match the
   9434  1.1  mrg      typespec for the C_PTR and C_FUNPTR symbols, which has already been
   9435  1.1  mrg      updated to be an integer with a kind equal to the size of a (void *).  */
   9436  1.1  mrg   if (expr->ts.type == BT_DERIVED && expr->ts.u.derived->ts.f90_type == BT_VOID
   9437  1.1  mrg       && expr->ts.u.derived->attr.is_bind_c)
   9438  1.1  mrg     {
   9439  1.1  mrg       if (expr->expr_type == EXPR_VARIABLE
   9440  1.1  mrg 	  && (expr->symtree->n.sym->intmod_sym_id == ISOCBINDING_NULL_PTR
   9441  1.1  mrg 	      || expr->symtree->n.sym->intmod_sym_id
   9442  1.1  mrg 		 == ISOCBINDING_NULL_FUNPTR))
   9443  1.1  mrg         {
   9444  1.1  mrg 	  /* Set expr_type to EXPR_NULL, which will result in
   9445  1.1  mrg 	     null_pointer_node being used below.  */
   9446  1.1  mrg           expr->expr_type = EXPR_NULL;
   9447  1.1  mrg         }
   9448  1.1  mrg       else
   9449  1.1  mrg         {
   9450  1.1  mrg           /* Update the type/kind of the expression to be what the new
   9451  1.1  mrg              type/kind are for the updated symbols of C_PTR/C_FUNPTR.  */
   9452  1.1  mrg           expr->ts.type = BT_INTEGER;
   9453  1.1  mrg           expr->ts.f90_type = BT_VOID;
   9454  1.1  mrg           expr->ts.kind = gfc_index_integer_kind;
   9455  1.1  mrg         }
   9456  1.1  mrg     }
   9457  1.1  mrg 
   9458  1.1  mrg   gfc_fix_class_refs (expr);
   9459  1.1  mrg 
   9460  1.1  mrg   switch (expr->expr_type)
   9461  1.1  mrg     {
   9462  1.1  mrg     case EXPR_OP:
   9463  1.1  mrg       gfc_conv_expr_op (se, expr);
   9464  1.1  mrg       break;
   9465  1.1  mrg 
   9466  1.1  mrg     case EXPR_FUNCTION:
   9467  1.1  mrg       gfc_conv_function_expr (se, expr);
   9468  1.1  mrg       break;
   9469  1.1  mrg 
   9470  1.1  mrg     case EXPR_CONSTANT:
   9471  1.1  mrg       gfc_conv_constant (se, expr);
   9472  1.1  mrg       break;
   9473  1.1  mrg 
   9474  1.1  mrg     case EXPR_VARIABLE:
   9475  1.1  mrg       gfc_conv_variable (se, expr);
   9476  1.1  mrg       break;
   9477  1.1  mrg 
   9478  1.1  mrg     case EXPR_NULL:
   9479  1.1  mrg       se->expr = null_pointer_node;
   9480  1.1  mrg       break;
   9481  1.1  mrg 
   9482  1.1  mrg     case EXPR_SUBSTRING:
   9483  1.1  mrg       gfc_conv_substring_expr (se, expr);
   9484  1.1  mrg       break;
   9485  1.1  mrg 
   9486  1.1  mrg     case EXPR_STRUCTURE:
   9487  1.1  mrg       gfc_conv_structure (se, expr, 0);
   9488  1.1  mrg       break;
   9489  1.1  mrg 
   9490  1.1  mrg     case EXPR_ARRAY:
   9491  1.1  mrg       gfc_conv_array_constructor_expr (se, expr);
   9492  1.1  mrg       break;
   9493  1.1  mrg 
   9494  1.1  mrg     default:
   9495  1.1  mrg       gcc_unreachable ();
   9496  1.1  mrg       break;
   9497  1.1  mrg     }
   9498  1.1  mrg }
   9499  1.1  mrg 
   9500  1.1  mrg /* Like gfc_conv_expr_val, but the value is also suitable for use in the lhs
   9501  1.1  mrg    of an assignment.  */
   9502  1.1  mrg void
   9503  1.1  mrg gfc_conv_expr_lhs (gfc_se * se, gfc_expr * expr)
   9504  1.1  mrg {
   9505  1.1  mrg   gfc_conv_expr (se, expr);
   9506  1.1  mrg   /* All numeric lvalues should have empty post chains.  If not we need to
   9507  1.1  mrg      figure out a way of rewriting an lvalue so that it has no post chain.  */
   9508  1.1  mrg   gcc_assert (expr->ts.type == BT_CHARACTER || !se->post.head);
   9509  1.1  mrg }
   9510  1.1  mrg 
   9511  1.1  mrg /* Like gfc_conv_expr, but the POST block is guaranteed to be empty for
   9512  1.1  mrg    numeric expressions.  Used for scalar values where inserting cleanup code
   9513  1.1  mrg    is inconvenient.  */
   9514  1.1  mrg void
   9515  1.1  mrg gfc_conv_expr_val (gfc_se * se, gfc_expr * expr)
   9516  1.1  mrg {
   9517  1.1  mrg   tree val;
   9518  1.1  mrg 
   9519  1.1  mrg   gcc_assert (expr->ts.type != BT_CHARACTER);
   9520  1.1  mrg   gfc_conv_expr (se, expr);
   9521  1.1  mrg   if (se->post.head)
   9522  1.1  mrg     {
   9523  1.1  mrg       val = gfc_create_var (TREE_TYPE (se->expr), NULL);
   9524  1.1  mrg       gfc_add_modify (&se->pre, val, se->expr);
   9525  1.1  mrg       se->expr = val;
   9526  1.1  mrg       gfc_add_block_to_block (&se->pre, &se->post);
   9527  1.1  mrg     }
   9528  1.1  mrg }
   9529  1.1  mrg 
   9530  1.1  mrg /* Helper to translate an expression and convert it to a particular type.  */
   9531  1.1  mrg void
   9532  1.1  mrg gfc_conv_expr_type (gfc_se * se, gfc_expr * expr, tree type)
   9533  1.1  mrg {
   9534  1.1  mrg   gfc_conv_expr_val (se, expr);
   9535  1.1  mrg   se->expr = convert (type, se->expr);
   9536  1.1  mrg }
   9537  1.1  mrg 
   9538  1.1  mrg 
   9539  1.1  mrg /* Converts an expression so that it can be passed by reference.  Scalar
   9540  1.1  mrg    values only.  */
   9541  1.1  mrg 
   9542  1.1  mrg void
   9543  1.1  mrg gfc_conv_expr_reference (gfc_se * se, gfc_expr * expr)
   9544  1.1  mrg {
   9545  1.1  mrg   gfc_ss *ss;
   9546  1.1  mrg   tree var;
   9547  1.1  mrg 
   9548  1.1  mrg   ss = se->ss;
   9549  1.1  mrg   if (ss && ss->info->expr == expr
   9550  1.1  mrg       && ss->info->type == GFC_SS_REFERENCE)
   9551  1.1  mrg     {
   9552  1.1  mrg       /* Returns a reference to the scalar evaluated outside the loop
   9553  1.1  mrg 	 for this case.  */
   9554  1.1  mrg       gfc_conv_expr (se, expr);
   9555  1.1  mrg 
   9556  1.1  mrg       if (expr->ts.type == BT_CHARACTER
   9557  1.1  mrg 	  && expr->expr_type != EXPR_FUNCTION)
   9558  1.1  mrg 	gfc_conv_string_parameter (se);
   9559  1.1  mrg      else
   9560  1.1  mrg 	se->expr = gfc_build_addr_expr (NULL_TREE, se->expr);
   9561  1.1  mrg 
   9562  1.1  mrg       return;
   9563  1.1  mrg     }
   9564  1.1  mrg 
   9565  1.1  mrg   if (expr->ts.type == BT_CHARACTER)
   9566  1.1  mrg     {
   9567  1.1  mrg       gfc_conv_expr (se, expr);
   9568  1.1  mrg       gfc_conv_string_parameter (se);
   9569  1.1  mrg       return;
   9570  1.1  mrg     }
   9571  1.1  mrg 
   9572  1.1  mrg   if (expr->expr_type == EXPR_VARIABLE)
   9573  1.1  mrg     {
   9574  1.1  mrg       se->want_pointer = 1;
   9575  1.1  mrg       gfc_conv_expr (se, expr);
   9576  1.1  mrg       if (se->post.head)
   9577  1.1  mrg 	{
   9578  1.1  mrg 	  var = gfc_create_var (TREE_TYPE (se->expr), NULL);
   9579  1.1  mrg 	  gfc_add_modify (&se->pre, var, se->expr);
   9580  1.1  mrg 	  gfc_add_block_to_block (&se->pre, &se->post);
   9581  1.1  mrg 	  se->expr = var;
   9582  1.1  mrg 	}
   9583  1.1  mrg       return;
   9584  1.1  mrg     }
   9585  1.1  mrg 
   9586  1.1  mrg   if (expr->expr_type == EXPR_FUNCTION
   9587  1.1  mrg       && ((expr->value.function.esym
   9588  1.1  mrg 	   && expr->value.function.esym->result
   9589  1.1  mrg 	   && expr->value.function.esym->result->attr.pointer
   9590  1.1  mrg 	   && !expr->value.function.esym->result->attr.dimension)
   9591  1.1  mrg 	  || (!expr->value.function.esym && !expr->ref
   9592  1.1  mrg 	      && expr->symtree->n.sym->attr.pointer
   9593  1.1  mrg 	      && !expr->symtree->n.sym->attr.dimension)))
   9594  1.1  mrg     {
   9595  1.1  mrg       se->want_pointer = 1;
   9596  1.1  mrg       gfc_conv_expr (se, expr);
   9597  1.1  mrg       var = gfc_create_var (TREE_TYPE (se->expr), NULL);
   9598  1.1  mrg       gfc_add_modify (&se->pre, var, se->expr);
   9599  1.1  mrg       se->expr = var;
   9600  1.1  mrg       return;
   9601  1.1  mrg     }
   9602  1.1  mrg 
   9603  1.1  mrg   gfc_conv_expr (se, expr);
   9604  1.1  mrg 
   9605  1.1  mrg   /* Create a temporary var to hold the value.  */
   9606  1.1  mrg   if (TREE_CONSTANT (se->expr))
   9607  1.1  mrg     {
   9608  1.1  mrg       tree tmp = se->expr;
   9609  1.1  mrg       STRIP_TYPE_NOPS (tmp);
   9610  1.1  mrg       var = build_decl (input_location,
   9611  1.1  mrg 			CONST_DECL, NULL, TREE_TYPE (tmp));
   9612  1.1  mrg       DECL_INITIAL (var) = tmp;
   9613  1.1  mrg       TREE_STATIC (var) = 1;
   9614  1.1  mrg       pushdecl (var);
   9615  1.1  mrg     }
   9616  1.1  mrg   else
   9617  1.1  mrg     {
   9618  1.1  mrg       var = gfc_create_var (TREE_TYPE (se->expr), NULL);
   9619  1.1  mrg       gfc_add_modify (&se->pre, var, se->expr);
   9620  1.1  mrg     }
   9621  1.1  mrg 
   9622  1.1  mrg   if (!expr->must_finalize)
   9623  1.1  mrg     gfc_add_block_to_block (&se->pre, &se->post);
   9624  1.1  mrg 
   9625  1.1  mrg   /* Take the address of that value.  */
   9626  1.1  mrg   se->expr = gfc_build_addr_expr (NULL_TREE, var);
   9627  1.1  mrg }
   9628  1.1  mrg 
   9629  1.1  mrg 
   9630  1.1  mrg /* Get the _len component for an unlimited polymorphic expression.  */
   9631  1.1  mrg 
   9632  1.1  mrg static tree
   9633  1.1  mrg trans_get_upoly_len (stmtblock_t *block, gfc_expr *expr)
   9634  1.1  mrg {
   9635  1.1  mrg   gfc_se se;
   9636  1.1  mrg   gfc_ref *ref = expr->ref;
   9637  1.1  mrg 
   9638  1.1  mrg   gfc_init_se (&se, NULL);
   9639  1.1  mrg   while (ref && ref->next)
   9640  1.1  mrg     ref = ref->next;
   9641  1.1  mrg   gfc_add_len_component (expr);
   9642  1.1  mrg   gfc_conv_expr (&se, expr);
   9643  1.1  mrg   gfc_add_block_to_block (block, &se.pre);
   9644  1.1  mrg   gcc_assert (se.post.head == NULL_TREE);
   9645  1.1  mrg   if (ref)
   9646  1.1  mrg     {
   9647  1.1  mrg       gfc_free_ref_list (ref->next);
   9648  1.1  mrg       ref->next = NULL;
   9649  1.1  mrg     }
   9650  1.1  mrg   else
   9651  1.1  mrg     {
   9652  1.1  mrg       gfc_free_ref_list (expr->ref);
   9653  1.1  mrg       expr->ref = NULL;
   9654  1.1  mrg     }
   9655  1.1  mrg   return se.expr;
   9656  1.1  mrg }
   9657  1.1  mrg 
   9658  1.1  mrg 
   9659  1.1  mrg /* Assign _vptr and _len components as appropriate.  BLOCK should be a
   9660  1.1  mrg    statement-list outside of the scalarizer-loop.  When code is generated, that
   9661  1.1  mrg    depends on the scalarized expression, it is added to RSE.PRE.
   9662  1.1  mrg    Returns le's _vptr tree and when set the len expressions in to_lenp and
   9663  1.1  mrg    from_lenp to form a le%_vptr%_copy (re, le, [from_lenp, to_lenp])
   9664  1.1  mrg    expression.  */
   9665  1.1  mrg 
   9666  1.1  mrg static tree
   9667  1.1  mrg trans_class_vptr_len_assignment (stmtblock_t *block, gfc_expr * le,
   9668  1.1  mrg 				 gfc_expr * re, gfc_se *rse,
   9669  1.1  mrg 				 tree * to_lenp, tree * from_lenp)
   9670  1.1  mrg {
   9671  1.1  mrg   gfc_se se;
   9672  1.1  mrg   gfc_expr * vptr_expr;
   9673  1.1  mrg   tree tmp, to_len = NULL_TREE, from_len = NULL_TREE, lhs_vptr;
   9674  1.1  mrg   bool set_vptr = false, temp_rhs = false;
   9675  1.1  mrg   stmtblock_t *pre = block;
   9676  1.1  mrg   tree class_expr = NULL_TREE;
   9677  1.1  mrg 
   9678  1.1  mrg   /* Create a temporary for complicated expressions.  */
   9679  1.1  mrg   if (re->expr_type != EXPR_VARIABLE && re->expr_type != EXPR_NULL
   9680  1.1  mrg       && rse->expr != NULL_TREE && !DECL_P (rse->expr))
   9681  1.1  mrg     {
   9682  1.1  mrg       if (re->ts.type == BT_CLASS && !GFC_CLASS_TYPE_P (TREE_TYPE (rse->expr)))
   9683  1.1  mrg 	class_expr = gfc_get_class_from_expr (rse->expr);
   9684  1.1  mrg 
   9685  1.1  mrg       if (rse->loop)
   9686  1.1  mrg 	pre = &rse->loop->pre;
   9687  1.1  mrg       else
   9688  1.1  mrg 	pre = &rse->pre;
   9689  1.1  mrg 
   9690  1.1  mrg       if (class_expr != NULL_TREE && UNLIMITED_POLY (re))
   9691  1.1  mrg 	{
   9692  1.1  mrg 	  tmp = TREE_OPERAND (rse->expr, 0);
   9693  1.1  mrg 	  tmp = gfc_create_var (TREE_TYPE (tmp), "rhs");
   9694  1.1  mrg 	  gfc_add_modify (&rse->pre, tmp, TREE_OPERAND (rse->expr, 0));
   9695  1.1  mrg 	}
   9696  1.1  mrg       else
   9697  1.1  mrg 	{
   9698  1.1  mrg 	  tmp = gfc_create_var (TREE_TYPE (rse->expr), "rhs");
   9699  1.1  mrg 	  gfc_add_modify (&rse->pre, tmp, rse->expr);
   9700  1.1  mrg 	}
   9701  1.1  mrg 
   9702  1.1  mrg       rse->expr = tmp;
   9703  1.1  mrg       temp_rhs = true;
   9704  1.1  mrg     }
   9705  1.1  mrg 
   9706  1.1  mrg   /* Get the _vptr for the left-hand side expression.  */
   9707  1.1  mrg   gfc_init_se (&se, NULL);
   9708  1.1  mrg   vptr_expr = gfc_find_and_cut_at_last_class_ref (le);
   9709  1.1  mrg   if (vptr_expr != NULL && gfc_expr_attr (vptr_expr).class_ok)
   9710  1.1  mrg     {
   9711  1.1  mrg       /* Care about _len for unlimited polymorphic entities.  */
   9712  1.1  mrg       if (UNLIMITED_POLY (vptr_expr)
   9713  1.1  mrg 	  || (vptr_expr->ts.type == BT_DERIVED
   9714  1.1  mrg 	      && vptr_expr->ts.u.derived->attr.unlimited_polymorphic))
   9715  1.1  mrg 	to_len = trans_get_upoly_len (block, vptr_expr);
   9716  1.1  mrg       gfc_add_vptr_component (vptr_expr);
   9717  1.1  mrg       set_vptr = true;
   9718  1.1  mrg     }
   9719  1.1  mrg   else
   9720  1.1  mrg     vptr_expr = gfc_lval_expr_from_sym (gfc_find_vtab (&le->ts));
   9721  1.1  mrg   se.want_pointer = 1;
   9722  1.1  mrg   gfc_conv_expr (&se, vptr_expr);
   9723  1.1  mrg   gfc_free_expr (vptr_expr);
   9724  1.1  mrg   gfc_add_block_to_block (block, &se.pre);
   9725  1.1  mrg   gcc_assert (se.post.head == NULL_TREE);
   9726  1.1  mrg   lhs_vptr = se.expr;
   9727  1.1  mrg   STRIP_NOPS (lhs_vptr);
   9728  1.1  mrg 
   9729  1.1  mrg   /* Set the _vptr only when the left-hand side of the assignment is a
   9730  1.1  mrg      class-object.  */
   9731  1.1  mrg   if (set_vptr)
   9732  1.1  mrg     {
   9733  1.1  mrg       /* Get the vptr from the rhs expression only, when it is variable.
   9734  1.1  mrg 	 Functions are expected to be assigned to a temporary beforehand.  */
   9735  1.1  mrg       vptr_expr = (re->expr_type == EXPR_VARIABLE && re->ts.type == BT_CLASS)
   9736  1.1  mrg 	  ? gfc_find_and_cut_at_last_class_ref (re)
   9737  1.1  mrg 	  : NULL;
   9738  1.1  mrg       if (vptr_expr != NULL && vptr_expr->ts.type == BT_CLASS)
   9739  1.1  mrg 	{
   9740  1.1  mrg 	  if (to_len != NULL_TREE)
   9741  1.1  mrg 	    {
   9742  1.1  mrg 	      /* Get the _len information from the rhs.  */
   9743  1.1  mrg 	      if (UNLIMITED_POLY (vptr_expr)
   9744  1.1  mrg 		  || (vptr_expr->ts.type == BT_DERIVED
   9745  1.1  mrg 		      && vptr_expr->ts.u.derived->attr.unlimited_polymorphic))
   9746  1.1  mrg 		from_len = trans_get_upoly_len (block, vptr_expr);
   9747  1.1  mrg 	    }
   9748  1.1  mrg 	  gfc_add_vptr_component (vptr_expr);
   9749  1.1  mrg 	}
   9750  1.1  mrg       else
   9751  1.1  mrg 	{
   9752  1.1  mrg 	  if (re->expr_type == EXPR_VARIABLE
   9753  1.1  mrg 	      && DECL_P (re->symtree->n.sym->backend_decl)
   9754  1.1  mrg 	      && DECL_LANG_SPECIFIC (re->symtree->n.sym->backend_decl)
   9755  1.1  mrg 	      && GFC_DECL_SAVED_DESCRIPTOR (re->symtree->n.sym->backend_decl)
   9756  1.1  mrg 	      && GFC_CLASS_TYPE_P (TREE_TYPE (GFC_DECL_SAVED_DESCRIPTOR (
   9757  1.1  mrg 					   re->symtree->n.sym->backend_decl))))
   9758  1.1  mrg 	    {
   9759  1.1  mrg 	      vptr_expr = NULL;
   9760  1.1  mrg 	      se.expr = gfc_class_vptr_get (GFC_DECL_SAVED_DESCRIPTOR (
   9761  1.1  mrg 					     re->symtree->n.sym->backend_decl));
   9762  1.1  mrg 	      if (to_len)
   9763  1.1  mrg 		from_len = gfc_class_len_get (GFC_DECL_SAVED_DESCRIPTOR (
   9764  1.1  mrg 					     re->symtree->n.sym->backend_decl));
   9765  1.1  mrg 	    }
   9766  1.1  mrg 	  else if (temp_rhs && re->ts.type == BT_CLASS)
   9767  1.1  mrg 	    {
   9768  1.1  mrg 	      vptr_expr = NULL;
   9769  1.1  mrg 	      if (class_expr)
   9770  1.1  mrg 		tmp = class_expr;
   9771  1.1  mrg 	      else if (!GFC_CLASS_TYPE_P (TREE_TYPE (rse->expr)))
   9772  1.1  mrg 		tmp = gfc_get_class_from_expr (rse->expr);
   9773  1.1  mrg 	      else
   9774  1.1  mrg 		tmp = rse->expr;
   9775  1.1  mrg 
   9776  1.1  mrg 	      se.expr = gfc_class_vptr_get (tmp);
   9777  1.1  mrg 	      if (UNLIMITED_POLY (re))
   9778  1.1  mrg 		from_len = gfc_class_len_get (tmp);
   9779  1.1  mrg 
   9780  1.1  mrg 	    }
   9781  1.1  mrg 	  else if (re->expr_type != EXPR_NULL)
   9782  1.1  mrg 	    /* Only when rhs is non-NULL use its declared type for vptr
   9783  1.1  mrg 	       initialisation.  */
   9784  1.1  mrg 	    vptr_expr = gfc_lval_expr_from_sym (gfc_find_vtab (&re->ts));
   9785  1.1  mrg 	  else
   9786  1.1  mrg 	    /* When the rhs is NULL use the vtab of lhs' declared type.  */
   9787  1.1  mrg 	    vptr_expr = gfc_lval_expr_from_sym (gfc_find_vtab (&le->ts));
   9788  1.1  mrg 	}
   9789  1.1  mrg 
   9790  1.1  mrg       if (vptr_expr)
   9791  1.1  mrg 	{
   9792  1.1  mrg 	  gfc_init_se (&se, NULL);
   9793  1.1  mrg 	  se.want_pointer = 1;
   9794  1.1  mrg 	  gfc_conv_expr (&se, vptr_expr);
   9795  1.1  mrg 	  gfc_free_expr (vptr_expr);
   9796  1.1  mrg 	  gfc_add_block_to_block (block, &se.pre);
   9797  1.1  mrg 	  gcc_assert (se.post.head == NULL_TREE);
   9798  1.1  mrg 	}
   9799  1.1  mrg       gfc_add_modify (pre, lhs_vptr, fold_convert (TREE_TYPE (lhs_vptr),
   9800  1.1  mrg 						se.expr));
   9801  1.1  mrg 
   9802  1.1  mrg       if (to_len != NULL_TREE)
   9803  1.1  mrg 	{
   9804  1.1  mrg 	  /* The _len component needs to be set.  Figure how to get the
   9805  1.1  mrg 	     value of the right-hand side.  */
   9806  1.1  mrg 	  if (from_len == NULL_TREE)
   9807  1.1  mrg 	    {
   9808  1.1  mrg 	      if (rse->string_length != NULL_TREE)
   9809  1.1  mrg 		from_len = rse->string_length;
   9810  1.1  mrg 	      else if (re->ts.type == BT_CHARACTER && re->ts.u.cl->length)
   9811  1.1  mrg 		{
   9812  1.1  mrg 		  gfc_init_se (&se, NULL);
   9813  1.1  mrg 		  gfc_conv_expr (&se, re->ts.u.cl->length);
   9814  1.1  mrg 		  gfc_add_block_to_block (block, &se.pre);
   9815  1.1  mrg 		  gcc_assert (se.post.head == NULL_TREE);
   9816  1.1  mrg 		  from_len = gfc_evaluate_now (se.expr, block);
   9817  1.1  mrg 		}
   9818  1.1  mrg 	      else
   9819  1.1  mrg 		from_len = build_zero_cst (gfc_charlen_type_node);
   9820  1.1  mrg 	    }
   9821  1.1  mrg 	  gfc_add_modify (pre, to_len, fold_convert (TREE_TYPE (to_len),
   9822  1.1  mrg 						     from_len));
   9823  1.1  mrg 	}
   9824  1.1  mrg     }
   9825  1.1  mrg 
   9826  1.1  mrg   /* Return the _len trees only, when requested.  */
   9827  1.1  mrg   if (to_lenp)
   9828  1.1  mrg     *to_lenp = to_len;
   9829  1.1  mrg   if (from_lenp)
   9830  1.1  mrg     *from_lenp = from_len;
   9831  1.1  mrg   return lhs_vptr;
   9832  1.1  mrg }
   9833  1.1  mrg 
   9834  1.1  mrg 
   9835  1.1  mrg /* Assign tokens for pointer components.  */
   9836  1.1  mrg 
   9837  1.1  mrg static void
   9838  1.1  mrg trans_caf_token_assign (gfc_se *lse, gfc_se *rse, gfc_expr *expr1,
   9839  1.1  mrg 			gfc_expr *expr2)
   9840  1.1  mrg {
   9841  1.1  mrg   symbol_attribute lhs_attr, rhs_attr;
   9842  1.1  mrg   tree tmp, lhs_tok, rhs_tok;
   9843  1.1  mrg   /* Flag to indicated component refs on the rhs.  */
   9844  1.1  mrg   bool rhs_cr;
   9845  1.1  mrg 
   9846  1.1  mrg   lhs_attr = gfc_caf_attr (expr1);
   9847  1.1  mrg   if (expr2->expr_type != EXPR_NULL)
   9848  1.1  mrg     {
   9849  1.1  mrg       rhs_attr = gfc_caf_attr (expr2, false, &rhs_cr);
   9850  1.1  mrg       if (lhs_attr.codimension && rhs_attr.codimension)
   9851  1.1  mrg 	{
   9852  1.1  mrg 	  lhs_tok = gfc_get_ultimate_alloc_ptr_comps_caf_token (lse, expr1);
   9853  1.1  mrg 	  lhs_tok = build_fold_indirect_ref (lhs_tok);
   9854  1.1  mrg 
   9855  1.1  mrg 	  if (rhs_cr)
   9856  1.1  mrg 	    rhs_tok = gfc_get_ultimate_alloc_ptr_comps_caf_token (rse, expr2);
   9857  1.1  mrg 	  else
   9858  1.1  mrg 	    {
   9859  1.1  mrg 	      tree caf_decl;
   9860  1.1  mrg 	      caf_decl = gfc_get_tree_for_caf_expr (expr2);
   9861  1.1  mrg 	      gfc_get_caf_token_offset (rse, &rhs_tok, NULL, caf_decl,
   9862  1.1  mrg 					NULL_TREE, NULL);
   9863  1.1  mrg 	    }
   9864  1.1  mrg 	  tmp = build2_loc (input_location, MODIFY_EXPR, void_type_node,
   9865  1.1  mrg 			    lhs_tok,
   9866  1.1  mrg 			    fold_convert (TREE_TYPE (lhs_tok), rhs_tok));
   9867  1.1  mrg 	  gfc_prepend_expr_to_block (&lse->post, tmp);
   9868  1.1  mrg 	}
   9869  1.1  mrg     }
   9870  1.1  mrg   else if (lhs_attr.codimension)
   9871  1.1  mrg     {
   9872  1.1  mrg       lhs_tok = gfc_get_ultimate_alloc_ptr_comps_caf_token (lse, expr1);
   9873  1.1  mrg       lhs_tok = build_fold_indirect_ref (lhs_tok);
   9874  1.1  mrg       tmp = build2_loc (input_location, MODIFY_EXPR, void_type_node,
   9875  1.1  mrg 			lhs_tok, null_pointer_node);
   9876  1.1  mrg       gfc_prepend_expr_to_block (&lse->post, tmp);
   9877  1.1  mrg     }
   9878  1.1  mrg }
   9879  1.1  mrg 
   9880  1.1  mrg 
   9881  1.1  mrg /* Do everything that is needed for a CLASS function expr2.  */
   9882  1.1  mrg 
   9883  1.1  mrg static tree
   9884  1.1  mrg trans_class_pointer_fcn (stmtblock_t *block, gfc_se *lse, gfc_se *rse,
   9885  1.1  mrg 			 gfc_expr *expr1, gfc_expr *expr2)
   9886  1.1  mrg {
   9887  1.1  mrg   tree expr1_vptr = NULL_TREE;
   9888  1.1  mrg   tree tmp;
   9889  1.1  mrg 
   9890  1.1  mrg   gfc_conv_function_expr (rse, expr2);
   9891  1.1  mrg   rse->expr = gfc_evaluate_now (rse->expr, &rse->pre);
   9892  1.1  mrg 
   9893  1.1  mrg   if (expr1->ts.type != BT_CLASS)
   9894  1.1  mrg       rse->expr = gfc_class_data_get (rse->expr);
   9895  1.1  mrg   else
   9896  1.1  mrg     {
   9897  1.1  mrg       expr1_vptr = trans_class_vptr_len_assignment (block, expr1,
   9898  1.1  mrg 						    expr2, rse,
   9899  1.1  mrg 						    NULL, NULL);
   9900  1.1  mrg       gfc_add_block_to_block (block, &rse->pre);
   9901  1.1  mrg       tmp = gfc_create_var (TREE_TYPE (rse->expr), "ptrtemp");
   9902  1.1  mrg       gfc_add_modify (&lse->pre, tmp, rse->expr);
   9903  1.1  mrg 
   9904  1.1  mrg       gfc_add_modify (&lse->pre, expr1_vptr,
   9905  1.1  mrg 		      fold_convert (TREE_TYPE (expr1_vptr),
   9906  1.1  mrg 		      gfc_class_vptr_get (tmp)));
   9907  1.1  mrg       rse->expr = gfc_class_data_get (tmp);
   9908  1.1  mrg     }
   9909  1.1  mrg 
   9910  1.1  mrg   return expr1_vptr;
   9911  1.1  mrg }
   9912  1.1  mrg 
   9913  1.1  mrg 
   9914  1.1  mrg tree
   9915  1.1  mrg gfc_trans_pointer_assign (gfc_code * code)
   9916  1.1  mrg {
   9917  1.1  mrg   return gfc_trans_pointer_assignment (code->expr1, code->expr2);
   9918  1.1  mrg }
   9919  1.1  mrg 
   9920  1.1  mrg 
   9921  1.1  mrg /* Generate code for a pointer assignment.  */
   9922  1.1  mrg 
   9923  1.1  mrg tree
   9924  1.1  mrg gfc_trans_pointer_assignment (gfc_expr * expr1, gfc_expr * expr2)
   9925  1.1  mrg {
   9926  1.1  mrg   gfc_se lse;
   9927  1.1  mrg   gfc_se rse;
   9928  1.1  mrg   stmtblock_t block;
   9929  1.1  mrg   tree desc;
   9930  1.1  mrg   tree tmp;
   9931  1.1  mrg   tree expr1_vptr = NULL_TREE;
   9932  1.1  mrg   bool scalar, non_proc_ptr_assign;
   9933  1.1  mrg   gfc_ss *ss;
   9934  1.1  mrg 
   9935  1.1  mrg   gfc_start_block (&block);
   9936  1.1  mrg 
   9937  1.1  mrg   gfc_init_se (&lse, NULL);
   9938  1.1  mrg 
   9939  1.1  mrg   /* Usually testing whether this is not a proc pointer assignment.  */
   9940  1.1  mrg   non_proc_ptr_assign = !(gfc_expr_attr (expr1).proc_pointer
   9941  1.1  mrg 			&& expr2->expr_type == EXPR_VARIABLE
   9942  1.1  mrg 			&& expr2->symtree->n.sym->attr.flavor == FL_PROCEDURE);
   9943  1.1  mrg 
   9944  1.1  mrg   /* Check whether the expression is a scalar or not; we cannot use
   9945  1.1  mrg      expr1->rank as it can be nonzero for proc pointers.  */
   9946  1.1  mrg   ss = gfc_walk_expr (expr1);
   9947  1.1  mrg   scalar = ss == gfc_ss_terminator;
   9948  1.1  mrg   if (!scalar)
   9949  1.1  mrg     gfc_free_ss_chain (ss);
   9950  1.1  mrg 
   9951  1.1  mrg   if (expr1->ts.type == BT_DERIVED && expr2->ts.type == BT_CLASS
   9952  1.1  mrg       && expr2->expr_type != EXPR_FUNCTION && non_proc_ptr_assign)
   9953  1.1  mrg     {
   9954  1.1  mrg       gfc_add_data_component (expr2);
   9955  1.1  mrg       /* The following is required as gfc_add_data_component doesn't
   9956  1.1  mrg 	 update ts.type if there is a trailing REF_ARRAY.  */
   9957  1.1  mrg       expr2->ts.type = BT_DERIVED;
   9958  1.1  mrg     }
   9959  1.1  mrg 
   9960  1.1  mrg   if (scalar)
   9961  1.1  mrg     {
   9962  1.1  mrg       /* Scalar pointers.  */
   9963  1.1  mrg       lse.want_pointer = 1;
   9964  1.1  mrg       gfc_conv_expr (&lse, expr1);
   9965  1.1  mrg       gfc_init_se (&rse, NULL);
   9966  1.1  mrg       rse.want_pointer = 1;
   9967  1.1  mrg       if (expr2->expr_type == EXPR_FUNCTION && expr2->ts.type == BT_CLASS)
   9968  1.1  mrg 	trans_class_pointer_fcn (&block, &lse, &rse, expr1, expr2);
   9969  1.1  mrg       else
   9970  1.1  mrg 	gfc_conv_expr (&rse, expr2);
   9971  1.1  mrg 
   9972  1.1  mrg       if (non_proc_ptr_assign && expr1->ts.type == BT_CLASS)
   9973  1.1  mrg 	{
   9974  1.1  mrg 	  trans_class_vptr_len_assignment (&block, expr1, expr2, &rse, NULL,
   9975  1.1  mrg 					   NULL);
   9976  1.1  mrg 	  lse.expr = gfc_class_data_get (lse.expr);
   9977  1.1  mrg 	}
   9978  1.1  mrg 
   9979  1.1  mrg       if (expr1->symtree->n.sym->attr.proc_pointer
   9980  1.1  mrg 	  && expr1->symtree->n.sym->attr.dummy)
   9981  1.1  mrg 	lse.expr = build_fold_indirect_ref_loc (input_location,
   9982  1.1  mrg 						lse.expr);
   9983  1.1  mrg 
   9984  1.1  mrg       if (expr2->symtree && expr2->symtree->n.sym->attr.proc_pointer
   9985  1.1  mrg 	  && expr2->symtree->n.sym->attr.dummy)
   9986  1.1  mrg 	rse.expr = build_fold_indirect_ref_loc (input_location,
   9987  1.1  mrg 						rse.expr);
   9988  1.1  mrg 
   9989  1.1  mrg       gfc_add_block_to_block (&block, &lse.pre);
   9990  1.1  mrg       gfc_add_block_to_block (&block, &rse.pre);
   9991  1.1  mrg 
   9992  1.1  mrg       /* Check character lengths if character expression.  The test is only
   9993  1.1  mrg 	 really added if -fbounds-check is enabled.  Exclude deferred
   9994  1.1  mrg 	 character length lefthand sides.  */
   9995  1.1  mrg       if (expr1->ts.type == BT_CHARACTER && expr2->expr_type != EXPR_NULL
   9996  1.1  mrg 	  && !expr1->ts.deferred
   9997  1.1  mrg 	  && !expr1->symtree->n.sym->attr.proc_pointer
   9998  1.1  mrg 	  && !gfc_is_proc_ptr_comp (expr1))
   9999  1.1  mrg 	{
   10000  1.1  mrg 	  gcc_assert (expr2->ts.type == BT_CHARACTER);
   10001  1.1  mrg 	  gcc_assert (lse.string_length && rse.string_length);
   10002  1.1  mrg 	  gfc_trans_same_strlen_check ("pointer assignment", &expr1->where,
   10003  1.1  mrg 				       lse.string_length, rse.string_length,
   10004  1.1  mrg 				       &block);
   10005  1.1  mrg 	}
   10006  1.1  mrg 
   10007  1.1  mrg       /* The assignment to an deferred character length sets the string
   10008  1.1  mrg 	 length to that of the rhs.  */
   10009  1.1  mrg       if (expr1->ts.deferred)
   10010  1.1  mrg 	{
   10011  1.1  mrg 	  if (expr2->expr_type != EXPR_NULL && lse.string_length != NULL)
   10012  1.1  mrg 	    gfc_add_modify (&block, lse.string_length,
   10013  1.1  mrg 			    fold_convert (TREE_TYPE (lse.string_length),
   10014  1.1  mrg 					  rse.string_length));
   10015  1.1  mrg 	  else if (lse.string_length != NULL)
   10016  1.1  mrg 	    gfc_add_modify (&block, lse.string_length,
   10017  1.1  mrg 			    build_zero_cst (TREE_TYPE (lse.string_length)));
   10018  1.1  mrg 	}
   10019  1.1  mrg 
   10020  1.1  mrg       gfc_add_modify (&block, lse.expr,
   10021  1.1  mrg 		      fold_convert (TREE_TYPE (lse.expr), rse.expr));
   10022  1.1  mrg 
   10023  1.1  mrg       /* Also set the tokens for pointer components in derived typed
   10024  1.1  mrg 	 coarrays.  */
   10025  1.1  mrg       if (flag_coarray == GFC_FCOARRAY_LIB)
   10026  1.1  mrg 	trans_caf_token_assign (&lse, &rse, expr1, expr2);
   10027  1.1  mrg 
   10028  1.1  mrg       gfc_add_block_to_block (&block, &rse.post);
   10029  1.1  mrg       gfc_add_block_to_block (&block, &lse.post);
   10030  1.1  mrg     }
   10031  1.1  mrg   else
   10032  1.1  mrg     {
   10033  1.1  mrg       gfc_ref* remap;
   10034  1.1  mrg       bool rank_remap;
   10035  1.1  mrg       tree strlen_lhs;
   10036  1.1  mrg       tree strlen_rhs = NULL_TREE;
   10037  1.1  mrg 
   10038  1.1  mrg       /* Array pointer.  Find the last reference on the LHS and if it is an
   10039  1.1  mrg 	 array section ref, we're dealing with bounds remapping.  In this case,
   10040  1.1  mrg 	 set it to AR_FULL so that gfc_conv_expr_descriptor does
   10041  1.1  mrg 	 not see it and process the bounds remapping afterwards explicitly.  */
   10042  1.1  mrg       for (remap = expr1->ref; remap; remap = remap->next)
   10043  1.1  mrg 	if (!remap->next && remap->type == REF_ARRAY
   10044  1.1  mrg 	    && remap->u.ar.type == AR_SECTION)
   10045  1.1  mrg 	  break;
   10046  1.1  mrg       rank_remap = (remap && remap->u.ar.end[0]);
   10047  1.1  mrg 
   10048  1.1  mrg       if (remap && expr2->expr_type == EXPR_NULL)
   10049  1.1  mrg 	{
   10050  1.1  mrg 	  gfc_error ("If bounds remapping is specified at %L, "
   10051  1.1  mrg 		     "the pointer target shall not be NULL", &expr1->where);
   10052  1.1  mrg 	  return NULL_TREE;
   10053  1.1  mrg 	}
   10054  1.1  mrg 
   10055  1.1  mrg       gfc_init_se (&lse, NULL);
   10056  1.1  mrg       if (remap)
   10057  1.1  mrg 	lse.descriptor_only = 1;
   10058  1.1  mrg       gfc_conv_expr_descriptor (&lse, expr1);
   10059  1.1  mrg       strlen_lhs = lse.string_length;
   10060  1.1  mrg       desc = lse.expr;
   10061  1.1  mrg 
   10062  1.1  mrg       if (expr2->expr_type == EXPR_NULL)
   10063  1.1  mrg 	{
   10064  1.1  mrg 	  /* Just set the data pointer to null.  */
   10065  1.1  mrg 	  gfc_conv_descriptor_data_set (&lse.pre, lse.expr, null_pointer_node);
   10066  1.1  mrg 	}
   10067  1.1  mrg       else if (rank_remap)
   10068  1.1  mrg 	{
   10069  1.1  mrg 	  /* If we are rank-remapping, just get the RHS's descriptor and
   10070  1.1  mrg 	     process this later on.  */
   10071  1.1  mrg 	  gfc_init_se (&rse, NULL);
   10072  1.1  mrg 	  rse.direct_byref = 1;
   10073  1.1  mrg 	  rse.byref_noassign = 1;
   10074  1.1  mrg 
   10075  1.1  mrg 	  if (expr2->expr_type == EXPR_FUNCTION && expr2->ts.type == BT_CLASS)
   10076  1.1  mrg 	    expr1_vptr = trans_class_pointer_fcn (&block, &lse, &rse,
   10077  1.1  mrg 						  expr1, expr2);
   10078  1.1  mrg 	  else if (expr2->expr_type == EXPR_FUNCTION)
   10079  1.1  mrg 	    {
   10080  1.1  mrg 	      tree bound[GFC_MAX_DIMENSIONS];
   10081  1.1  mrg 	      int i;
   10082  1.1  mrg 
   10083  1.1  mrg 	      for (i = 0; i < expr2->rank; i++)
   10084  1.1  mrg 		bound[i] = NULL_TREE;
   10085  1.1  mrg 	      tmp = gfc_typenode_for_spec (&expr2->ts);
   10086  1.1  mrg 	      tmp = gfc_get_array_type_bounds (tmp, expr2->rank, 0,
   10087  1.1  mrg 					       bound, bound, 0,
   10088  1.1  mrg 					       GFC_ARRAY_POINTER_CONT, false);
   10089  1.1  mrg 	      tmp = gfc_create_var (tmp, "ptrtemp");
   10090  1.1  mrg 	      rse.descriptor_only = 0;
   10091  1.1  mrg 	      rse.expr = tmp;
   10092  1.1  mrg 	      rse.direct_byref = 1;
   10093  1.1  mrg 	      gfc_conv_expr_descriptor (&rse, expr2);
   10094  1.1  mrg 	      strlen_rhs = rse.string_length;
   10095  1.1  mrg 	      rse.expr = tmp;
   10096  1.1  mrg 	    }
   10097  1.1  mrg 	  else
   10098  1.1  mrg 	    {
   10099  1.1  mrg 	      gfc_conv_expr_descriptor (&rse, expr2);
   10100  1.1  mrg 	      strlen_rhs = rse.string_length;
   10101  1.1  mrg 	      if (expr1->ts.type == BT_CLASS)
   10102  1.1  mrg 		expr1_vptr = trans_class_vptr_len_assignment (&block, expr1,
   10103  1.1  mrg 							      expr2, &rse,
   10104  1.1  mrg 							      NULL, NULL);
   10105  1.1  mrg 	    }
   10106  1.1  mrg 	}
   10107  1.1  mrg       else if (expr2->expr_type == EXPR_VARIABLE)
   10108  1.1  mrg 	{
   10109  1.1  mrg 	  /* Assign directly to the LHS's descriptor.  */
   10110  1.1  mrg 	  lse.descriptor_only = 0;
   10111  1.1  mrg 	  lse.direct_byref = 1;
   10112  1.1  mrg 	  gfc_conv_expr_descriptor (&lse, expr2);
   10113  1.1  mrg 	  strlen_rhs = lse.string_length;
   10114  1.1  mrg 	  gfc_init_se (&rse, NULL);
   10115  1.1  mrg 
   10116  1.1  mrg 	  if (expr1->ts.type == BT_CLASS)
   10117  1.1  mrg 	    {
   10118  1.1  mrg 	      rse.expr = NULL_TREE;
   10119  1.1  mrg 	      rse.string_length = strlen_rhs;
   10120  1.1  mrg 	      trans_class_vptr_len_assignment (&block, expr1, expr2, &rse,
   10121  1.1  mrg 					       NULL, NULL);
   10122  1.1  mrg 	    }
   10123  1.1  mrg 
   10124  1.1  mrg 	  if (remap == NULL)
   10125  1.1  mrg 	    {
   10126  1.1  mrg 	      /* If the target is not a whole array, use the target array
   10127  1.1  mrg 		 reference for remap.  */
   10128  1.1  mrg 	      for (remap = expr2->ref; remap; remap = remap->next)
   10129  1.1  mrg 		if (remap->type == REF_ARRAY
   10130  1.1  mrg 		    && remap->u.ar.type == AR_FULL
   10131  1.1  mrg 		    && remap->next)
   10132  1.1  mrg 		  break;
   10133  1.1  mrg 	    }
   10134  1.1  mrg 	}
   10135  1.1  mrg       else if (expr2->expr_type == EXPR_FUNCTION && expr2->ts.type == BT_CLASS)
   10136  1.1  mrg 	{
   10137  1.1  mrg 	  gfc_init_se (&rse, NULL);
   10138  1.1  mrg 	  rse.want_pointer = 1;
   10139  1.1  mrg 	  gfc_conv_function_expr (&rse, expr2);
   10140  1.1  mrg 	  if (expr1->ts.type != BT_CLASS)
   10141  1.1  mrg 	    {
   10142  1.1  mrg 	      rse.expr = gfc_class_data_get (rse.expr);
   10143  1.1  mrg 	      gfc_add_modify (&lse.pre, desc, rse.expr);
   10144  1.1  mrg 	      /* Set the lhs span.  */
   10145  1.1  mrg 	      tmp = TREE_TYPE (rse.expr);
   10146  1.1  mrg 	      tmp = TYPE_SIZE_UNIT (gfc_get_element_type (tmp));
   10147  1.1  mrg 	      tmp = fold_convert (gfc_array_index_type, tmp);
   10148  1.1  mrg 	      gfc_conv_descriptor_span_set (&lse.pre, desc, tmp);
   10149  1.1  mrg  	    }
   10150  1.1  mrg 	  else
   10151  1.1  mrg 	    {
   10152  1.1  mrg 	      expr1_vptr = trans_class_vptr_len_assignment (&block, expr1,
   10153  1.1  mrg 							    expr2, &rse, NULL,
   10154  1.1  mrg 							    NULL);
   10155  1.1  mrg 	      gfc_add_block_to_block (&block, &rse.pre);
   10156  1.1  mrg 	      tmp = gfc_create_var (TREE_TYPE (rse.expr), "ptrtemp");
   10157  1.1  mrg 	      gfc_add_modify (&lse.pre, tmp, rse.expr);
   10158  1.1  mrg 
   10159  1.1  mrg 	      gfc_add_modify (&lse.pre, expr1_vptr,
   10160  1.1  mrg 			      fold_convert (TREE_TYPE (expr1_vptr),
   10161  1.1  mrg 					gfc_class_vptr_get (tmp)));
   10162  1.1  mrg 	      rse.expr = gfc_class_data_get (tmp);
   10163  1.1  mrg 	      gfc_add_modify (&lse.pre, desc, rse.expr);
   10164  1.1  mrg 	    }
   10165  1.1  mrg 	}
   10166  1.1  mrg       else
   10167  1.1  mrg 	{
   10168  1.1  mrg 	  /* Assign to a temporary descriptor and then copy that
   10169  1.1  mrg 	     temporary to the pointer.  */
   10170  1.1  mrg 	  tmp = gfc_create_var (TREE_TYPE (desc), "ptrtemp");
   10171  1.1  mrg 	  lse.descriptor_only = 0;
   10172  1.1  mrg 	  lse.expr = tmp;
   10173  1.1  mrg 	  lse.direct_byref = 1;
   10174  1.1  mrg 	  gfc_conv_expr_descriptor (&lse, expr2);
   10175  1.1  mrg 	  strlen_rhs = lse.string_length;
   10176  1.1  mrg 	  gfc_add_modify (&lse.pre, desc, tmp);
   10177  1.1  mrg 	}
   10178  1.1  mrg 
   10179  1.1  mrg       if (expr1->ts.type == BT_CHARACTER
   10180  1.1  mrg 	  && expr1->symtree->n.sym->ts.deferred
   10181  1.1  mrg 	  && expr1->symtree->n.sym->ts.u.cl->backend_decl
   10182  1.1  mrg 	  && VAR_P (expr1->symtree->n.sym->ts.u.cl->backend_decl))
   10183  1.1  mrg 	{
   10184  1.1  mrg 	  tmp = expr1->symtree->n.sym->ts.u.cl->backend_decl;
   10185  1.1  mrg 	  if (expr2->expr_type != EXPR_NULL)
   10186  1.1  mrg 	    gfc_add_modify (&block, tmp,
   10187  1.1  mrg 			    fold_convert (TREE_TYPE (tmp), strlen_rhs));
   10188  1.1  mrg 	  else
   10189  1.1  mrg 	    gfc_add_modify (&block, tmp, build_zero_cst (TREE_TYPE (tmp)));
   10190  1.1  mrg 	}
   10191  1.1  mrg 
   10192  1.1  mrg       gfc_add_block_to_block (&block, &lse.pre);
   10193  1.1  mrg       if (rank_remap)
   10194  1.1  mrg 	gfc_add_block_to_block (&block, &rse.pre);
   10195  1.1  mrg 
   10196  1.1  mrg       /* If we do bounds remapping, update LHS descriptor accordingly.  */
   10197  1.1  mrg       if (remap)
   10198  1.1  mrg 	{
   10199  1.1  mrg 	  int dim;
   10200  1.1  mrg 	  gcc_assert (remap->u.ar.dimen == expr1->rank);
   10201  1.1  mrg 
   10202  1.1  mrg 	  if (rank_remap)
   10203  1.1  mrg 	    {
   10204  1.1  mrg 	      /* Do rank remapping.  We already have the RHS's descriptor
   10205  1.1  mrg 		 converted in rse and now have to build the correct LHS
   10206  1.1  mrg 		 descriptor for it.  */
   10207  1.1  mrg 
   10208  1.1  mrg 	      tree dtype, data, span;
   10209  1.1  mrg 	      tree offs, stride;
   10210  1.1  mrg 	      tree lbound, ubound;
   10211  1.1  mrg 
   10212  1.1  mrg 	      /* Set dtype.  */
   10213  1.1  mrg 	      dtype = gfc_conv_descriptor_dtype (desc);
   10214  1.1  mrg 	      tmp = gfc_get_dtype (TREE_TYPE (desc));
   10215  1.1  mrg 	      gfc_add_modify (&block, dtype, tmp);
   10216  1.1  mrg 
   10217  1.1  mrg 	      /* Copy data pointer.  */
   10218  1.1  mrg 	      data = gfc_conv_descriptor_data_get (rse.expr);
   10219  1.1  mrg 	      gfc_conv_descriptor_data_set (&block, desc, data);
   10220  1.1  mrg 
   10221  1.1  mrg 	      /* Copy the span.  */
   10222  1.1  mrg 	      if (TREE_CODE (rse.expr) == VAR_DECL
   10223  1.1  mrg 		  && GFC_DECL_PTR_ARRAY_P (rse.expr))
   10224  1.1  mrg 		span = gfc_conv_descriptor_span_get (rse.expr);
   10225  1.1  mrg 	      else
   10226  1.1  mrg 		{
   10227  1.1  mrg 		  tmp = TREE_TYPE (rse.expr);
   10228  1.1  mrg 		  tmp = TYPE_SIZE_UNIT (gfc_get_element_type (tmp));
   10229  1.1  mrg 		  span = fold_convert (gfc_array_index_type, tmp);
   10230  1.1  mrg 		}
   10231  1.1  mrg 	      gfc_conv_descriptor_span_set (&block, desc, span);
   10232  1.1  mrg 
   10233  1.1  mrg 	      /* Copy offset but adjust it such that it would correspond
   10234  1.1  mrg 		 to a lbound of zero.  */
   10235  1.1  mrg 	      offs = gfc_conv_descriptor_offset_get (rse.expr);
   10236  1.1  mrg 	      for (dim = 0; dim < expr2->rank; ++dim)
   10237  1.1  mrg 		{
   10238  1.1  mrg 		  stride = gfc_conv_descriptor_stride_get (rse.expr,
   10239  1.1  mrg 							   gfc_rank_cst[dim]);
   10240  1.1  mrg 		  lbound = gfc_conv_descriptor_lbound_get (rse.expr,
   10241  1.1  mrg 							   gfc_rank_cst[dim]);
   10242  1.1  mrg 		  tmp = fold_build2_loc (input_location, MULT_EXPR,
   10243  1.1  mrg 					 gfc_array_index_type, stride, lbound);
   10244  1.1  mrg 		  offs = fold_build2_loc (input_location, PLUS_EXPR,
   10245  1.1  mrg 					  gfc_array_index_type, offs, tmp);
   10246  1.1  mrg 		}
   10247  1.1  mrg 	      gfc_conv_descriptor_offset_set (&block, desc, offs);
   10248  1.1  mrg 
   10249  1.1  mrg 	      /* Set the bounds as declared for the LHS and calculate strides as
   10250  1.1  mrg 		 well as another offset update accordingly.  */
   10251  1.1  mrg 	      stride = gfc_conv_descriptor_stride_get (rse.expr,
   10252  1.1  mrg 						       gfc_rank_cst[0]);
   10253  1.1  mrg 	      for (dim = 0; dim < expr1->rank; ++dim)
   10254  1.1  mrg 		{
   10255  1.1  mrg 		  gfc_se lower_se;
   10256  1.1  mrg 		  gfc_se upper_se;
   10257  1.1  mrg 
   10258  1.1  mrg 		  gcc_assert (remap->u.ar.start[dim] && remap->u.ar.end[dim]);
   10259  1.1  mrg 
   10260  1.1  mrg 		  /* Convert declared bounds.  */
   10261  1.1  mrg 		  gfc_init_se (&lower_se, NULL);
   10262  1.1  mrg 		  gfc_init_se (&upper_se, NULL);
   10263  1.1  mrg 		  gfc_conv_expr (&lower_se, remap->u.ar.start[dim]);
   10264  1.1  mrg 		  gfc_conv_expr (&upper_se, remap->u.ar.end[dim]);
   10265  1.1  mrg 
   10266  1.1  mrg 		  gfc_add_block_to_block (&block, &lower_se.pre);
   10267  1.1  mrg 		  gfc_add_block_to_block (&block, &upper_se.pre);
   10268  1.1  mrg 
   10269  1.1  mrg 		  lbound = fold_convert (gfc_array_index_type, lower_se.expr);
   10270  1.1  mrg 		  ubound = fold_convert (gfc_array_index_type, upper_se.expr);
   10271  1.1  mrg 
   10272  1.1  mrg 		  lbound = gfc_evaluate_now (lbound, &block);
   10273  1.1  mrg 		  ubound = gfc_evaluate_now (ubound, &block);
   10274  1.1  mrg 
   10275  1.1  mrg 		  gfc_add_block_to_block (&block, &lower_se.post);
   10276  1.1  mrg 		  gfc_add_block_to_block (&block, &upper_se.post);
   10277  1.1  mrg 
   10278  1.1  mrg 		  /* Set bounds in descriptor.  */
   10279  1.1  mrg 		  gfc_conv_descriptor_lbound_set (&block, desc,
   10280  1.1  mrg 						  gfc_rank_cst[dim], lbound);
   10281  1.1  mrg 		  gfc_conv_descriptor_ubound_set (&block, desc,
   10282  1.1  mrg 						  gfc_rank_cst[dim], ubound);
   10283  1.1  mrg 
   10284  1.1  mrg 		  /* Set stride.  */
   10285  1.1  mrg 		  stride = gfc_evaluate_now (stride, &block);
   10286  1.1  mrg 		  gfc_conv_descriptor_stride_set (&block, desc,
   10287  1.1  mrg 						  gfc_rank_cst[dim], stride);
   10288  1.1  mrg 
   10289  1.1  mrg 		  /* Update offset.  */
   10290  1.1  mrg 		  offs = gfc_conv_descriptor_offset_get (desc);
   10291  1.1  mrg 		  tmp = fold_build2_loc (input_location, MULT_EXPR,
   10292  1.1  mrg 					 gfc_array_index_type, lbound, stride);
   10293  1.1  mrg 		  offs = fold_build2_loc (input_location, MINUS_EXPR,
   10294  1.1  mrg 					  gfc_array_index_type, offs, tmp);
   10295  1.1  mrg 		  offs = gfc_evaluate_now (offs, &block);
   10296  1.1  mrg 		  gfc_conv_descriptor_offset_set (&block, desc, offs);
   10297  1.1  mrg 
   10298  1.1  mrg 		  /* Update stride.  */
   10299  1.1  mrg 		  tmp = gfc_conv_array_extent_dim (lbound, ubound, NULL);
   10300  1.1  mrg 		  stride = fold_build2_loc (input_location, MULT_EXPR,
   10301  1.1  mrg 					    gfc_array_index_type, stride, tmp);
   10302  1.1  mrg 		}
   10303  1.1  mrg 	    }
   10304  1.1  mrg 	  else
   10305  1.1  mrg 	    {
   10306  1.1  mrg 	      /* Bounds remapping.  Just shift the lower bounds.  */
   10307  1.1  mrg 
   10308  1.1  mrg 	      gcc_assert (expr1->rank == expr2->rank);
   10309  1.1  mrg 
   10310  1.1  mrg 	      for (dim = 0; dim < remap->u.ar.dimen; ++dim)
   10311  1.1  mrg 		{
   10312  1.1  mrg 		  gfc_se lbound_se;
   10313  1.1  mrg 
   10314  1.1  mrg 		  gcc_assert (!remap->u.ar.end[dim]);
   10315  1.1  mrg 		  gfc_init_se (&lbound_se, NULL);
   10316  1.1  mrg 		  if (remap->u.ar.start[dim])
   10317  1.1  mrg 		    {
   10318  1.1  mrg 		      gfc_conv_expr (&lbound_se, remap->u.ar.start[dim]);
   10319  1.1  mrg 		      gfc_add_block_to_block (&block, &lbound_se.pre);
   10320  1.1  mrg 		    }
   10321  1.1  mrg 		  else
   10322  1.1  mrg 		    /* This remap arises from a target that is not a whole
   10323  1.1  mrg 		       array. The start expressions will be NULL but we need
   10324  1.1  mrg 		       the lbounds to be one.  */
   10325  1.1  mrg 		    lbound_se.expr = gfc_index_one_node;
   10326  1.1  mrg 		  gfc_conv_shift_descriptor_lbound (&block, desc,
   10327  1.1  mrg 						    dim, lbound_se.expr);
   10328  1.1  mrg 		  gfc_add_block_to_block (&block, &lbound_se.post);
   10329  1.1  mrg 		}
   10330  1.1  mrg 	    }
   10331  1.1  mrg 	}
   10332  1.1  mrg 
   10333  1.1  mrg       /* If rank remapping was done, check with -fcheck=bounds that
   10334  1.1  mrg 	 the target is at least as large as the pointer.  */
   10335  1.1  mrg       if (rank_remap && (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS))
   10336  1.1  mrg 	{
   10337  1.1  mrg 	  tree lsize, rsize;
   10338  1.1  mrg 	  tree fault;
   10339  1.1  mrg 	  const char* msg;
   10340  1.1  mrg 
   10341  1.1  mrg 	  lsize = gfc_conv_descriptor_size (lse.expr, expr1->rank);
   10342  1.1  mrg 	  rsize = gfc_conv_descriptor_size (rse.expr, expr2->rank);
   10343  1.1  mrg 
   10344  1.1  mrg 	  lsize = gfc_evaluate_now (lsize, &block);
   10345  1.1  mrg 	  rsize = gfc_evaluate_now (rsize, &block);
   10346  1.1  mrg 	  fault = fold_build2_loc (input_location, LT_EXPR, logical_type_node,
   10347  1.1  mrg 				   rsize, lsize);
   10348  1.1  mrg 
   10349  1.1  mrg 	  msg = _("Target of rank remapping is too small (%ld < %ld)");
   10350  1.1  mrg 	  gfc_trans_runtime_check (true, false, fault, &block, &expr2->where,
   10351  1.1  mrg 				   msg, rsize, lsize);
   10352  1.1  mrg 	}
   10353  1.1  mrg 
   10354  1.1  mrg       /* Check string lengths if applicable.  The check is only really added
   10355  1.1  mrg 	 to the output code if -fbounds-check is enabled.  */
   10356  1.1  mrg       if (expr1->ts.type == BT_CHARACTER && expr2->expr_type != EXPR_NULL)
   10357  1.1  mrg 	{
   10358  1.1  mrg 	  gcc_assert (expr2->ts.type == BT_CHARACTER);
   10359  1.1  mrg 	  gcc_assert (strlen_lhs && strlen_rhs);
   10360  1.1  mrg 	  gfc_trans_same_strlen_check ("pointer assignment", &expr1->where,
   10361  1.1  mrg 				       strlen_lhs, strlen_rhs, &block);
   10362  1.1  mrg 	}
   10363  1.1  mrg 
   10364  1.1  mrg       gfc_add_block_to_block (&block, &lse.post);
   10365  1.1  mrg       if (rank_remap)
   10366  1.1  mrg 	gfc_add_block_to_block (&block, &rse.post);
   10367  1.1  mrg     }
   10368  1.1  mrg 
   10369  1.1  mrg   return gfc_finish_block (&block);
   10370  1.1  mrg }
   10371  1.1  mrg 
   10372  1.1  mrg 
   10373  1.1  mrg /* Makes sure se is suitable for passing as a function string parameter.  */
   10374  1.1  mrg /* TODO: Need to check all callers of this function.  It may be abused.  */
   10375  1.1  mrg 
   10376  1.1  mrg void
   10377  1.1  mrg gfc_conv_string_parameter (gfc_se * se)
   10378  1.1  mrg {
   10379  1.1  mrg   tree type;
   10380  1.1  mrg 
   10381  1.1  mrg   if (TREE_CODE (se->expr) == STRING_CST)
   10382  1.1  mrg     {
   10383  1.1  mrg       type = TREE_TYPE (TREE_TYPE (se->expr));
   10384  1.1  mrg       se->expr = gfc_build_addr_expr (build_pointer_type (type), se->expr);
   10385  1.1  mrg       return;
   10386  1.1  mrg     }
   10387  1.1  mrg 
   10388  1.1  mrg   if ((TREE_CODE (TREE_TYPE (se->expr)) == ARRAY_TYPE
   10389  1.1  mrg        || TREE_CODE (TREE_TYPE (se->expr)) == INTEGER_TYPE)
   10390  1.1  mrg       && TYPE_STRING_FLAG (TREE_TYPE (se->expr)))
   10391  1.1  mrg     {
   10392  1.1  mrg       if (TREE_CODE (se->expr) != INDIRECT_REF)
   10393  1.1  mrg 	{
   10394  1.1  mrg 	  type = TREE_TYPE (se->expr);
   10395  1.1  mrg           se->expr = gfc_build_addr_expr (build_pointer_type (type), se->expr);
   10396  1.1  mrg 	}
   10397  1.1  mrg       else
   10398  1.1  mrg 	{
   10399  1.1  mrg 	  type = gfc_get_character_type_len (gfc_default_character_kind,
   10400  1.1  mrg 					     se->string_length);
   10401  1.1  mrg 	  type = build_pointer_type (type);
   10402  1.1  mrg 	  se->expr = gfc_build_addr_expr (type, se->expr);
   10403  1.1  mrg 	}
   10404  1.1  mrg     }
   10405  1.1  mrg 
   10406  1.1  mrg   gcc_assert (POINTER_TYPE_P (TREE_TYPE (se->expr)));
   10407  1.1  mrg }
   10408  1.1  mrg 
   10409  1.1  mrg 
   10410  1.1  mrg /* Generate code for assignment of scalar variables.  Includes character
   10411  1.1  mrg    strings and derived types with allocatable components.
   10412  1.1  mrg    If you know that the LHS has no allocations, set dealloc to false.
   10413  1.1  mrg 
   10414  1.1  mrg    DEEP_COPY has no effect if the typespec TS is not a derived type with
   10415  1.1  mrg    allocatable components.  Otherwise, if it is set, an explicit copy of each
   10416  1.1  mrg    allocatable component is made.  This is necessary as a simple copy of the
   10417  1.1  mrg    whole object would copy array descriptors as is, so that the lhs's
   10418  1.1  mrg    allocatable components would point to the rhs's after the assignment.
   10419  1.1  mrg    Typically, setting DEEP_COPY is necessary if the rhs is a variable, and not
   10420  1.1  mrg    necessary if the rhs is a non-pointer function, as the allocatable components
   10421  1.1  mrg    are not accessible by other means than the function's result after the
   10422  1.1  mrg    function has returned.  It is even more subtle when temporaries are involved,
   10423  1.1  mrg    as the two following examples show:
   10424  1.1  mrg     1.  When we evaluate an array constructor, a temporary is created.  Thus
   10425  1.1  mrg       there is theoretically no alias possible.  However, no deep copy is
   10426  1.1  mrg       made for this temporary, so that if the constructor is made of one or
   10427  1.1  mrg       more variable with allocatable components, those components still point
   10428  1.1  mrg       to the variable's: DEEP_COPY should be set for the assignment from the
   10429  1.1  mrg       temporary to the lhs in that case.
   10430  1.1  mrg     2.  When assigning a scalar to an array, we evaluate the scalar value out
   10431  1.1  mrg       of the loop, store it into a temporary variable, and assign from that.
   10432  1.1  mrg       In that case, deep copying when assigning to the temporary would be a
   10433  1.1  mrg       waste of resources; however deep copies should happen when assigning from
   10434  1.1  mrg       the temporary to each array element: again DEEP_COPY should be set for
   10435  1.1  mrg       the assignment from the temporary to the lhs.  */
   10436  1.1  mrg 
   10437  1.1  mrg tree
   10438  1.1  mrg gfc_trans_scalar_assign (gfc_se * lse, gfc_se * rse, gfc_typespec ts,
   10439  1.1  mrg 			 bool deep_copy, bool dealloc, bool in_coarray)
   10440  1.1  mrg {
   10441  1.1  mrg   stmtblock_t block;
   10442  1.1  mrg   tree tmp;
   10443  1.1  mrg   tree cond;
   10444  1.1  mrg 
   10445  1.1  mrg   gfc_init_block (&block);
   10446  1.1  mrg 
   10447  1.1  mrg   if (ts.type == BT_CHARACTER)
   10448  1.1  mrg     {
   10449  1.1  mrg       tree rlen = NULL;
   10450  1.1  mrg       tree llen = NULL;
   10451  1.1  mrg 
   10452  1.1  mrg       if (lse->string_length != NULL_TREE)
   10453  1.1  mrg 	{
   10454  1.1  mrg 	  gfc_conv_string_parameter (lse);
   10455  1.1  mrg 	  gfc_add_block_to_block (&block, &lse->pre);
   10456  1.1  mrg 	  llen = lse->string_length;
   10457  1.1  mrg 	}
   10458  1.1  mrg 
   10459  1.1  mrg       if (rse->string_length != NULL_TREE)
   10460  1.1  mrg 	{
   10461  1.1  mrg 	  gfc_conv_string_parameter (rse);
   10462  1.1  mrg 	  gfc_add_block_to_block (&block, &rse->pre);
   10463  1.1  mrg 	  rlen = rse->string_length;
   10464  1.1  mrg 	}
   10465  1.1  mrg 
   10466  1.1  mrg       gfc_trans_string_copy (&block, llen, lse->expr, ts.kind, rlen,
   10467  1.1  mrg 			     rse->expr, ts.kind);
   10468  1.1  mrg     }
   10469  1.1  mrg   else if (gfc_bt_struct (ts.type)
   10470  1.1  mrg 	   && (ts.u.derived->attr.alloc_comp
   10471  1.1  mrg 		|| (deep_copy && ts.u.derived->attr.pdt_type)))
   10472  1.1  mrg     {
   10473  1.1  mrg       tree tmp_var = NULL_TREE;
   10474  1.1  mrg       cond = NULL_TREE;
   10475  1.1  mrg 
   10476  1.1  mrg       /* Are the rhs and the lhs the same?  */
   10477  1.1  mrg       if (deep_copy)
   10478  1.1  mrg 	{
   10479  1.1  mrg 	  cond = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
   10480  1.1  mrg 				  gfc_build_addr_expr (NULL_TREE, lse->expr),
   10481  1.1  mrg 				  gfc_build_addr_expr (NULL_TREE, rse->expr));
   10482  1.1  mrg 	  cond = gfc_evaluate_now (cond, &lse->pre);
   10483  1.1  mrg 	}
   10484  1.1  mrg 
   10485  1.1  mrg       /* Deallocate the lhs allocated components as long as it is not
   10486  1.1  mrg 	 the same as the rhs.  This must be done following the assignment
   10487  1.1  mrg 	 to prevent deallocating data that could be used in the rhs
   10488  1.1  mrg 	 expression.  */
   10489  1.1  mrg       if (dealloc)
   10490  1.1  mrg 	{
   10491  1.1  mrg 	  tmp_var = gfc_evaluate_now (lse->expr, &lse->pre);
   10492  1.1  mrg 	  tmp = gfc_deallocate_alloc_comp_no_caf (ts.u.derived, tmp_var, 0);
   10493  1.1  mrg 	  if (deep_copy)
   10494  1.1  mrg 	    tmp = build3_v (COND_EXPR, cond, build_empty_stmt (input_location),
   10495  1.1  mrg 			    tmp);
   10496  1.1  mrg 	  gfc_add_expr_to_block (&lse->post, tmp);
   10497  1.1  mrg 	}
   10498  1.1  mrg 
   10499  1.1  mrg       gfc_add_block_to_block (&block, &rse->pre);
   10500  1.1  mrg       gfc_add_block_to_block (&block, &lse->pre);
   10501  1.1  mrg 
   10502  1.1  mrg       gfc_add_modify (&block, lse->expr,
   10503  1.1  mrg 			   fold_convert (TREE_TYPE (lse->expr), rse->expr));
   10504  1.1  mrg 
   10505  1.1  mrg       /* Restore pointer address of coarray components.  */
   10506  1.1  mrg       if (ts.u.derived->attr.coarray_comp && deep_copy && tmp_var != NULL_TREE)
   10507  1.1  mrg 	{
   10508  1.1  mrg 	  tmp = gfc_reassign_alloc_comp_caf (ts.u.derived, tmp_var, lse->expr);
   10509  1.1  mrg 	  tmp = build3_v (COND_EXPR, cond, build_empty_stmt (input_location),
   10510  1.1  mrg 			  tmp);
   10511  1.1  mrg 	  gfc_add_expr_to_block (&block, tmp);
   10512  1.1  mrg 	}
   10513  1.1  mrg 
   10514  1.1  mrg       /* Do a deep copy if the rhs is a variable, if it is not the
   10515  1.1  mrg 	 same as the lhs.  */
   10516  1.1  mrg       if (deep_copy)
   10517  1.1  mrg 	{
   10518  1.1  mrg 	  int caf_mode = in_coarray ? (GFC_STRUCTURE_CAF_MODE_ENABLE_COARRAY
   10519  1.1  mrg 				       | GFC_STRUCTURE_CAF_MODE_IN_COARRAY) : 0;
   10520  1.1  mrg 	  tmp = gfc_copy_alloc_comp (ts.u.derived, rse->expr, lse->expr, 0,
   10521  1.1  mrg 				     caf_mode);
   10522  1.1  mrg 	  tmp = build3_v (COND_EXPR, cond, build_empty_stmt (input_location),
   10523  1.1  mrg 			  tmp);
   10524  1.1  mrg 	  gfc_add_expr_to_block (&block, tmp);
   10525  1.1  mrg 	}
   10526  1.1  mrg     }
   10527  1.1  mrg   else if (gfc_bt_struct (ts.type))
   10528  1.1  mrg     {
   10529  1.1  mrg       gfc_add_block_to_block (&block, &lse->pre);
   10530  1.1  mrg       gfc_add_block_to_block (&block, &rse->pre);
   10531  1.1  mrg       tmp = fold_build1_loc (input_location, VIEW_CONVERT_EXPR,
   10532  1.1  mrg 			     TREE_TYPE (lse->expr), rse->expr);
   10533  1.1  mrg       gfc_add_modify (&block, lse->expr, tmp);
   10534  1.1  mrg     }
   10535  1.1  mrg   /* If possible use the rhs vptr copy with trans_scalar_class_assign....  */
   10536  1.1  mrg   else if (ts.type == BT_CLASS)
   10537  1.1  mrg     {
   10538  1.1  mrg       gfc_add_block_to_block (&block, &lse->pre);
   10539  1.1  mrg       gfc_add_block_to_block (&block, &rse->pre);
   10540  1.1  mrg 
   10541  1.1  mrg       if (!trans_scalar_class_assign (&block, lse, rse))
   10542  1.1  mrg 	{
   10543  1.1  mrg 	  /* ...otherwise assignment suffices. Note the use of VIEW_CONVERT_EXPR
   10544  1.1  mrg 	  for the lhs which ensures that class data rhs cast as a string assigns
   10545  1.1  mrg 	  correctly.  */
   10546  1.1  mrg 	  tmp = fold_build1_loc (input_location, VIEW_CONVERT_EXPR,
   10547  1.1  mrg 				 TREE_TYPE (rse->expr), lse->expr);
   10548  1.1  mrg 	  gfc_add_modify (&block, tmp, rse->expr);
   10549  1.1  mrg 	}
   10550  1.1  mrg     }
   10551  1.1  mrg   else if (ts.type != BT_CLASS)
   10552  1.1  mrg     {
   10553  1.1  mrg       gfc_add_block_to_block (&block, &lse->pre);
   10554  1.1  mrg       gfc_add_block_to_block (&block, &rse->pre);
   10555  1.1  mrg 
   10556  1.1  mrg       gfc_add_modify (&block, lse->expr,
   10557  1.1  mrg 		      fold_convert (TREE_TYPE (lse->expr), rse->expr));
   10558  1.1  mrg     }
   10559  1.1  mrg 
   10560  1.1  mrg   gfc_add_block_to_block (&block, &lse->post);
   10561  1.1  mrg   gfc_add_block_to_block (&block, &rse->post);
   10562  1.1  mrg 
   10563  1.1  mrg   return gfc_finish_block (&block);
   10564  1.1  mrg }
   10565  1.1  mrg 
   10566  1.1  mrg 
   10567  1.1  mrg /* There are quite a lot of restrictions on the optimisation in using an
   10568  1.1  mrg    array function assign without a temporary.  */
   10569  1.1  mrg 
   10570  1.1  mrg static bool
   10571  1.1  mrg arrayfunc_assign_needs_temporary (gfc_expr * expr1, gfc_expr * expr2)
   10572  1.1  mrg {
   10573  1.1  mrg   gfc_ref * ref;
   10574  1.1  mrg   bool seen_array_ref;
   10575  1.1  mrg   bool c = false;
   10576  1.1  mrg   gfc_symbol *sym = expr1->symtree->n.sym;
   10577  1.1  mrg 
   10578  1.1  mrg   /* Play it safe with class functions assigned to a derived type.  */
   10579  1.1  mrg   if (gfc_is_class_array_function (expr2)
   10580  1.1  mrg       && expr1->ts.type == BT_DERIVED)
   10581  1.1  mrg     return true;
   10582  1.1  mrg 
   10583  1.1  mrg   /* The caller has already checked rank>0 and expr_type == EXPR_FUNCTION.  */
   10584  1.1  mrg   if (expr2->value.function.isym && !gfc_is_intrinsic_libcall (expr2))
   10585  1.1  mrg     return true;
   10586  1.1  mrg 
   10587  1.1  mrg   /* Elemental functions are scalarized so that they don't need a
   10588  1.1  mrg      temporary in gfc_trans_assignment_1, so return a true.  Otherwise,
   10589  1.1  mrg      they would need special treatment in gfc_trans_arrayfunc_assign.  */
   10590  1.1  mrg   if (expr2->value.function.esym != NULL
   10591  1.1  mrg       && expr2->value.function.esym->attr.elemental)
   10592  1.1  mrg     return true;
   10593  1.1  mrg 
   10594  1.1  mrg   /* Need a temporary if rhs is not FULL or a contiguous section.  */
   10595  1.1  mrg   if (expr1->ref && !(gfc_full_array_ref_p (expr1->ref, &c) || c))
   10596  1.1  mrg     return true;
   10597  1.1  mrg 
   10598  1.1  mrg   /* Need a temporary if EXPR1 can't be expressed as a descriptor.  */
   10599  1.1  mrg   if (gfc_ref_needs_temporary_p (expr1->ref))
   10600  1.1  mrg     return true;
   10601  1.1  mrg 
   10602  1.1  mrg   /* Functions returning pointers or allocatables need temporaries.  */
   10603  1.1  mrg   if (gfc_expr_attr (expr2).pointer
   10604  1.1  mrg       || gfc_expr_attr (expr2).allocatable)
   10605  1.1  mrg     return true;
   10606  1.1  mrg 
   10607  1.1  mrg   /* Character array functions need temporaries unless the
   10608  1.1  mrg      character lengths are the same.  */
   10609  1.1  mrg   if (expr2->ts.type == BT_CHARACTER && expr2->rank > 0)
   10610  1.1  mrg     {
   10611  1.1  mrg       if (expr1->ts.u.cl->length == NULL
   10612  1.1  mrg 	    || expr1->ts.u.cl->length->expr_type != EXPR_CONSTANT)
   10613  1.1  mrg 	return true;
   10614  1.1  mrg 
   10615  1.1  mrg       if (expr2->ts.u.cl->length == NULL
   10616  1.1  mrg 	    || expr2->ts.u.cl->length->expr_type != EXPR_CONSTANT)
   10617  1.1  mrg 	return true;
   10618  1.1  mrg 
   10619  1.1  mrg       if (mpz_cmp (expr1->ts.u.cl->length->value.integer,
   10620  1.1  mrg 		     expr2->ts.u.cl->length->value.integer) != 0)
   10621  1.1  mrg 	return true;
   10622  1.1  mrg     }
   10623  1.1  mrg 
   10624  1.1  mrg   /* Check that no LHS component references appear during an array
   10625  1.1  mrg      reference. This is needed because we do not have the means to
   10626  1.1  mrg      span any arbitrary stride with an array descriptor. This check
   10627  1.1  mrg      is not needed for the rhs because the function result has to be
   10628  1.1  mrg      a complete type.  */
   10629  1.1  mrg   seen_array_ref = false;
   10630  1.1  mrg   for (ref = expr1->ref; ref; ref = ref->next)
   10631  1.1  mrg     {
   10632  1.1  mrg       if (ref->type == REF_ARRAY)
   10633  1.1  mrg 	seen_array_ref= true;
   10634  1.1  mrg       else if (ref->type == REF_COMPONENT && seen_array_ref)
   10635  1.1  mrg 	return true;
   10636  1.1  mrg     }
   10637  1.1  mrg 
   10638  1.1  mrg   /* Check for a dependency.  */
   10639  1.1  mrg   if (gfc_check_fncall_dependency (expr1, INTENT_OUT,
   10640  1.1  mrg 				   expr2->value.function.esym,
   10641  1.1  mrg 				   expr2->value.function.actual,
   10642  1.1  mrg 				   NOT_ELEMENTAL))
   10643  1.1  mrg     return true;
   10644  1.1  mrg 
   10645  1.1  mrg   /* If we have reached here with an intrinsic function, we do not
   10646  1.1  mrg      need a temporary except in the particular case that reallocation
   10647  1.1  mrg      on assignment is active and the lhs is allocatable and a target,
   10648  1.1  mrg      or a pointer which may be a subref pointer.  FIXME: The last
   10649  1.1  mrg      condition can go away when we use span in the intrinsics
   10650  1.1  mrg      directly.*/
   10651  1.1  mrg   if (expr2->value.function.isym)
   10652  1.1  mrg     return (flag_realloc_lhs && sym->attr.allocatable && sym->attr.target)
   10653  1.1  mrg       || (sym->attr.pointer && sym->attr.subref_array_pointer);
   10654  1.1  mrg 
   10655  1.1  mrg   /* If the LHS is a dummy, we need a temporary if it is not
   10656  1.1  mrg      INTENT(OUT).  */
   10657  1.1  mrg   if (sym->attr.dummy && sym->attr.intent != INTENT_OUT)
   10658  1.1  mrg     return true;
   10659  1.1  mrg 
   10660  1.1  mrg   /* If the lhs has been host_associated, is in common, a pointer or is
   10661  1.1  mrg      a target and the function is not using a RESULT variable, aliasing
   10662  1.1  mrg      can occur and a temporary is needed.  */
   10663  1.1  mrg   if ((sym->attr.host_assoc
   10664  1.1  mrg 	   || sym->attr.in_common
   10665  1.1  mrg 	   || sym->attr.pointer
   10666  1.1  mrg 	   || sym->attr.cray_pointee
   10667  1.1  mrg 	   || sym->attr.target)
   10668  1.1  mrg 	&& expr2->symtree != NULL
   10669  1.1  mrg 	&& expr2->symtree->n.sym == expr2->symtree->n.sym->result)
   10670  1.1  mrg     return true;
   10671  1.1  mrg 
   10672  1.1  mrg   /* A PURE function can unconditionally be called without a temporary.  */
   10673  1.1  mrg   if (expr2->value.function.esym != NULL
   10674  1.1  mrg       && expr2->value.function.esym->attr.pure)
   10675  1.1  mrg     return false;
   10676  1.1  mrg 
   10677  1.1  mrg   /* Implicit_pure functions are those which could legally be declared
   10678  1.1  mrg      to be PURE.  */
   10679  1.1  mrg   if (expr2->value.function.esym != NULL
   10680  1.1  mrg       && expr2->value.function.esym->attr.implicit_pure)
   10681  1.1  mrg     return false;
   10682  1.1  mrg 
   10683  1.1  mrg   if (!sym->attr.use_assoc
   10684  1.1  mrg 	&& !sym->attr.in_common
   10685  1.1  mrg 	&& !sym->attr.pointer
   10686  1.1  mrg 	&& !sym->attr.target
   10687  1.1  mrg 	&& !sym->attr.cray_pointee
   10688  1.1  mrg 	&& expr2->value.function.esym)
   10689  1.1  mrg     {
   10690  1.1  mrg       /* A temporary is not needed if the function is not contained and
   10691  1.1  mrg 	 the variable is local or host associated and not a pointer or
   10692  1.1  mrg 	 a target.  */
   10693  1.1  mrg       if (!expr2->value.function.esym->attr.contained)
   10694  1.1  mrg 	return false;
   10695  1.1  mrg 
   10696  1.1  mrg       /* A temporary is not needed if the lhs has never been host
   10697  1.1  mrg 	 associated and the procedure is contained.  */
   10698  1.1  mrg       else if (!sym->attr.host_assoc)
   10699  1.1  mrg 	return false;
   10700  1.1  mrg 
   10701  1.1  mrg       /* A temporary is not needed if the variable is local and not
   10702  1.1  mrg 	 a pointer, a target or a result.  */
   10703  1.1  mrg       if (sym->ns->parent
   10704  1.1  mrg 	    && expr2->value.function.esym->ns == sym->ns->parent)
   10705  1.1  mrg 	return false;
   10706  1.1  mrg     }
   10707  1.1  mrg 
   10708  1.1  mrg   /* Default to temporary use.  */
   10709  1.1  mrg   return true;
   10710  1.1  mrg }
   10711  1.1  mrg 
   10712  1.1  mrg 
   10713  1.1  mrg /* Provide the loop info so that the lhs descriptor can be built for
   10714  1.1  mrg    reallocatable assignments from extrinsic function calls.  */
   10715  1.1  mrg 
   10716  1.1  mrg static void
   10717  1.1  mrg realloc_lhs_loop_for_fcn_call (gfc_se *se, locus *where, gfc_ss **ss,
   10718  1.1  mrg 			       gfc_loopinfo *loop)
   10719  1.1  mrg {
   10720  1.1  mrg   /* Signal that the function call should not be made by
   10721  1.1  mrg      gfc_conv_loop_setup.  */
   10722  1.1  mrg   se->ss->is_alloc_lhs = 1;
   10723  1.1  mrg   gfc_init_loopinfo (loop);
   10724  1.1  mrg   gfc_add_ss_to_loop (loop, *ss);
   10725  1.1  mrg   gfc_add_ss_to_loop (loop, se->ss);
   10726  1.1  mrg   gfc_conv_ss_startstride (loop);
   10727  1.1  mrg   gfc_conv_loop_setup (loop, where);
   10728  1.1  mrg   gfc_copy_loopinfo_to_se (se, loop);
   10729  1.1  mrg   gfc_add_block_to_block (&se->pre, &loop->pre);
   10730  1.1  mrg   gfc_add_block_to_block (&se->pre, &loop->post);
   10731  1.1  mrg   se->ss->is_alloc_lhs = 0;
   10732  1.1  mrg }
   10733  1.1  mrg 
   10734  1.1  mrg 
   10735  1.1  mrg /* For assignment to a reallocatable lhs from intrinsic functions,
   10736  1.1  mrg    replace the se.expr (ie. the result) with a temporary descriptor.
   10737  1.1  mrg    Null the data field so that the library allocates space for the
   10738  1.1  mrg    result. Free the data of the original descriptor after the function,
   10739  1.1  mrg    in case it appears in an argument expression and transfer the
   10740  1.1  mrg    result to the original descriptor.  */
   10741  1.1  mrg 
   10742  1.1  mrg static void
   10743  1.1  mrg fcncall_realloc_result (gfc_se *se, int rank)
   10744  1.1  mrg {
   10745  1.1  mrg   tree desc;
   10746  1.1  mrg   tree res_desc;
   10747  1.1  mrg   tree tmp;
   10748  1.1  mrg   tree offset;
   10749  1.1  mrg   tree zero_cond;
   10750  1.1  mrg   tree not_same_shape;
   10751  1.1  mrg   stmtblock_t shape_block;
   10752  1.1  mrg   int n;
   10753  1.1  mrg 
   10754  1.1  mrg   /* Use the allocation done by the library.  Substitute the lhs
   10755  1.1  mrg      descriptor with a copy, whose data field is nulled.*/
   10756  1.1  mrg   desc = build_fold_indirect_ref_loc (input_location, se->expr);
   10757  1.1  mrg   if (POINTER_TYPE_P (TREE_TYPE (desc)))
   10758  1.1  mrg     desc = build_fold_indirect_ref_loc (input_location, desc);
   10759  1.1  mrg 
   10760  1.1  mrg   /* Unallocated, the descriptor does not have a dtype.  */
   10761  1.1  mrg   tmp = gfc_conv_descriptor_dtype (desc);
   10762  1.1  mrg   gfc_add_modify (&se->pre, tmp, gfc_get_dtype (TREE_TYPE (desc)));
   10763  1.1  mrg 
   10764  1.1  mrg   res_desc = gfc_evaluate_now (desc, &se->pre);
   10765  1.1  mrg   gfc_conv_descriptor_data_set (&se->pre, res_desc, null_pointer_node);
   10766  1.1  mrg   se->expr = gfc_build_addr_expr (NULL_TREE, res_desc);
   10767  1.1  mrg 
   10768  1.1  mrg   /* Free the lhs after the function call and copy the result data to
   10769  1.1  mrg      the lhs descriptor.  */
   10770  1.1  mrg   tmp = gfc_conv_descriptor_data_get (desc);
   10771  1.1  mrg   zero_cond = fold_build2_loc (input_location, EQ_EXPR,
   10772  1.1  mrg 			       logical_type_node, tmp,
   10773  1.1  mrg 			       build_int_cst (TREE_TYPE (tmp), 0));
   10774  1.1  mrg   zero_cond = gfc_evaluate_now (zero_cond, &se->post);
   10775  1.1  mrg   tmp = gfc_call_free (tmp);
   10776  1.1  mrg   gfc_add_expr_to_block (&se->post, tmp);
   10777  1.1  mrg 
   10778  1.1  mrg   tmp = gfc_conv_descriptor_data_get (res_desc);
   10779  1.1  mrg   gfc_conv_descriptor_data_set (&se->post, desc, tmp);
   10780  1.1  mrg 
   10781  1.1  mrg   /* Check that the shapes are the same between lhs and expression.
   10782  1.1  mrg      The evaluation of the shape is done in 'shape_block' to avoid
   10783  1.1  mrg      unitialized warnings from the lhs bounds. */
   10784  1.1  mrg   not_same_shape = boolean_false_node;
   10785  1.1  mrg   gfc_start_block (&shape_block);
   10786  1.1  mrg   for (n = 0 ; n < rank; n++)
   10787  1.1  mrg     {
   10788  1.1  mrg       tree tmp1;
   10789  1.1  mrg       tmp = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[n]);
   10790  1.1  mrg       tmp1 = gfc_conv_descriptor_lbound_get (res_desc, gfc_rank_cst[n]);
   10791  1.1  mrg       tmp = fold_build2_loc (input_location, MINUS_EXPR,
   10792  1.1  mrg 			     gfc_array_index_type, tmp, tmp1);
   10793  1.1  mrg       tmp1 = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[n]);
   10794  1.1  mrg       tmp = fold_build2_loc (input_location, MINUS_EXPR,
   10795  1.1  mrg 			     gfc_array_index_type, tmp, tmp1);
   10796  1.1  mrg       tmp1 = gfc_conv_descriptor_ubound_get (res_desc, gfc_rank_cst[n]);
   10797  1.1  mrg       tmp = fold_build2_loc (input_location, PLUS_EXPR,
   10798  1.1  mrg 			     gfc_array_index_type, tmp, tmp1);
   10799  1.1  mrg       tmp = fold_build2_loc (input_location, NE_EXPR,
   10800  1.1  mrg 			     logical_type_node, tmp,
   10801  1.1  mrg 			     gfc_index_zero_node);
   10802  1.1  mrg       tmp = gfc_evaluate_now (tmp, &shape_block);
   10803  1.1  mrg       if (n == 0)
   10804  1.1  mrg 	not_same_shape = tmp;
   10805  1.1  mrg       else
   10806  1.1  mrg 	not_same_shape = fold_build2_loc (input_location, TRUTH_OR_EXPR,
   10807  1.1  mrg 					  logical_type_node, tmp,
   10808  1.1  mrg 					  not_same_shape);
   10809  1.1  mrg     }
   10810  1.1  mrg 
   10811  1.1  mrg   /* 'zero_cond' being true is equal to lhs not being allocated or the
   10812  1.1  mrg      shapes being different.  */
   10813  1.1  mrg   tmp = fold_build2_loc (input_location, TRUTH_OR_EXPR, logical_type_node,
   10814  1.1  mrg 			 zero_cond, not_same_shape);
   10815  1.1  mrg   gfc_add_modify (&shape_block, zero_cond, tmp);
   10816  1.1  mrg   tmp = gfc_finish_block (&shape_block);
   10817  1.1  mrg   tmp = build3_v (COND_EXPR, zero_cond,
   10818  1.1  mrg 		  build_empty_stmt (input_location), tmp);
   10819  1.1  mrg   gfc_add_expr_to_block (&se->post, tmp);
   10820  1.1  mrg 
   10821  1.1  mrg   /* Now reset the bounds returned from the function call to bounds based
   10822  1.1  mrg      on the lhs lbounds, except where the lhs is not allocated or the shapes
   10823  1.1  mrg      of 'variable and 'expr' are different. Set the offset accordingly.  */
   10824  1.1  mrg   offset = gfc_index_zero_node;
   10825  1.1  mrg   for (n = 0 ; n < rank; n++)
   10826  1.1  mrg     {
   10827  1.1  mrg       tree lbound;
   10828  1.1  mrg 
   10829  1.1  mrg       lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[n]);
   10830  1.1  mrg       lbound = fold_build3_loc (input_location, COND_EXPR,
   10831  1.1  mrg 				gfc_array_index_type, zero_cond,
   10832  1.1  mrg 				gfc_index_one_node, lbound);
   10833  1.1  mrg       lbound = gfc_evaluate_now (lbound, &se->post);
   10834  1.1  mrg 
   10835  1.1  mrg       tmp = gfc_conv_descriptor_ubound_get (res_desc, gfc_rank_cst[n]);
   10836  1.1  mrg       tmp = fold_build2_loc (input_location, PLUS_EXPR,
   10837  1.1  mrg 			     gfc_array_index_type, tmp, lbound);
   10838  1.1  mrg       gfc_conv_descriptor_lbound_set (&se->post, desc,
   10839  1.1  mrg 				      gfc_rank_cst[n], lbound);
   10840  1.1  mrg       gfc_conv_descriptor_ubound_set (&se->post, desc,
   10841  1.1  mrg 				      gfc_rank_cst[n], tmp);
   10842  1.1  mrg 
   10843  1.1  mrg       /* Set stride and accumulate the offset.  */
   10844  1.1  mrg       tmp = gfc_conv_descriptor_stride_get (res_desc, gfc_rank_cst[n]);
   10845  1.1  mrg       gfc_conv_descriptor_stride_set (&se->post, desc,
   10846  1.1  mrg 				      gfc_rank_cst[n], tmp);
   10847  1.1  mrg       tmp = fold_build2_loc (input_location, MULT_EXPR,
   10848  1.1  mrg 			     gfc_array_index_type, lbound, tmp);
   10849  1.1  mrg       offset = fold_build2_loc (input_location, MINUS_EXPR,
   10850  1.1  mrg 				gfc_array_index_type, offset, tmp);
   10851  1.1  mrg       offset = gfc_evaluate_now (offset, &se->post);
   10852  1.1  mrg     }
   10853  1.1  mrg 
   10854  1.1  mrg   gfc_conv_descriptor_offset_set (&se->post, desc, offset);
   10855  1.1  mrg }
   10856  1.1  mrg 
   10857  1.1  mrg 
   10858  1.1  mrg 
   10859  1.1  mrg /* Try to translate array(:) = func (...), where func is a transformational
   10860  1.1  mrg    array function, without using a temporary.  Returns NULL if this isn't the
   10861  1.1  mrg    case.  */
   10862  1.1  mrg 
   10863  1.1  mrg static tree
   10864  1.1  mrg gfc_trans_arrayfunc_assign (gfc_expr * expr1, gfc_expr * expr2)
   10865  1.1  mrg {
   10866  1.1  mrg   gfc_se se;
   10867  1.1  mrg   gfc_ss *ss = NULL;
   10868  1.1  mrg   gfc_component *comp = NULL;
   10869  1.1  mrg   gfc_loopinfo loop;
   10870  1.1  mrg 
   10871  1.1  mrg   if (arrayfunc_assign_needs_temporary (expr1, expr2))
   10872  1.1  mrg     return NULL;
   10873  1.1  mrg 
   10874  1.1  mrg   /* The frontend doesn't seem to bother filling in expr->symtree for intrinsic
   10875  1.1  mrg      functions.  */
   10876  1.1  mrg   comp = gfc_get_proc_ptr_comp (expr2);
   10877  1.1  mrg 
   10878  1.1  mrg   if (!(expr2->value.function.isym
   10879  1.1  mrg 	      || (comp && comp->attr.dimension)
   10880  1.1  mrg 	      || (!comp && gfc_return_by_reference (expr2->value.function.esym)
   10881  1.1  mrg 		  && expr2->value.function.esym->result->attr.dimension)))
   10882  1.1  mrg     return NULL;
   10883  1.1  mrg 
   10884  1.1  mrg   gfc_init_se (&se, NULL);
   10885  1.1  mrg   gfc_start_block (&se.pre);
   10886  1.1  mrg   se.want_pointer = 1;
   10887  1.1  mrg 
   10888  1.1  mrg   gfc_conv_array_parameter (&se, expr1, false, NULL, NULL, NULL);
   10889  1.1  mrg 
   10890  1.1  mrg   if (expr1->ts.type == BT_DERIVED
   10891  1.1  mrg 	&& expr1->ts.u.derived->attr.alloc_comp)
   10892  1.1  mrg     {
   10893  1.1  mrg       tree tmp;
   10894  1.1  mrg       tmp = gfc_deallocate_alloc_comp_no_caf (expr1->ts.u.derived, se.expr,
   10895  1.1  mrg 					      expr1->rank);
   10896  1.1  mrg       gfc_add_expr_to_block (&se.pre, tmp);
   10897  1.1  mrg     }
   10898  1.1  mrg 
   10899  1.1  mrg   se.direct_byref = 1;
   10900  1.1  mrg   se.ss = gfc_walk_expr (expr2);
   10901  1.1  mrg   gcc_assert (se.ss != gfc_ss_terminator);
   10902  1.1  mrg 
   10903  1.1  mrg   /* Reallocate on assignment needs the loopinfo for extrinsic functions.
   10904  1.1  mrg      This is signalled to gfc_conv_procedure_call by setting is_alloc_lhs.
   10905  1.1  mrg      Clearly, this cannot be done for an allocatable function result, since
   10906  1.1  mrg      the shape of the result is unknown and, in any case, the function must
   10907  1.1  mrg      correctly take care of the reallocation internally. For intrinsic
   10908  1.1  mrg      calls, the array data is freed and the library takes care of allocation.
   10909  1.1  mrg      TODO: Add logic of trans-array.cc: gfc_alloc_allocatable_for_assignment
   10910  1.1  mrg      to the library.  */
   10911  1.1  mrg   if (flag_realloc_lhs
   10912  1.1  mrg 	&& gfc_is_reallocatable_lhs (expr1)
   10913  1.1  mrg 	&& !gfc_expr_attr (expr1).codimension
   10914  1.1  mrg 	&& !gfc_is_coindexed (expr1)
   10915  1.1  mrg 	&& !(expr2->value.function.esym
   10916  1.1  mrg 	    && expr2->value.function.esym->result->attr.allocatable))
   10917  1.1  mrg     {
   10918  1.1  mrg       realloc_lhs_warning (expr1->ts.type, true, &expr1->where);
   10919  1.1  mrg 
   10920  1.1  mrg       if (!expr2->value.function.isym)
   10921  1.1  mrg 	{
   10922  1.1  mrg 	  ss = gfc_walk_expr (expr1);
   10923  1.1  mrg 	  gcc_assert (ss != gfc_ss_terminator);
   10924  1.1  mrg 
   10925  1.1  mrg 	  realloc_lhs_loop_for_fcn_call (&se, &expr1->where, &ss, &loop);
   10926  1.1  mrg 	  ss->is_alloc_lhs = 1;
   10927  1.1  mrg 	}
   10928  1.1  mrg       else
   10929  1.1  mrg 	fcncall_realloc_result (&se, expr1->rank);
   10930  1.1  mrg     }
   10931  1.1  mrg 
   10932  1.1  mrg   gfc_conv_function_expr (&se, expr2);
   10933  1.1  mrg   gfc_add_block_to_block (&se.pre, &se.post);
   10934  1.1  mrg 
   10935  1.1  mrg   if (ss)
   10936  1.1  mrg     gfc_cleanup_loop (&loop);
   10937  1.1  mrg   else
   10938  1.1  mrg     gfc_free_ss_chain (se.ss);
   10939  1.1  mrg 
   10940  1.1  mrg   return gfc_finish_block (&se.pre);
   10941  1.1  mrg }
   10942  1.1  mrg 
   10943  1.1  mrg 
   10944  1.1  mrg /* Try to efficiently translate array(:) = 0.  Return NULL if this
   10945  1.1  mrg    can't be done.  */
   10946  1.1  mrg 
   10947  1.1  mrg static tree
   10948  1.1  mrg gfc_trans_zero_assign (gfc_expr * expr)
   10949  1.1  mrg {
   10950  1.1  mrg   tree dest, len, type;
   10951  1.1  mrg   tree tmp;
   10952  1.1  mrg   gfc_symbol *sym;
   10953  1.1  mrg 
   10954  1.1  mrg   sym = expr->symtree->n.sym;
   10955  1.1  mrg   dest = gfc_get_symbol_decl (sym);
   10956  1.1  mrg 
   10957  1.1  mrg   type = TREE_TYPE (dest);
   10958  1.1  mrg   if (POINTER_TYPE_P (type))
   10959  1.1  mrg     type = TREE_TYPE (type);
   10960  1.1  mrg   if (!GFC_ARRAY_TYPE_P (type))
   10961  1.1  mrg     return NULL_TREE;
   10962  1.1  mrg 
   10963  1.1  mrg   /* Determine the length of the array.  */
   10964  1.1  mrg   len = GFC_TYPE_ARRAY_SIZE (type);
   10965  1.1  mrg   if (!len || TREE_CODE (len) != INTEGER_CST)
   10966  1.1  mrg     return NULL_TREE;
   10967  1.1  mrg 
   10968  1.1  mrg   tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type));
   10969  1.1  mrg   len = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type, len,
   10970  1.1  mrg 			 fold_convert (gfc_array_index_type, tmp));
   10971  1.1  mrg 
   10972  1.1  mrg   /* If we are zeroing a local array avoid taking its address by emitting
   10973  1.1  mrg      a = {} instead.  */
   10974  1.1  mrg   if (!POINTER_TYPE_P (TREE_TYPE (dest)))
   10975  1.1  mrg     return build2_loc (input_location, MODIFY_EXPR, void_type_node,
   10976  1.1  mrg 		       dest, build_constructor (TREE_TYPE (dest),
   10977  1.1  mrg 					      NULL));
   10978  1.1  mrg 
   10979  1.1  mrg   /* Convert arguments to the correct types.  */
   10980  1.1  mrg   dest = fold_convert (pvoid_type_node, dest);
   10981  1.1  mrg   len = fold_convert (size_type_node, len);
   10982  1.1  mrg 
   10983  1.1  mrg   /* Construct call to __builtin_memset.  */
   10984  1.1  mrg   tmp = build_call_expr_loc (input_location,
   10985  1.1  mrg 			     builtin_decl_explicit (BUILT_IN_MEMSET),
   10986  1.1  mrg 			     3, dest, integer_zero_node, len);
   10987  1.1  mrg   return fold_convert (void_type_node, tmp);
   10988  1.1  mrg }
   10989  1.1  mrg 
   10990  1.1  mrg 
   10991  1.1  mrg /* Helper for gfc_trans_array_copy and gfc_trans_array_constructor_copy
   10992  1.1  mrg    that constructs the call to __builtin_memcpy.  */
   10993  1.1  mrg 
   10994  1.1  mrg tree
   10995  1.1  mrg gfc_build_memcpy_call (tree dst, tree src, tree len)
   10996  1.1  mrg {
   10997  1.1  mrg   tree tmp;
   10998  1.1  mrg 
   10999  1.1  mrg   /* Convert arguments to the correct types.  */
   11000  1.1  mrg   if (!POINTER_TYPE_P (TREE_TYPE (dst)))
   11001  1.1  mrg     dst = gfc_build_addr_expr (pvoid_type_node, dst);
   11002  1.1  mrg   else
   11003  1.1  mrg     dst = fold_convert (pvoid_type_node, dst);
   11004  1.1  mrg 
   11005  1.1  mrg   if (!POINTER_TYPE_P (TREE_TYPE (src)))
   11006  1.1  mrg     src = gfc_build_addr_expr (pvoid_type_node, src);
   11007  1.1  mrg   else
   11008  1.1  mrg     src = fold_convert (pvoid_type_node, src);
   11009  1.1  mrg 
   11010  1.1  mrg   len = fold_convert (size_type_node, len);
   11011  1.1  mrg 
   11012  1.1  mrg   /* Construct call to __builtin_memcpy.  */
   11013  1.1  mrg   tmp = build_call_expr_loc (input_location,
   11014  1.1  mrg 			     builtin_decl_explicit (BUILT_IN_MEMCPY),
   11015  1.1  mrg 			     3, dst, src, len);
   11016  1.1  mrg   return fold_convert (void_type_node, tmp);
   11017  1.1  mrg }
   11018  1.1  mrg 
   11019  1.1  mrg 
   11020  1.1  mrg /* Try to efficiently translate dst(:) = src(:).  Return NULL if this
   11021  1.1  mrg    can't be done.  EXPR1 is the destination/lhs and EXPR2 is the
   11022  1.1  mrg    source/rhs, both are gfc_full_array_ref_p which have been checked for
   11023  1.1  mrg    dependencies.  */
   11024  1.1  mrg 
   11025  1.1  mrg static tree
   11026  1.1  mrg gfc_trans_array_copy (gfc_expr * expr1, gfc_expr * expr2)
   11027  1.1  mrg {
   11028  1.1  mrg   tree dst, dlen, dtype;
   11029  1.1  mrg   tree src, slen, stype;
   11030  1.1  mrg   tree tmp;
   11031  1.1  mrg 
   11032  1.1  mrg   dst = gfc_get_symbol_decl (expr1->symtree->n.sym);
   11033  1.1  mrg   src = gfc_get_symbol_decl (expr2->symtree->n.sym);
   11034  1.1  mrg 
   11035  1.1  mrg   dtype = TREE_TYPE (dst);
   11036  1.1  mrg   if (POINTER_TYPE_P (dtype))
   11037  1.1  mrg     dtype = TREE_TYPE (dtype);
   11038  1.1  mrg   stype = TREE_TYPE (src);
   11039  1.1  mrg   if (POINTER_TYPE_P (stype))
   11040  1.1  mrg     stype = TREE_TYPE (stype);
   11041  1.1  mrg 
   11042  1.1  mrg   if (!GFC_ARRAY_TYPE_P (dtype) || !GFC_ARRAY_TYPE_P (stype))
   11043  1.1  mrg     return NULL_TREE;
   11044  1.1  mrg 
   11045  1.1  mrg   /* Determine the lengths of the arrays.  */
   11046  1.1  mrg   dlen = GFC_TYPE_ARRAY_SIZE (dtype);
   11047  1.1  mrg   if (!dlen || TREE_CODE (dlen) != INTEGER_CST)
   11048  1.1  mrg     return NULL_TREE;
   11049  1.1  mrg   tmp = TYPE_SIZE_UNIT (gfc_get_element_type (dtype));
   11050  1.1  mrg   dlen = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
   11051  1.1  mrg 			  dlen, fold_convert (gfc_array_index_type, tmp));
   11052  1.1  mrg 
   11053  1.1  mrg   slen = GFC_TYPE_ARRAY_SIZE (stype);
   11054  1.1  mrg   if (!slen || TREE_CODE (slen) != INTEGER_CST)
   11055  1.1  mrg     return NULL_TREE;
   11056  1.1  mrg   tmp = TYPE_SIZE_UNIT (gfc_get_element_type (stype));
   11057  1.1  mrg   slen = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
   11058  1.1  mrg 			  slen, fold_convert (gfc_array_index_type, tmp));
   11059  1.1  mrg 
   11060  1.1  mrg   /* Sanity check that they are the same.  This should always be
   11061  1.1  mrg      the case, as we should already have checked for conformance.  */
   11062  1.1  mrg   if (!tree_int_cst_equal (slen, dlen))
   11063  1.1  mrg     return NULL_TREE;
   11064  1.1  mrg 
   11065  1.1  mrg   return gfc_build_memcpy_call (dst, src, dlen);
   11066  1.1  mrg }
   11067  1.1  mrg 
   11068  1.1  mrg 
   11069  1.1  mrg /* Try to efficiently translate array(:) = (/ ... /).  Return NULL if
   11070  1.1  mrg    this can't be done.  EXPR1 is the destination/lhs for which
   11071  1.1  mrg    gfc_full_array_ref_p is true, and EXPR2 is the source/rhs.  */
   11072  1.1  mrg 
   11073  1.1  mrg static tree
   11074  1.1  mrg gfc_trans_array_constructor_copy (gfc_expr * expr1, gfc_expr * expr2)
   11075  1.1  mrg {
   11076  1.1  mrg   unsigned HOST_WIDE_INT nelem;
   11077  1.1  mrg   tree dst, dtype;
   11078  1.1  mrg   tree src, stype;
   11079  1.1  mrg   tree len;
   11080  1.1  mrg   tree tmp;
   11081  1.1  mrg 
   11082  1.1  mrg   nelem = gfc_constant_array_constructor_p (expr2->value.constructor);
   11083  1.1  mrg   if (nelem == 0)
   11084  1.1  mrg     return NULL_TREE;
   11085  1.1  mrg 
   11086  1.1  mrg   dst = gfc_get_symbol_decl (expr1->symtree->n.sym);
   11087  1.1  mrg   dtype = TREE_TYPE (dst);
   11088  1.1  mrg   if (POINTER_TYPE_P (dtype))
   11089  1.1  mrg     dtype = TREE_TYPE (dtype);
   11090  1.1  mrg   if (!GFC_ARRAY_TYPE_P (dtype))
   11091  1.1  mrg     return NULL_TREE;
   11092  1.1  mrg 
   11093  1.1  mrg   /* Determine the lengths of the array.  */
   11094  1.1  mrg   len = GFC_TYPE_ARRAY_SIZE (dtype);
   11095  1.1  mrg   if (!len || TREE_CODE (len) != INTEGER_CST)
   11096  1.1  mrg     return NULL_TREE;
   11097  1.1  mrg 
   11098  1.1  mrg   /* Confirm that the constructor is the same size.  */
   11099  1.1  mrg   if (compare_tree_int (len, nelem) != 0)
   11100  1.1  mrg     return NULL_TREE;
   11101  1.1  mrg 
   11102  1.1  mrg   tmp = TYPE_SIZE_UNIT (gfc_get_element_type (dtype));
   11103  1.1  mrg   len = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type, len,
   11104  1.1  mrg 			 fold_convert (gfc_array_index_type, tmp));
   11105  1.1  mrg 
   11106  1.1  mrg   stype = gfc_typenode_for_spec (&expr2->ts);
   11107  1.1  mrg   src = gfc_build_constant_array_constructor (expr2, stype);
   11108  1.1  mrg 
   11109  1.1  mrg   return gfc_build_memcpy_call (dst, src, len);
   11110  1.1  mrg }
   11111  1.1  mrg 
   11112  1.1  mrg 
   11113  1.1  mrg /* Tells whether the expression is to be treated as a variable reference.  */
   11114  1.1  mrg 
   11115  1.1  mrg bool
   11116  1.1  mrg gfc_expr_is_variable (gfc_expr *expr)
   11117  1.1  mrg {
   11118  1.1  mrg   gfc_expr *arg;
   11119  1.1  mrg   gfc_component *comp;
   11120  1.1  mrg   gfc_symbol *func_ifc;
   11121  1.1  mrg 
   11122  1.1  mrg   if (expr->expr_type == EXPR_VARIABLE)
   11123  1.1  mrg     return true;
   11124  1.1  mrg 
   11125  1.1  mrg   arg = gfc_get_noncopying_intrinsic_argument (expr);
   11126  1.1  mrg   if (arg)
   11127  1.1  mrg     {
   11128  1.1  mrg       gcc_assert (expr->value.function.isym->id == GFC_ISYM_TRANSPOSE);
   11129  1.1  mrg       return gfc_expr_is_variable (arg);
   11130  1.1  mrg     }
   11131  1.1  mrg 
   11132  1.1  mrg   /* A data-pointer-returning function should be considered as a variable
   11133  1.1  mrg      too.  */
   11134  1.1  mrg   if (expr->expr_type == EXPR_FUNCTION
   11135  1.1  mrg       && expr->ref == NULL)
   11136  1.1  mrg     {
   11137  1.1  mrg       if (expr->value.function.isym != NULL)
   11138  1.1  mrg 	return false;
   11139  1.1  mrg 
   11140  1.1  mrg       if (expr->value.function.esym != NULL)
   11141  1.1  mrg 	{
   11142  1.1  mrg 	  func_ifc = expr->value.function.esym;
   11143  1.1  mrg 	  goto found_ifc;
   11144  1.1  mrg 	}
   11145  1.1  mrg       gcc_assert (expr->symtree);
   11146  1.1  mrg       func_ifc = expr->symtree->n.sym;
   11147  1.1  mrg       goto found_ifc;
   11148  1.1  mrg     }
   11149  1.1  mrg 
   11150  1.1  mrg   comp = gfc_get_proc_ptr_comp (expr);
   11151  1.1  mrg   if ((expr->expr_type == EXPR_PPC || expr->expr_type == EXPR_FUNCTION)
   11152  1.1  mrg       && comp)
   11153  1.1  mrg     {
   11154  1.1  mrg       func_ifc = comp->ts.interface;
   11155  1.1  mrg       goto found_ifc;
   11156  1.1  mrg     }
   11157  1.1  mrg 
   11158  1.1  mrg   if (expr->expr_type == EXPR_COMPCALL)
   11159  1.1  mrg     {
   11160  1.1  mrg       gcc_assert (!expr->value.compcall.tbp->is_generic);
   11161  1.1  mrg       func_ifc = expr->value.compcall.tbp->u.specific->n.sym;
   11162  1.1  mrg       goto found_ifc;
   11163  1.1  mrg     }
   11164  1.1  mrg 
   11165  1.1  mrg   return false;
   11166  1.1  mrg 
   11167  1.1  mrg found_ifc:
   11168  1.1  mrg   gcc_assert (func_ifc->attr.function
   11169  1.1  mrg 	      && func_ifc->result != NULL);
   11170  1.1  mrg   return func_ifc->result->attr.pointer;
   11171  1.1  mrg }
   11172  1.1  mrg 
   11173  1.1  mrg 
   11174  1.1  mrg /* Is the lhs OK for automatic reallocation?  */
   11175  1.1  mrg 
   11176  1.1  mrg static bool
   11177  1.1  mrg is_scalar_reallocatable_lhs (gfc_expr *expr)
   11178  1.1  mrg {
   11179  1.1  mrg   gfc_ref * ref;
   11180  1.1  mrg 
   11181  1.1  mrg   /* An allocatable variable with no reference.  */
   11182  1.1  mrg   if (expr->symtree->n.sym->attr.allocatable
   11183  1.1  mrg 	&& !expr->ref)
   11184  1.1  mrg     return true;
   11185  1.1  mrg 
   11186  1.1  mrg   /* All that can be left are allocatable components.  However, we do
   11187  1.1  mrg      not check for allocatable components here because the expression
   11188  1.1  mrg      could be an allocatable component of a pointer component.  */
   11189  1.1  mrg   if (expr->symtree->n.sym->ts.type != BT_DERIVED
   11190  1.1  mrg 	&& expr->symtree->n.sym->ts.type != BT_CLASS)
   11191  1.1  mrg     return false;
   11192  1.1  mrg 
   11193  1.1  mrg   /* Find an allocatable component ref last.  */
   11194  1.1  mrg   for (ref = expr->ref; ref; ref = ref->next)
   11195  1.1  mrg     if (ref->type == REF_COMPONENT
   11196  1.1  mrg 	  && !ref->next
   11197  1.1  mrg 	  && ref->u.c.component->attr.allocatable)
   11198  1.1  mrg       return true;
   11199  1.1  mrg 
   11200  1.1  mrg   return false;
   11201  1.1  mrg }
   11202  1.1  mrg 
   11203  1.1  mrg 
   11204  1.1  mrg /* Allocate or reallocate scalar lhs, as necessary.  */
   11205  1.1  mrg 
   11206  1.1  mrg static void
   11207  1.1  mrg alloc_scalar_allocatable_for_assignment (stmtblock_t *block,
   11208  1.1  mrg 					 tree string_length,
   11209  1.1  mrg 					 gfc_expr *expr1,
   11210  1.1  mrg 					 gfc_expr *expr2)
   11211  1.1  mrg 
   11212  1.1  mrg {
   11213  1.1  mrg   tree cond;
   11214  1.1  mrg   tree tmp;
   11215  1.1  mrg   tree size;
   11216  1.1  mrg   tree size_in_bytes;
   11217  1.1  mrg   tree jump_label1;
   11218  1.1  mrg   tree jump_label2;
   11219  1.1  mrg   gfc_se lse;
   11220  1.1  mrg   gfc_ref *ref;
   11221  1.1  mrg 
   11222  1.1  mrg   if (!expr1 || expr1->rank)
   11223  1.1  mrg     return;
   11224  1.1  mrg 
   11225  1.1  mrg   if (!expr2 || expr2->rank)
   11226  1.1  mrg     return;
   11227  1.1  mrg 
   11228  1.1  mrg   for (ref = expr1->ref; ref; ref = ref->next)
   11229  1.1  mrg     if (ref->type == REF_SUBSTRING)
   11230  1.1  mrg       return;
   11231  1.1  mrg 
   11232  1.1  mrg   realloc_lhs_warning (expr2->ts.type, false, &expr2->where);
   11233  1.1  mrg 
   11234  1.1  mrg   /* Since this is a scalar lhs, we can afford to do this.  That is,
   11235  1.1  mrg      there is no risk of side effects being repeated.  */
   11236  1.1  mrg   gfc_init_se (&lse, NULL);
   11237  1.1  mrg   lse.want_pointer = 1;
   11238  1.1  mrg   gfc_conv_expr (&lse, expr1);
   11239  1.1  mrg 
   11240  1.1  mrg   jump_label1 = gfc_build_label_decl (NULL_TREE);
   11241  1.1  mrg   jump_label2 = gfc_build_label_decl (NULL_TREE);
   11242  1.1  mrg 
   11243  1.1  mrg   /* Do the allocation if the lhs is NULL. Otherwise go to label 1.  */
   11244  1.1  mrg   tmp = build_int_cst (TREE_TYPE (lse.expr), 0);
   11245  1.1  mrg   cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
   11246  1.1  mrg 			  lse.expr, tmp);
   11247  1.1  mrg   tmp = build3_v (COND_EXPR, cond,
   11248  1.1  mrg 		  build1_v (GOTO_EXPR, jump_label1),
   11249  1.1  mrg 		  build_empty_stmt (input_location));
   11250  1.1  mrg   gfc_add_expr_to_block (block, tmp);
   11251  1.1  mrg 
   11252  1.1  mrg   if (expr1->ts.type == BT_CHARACTER && expr1->ts.deferred)
   11253  1.1  mrg     {
   11254  1.1  mrg       /* Use the rhs string length and the lhs element size.  */
   11255  1.1  mrg       size = string_length;
   11256  1.1  mrg       tmp = TREE_TYPE (gfc_typenode_for_spec (&expr1->ts));
   11257  1.1  mrg       tmp = TYPE_SIZE_UNIT (tmp);
   11258  1.1  mrg       size_in_bytes = fold_build2_loc (input_location, MULT_EXPR,
   11259  1.1  mrg 				       TREE_TYPE (tmp), tmp,
   11260  1.1  mrg 				       fold_convert (TREE_TYPE (tmp), size));
   11261  1.1  mrg     }
   11262  1.1  mrg   else
   11263  1.1  mrg     {
   11264  1.1  mrg       /* Otherwise use the length in bytes of the rhs.  */
   11265  1.1  mrg       size = TYPE_SIZE_UNIT (gfc_typenode_for_spec (&expr1->ts));
   11266  1.1  mrg       size_in_bytes = size;
   11267  1.1  mrg     }
   11268  1.1  mrg 
   11269  1.1  mrg   size_in_bytes = fold_build2_loc (input_location, MAX_EXPR, size_type_node,
   11270  1.1  mrg 				   size_in_bytes, size_one_node);
   11271  1.1  mrg 
   11272  1.1  mrg   if (gfc_caf_attr (expr1).codimension && flag_coarray == GFC_FCOARRAY_LIB)
   11273  1.1  mrg     {
   11274  1.1  mrg       tree caf_decl, token;
   11275  1.1  mrg       gfc_se caf_se;
   11276  1.1  mrg       symbol_attribute attr;
   11277  1.1  mrg 
   11278  1.1  mrg       gfc_clear_attr (&attr);
   11279  1.1  mrg       gfc_init_se (&caf_se, NULL);
   11280  1.1  mrg 
   11281  1.1  mrg       caf_decl = gfc_get_tree_for_caf_expr (expr1);
   11282  1.1  mrg       gfc_get_caf_token_offset (&caf_se, &token, NULL, caf_decl, NULL_TREE,
   11283  1.1  mrg 				NULL);
   11284  1.1  mrg       gfc_add_block_to_block (block, &caf_se.pre);
   11285  1.1  mrg       gfc_allocate_allocatable (block, lse.expr, size_in_bytes,
   11286  1.1  mrg 				gfc_build_addr_expr (NULL_TREE, token),
   11287  1.1  mrg 				NULL_TREE, NULL_TREE, NULL_TREE, jump_label1,
   11288  1.1  mrg 				expr1, 1);
   11289  1.1  mrg     }
   11290  1.1  mrg   else if (expr1->ts.type == BT_DERIVED && expr1->ts.u.derived->attr.alloc_comp)
   11291  1.1  mrg     {
   11292  1.1  mrg       tmp = build_call_expr_loc (input_location,
   11293  1.1  mrg 				 builtin_decl_explicit (BUILT_IN_CALLOC),
   11294  1.1  mrg 				 2, build_one_cst (size_type_node),
   11295  1.1  mrg 				 size_in_bytes);
   11296  1.1  mrg       tmp = fold_convert (TREE_TYPE (lse.expr), tmp);
   11297  1.1  mrg       gfc_add_modify (block, lse.expr, tmp);
   11298  1.1  mrg     }
   11299  1.1  mrg   else
   11300  1.1  mrg     {
   11301  1.1  mrg       tmp = build_call_expr_loc (input_location,
   11302  1.1  mrg 				 builtin_decl_explicit (BUILT_IN_MALLOC),
   11303  1.1  mrg 				 1, size_in_bytes);
   11304  1.1  mrg       tmp = fold_convert (TREE_TYPE (lse.expr), tmp);
   11305  1.1  mrg       gfc_add_modify (block, lse.expr, tmp);
   11306  1.1  mrg     }
   11307  1.1  mrg 
   11308  1.1  mrg   if (expr1->ts.type == BT_CHARACTER && expr1->ts.deferred)
   11309  1.1  mrg     {
   11310  1.1  mrg       /* Deferred characters need checking for lhs and rhs string
   11311  1.1  mrg 	 length.  Other deferred parameter variables will have to
   11312  1.1  mrg 	 come here too.  */
   11313  1.1  mrg       tmp = build1_v (GOTO_EXPR, jump_label2);
   11314  1.1  mrg       gfc_add_expr_to_block (block, tmp);
   11315  1.1  mrg     }
   11316  1.1  mrg   tmp = build1_v (LABEL_EXPR, jump_label1);
   11317  1.1  mrg   gfc_add_expr_to_block (block, tmp);
   11318  1.1  mrg 
   11319  1.1  mrg   /* For a deferred length character, reallocate if lengths of lhs and
   11320  1.1  mrg      rhs are different.  */
   11321  1.1  mrg   if (expr1->ts.type == BT_CHARACTER && expr1->ts.deferred)
   11322  1.1  mrg     {
   11323  1.1  mrg       cond = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
   11324  1.1  mrg 			      lse.string_length,
   11325  1.1  mrg 			      fold_convert (TREE_TYPE (lse.string_length),
   11326  1.1  mrg 					    size));
   11327  1.1  mrg       /* Jump past the realloc if the lengths are the same.  */
   11328  1.1  mrg       tmp = build3_v (COND_EXPR, cond,
   11329  1.1  mrg 		      build1_v (GOTO_EXPR, jump_label2),
   11330  1.1  mrg 		      build_empty_stmt (input_location));
   11331  1.1  mrg       gfc_add_expr_to_block (block, tmp);
   11332  1.1  mrg       tmp = build_call_expr_loc (input_location,
   11333  1.1  mrg 				 builtin_decl_explicit (BUILT_IN_REALLOC),
   11334  1.1  mrg 				 2, fold_convert (pvoid_type_node, lse.expr),
   11335  1.1  mrg 				 size_in_bytes);
   11336  1.1  mrg       tmp = fold_convert (TREE_TYPE (lse.expr), tmp);
   11337  1.1  mrg       gfc_add_modify (block, lse.expr, tmp);
   11338  1.1  mrg       tmp = build1_v (LABEL_EXPR, jump_label2);
   11339  1.1  mrg       gfc_add_expr_to_block (block, tmp);
   11340  1.1  mrg 
   11341  1.1  mrg       /* Update the lhs character length.  */
   11342  1.1  mrg       size = string_length;
   11343  1.1  mrg       gfc_add_modify (block, lse.string_length,
   11344  1.1  mrg 		      fold_convert (TREE_TYPE (lse.string_length), size));
   11345  1.1  mrg     }
   11346  1.1  mrg }
   11347  1.1  mrg 
   11348  1.1  mrg /* Check for assignments of the type
   11349  1.1  mrg 
   11350  1.1  mrg    a = a + 4
   11351  1.1  mrg 
   11352  1.1  mrg    to make sure we do not check for reallocation unneccessarily.  */
   11353  1.1  mrg 
   11354  1.1  mrg 
   11355  1.1  mrg static bool
   11356  1.1  mrg is_runtime_conformable (gfc_expr *expr1, gfc_expr *expr2)
   11357  1.1  mrg {
   11358  1.1  mrg   gfc_actual_arglist *a;
   11359  1.1  mrg   gfc_expr *e1, *e2;
   11360  1.1  mrg 
   11361  1.1  mrg   switch (expr2->expr_type)
   11362  1.1  mrg     {
   11363  1.1  mrg     case EXPR_VARIABLE:
   11364  1.1  mrg       return gfc_dep_compare_expr (expr1, expr2) == 0;
   11365  1.1  mrg 
   11366  1.1  mrg     case EXPR_FUNCTION:
   11367  1.1  mrg       if (expr2->value.function.esym
   11368  1.1  mrg 	  && expr2->value.function.esym->attr.elemental)
   11369  1.1  mrg 	{
   11370  1.1  mrg 	  for (a = expr2->value.function.actual; a != NULL; a = a->next)
   11371  1.1  mrg 	    {
   11372  1.1  mrg 	      e1 = a->expr;
   11373  1.1  mrg 	      if (e1 && e1->rank > 0 && !is_runtime_conformable (expr1, e1))
   11374  1.1  mrg 		return false;
   11375  1.1  mrg 	    }
   11376  1.1  mrg 	  return true;
   11377  1.1  mrg 	}
   11378  1.1  mrg       else if (expr2->value.function.isym
   11379  1.1  mrg 	       && expr2->value.function.isym->elemental)
   11380  1.1  mrg 	{
   11381  1.1  mrg 	  for (a = expr2->value.function.actual; a != NULL; a = a->next)
   11382  1.1  mrg 	    {
   11383  1.1  mrg 	      e1 = a->expr;
   11384  1.1  mrg 	      if (e1 && e1->rank > 0 && !is_runtime_conformable (expr1, e1))
   11385  1.1  mrg 		return false;
   11386  1.1  mrg 	    }
   11387  1.1  mrg 	  return true;
   11388  1.1  mrg 	}
   11389  1.1  mrg 
   11390  1.1  mrg       break;
   11391  1.1  mrg 
   11392  1.1  mrg     case EXPR_OP:
   11393  1.1  mrg       switch (expr2->value.op.op)
   11394  1.1  mrg 	{
   11395  1.1  mrg 	case INTRINSIC_NOT:
   11396  1.1  mrg 	case INTRINSIC_UPLUS:
   11397  1.1  mrg 	case INTRINSIC_UMINUS:
   11398  1.1  mrg 	case INTRINSIC_PARENTHESES:
   11399  1.1  mrg 	  return is_runtime_conformable (expr1, expr2->value.op.op1);
   11400  1.1  mrg 
   11401  1.1  mrg 	case INTRINSIC_PLUS:
   11402  1.1  mrg 	case INTRINSIC_MINUS:
   11403  1.1  mrg 	case INTRINSIC_TIMES:
   11404  1.1  mrg 	case INTRINSIC_DIVIDE:
   11405  1.1  mrg 	case INTRINSIC_POWER:
   11406  1.1  mrg 	case INTRINSIC_AND:
   11407  1.1  mrg 	case INTRINSIC_OR:
   11408  1.1  mrg 	case INTRINSIC_EQV:
   11409  1.1  mrg 	case INTRINSIC_NEQV:
   11410  1.1  mrg 	case INTRINSIC_EQ:
   11411  1.1  mrg 	case INTRINSIC_NE:
   11412  1.1  mrg 	case INTRINSIC_GT:
   11413  1.1  mrg 	case INTRINSIC_GE:
   11414  1.1  mrg 	case INTRINSIC_LT:
   11415  1.1  mrg 	case INTRINSIC_LE:
   11416  1.1  mrg 	case INTRINSIC_EQ_OS:
   11417  1.1  mrg 	case INTRINSIC_NE_OS:
   11418  1.1  mrg 	case INTRINSIC_GT_OS:
   11419  1.1  mrg 	case INTRINSIC_GE_OS:
   11420  1.1  mrg 	case INTRINSIC_LT_OS:
   11421  1.1  mrg 	case INTRINSIC_LE_OS:
   11422  1.1  mrg 
   11423  1.1  mrg 	  e1 = expr2->value.op.op1;
   11424  1.1  mrg 	  e2 = expr2->value.op.op2;
   11425  1.1  mrg 
   11426  1.1  mrg 	  if (e1->rank == 0 && e2->rank > 0)
   11427  1.1  mrg 	    return is_runtime_conformable (expr1, e2);
   11428  1.1  mrg 	  else if (e1->rank > 0 && e2->rank == 0)
   11429  1.1  mrg 	    return is_runtime_conformable (expr1, e1);
   11430  1.1  mrg 	  else if (e1->rank > 0 && e2->rank > 0)
   11431  1.1  mrg 	    return is_runtime_conformable (expr1, e1)
   11432  1.1  mrg 	      && is_runtime_conformable (expr1, e2);
   11433  1.1  mrg 	  break;
   11434  1.1  mrg 
   11435  1.1  mrg 	default:
   11436  1.1  mrg 	  break;
   11437  1.1  mrg 
   11438  1.1  mrg 	}
   11439  1.1  mrg 
   11440  1.1  mrg       break;
   11441  1.1  mrg 
   11442  1.1  mrg     default:
   11443  1.1  mrg       break;
   11444  1.1  mrg     }
   11445  1.1  mrg   return false;
   11446  1.1  mrg }
   11447  1.1  mrg 
   11448  1.1  mrg 
   11449  1.1  mrg static tree
   11450  1.1  mrg trans_class_assignment (stmtblock_t *block, gfc_expr *lhs, gfc_expr *rhs,
   11451  1.1  mrg 			gfc_se *lse, gfc_se *rse, bool use_vptr_copy,
   11452  1.1  mrg 			bool class_realloc)
   11453  1.1  mrg {
   11454  1.1  mrg   tree tmp, fcn, stdcopy, to_len, from_len, vptr, old_vptr;
   11455  1.1  mrg   vec<tree, va_gc> *args = NULL;
   11456  1.1  mrg 
   11457  1.1  mrg   /* Store the old vptr so that dynamic types can be compared for
   11458  1.1  mrg      reallocation to occur or not.  */
   11459  1.1  mrg   if (class_realloc)
   11460  1.1  mrg     {
   11461  1.1  mrg       tmp = lse->expr;
   11462  1.1  mrg       if (!GFC_CLASS_TYPE_P (TREE_TYPE (tmp)))
   11463  1.1  mrg 	tmp = gfc_get_class_from_expr (tmp);
   11464  1.1  mrg     }
   11465  1.1  mrg 
   11466  1.1  mrg   vptr = trans_class_vptr_len_assignment (block, lhs, rhs, rse, &to_len,
   11467  1.1  mrg 					 &from_len);
   11468  1.1  mrg 
   11469  1.1  mrg   /* Generate (re)allocation of the lhs.  */
   11470  1.1  mrg   if (class_realloc)
   11471  1.1  mrg     {
   11472  1.1  mrg       stmtblock_t alloc, re_alloc;
   11473  1.1  mrg       tree class_han, re, size;
   11474  1.1  mrg 
   11475  1.1  mrg       if (tmp && GFC_CLASS_TYPE_P (TREE_TYPE (tmp)))
   11476  1.1  mrg 	old_vptr = gfc_evaluate_now (gfc_class_vptr_get (tmp), block);
   11477  1.1  mrg       else
   11478  1.1  mrg 	old_vptr = build_int_cst (TREE_TYPE (vptr), 0);
   11479  1.1  mrg 
   11480  1.1  mrg       size = gfc_vptr_size_get (vptr);
   11481  1.1  mrg       class_han = GFC_CLASS_TYPE_P (TREE_TYPE (lse->expr))
   11482  1.1  mrg 	  ? gfc_class_data_get (lse->expr) : lse->expr;
   11483  1.1  mrg 
   11484  1.1  mrg       if (!POINTER_TYPE_P (TREE_TYPE (class_han)))
   11485  1.1  mrg 	class_han = gfc_build_addr_expr (NULL_TREE, class_han);
   11486  1.1  mrg 
   11487  1.1  mrg       /* Allocate block.  */
   11488  1.1  mrg       gfc_init_block (&alloc);
   11489  1.1  mrg       gfc_allocate_using_malloc (&alloc, class_han, size, NULL_TREE);
   11490  1.1  mrg 
   11491  1.1  mrg       /* Reallocate if dynamic types are different. */
   11492  1.1  mrg       gfc_init_block (&re_alloc);
   11493  1.1  mrg       re = build_call_expr_loc (input_location,
   11494  1.1  mrg 				builtin_decl_explicit (BUILT_IN_REALLOC), 2,
   11495  1.1  mrg 				fold_convert (pvoid_type_node, class_han),
   11496  1.1  mrg 				size);
   11497  1.1  mrg       tmp = fold_build2_loc (input_location, NE_EXPR,
   11498  1.1  mrg 			     logical_type_node, vptr, old_vptr);
   11499  1.1  mrg       re = fold_build3_loc (input_location, COND_EXPR, void_type_node,
   11500  1.1  mrg 			    tmp, re, build_empty_stmt (input_location));
   11501  1.1  mrg       gfc_add_expr_to_block (&re_alloc, re);
   11502  1.1  mrg 
   11503  1.1  mrg       /* Allocate if _data is NULL, reallocate otherwise.  */
   11504  1.1  mrg       tmp = fold_build2_loc (input_location, EQ_EXPR,
   11505  1.1  mrg 			     logical_type_node, class_han,
   11506  1.1  mrg 			     build_int_cst (prvoid_type_node, 0));
   11507  1.1  mrg       tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
   11508  1.1  mrg 			     gfc_unlikely (tmp,
   11509  1.1  mrg 					   PRED_FORTRAN_FAIL_ALLOC),
   11510  1.1  mrg 			     gfc_finish_block (&alloc),
   11511  1.1  mrg 			     gfc_finish_block (&re_alloc));
   11512  1.1  mrg       gfc_add_expr_to_block (&lse->pre, tmp);
   11513  1.1  mrg     }
   11514  1.1  mrg 
   11515  1.1  mrg   fcn = gfc_vptr_copy_get (vptr);
   11516  1.1  mrg 
   11517  1.1  mrg   tmp = GFC_CLASS_TYPE_P (TREE_TYPE (rse->expr))
   11518  1.1  mrg       ? gfc_class_data_get (rse->expr) : rse->expr;
   11519  1.1  mrg   if (use_vptr_copy)
   11520  1.1  mrg     {
   11521  1.1  mrg       if (!POINTER_TYPE_P (TREE_TYPE (tmp))
   11522  1.1  mrg 	  || INDIRECT_REF_P (tmp)
   11523  1.1  mrg 	  || (rhs->ts.type == BT_DERIVED
   11524  1.1  mrg 	      && rhs->ts.u.derived->attr.unlimited_polymorphic
   11525  1.1  mrg 	      && !rhs->ts.u.derived->attr.pointer
   11526  1.1  mrg 	      && !rhs->ts.u.derived->attr.allocatable)
   11527  1.1  mrg 	  || (UNLIMITED_POLY (rhs)
   11528  1.1  mrg 	      && !CLASS_DATA (rhs)->attr.pointer
   11529  1.1  mrg 	      && !CLASS_DATA (rhs)->attr.allocatable))
   11530  1.1  mrg 	vec_safe_push (args, gfc_build_addr_expr (NULL_TREE, tmp));
   11531  1.1  mrg       else
   11532  1.1  mrg 	vec_safe_push (args, tmp);
   11533  1.1  mrg       tmp = GFC_CLASS_TYPE_P (TREE_TYPE (lse->expr))
   11534  1.1  mrg 	  ? gfc_class_data_get (lse->expr) : lse->expr;
   11535  1.1  mrg       if (!POINTER_TYPE_P (TREE_TYPE (tmp))
   11536  1.1  mrg 	  || INDIRECT_REF_P (tmp)
   11537  1.1  mrg 	  || (lhs->ts.type == BT_DERIVED
   11538  1.1  mrg 	      && lhs->ts.u.derived->attr.unlimited_polymorphic
   11539  1.1  mrg 	      && !lhs->ts.u.derived->attr.pointer
   11540  1.1  mrg 	      && !lhs->ts.u.derived->attr.allocatable)
   11541  1.1  mrg 	  || (UNLIMITED_POLY (lhs)
   11542  1.1  mrg 	      && !CLASS_DATA (lhs)->attr.pointer
   11543  1.1  mrg 	      && !CLASS_DATA (lhs)->attr.allocatable))
   11544  1.1  mrg 	vec_safe_push (args, gfc_build_addr_expr (NULL_TREE, tmp));
   11545  1.1  mrg       else
   11546  1.1  mrg 	vec_safe_push (args, tmp);
   11547  1.1  mrg 
   11548  1.1  mrg       stdcopy = build_call_vec (TREE_TYPE (TREE_TYPE (fcn)), fcn, args);
   11549  1.1  mrg 
   11550  1.1  mrg       if (to_len != NULL_TREE && !integer_zerop (from_len))
   11551  1.1  mrg 	{
   11552  1.1  mrg 	  tree extcopy;
   11553  1.1  mrg 	  vec_safe_push (args, from_len);
   11554  1.1  mrg 	  vec_safe_push (args, to_len);
   11555  1.1  mrg 	  extcopy = build_call_vec (TREE_TYPE (TREE_TYPE (fcn)), fcn, args);
   11556  1.1  mrg 
   11557  1.1  mrg 	  tmp = fold_build2_loc (input_location, GT_EXPR,
   11558  1.1  mrg 				 logical_type_node, from_len,
   11559  1.1  mrg 				 build_zero_cst (TREE_TYPE (from_len)));
   11560  1.1  mrg 	  return fold_build3_loc (input_location, COND_EXPR,
   11561  1.1  mrg 				  void_type_node, tmp,
   11562  1.1  mrg 				  extcopy, stdcopy);
   11563  1.1  mrg 	}
   11564  1.1  mrg       else
   11565  1.1  mrg 	return stdcopy;
   11566  1.1  mrg     }
   11567  1.1  mrg   else
   11568  1.1  mrg     {
   11569  1.1  mrg       tree rhst = GFC_CLASS_TYPE_P (TREE_TYPE (lse->expr))
   11570  1.1  mrg 	  ? gfc_class_data_get (lse->expr) : lse->expr;
   11571  1.1  mrg       stmtblock_t tblock;
   11572  1.1  mrg       gfc_init_block (&tblock);
   11573  1.1  mrg       if (!POINTER_TYPE_P (TREE_TYPE (tmp)))
   11574  1.1  mrg 	tmp = gfc_build_addr_expr (NULL_TREE, tmp);
   11575  1.1  mrg       if (!POINTER_TYPE_P (TREE_TYPE (rhst)))
   11576  1.1  mrg 	rhst = gfc_build_addr_expr (NULL_TREE, rhst);
   11577  1.1  mrg       /* When coming from a ptr_copy lhs and rhs are swapped.  */
   11578  1.1  mrg       gfc_add_modify_loc (input_location, &tblock, rhst,
   11579  1.1  mrg 			  fold_convert (TREE_TYPE (rhst), tmp));
   11580  1.1  mrg       return gfc_finish_block (&tblock);
   11581  1.1  mrg     }
   11582  1.1  mrg }
   11583  1.1  mrg 
   11584  1.1  mrg /* Subroutine of gfc_trans_assignment that actually scalarizes the
   11585  1.1  mrg    assignment.  EXPR1 is the destination/LHS and EXPR2 is the source/RHS.
   11586  1.1  mrg    init_flag indicates initialization expressions and dealloc that no
   11587  1.1  mrg    deallocate prior assignment is needed (if in doubt, set true).
   11588  1.1  mrg    When PTR_COPY is set and expr1 is a class type, then use the _vptr-copy
   11589  1.1  mrg    routine instead of a pointer assignment.  Alias resolution is only done,
   11590  1.1  mrg    when MAY_ALIAS is set (the default).  This flag is used by ALLOCATE()
   11591  1.1  mrg    where it is known, that newly allocated memory on the lhs can never be
   11592  1.1  mrg    an alias of the rhs.  */
   11593  1.1  mrg 
   11594  1.1  mrg static tree
   11595  1.1  mrg gfc_trans_assignment_1 (gfc_expr * expr1, gfc_expr * expr2, bool init_flag,
   11596  1.1  mrg 			bool dealloc, bool use_vptr_copy, bool may_alias)
   11597  1.1  mrg {
   11598  1.1  mrg   gfc_se lse;
   11599  1.1  mrg   gfc_se rse;
   11600  1.1  mrg   gfc_ss *lss;
   11601  1.1  mrg   gfc_ss *lss_section;
   11602  1.1  mrg   gfc_ss *rss;
   11603  1.1  mrg   gfc_loopinfo loop;
   11604  1.1  mrg   tree tmp;
   11605  1.1  mrg   stmtblock_t block;
   11606  1.1  mrg   stmtblock_t body;
   11607  1.1  mrg   bool l_is_temp;
   11608  1.1  mrg   bool scalar_to_array;
   11609  1.1  mrg   tree string_length;
   11610  1.1  mrg   int n;
   11611  1.1  mrg   bool maybe_workshare = false, lhs_refs_comp = false, rhs_refs_comp = false;
   11612  1.1  mrg   symbol_attribute lhs_caf_attr, rhs_caf_attr, lhs_attr;
   11613  1.1  mrg   bool is_poly_assign;
   11614  1.1  mrg   bool realloc_flag;
   11615  1.1  mrg 
   11616  1.1  mrg   /* Assignment of the form lhs = rhs.  */
   11617  1.1  mrg   gfc_start_block (&block);
   11618  1.1  mrg 
   11619  1.1  mrg   gfc_init_se (&lse, NULL);
   11620  1.1  mrg   gfc_init_se (&rse, NULL);
   11621  1.1  mrg 
   11622  1.1  mrg   /* Walk the lhs.  */
   11623  1.1  mrg   lss = gfc_walk_expr (expr1);
   11624  1.1  mrg   if (gfc_is_reallocatable_lhs (expr1))
   11625  1.1  mrg     {
   11626  1.1  mrg       lss->no_bounds_check = 1;
   11627  1.1  mrg       if (!(expr2->expr_type == EXPR_FUNCTION
   11628  1.1  mrg 	    && expr2->value.function.isym != NULL
   11629  1.1  mrg 	    && !(expr2->value.function.isym->elemental
   11630  1.1  mrg 		 || expr2->value.function.isym->conversion)))
   11631  1.1  mrg 	lss->is_alloc_lhs = 1;
   11632  1.1  mrg     }
   11633  1.1  mrg   else
   11634  1.1  mrg     lss->no_bounds_check = expr1->no_bounds_check;
   11635  1.1  mrg 
   11636  1.1  mrg   rss = NULL;
   11637  1.1  mrg 
   11638  1.1  mrg   if ((expr1->ts.type == BT_DERIVED)
   11639  1.1  mrg       && (gfc_is_class_array_function (expr2)
   11640  1.1  mrg 	  || gfc_is_alloc_class_scalar_function (expr2)))
   11641  1.1  mrg     expr2->must_finalize = 1;
   11642  1.1  mrg 
   11643  1.1  mrg   /* Checking whether a class assignment is desired is quite complicated and
   11644  1.1  mrg      needed at two locations, so do it once only before the information is
   11645  1.1  mrg      needed.  */
   11646  1.1  mrg   lhs_attr = gfc_expr_attr (expr1);
   11647  1.1  mrg   is_poly_assign = (use_vptr_copy || lhs_attr.pointer
   11648  1.1  mrg 		    || (lhs_attr.allocatable && !lhs_attr.dimension))
   11649  1.1  mrg 		   && (expr1->ts.type == BT_CLASS
   11650  1.1  mrg 		       || gfc_is_class_array_ref (expr1, NULL)
   11651  1.1  mrg 		       || gfc_is_class_scalar_expr (expr1)
   11652  1.1  mrg 		       || gfc_is_class_array_ref (expr2, NULL)
   11653  1.1  mrg 		       || gfc_is_class_scalar_expr (expr2))
   11654  1.1  mrg 		   && lhs_attr.flavor != FL_PROCEDURE;
   11655  1.1  mrg 
   11656  1.1  mrg   realloc_flag = flag_realloc_lhs
   11657  1.1  mrg 		 && gfc_is_reallocatable_lhs (expr1)
   11658  1.1  mrg 		 && expr2->rank
   11659  1.1  mrg 		 && !is_runtime_conformable (expr1, expr2);
   11660  1.1  mrg 
   11661  1.1  mrg   /* Only analyze the expressions for coarray properties, when in coarray-lib
   11662  1.1  mrg      mode.  */
   11663  1.1  mrg   if (flag_coarray == GFC_FCOARRAY_LIB)
   11664  1.1  mrg     {
   11665  1.1  mrg       lhs_caf_attr = gfc_caf_attr (expr1, false, &lhs_refs_comp);
   11666  1.1  mrg       rhs_caf_attr = gfc_caf_attr (expr2, false, &rhs_refs_comp);
   11667  1.1  mrg     }
   11668  1.1  mrg 
   11669  1.1  mrg   if (lss != gfc_ss_terminator)
   11670  1.1  mrg     {
   11671  1.1  mrg       /* The assignment needs scalarization.  */
   11672  1.1  mrg       lss_section = lss;
   11673  1.1  mrg 
   11674  1.1  mrg       /* Find a non-scalar SS from the lhs.  */
   11675  1.1  mrg       while (lss_section != gfc_ss_terminator
   11676  1.1  mrg 	     && lss_section->info->type != GFC_SS_SECTION)
   11677  1.1  mrg 	lss_section = lss_section->next;
   11678  1.1  mrg 
   11679  1.1  mrg       gcc_assert (lss_section != gfc_ss_terminator);
   11680  1.1  mrg 
   11681  1.1  mrg       /* Initialize the scalarizer.  */
   11682  1.1  mrg       gfc_init_loopinfo (&loop);
   11683  1.1  mrg 
   11684  1.1  mrg       /* Walk the rhs.  */
   11685  1.1  mrg       rss = gfc_walk_expr (expr2);
   11686  1.1  mrg       if (rss == gfc_ss_terminator)
   11687  1.1  mrg 	/* The rhs is scalar.  Add a ss for the expression.  */
   11688  1.1  mrg 	rss = gfc_get_scalar_ss (gfc_ss_terminator, expr2);
   11689  1.1  mrg       /* When doing a class assign, then the handle to the rhs needs to be a
   11690  1.1  mrg 	 pointer to allow for polymorphism.  */
   11691  1.1  mrg       if (is_poly_assign && expr2->rank == 0 && !UNLIMITED_POLY (expr2))
   11692  1.1  mrg 	rss->info->type = GFC_SS_REFERENCE;
   11693  1.1  mrg 
   11694  1.1  mrg       rss->no_bounds_check = expr2->no_bounds_check;
   11695  1.1  mrg       /* Associate the SS with the loop.  */
   11696  1.1  mrg       gfc_add_ss_to_loop (&loop, lss);
   11697  1.1  mrg       gfc_add_ss_to_loop (&loop, rss);
   11698  1.1  mrg 
   11699  1.1  mrg       /* Calculate the bounds of the scalarization.  */
   11700  1.1  mrg       gfc_conv_ss_startstride (&loop);
   11701  1.1  mrg       /* Enable loop reversal.  */
   11702  1.1  mrg       for (n = 0; n < GFC_MAX_DIMENSIONS; n++)
   11703  1.1  mrg 	loop.reverse[n] = GFC_ENABLE_REVERSE;
   11704  1.1  mrg       /* Resolve any data dependencies in the statement.  */
   11705  1.1  mrg       if (may_alias)
   11706  1.1  mrg 	gfc_conv_resolve_dependencies (&loop, lss, rss);
   11707  1.1  mrg       /* Setup the scalarizing loops.  */
   11708  1.1  mrg       gfc_conv_loop_setup (&loop, &expr2->where);
   11709  1.1  mrg 
   11710  1.1  mrg       /* Setup the gfc_se structures.  */
   11711  1.1  mrg       gfc_copy_loopinfo_to_se (&lse, &loop);
   11712  1.1  mrg       gfc_copy_loopinfo_to_se (&rse, &loop);
   11713  1.1  mrg 
   11714  1.1  mrg       rse.ss = rss;
   11715  1.1  mrg       gfc_mark_ss_chain_used (rss, 1);
   11716  1.1  mrg       if (loop.temp_ss == NULL)
   11717  1.1  mrg 	{
   11718  1.1  mrg 	  lse.ss = lss;
   11719  1.1  mrg 	  gfc_mark_ss_chain_used (lss, 1);
   11720  1.1  mrg 	}
   11721  1.1  mrg       else
   11722  1.1  mrg 	{
   11723  1.1  mrg 	  lse.ss = loop.temp_ss;
   11724  1.1  mrg 	  gfc_mark_ss_chain_used (lss, 3);
   11725  1.1  mrg 	  gfc_mark_ss_chain_used (loop.temp_ss, 3);
   11726  1.1  mrg 	}
   11727  1.1  mrg 
   11728  1.1  mrg       /* Allow the scalarizer to workshare array assignments.  */
   11729  1.1  mrg       if ((ompws_flags & (OMPWS_WORKSHARE_FLAG | OMPWS_SCALARIZER_BODY))
   11730  1.1  mrg 	  == OMPWS_WORKSHARE_FLAG
   11731  1.1  mrg 	  && loop.temp_ss == NULL)
   11732  1.1  mrg 	{
   11733  1.1  mrg 	  maybe_workshare = true;
   11734  1.1  mrg 	  ompws_flags |= OMPWS_SCALARIZER_WS | OMPWS_SCALARIZER_BODY;
   11735  1.1  mrg 	}
   11736  1.1  mrg 
   11737  1.1  mrg       /* Start the scalarized loop body.  */
   11738  1.1  mrg       gfc_start_scalarized_body (&loop, &body);
   11739  1.1  mrg     }
   11740  1.1  mrg   else
   11741  1.1  mrg     gfc_init_block (&body);
   11742  1.1  mrg 
   11743  1.1  mrg   l_is_temp = (lss != gfc_ss_terminator && loop.temp_ss != NULL);
   11744  1.1  mrg 
   11745  1.1  mrg   /* Translate the expression.  */
   11746  1.1  mrg   rse.want_coarray = flag_coarray == GFC_FCOARRAY_LIB && init_flag
   11747  1.1  mrg       && lhs_caf_attr.codimension;
   11748  1.1  mrg   gfc_conv_expr (&rse, expr2);
   11749  1.1  mrg 
   11750  1.1  mrg   /* Deal with the case of a scalar class function assigned to a derived type.  */
   11751  1.1  mrg   if (gfc_is_alloc_class_scalar_function (expr2)
   11752  1.1  mrg       && expr1->ts.type == BT_DERIVED)
   11753  1.1  mrg     {
   11754  1.1  mrg       rse.expr = gfc_class_data_get (rse.expr);
   11755  1.1  mrg       rse.expr = build_fold_indirect_ref_loc (input_location, rse.expr);
   11756  1.1  mrg     }
   11757  1.1  mrg 
   11758  1.1  mrg   /* Stabilize a string length for temporaries.  */
   11759  1.1  mrg   if (expr2->ts.type == BT_CHARACTER && !expr1->ts.deferred
   11760  1.1  mrg       && !(VAR_P (rse.string_length)
   11761  1.1  mrg 	   || TREE_CODE (rse.string_length) == PARM_DECL
   11762  1.1  mrg 	   || TREE_CODE (rse.string_length) == INDIRECT_REF))
   11763  1.1  mrg     string_length = gfc_evaluate_now (rse.string_length, &rse.pre);
   11764  1.1  mrg   else if (expr2->ts.type == BT_CHARACTER)
   11765  1.1  mrg     {
   11766  1.1  mrg       if (expr1->ts.deferred
   11767  1.1  mrg 	  && gfc_expr_attr (expr1).allocatable
   11768  1.1  mrg 	  && gfc_check_dependency (expr1, expr2, true))
   11769  1.1  mrg 	rse.string_length =
   11770  1.1  mrg 	  gfc_evaluate_now_function_scope (rse.string_length, &rse.pre);
   11771  1.1  mrg       string_length = rse.string_length;
   11772  1.1  mrg     }
   11773  1.1  mrg   else
   11774  1.1  mrg     string_length = NULL_TREE;
   11775  1.1  mrg 
   11776  1.1  mrg   if (l_is_temp)
   11777  1.1  mrg     {
   11778  1.1  mrg       gfc_conv_tmp_array_ref (&lse);
   11779  1.1  mrg       if (expr2->ts.type == BT_CHARACTER)
   11780  1.1  mrg 	lse.string_length = string_length;
   11781  1.1  mrg     }
   11782  1.1  mrg   else
   11783  1.1  mrg     {
   11784  1.1  mrg       gfc_conv_expr (&lse, expr1);
   11785  1.1  mrg       if (gfc_option.rtcheck & GFC_RTCHECK_MEM
   11786  1.1  mrg 	  && !init_flag
   11787  1.1  mrg 	  && gfc_expr_attr (expr1).allocatable
   11788  1.1  mrg 	  && expr1->rank
   11789  1.1  mrg 	  && !expr2->rank)
   11790  1.1  mrg 	{
   11791  1.1  mrg 	  tree cond;
   11792  1.1  mrg 	  const char* msg;
   11793  1.1  mrg 
   11794  1.1  mrg 	  tmp = INDIRECT_REF_P (lse.expr)
   11795  1.1  mrg 	      ? gfc_build_addr_expr (NULL_TREE, lse.expr) : lse.expr;
   11796  1.1  mrg 	  STRIP_NOPS (tmp);
   11797  1.1  mrg 
   11798  1.1  mrg 	  /* We should only get array references here.  */
   11799  1.1  mrg 	  gcc_assert (TREE_CODE (tmp) == POINTER_PLUS_EXPR
   11800  1.1  mrg 		      || TREE_CODE (tmp) == ARRAY_REF);
   11801  1.1  mrg 
   11802  1.1  mrg 	  /* 'tmp' is either the pointer to the array(POINTER_PLUS_EXPR)
   11803  1.1  mrg 	     or the array itself(ARRAY_REF).  */
   11804  1.1  mrg 	  tmp = TREE_OPERAND (tmp, 0);
   11805  1.1  mrg 
   11806  1.1  mrg 	  /* Provide the address of the array.  */
   11807  1.1  mrg 	  if (TREE_CODE (lse.expr) == ARRAY_REF)
   11808  1.1  mrg 	    tmp = gfc_build_addr_expr (NULL_TREE, tmp);
   11809  1.1  mrg 
   11810  1.1  mrg 	  cond = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
   11811  1.1  mrg 				  tmp, build_int_cst (TREE_TYPE (tmp), 0));
   11812  1.1  mrg 	  msg = _("Assignment of scalar to unallocated array");
   11813  1.1  mrg 	  gfc_trans_runtime_check (true, false, cond, &loop.pre,
   11814  1.1  mrg 				   &expr1->where, msg);
   11815  1.1  mrg 	}
   11816  1.1  mrg 
   11817  1.1  mrg       /* Deallocate the lhs parameterized components if required.  */
   11818  1.1  mrg       if (dealloc && expr2->expr_type == EXPR_FUNCTION
   11819  1.1  mrg 	  && !expr1->symtree->n.sym->attr.associate_var)
   11820  1.1  mrg 	{
   11821  1.1  mrg 	  if (expr1->ts.type == BT_DERIVED
   11822  1.1  mrg 	      && expr1->ts.u.derived
   11823  1.1  mrg 	      && expr1->ts.u.derived->attr.pdt_type)
   11824  1.1  mrg 	    {
   11825  1.1  mrg 	      tmp = gfc_deallocate_pdt_comp (expr1->ts.u.derived, lse.expr,
   11826  1.1  mrg 					     expr1->rank);
   11827  1.1  mrg 	      gfc_add_expr_to_block (&lse.pre, tmp);
   11828  1.1  mrg 	    }
   11829  1.1  mrg 	  else if (expr1->ts.type == BT_CLASS
   11830  1.1  mrg 		   && CLASS_DATA (expr1)->ts.u.derived
   11831  1.1  mrg 		   && CLASS_DATA (expr1)->ts.u.derived->attr.pdt_type)
   11832  1.1  mrg 	    {
   11833  1.1  mrg 	      tmp = gfc_class_data_get (lse.expr);
   11834  1.1  mrg 	      tmp = gfc_deallocate_pdt_comp (CLASS_DATA (expr1)->ts.u.derived,
   11835  1.1  mrg 					     tmp, expr1->rank);
   11836  1.1  mrg 	      gfc_add_expr_to_block (&lse.pre, tmp);
   11837  1.1  mrg 	    }
   11838  1.1  mrg 	}
   11839  1.1  mrg     }
   11840  1.1  mrg 
   11841  1.1  mrg   /* Assignments of scalar derived types with allocatable components
   11842  1.1  mrg      to arrays must be done with a deep copy and the rhs temporary
   11843  1.1  mrg      must have its components deallocated afterwards.  */
   11844  1.1  mrg   scalar_to_array = (expr2->ts.type == BT_DERIVED
   11845  1.1  mrg 		       && expr2->ts.u.derived->attr.alloc_comp
   11846  1.1  mrg 		       && !gfc_expr_is_variable (expr2)
   11847  1.1  mrg 		       && expr1->rank && !expr2->rank);
   11848  1.1  mrg   scalar_to_array |= (expr1->ts.type == BT_DERIVED
   11849  1.1  mrg 				    && expr1->rank
   11850  1.1  mrg 				    && expr1->ts.u.derived->attr.alloc_comp
   11851  1.1  mrg 				    && gfc_is_alloc_class_scalar_function (expr2));
   11852  1.1  mrg   if (scalar_to_array && dealloc)
   11853  1.1  mrg     {
   11854  1.1  mrg       tmp = gfc_deallocate_alloc_comp_no_caf (expr2->ts.u.derived, rse.expr, 0);
   11855  1.1  mrg       gfc_prepend_expr_to_block (&loop.post, tmp);
   11856  1.1  mrg     }
   11857  1.1  mrg 
   11858  1.1  mrg   /* When assigning a character function result to a deferred-length variable,
   11859  1.1  mrg      the function call must happen before the (re)allocation of the lhs -
   11860  1.1  mrg      otherwise the character length of the result is not known.
   11861  1.1  mrg      NOTE 1: This relies on having the exact dependence of the length type
   11862  1.1  mrg      parameter available to the caller; gfortran saves it in the .mod files.
   11863  1.1  mrg      NOTE 2: Vector array references generate an index temporary that must
   11864  1.1  mrg      not go outside the loop. Otherwise, variables should not generate
   11865  1.1  mrg      a pre block.
   11866  1.1  mrg      NOTE 3: The concatenation operation generates a temporary pointer,
   11867  1.1  mrg      whose allocation must go to the innermost loop.
   11868  1.1  mrg      NOTE 4: Elemental functions may generate a temporary, too.  */
   11869  1.1  mrg   if (flag_realloc_lhs
   11870  1.1  mrg       && expr2->ts.type == BT_CHARACTER && expr1->ts.deferred
   11871  1.1  mrg       && !(lss != gfc_ss_terminator
   11872  1.1  mrg 	   && rss != gfc_ss_terminator
   11873  1.1  mrg 	   && ((expr2->expr_type == EXPR_VARIABLE && expr2->rank)
   11874  1.1  mrg 	       || (expr2->expr_type == EXPR_FUNCTION
   11875  1.1  mrg 		   && expr2->value.function.esym != NULL
   11876  1.1  mrg 		   && expr2->value.function.esym->attr.elemental)
   11877  1.1  mrg 	       || (expr2->expr_type == EXPR_FUNCTION
   11878  1.1  mrg 		   && expr2->value.function.isym != NULL
   11879  1.1  mrg 		   && expr2->value.function.isym->elemental)
   11880  1.1  mrg 	       || (expr2->expr_type == EXPR_OP
   11881  1.1  mrg 		   && expr2->value.op.op == INTRINSIC_CONCAT))))
   11882  1.1  mrg     gfc_add_block_to_block (&block, &rse.pre);
   11883  1.1  mrg 
   11884  1.1  mrg   /* Nullify the allocatable components corresponding to those of the lhs
   11885  1.1  mrg      derived type, so that the finalization of the function result does not
   11886  1.1  mrg      affect the lhs of the assignment. Prepend is used to ensure that the
   11887  1.1  mrg      nullification occurs before the call to the finalizer. In the case of
   11888  1.1  mrg      a scalar to array assignment, this is done in gfc_trans_scalar_assign
   11889  1.1  mrg      as part of the deep copy.  */
   11890  1.1  mrg   if (!scalar_to_array && expr1->ts.type == BT_DERIVED
   11891  1.1  mrg 		       && (gfc_is_class_array_function (expr2)
   11892  1.1  mrg 			   || gfc_is_alloc_class_scalar_function (expr2)))
   11893  1.1  mrg     {
   11894  1.1  mrg       tmp = gfc_nullify_alloc_comp (expr1->ts.u.derived, rse.expr, 0);
   11895  1.1  mrg       gfc_prepend_expr_to_block (&rse.post, tmp);
   11896  1.1  mrg       if (lss != gfc_ss_terminator && rss == gfc_ss_terminator)
   11897  1.1  mrg 	gfc_add_block_to_block (&loop.post, &rse.post);
   11898  1.1  mrg     }
   11899  1.1  mrg 
   11900  1.1  mrg   tmp = NULL_TREE;
   11901  1.1  mrg 
   11902  1.1  mrg   if (is_poly_assign)
   11903  1.1  mrg     {
   11904  1.1  mrg       tmp = trans_class_assignment (&body, expr1, expr2, &lse, &rse,
   11905  1.1  mrg 				    use_vptr_copy || (lhs_attr.allocatable
   11906  1.1  mrg 						      && !lhs_attr.dimension),
   11907  1.1  mrg 				    !realloc_flag && flag_realloc_lhs
   11908  1.1  mrg 				    && !lhs_attr.pointer);
   11909  1.1  mrg       if (expr2->expr_type == EXPR_FUNCTION
   11910  1.1  mrg 	  && expr2->ts.type == BT_DERIVED
   11911  1.1  mrg 	  && expr2->ts.u.derived->attr.alloc_comp)
   11912  1.1  mrg 	{
   11913  1.1  mrg 	  tree tmp2 = gfc_deallocate_alloc_comp (expr2->ts.u.derived,
   11914  1.1  mrg 						 rse.expr, expr2->rank);
   11915  1.1  mrg 	  if (lss == gfc_ss_terminator)
   11916  1.1  mrg 	    gfc_add_expr_to_block (&rse.post, tmp2);
   11917  1.1  mrg 	  else
   11918  1.1  mrg 	    gfc_add_expr_to_block (&loop.post, tmp2);
   11919  1.1  mrg 	}
   11920  1.1  mrg     }
   11921  1.1  mrg   else if (flag_coarray == GFC_FCOARRAY_LIB
   11922  1.1  mrg 	   && lhs_caf_attr.codimension && rhs_caf_attr.codimension
   11923  1.1  mrg 	   && ((lhs_caf_attr.allocatable && lhs_refs_comp)
   11924  1.1  mrg 	       || (rhs_caf_attr.allocatable && rhs_refs_comp)))
   11925  1.1  mrg     {
   11926  1.1  mrg       /* Only detour to caf_send[get][_by_ref] () when the lhs or rhs is an
   11927  1.1  mrg 	 allocatable component, because those need to be accessed via the
   11928  1.1  mrg 	 caf-runtime.  No need to check for coindexes here, because resolve
   11929  1.1  mrg 	 has rewritten those already.  */
   11930  1.1  mrg       gfc_code code;
   11931  1.1  mrg       gfc_actual_arglist a1, a2;
   11932  1.1  mrg       /* Clear the structures to prevent accessing garbage.  */
   11933  1.1  mrg       memset (&code, '\0', sizeof (gfc_code));
   11934  1.1  mrg       memset (&a1, '\0', sizeof (gfc_actual_arglist));
   11935  1.1  mrg       memset (&a2, '\0', sizeof (gfc_actual_arglist));
   11936  1.1  mrg       a1.expr = expr1;
   11937  1.1  mrg       a1.next = &a2;
   11938  1.1  mrg       a2.expr = expr2;
   11939  1.1  mrg       a2.next = NULL;
   11940  1.1  mrg       code.ext.actual = &a1;
   11941  1.1  mrg       code.resolved_isym = gfc_intrinsic_subroutine_by_id (GFC_ISYM_CAF_SEND);
   11942  1.1  mrg       tmp = gfc_conv_intrinsic_subroutine (&code);
   11943  1.1  mrg     }
   11944  1.1  mrg   else if (!is_poly_assign && expr2->must_finalize
   11945  1.1  mrg 	   && expr1->ts.type == BT_CLASS
   11946  1.1  mrg 	   && expr2->ts.type == BT_CLASS)
   11947  1.1  mrg     {
   11948  1.1  mrg       /* This case comes about when the scalarizer provides array element
   11949  1.1  mrg 	 references. Use the vptr copy function, since this does a deep
   11950  1.1  mrg 	 copy of allocatable components, without which the finalizer call
   11951  1.1  mrg 	 will deallocate the components.  */
   11952  1.1  mrg       tmp = gfc_get_vptr_from_expr (rse.expr);
   11953  1.1  mrg       if (tmp != NULL_TREE)
   11954  1.1  mrg 	{
   11955  1.1  mrg 	  tree fcn = gfc_vptr_copy_get (tmp);
   11956  1.1  mrg 	  if (POINTER_TYPE_P (TREE_TYPE (fcn)))
   11957  1.1  mrg 	    fcn = build_fold_indirect_ref_loc (input_location, fcn);
   11958  1.1  mrg 	  tmp = build_call_expr_loc (input_location,
   11959  1.1  mrg 				     fcn, 2,
   11960  1.1  mrg 				     gfc_build_addr_expr (NULL, rse.expr),
   11961  1.1  mrg 				     gfc_build_addr_expr (NULL, lse.expr));
   11962  1.1  mrg 	}
   11963  1.1  mrg     }
   11964  1.1  mrg 
   11965  1.1  mrg   /* If nothing else works, do it the old fashioned way!  */
   11966  1.1  mrg   if (tmp == NULL_TREE)
   11967  1.1  mrg     tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts,
   11968  1.1  mrg 				   gfc_expr_is_variable (expr2)
   11969  1.1  mrg 				   || scalar_to_array
   11970  1.1  mrg 				   || expr2->expr_type == EXPR_ARRAY,
   11971  1.1  mrg 				   !(l_is_temp || init_flag) && dealloc,
   11972  1.1  mrg 				   expr1->symtree->n.sym->attr.codimension);
   11973  1.1  mrg 
   11974  1.1  mrg   /* Add the pre blocks to the body.  */
   11975  1.1  mrg   gfc_add_block_to_block (&body, &rse.pre);
   11976  1.1  mrg   gfc_add_block_to_block (&body, &lse.pre);
   11977  1.1  mrg   gfc_add_expr_to_block (&body, tmp);
   11978  1.1  mrg   /* Add the post blocks to the body.  */
   11979  1.1  mrg   gfc_add_block_to_block (&body, &rse.post);
   11980  1.1  mrg   gfc_add_block_to_block (&body, &lse.post);
   11981  1.1  mrg 
   11982  1.1  mrg   if (lss == gfc_ss_terminator)
   11983  1.1  mrg     {
   11984  1.1  mrg       /* F2003: Add the code for reallocation on assignment.  */
   11985  1.1  mrg       if (flag_realloc_lhs && is_scalar_reallocatable_lhs (expr1)
   11986  1.1  mrg 	  && !is_poly_assign)
   11987  1.1  mrg 	alloc_scalar_allocatable_for_assignment (&block, string_length,
   11988  1.1  mrg 						 expr1, expr2);
   11989  1.1  mrg 
   11990  1.1  mrg       /* Use the scalar assignment as is.  */
   11991  1.1  mrg       gfc_add_block_to_block (&block, &body);
   11992  1.1  mrg     }
   11993  1.1  mrg   else
   11994  1.1  mrg     {
   11995  1.1  mrg       gcc_assert (lse.ss == gfc_ss_terminator
   11996  1.1  mrg 		  && rse.ss == gfc_ss_terminator);
   11997  1.1  mrg 
   11998  1.1  mrg       if (l_is_temp)
   11999  1.1  mrg 	{
   12000  1.1  mrg 	  gfc_trans_scalarized_loop_boundary (&loop, &body);
   12001  1.1  mrg 
   12002  1.1  mrg 	  /* We need to copy the temporary to the actual lhs.  */
   12003  1.1  mrg 	  gfc_init_se (&lse, NULL);
   12004  1.1  mrg 	  gfc_init_se (&rse, NULL);
   12005  1.1  mrg 	  gfc_copy_loopinfo_to_se (&lse, &loop);
   12006  1.1  mrg 	  gfc_copy_loopinfo_to_se (&rse, &loop);
   12007  1.1  mrg 
   12008  1.1  mrg 	  rse.ss = loop.temp_ss;
   12009  1.1  mrg 	  lse.ss = lss;
   12010  1.1  mrg 
   12011  1.1  mrg 	  gfc_conv_tmp_array_ref (&rse);
   12012  1.1  mrg 	  gfc_conv_expr (&lse, expr1);
   12013  1.1  mrg 
   12014  1.1  mrg 	  gcc_assert (lse.ss == gfc_ss_terminator
   12015  1.1  mrg 		      && rse.ss == gfc_ss_terminator);
   12016  1.1  mrg 
   12017  1.1  mrg 	  if (expr2->ts.type == BT_CHARACTER)
   12018  1.1  mrg 	    rse.string_length = string_length;
   12019  1.1  mrg 
   12020  1.1  mrg 	  tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts,
   12021  1.1  mrg 					 false, dealloc);
   12022  1.1  mrg 	  gfc_add_expr_to_block (&body, tmp);
   12023  1.1  mrg 	}
   12024  1.1  mrg 
   12025  1.1  mrg       /* F2003: Allocate or reallocate lhs of allocatable array.  */
   12026  1.1  mrg       if (realloc_flag)
   12027  1.1  mrg 	{
   12028  1.1  mrg 	  realloc_lhs_warning (expr1->ts.type, true, &expr1->where);
   12029  1.1  mrg 	  ompws_flags &= ~OMPWS_SCALARIZER_WS;
   12030  1.1  mrg 	  tmp = gfc_alloc_allocatable_for_assignment (&loop, expr1, expr2);
   12031  1.1  mrg 	  if (tmp != NULL_TREE)
   12032  1.1  mrg 	    gfc_add_expr_to_block (&loop.code[expr1->rank - 1], tmp);
   12033  1.1  mrg 	}
   12034  1.1  mrg 
   12035  1.1  mrg       if (maybe_workshare)
   12036  1.1  mrg 	ompws_flags &= ~OMPWS_SCALARIZER_BODY;
   12037  1.1  mrg 
   12038  1.1  mrg       /* Generate the copying loops.  */
   12039  1.1  mrg       gfc_trans_scalarizing_loops (&loop, &body);
   12040  1.1  mrg 
   12041  1.1  mrg       /* Wrap the whole thing up.  */
   12042  1.1  mrg       gfc_add_block_to_block (&block, &loop.pre);
   12043  1.1  mrg       gfc_add_block_to_block (&block, &loop.post);
   12044  1.1  mrg 
   12045  1.1  mrg       gfc_cleanup_loop (&loop);
   12046  1.1  mrg     }
   12047  1.1  mrg 
   12048  1.1  mrg   return gfc_finish_block (&block);
   12049  1.1  mrg }
   12050  1.1  mrg 
   12051  1.1  mrg 
   12052  1.1  mrg /* Check whether EXPR is a copyable array.  */
   12053  1.1  mrg 
   12054  1.1  mrg static bool
   12055  1.1  mrg copyable_array_p (gfc_expr * expr)
   12056  1.1  mrg {
   12057  1.1  mrg   if (expr->expr_type != EXPR_VARIABLE)
   12058  1.1  mrg     return false;
   12059  1.1  mrg 
   12060  1.1  mrg   /* First check it's an array.  */
   12061  1.1  mrg   if (expr->rank < 1 || !expr->ref || expr->ref->next)
   12062  1.1  mrg     return false;
   12063  1.1  mrg 
   12064  1.1  mrg   if (!gfc_full_array_ref_p (expr->ref, NULL))
   12065  1.1  mrg     return false;
   12066  1.1  mrg 
   12067  1.1  mrg   /* Next check that it's of a simple enough type.  */
   12068  1.1  mrg   switch (expr->ts.type)
   12069  1.1  mrg     {
   12070  1.1  mrg     case BT_INTEGER:
   12071  1.1  mrg     case BT_REAL:
   12072  1.1  mrg     case BT_COMPLEX:
   12073  1.1  mrg     case BT_LOGICAL:
   12074  1.1  mrg       return true;
   12075  1.1  mrg 
   12076  1.1  mrg     case BT_CHARACTER:
   12077  1.1  mrg       return false;
   12078  1.1  mrg 
   12079  1.1  mrg     case_bt_struct:
   12080  1.1  mrg       return !expr->ts.u.derived->attr.alloc_comp;
   12081  1.1  mrg 
   12082  1.1  mrg     default:
   12083  1.1  mrg       break;
   12084  1.1  mrg     }
   12085  1.1  mrg 
   12086  1.1  mrg   return false;
   12087  1.1  mrg }
   12088  1.1  mrg 
   12089  1.1  mrg /* Translate an assignment.  */
   12090  1.1  mrg 
   12091  1.1  mrg tree
   12092  1.1  mrg gfc_trans_assignment (gfc_expr * expr1, gfc_expr * expr2, bool init_flag,
   12093  1.1  mrg 		      bool dealloc, bool use_vptr_copy, bool may_alias)
   12094  1.1  mrg {
   12095  1.1  mrg   tree tmp;
   12096  1.1  mrg 
   12097  1.1  mrg   /* Special case a single function returning an array.  */
   12098  1.1  mrg   if (expr2->expr_type == EXPR_FUNCTION && expr2->rank > 0)
   12099  1.1  mrg     {
   12100  1.1  mrg       tmp = gfc_trans_arrayfunc_assign (expr1, expr2);
   12101  1.1  mrg       if (tmp)
   12102  1.1  mrg 	return tmp;
   12103  1.1  mrg     }
   12104  1.1  mrg 
   12105  1.1  mrg   /* Special case assigning an array to zero.  */
   12106  1.1  mrg   if (copyable_array_p (expr1)
   12107  1.1  mrg       && is_zero_initializer_p (expr2))
   12108  1.1  mrg     {
   12109  1.1  mrg       tmp = gfc_trans_zero_assign (expr1);
   12110  1.1  mrg       if (tmp)
   12111  1.1  mrg         return tmp;
   12112  1.1  mrg     }
   12113  1.1  mrg 
   12114  1.1  mrg   /* Special case copying one array to another.  */
   12115  1.1  mrg   if (copyable_array_p (expr1)
   12116  1.1  mrg       && copyable_array_p (expr2)
   12117  1.1  mrg       && gfc_compare_types (&expr1->ts, &expr2->ts)
   12118  1.1  mrg       && !gfc_check_dependency (expr1, expr2, 0))
   12119  1.1  mrg     {
   12120  1.1  mrg       tmp = gfc_trans_array_copy (expr1, expr2);
   12121  1.1  mrg       if (tmp)
   12122  1.1  mrg         return tmp;
   12123  1.1  mrg     }
   12124  1.1  mrg 
   12125  1.1  mrg   /* Special case initializing an array from a constant array constructor.  */
   12126  1.1  mrg   if (copyable_array_p (expr1)
   12127  1.1  mrg       && expr2->expr_type == EXPR_ARRAY
   12128  1.1  mrg       && gfc_compare_types (&expr1->ts, &expr2->ts))
   12129  1.1  mrg     {
   12130  1.1  mrg       tmp = gfc_trans_array_constructor_copy (expr1, expr2);
   12131  1.1  mrg       if (tmp)
   12132  1.1  mrg 	return tmp;
   12133  1.1  mrg     }
   12134  1.1  mrg 
   12135  1.1  mrg   if (UNLIMITED_POLY (expr1) && expr1->rank)
   12136  1.1  mrg     use_vptr_copy = true;
   12137  1.1  mrg 
   12138  1.1  mrg   /* Fallback to the scalarizer to generate explicit loops.  */
   12139  1.1  mrg   return gfc_trans_assignment_1 (expr1, expr2, init_flag, dealloc,
   12140  1.1  mrg 				 use_vptr_copy, may_alias);
   12141  1.1  mrg }
   12142  1.1  mrg 
   12143  1.1  mrg tree
   12144  1.1  mrg gfc_trans_init_assign (gfc_code * code)
   12145  1.1  mrg {
   12146  1.1  mrg   return gfc_trans_assignment (code->expr1, code->expr2, true, false, true);
   12147  1.1  mrg }
   12148  1.1  mrg 
   12149  1.1  mrg tree
   12150  1.1  mrg gfc_trans_assign (gfc_code * code)
   12151  1.1  mrg {
   12152  1.1  mrg   return gfc_trans_assignment (code->expr1, code->expr2, false, true);
   12153  1.1  mrg }
   12154  1.1  mrg 
   12155  1.1  mrg /* Generate a simple loop for internal use of the form
   12156  1.1  mrg    for (var = begin; var <cond> end; var += step)
   12157  1.1  mrg       body;  */
   12158  1.1  mrg void
   12159  1.1  mrg gfc_simple_for_loop (stmtblock_t *block, tree var, tree begin, tree end,
   12160  1.1  mrg 		     enum tree_code cond, tree step, tree body)
   12161  1.1  mrg {
   12162  1.1  mrg   tree tmp;
   12163  1.1  mrg 
   12164  1.1  mrg   /* var = begin. */
   12165  1.1  mrg   gfc_add_modify (block, var, begin);
   12166  1.1  mrg 
   12167  1.1  mrg   /* Loop: for (var = begin; var <cond> end; var += step).  */
   12168  1.1  mrg   tree label_loop = gfc_build_label_decl (NULL_TREE);
   12169  1.1  mrg   tree label_cond = gfc_build_label_decl (NULL_TREE);
   12170  1.1  mrg   TREE_USED (label_loop) = 1;
   12171  1.1  mrg   TREE_USED (label_cond) = 1;
   12172  1.1  mrg 
   12173  1.1  mrg   gfc_add_expr_to_block (block, build1_v (GOTO_EXPR, label_cond));
   12174  1.1  mrg   gfc_add_expr_to_block (block, build1_v (LABEL_EXPR, label_loop));
   12175  1.1  mrg 
   12176  1.1  mrg   /* Loop body.  */
   12177  1.1  mrg   gfc_add_expr_to_block (block, body);
   12178  1.1  mrg 
   12179  1.1  mrg   /* End of loop body.  */
   12180  1.1  mrg   tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (var), var, step);
   12181  1.1  mrg   gfc_add_modify (block, var, tmp);
   12182  1.1  mrg   gfc_add_expr_to_block (block, build1_v (LABEL_EXPR, label_cond));
   12183  1.1  mrg   tmp = fold_build2_loc (input_location, cond, boolean_type_node, var, end);
   12184  1.1  mrg   tmp = build3_v (COND_EXPR, tmp, build1_v (GOTO_EXPR, label_loop),
   12185  1.1  mrg 		  build_empty_stmt (input_location));
   12186  1.1  mrg   gfc_add_expr_to_block (block, tmp);
   12187  1.1  mrg }
   12188