xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/fortran/trans-expr.c (revision 627f7eb200a4419d89b531d55fccd2ee3ffdcde0)
1 /* Expression translation
2    Copyright (C) 2002-2019 Free Software Foundation, Inc.
3    Contributed by Paul Brook <paul@nowt.org>
4    and Steven Bosscher <s.bosscher@student.tudelft.nl>
5 
6 This file is part of GCC.
7 
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 3, or (at your option) any later
11 version.
12 
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16 for more details.
17 
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3.  If not see
20 <http://www.gnu.org/licenses/>.  */
21 
22 /* trans-expr.c-- generate GENERIC trees for gfc_expr.  */
23 
24 #include "config.h"
25 #include "system.h"
26 #include "coretypes.h"
27 #include "options.h"
28 #include "tree.h"
29 #include "gfortran.h"
30 #include "trans.h"
31 #include "stringpool.h"
32 #include "diagnostic-core.h"	/* For fatal_error.  */
33 #include "fold-const.h"
34 #include "langhooks.h"
35 #include "arith.h"
36 #include "constructor.h"
37 #include "trans-const.h"
38 #include "trans-types.h"
39 #include "trans-array.h"
40 /* Only for gfc_trans_assign and gfc_trans_pointer_assign.  */
41 #include "trans-stmt.h"
42 #include "dependency.h"
43 #include "gimplify.h"
44 
45 /* Convert a scalar to an array descriptor. To be used for assumed-rank
46    arrays.  */
47 
48 static tree
49 get_scalar_to_descriptor_type (tree scalar, symbol_attribute attr)
50 {
51   enum gfc_array_kind akind;
52 
53   if (attr.pointer)
54     akind = GFC_ARRAY_POINTER_CONT;
55   else if (attr.allocatable)
56     akind = GFC_ARRAY_ALLOCATABLE;
57   else
58     akind = GFC_ARRAY_ASSUMED_SHAPE_CONT;
59 
60   if (POINTER_TYPE_P (TREE_TYPE (scalar)))
61     scalar = TREE_TYPE (scalar);
62   return gfc_get_array_type_bounds (TREE_TYPE (scalar), 0, 0, NULL, NULL, 1,
63 				    akind, !(attr.pointer || attr.target));
64 }
65 
66 tree
67 gfc_conv_scalar_to_descriptor (gfc_se *se, tree scalar, symbol_attribute attr)
68 {
69   tree desc, type, etype;
70 
71   type = get_scalar_to_descriptor_type (scalar, attr);
72   etype = TREE_TYPE (scalar);
73   desc = gfc_create_var (type, "desc");
74   DECL_ARTIFICIAL (desc) = 1;
75 
76   if (CONSTANT_CLASS_P (scalar))
77     {
78       tree tmp;
79       tmp = gfc_create_var (TREE_TYPE (scalar), "scalar");
80       gfc_add_modify (&se->pre, tmp, scalar);
81       scalar = tmp;
82     }
83   if (!POINTER_TYPE_P (TREE_TYPE (scalar)))
84     scalar = gfc_build_addr_expr (NULL_TREE, scalar);
85   else if (TREE_TYPE (etype) && TREE_CODE (TREE_TYPE (etype)) == ARRAY_TYPE)
86     etype = TREE_TYPE (etype);
87   gfc_add_modify (&se->pre, gfc_conv_descriptor_dtype (desc),
88 		  gfc_get_dtype_rank_type (0, etype));
89   gfc_conv_descriptor_data_set (&se->pre, desc, scalar);
90 
91   /* Copy pointer address back - but only if it could have changed and
92      if the actual argument is a pointer and not, e.g., NULL().  */
93   if ((attr.pointer || attr.allocatable) && attr.intent != INTENT_IN)
94     gfc_add_modify (&se->post, scalar,
95 		    fold_convert (TREE_TYPE (scalar),
96 				  gfc_conv_descriptor_data_get (desc)));
97   return desc;
98 }
99 
100 
101 /* Get the coarray token from the ultimate array or component ref.
102    Returns a NULL_TREE, when the ref object is not allocatable or pointer.  */
103 
104 tree
105 gfc_get_ultimate_alloc_ptr_comps_caf_token (gfc_se *outerse, gfc_expr *expr)
106 {
107   gfc_symbol *sym = expr->symtree->n.sym;
108   bool is_coarray = sym->attr.codimension;
109   gfc_expr *caf_expr = gfc_copy_expr (expr);
110   gfc_ref *ref = caf_expr->ref, *last_caf_ref = NULL;
111 
112   while (ref)
113     {
114       if (ref->type == REF_COMPONENT
115 	  && (ref->u.c.component->attr.allocatable
116 	      || ref->u.c.component->attr.pointer)
117 	  && (is_coarray || ref->u.c.component->attr.codimension))
118 	  last_caf_ref = ref;
119       ref = ref->next;
120     }
121 
122   if (last_caf_ref == NULL)
123     return NULL_TREE;
124 
125   tree comp = last_caf_ref->u.c.component->caf_token, caf;
126   gfc_se se;
127   bool comp_ref = !last_caf_ref->u.c.component->attr.dimension;
128   if (comp == NULL_TREE && comp_ref)
129     return NULL_TREE;
130   gfc_init_se (&se, outerse);
131   gfc_free_ref_list (last_caf_ref->next);
132   last_caf_ref->next = NULL;
133   caf_expr->rank = comp_ref ? 0 : last_caf_ref->u.c.component->as->rank;
134   se.want_pointer = comp_ref;
135   gfc_conv_expr (&se, caf_expr);
136   gfc_add_block_to_block (&outerse->pre, &se.pre);
137 
138   if (TREE_CODE (se.expr) == COMPONENT_REF && comp_ref)
139     se.expr = TREE_OPERAND (se.expr, 0);
140   gfc_free_expr (caf_expr);
141 
142   if (comp_ref)
143     caf = fold_build3_loc (input_location, COMPONENT_REF,
144 			   TREE_TYPE (comp), se.expr, comp, NULL_TREE);
145   else
146     caf = gfc_conv_descriptor_token (se.expr);
147   return gfc_build_addr_expr (NULL_TREE, caf);
148 }
149 
150 
151 /* This is the seed for an eventual trans-class.c
152 
153    The following parameters should not be used directly since they might
154    in future implementations.  Use the corresponding APIs.  */
155 #define CLASS_DATA_FIELD 0
156 #define CLASS_VPTR_FIELD 1
157 #define CLASS_LEN_FIELD 2
158 #define VTABLE_HASH_FIELD 0
159 #define VTABLE_SIZE_FIELD 1
160 #define VTABLE_EXTENDS_FIELD 2
161 #define VTABLE_DEF_INIT_FIELD 3
162 #define VTABLE_COPY_FIELD 4
163 #define VTABLE_FINAL_FIELD 5
164 #define VTABLE_DEALLOCATE_FIELD 6
165 
166 
167 tree
168 gfc_class_set_static_fields (tree decl, tree vptr, tree data)
169 {
170   tree tmp;
171   tree field;
172   vec<constructor_elt, va_gc> *init = NULL;
173 
174   field = TYPE_FIELDS (TREE_TYPE (decl));
175   tmp = gfc_advance_chain (field, CLASS_DATA_FIELD);
176   CONSTRUCTOR_APPEND_ELT (init, tmp, data);
177 
178   tmp = gfc_advance_chain (field, CLASS_VPTR_FIELD);
179   CONSTRUCTOR_APPEND_ELT (init, tmp, vptr);
180 
181   return build_constructor (TREE_TYPE (decl), init);
182 }
183 
184 
185 tree
186 gfc_class_data_get (tree decl)
187 {
188   tree data;
189   if (POINTER_TYPE_P (TREE_TYPE (decl)))
190     decl = build_fold_indirect_ref_loc (input_location, decl);
191   data = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (decl)),
192 			    CLASS_DATA_FIELD);
193   return fold_build3_loc (input_location, COMPONENT_REF,
194 			  TREE_TYPE (data), decl, data,
195 			  NULL_TREE);
196 }
197 
198 
199 tree
200 gfc_class_vptr_get (tree decl)
201 {
202   tree vptr;
203   /* For class arrays decl may be a temporary descriptor handle, the vptr is
204      then available through the saved descriptor.  */
205   if (VAR_P (decl) && DECL_LANG_SPECIFIC (decl)
206       && GFC_DECL_SAVED_DESCRIPTOR (decl))
207     decl = GFC_DECL_SAVED_DESCRIPTOR (decl);
208   if (POINTER_TYPE_P (TREE_TYPE (decl)))
209     decl = build_fold_indirect_ref_loc (input_location, decl);
210   vptr = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (decl)),
211 			    CLASS_VPTR_FIELD);
212   return fold_build3_loc (input_location, COMPONENT_REF,
213 			  TREE_TYPE (vptr), decl, vptr,
214 			  NULL_TREE);
215 }
216 
217 
218 tree
219 gfc_class_len_get (tree decl)
220 {
221   tree len;
222   /* For class arrays decl may be a temporary descriptor handle, the len is
223      then available through the saved descriptor.  */
224   if (VAR_P (decl) && DECL_LANG_SPECIFIC (decl)
225       && GFC_DECL_SAVED_DESCRIPTOR (decl))
226     decl = GFC_DECL_SAVED_DESCRIPTOR (decl);
227   if (POINTER_TYPE_P (TREE_TYPE (decl)))
228     decl = build_fold_indirect_ref_loc (input_location, decl);
229   len = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (decl)),
230 			   CLASS_LEN_FIELD);
231   return fold_build3_loc (input_location, COMPONENT_REF,
232 			  TREE_TYPE (len), decl, len,
233 			  NULL_TREE);
234 }
235 
236 
237 /* Try to get the _len component of a class.  When the class is not unlimited
238    poly, i.e. no _len field exists, then return a zero node.  */
239 
240 tree
241 gfc_class_len_or_zero_get (tree decl)
242 {
243   tree len;
244   /* For class arrays decl may be a temporary descriptor handle, the vptr is
245      then available through the saved descriptor.  */
246   if (VAR_P (decl) && DECL_LANG_SPECIFIC (decl)
247       && GFC_DECL_SAVED_DESCRIPTOR (decl))
248     decl = GFC_DECL_SAVED_DESCRIPTOR (decl);
249   if (POINTER_TYPE_P (TREE_TYPE (decl)))
250     decl = build_fold_indirect_ref_loc (input_location, decl);
251   len = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (decl)),
252 			   CLASS_LEN_FIELD);
253   return len != NULL_TREE ? fold_build3_loc (input_location, COMPONENT_REF,
254 					     TREE_TYPE (len), decl, len,
255 					     NULL_TREE)
256     : build_zero_cst (gfc_charlen_type_node);
257 }
258 
259 
260 /* Get the specified FIELD from the VPTR.  */
261 
262 static tree
263 vptr_field_get (tree vptr, int fieldno)
264 {
265   tree field;
266   vptr = build_fold_indirect_ref_loc (input_location, vptr);
267   field = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (vptr)),
268 			     fieldno);
269   field = fold_build3_loc (input_location, COMPONENT_REF,
270 			   TREE_TYPE (field), vptr, field,
271 			   NULL_TREE);
272   gcc_assert (field);
273   return field;
274 }
275 
276 
277 /* Get the field from the class' vptr.  */
278 
279 static tree
280 class_vtab_field_get (tree decl, int fieldno)
281 {
282   tree vptr;
283   vptr = gfc_class_vptr_get (decl);
284   return vptr_field_get (vptr, fieldno);
285 }
286 
287 
288 /* Define a macro for creating the class_vtab_* and vptr_* accessors in
289    unison.  */
290 #define VTAB_GET_FIELD_GEN(name, field) tree \
291 gfc_class_vtab_## name ##_get (tree cl) \
292 { \
293   return class_vtab_field_get (cl, field); \
294 } \
295  \
296 tree \
297 gfc_vptr_## name ##_get (tree vptr) \
298 { \
299   return vptr_field_get (vptr, field); \
300 }
301 
302 VTAB_GET_FIELD_GEN (hash, VTABLE_HASH_FIELD)
303 VTAB_GET_FIELD_GEN (extends, VTABLE_EXTENDS_FIELD)
304 VTAB_GET_FIELD_GEN (def_init, VTABLE_DEF_INIT_FIELD)
305 VTAB_GET_FIELD_GEN (copy, VTABLE_COPY_FIELD)
306 VTAB_GET_FIELD_GEN (final, VTABLE_FINAL_FIELD)
307 VTAB_GET_FIELD_GEN (deallocate, VTABLE_DEALLOCATE_FIELD)
308 
309 
310 /* The size field is returned as an array index type.  Therefore treat
311    it and only it specially.  */
312 
313 tree
314 gfc_class_vtab_size_get (tree cl)
315 {
316   tree size;
317   size = class_vtab_field_get (cl, VTABLE_SIZE_FIELD);
318   /* Always return size as an array index type.  */
319   size = fold_convert (gfc_array_index_type, size);
320   gcc_assert (size);
321   return size;
322 }
323 
324 tree
325 gfc_vptr_size_get (tree vptr)
326 {
327   tree size;
328   size = vptr_field_get (vptr, VTABLE_SIZE_FIELD);
329   /* Always return size as an array index type.  */
330   size = fold_convert (gfc_array_index_type, size);
331   gcc_assert (size);
332   return size;
333 }
334 
335 
336 #undef CLASS_DATA_FIELD
337 #undef CLASS_VPTR_FIELD
338 #undef CLASS_LEN_FIELD
339 #undef VTABLE_HASH_FIELD
340 #undef VTABLE_SIZE_FIELD
341 #undef VTABLE_EXTENDS_FIELD
342 #undef VTABLE_DEF_INIT_FIELD
343 #undef VTABLE_COPY_FIELD
344 #undef VTABLE_FINAL_FIELD
345 
346 
347 /* Search for the last _class ref in the chain of references of this
348    expression and cut the chain there.  Albeit this routine is similiar
349    to class.c::gfc_add_component_ref (), is there a significant
350    difference: gfc_add_component_ref () concentrates on an array ref to
351    be the last ref in the chain.  This routine is oblivious to the kind
352    of refs following.  */
353 
354 gfc_expr *
355 gfc_find_and_cut_at_last_class_ref (gfc_expr *e, bool is_mold)
356 {
357   gfc_expr *base_expr;
358   gfc_ref *ref, *class_ref, *tail = NULL, *array_ref;
359 
360   /* Find the last class reference.  */
361   class_ref = NULL;
362   array_ref = NULL;
363   for (ref = e->ref; ref; ref = ref->next)
364     {
365       if (ref->type == REF_ARRAY && ref->u.ar.type != AR_ELEMENT)
366 	array_ref = ref;
367 
368       if (ref->type == REF_COMPONENT
369 	  && ref->u.c.component->ts.type == BT_CLASS)
370 	{
371 	  /* Component to the right of a part reference with nonzero rank
372 	     must not have the ALLOCATABLE attribute.  If attempts are
373 	     made to reference such a component reference, an error results
374 	     followed by an ICE.  */
375 	  if (array_ref && CLASS_DATA (ref->u.c.component)->attr.allocatable)
376 	    return NULL;
377 	  class_ref = ref;
378 	}
379 
380       if (ref->next == NULL)
381 	break;
382     }
383 
384   /* Remove and store all subsequent references after the
385      CLASS reference.  */
386   if (class_ref)
387     {
388       tail = class_ref->next;
389       class_ref->next = NULL;
390     }
391   else if (e->symtree && e->symtree->n.sym->ts.type == BT_CLASS)
392     {
393       tail = e->ref;
394       e->ref = NULL;
395     }
396 
397   if (is_mold)
398     base_expr = gfc_expr_to_initialize (e);
399   else
400     base_expr = gfc_copy_expr (e);
401 
402   /* Restore the original tail expression.  */
403   if (class_ref)
404     {
405       gfc_free_ref_list (class_ref->next);
406       class_ref->next = tail;
407     }
408   else if (e->symtree && e->symtree->n.sym->ts.type == BT_CLASS)
409     {
410       gfc_free_ref_list (e->ref);
411       e->ref = tail;
412     }
413   return base_expr;
414 }
415 
416 
417 /* Reset the vptr to the declared type, e.g. after deallocation.  */
418 
419 void
420 gfc_reset_vptr (stmtblock_t *block, gfc_expr *e)
421 {
422   gfc_symbol *vtab;
423   tree vptr;
424   tree vtable;
425   gfc_se se;
426 
427   /* Evaluate the expression and obtain the vptr from it.  */
428   gfc_init_se (&se, NULL);
429   if (e->rank)
430     gfc_conv_expr_descriptor (&se, e);
431   else
432     gfc_conv_expr (&se, e);
433   gfc_add_block_to_block (block, &se.pre);
434   vptr = gfc_get_vptr_from_expr (se.expr);
435 
436   /* If a vptr is not found, we can do nothing more.  */
437   if (vptr == NULL_TREE)
438     return;
439 
440   if (UNLIMITED_POLY (e))
441     gfc_add_modify (block, vptr, build_int_cst (TREE_TYPE (vptr), 0));
442   else
443     {
444       /* Return the vptr to the address of the declared type.  */
445       vtab = gfc_find_derived_vtab (e->ts.u.derived);
446       vtable = vtab->backend_decl;
447       if (vtable == NULL_TREE)
448 	vtable = gfc_get_symbol_decl (vtab);
449       vtable = gfc_build_addr_expr (NULL, vtable);
450       vtable = fold_convert (TREE_TYPE (vptr), vtable);
451       gfc_add_modify (block, vptr, vtable);
452     }
453 }
454 
455 
456 /* Reset the len for unlimited polymorphic objects.  */
457 
458 void
459 gfc_reset_len (stmtblock_t *block, gfc_expr *expr)
460 {
461   gfc_expr *e;
462   gfc_se se_len;
463   e = gfc_find_and_cut_at_last_class_ref (expr);
464   if (e == NULL)
465     return;
466   gfc_add_len_component (e);
467   gfc_init_se (&se_len, NULL);
468   gfc_conv_expr (&se_len, e);
469   gfc_add_modify (block, se_len.expr,
470 		  fold_convert (TREE_TYPE (se_len.expr), integer_zero_node));
471   gfc_free_expr (e);
472 }
473 
474 
475 /* Obtain the vptr of the last class reference in an expression.
476    Return NULL_TREE if no class reference is found.  */
477 
478 tree
479 gfc_get_vptr_from_expr (tree expr)
480 {
481   tree tmp;
482   tree type;
483 
484   for (tmp = expr; tmp; tmp = TREE_OPERAND (tmp, 0))
485     {
486       type = TREE_TYPE (tmp);
487       while (type)
488 	{
489 	  if (GFC_CLASS_TYPE_P (type))
490 	    return gfc_class_vptr_get (tmp);
491 	  if (type != TYPE_CANONICAL (type))
492 	    type = TYPE_CANONICAL (type);
493 	  else
494 	    type = NULL_TREE;
495 	}
496       if (VAR_P (tmp) || TREE_CODE (tmp) == PARM_DECL)
497 	break;
498     }
499 
500   if (POINTER_TYPE_P (TREE_TYPE (tmp)))
501     tmp = build_fold_indirect_ref_loc (input_location, tmp);
502 
503   if (GFC_CLASS_TYPE_P (TREE_TYPE (tmp)))
504     return gfc_class_vptr_get (tmp);
505 
506   return NULL_TREE;
507 }
508 
509 
510 static void
511 class_array_data_assign (stmtblock_t *block, tree lhs_desc, tree rhs_desc,
512 			 bool lhs_type)
513 {
514   tree tmp, tmp2, type;
515 
516   gfc_conv_descriptor_data_set (block, lhs_desc,
517 				gfc_conv_descriptor_data_get (rhs_desc));
518   gfc_conv_descriptor_offset_set (block, lhs_desc,
519 				  gfc_conv_descriptor_offset_get (rhs_desc));
520 
521   gfc_add_modify (block, gfc_conv_descriptor_dtype (lhs_desc),
522 		  gfc_conv_descriptor_dtype (rhs_desc));
523 
524   /* Assign the dimension as range-ref.  */
525   tmp = gfc_get_descriptor_dimension (lhs_desc);
526   tmp2 = gfc_get_descriptor_dimension (rhs_desc);
527 
528   type = lhs_type ? TREE_TYPE (tmp) : TREE_TYPE (tmp2);
529   tmp = build4_loc (input_location, ARRAY_RANGE_REF, type, tmp,
530 		    gfc_index_zero_node, NULL_TREE, NULL_TREE);
531   tmp2 = build4_loc (input_location, ARRAY_RANGE_REF, type, tmp2,
532 		     gfc_index_zero_node, NULL_TREE, NULL_TREE);
533   gfc_add_modify (block, tmp, tmp2);
534 }
535 
536 
537 /* Takes a derived type expression and returns the address of a temporary
538    class object of the 'declared' type.  If vptr is not NULL, this is
539    used for the temporary class object.
540    optional_alloc_ptr is false when the dummy is neither allocatable
541    nor a pointer; that's only relevant for the optional handling.  */
542 void
543 gfc_conv_derived_to_class (gfc_se *parmse, gfc_expr *e,
544 			   gfc_typespec class_ts, tree vptr, bool optional,
545 			   bool optional_alloc_ptr)
546 {
547   gfc_symbol *vtab;
548   tree cond_optional = NULL_TREE;
549   gfc_ss *ss;
550   tree ctree;
551   tree var;
552   tree tmp;
553   int dim;
554 
555   /* The derived type needs to be converted to a temporary
556      CLASS object.  */
557   tmp = gfc_typenode_for_spec (&class_ts);
558   var = gfc_create_var (tmp, "class");
559 
560   /* Set the vptr.  */
561   ctree =  gfc_class_vptr_get (var);
562 
563   if (vptr != NULL_TREE)
564     {
565       /* Use the dynamic vptr.  */
566       tmp = vptr;
567     }
568   else
569     {
570       /* In this case the vtab corresponds to the derived type and the
571 	 vptr must point to it.  */
572       vtab = gfc_find_derived_vtab (e->ts.u.derived);
573       gcc_assert (vtab);
574       tmp = gfc_build_addr_expr (NULL_TREE, gfc_get_symbol_decl (vtab));
575     }
576   gfc_add_modify (&parmse->pre, ctree,
577 		  fold_convert (TREE_TYPE (ctree), tmp));
578 
579   /* Now set the data field.  */
580   ctree =  gfc_class_data_get (var);
581 
582   if (optional)
583     cond_optional = gfc_conv_expr_present (e->symtree->n.sym);
584 
585   if (parmse->expr && POINTER_TYPE_P (TREE_TYPE (parmse->expr)))
586     {
587       /* If there is a ready made pointer to a derived type, use it
588 	 rather than evaluating the expression again.  */
589       tmp = fold_convert (TREE_TYPE (ctree), parmse->expr);
590       gfc_add_modify (&parmse->pre, ctree, tmp);
591     }
592   else if (parmse->ss && parmse->ss->info && parmse->ss->info->useflags)
593     {
594       /* For an array reference in an elemental procedure call we need
595 	 to retain the ss to provide the scalarized array reference.  */
596       gfc_conv_expr_reference (parmse, e);
597       tmp = fold_convert (TREE_TYPE (ctree), parmse->expr);
598       if (optional)
599 	tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp),
600 			  cond_optional, tmp,
601 			  fold_convert (TREE_TYPE (tmp), null_pointer_node));
602       gfc_add_modify (&parmse->pre, ctree, tmp);
603     }
604   else
605     {
606       ss = gfc_walk_expr (e);
607       if (ss == gfc_ss_terminator)
608 	{
609 	  parmse->ss = NULL;
610 	  gfc_conv_expr_reference (parmse, e);
611 
612 	  /* Scalar to an assumed-rank array.  */
613 	  if (class_ts.u.derived->components->as)
614 	    {
615 	      tree type;
616 	      type = get_scalar_to_descriptor_type (parmse->expr,
617 						    gfc_expr_attr (e));
618 	      gfc_add_modify (&parmse->pre, gfc_conv_descriptor_dtype (ctree),
619 			      gfc_get_dtype (type));
620 	      if (optional)
621 		parmse->expr = build3_loc (input_location, COND_EXPR,
622 					   TREE_TYPE (parmse->expr),
623 					   cond_optional, parmse->expr,
624 					   fold_convert (TREE_TYPE (parmse->expr),
625 							 null_pointer_node));
626 	      gfc_conv_descriptor_data_set (&parmse->pre, ctree, parmse->expr);
627 	    }
628           else
629 	    {
630 	      tmp = fold_convert (TREE_TYPE (ctree), parmse->expr);
631 	      if (optional)
632 		tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp),
633 				  cond_optional, tmp,
634 				  fold_convert (TREE_TYPE (tmp),
635 						null_pointer_node));
636 	      gfc_add_modify (&parmse->pre, ctree, tmp);
637 	    }
638 	}
639       else
640 	{
641 	  stmtblock_t block;
642 	  gfc_init_block (&block);
643 	  gfc_ref *ref;
644 
645 	  parmse->ss = ss;
646 	  parmse->use_offset = 1;
647 	  gfc_conv_expr_descriptor (parmse, e);
648 
649 	  /* Detect any array references with vector subscripts.  */
650 	  for (ref = e->ref; ref; ref = ref->next)
651 	    if (ref->type == REF_ARRAY
652 		&& ref->u.ar.type != AR_ELEMENT
653 		&& ref->u.ar.type != AR_FULL)
654 	      {
655 		for (dim = 0; dim < ref->u.ar.dimen; dim++)
656 		  if (ref->u.ar.dimen_type[dim] == DIMEN_VECTOR)
657 		    break;
658 		if (dim < ref->u.ar.dimen)
659 		  break;
660 	      }
661 
662 	  /* Array references with vector subscripts and non-variable expressions
663 	     need be converted to a one-based descriptor.  */
664 	  if (ref || e->expr_type != EXPR_VARIABLE)
665 	    {
666 	      for (dim = 0; dim < e->rank; ++dim)
667 		gfc_conv_shift_descriptor_lbound (&block, parmse->expr, dim,
668 						  gfc_index_one_node);
669 	    }
670 
671 	  if (e->rank != class_ts.u.derived->components->as->rank)
672 	    {
673 	      gcc_assert (class_ts.u.derived->components->as->type
674 			  == AS_ASSUMED_RANK);
675 	      class_array_data_assign (&block, ctree, parmse->expr, false);
676 	    }
677 	  else
678 	    {
679 	      if (gfc_expr_attr (e).codimension)
680 		parmse->expr = fold_build1_loc (input_location,
681 						VIEW_CONVERT_EXPR,
682 						TREE_TYPE (ctree),
683 						parmse->expr);
684 	      gfc_add_modify (&block, ctree, parmse->expr);
685 	    }
686 
687 	  if (optional)
688 	    {
689 	      tmp = gfc_finish_block (&block);
690 
691 	      gfc_init_block (&block);
692 	      gfc_conv_descriptor_data_set (&block, ctree, null_pointer_node);
693 
694 	      tmp = build3_v (COND_EXPR, cond_optional, tmp,
695 			      gfc_finish_block (&block));
696 	      gfc_add_expr_to_block (&parmse->pre, tmp);
697 	    }
698 	  else
699 	    gfc_add_block_to_block (&parmse->pre, &block);
700 	}
701     }
702 
703   if (class_ts.u.derived->components->ts.type == BT_DERIVED
704       && class_ts.u.derived->components->ts.u.derived
705 		 ->attr.unlimited_polymorphic)
706     {
707       /* Take care about initializing the _len component correctly.  */
708       ctree = gfc_class_len_get (var);
709       if (UNLIMITED_POLY (e))
710 	{
711 	  gfc_expr *len;
712 	  gfc_se se;
713 
714 	  len = gfc_copy_expr (e);
715 	  gfc_add_len_component (len);
716 	  gfc_init_se (&se, NULL);
717 	  gfc_conv_expr (&se, len);
718 	  if (optional)
719 	    tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (se.expr),
720 			      cond_optional, se.expr,
721 			      fold_convert (TREE_TYPE (se.expr),
722 					    integer_zero_node));
723 	  else
724 	    tmp = se.expr;
725 	}
726       else
727 	tmp = integer_zero_node;
728       gfc_add_modify (&parmse->pre, ctree, fold_convert (TREE_TYPE (ctree),
729 							  tmp));
730     }
731   /* Pass the address of the class object.  */
732   parmse->expr = gfc_build_addr_expr (NULL_TREE, var);
733 
734   if (optional && optional_alloc_ptr)
735     parmse->expr = build3_loc (input_location, COND_EXPR,
736 			       TREE_TYPE (parmse->expr),
737 			       cond_optional, parmse->expr,
738 			       fold_convert (TREE_TYPE (parmse->expr),
739 					     null_pointer_node));
740 }
741 
742 
743 /* Create a new class container, which is required as scalar coarrays
744    have an array descriptor while normal scalars haven't. Optionally,
745    NULL pointer checks are added if the argument is OPTIONAL.  */
746 
747 static void
748 class_scalar_coarray_to_class (gfc_se *parmse, gfc_expr *e,
749 			       gfc_typespec class_ts, bool optional)
750 {
751   tree var, ctree, tmp;
752   stmtblock_t block;
753   gfc_ref *ref;
754   gfc_ref *class_ref;
755 
756   gfc_init_block (&block);
757 
758   class_ref = NULL;
759   for (ref = e->ref; ref; ref = ref->next)
760     {
761       if (ref->type == REF_COMPONENT
762 	    && ref->u.c.component->ts.type == BT_CLASS)
763 	class_ref = ref;
764     }
765 
766   if (class_ref == NULL
767 	&& e->symtree && e->symtree->n.sym->ts.type == BT_CLASS)
768     tmp = e->symtree->n.sym->backend_decl;
769   else
770     {
771       /* Remove everything after the last class reference, convert the
772 	 expression and then recover its tailend once more.  */
773       gfc_se tmpse;
774       ref = class_ref->next;
775       class_ref->next = NULL;
776       gfc_init_se (&tmpse, NULL);
777       gfc_conv_expr (&tmpse, e);
778       class_ref->next = ref;
779       tmp = tmpse.expr;
780     }
781 
782   var = gfc_typenode_for_spec (&class_ts);
783   var = gfc_create_var (var, "class");
784 
785   ctree = gfc_class_vptr_get (var);
786   gfc_add_modify (&block, ctree,
787 		  fold_convert (TREE_TYPE (ctree), gfc_class_vptr_get (tmp)));
788 
789   ctree = gfc_class_data_get (var);
790   tmp = gfc_conv_descriptor_data_get (gfc_class_data_get (tmp));
791   gfc_add_modify (&block, ctree, fold_convert (TREE_TYPE (ctree), tmp));
792 
793   /* Pass the address of the class object.  */
794   parmse->expr = gfc_build_addr_expr (NULL_TREE, var);
795 
796   if (optional)
797     {
798       tree cond = gfc_conv_expr_present (e->symtree->n.sym);
799       tree tmp2;
800 
801       tmp = gfc_finish_block (&block);
802 
803       gfc_init_block (&block);
804       tmp2 = gfc_class_data_get (var);
805       gfc_add_modify (&block, tmp2, fold_convert (TREE_TYPE (tmp2),
806 						  null_pointer_node));
807       tmp2 = gfc_finish_block (&block);
808 
809       tmp = build3_loc (input_location, COND_EXPR, void_type_node,
810 			cond, tmp, tmp2);
811       gfc_add_expr_to_block (&parmse->pre, tmp);
812     }
813   else
814     gfc_add_block_to_block (&parmse->pre, &block);
815 }
816 
817 
818 /* Takes an intrinsic type expression and returns the address of a temporary
819    class object of the 'declared' type.  */
820 void
821 gfc_conv_intrinsic_to_class (gfc_se *parmse, gfc_expr *e,
822 			     gfc_typespec class_ts)
823 {
824   gfc_symbol *vtab;
825   gfc_ss *ss;
826   tree ctree;
827   tree var;
828   tree tmp;
829 
830   /* The intrinsic type needs to be converted to a temporary
831      CLASS object.  */
832   tmp = gfc_typenode_for_spec (&class_ts);
833   var = gfc_create_var (tmp, "class");
834 
835   /* Set the vptr.  */
836   ctree = gfc_class_vptr_get (var);
837 
838   vtab = gfc_find_vtab (&e->ts);
839   gcc_assert (vtab);
840   tmp = gfc_build_addr_expr (NULL_TREE, gfc_get_symbol_decl (vtab));
841   gfc_add_modify (&parmse->pre, ctree,
842 		  fold_convert (TREE_TYPE (ctree), tmp));
843 
844   /* Now set the data field.  */
845   ctree = gfc_class_data_get (var);
846   if (parmse->ss && parmse->ss->info->useflags)
847     {
848       /* For an array reference in an elemental procedure call we need
849 	 to retain the ss to provide the scalarized array reference.  */
850       gfc_conv_expr_reference (parmse, e);
851       tmp = fold_convert (TREE_TYPE (ctree), parmse->expr);
852       gfc_add_modify (&parmse->pre, ctree, tmp);
853     }
854   else
855     {
856       ss = gfc_walk_expr (e);
857       if (ss == gfc_ss_terminator)
858 	{
859 	  parmse->ss = NULL;
860 	  gfc_conv_expr_reference (parmse, e);
861 	  if (class_ts.u.derived->components->as
862 	      && class_ts.u.derived->components->as->type == AS_ASSUMED_RANK)
863 	    {
864 	      tmp = gfc_conv_scalar_to_descriptor (parmse, parmse->expr,
865 						   gfc_expr_attr (e));
866 	      tmp = fold_build1_loc (input_location, VIEW_CONVERT_EXPR,
867 				     TREE_TYPE (ctree), tmp);
868 	    }
869 	  else
870 	      tmp = fold_convert (TREE_TYPE (ctree), parmse->expr);
871 	  gfc_add_modify (&parmse->pre, ctree, tmp);
872 	}
873       else
874 	{
875 	  parmse->ss = ss;
876 	  parmse->use_offset = 1;
877 	  gfc_conv_expr_descriptor (parmse, e);
878 	  if (class_ts.u.derived->components->as->rank != e->rank)
879 	    {
880 	      tmp = fold_build1_loc (input_location, VIEW_CONVERT_EXPR,
881 				     TREE_TYPE (ctree), parmse->expr);
882 	      gfc_add_modify (&parmse->pre, ctree, tmp);
883 	    }
884 	  else
885 	    gfc_add_modify (&parmse->pre, ctree, parmse->expr);
886 	}
887     }
888 
889   gcc_assert (class_ts.type == BT_CLASS);
890   if (class_ts.u.derived->components->ts.type == BT_DERIVED
891       && class_ts.u.derived->components->ts.u.derived
892 		 ->attr.unlimited_polymorphic)
893     {
894       ctree = gfc_class_len_get (var);
895       /* When the actual arg is a char array, then set the _len component of the
896 	 unlimited polymorphic entity to the length of the string.  */
897       if (e->ts.type == BT_CHARACTER)
898 	{
899 	  /* Start with parmse->string_length because this seems to be set to a
900 	   correct value more often.  */
901 	  if (parmse->string_length)
902 	    tmp = parmse->string_length;
903 	  /* When the string_length is not yet set, then try the backend_decl of
904 	   the cl.  */
905 	  else if (e->ts.u.cl->backend_decl)
906 	    tmp = e->ts.u.cl->backend_decl;
907 	  /* If both of the above approaches fail, then try to generate an
908 	   expression from the input, which is only feasible currently, when the
909 	   expression can be evaluated to a constant one.  */
910 	  else
911 	    {
912 	      /* Try to simplify the expression.  */
913 	      gfc_simplify_expr (e, 0);
914 	      if (e->expr_type == EXPR_CONSTANT && !e->ts.u.cl->resolved)
915 		{
916 		  /* Amazingly all data is present to compute the length of a
917 		   constant string, but the expression is not yet there.  */
918 		  e->ts.u.cl->length = gfc_get_constant_expr (BT_INTEGER,
919 							      gfc_charlen_int_kind,
920 							      &e->where);
921 		  mpz_set_ui (e->ts.u.cl->length->value.integer,
922 			      e->value.character.length);
923 		  gfc_conv_const_charlen (e->ts.u.cl);
924 		  e->ts.u.cl->resolved = 1;
925 		  tmp = e->ts.u.cl->backend_decl;
926 		}
927 	      else
928 		{
929 		  gfc_error ("Cannot compute the length of the char array "
930 			     "at %L.", &e->where);
931 		}
932 	    }
933 	}
934       else
935 	tmp = integer_zero_node;
936 
937       gfc_add_modify (&parmse->pre, ctree, fold_convert (TREE_TYPE (ctree), tmp));
938     }
939   else if (class_ts.type == BT_CLASS
940 	   && class_ts.u.derived->components
941 	   && class_ts.u.derived->components->ts.u
942 		.derived->attr.unlimited_polymorphic)
943     {
944       ctree = gfc_class_len_get (var);
945       gfc_add_modify (&parmse->pre, ctree,
946 		      fold_convert (TREE_TYPE (ctree),
947 				    integer_zero_node));
948     }
949   /* Pass the address of the class object.  */
950   parmse->expr = gfc_build_addr_expr (NULL_TREE, var);
951 }
952 
953 
954 /* Takes a scalarized class array expression and returns the
955    address of a temporary scalar class object of the 'declared'
956    type.
957    OOP-TODO: This could be improved by adding code that branched on
958    the dynamic type being the same as the declared type. In this case
959    the original class expression can be passed directly.
960    optional_alloc_ptr is false when the dummy is neither allocatable
961    nor a pointer; that's relevant for the optional handling.
962    Set copyback to true if class container's _data and _vtab pointers
963    might get modified.  */
964 
965 void
966 gfc_conv_class_to_class (gfc_se *parmse, gfc_expr *e, gfc_typespec class_ts,
967 			 bool elemental, bool copyback, bool optional,
968 		         bool optional_alloc_ptr)
969 {
970   tree ctree;
971   tree var;
972   tree tmp;
973   tree vptr;
974   tree cond = NULL_TREE;
975   tree slen = NULL_TREE;
976   gfc_ref *ref;
977   gfc_ref *class_ref;
978   stmtblock_t block;
979   bool full_array = false;
980 
981   gfc_init_block (&block);
982 
983   class_ref = NULL;
984   for (ref = e->ref; ref; ref = ref->next)
985     {
986       if (ref->type == REF_COMPONENT
987 	    && ref->u.c.component->ts.type == BT_CLASS)
988 	class_ref = ref;
989 
990       if (ref->next == NULL)
991 	break;
992     }
993 
994   if ((ref == NULL || class_ref == ref)
995       && !(gfc_is_class_array_function (e) && parmse->class_vptr != NULL_TREE)
996       && (!class_ts.u.derived->components->as
997 	  || class_ts.u.derived->components->as->rank != -1))
998     return;
999 
1000   /* Test for FULL_ARRAY.  */
1001   if (e->rank == 0 && gfc_expr_attr (e).codimension
1002       && gfc_expr_attr (e).dimension)
1003     full_array = true;
1004   else
1005     gfc_is_class_array_ref (e, &full_array);
1006 
1007   /* The derived type needs to be converted to a temporary
1008      CLASS object.  */
1009   tmp = gfc_typenode_for_spec (&class_ts);
1010   var = gfc_create_var (tmp, "class");
1011 
1012   /* Set the data.  */
1013   ctree = gfc_class_data_get (var);
1014   if (class_ts.u.derived->components->as
1015       && e->rank != class_ts.u.derived->components->as->rank)
1016     {
1017       if (e->rank == 0)
1018 	{
1019 	  tree type = get_scalar_to_descriptor_type (parmse->expr,
1020 						     gfc_expr_attr (e));
1021 	  gfc_add_modify (&block, gfc_conv_descriptor_dtype (ctree),
1022 			  gfc_get_dtype (type));
1023 
1024 	  tmp = gfc_class_data_get (parmse->expr);
1025 	  if (!POINTER_TYPE_P (TREE_TYPE (tmp)))
1026 	    tmp = gfc_build_addr_expr (NULL_TREE, tmp);
1027 
1028 	  gfc_conv_descriptor_data_set (&block, ctree, tmp);
1029 	}
1030       else
1031 	class_array_data_assign (&block, ctree, parmse->expr, false);
1032     }
1033   else
1034     {
1035       if (TREE_TYPE (parmse->expr) != TREE_TYPE (ctree))
1036 	parmse->expr = fold_build1_loc (input_location, VIEW_CONVERT_EXPR,
1037 					TREE_TYPE (ctree), parmse->expr);
1038       gfc_add_modify (&block, ctree, parmse->expr);
1039     }
1040 
1041   /* Return the data component, except in the case of scalarized array
1042      references, where nullification of the cannot occur and so there
1043      is no need.  */
1044   if (!elemental && full_array && copyback)
1045     {
1046       if (class_ts.u.derived->components->as
1047 	  && e->rank != class_ts.u.derived->components->as->rank)
1048 	{
1049 	  if (e->rank == 0)
1050 	    gfc_add_modify (&parmse->post, gfc_class_data_get (parmse->expr),
1051 			    gfc_conv_descriptor_data_get (ctree));
1052 	  else
1053 	    class_array_data_assign (&parmse->post, parmse->expr, ctree, true);
1054 	}
1055       else
1056 	gfc_add_modify (&parmse->post, parmse->expr, ctree);
1057     }
1058 
1059   /* Set the vptr.  */
1060   ctree = gfc_class_vptr_get (var);
1061 
1062   /* The vptr is the second field of the actual argument.
1063      First we have to find the corresponding class reference.  */
1064 
1065   tmp = NULL_TREE;
1066   if (gfc_is_class_array_function (e)
1067       && parmse->class_vptr != NULL_TREE)
1068     tmp = parmse->class_vptr;
1069   else if (class_ref == NULL
1070 	   && e->symtree && e->symtree->n.sym->ts.type == BT_CLASS)
1071     {
1072       tmp = e->symtree->n.sym->backend_decl;
1073 
1074       if (TREE_CODE (tmp) == FUNCTION_DECL)
1075 	tmp = gfc_get_fake_result_decl (e->symtree->n.sym, 0);
1076 
1077       if (DECL_LANG_SPECIFIC (tmp) && GFC_DECL_SAVED_DESCRIPTOR (tmp))
1078 	tmp = GFC_DECL_SAVED_DESCRIPTOR (tmp);
1079 
1080       slen = build_zero_cst (size_type_node);
1081     }
1082   else
1083     {
1084       /* Remove everything after the last class reference, convert the
1085 	 expression and then recover its tailend once more.  */
1086       gfc_se tmpse;
1087       ref = class_ref->next;
1088       class_ref->next = NULL;
1089       gfc_init_se (&tmpse, NULL);
1090       gfc_conv_expr (&tmpse, e);
1091       class_ref->next = ref;
1092       tmp = tmpse.expr;
1093       slen = tmpse.string_length;
1094     }
1095 
1096   gcc_assert (tmp != NULL_TREE);
1097 
1098   /* Dereference if needs be.  */
1099   if (TREE_CODE (TREE_TYPE (tmp)) == REFERENCE_TYPE)
1100     tmp = build_fold_indirect_ref_loc (input_location, tmp);
1101 
1102   if (!(gfc_is_class_array_function (e) && parmse->class_vptr))
1103     vptr = gfc_class_vptr_get (tmp);
1104   else
1105     vptr = tmp;
1106 
1107   gfc_add_modify (&block, ctree,
1108 		  fold_convert (TREE_TYPE (ctree), vptr));
1109 
1110   /* Return the vptr component, except in the case of scalarized array
1111      references, where the dynamic type cannot change.  */
1112   if (!elemental && full_array && copyback)
1113     gfc_add_modify (&parmse->post, vptr,
1114 		    fold_convert (TREE_TYPE (vptr), ctree));
1115 
1116   /* For unlimited polymorphic objects also set the _len component.  */
1117   if (class_ts.type == BT_CLASS
1118       && class_ts.u.derived->components
1119       && class_ts.u.derived->components->ts.u
1120 		      .derived->attr.unlimited_polymorphic)
1121     {
1122       ctree = gfc_class_len_get (var);
1123       if (UNLIMITED_POLY (e))
1124 	tmp = gfc_class_len_get (tmp);
1125       else if (e->ts.type == BT_CHARACTER)
1126 	{
1127 	  gcc_assert (slen != NULL_TREE);
1128 	  tmp = slen;
1129 	}
1130       else
1131 	tmp = build_zero_cst (size_type_node);
1132       gfc_add_modify (&parmse->pre, ctree,
1133 		      fold_convert (TREE_TYPE (ctree), tmp));
1134 
1135       /* Return the len component, except in the case of scalarized array
1136 	references, where the dynamic type cannot change.  */
1137       if (!elemental && full_array && copyback
1138 	  && (UNLIMITED_POLY (e) || VAR_P (tmp)))
1139 	  gfc_add_modify (&parmse->post, tmp,
1140 			  fold_convert (TREE_TYPE (tmp), ctree));
1141     }
1142 
1143   if (optional)
1144     {
1145       tree tmp2;
1146 
1147       cond = gfc_conv_expr_present (e->symtree->n.sym);
1148       /* parmse->pre may contain some preparatory instructions for the
1149  	 temporary array descriptor.  Those may only be executed when the
1150 	 optional argument is set, therefore add parmse->pre's instructions
1151 	 to block, which is later guarded by an if (optional_arg_given).  */
1152       gfc_add_block_to_block (&parmse->pre, &block);
1153       block.head = parmse->pre.head;
1154       parmse->pre.head = NULL_TREE;
1155       tmp = gfc_finish_block (&block);
1156 
1157       if (optional_alloc_ptr)
1158 	tmp2 = build_empty_stmt (input_location);
1159       else
1160 	{
1161 	  gfc_init_block (&block);
1162 
1163 	  tmp2 = gfc_conv_descriptor_data_get (gfc_class_data_get (var));
1164 	  gfc_add_modify (&block, tmp2, fold_convert (TREE_TYPE (tmp2),
1165 						      null_pointer_node));
1166 	  tmp2 = gfc_finish_block (&block);
1167 	}
1168 
1169       tmp = build3_loc (input_location, COND_EXPR, void_type_node,
1170 			cond, tmp, tmp2);
1171       gfc_add_expr_to_block (&parmse->pre, tmp);
1172     }
1173   else
1174     gfc_add_block_to_block (&parmse->pre, &block);
1175 
1176   /* Pass the address of the class object.  */
1177   parmse->expr = gfc_build_addr_expr (NULL_TREE, var);
1178 
1179   if (optional && optional_alloc_ptr)
1180     parmse->expr = build3_loc (input_location, COND_EXPR,
1181 			       TREE_TYPE (parmse->expr),
1182 			       cond, parmse->expr,
1183 			       fold_convert (TREE_TYPE (parmse->expr),
1184 					     null_pointer_node));
1185 }
1186 
1187 
1188 /* Given a class array declaration and an index, returns the address
1189    of the referenced element.  */
1190 
1191 tree
1192 gfc_get_class_array_ref (tree index, tree class_decl, tree data_comp,
1193 			 bool unlimited)
1194 {
1195   tree data, size, tmp, ctmp, offset, ptr;
1196 
1197   data = data_comp != NULL_TREE ? data_comp :
1198 				  gfc_class_data_get (class_decl);
1199   size = gfc_class_vtab_size_get (class_decl);
1200 
1201   if (unlimited)
1202     {
1203       tmp = fold_convert (gfc_array_index_type,
1204 			  gfc_class_len_get (class_decl));
1205       ctmp = fold_build2_loc (input_location, MULT_EXPR,
1206 			      gfc_array_index_type, size, tmp);
1207       tmp = fold_build2_loc (input_location, GT_EXPR,
1208 			     logical_type_node, tmp,
1209 			     build_zero_cst (TREE_TYPE (tmp)));
1210       size = fold_build3_loc (input_location, COND_EXPR,
1211 			      gfc_array_index_type, tmp, ctmp, size);
1212     }
1213 
1214   offset = fold_build2_loc (input_location, MULT_EXPR,
1215 			    gfc_array_index_type,
1216 			    index, size);
1217 
1218   data = gfc_conv_descriptor_data_get (data);
1219   ptr = fold_convert (pvoid_type_node, data);
1220   ptr = fold_build_pointer_plus_loc (input_location, ptr, offset);
1221   return fold_convert (TREE_TYPE (data), ptr);
1222 }
1223 
1224 
1225 /* Copies one class expression to another, assuming that if either
1226    'to' or 'from' are arrays they are packed.  Should 'from' be
1227    NULL_TREE, the initialization expression for 'to' is used, assuming
1228    that the _vptr is set.  */
1229 
1230 tree
1231 gfc_copy_class_to_class (tree from, tree to, tree nelems, bool unlimited)
1232 {
1233   tree fcn;
1234   tree fcn_type;
1235   tree from_data;
1236   tree from_len;
1237   tree to_data;
1238   tree to_len;
1239   tree to_ref;
1240   tree from_ref;
1241   vec<tree, va_gc> *args;
1242   tree tmp;
1243   tree stdcopy;
1244   tree extcopy;
1245   tree index;
1246   bool is_from_desc = false, is_to_class = false;
1247 
1248   args = NULL;
1249   /* To prevent warnings on uninitialized variables.  */
1250   from_len = to_len = NULL_TREE;
1251 
1252   if (from != NULL_TREE)
1253     fcn = gfc_class_vtab_copy_get (from);
1254   else
1255     fcn = gfc_class_vtab_copy_get (to);
1256 
1257   fcn_type = TREE_TYPE (TREE_TYPE (fcn));
1258 
1259   if (from != NULL_TREE)
1260     {
1261       is_from_desc = GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (from));
1262       if (is_from_desc)
1263 	{
1264 	  from_data = from;
1265 	  from = GFC_DECL_SAVED_DESCRIPTOR (from);
1266 	}
1267       else
1268 	{
1269 	  /* Check that from is a class.  When the class is part of a coarray,
1270 	     then from is a common pointer and is to be used as is.  */
1271 	  tmp = POINTER_TYPE_P (TREE_TYPE (from))
1272 	      ? build_fold_indirect_ref (from) : from;
1273 	  from_data =
1274 	      (GFC_CLASS_TYPE_P (TREE_TYPE (tmp))
1275 	       || (DECL_P (tmp) && GFC_DECL_CLASS (tmp)))
1276 	      ? gfc_class_data_get (from) : from;
1277 	  is_from_desc = GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (from_data));
1278 	}
1279      }
1280   else
1281     from_data = gfc_class_vtab_def_init_get (to);
1282 
1283   if (unlimited)
1284     {
1285       if (from != NULL_TREE && unlimited)
1286 	from_len = gfc_class_len_or_zero_get (from);
1287       else
1288 	from_len = build_zero_cst (size_type_node);
1289     }
1290 
1291   if (GFC_CLASS_TYPE_P (TREE_TYPE (to)))
1292     {
1293       is_to_class = true;
1294       to_data = gfc_class_data_get (to);
1295       if (unlimited)
1296 	to_len = gfc_class_len_get (to);
1297     }
1298   else
1299     /* When to is a BT_DERIVED and not a BT_CLASS, then to_data == to.  */
1300     to_data = to;
1301 
1302   if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (to_data)))
1303     {
1304       stmtblock_t loopbody;
1305       stmtblock_t body;
1306       stmtblock_t ifbody;
1307       gfc_loopinfo loop;
1308       tree orig_nelems = nelems; /* Needed for bounds check.  */
1309 
1310       gfc_init_block (&body);
1311       tmp = fold_build2_loc (input_location, MINUS_EXPR,
1312 			     gfc_array_index_type, nelems,
1313 			     gfc_index_one_node);
1314       nelems = gfc_evaluate_now (tmp, &body);
1315       index = gfc_create_var (gfc_array_index_type, "S");
1316 
1317       if (is_from_desc)
1318 	{
1319 	  from_ref = gfc_get_class_array_ref (index, from, from_data,
1320 					      unlimited);
1321 	  vec_safe_push (args, from_ref);
1322 	}
1323       else
1324         vec_safe_push (args, from_data);
1325 
1326       if (is_to_class)
1327 	to_ref = gfc_get_class_array_ref (index, to, to_data, unlimited);
1328       else
1329 	{
1330 	  tmp = gfc_conv_array_data (to);
1331 	  tmp = build_fold_indirect_ref_loc (input_location, tmp);
1332 	  to_ref = gfc_build_addr_expr (NULL_TREE,
1333 					gfc_build_array_ref (tmp, index, to));
1334 	}
1335       vec_safe_push (args, to_ref);
1336 
1337       /* Add bounds check.  */
1338       if ((gfc_option.rtcheck & GFC_RTCHECK_BOUNDS) > 0 && is_from_desc)
1339 	{
1340 	  char *msg;
1341 	  const char *name = "<<unknown>>";
1342 	  tree from_len;
1343 
1344 	  if (DECL_P (to))
1345 	    name = (const char *)(DECL_NAME (to)->identifier.id.str);
1346 
1347 	  from_len = gfc_conv_descriptor_size (from_data, 1);
1348 	  tmp = fold_build2_loc (input_location, NE_EXPR,
1349 				  logical_type_node, from_len, orig_nelems);
1350 	  msg = xasprintf ("Array bound mismatch for dimension %d "
1351 			   "of array '%s' (%%ld/%%ld)",
1352 			   1, name);
1353 
1354 	  gfc_trans_runtime_check (true, false, tmp, &body,
1355 				   &gfc_current_locus, msg,
1356 			     fold_convert (long_integer_type_node, orig_nelems),
1357 			       fold_convert (long_integer_type_node, from_len));
1358 
1359 	  free (msg);
1360 	}
1361 
1362       tmp = build_call_vec (fcn_type, fcn, args);
1363 
1364       /* Build the body of the loop.  */
1365       gfc_init_block (&loopbody);
1366       gfc_add_expr_to_block (&loopbody, tmp);
1367 
1368       /* Build the loop and return.  */
1369       gfc_init_loopinfo (&loop);
1370       loop.dimen = 1;
1371       loop.from[0] = gfc_index_zero_node;
1372       loop.loopvar[0] = index;
1373       loop.to[0] = nelems;
1374       gfc_trans_scalarizing_loops (&loop, &loopbody);
1375       gfc_init_block (&ifbody);
1376       gfc_add_block_to_block (&ifbody, &loop.pre);
1377       stdcopy = gfc_finish_block (&ifbody);
1378       /* In initialization mode from_len is a constant zero.  */
1379       if (unlimited && !integer_zerop (from_len))
1380 	{
1381 	  vec_safe_push (args, from_len);
1382 	  vec_safe_push (args, to_len);
1383 	  tmp = build_call_vec (fcn_type, fcn, args);
1384 	  /* Build the body of the loop.  */
1385 	  gfc_init_block (&loopbody);
1386 	  gfc_add_expr_to_block (&loopbody, tmp);
1387 
1388 	  /* Build the loop and return.  */
1389 	  gfc_init_loopinfo (&loop);
1390 	  loop.dimen = 1;
1391 	  loop.from[0] = gfc_index_zero_node;
1392 	  loop.loopvar[0] = index;
1393 	  loop.to[0] = nelems;
1394 	  gfc_trans_scalarizing_loops (&loop, &loopbody);
1395 	  gfc_init_block (&ifbody);
1396 	  gfc_add_block_to_block (&ifbody, &loop.pre);
1397 	  extcopy = gfc_finish_block (&ifbody);
1398 
1399 	  tmp = fold_build2_loc (input_location, GT_EXPR,
1400 				 logical_type_node, from_len,
1401 				 build_zero_cst (TREE_TYPE (from_len)));
1402 	  tmp = fold_build3_loc (input_location, COND_EXPR,
1403 				 void_type_node, tmp, extcopy, stdcopy);
1404 	  gfc_add_expr_to_block (&body, tmp);
1405 	  tmp = gfc_finish_block (&body);
1406 	}
1407       else
1408 	{
1409 	  gfc_add_expr_to_block (&body, stdcopy);
1410 	  tmp = gfc_finish_block (&body);
1411 	}
1412       gfc_cleanup_loop (&loop);
1413     }
1414   else
1415     {
1416       gcc_assert (!is_from_desc);
1417       vec_safe_push (args, from_data);
1418       vec_safe_push (args, to_data);
1419       stdcopy = build_call_vec (fcn_type, fcn, args);
1420 
1421       /* In initialization mode from_len is a constant zero.  */
1422       if (unlimited && !integer_zerop (from_len))
1423 	{
1424 	  vec_safe_push (args, from_len);
1425 	  vec_safe_push (args, to_len);
1426 	  extcopy = build_call_vec (fcn_type, fcn, args);
1427 	  tmp = fold_build2_loc (input_location, GT_EXPR,
1428 				 logical_type_node, from_len,
1429 				 build_zero_cst (TREE_TYPE (from_len)));
1430 	  tmp = fold_build3_loc (input_location, COND_EXPR,
1431 				 void_type_node, tmp, extcopy, stdcopy);
1432 	}
1433       else
1434 	tmp = stdcopy;
1435     }
1436 
1437   /* Only copy _def_init to to_data, when it is not a NULL-pointer.  */
1438   if (from == NULL_TREE)
1439     {
1440       tree cond;
1441       cond = fold_build2_loc (input_location, NE_EXPR,
1442 			      logical_type_node,
1443 			      from_data, null_pointer_node);
1444       tmp = fold_build3_loc (input_location, COND_EXPR,
1445 			     void_type_node, cond,
1446 			     tmp, build_empty_stmt (input_location));
1447     }
1448 
1449   return tmp;
1450 }
1451 
1452 
1453 static tree
1454 gfc_trans_class_array_init_assign (gfc_expr *rhs, gfc_expr *lhs, gfc_expr *obj)
1455 {
1456   gfc_actual_arglist *actual;
1457   gfc_expr *ppc;
1458   gfc_code *ppc_code;
1459   tree res;
1460 
1461   actual = gfc_get_actual_arglist ();
1462   actual->expr = gfc_copy_expr (rhs);
1463   actual->next = gfc_get_actual_arglist ();
1464   actual->next->expr = gfc_copy_expr (lhs);
1465   ppc = gfc_copy_expr (obj);
1466   gfc_add_vptr_component (ppc);
1467   gfc_add_component_ref (ppc, "_copy");
1468   ppc_code = gfc_get_code (EXEC_CALL);
1469   ppc_code->resolved_sym = ppc->symtree->n.sym;
1470   /* Although '_copy' is set to be elemental in class.c, it is
1471      not staying that way.  Find out why, sometime....  */
1472   ppc_code->resolved_sym->attr.elemental = 1;
1473   ppc_code->ext.actual = actual;
1474   ppc_code->expr1 = ppc;
1475   /* Since '_copy' is elemental, the scalarizer will take care
1476      of arrays in gfc_trans_call.  */
1477   res = gfc_trans_call (ppc_code, false, NULL, NULL, false);
1478   gfc_free_statements (ppc_code);
1479 
1480   if (UNLIMITED_POLY(obj))
1481     {
1482       /* Check if rhs is non-NULL. */
1483       gfc_se src;
1484       gfc_init_se (&src, NULL);
1485       gfc_conv_expr (&src, rhs);
1486       src.expr = gfc_build_addr_expr (NULL_TREE, src.expr);
1487       tree cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
1488 				   src.expr, fold_convert (TREE_TYPE (src.expr),
1489 							   null_pointer_node));
1490       res = build3_loc (input_location, COND_EXPR, TREE_TYPE (res), cond, res,
1491 			build_empty_stmt (input_location));
1492     }
1493 
1494   return res;
1495 }
1496 
1497 /* Special case for initializing a polymorphic dummy with INTENT(OUT).
1498    A MEMCPY is needed to copy the full data from the default initializer
1499    of the dynamic type.  */
1500 
1501 tree
1502 gfc_trans_class_init_assign (gfc_code *code)
1503 {
1504   stmtblock_t block;
1505   tree tmp;
1506   gfc_se dst,src,memsz;
1507   gfc_expr *lhs, *rhs, *sz;
1508 
1509   gfc_start_block (&block);
1510 
1511   lhs = gfc_copy_expr (code->expr1);
1512 
1513   rhs = gfc_copy_expr (code->expr1);
1514   gfc_add_vptr_component (rhs);
1515 
1516   /* Make sure that the component backend_decls have been built, which
1517      will not have happened if the derived types concerned have not
1518      been referenced.  */
1519   gfc_get_derived_type (rhs->ts.u.derived);
1520   gfc_add_def_init_component (rhs);
1521   /* The _def_init is always scalar.  */
1522   rhs->rank = 0;
1523 
1524   if (code->expr1->ts.type == BT_CLASS
1525       && CLASS_DATA (code->expr1)->attr.dimension)
1526     {
1527       gfc_array_spec *tmparr = gfc_get_array_spec ();
1528       *tmparr = *CLASS_DATA (code->expr1)->as;
1529       /* Adding the array ref to the class expression results in correct
1530 	 indexing to the dynamic type.  */
1531       gfc_add_full_array_ref (lhs, tmparr);
1532       tmp = gfc_trans_class_array_init_assign (rhs, lhs, code->expr1);
1533     }
1534   else
1535     {
1536       /* Scalar initialization needs the _data component.  */
1537       gfc_add_data_component (lhs);
1538       sz = gfc_copy_expr (code->expr1);
1539       gfc_add_vptr_component (sz);
1540       gfc_add_size_component (sz);
1541 
1542       gfc_init_se (&dst, NULL);
1543       gfc_init_se (&src, NULL);
1544       gfc_init_se (&memsz, NULL);
1545       gfc_conv_expr (&dst, lhs);
1546       gfc_conv_expr (&src, rhs);
1547       gfc_conv_expr (&memsz, sz);
1548       gfc_add_block_to_block (&block, &src.pre);
1549       src.expr = gfc_build_addr_expr (NULL_TREE, src.expr);
1550 
1551       tmp = gfc_build_memcpy_call (dst.expr, src.expr, memsz.expr);
1552 
1553       if (UNLIMITED_POLY(code->expr1))
1554 	{
1555 	  /* Check if _def_init is non-NULL. */
1556 	  tree cond = fold_build2_loc (input_location, NE_EXPR,
1557 				       logical_type_node, src.expr,
1558 				       fold_convert (TREE_TYPE (src.expr),
1559 						     null_pointer_node));
1560 	  tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp), cond,
1561 			    tmp, build_empty_stmt (input_location));
1562 	}
1563     }
1564 
1565   if (code->expr1->symtree->n.sym->attr.optional
1566       || code->expr1->symtree->n.sym->ns->proc_name->attr.entry_master)
1567     {
1568       tree present = gfc_conv_expr_present (code->expr1->symtree->n.sym);
1569       tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp),
1570 			present, tmp,
1571 			build_empty_stmt (input_location));
1572     }
1573 
1574   gfc_add_expr_to_block (&block, tmp);
1575 
1576   return gfc_finish_block (&block);
1577 }
1578 
1579 
1580 /* End of prototype trans-class.c  */
1581 
1582 
1583 static void
1584 realloc_lhs_warning (bt type, bool array, locus *where)
1585 {
1586   if (array && type != BT_CLASS && type != BT_DERIVED && warn_realloc_lhs)
1587     gfc_warning (OPT_Wrealloc_lhs,
1588 		 "Code for reallocating the allocatable array at %L will "
1589 		 "be added", where);
1590   else if (warn_realloc_lhs_all)
1591     gfc_warning (OPT_Wrealloc_lhs_all,
1592 		 "Code for reallocating the allocatable variable at %L "
1593 		 "will be added", where);
1594 }
1595 
1596 
1597 static void gfc_apply_interface_mapping_to_expr (gfc_interface_mapping *,
1598 						 gfc_expr *);
1599 
1600 /* Copy the scalarization loop variables.  */
1601 
1602 static void
1603 gfc_copy_se_loopvars (gfc_se * dest, gfc_se * src)
1604 {
1605   dest->ss = src->ss;
1606   dest->loop = src->loop;
1607 }
1608 
1609 
1610 /* Initialize a simple expression holder.
1611 
1612    Care must be taken when multiple se are created with the same parent.
1613    The child se must be kept in sync.  The easiest way is to delay creation
1614    of a child se until after after the previous se has been translated.  */
1615 
1616 void
1617 gfc_init_se (gfc_se * se, gfc_se * parent)
1618 {
1619   memset (se, 0, sizeof (gfc_se));
1620   gfc_init_block (&se->pre);
1621   gfc_init_block (&se->post);
1622 
1623   se->parent = parent;
1624 
1625   if (parent)
1626     gfc_copy_se_loopvars (se, parent);
1627 }
1628 
1629 
1630 /* Advances to the next SS in the chain.  Use this rather than setting
1631    se->ss = se->ss->next because all the parents needs to be kept in sync.
1632    See gfc_init_se.  */
1633 
1634 void
1635 gfc_advance_se_ss_chain (gfc_se * se)
1636 {
1637   gfc_se *p;
1638   gfc_ss *ss;
1639 
1640   gcc_assert (se != NULL && se->ss != NULL && se->ss != gfc_ss_terminator);
1641 
1642   p = se;
1643   /* Walk down the parent chain.  */
1644   while (p != NULL)
1645     {
1646       /* Simple consistency check.  */
1647       gcc_assert (p->parent == NULL || p->parent->ss == p->ss
1648 		  || p->parent->ss->nested_ss == p->ss);
1649 
1650       /* If we were in a nested loop, the next scalarized expression can be
1651 	 on the parent ss' next pointer.  Thus we should not take the next
1652 	 pointer blindly, but rather go up one nest level as long as next
1653 	 is the end of chain.  */
1654       ss = p->ss;
1655       while (ss->next == gfc_ss_terminator && ss->parent != NULL)
1656 	ss = ss->parent;
1657 
1658       p->ss = ss->next;
1659 
1660       p = p->parent;
1661     }
1662 }
1663 
1664 
1665 /* Ensures the result of the expression as either a temporary variable
1666    or a constant so that it can be used repeatedly.  */
1667 
1668 void
1669 gfc_make_safe_expr (gfc_se * se)
1670 {
1671   tree var;
1672 
1673   if (CONSTANT_CLASS_P (se->expr))
1674     return;
1675 
1676   /* We need a temporary for this result.  */
1677   var = gfc_create_var (TREE_TYPE (se->expr), NULL);
1678   gfc_add_modify (&se->pre, var, se->expr);
1679   se->expr = var;
1680 }
1681 
1682 
1683 /* Return an expression which determines if a dummy parameter is present.
1684    Also used for arguments to procedures with multiple entry points.  */
1685 
1686 tree
1687 gfc_conv_expr_present (gfc_symbol * sym)
1688 {
1689   tree decl, cond;
1690 
1691   gcc_assert (sym->attr.dummy);
1692   decl = gfc_get_symbol_decl (sym);
1693 
1694   /* Intrinsic scalars with VALUE attribute which are passed by value
1695      use a hidden argument to denote the present status.  */
1696   if (sym->attr.value && sym->ts.type != BT_CHARACTER
1697       && sym->ts.type != BT_CLASS && sym->ts.type != BT_DERIVED
1698       && !sym->attr.dimension)
1699     {
1700       char name[GFC_MAX_SYMBOL_LEN + 2];
1701       tree tree_name;
1702 
1703       gcc_assert (TREE_CODE (decl) == PARM_DECL);
1704       name[0] = '_';
1705       strcpy (&name[1], sym->name);
1706       tree_name = get_identifier (name);
1707 
1708       /* Walk function argument list to find hidden arg.  */
1709       cond = DECL_ARGUMENTS (DECL_CONTEXT (decl));
1710       for ( ; cond != NULL_TREE; cond = TREE_CHAIN (cond))
1711 	if (DECL_NAME (cond) == tree_name)
1712 	  break;
1713 
1714       gcc_assert (cond);
1715       return cond;
1716     }
1717 
1718   if (TREE_CODE (decl) != PARM_DECL)
1719     {
1720       /* Array parameters use a temporary descriptor, we want the real
1721          parameter.  */
1722       gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl))
1723              || GFC_ARRAY_TYPE_P (TREE_TYPE (decl)));
1724       decl = GFC_DECL_SAVED_DESCRIPTOR (decl);
1725     }
1726 
1727   cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node, decl,
1728 			  fold_convert (TREE_TYPE (decl), null_pointer_node));
1729 
1730   /* Fortran 2008 allows to pass null pointers and non-associated pointers
1731      as actual argument to denote absent dummies. For array descriptors,
1732      we thus also need to check the array descriptor.  For BT_CLASS, it
1733      can also occur for scalars and F2003 due to type->class wrapping and
1734      class->class wrapping.  Note further that BT_CLASS always uses an
1735      array descriptor for arrays, also for explicit-shape/assumed-size.  */
1736 
1737   if (!sym->attr.allocatable
1738       && ((sym->ts.type != BT_CLASS && !sym->attr.pointer)
1739 	  || (sym->ts.type == BT_CLASS
1740 	      && !CLASS_DATA (sym)->attr.allocatable
1741 	      && !CLASS_DATA (sym)->attr.class_pointer))
1742       && ((gfc_option.allow_std & GFC_STD_F2008) != 0
1743 	  || sym->ts.type == BT_CLASS))
1744     {
1745       tree tmp;
1746 
1747       if ((sym->as && (sym->as->type == AS_ASSUMED_SHAPE
1748 		       || sym->as->type == AS_ASSUMED_RANK
1749 		       || sym->attr.codimension))
1750 	  || (sym->ts.type == BT_CLASS && CLASS_DATA (sym)->as))
1751 	{
1752 	  tmp = build_fold_indirect_ref_loc (input_location, decl);
1753 	  if (sym->ts.type == BT_CLASS)
1754 	    tmp = gfc_class_data_get (tmp);
1755 	  tmp = gfc_conv_array_data (tmp);
1756 	}
1757       else if (sym->ts.type == BT_CLASS)
1758 	tmp = gfc_class_data_get (decl);
1759       else
1760 	tmp = NULL_TREE;
1761 
1762       if (tmp != NULL_TREE)
1763 	{
1764 	  tmp = fold_build2_loc (input_location, NE_EXPR, logical_type_node, tmp,
1765 				 fold_convert (TREE_TYPE (tmp), null_pointer_node));
1766 	  cond = fold_build2_loc (input_location, TRUTH_ANDIF_EXPR,
1767 				  logical_type_node, cond, tmp);
1768 	}
1769     }
1770 
1771   return cond;
1772 }
1773 
1774 
1775 /* Converts a missing, dummy argument into a null or zero.  */
1776 
1777 void
1778 gfc_conv_missing_dummy (gfc_se * se, gfc_expr * arg, gfc_typespec ts, int kind)
1779 {
1780   tree present;
1781   tree tmp;
1782 
1783   present = gfc_conv_expr_present (arg->symtree->n.sym);
1784 
1785   if (kind > 0)
1786     {
1787       /* Create a temporary and convert it to the correct type.  */
1788       tmp = gfc_get_int_type (kind);
1789       tmp = fold_convert (tmp, build_fold_indirect_ref_loc (input_location,
1790 							se->expr));
1791 
1792       /* Test for a NULL value.  */
1793       tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp), present,
1794 			tmp, fold_convert (TREE_TYPE (tmp), integer_one_node));
1795       tmp = gfc_evaluate_now (tmp, &se->pre);
1796       se->expr = gfc_build_addr_expr (NULL_TREE, tmp);
1797     }
1798   else
1799     {
1800       tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (se->expr),
1801 			present, se->expr,
1802 			build_zero_cst (TREE_TYPE (se->expr)));
1803       tmp = gfc_evaluate_now (tmp, &se->pre);
1804       se->expr = tmp;
1805     }
1806 
1807   if (ts.type == BT_CHARACTER)
1808     {
1809       tmp = build_int_cst (gfc_charlen_type_node, 0);
1810       tmp = fold_build3_loc (input_location, COND_EXPR, gfc_charlen_type_node,
1811 			     present, se->string_length, tmp);
1812       tmp = gfc_evaluate_now (tmp, &se->pre);
1813       se->string_length = tmp;
1814     }
1815   return;
1816 }
1817 
1818 
1819 /* Get the character length of an expression, looking through gfc_refs
1820    if necessary.  */
1821 
1822 tree
1823 gfc_get_expr_charlen (gfc_expr *e)
1824 {
1825   gfc_ref *r;
1826   tree length;
1827   gfc_se se;
1828 
1829   gcc_assert (e->expr_type == EXPR_VARIABLE
1830 	      && e->ts.type == BT_CHARACTER);
1831 
1832   length = NULL; /* To silence compiler warning.  */
1833 
1834   if (is_subref_array (e) && e->ts.u.cl->length)
1835     {
1836       gfc_se tmpse;
1837       gfc_init_se (&tmpse, NULL);
1838       gfc_conv_expr_type (&tmpse, e->ts.u.cl->length, gfc_charlen_type_node);
1839       e->ts.u.cl->backend_decl = tmpse.expr;
1840       return tmpse.expr;
1841     }
1842 
1843   /* First candidate: if the variable is of type CHARACTER, the
1844      expression's length could be the length of the character
1845      variable.  */
1846   if (e->symtree->n.sym->ts.type == BT_CHARACTER)
1847     length = e->symtree->n.sym->ts.u.cl->backend_decl;
1848 
1849   /* Look through the reference chain for component references.  */
1850   for (r = e->ref; r; r = r->next)
1851     {
1852       switch (r->type)
1853 	{
1854 	case REF_COMPONENT:
1855 	  if (r->u.c.component->ts.type == BT_CHARACTER)
1856 	    length = r->u.c.component->ts.u.cl->backend_decl;
1857 	  break;
1858 
1859 	case REF_ARRAY:
1860 	  /* Do nothing.  */
1861 	  break;
1862 
1863 	case REF_SUBSTRING:
1864 	  gfc_init_se (&se, NULL);
1865 	  gfc_conv_expr_type (&se, r->u.ss.start, gfc_charlen_type_node);
1866 	  length = se.expr;
1867 	  gfc_conv_expr_type (&se, r->u.ss.end, gfc_charlen_type_node);
1868 	  length = fold_build2_loc (input_location, MINUS_EXPR,
1869 				    gfc_charlen_type_node,
1870 				    se.expr, length);
1871 	  length = fold_build2_loc (input_location, PLUS_EXPR,
1872 				    gfc_charlen_type_node, length,
1873 				    gfc_index_one_node);
1874 	  break;
1875 
1876 	default:
1877 	  gcc_unreachable ();
1878 	  break;
1879 	}
1880     }
1881 
1882   gcc_assert (length != NULL);
1883   return length;
1884 }
1885 
1886 
1887 /* Return for an expression the backend decl of the coarray.  */
1888 
1889 tree
1890 gfc_get_tree_for_caf_expr (gfc_expr *expr)
1891 {
1892   tree caf_decl;
1893   bool found = false;
1894   gfc_ref *ref;
1895 
1896   gcc_assert (expr && expr->expr_type == EXPR_VARIABLE);
1897 
1898   /* Not-implemented diagnostic.  */
1899   if (expr->symtree->n.sym->ts.type == BT_CLASS
1900       && UNLIMITED_POLY (expr->symtree->n.sym)
1901       && CLASS_DATA (expr->symtree->n.sym)->attr.codimension)
1902     gfc_error ("Sorry, coindexed access to an unlimited polymorphic object at "
1903 	       "%L is not supported", &expr->where);
1904 
1905   for (ref = expr->ref; ref; ref = ref->next)
1906     if (ref->type == REF_COMPONENT)
1907       {
1908 	if (ref->u.c.component->ts.type == BT_CLASS
1909 	    && UNLIMITED_POLY (ref->u.c.component)
1910 	    && CLASS_DATA (ref->u.c.component)->attr.codimension)
1911 	  gfc_error ("Sorry, coindexed access to an unlimited polymorphic "
1912 		     "component at %L is not supported", &expr->where);
1913       }
1914 
1915   /* Make sure the backend_decl is present before accessing it.  */
1916   caf_decl = expr->symtree->n.sym->backend_decl == NULL_TREE
1917       ? gfc_get_symbol_decl (expr->symtree->n.sym)
1918       : expr->symtree->n.sym->backend_decl;
1919 
1920   if (expr->symtree->n.sym->ts.type == BT_CLASS)
1921     {
1922       if (expr->ref && expr->ref->type == REF_ARRAY)
1923 	{
1924 	  caf_decl = gfc_class_data_get (caf_decl);
1925 	  if (CLASS_DATA (expr->symtree->n.sym)->attr.codimension)
1926 	    return caf_decl;
1927 	}
1928       for (ref = expr->ref; ref; ref = ref->next)
1929 	{
1930 	  if (ref->type == REF_COMPONENT
1931 	      && strcmp (ref->u.c.component->name, "_data") != 0)
1932 	    {
1933 	      caf_decl = gfc_class_data_get (caf_decl);
1934 	      if (CLASS_DATA (expr->symtree->n.sym)->attr.codimension)
1935 		return caf_decl;
1936 	      break;
1937 	    }
1938 	  else if (ref->type == REF_ARRAY && ref->u.ar.dimen)
1939 	    break;
1940 	}
1941     }
1942   if (expr->symtree->n.sym->attr.codimension)
1943     return caf_decl;
1944 
1945   /* The following code assumes that the coarray is a component reachable via
1946      only scalar components/variables; the Fortran standard guarantees this.  */
1947 
1948   for (ref = expr->ref; ref; ref = ref->next)
1949     if (ref->type == REF_COMPONENT)
1950       {
1951 	gfc_component *comp = ref->u.c.component;
1952 
1953 	if (POINTER_TYPE_P (TREE_TYPE (caf_decl)))
1954 	  caf_decl = build_fold_indirect_ref_loc (input_location, caf_decl);
1955 	caf_decl = fold_build3_loc (input_location, COMPONENT_REF,
1956 				    TREE_TYPE (comp->backend_decl), caf_decl,
1957 				    comp->backend_decl, NULL_TREE);
1958 	if (comp->ts.type == BT_CLASS)
1959 	  {
1960 	    caf_decl = gfc_class_data_get (caf_decl);
1961 	    if (CLASS_DATA (comp)->attr.codimension)
1962 	      {
1963 		found = true;
1964 		break;
1965 	      }
1966 	  }
1967 	if (comp->attr.codimension)
1968 	  {
1969 	    found = true;
1970 	    break;
1971 	  }
1972       }
1973   gcc_assert (found && caf_decl);
1974   return caf_decl;
1975 }
1976 
1977 
1978 /* Obtain the Coarray token - and optionally also the offset.  */
1979 
1980 void
1981 gfc_get_caf_token_offset (gfc_se *se, tree *token, tree *offset, tree caf_decl,
1982 			  tree se_expr, gfc_expr *expr)
1983 {
1984   tree tmp;
1985 
1986   /* Coarray token.  */
1987   if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (caf_decl)))
1988     {
1989       gcc_assert (GFC_TYPE_ARRAY_AKIND (TREE_TYPE (caf_decl))
1990 		    == GFC_ARRAY_ALLOCATABLE
1991 		  || expr->symtree->n.sym->attr.select_type_temporary);
1992       *token = gfc_conv_descriptor_token (caf_decl);
1993     }
1994   else if (DECL_LANG_SPECIFIC (caf_decl)
1995 	   && GFC_DECL_TOKEN (caf_decl) != NULL_TREE)
1996     *token = GFC_DECL_TOKEN (caf_decl);
1997   else
1998     {
1999       gcc_assert (GFC_ARRAY_TYPE_P (TREE_TYPE (caf_decl))
2000 		  && GFC_TYPE_ARRAY_CAF_TOKEN (TREE_TYPE (caf_decl)) != NULL_TREE);
2001       *token = GFC_TYPE_ARRAY_CAF_TOKEN (TREE_TYPE (caf_decl));
2002     }
2003 
2004   if (offset == NULL)
2005     return;
2006 
2007   /* Offset between the coarray base address and the address wanted.  */
2008   if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (caf_decl))
2009       && (GFC_TYPE_ARRAY_AKIND (TREE_TYPE (caf_decl)) == GFC_ARRAY_ALLOCATABLE
2010 	  || GFC_TYPE_ARRAY_AKIND (TREE_TYPE (caf_decl)) == GFC_ARRAY_POINTER))
2011     *offset = build_int_cst (gfc_array_index_type, 0);
2012   else if (DECL_LANG_SPECIFIC (caf_decl)
2013 	   && GFC_DECL_CAF_OFFSET (caf_decl) != NULL_TREE)
2014     *offset = GFC_DECL_CAF_OFFSET (caf_decl);
2015   else if (GFC_TYPE_ARRAY_CAF_OFFSET (TREE_TYPE (caf_decl)) != NULL_TREE)
2016     *offset = GFC_TYPE_ARRAY_CAF_OFFSET (TREE_TYPE (caf_decl));
2017   else
2018     *offset = build_int_cst (gfc_array_index_type, 0);
2019 
2020   if (POINTER_TYPE_P (TREE_TYPE (se_expr))
2021       && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (TREE_TYPE (se_expr))))
2022     {
2023       tmp = build_fold_indirect_ref_loc (input_location, se_expr);
2024       tmp = gfc_conv_descriptor_data_get (tmp);
2025     }
2026   else if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se_expr)))
2027     tmp = gfc_conv_descriptor_data_get (se_expr);
2028   else
2029     {
2030       gcc_assert (POINTER_TYPE_P (TREE_TYPE (se_expr)));
2031       tmp = se_expr;
2032     }
2033 
2034   *offset = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
2035 			     *offset, fold_convert (gfc_array_index_type, tmp));
2036 
2037   if (expr->symtree->n.sym->ts.type == BT_DERIVED
2038       && expr->symtree->n.sym->attr.codimension
2039       && expr->symtree->n.sym->ts.u.derived->attr.alloc_comp)
2040     {
2041       gfc_expr *base_expr = gfc_copy_expr (expr);
2042       gfc_ref *ref = base_expr->ref;
2043       gfc_se base_se;
2044 
2045       // Iterate through the refs until the last one.
2046       while (ref->next)
2047 	  ref = ref->next;
2048 
2049       if (ref->type == REF_ARRAY
2050 	  && ref->u.ar.type != AR_FULL)
2051 	{
2052 	  const int ranksum = ref->u.ar.dimen + ref->u.ar.codimen;
2053 	  int i;
2054 	  for (i = 0; i < ranksum; ++i)
2055 	    {
2056 	      ref->u.ar.start[i] = NULL;
2057 	      ref->u.ar.end[i] = NULL;
2058 	    }
2059 	  ref->u.ar.type = AR_FULL;
2060 	}
2061       gfc_init_se (&base_se, NULL);
2062       if (gfc_caf_attr (base_expr).dimension)
2063 	{
2064 	  gfc_conv_expr_descriptor (&base_se, base_expr);
2065 	  tmp = gfc_conv_descriptor_data_get (base_se.expr);
2066 	}
2067       else
2068 	{
2069 	  gfc_conv_expr (&base_se, base_expr);
2070 	  tmp = base_se.expr;
2071 	}
2072 
2073       gfc_free_expr (base_expr);
2074       gfc_add_block_to_block (&se->pre, &base_se.pre);
2075       gfc_add_block_to_block (&se->post, &base_se.post);
2076     }
2077   else if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (caf_decl)))
2078     tmp = gfc_conv_descriptor_data_get (caf_decl);
2079   else
2080    {
2081      gcc_assert (POINTER_TYPE_P (TREE_TYPE (caf_decl)));
2082      tmp = caf_decl;
2083    }
2084 
2085   *offset = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
2086 			    fold_convert (gfc_array_index_type, *offset),
2087 			    fold_convert (gfc_array_index_type, tmp));
2088 }
2089 
2090 
2091 /* Convert the coindex of a coarray into an image index; the result is
2092    image_num =  (idx(1)-lcobound(1)+1) + (idx(2)-lcobound(2))*extent(1)
2093               + (idx(3)-lcobound(3))*extend(1)*extent(2) + ...  */
2094 
2095 tree
2096 gfc_caf_get_image_index (stmtblock_t *block, gfc_expr *e, tree desc)
2097 {
2098   gfc_ref *ref;
2099   tree lbound, ubound, extent, tmp, img_idx;
2100   gfc_se se;
2101   int i;
2102 
2103   for (ref = e->ref; ref; ref = ref->next)
2104     if (ref->type == REF_ARRAY && ref->u.ar.codimen > 0)
2105       break;
2106   gcc_assert (ref != NULL);
2107 
2108   if (ref->u.ar.dimen_type[ref->u.ar.dimen] == DIMEN_THIS_IMAGE)
2109     {
2110       return build_call_expr_loc (input_location, gfor_fndecl_caf_this_image, 1,
2111 				  integer_zero_node);
2112     }
2113 
2114   img_idx = build_zero_cst (gfc_array_index_type);
2115   extent = build_one_cst (gfc_array_index_type);
2116   if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (desc)))
2117     for (i = ref->u.ar.dimen; i < ref->u.ar.dimen + ref->u.ar.codimen; i++)
2118       {
2119 	gfc_init_se (&se, NULL);
2120 	gfc_conv_expr_type (&se, ref->u.ar.start[i], gfc_array_index_type);
2121 	gfc_add_block_to_block (block, &se.pre);
2122 	lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[i]);
2123 	tmp = fold_build2_loc (input_location, MINUS_EXPR,
2124 			       TREE_TYPE (lbound), se.expr, lbound);
2125 	tmp = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (tmp),
2126 			       extent, tmp);
2127 	img_idx = fold_build2_loc (input_location, PLUS_EXPR,
2128 				   TREE_TYPE (tmp), img_idx, tmp);
2129 	if (i < ref->u.ar.dimen + ref->u.ar.codimen - 1)
2130 	  {
2131 	    ubound = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[i]);
2132 	    tmp = gfc_conv_array_extent_dim (lbound, ubound, NULL);
2133 	    extent = fold_build2_loc (input_location, MULT_EXPR,
2134 				      TREE_TYPE (tmp), extent, tmp);
2135 	  }
2136       }
2137   else
2138     for (i = ref->u.ar.dimen; i < ref->u.ar.dimen + ref->u.ar.codimen; i++)
2139       {
2140 	gfc_init_se (&se, NULL);
2141 	gfc_conv_expr_type (&se, ref->u.ar.start[i], gfc_array_index_type);
2142 	gfc_add_block_to_block (block, &se.pre);
2143 	lbound = GFC_TYPE_ARRAY_LBOUND (TREE_TYPE (desc), i);
2144 	tmp = fold_build2_loc (input_location, MINUS_EXPR,
2145 			       TREE_TYPE (lbound), se.expr, lbound);
2146 	tmp = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (tmp),
2147 			       extent, tmp);
2148 	img_idx = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (tmp),
2149 				   img_idx, tmp);
2150 	if (i < ref->u.ar.dimen + ref->u.ar.codimen - 1)
2151 	  {
2152 	    ubound = GFC_TYPE_ARRAY_UBOUND (TREE_TYPE (desc), i);
2153 	    tmp = fold_build2_loc (input_location, MINUS_EXPR,
2154 				   TREE_TYPE (ubound), ubound, lbound);
2155 	    tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (tmp),
2156 				   tmp, build_one_cst (TREE_TYPE (tmp)));
2157 	    extent = fold_build2_loc (input_location, MULT_EXPR,
2158 				      TREE_TYPE (tmp), extent, tmp);
2159 	  }
2160       }
2161   img_idx = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (img_idx),
2162 			     img_idx, build_one_cst (TREE_TYPE (img_idx)));
2163   return fold_convert (integer_type_node, img_idx);
2164 }
2165 
2166 
2167 /* For each character array constructor subexpression without a ts.u.cl->length,
2168    replace it by its first element (if there aren't any elements, the length
2169    should already be set to zero).  */
2170 
2171 static void
2172 flatten_array_ctors_without_strlen (gfc_expr* e)
2173 {
2174   gfc_actual_arglist* arg;
2175   gfc_constructor* c;
2176 
2177   if (!e)
2178     return;
2179 
2180   switch (e->expr_type)
2181     {
2182 
2183     case EXPR_OP:
2184       flatten_array_ctors_without_strlen (e->value.op.op1);
2185       flatten_array_ctors_without_strlen (e->value.op.op2);
2186       break;
2187 
2188     case EXPR_COMPCALL:
2189       /* TODO: Implement as with EXPR_FUNCTION when needed.  */
2190       gcc_unreachable ();
2191 
2192     case EXPR_FUNCTION:
2193       for (arg = e->value.function.actual; arg; arg = arg->next)
2194 	flatten_array_ctors_without_strlen (arg->expr);
2195       break;
2196 
2197     case EXPR_ARRAY:
2198 
2199       /* We've found what we're looking for.  */
2200       if (e->ts.type == BT_CHARACTER && !e->ts.u.cl->length)
2201 	{
2202 	  gfc_constructor *c;
2203 	  gfc_expr* new_expr;
2204 
2205 	  gcc_assert (e->value.constructor);
2206 
2207 	  c = gfc_constructor_first (e->value.constructor);
2208 	  new_expr = c->expr;
2209 	  c->expr = NULL;
2210 
2211 	  flatten_array_ctors_without_strlen (new_expr);
2212 	  gfc_replace_expr (e, new_expr);
2213 	  break;
2214 	}
2215 
2216       /* Otherwise, fall through to handle constructor elements.  */
2217       gcc_fallthrough ();
2218     case EXPR_STRUCTURE:
2219       for (c = gfc_constructor_first (e->value.constructor);
2220 	   c; c = gfc_constructor_next (c))
2221 	flatten_array_ctors_without_strlen (c->expr);
2222       break;
2223 
2224     default:
2225       break;
2226 
2227     }
2228 }
2229 
2230 
2231 /* Generate code to initialize a string length variable. Returns the
2232    value.  For array constructors, cl->length might be NULL and in this case,
2233    the first element of the constructor is needed.  expr is the original
2234    expression so we can access it but can be NULL if this is not needed.  */
2235 
2236 void
2237 gfc_conv_string_length (gfc_charlen * cl, gfc_expr * expr, stmtblock_t * pblock)
2238 {
2239   gfc_se se;
2240 
2241   gfc_init_se (&se, NULL);
2242 
2243   if (!cl->length && cl->backend_decl && VAR_P (cl->backend_decl))
2244     return;
2245 
2246   /* If cl->length is NULL, use gfc_conv_expr to obtain the string length but
2247      "flatten" array constructors by taking their first element; all elements
2248      should be the same length or a cl->length should be present.  */
2249   if (!cl->length)
2250     {
2251       gfc_expr* expr_flat;
2252       if (!expr)
2253 	return;
2254       expr_flat = gfc_copy_expr (expr);
2255       flatten_array_ctors_without_strlen (expr_flat);
2256       gfc_resolve_expr (expr_flat);
2257 
2258       gfc_conv_expr (&se, expr_flat);
2259       gfc_add_block_to_block (pblock, &se.pre);
2260       cl->backend_decl = convert (gfc_charlen_type_node, se.string_length);
2261 
2262       gfc_free_expr (expr_flat);
2263       return;
2264     }
2265 
2266   /* Convert cl->length.  */
2267 
2268   gcc_assert (cl->length);
2269 
2270   gfc_conv_expr_type (&se, cl->length, gfc_charlen_type_node);
2271   se.expr = fold_build2_loc (input_location, MAX_EXPR, gfc_charlen_type_node,
2272 			     se.expr, build_zero_cst (TREE_TYPE (se.expr)));
2273   gfc_add_block_to_block (pblock, &se.pre);
2274 
2275   if (cl->backend_decl)
2276     gfc_add_modify (pblock, cl->backend_decl, se.expr);
2277   else
2278     cl->backend_decl = gfc_evaluate_now (se.expr, pblock);
2279 }
2280 
2281 
2282 static void
2283 gfc_conv_substring (gfc_se * se, gfc_ref * ref, int kind,
2284 		    const char *name, locus *where)
2285 {
2286   tree tmp;
2287   tree type;
2288   tree fault;
2289   gfc_se start;
2290   gfc_se end;
2291   char *msg;
2292   mpz_t length;
2293 
2294   type = gfc_get_character_type (kind, ref->u.ss.length);
2295   type = build_pointer_type (type);
2296 
2297   gfc_init_se (&start, se);
2298   gfc_conv_expr_type (&start, ref->u.ss.start, gfc_charlen_type_node);
2299   gfc_add_block_to_block (&se->pre, &start.pre);
2300 
2301   if (integer_onep (start.expr))
2302     gfc_conv_string_parameter (se);
2303   else
2304     {
2305       tmp = start.expr;
2306       STRIP_NOPS (tmp);
2307       /* Avoid multiple evaluation of substring start.  */
2308       if (!CONSTANT_CLASS_P (tmp) && !DECL_P (tmp))
2309 	start.expr = gfc_evaluate_now (start.expr, &se->pre);
2310 
2311       /* Change the start of the string.  */
2312       if (TYPE_STRING_FLAG (TREE_TYPE (se->expr)))
2313 	tmp = se->expr;
2314       else
2315 	tmp = build_fold_indirect_ref_loc (input_location,
2316 				       se->expr);
2317       tmp = gfc_build_array_ref (tmp, start.expr, NULL);
2318       se->expr = gfc_build_addr_expr (type, tmp);
2319     }
2320 
2321   /* Length = end + 1 - start.  */
2322   gfc_init_se (&end, se);
2323   if (ref->u.ss.end == NULL)
2324     end.expr = se->string_length;
2325   else
2326     {
2327       gfc_conv_expr_type (&end, ref->u.ss.end, gfc_charlen_type_node);
2328       gfc_add_block_to_block (&se->pre, &end.pre);
2329     }
2330   tmp = end.expr;
2331   STRIP_NOPS (tmp);
2332   if (!CONSTANT_CLASS_P (tmp) && !DECL_P (tmp))
2333     end.expr = gfc_evaluate_now (end.expr, &se->pre);
2334 
2335   if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
2336     {
2337       tree nonempty = fold_build2_loc (input_location, LE_EXPR,
2338 				       logical_type_node, start.expr,
2339 				       end.expr);
2340 
2341       /* Check lower bound.  */
2342       fault = fold_build2_loc (input_location, LT_EXPR, logical_type_node,
2343 			       start.expr,
2344 			       build_one_cst (TREE_TYPE (start.expr)));
2345       fault = fold_build2_loc (input_location, TRUTH_ANDIF_EXPR,
2346 			       logical_type_node, nonempty, fault);
2347       if (name)
2348 	msg = xasprintf ("Substring out of bounds: lower bound (%%ld) of '%s' "
2349 			 "is less than one", name);
2350       else
2351 	msg = xasprintf ("Substring out of bounds: lower bound (%%ld) "
2352 			 "is less than one");
2353       gfc_trans_runtime_check (true, false, fault, &se->pre, where, msg,
2354 			       fold_convert (long_integer_type_node,
2355 					     start.expr));
2356       free (msg);
2357 
2358       /* Check upper bound.  */
2359       fault = fold_build2_loc (input_location, GT_EXPR, logical_type_node,
2360 			       end.expr, se->string_length);
2361       fault = fold_build2_loc (input_location, TRUTH_ANDIF_EXPR,
2362 			       logical_type_node, nonempty, fault);
2363       if (name)
2364 	msg = xasprintf ("Substring out of bounds: upper bound (%%ld) of '%s' "
2365 			 "exceeds string length (%%ld)", name);
2366       else
2367 	msg = xasprintf ("Substring out of bounds: upper bound (%%ld) "
2368 			 "exceeds string length (%%ld)");
2369       gfc_trans_runtime_check (true, false, fault, &se->pre, where, msg,
2370 			       fold_convert (long_integer_type_node, end.expr),
2371 			       fold_convert (long_integer_type_node,
2372 					     se->string_length));
2373       free (msg);
2374     }
2375 
2376   /* Try to calculate the length from the start and end expressions.  */
2377   if (ref->u.ss.end
2378       && gfc_dep_difference (ref->u.ss.end, ref->u.ss.start, &length))
2379     {
2380       HOST_WIDE_INT i_len;
2381 
2382       i_len = gfc_mpz_get_hwi (length) + 1;
2383       if (i_len < 0)
2384 	i_len = 0;
2385 
2386       tmp = build_int_cst (gfc_charlen_type_node, i_len);
2387       mpz_clear (length);  /* Was initialized by gfc_dep_difference.  */
2388     }
2389   else
2390     {
2391       tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_charlen_type_node,
2392 			     fold_convert (gfc_charlen_type_node, end.expr),
2393 			     fold_convert (gfc_charlen_type_node, start.expr));
2394       tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_charlen_type_node,
2395 			     build_int_cst (gfc_charlen_type_node, 1), tmp);
2396       tmp = fold_build2_loc (input_location, MAX_EXPR, gfc_charlen_type_node,
2397 			     tmp, build_int_cst (gfc_charlen_type_node, 0));
2398     }
2399 
2400   se->string_length = tmp;
2401 }
2402 
2403 
2404 /* Convert a derived type component reference.  */
2405 
2406 static void
2407 gfc_conv_component_ref (gfc_se * se, gfc_ref * ref)
2408 {
2409   gfc_component *c;
2410   tree tmp;
2411   tree decl;
2412   tree field;
2413   tree context;
2414 
2415   c = ref->u.c.component;
2416 
2417   if (c->backend_decl == NULL_TREE
2418       && ref->u.c.sym != NULL)
2419     gfc_get_derived_type (ref->u.c.sym);
2420 
2421   field = c->backend_decl;
2422   gcc_assert (field && TREE_CODE (field) == FIELD_DECL);
2423   decl = se->expr;
2424   context = DECL_FIELD_CONTEXT (field);
2425 
2426   /* Components can correspond to fields of different containing
2427      types, as components are created without context, whereas
2428      a concrete use of a component has the type of decl as context.
2429      So, if the type doesn't match, we search the corresponding
2430      FIELD_DECL in the parent type.  To not waste too much time
2431      we cache this result in norestrict_decl.
2432      On the other hand, if the context is a UNION or a MAP (a
2433      RECORD_TYPE within a UNION_TYPE) always use the given FIELD_DECL.  */
2434 
2435   if (context != TREE_TYPE (decl)
2436       && !(   TREE_CODE (TREE_TYPE (field)) == UNION_TYPE /* Field is union */
2437            || TREE_CODE (context) == UNION_TYPE))         /* Field is map */
2438     {
2439       tree f2 = c->norestrict_decl;
2440       if (!f2 || DECL_FIELD_CONTEXT (f2) != TREE_TYPE (decl))
2441 	for (f2 = TYPE_FIELDS (TREE_TYPE (decl)); f2; f2 = DECL_CHAIN (f2))
2442 	  if (TREE_CODE (f2) == FIELD_DECL
2443 	      && DECL_NAME (f2) == DECL_NAME (field))
2444 	    break;
2445       gcc_assert (f2);
2446       c->norestrict_decl = f2;
2447       field = f2;
2448     }
2449 
2450   if (ref->u.c.sym && ref->u.c.sym->ts.type == BT_CLASS
2451       && strcmp ("_data", c->name) == 0)
2452     {
2453       /* Found a ref to the _data component.  Store the associated ref to
2454 	 the vptr in se->class_vptr.  */
2455       se->class_vptr = gfc_class_vptr_get (decl);
2456     }
2457   else
2458     se->class_vptr = NULL_TREE;
2459 
2460   tmp = fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field),
2461 			 decl, field, NULL_TREE);
2462 
2463   se->expr = tmp;
2464 
2465   /* Allocatable deferred char arrays are to be handled by the gfc_deferred_
2466      strlen () conditional below.  */
2467   if (c->ts.type == BT_CHARACTER && !c->attr.proc_pointer
2468       && !(c->attr.allocatable && c->ts.deferred)
2469       && !c->attr.pdt_string)
2470     {
2471       tmp = c->ts.u.cl->backend_decl;
2472       /* Components must always be constant length.  */
2473       gcc_assert (tmp && INTEGER_CST_P (tmp));
2474       se->string_length = tmp;
2475     }
2476 
2477   if (gfc_deferred_strlen (c, &field))
2478     {
2479       tmp = fold_build3_loc (input_location, COMPONENT_REF,
2480 			     TREE_TYPE (field),
2481 			     decl, field, NULL_TREE);
2482       se->string_length = tmp;
2483     }
2484 
2485   if (((c->attr.pointer || c->attr.allocatable)
2486        && (!c->attr.dimension && !c->attr.codimension)
2487        && c->ts.type != BT_CHARACTER)
2488       || c->attr.proc_pointer)
2489     se->expr = build_fold_indirect_ref_loc (input_location,
2490 					se->expr);
2491 }
2492 
2493 
2494 /* This function deals with component references to components of the
2495    parent type for derived type extensions.  */
2496 static void
2497 conv_parent_component_references (gfc_se * se, gfc_ref * ref)
2498 {
2499   gfc_component *c;
2500   gfc_component *cmp;
2501   gfc_symbol *dt;
2502   gfc_ref parent;
2503 
2504   dt = ref->u.c.sym;
2505   c = ref->u.c.component;
2506 
2507   /* Return if the component is in the parent type.  */
2508   for (cmp = dt->components; cmp; cmp = cmp->next)
2509     if (strcmp (c->name, cmp->name) == 0)
2510       return;
2511 
2512   /* Build a gfc_ref to recursively call gfc_conv_component_ref.  */
2513   parent.type = REF_COMPONENT;
2514   parent.next = NULL;
2515   parent.u.c.sym = dt;
2516   parent.u.c.component = dt->components;
2517 
2518   if (dt->backend_decl == NULL)
2519     gfc_get_derived_type (dt);
2520 
2521   /* Build the reference and call self.  */
2522   gfc_conv_component_ref (se, &parent);
2523   parent.u.c.sym = dt->components->ts.u.derived;
2524   parent.u.c.component = c;
2525   conv_parent_component_references (se, &parent);
2526 }
2527 
2528 
2529 static void
2530 conv_inquiry (gfc_se * se, gfc_ref * ref, gfc_expr *expr, gfc_typespec *ts)
2531 {
2532   tree res = se->expr;
2533 
2534   switch (ref->u.i)
2535     {
2536     case INQUIRY_RE:
2537       res = fold_build1_loc (input_location, REALPART_EXPR,
2538 			     TREE_TYPE (TREE_TYPE (res)), res);
2539       break;
2540 
2541     case INQUIRY_IM:
2542       res = fold_build1_loc (input_location, IMAGPART_EXPR,
2543 			     TREE_TYPE (TREE_TYPE (res)), res);
2544       break;
2545 
2546     case INQUIRY_KIND:
2547       res = build_int_cst (gfc_typenode_for_spec (&expr->ts),
2548 			   ts->kind);
2549       break;
2550 
2551     case INQUIRY_LEN:
2552       res = fold_convert (gfc_typenode_for_spec (&expr->ts),
2553 			  se->string_length);
2554       break;
2555 
2556     default:
2557       gcc_unreachable ();
2558     }
2559   se->expr = res;
2560 }
2561 
2562 /* Return the contents of a variable. Also handles reference/pointer
2563    variables (all Fortran pointer references are implicit).  */
2564 
2565 static void
2566 gfc_conv_variable (gfc_se * se, gfc_expr * expr)
2567 {
2568   gfc_ss *ss;
2569   gfc_ref *ref;
2570   gfc_symbol *sym;
2571   tree parent_decl = NULL_TREE;
2572   int parent_flag;
2573   bool return_value;
2574   bool alternate_entry;
2575   bool entry_master;
2576   bool is_classarray;
2577   bool first_time = true;
2578 
2579   sym = expr->symtree->n.sym;
2580   is_classarray = IS_CLASS_ARRAY (sym);
2581   ss = se->ss;
2582   if (ss != NULL)
2583     {
2584       gfc_ss_info *ss_info = ss->info;
2585 
2586       /* Check that something hasn't gone horribly wrong.  */
2587       gcc_assert (ss != gfc_ss_terminator);
2588       gcc_assert (ss_info->expr == expr);
2589 
2590       /* A scalarized term.  We already know the descriptor.  */
2591       se->expr = ss_info->data.array.descriptor;
2592       se->string_length = ss_info->string_length;
2593       ref = ss_info->data.array.ref;
2594       if (ref)
2595 	gcc_assert (ref->type == REF_ARRAY
2596 		    && ref->u.ar.type != AR_ELEMENT);
2597       else
2598 	gfc_conv_tmp_array_ref (se);
2599     }
2600   else
2601     {
2602       tree se_expr = NULL_TREE;
2603 
2604       se->expr = gfc_get_symbol_decl (sym);
2605 
2606       /* Deal with references to a parent results or entries by storing
2607 	 the current_function_decl and moving to the parent_decl.  */
2608       return_value = sym->attr.function && sym->result == sym;
2609       alternate_entry = sym->attr.function && sym->attr.entry
2610 			&& sym->result == sym;
2611       entry_master = sym->attr.result
2612 		     && sym->ns->proc_name->attr.entry_master
2613 		     && !gfc_return_by_reference (sym->ns->proc_name);
2614       if (current_function_decl)
2615 	parent_decl = DECL_CONTEXT (current_function_decl);
2616 
2617       if ((se->expr == parent_decl && return_value)
2618 	   || (sym->ns && sym->ns->proc_name
2619 	       && parent_decl
2620 	       && sym->ns->proc_name->backend_decl == parent_decl
2621 	       && (alternate_entry || entry_master)))
2622 	parent_flag = 1;
2623       else
2624 	parent_flag = 0;
2625 
2626       /* Special case for assigning the return value of a function.
2627 	 Self recursive functions must have an explicit return value.  */
2628       if (return_value && (se->expr == current_function_decl || parent_flag))
2629 	se_expr = gfc_get_fake_result_decl (sym, parent_flag);
2630 
2631       /* Similarly for alternate entry points.  */
2632       else if (alternate_entry
2633 	       && (sym->ns->proc_name->backend_decl == current_function_decl
2634 		   || parent_flag))
2635 	{
2636 	  gfc_entry_list *el = NULL;
2637 
2638 	  for (el = sym->ns->entries; el; el = el->next)
2639 	    if (sym == el->sym)
2640 	      {
2641 		se_expr = gfc_get_fake_result_decl (sym, parent_flag);
2642 		break;
2643 	      }
2644 	}
2645 
2646       else if (entry_master
2647 	       && (sym->ns->proc_name->backend_decl == current_function_decl
2648 		   || parent_flag))
2649 	se_expr = gfc_get_fake_result_decl (sym, parent_flag);
2650 
2651       if (se_expr)
2652 	se->expr = se_expr;
2653 
2654       /* Procedure actual arguments.  Look out for temporary variables
2655 	 with the same attributes as function values.  */
2656       else if (!sym->attr.temporary
2657 	       && sym->attr.flavor == FL_PROCEDURE
2658 	       && se->expr != current_function_decl)
2659 	{
2660 	  if (!sym->attr.dummy && !sym->attr.proc_pointer)
2661 	    {
2662 	      gcc_assert (TREE_CODE (se->expr) == FUNCTION_DECL);
2663 	      se->expr = gfc_build_addr_expr (NULL_TREE, se->expr);
2664 	    }
2665 	  return;
2666 	}
2667 
2668 
2669       /* Dereference the expression, where needed. Since characters
2670 	 are entirely different from other types, they are treated
2671 	 separately.  */
2672       if (sym->ts.type == BT_CHARACTER)
2673 	{
2674 	  /* Dereference character pointer dummy arguments
2675 	     or results.  */
2676 	  if ((sym->attr.pointer || sym->attr.allocatable)
2677 	      && (sym->attr.dummy
2678 		  || sym->attr.function
2679 		  || sym->attr.result))
2680 	    se->expr = build_fold_indirect_ref_loc (input_location,
2681 						se->expr);
2682 
2683 	}
2684       else if (!sym->attr.value)
2685 	{
2686 	  /* Dereference temporaries for class array dummy arguments.  */
2687 	  if (sym->attr.dummy && is_classarray
2688 	      && GFC_ARRAY_TYPE_P (TREE_TYPE (se->expr)))
2689 	    {
2690 	      if (!se->descriptor_only)
2691 		se->expr = GFC_DECL_SAVED_DESCRIPTOR (se->expr);
2692 
2693 	      se->expr = build_fold_indirect_ref_loc (input_location,
2694 						      se->expr);
2695 	    }
2696 
2697 	  /* Dereference non-character scalar dummy arguments.  */
2698 	  if (sym->attr.dummy && !sym->attr.dimension
2699 	      && !(sym->attr.codimension && sym->attr.allocatable)
2700 	      && (sym->ts.type != BT_CLASS
2701 		  || (!CLASS_DATA (sym)->attr.dimension
2702 		      && !(CLASS_DATA (sym)->attr.codimension
2703 			   && CLASS_DATA (sym)->attr.allocatable))))
2704 	    se->expr = build_fold_indirect_ref_loc (input_location,
2705 						se->expr);
2706 
2707           /* Dereference scalar hidden result.  */
2708 	  if (flag_f2c && sym->ts.type == BT_COMPLEX
2709 	      && (sym->attr.function || sym->attr.result)
2710 	      && !sym->attr.dimension && !sym->attr.pointer
2711 	      && !sym->attr.always_explicit)
2712 	    se->expr = build_fold_indirect_ref_loc (input_location,
2713 						se->expr);
2714 
2715 	  /* Dereference non-character, non-class pointer variables.
2716 	     These must be dummies, results, or scalars.  */
2717 	  if (!is_classarray
2718 	      && (sym->attr.pointer || sym->attr.allocatable
2719 		  || gfc_is_associate_pointer (sym)
2720 		  || (sym->as && sym->as->type == AS_ASSUMED_RANK))
2721 	      && (sym->attr.dummy
2722 		  || sym->attr.function
2723 		  || sym->attr.result
2724 		  || (!sym->attr.dimension
2725 		      && (!sym->attr.codimension || !sym->attr.allocatable))))
2726 	    se->expr = build_fold_indirect_ref_loc (input_location,
2727 						se->expr);
2728 	  /* Now treat the class array pointer variables accordingly.  */
2729 	  else if (sym->ts.type == BT_CLASS
2730 		   && sym->attr.dummy
2731 		   && (CLASS_DATA (sym)->attr.dimension
2732 		       || CLASS_DATA (sym)->attr.codimension)
2733 		   && ((CLASS_DATA (sym)->as
2734 			&& CLASS_DATA (sym)->as->type == AS_ASSUMED_RANK)
2735 		       || CLASS_DATA (sym)->attr.allocatable
2736 		       || CLASS_DATA (sym)->attr.class_pointer))
2737 	    se->expr = build_fold_indirect_ref_loc (input_location,
2738 						se->expr);
2739 	  /* And the case where a non-dummy, non-result, non-function,
2740 	     non-allotable and non-pointer classarray is present.  This case was
2741 	     previously covered by the first if, but with introducing the
2742 	     condition !is_classarray there, that case has to be covered
2743 	     explicitly.  */
2744 	  else if (sym->ts.type == BT_CLASS
2745 		   && !sym->attr.dummy
2746 		   && !sym->attr.function
2747 		   && !sym->attr.result
2748 		   && (CLASS_DATA (sym)->attr.dimension
2749 		       || CLASS_DATA (sym)->attr.codimension)
2750 		   && (sym->assoc
2751 		       || !CLASS_DATA (sym)->attr.allocatable)
2752 		   && !CLASS_DATA (sym)->attr.class_pointer)
2753 	    se->expr = build_fold_indirect_ref_loc (input_location,
2754 						se->expr);
2755 	}
2756 
2757       ref = expr->ref;
2758     }
2759 
2760   /* For character variables, also get the length.  */
2761   if (sym->ts.type == BT_CHARACTER)
2762     {
2763       /* If the character length of an entry isn't set, get the length from
2764          the master function instead.  */
2765       if (sym->attr.entry && !sym->ts.u.cl->backend_decl)
2766         se->string_length = sym->ns->proc_name->ts.u.cl->backend_decl;
2767       else
2768         se->string_length = sym->ts.u.cl->backend_decl;
2769       gcc_assert (se->string_length);
2770     }
2771 
2772   gfc_typespec *ts = &sym->ts;
2773   while (ref)
2774     {
2775       switch (ref->type)
2776 	{
2777 	case REF_ARRAY:
2778 	  /* Return the descriptor if that's what we want and this is an array
2779 	     section reference.  */
2780 	  if (se->descriptor_only && ref->u.ar.type != AR_ELEMENT)
2781 	    return;
2782 /* TODO: Pointers to single elements of array sections, eg elemental subs.  */
2783 	  /* Return the descriptor for array pointers and allocations.  */
2784 	  if (se->want_pointer
2785 	      && ref->next == NULL && (se->descriptor_only))
2786 	    return;
2787 
2788 	  gfc_conv_array_ref (se, &ref->u.ar, expr, &expr->where);
2789 	  /* Return a pointer to an element.  */
2790 	  break;
2791 
2792 	case REF_COMPONENT:
2793 	  ts = &ref->u.c.component->ts;
2794 	  if (first_time && is_classarray && sym->attr.dummy
2795 	      && se->descriptor_only
2796 	      && !CLASS_DATA (sym)->attr.allocatable
2797 	      && !CLASS_DATA (sym)->attr.class_pointer
2798 	      && CLASS_DATA (sym)->as
2799 	      && CLASS_DATA (sym)->as->type != AS_ASSUMED_RANK
2800 	      && strcmp ("_data", ref->u.c.component->name) == 0)
2801 	    /* Skip the first ref of a _data component, because for class
2802 	       arrays that one is already done by introducing a temporary
2803 	       array descriptor.  */
2804 	    break;
2805 
2806 	  if (ref->u.c.sym->attr.extension)
2807 	    conv_parent_component_references (se, ref);
2808 
2809 	  gfc_conv_component_ref (se, ref);
2810 	  if (!ref->next && ref->u.c.sym->attr.codimension
2811 	      && se->want_pointer && se->descriptor_only)
2812 	    return;
2813 
2814 	  break;
2815 
2816 	case REF_SUBSTRING:
2817 	  gfc_conv_substring (se, ref, expr->ts.kind,
2818 			      expr->symtree->name, &expr->where);
2819 	  break;
2820 
2821 	case REF_INQUIRY:
2822 	  conv_inquiry (se, ref, expr, ts);
2823 	  break;
2824 
2825 	default:
2826 	  gcc_unreachable ();
2827 	  break;
2828 	}
2829       first_time = false;
2830       ref = ref->next;
2831     }
2832   /* Pointer assignment, allocation or pass by reference.  Arrays are handled
2833      separately.  */
2834   if (se->want_pointer)
2835     {
2836       if (expr->ts.type == BT_CHARACTER && !gfc_is_proc_ptr_comp (expr))
2837 	gfc_conv_string_parameter (se);
2838       else
2839 	se->expr = gfc_build_addr_expr (NULL_TREE, se->expr);
2840     }
2841 }
2842 
2843 
2844 /* Unary ops are easy... Or they would be if ! was a valid op.  */
2845 
2846 static void
2847 gfc_conv_unary_op (enum tree_code code, gfc_se * se, gfc_expr * expr)
2848 {
2849   gfc_se operand;
2850   tree type;
2851 
2852   gcc_assert (expr->ts.type != BT_CHARACTER);
2853   /* Initialize the operand.  */
2854   gfc_init_se (&operand, se);
2855   gfc_conv_expr_val (&operand, expr->value.op.op1);
2856   gfc_add_block_to_block (&se->pre, &operand.pre);
2857 
2858   type = gfc_typenode_for_spec (&expr->ts);
2859 
2860   /* TRUTH_NOT_EXPR is not a "true" unary operator in GCC.
2861      We must convert it to a compare to 0 (e.g. EQ_EXPR (op1, 0)).
2862      All other unary operators have an equivalent GIMPLE unary operator.  */
2863   if (code == TRUTH_NOT_EXPR)
2864     se->expr = fold_build2_loc (input_location, EQ_EXPR, type, operand.expr,
2865 				build_int_cst (type, 0));
2866   else
2867     se->expr = fold_build1_loc (input_location, code, type, operand.expr);
2868 
2869 }
2870 
2871 /* Expand power operator to optimal multiplications when a value is raised
2872    to a constant integer n. See section 4.6.3, "Evaluation of Powers" of
2873    Donald E. Knuth, "Seminumerical Algorithms", Vol. 2, "The Art of Computer
2874    Programming", 3rd Edition, 1998.  */
2875 
2876 /* This code is mostly duplicated from expand_powi in the backend.
2877    We establish the "optimal power tree" lookup table with the defined size.
2878    The items in the table are the exponents used to calculate the index
2879    exponents. Any integer n less than the value can get an "addition chain",
2880    with the first node being one.  */
2881 #define POWI_TABLE_SIZE 256
2882 
2883 /* The table is from builtins.c.  */
2884 static const unsigned char powi_table[POWI_TABLE_SIZE] =
2885   {
2886       0,   1,   1,   2,   2,   3,   3,   4,  /*   0 -   7 */
2887       4,   6,   5,   6,   6,  10,   7,   9,  /*   8 -  15 */
2888       8,  16,   9,  16,  10,  12,  11,  13,  /*  16 -  23 */
2889      12,  17,  13,  18,  14,  24,  15,  26,  /*  24 -  31 */
2890      16,  17,  17,  19,  18,  33,  19,  26,  /*  32 -  39 */
2891      20,  25,  21,  40,  22,  27,  23,  44,  /*  40 -  47 */
2892      24,  32,  25,  34,  26,  29,  27,  44,  /*  48 -  55 */
2893      28,  31,  29,  34,  30,  60,  31,  36,  /*  56 -  63 */
2894      32,  64,  33,  34,  34,  46,  35,  37,  /*  64 -  71 */
2895      36,  65,  37,  50,  38,  48,  39,  69,  /*  72 -  79 */
2896      40,  49,  41,  43,  42,  51,  43,  58,  /*  80 -  87 */
2897      44,  64,  45,  47,  46,  59,  47,  76,  /*  88 -  95 */
2898      48,  65,  49,  66,  50,  67,  51,  66,  /*  96 - 103 */
2899      52,  70,  53,  74,  54, 104,  55,  74,  /* 104 - 111 */
2900      56,  64,  57,  69,  58,  78,  59,  68,  /* 112 - 119 */
2901      60,  61,  61,  80,  62,  75,  63,  68,  /* 120 - 127 */
2902      64,  65,  65, 128,  66, 129,  67,  90,  /* 128 - 135 */
2903      68,  73,  69, 131,  70,  94,  71,  88,  /* 136 - 143 */
2904      72, 128,  73,  98,  74, 132,  75, 121,  /* 144 - 151 */
2905      76, 102,  77, 124,  78, 132,  79, 106,  /* 152 - 159 */
2906      80,  97,  81, 160,  82,  99,  83, 134,  /* 160 - 167 */
2907      84,  86,  85,  95,  86, 160,  87, 100,  /* 168 - 175 */
2908      88, 113,  89,  98,  90, 107,  91, 122,  /* 176 - 183 */
2909      92, 111,  93, 102,  94, 126,  95, 150,  /* 184 - 191 */
2910      96, 128,  97, 130,  98, 133,  99, 195,  /* 192 - 199 */
2911     100, 128, 101, 123, 102, 164, 103, 138,  /* 200 - 207 */
2912     104, 145, 105, 146, 106, 109, 107, 149,  /* 208 - 215 */
2913     108, 200, 109, 146, 110, 170, 111, 157,  /* 216 - 223 */
2914     112, 128, 113, 130, 114, 182, 115, 132,  /* 224 - 231 */
2915     116, 200, 117, 132, 118, 158, 119, 206,  /* 232 - 239 */
2916     120, 240, 121, 162, 122, 147, 123, 152,  /* 240 - 247 */
2917     124, 166, 125, 214, 126, 138, 127, 153,  /* 248 - 255 */
2918   };
2919 
2920 /* If n is larger than lookup table's max index, we use the "window
2921    method".  */
2922 #define POWI_WINDOW_SIZE 3
2923 
2924 /* Recursive function to expand the power operator. The temporary
2925    values are put in tmpvar. The function returns tmpvar[1] ** n.  */
2926 static tree
2927 gfc_conv_powi (gfc_se * se, unsigned HOST_WIDE_INT n, tree * tmpvar)
2928 {
2929   tree op0;
2930   tree op1;
2931   tree tmp;
2932   int digit;
2933 
2934   if (n < POWI_TABLE_SIZE)
2935     {
2936       if (tmpvar[n])
2937         return tmpvar[n];
2938 
2939       op0 = gfc_conv_powi (se, n - powi_table[n], tmpvar);
2940       op1 = gfc_conv_powi (se, powi_table[n], tmpvar);
2941     }
2942   else if (n & 1)
2943     {
2944       digit = n & ((1 << POWI_WINDOW_SIZE) - 1);
2945       op0 = gfc_conv_powi (se, n - digit, tmpvar);
2946       op1 = gfc_conv_powi (se, digit, tmpvar);
2947     }
2948   else
2949     {
2950       op0 = gfc_conv_powi (se, n >> 1, tmpvar);
2951       op1 = op0;
2952     }
2953 
2954   tmp = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (op0), op0, op1);
2955   tmp = gfc_evaluate_now (tmp, &se->pre);
2956 
2957   if (n < POWI_TABLE_SIZE)
2958     tmpvar[n] = tmp;
2959 
2960   return tmp;
2961 }
2962 
2963 
2964 /* Expand lhs ** rhs. rhs is a constant integer. If it expands successfully,
2965    return 1. Else return 0 and a call to runtime library functions
2966    will have to be built.  */
2967 static int
2968 gfc_conv_cst_int_power (gfc_se * se, tree lhs, tree rhs)
2969 {
2970   tree cond;
2971   tree tmp;
2972   tree type;
2973   tree vartmp[POWI_TABLE_SIZE];
2974   HOST_WIDE_INT m;
2975   unsigned HOST_WIDE_INT n;
2976   int sgn;
2977   wi::tree_to_wide_ref wrhs = wi::to_wide (rhs);
2978 
2979   /* If exponent is too large, we won't expand it anyway, so don't bother
2980      with large integer values.  */
2981   if (!wi::fits_shwi_p (wrhs))
2982     return 0;
2983 
2984   m = wrhs.to_shwi ();
2985   /* Use the wide_int's routine to reliably get the absolute value on all
2986      platforms.  Then convert it to a HOST_WIDE_INT like above.  */
2987   n = wi::abs (wrhs).to_shwi ();
2988 
2989   type = TREE_TYPE (lhs);
2990   sgn = tree_int_cst_sgn (rhs);
2991 
2992   if (((FLOAT_TYPE_P (type) && !flag_unsafe_math_optimizations)
2993        || optimize_size) && (m > 2 || m < -1))
2994     return 0;
2995 
2996   /* rhs == 0  */
2997   if (sgn == 0)
2998     {
2999       se->expr = gfc_build_const (type, integer_one_node);
3000       return 1;
3001     }
3002 
3003   /* If rhs < 0 and lhs is an integer, the result is -1, 0 or 1.  */
3004   if ((sgn == -1) && (TREE_CODE (type) == INTEGER_TYPE))
3005     {
3006       tmp = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
3007 			     lhs, build_int_cst (TREE_TYPE (lhs), -1));
3008       cond = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
3009 			      lhs, build_int_cst (TREE_TYPE (lhs), 1));
3010 
3011       /* If rhs is even,
3012 	 result = (lhs == 1 || lhs == -1) ? 1 : 0.  */
3013       if ((n & 1) == 0)
3014         {
3015 	  tmp = fold_build2_loc (input_location, TRUTH_OR_EXPR,
3016 				 logical_type_node, tmp, cond);
3017 	  se->expr = fold_build3_loc (input_location, COND_EXPR, type,
3018 				      tmp, build_int_cst (type, 1),
3019 				      build_int_cst (type, 0));
3020 	  return 1;
3021 	}
3022       /* If rhs is odd,
3023 	 result = (lhs == 1) ? 1 : (lhs == -1) ? -1 : 0.  */
3024       tmp = fold_build3_loc (input_location, COND_EXPR, type, tmp,
3025 			     build_int_cst (type, -1),
3026 			     build_int_cst (type, 0));
3027       se->expr = fold_build3_loc (input_location, COND_EXPR, type,
3028 				  cond, build_int_cst (type, 1), tmp);
3029       return 1;
3030     }
3031 
3032   memset (vartmp, 0, sizeof (vartmp));
3033   vartmp[1] = lhs;
3034   if (sgn == -1)
3035     {
3036       tmp = gfc_build_const (type, integer_one_node);
3037       vartmp[1] = fold_build2_loc (input_location, RDIV_EXPR, type, tmp,
3038 				   vartmp[1]);
3039     }
3040 
3041   se->expr = gfc_conv_powi (se, n, vartmp);
3042 
3043   return 1;
3044 }
3045 
3046 
3047 /* Power op (**).  Constant integer exponent has special handling.  */
3048 
3049 static void
3050 gfc_conv_power_op (gfc_se * se, gfc_expr * expr)
3051 {
3052   tree gfc_int4_type_node;
3053   int kind;
3054   int ikind;
3055   int res_ikind_1, res_ikind_2;
3056   gfc_se lse;
3057   gfc_se rse;
3058   tree fndecl = NULL;
3059 
3060   gfc_init_se (&lse, se);
3061   gfc_conv_expr_val (&lse, expr->value.op.op1);
3062   lse.expr = gfc_evaluate_now (lse.expr, &lse.pre);
3063   gfc_add_block_to_block (&se->pre, &lse.pre);
3064 
3065   gfc_init_se (&rse, se);
3066   gfc_conv_expr_val (&rse, expr->value.op.op2);
3067   gfc_add_block_to_block (&se->pre, &rse.pre);
3068 
3069   if (expr->value.op.op2->ts.type == BT_INTEGER
3070       && expr->value.op.op2->expr_type == EXPR_CONSTANT)
3071     if (gfc_conv_cst_int_power (se, lse.expr, rse.expr))
3072       return;
3073 
3074   if (INTEGER_CST_P (lse.expr)
3075       && TREE_CODE (TREE_TYPE (rse.expr)) == INTEGER_TYPE)
3076     {
3077       wi::tree_to_wide_ref wlhs = wi::to_wide (lse.expr);
3078       HOST_WIDE_INT v, w;
3079       int kind, ikind, bit_size;
3080 
3081       v = wlhs.to_shwi ();
3082       w = abs (v);
3083 
3084       kind = expr->value.op.op1->ts.kind;
3085       ikind = gfc_validate_kind (BT_INTEGER, kind, false);
3086       bit_size = gfc_integer_kinds[ikind].bit_size;
3087 
3088       if (v == 1)
3089 	{
3090 	  /* 1**something is always 1.  */
3091 	  se->expr = build_int_cst (TREE_TYPE (lse.expr), 1);
3092 	  return;
3093 	}
3094       else if (v == -1)
3095 	{
3096 	  /* (-1)**n is 1 - ((n & 1) << 1) */
3097 	  tree type;
3098 	  tree tmp;
3099 
3100 	  type = TREE_TYPE (lse.expr);
3101 	  tmp = fold_build2_loc (input_location, BIT_AND_EXPR, type,
3102 				 rse.expr, build_int_cst (type, 1));
3103 	  tmp = fold_build2_loc (input_location, LSHIFT_EXPR, type,
3104 				 tmp, build_int_cst (type, 1));
3105 	  tmp = fold_build2_loc (input_location, MINUS_EXPR, type,
3106 				 build_int_cst (type, 1), tmp);
3107 	  se->expr = tmp;
3108 	  return;
3109 	}
3110       else if (w > 0 && ((w & (w-1)) == 0) && ((w >> (bit_size-1)) == 0))
3111 	{
3112 	  /* Here v is +/- 2**e.  The further simplification uses
3113 	     2**n = 1<<n, 4**n = 1<<(n+n), 8**n = 1 <<(3*n), 16**n =
3114 	     1<<(4*n), etc., but we have to make sure to return zero
3115 	     if the number of bits is too large. */
3116 	  tree lshift;
3117 	  tree type;
3118 	  tree shift;
3119 	  tree ge;
3120 	  tree cond;
3121 	  tree num_bits;
3122 	  tree cond2;
3123 	  tree tmp1;
3124 
3125 	  type = TREE_TYPE (lse.expr);
3126 
3127 	  if (w == 2)
3128 	    shift = rse.expr;
3129 	  else if (w == 4)
3130 	    shift = fold_build2_loc (input_location, PLUS_EXPR,
3131 				     TREE_TYPE (rse.expr),
3132 				       rse.expr, rse.expr);
3133 	  else
3134 	    {
3135 	      /* use popcount for fast log2(w) */
3136 	      int e = wi::popcount (w-1);
3137 	      shift = fold_build2_loc (input_location, MULT_EXPR,
3138 				       TREE_TYPE (rse.expr),
3139 				       build_int_cst (TREE_TYPE (rse.expr), e),
3140 				       rse.expr);
3141 	    }
3142 
3143 	  lshift = fold_build2_loc (input_location, LSHIFT_EXPR, type,
3144 				    build_int_cst (type, 1), shift);
3145 	  ge = fold_build2_loc (input_location, GE_EXPR, logical_type_node,
3146 				rse.expr, build_int_cst (type, 0));
3147 	  cond = fold_build3_loc (input_location, COND_EXPR, type, ge, lshift,
3148 				 build_int_cst (type, 0));
3149 	  num_bits = build_int_cst (TREE_TYPE (rse.expr), TYPE_PRECISION (type));
3150 	  cond2 = fold_build2_loc (input_location, GE_EXPR, logical_type_node,
3151 				   rse.expr, num_bits);
3152 	  tmp1 = fold_build3_loc (input_location, COND_EXPR, type, cond2,
3153 				  build_int_cst (type, 0), cond);
3154 	  if (v > 0)
3155 	    {
3156 	      se->expr = tmp1;
3157 	    }
3158 	  else
3159 	    {
3160 	      /* for v < 0, calculate v**n = |v|**n * (-1)**n */
3161 	      tree tmp2;
3162 	      tmp2 = fold_build2_loc (input_location, BIT_AND_EXPR, type,
3163 				      rse.expr, build_int_cst (type, 1));
3164 	      tmp2 = fold_build2_loc (input_location, LSHIFT_EXPR, type,
3165 				      tmp2, build_int_cst (type, 1));
3166 	      tmp2 = fold_build2_loc (input_location, MINUS_EXPR, type,
3167 				      build_int_cst (type, 1), tmp2);
3168 	      se->expr = fold_build2_loc (input_location, MULT_EXPR, type,
3169 					  tmp1, tmp2);
3170 	    }
3171 	  return;
3172 	}
3173     }
3174 
3175   gfc_int4_type_node = gfc_get_int_type (4);
3176 
3177   /* In case of integer operands with kinds 1 or 2, we call the integer kind 4
3178      library routine.  But in the end, we have to convert the result back
3179      if this case applies -- with res_ikind_K, we keep track whether operand K
3180      falls into this case.  */
3181   res_ikind_1 = -1;
3182   res_ikind_2 = -1;
3183 
3184   kind = expr->value.op.op1->ts.kind;
3185   switch (expr->value.op.op2->ts.type)
3186     {
3187     case BT_INTEGER:
3188       ikind = expr->value.op.op2->ts.kind;
3189       switch (ikind)
3190 	{
3191 	case 1:
3192 	case 2:
3193 	  rse.expr = convert (gfc_int4_type_node, rse.expr);
3194 	  res_ikind_2 = ikind;
3195 	  /* Fall through.  */
3196 
3197 	case 4:
3198 	  ikind = 0;
3199 	  break;
3200 
3201 	case 8:
3202 	  ikind = 1;
3203 	  break;
3204 
3205 	case 16:
3206 	  ikind = 2;
3207 	  break;
3208 
3209 	default:
3210 	  gcc_unreachable ();
3211 	}
3212       switch (kind)
3213 	{
3214 	case 1:
3215 	case 2:
3216 	  if (expr->value.op.op1->ts.type == BT_INTEGER)
3217 	    {
3218 	      lse.expr = convert (gfc_int4_type_node, lse.expr);
3219 	      res_ikind_1 = kind;
3220 	    }
3221 	  else
3222 	    gcc_unreachable ();
3223 	  /* Fall through.  */
3224 
3225 	case 4:
3226 	  kind = 0;
3227 	  break;
3228 
3229 	case 8:
3230 	  kind = 1;
3231 	  break;
3232 
3233 	case 10:
3234 	  kind = 2;
3235 	  break;
3236 
3237 	case 16:
3238 	  kind = 3;
3239 	  break;
3240 
3241 	default:
3242 	  gcc_unreachable ();
3243 	}
3244 
3245       switch (expr->value.op.op1->ts.type)
3246 	{
3247 	case BT_INTEGER:
3248 	  if (kind == 3) /* Case 16 was not handled properly above.  */
3249 	    kind = 2;
3250 	  fndecl = gfor_fndecl_math_powi[kind][ikind].integer;
3251 	  break;
3252 
3253 	case BT_REAL:
3254 	  /* Use builtins for real ** int4.  */
3255 	  if (ikind == 0)
3256 	    {
3257 	      switch (kind)
3258 		{
3259 		case 0:
3260 		  fndecl = builtin_decl_explicit (BUILT_IN_POWIF);
3261 		  break;
3262 
3263 		case 1:
3264 		  fndecl = builtin_decl_explicit (BUILT_IN_POWI);
3265 		  break;
3266 
3267 		case 2:
3268 		  fndecl = builtin_decl_explicit (BUILT_IN_POWIL);
3269 		  break;
3270 
3271 		case 3:
3272 		  /* Use the __builtin_powil() only if real(kind=16) is
3273 		     actually the C long double type.  */
3274 		  if (!gfc_real16_is_float128)
3275 		    fndecl = builtin_decl_explicit (BUILT_IN_POWIL);
3276 		  break;
3277 
3278 		default:
3279 		  gcc_unreachable ();
3280 		}
3281 	    }
3282 
3283 	  /* If we don't have a good builtin for this, go for the
3284 	     library function.  */
3285 	  if (!fndecl)
3286 	    fndecl = gfor_fndecl_math_powi[kind][ikind].real;
3287 	  break;
3288 
3289 	case BT_COMPLEX:
3290 	  fndecl = gfor_fndecl_math_powi[kind][ikind].cmplx;
3291 	  break;
3292 
3293 	default:
3294 	  gcc_unreachable ();
3295  	}
3296       break;
3297 
3298     case BT_REAL:
3299       fndecl = gfc_builtin_decl_for_float_kind (BUILT_IN_POW, kind);
3300       break;
3301 
3302     case BT_COMPLEX:
3303       fndecl = gfc_builtin_decl_for_float_kind (BUILT_IN_CPOW, kind);
3304       break;
3305 
3306     default:
3307       gcc_unreachable ();
3308       break;
3309     }
3310 
3311   se->expr = build_call_expr_loc (input_location,
3312 			      fndecl, 2, lse.expr, rse.expr);
3313 
3314   /* Convert the result back if it is of wrong integer kind.  */
3315   if (res_ikind_1 != -1 && res_ikind_2 != -1)
3316     {
3317       /* We want the maximum of both operand kinds as result.  */
3318       if (res_ikind_1 < res_ikind_2)
3319 	res_ikind_1 = res_ikind_2;
3320       se->expr = convert (gfc_get_int_type (res_ikind_1), se->expr);
3321     }
3322 }
3323 
3324 
3325 /* Generate code to allocate a string temporary.  */
3326 
3327 tree
3328 gfc_conv_string_tmp (gfc_se * se, tree type, tree len)
3329 {
3330   tree var;
3331   tree tmp;
3332 
3333   if (gfc_can_put_var_on_stack (len))
3334     {
3335       /* Create a temporary variable to hold the result.  */
3336       tmp = fold_build2_loc (input_location, MINUS_EXPR,
3337 			     TREE_TYPE (len), len,
3338 			     build_int_cst (TREE_TYPE (len), 1));
3339       tmp = build_range_type (gfc_charlen_type_node, size_zero_node, tmp);
3340 
3341       if (TREE_CODE (TREE_TYPE (type)) == ARRAY_TYPE)
3342 	tmp = build_array_type (TREE_TYPE (TREE_TYPE (type)), tmp);
3343       else
3344 	tmp = build_array_type (TREE_TYPE (type), tmp);
3345 
3346       var = gfc_create_var (tmp, "str");
3347       var = gfc_build_addr_expr (type, var);
3348     }
3349   else
3350     {
3351       /* Allocate a temporary to hold the result.  */
3352       var = gfc_create_var (type, "pstr");
3353       gcc_assert (POINTER_TYPE_P (type));
3354       tmp = TREE_TYPE (type);
3355       if (TREE_CODE (tmp) == ARRAY_TYPE)
3356         tmp = TREE_TYPE (tmp);
3357       tmp = TYPE_SIZE_UNIT (tmp);
3358       tmp = fold_build2_loc (input_location, MULT_EXPR, size_type_node,
3359 			    fold_convert (size_type_node, len),
3360 			    fold_convert (size_type_node, tmp));
3361       tmp = gfc_call_malloc (&se->pre, type, tmp);
3362       gfc_add_modify (&se->pre, var, tmp);
3363 
3364       /* Free the temporary afterwards.  */
3365       tmp = gfc_call_free (var);
3366       gfc_add_expr_to_block (&se->post, tmp);
3367     }
3368 
3369   return var;
3370 }
3371 
3372 
3373 /* Handle a string concatenation operation.  A temporary will be allocated to
3374    hold the result.  */
3375 
3376 static void
3377 gfc_conv_concat_op (gfc_se * se, gfc_expr * expr)
3378 {
3379   gfc_se lse, rse;
3380   tree len, type, var, tmp, fndecl;
3381 
3382   gcc_assert (expr->value.op.op1->ts.type == BT_CHARACTER
3383 	      && expr->value.op.op2->ts.type == BT_CHARACTER);
3384   gcc_assert (expr->value.op.op1->ts.kind == expr->value.op.op2->ts.kind);
3385 
3386   gfc_init_se (&lse, se);
3387   gfc_conv_expr (&lse, expr->value.op.op1);
3388   gfc_conv_string_parameter (&lse);
3389   gfc_init_se (&rse, se);
3390   gfc_conv_expr (&rse, expr->value.op.op2);
3391   gfc_conv_string_parameter (&rse);
3392 
3393   gfc_add_block_to_block (&se->pre, &lse.pre);
3394   gfc_add_block_to_block (&se->pre, &rse.pre);
3395 
3396   type = gfc_get_character_type (expr->ts.kind, expr->ts.u.cl);
3397   len = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
3398   if (len == NULL_TREE)
3399     {
3400       len = fold_build2_loc (input_location, PLUS_EXPR,
3401 			     gfc_charlen_type_node,
3402 			     fold_convert (gfc_charlen_type_node,
3403 					   lse.string_length),
3404 			     fold_convert (gfc_charlen_type_node,
3405 					   rse.string_length));
3406     }
3407 
3408   type = build_pointer_type (type);
3409 
3410   var = gfc_conv_string_tmp (se, type, len);
3411 
3412   /* Do the actual concatenation.  */
3413   if (expr->ts.kind == 1)
3414     fndecl = gfor_fndecl_concat_string;
3415   else if (expr->ts.kind == 4)
3416     fndecl = gfor_fndecl_concat_string_char4;
3417   else
3418     gcc_unreachable ();
3419 
3420   tmp = build_call_expr_loc (input_location,
3421 			 fndecl, 6, len, var, lse.string_length, lse.expr,
3422 			 rse.string_length, rse.expr);
3423   gfc_add_expr_to_block (&se->pre, tmp);
3424 
3425   /* Add the cleanup for the operands.  */
3426   gfc_add_block_to_block (&se->pre, &rse.post);
3427   gfc_add_block_to_block (&se->pre, &lse.post);
3428 
3429   se->expr = var;
3430   se->string_length = len;
3431 }
3432 
3433 /* Translates an op expression. Common (binary) cases are handled by this
3434    function, others are passed on. Recursion is used in either case.
3435    We use the fact that (op1.ts == op2.ts) (except for the power
3436    operator **).
3437    Operators need no special handling for scalarized expressions as long as
3438    they call gfc_conv_simple_val to get their operands.
3439    Character strings get special handling.  */
3440 
3441 static void
3442 gfc_conv_expr_op (gfc_se * se, gfc_expr * expr)
3443 {
3444   enum tree_code code;
3445   gfc_se lse;
3446   gfc_se rse;
3447   tree tmp, type;
3448   int lop;
3449   int checkstring;
3450 
3451   checkstring = 0;
3452   lop = 0;
3453   switch (expr->value.op.op)
3454     {
3455     case INTRINSIC_PARENTHESES:
3456       if ((expr->ts.type == BT_REAL || expr->ts.type == BT_COMPLEX)
3457 	  && flag_protect_parens)
3458 	{
3459 	  gfc_conv_unary_op (PAREN_EXPR, se, expr);
3460 	  gcc_assert (FLOAT_TYPE_P (TREE_TYPE (se->expr)));
3461 	  return;
3462 	}
3463 
3464       /* Fallthrough.  */
3465     case INTRINSIC_UPLUS:
3466       gfc_conv_expr (se, expr->value.op.op1);
3467       return;
3468 
3469     case INTRINSIC_UMINUS:
3470       gfc_conv_unary_op (NEGATE_EXPR, se, expr);
3471       return;
3472 
3473     case INTRINSIC_NOT:
3474       gfc_conv_unary_op (TRUTH_NOT_EXPR, se, expr);
3475       return;
3476 
3477     case INTRINSIC_PLUS:
3478       code = PLUS_EXPR;
3479       break;
3480 
3481     case INTRINSIC_MINUS:
3482       code = MINUS_EXPR;
3483       break;
3484 
3485     case INTRINSIC_TIMES:
3486       code = MULT_EXPR;
3487       break;
3488 
3489     case INTRINSIC_DIVIDE:
3490       /* If expr is a real or complex expr, use an RDIV_EXPR. If op1 is
3491          an integer, we must round towards zero, so we use a
3492          TRUNC_DIV_EXPR.  */
3493       if (expr->ts.type == BT_INTEGER)
3494 	code = TRUNC_DIV_EXPR;
3495       else
3496 	code = RDIV_EXPR;
3497       break;
3498 
3499     case INTRINSIC_POWER:
3500       gfc_conv_power_op (se, expr);
3501       return;
3502 
3503     case INTRINSIC_CONCAT:
3504       gfc_conv_concat_op (se, expr);
3505       return;
3506 
3507     case INTRINSIC_AND:
3508       code = flag_frontend_optimize ? TRUTH_ANDIF_EXPR : TRUTH_AND_EXPR;
3509       lop = 1;
3510       break;
3511 
3512     case INTRINSIC_OR:
3513       code = flag_frontend_optimize ? TRUTH_ORIF_EXPR : TRUTH_OR_EXPR;
3514       lop = 1;
3515       break;
3516 
3517       /* EQV and NEQV only work on logicals, but since we represent them
3518          as integers, we can use EQ_EXPR and NE_EXPR for them in GIMPLE.  */
3519     case INTRINSIC_EQ:
3520     case INTRINSIC_EQ_OS:
3521     case INTRINSIC_EQV:
3522       code = EQ_EXPR;
3523       checkstring = 1;
3524       lop = 1;
3525       break;
3526 
3527     case INTRINSIC_NE:
3528     case INTRINSIC_NE_OS:
3529     case INTRINSIC_NEQV:
3530       code = NE_EXPR;
3531       checkstring = 1;
3532       lop = 1;
3533       break;
3534 
3535     case INTRINSIC_GT:
3536     case INTRINSIC_GT_OS:
3537       code = GT_EXPR;
3538       checkstring = 1;
3539       lop = 1;
3540       break;
3541 
3542     case INTRINSIC_GE:
3543     case INTRINSIC_GE_OS:
3544       code = GE_EXPR;
3545       checkstring = 1;
3546       lop = 1;
3547       break;
3548 
3549     case INTRINSIC_LT:
3550     case INTRINSIC_LT_OS:
3551       code = LT_EXPR;
3552       checkstring = 1;
3553       lop = 1;
3554       break;
3555 
3556     case INTRINSIC_LE:
3557     case INTRINSIC_LE_OS:
3558       code = LE_EXPR;
3559       checkstring = 1;
3560       lop = 1;
3561       break;
3562 
3563     case INTRINSIC_USER:
3564     case INTRINSIC_ASSIGN:
3565       /* These should be converted into function calls by the frontend.  */
3566       gcc_unreachable ();
3567 
3568     default:
3569       fatal_error (input_location, "Unknown intrinsic op");
3570       return;
3571     }
3572 
3573   /* The only exception to this is **, which is handled separately anyway.  */
3574   gcc_assert (expr->value.op.op1->ts.type == expr->value.op.op2->ts.type);
3575 
3576   if (checkstring && expr->value.op.op1->ts.type != BT_CHARACTER)
3577     checkstring = 0;
3578 
3579   /* lhs */
3580   gfc_init_se (&lse, se);
3581   gfc_conv_expr (&lse, expr->value.op.op1);
3582   gfc_add_block_to_block (&se->pre, &lse.pre);
3583 
3584   /* rhs */
3585   gfc_init_se (&rse, se);
3586   gfc_conv_expr (&rse, expr->value.op.op2);
3587   gfc_add_block_to_block (&se->pre, &rse.pre);
3588 
3589   if (checkstring)
3590     {
3591       gfc_conv_string_parameter (&lse);
3592       gfc_conv_string_parameter (&rse);
3593 
3594       lse.expr = gfc_build_compare_string (lse.string_length, lse.expr,
3595 					   rse.string_length, rse.expr,
3596 					   expr->value.op.op1->ts.kind,
3597 					   code);
3598       rse.expr = build_int_cst (TREE_TYPE (lse.expr), 0);
3599       gfc_add_block_to_block (&lse.post, &rse.post);
3600     }
3601 
3602   type = gfc_typenode_for_spec (&expr->ts);
3603 
3604   if (lop)
3605     {
3606       /* The result of logical ops is always logical_type_node.  */
3607       tmp = fold_build2_loc (input_location, code, logical_type_node,
3608 			     lse.expr, rse.expr);
3609       se->expr = convert (type, tmp);
3610     }
3611   else
3612     se->expr = fold_build2_loc (input_location, code, type, lse.expr, rse.expr);
3613 
3614   /* Add the post blocks.  */
3615   gfc_add_block_to_block (&se->post, &rse.post);
3616   gfc_add_block_to_block (&se->post, &lse.post);
3617 }
3618 
3619 /* If a string's length is one, we convert it to a single character.  */
3620 
3621 tree
3622 gfc_string_to_single_character (tree len, tree str, int kind)
3623 {
3624 
3625   if (len == NULL
3626       || !tree_fits_uhwi_p (len)
3627       || !POINTER_TYPE_P (TREE_TYPE (str)))
3628     return NULL_TREE;
3629 
3630   if (TREE_INT_CST_LOW (len) == 1)
3631     {
3632       str = fold_convert (gfc_get_pchar_type (kind), str);
3633       return build_fold_indirect_ref_loc (input_location, str);
3634     }
3635 
3636   if (kind == 1
3637       && TREE_CODE (str) == ADDR_EXPR
3638       && TREE_CODE (TREE_OPERAND (str, 0)) == ARRAY_REF
3639       && TREE_CODE (TREE_OPERAND (TREE_OPERAND (str, 0), 0)) == STRING_CST
3640       && array_ref_low_bound (TREE_OPERAND (str, 0))
3641 	 == TREE_OPERAND (TREE_OPERAND (str, 0), 1)
3642       && TREE_INT_CST_LOW (len) > 1
3643       && TREE_INT_CST_LOW (len)
3644 	 == (unsigned HOST_WIDE_INT)
3645 	    TREE_STRING_LENGTH (TREE_OPERAND (TREE_OPERAND (str, 0), 0)))
3646     {
3647       tree ret = fold_convert (gfc_get_pchar_type (kind), str);
3648       ret = build_fold_indirect_ref_loc (input_location, ret);
3649       if (TREE_CODE (ret) == INTEGER_CST)
3650 	{
3651 	  tree string_cst = TREE_OPERAND (TREE_OPERAND (str, 0), 0);
3652 	  int i, length = TREE_STRING_LENGTH (string_cst);
3653 	  const char *ptr = TREE_STRING_POINTER (string_cst);
3654 
3655 	  for (i = 1; i < length; i++)
3656 	    if (ptr[i] != ' ')
3657 	      return NULL_TREE;
3658 
3659 	  return ret;
3660 	}
3661     }
3662 
3663   return NULL_TREE;
3664 }
3665 
3666 
3667 void
3668 gfc_conv_scalar_char_value (gfc_symbol *sym, gfc_se *se, gfc_expr **expr)
3669 {
3670 
3671   if (sym->backend_decl)
3672     {
3673       /* This becomes the nominal_type in
3674 	 function.c:assign_parm_find_data_types.  */
3675       TREE_TYPE (sym->backend_decl) = unsigned_char_type_node;
3676       /* This becomes the passed_type in
3677 	 function.c:assign_parm_find_data_types.  C promotes char to
3678 	 integer for argument passing.  */
3679       DECL_ARG_TYPE (sym->backend_decl) = unsigned_type_node;
3680 
3681       DECL_BY_REFERENCE (sym->backend_decl) = 0;
3682     }
3683 
3684   if (expr != NULL)
3685     {
3686       /* If we have a constant character expression, make it into an
3687 	 integer.  */
3688       if ((*expr)->expr_type == EXPR_CONSTANT)
3689         {
3690 	  gfc_typespec ts;
3691           gfc_clear_ts (&ts);
3692 
3693 	  *expr = gfc_get_int_expr (gfc_default_integer_kind, NULL,
3694 				    (int)(*expr)->value.character.string[0]);
3695 	  if ((*expr)->ts.kind != gfc_c_int_kind)
3696 	    {
3697   	      /* The expr needs to be compatible with a C int.  If the
3698 		 conversion fails, then the 2 causes an ICE.  */
3699 	      ts.type = BT_INTEGER;
3700 	      ts.kind = gfc_c_int_kind;
3701 	      gfc_convert_type (*expr, &ts, 2);
3702 	    }
3703 	}
3704       else if (se != NULL && (*expr)->expr_type == EXPR_VARIABLE)
3705         {
3706 	  if ((*expr)->ref == NULL)
3707 	    {
3708 	      se->expr = gfc_string_to_single_character
3709 		(build_int_cst (integer_type_node, 1),
3710 		 gfc_build_addr_expr (gfc_get_pchar_type ((*expr)->ts.kind),
3711 				      gfc_get_symbol_decl
3712 				      ((*expr)->symtree->n.sym)),
3713 		 (*expr)->ts.kind);
3714 	    }
3715 	  else
3716 	    {
3717 	      gfc_conv_variable (se, *expr);
3718 	      se->expr = gfc_string_to_single_character
3719 		(build_int_cst (integer_type_node, 1),
3720 		 gfc_build_addr_expr (gfc_get_pchar_type ((*expr)->ts.kind),
3721 				      se->expr),
3722 		 (*expr)->ts.kind);
3723 	    }
3724 	}
3725     }
3726 }
3727 
3728 /* Helper function for gfc_build_compare_string.  Return LEN_TRIM value
3729    if STR is a string literal, otherwise return -1.  */
3730 
3731 static int
3732 gfc_optimize_len_trim (tree len, tree str, int kind)
3733 {
3734   if (kind == 1
3735       && TREE_CODE (str) == ADDR_EXPR
3736       && TREE_CODE (TREE_OPERAND (str, 0)) == ARRAY_REF
3737       && TREE_CODE (TREE_OPERAND (TREE_OPERAND (str, 0), 0)) == STRING_CST
3738       && array_ref_low_bound (TREE_OPERAND (str, 0))
3739 	 == TREE_OPERAND (TREE_OPERAND (str, 0), 1)
3740       && tree_fits_uhwi_p (len)
3741       && tree_to_uhwi (len) >= 1
3742       && tree_to_uhwi (len)
3743 	 == (unsigned HOST_WIDE_INT)
3744 	    TREE_STRING_LENGTH (TREE_OPERAND (TREE_OPERAND (str, 0), 0)))
3745     {
3746       tree folded = fold_convert (gfc_get_pchar_type (kind), str);
3747       folded = build_fold_indirect_ref_loc (input_location, folded);
3748       if (TREE_CODE (folded) == INTEGER_CST)
3749 	{
3750 	  tree string_cst = TREE_OPERAND (TREE_OPERAND (str, 0), 0);
3751 	  int length = TREE_STRING_LENGTH (string_cst);
3752 	  const char *ptr = TREE_STRING_POINTER (string_cst);
3753 
3754 	  for (; length > 0; length--)
3755 	    if (ptr[length - 1] != ' ')
3756 	      break;
3757 
3758 	  return length;
3759 	}
3760     }
3761   return -1;
3762 }
3763 
3764 /* Helper to build a call to memcmp.  */
3765 
3766 static tree
3767 build_memcmp_call (tree s1, tree s2, tree n)
3768 {
3769   tree tmp;
3770 
3771   if (!POINTER_TYPE_P (TREE_TYPE (s1)))
3772     s1 = gfc_build_addr_expr (pvoid_type_node, s1);
3773   else
3774     s1 = fold_convert (pvoid_type_node, s1);
3775 
3776   if (!POINTER_TYPE_P (TREE_TYPE (s2)))
3777     s2 = gfc_build_addr_expr (pvoid_type_node, s2);
3778   else
3779     s2 = fold_convert (pvoid_type_node, s2);
3780 
3781   n = fold_convert (size_type_node, n);
3782 
3783   tmp = build_call_expr_loc (input_location,
3784 			     builtin_decl_explicit (BUILT_IN_MEMCMP),
3785 			     3, s1, s2, n);
3786 
3787   return fold_convert (integer_type_node, tmp);
3788 }
3789 
3790 /* Compare two strings. If they are all single characters, the result is the
3791    subtraction of them. Otherwise, we build a library call.  */
3792 
3793 tree
3794 gfc_build_compare_string (tree len1, tree str1, tree len2, tree str2, int kind,
3795 			  enum tree_code code)
3796 {
3797   tree sc1;
3798   tree sc2;
3799   tree fndecl;
3800 
3801   gcc_assert (POINTER_TYPE_P (TREE_TYPE (str1)));
3802   gcc_assert (POINTER_TYPE_P (TREE_TYPE (str2)));
3803 
3804   sc1 = gfc_string_to_single_character (len1, str1, kind);
3805   sc2 = gfc_string_to_single_character (len2, str2, kind);
3806 
3807   if (sc1 != NULL_TREE && sc2 != NULL_TREE)
3808     {
3809       /* Deal with single character specially.  */
3810       sc1 = fold_convert (integer_type_node, sc1);
3811       sc2 = fold_convert (integer_type_node, sc2);
3812       return fold_build2_loc (input_location, MINUS_EXPR, integer_type_node,
3813 			      sc1, sc2);
3814     }
3815 
3816   if ((code == EQ_EXPR || code == NE_EXPR)
3817       && optimize
3818       && INTEGER_CST_P (len1) && INTEGER_CST_P (len2))
3819     {
3820       /* If one string is a string literal with LEN_TRIM longer
3821 	 than the length of the second string, the strings
3822 	 compare unequal.  */
3823       int len = gfc_optimize_len_trim (len1, str1, kind);
3824       if (len > 0 && compare_tree_int (len2, len) < 0)
3825 	return integer_one_node;
3826       len = gfc_optimize_len_trim (len2, str2, kind);
3827       if (len > 0 && compare_tree_int (len1, len) < 0)
3828 	return integer_one_node;
3829     }
3830 
3831   /* We can compare via memcpy if the strings are known to be equal
3832      in length and they are
3833      - kind=1
3834      - kind=4 and the comparison is for (in)equality.  */
3835 
3836   if (INTEGER_CST_P (len1) && INTEGER_CST_P (len2)
3837       && tree_int_cst_equal (len1, len2)
3838       && (kind == 1 || code == EQ_EXPR || code == NE_EXPR))
3839     {
3840       tree tmp;
3841       tree chartype;
3842 
3843       chartype = gfc_get_char_type (kind);
3844       tmp = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE(len1),
3845 			     fold_convert (TREE_TYPE(len1),
3846 					   TYPE_SIZE_UNIT(chartype)),
3847 			     len1);
3848       return build_memcmp_call (str1, str2, tmp);
3849     }
3850 
3851   /* Build a call for the comparison.  */
3852   if (kind == 1)
3853     fndecl = gfor_fndecl_compare_string;
3854   else if (kind == 4)
3855     fndecl = gfor_fndecl_compare_string_char4;
3856   else
3857     gcc_unreachable ();
3858 
3859   return build_call_expr_loc (input_location, fndecl, 4,
3860 			      len1, str1, len2, str2);
3861 }
3862 
3863 
3864 /* Return the backend_decl for a procedure pointer component.  */
3865 
3866 static tree
3867 get_proc_ptr_comp (gfc_expr *e)
3868 {
3869   gfc_se comp_se;
3870   gfc_expr *e2;
3871   expr_t old_type;
3872 
3873   gfc_init_se (&comp_se, NULL);
3874   e2 = gfc_copy_expr (e);
3875   /* We have to restore the expr type later so that gfc_free_expr frees
3876      the exact same thing that was allocated.
3877      TODO: This is ugly.  */
3878   old_type = e2->expr_type;
3879   e2->expr_type = EXPR_VARIABLE;
3880   gfc_conv_expr (&comp_se, e2);
3881   e2->expr_type = old_type;
3882   gfc_free_expr (e2);
3883   return build_fold_addr_expr_loc (input_location, comp_se.expr);
3884 }
3885 
3886 
3887 /* Convert a typebound function reference from a class object.  */
3888 static void
3889 conv_base_obj_fcn_val (gfc_se * se, tree base_object, gfc_expr * expr)
3890 {
3891   gfc_ref *ref;
3892   tree var;
3893 
3894   if (!VAR_P (base_object))
3895     {
3896       var = gfc_create_var (TREE_TYPE (base_object), NULL);
3897       gfc_add_modify (&se->pre, var, base_object);
3898     }
3899   se->expr = gfc_class_vptr_get (base_object);
3900   se->expr = build_fold_indirect_ref_loc (input_location, se->expr);
3901   ref = expr->ref;
3902   while (ref && ref->next)
3903     ref = ref->next;
3904   gcc_assert (ref && ref->type == REF_COMPONENT);
3905   if (ref->u.c.sym->attr.extension)
3906     conv_parent_component_references (se, ref);
3907   gfc_conv_component_ref (se, ref);
3908   se->expr = build_fold_addr_expr_loc (input_location, se->expr);
3909 }
3910 
3911 
3912 static void
3913 conv_function_val (gfc_se * se, gfc_symbol * sym, gfc_expr * expr,
3914 		   gfc_actual_arglist *actual_args)
3915 {
3916   tree tmp;
3917 
3918   if (gfc_is_proc_ptr_comp (expr))
3919     tmp = get_proc_ptr_comp (expr);
3920   else if (sym->attr.dummy)
3921     {
3922       tmp = gfc_get_symbol_decl (sym);
3923       if (sym->attr.proc_pointer)
3924         tmp = build_fold_indirect_ref_loc (input_location,
3925 				       tmp);
3926       gcc_assert (TREE_CODE (TREE_TYPE (tmp)) == POINTER_TYPE
3927 	      && TREE_CODE (TREE_TYPE (TREE_TYPE (tmp))) == FUNCTION_TYPE);
3928     }
3929   else
3930     {
3931       if (!sym->backend_decl)
3932 	sym->backend_decl = gfc_get_extern_function_decl (sym, actual_args);
3933 
3934       TREE_USED (sym->backend_decl) = 1;
3935 
3936       tmp = sym->backend_decl;
3937 
3938       if (sym->attr.cray_pointee)
3939 	{
3940 	  /* TODO - make the cray pointee a pointer to a procedure,
3941 	     assign the pointer to it and use it for the call.  This
3942 	     will do for now!  */
3943 	  tmp = convert (build_pointer_type (TREE_TYPE (tmp)),
3944 			 gfc_get_symbol_decl (sym->cp_pointer));
3945 	  tmp = gfc_evaluate_now (tmp, &se->pre);
3946 	}
3947 
3948       if (!POINTER_TYPE_P (TREE_TYPE (tmp)))
3949 	{
3950 	  gcc_assert (TREE_CODE (tmp) == FUNCTION_DECL);
3951 	  tmp = gfc_build_addr_expr (NULL_TREE, tmp);
3952 	}
3953     }
3954   se->expr = tmp;
3955 }
3956 
3957 
3958 /* Initialize MAPPING.  */
3959 
3960 void
3961 gfc_init_interface_mapping (gfc_interface_mapping * mapping)
3962 {
3963   mapping->syms = NULL;
3964   mapping->charlens = NULL;
3965 }
3966 
3967 
3968 /* Free all memory held by MAPPING (but not MAPPING itself).  */
3969 
3970 void
3971 gfc_free_interface_mapping (gfc_interface_mapping * mapping)
3972 {
3973   gfc_interface_sym_mapping *sym;
3974   gfc_interface_sym_mapping *nextsym;
3975   gfc_charlen *cl;
3976   gfc_charlen *nextcl;
3977 
3978   for (sym = mapping->syms; sym; sym = nextsym)
3979     {
3980       nextsym = sym->next;
3981       sym->new_sym->n.sym->formal = NULL;
3982       gfc_free_symbol (sym->new_sym->n.sym);
3983       gfc_free_expr (sym->expr);
3984       free (sym->new_sym);
3985       free (sym);
3986     }
3987   for (cl = mapping->charlens; cl; cl = nextcl)
3988     {
3989       nextcl = cl->next;
3990       gfc_free_expr (cl->length);
3991       free (cl);
3992     }
3993 }
3994 
3995 
3996 /* Return a copy of gfc_charlen CL.  Add the returned structure to
3997    MAPPING so that it will be freed by gfc_free_interface_mapping.  */
3998 
3999 static gfc_charlen *
4000 gfc_get_interface_mapping_charlen (gfc_interface_mapping * mapping,
4001 				   gfc_charlen * cl)
4002 {
4003   gfc_charlen *new_charlen;
4004 
4005   new_charlen = gfc_get_charlen ();
4006   new_charlen->next = mapping->charlens;
4007   new_charlen->length = gfc_copy_expr (cl->length);
4008 
4009   mapping->charlens = new_charlen;
4010   return new_charlen;
4011 }
4012 
4013 
4014 /* A subroutine of gfc_add_interface_mapping.  Return a descriptorless
4015    array variable that can be used as the actual argument for dummy
4016    argument SYM.  Add any initialization code to BLOCK.  PACKED is as
4017    for gfc_get_nodesc_array_type and DATA points to the first element
4018    in the passed array.  */
4019 
4020 static tree
4021 gfc_get_interface_mapping_array (stmtblock_t * block, gfc_symbol * sym,
4022 				 gfc_packed packed, tree data)
4023 {
4024   tree type;
4025   tree var;
4026 
4027   type = gfc_typenode_for_spec (&sym->ts);
4028   type = gfc_get_nodesc_array_type (type, sym->as, packed,
4029 				    !sym->attr.target && !sym->attr.pointer
4030 				    && !sym->attr.proc_pointer);
4031 
4032   var = gfc_create_var (type, "ifm");
4033   gfc_add_modify (block, var, fold_convert (type, data));
4034 
4035   return var;
4036 }
4037 
4038 
4039 /* A subroutine of gfc_add_interface_mapping.  Set the stride, upper bounds
4040    and offset of descriptorless array type TYPE given that it has the same
4041    size as DESC.  Add any set-up code to BLOCK.  */
4042 
4043 static void
4044 gfc_set_interface_mapping_bounds (stmtblock_t * block, tree type, tree desc)
4045 {
4046   int n;
4047   tree dim;
4048   tree offset;
4049   tree tmp;
4050 
4051   offset = gfc_index_zero_node;
4052   for (n = 0; n < GFC_TYPE_ARRAY_RANK (type); n++)
4053     {
4054       dim = gfc_rank_cst[n];
4055       GFC_TYPE_ARRAY_STRIDE (type, n) = gfc_conv_array_stride (desc, n);
4056       if (GFC_TYPE_ARRAY_LBOUND (type, n) == NULL_TREE)
4057 	{
4058 	  GFC_TYPE_ARRAY_LBOUND (type, n)
4059 		= gfc_conv_descriptor_lbound_get (desc, dim);
4060 	  GFC_TYPE_ARRAY_UBOUND (type, n)
4061 		= gfc_conv_descriptor_ubound_get (desc, dim);
4062 	}
4063       else if (GFC_TYPE_ARRAY_UBOUND (type, n) == NULL_TREE)
4064 	{
4065 	  tmp = fold_build2_loc (input_location, MINUS_EXPR,
4066 				 gfc_array_index_type,
4067 				 gfc_conv_descriptor_ubound_get (desc, dim),
4068 				 gfc_conv_descriptor_lbound_get (desc, dim));
4069 	  tmp = fold_build2_loc (input_location, PLUS_EXPR,
4070 				 gfc_array_index_type,
4071 				 GFC_TYPE_ARRAY_LBOUND (type, n), tmp);
4072 	  tmp = gfc_evaluate_now (tmp, block);
4073 	  GFC_TYPE_ARRAY_UBOUND (type, n) = tmp;
4074 	}
4075       tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
4076 			     GFC_TYPE_ARRAY_LBOUND (type, n),
4077 			     GFC_TYPE_ARRAY_STRIDE (type, n));
4078       offset = fold_build2_loc (input_location, MINUS_EXPR,
4079 				gfc_array_index_type, offset, tmp);
4080     }
4081   offset = gfc_evaluate_now (offset, block);
4082   GFC_TYPE_ARRAY_OFFSET (type) = offset;
4083 }
4084 
4085 
4086 /* Extend MAPPING so that it maps dummy argument SYM to the value stored
4087    in SE.  The caller may still use se->expr and se->string_length after
4088    calling this function.  */
4089 
4090 void
4091 gfc_add_interface_mapping (gfc_interface_mapping * mapping,
4092 			   gfc_symbol * sym, gfc_se * se,
4093 			   gfc_expr *expr)
4094 {
4095   gfc_interface_sym_mapping *sm;
4096   tree desc;
4097   tree tmp;
4098   tree value;
4099   gfc_symbol *new_sym;
4100   gfc_symtree *root;
4101   gfc_symtree *new_symtree;
4102 
4103   /* Create a new symbol to represent the actual argument.  */
4104   new_sym = gfc_new_symbol (sym->name, NULL);
4105   new_sym->ts = sym->ts;
4106   new_sym->as = gfc_copy_array_spec (sym->as);
4107   new_sym->attr.referenced = 1;
4108   new_sym->attr.dimension = sym->attr.dimension;
4109   new_sym->attr.contiguous = sym->attr.contiguous;
4110   new_sym->attr.codimension = sym->attr.codimension;
4111   new_sym->attr.pointer = sym->attr.pointer;
4112   new_sym->attr.allocatable = sym->attr.allocatable;
4113   new_sym->attr.flavor = sym->attr.flavor;
4114   new_sym->attr.function = sym->attr.function;
4115 
4116   /* Ensure that the interface is available and that
4117      descriptors are passed for array actual arguments.  */
4118   if (sym->attr.flavor == FL_PROCEDURE)
4119     {
4120       new_sym->formal = expr->symtree->n.sym->formal;
4121       new_sym->attr.always_explicit
4122 	    = expr->symtree->n.sym->attr.always_explicit;
4123     }
4124 
4125   /* Create a fake symtree for it.  */
4126   root = NULL;
4127   new_symtree = gfc_new_symtree (&root, sym->name);
4128   new_symtree->n.sym = new_sym;
4129   gcc_assert (new_symtree == root);
4130 
4131   /* Create a dummy->actual mapping.  */
4132   sm = XCNEW (gfc_interface_sym_mapping);
4133   sm->next = mapping->syms;
4134   sm->old = sym;
4135   sm->new_sym = new_symtree;
4136   sm->expr = gfc_copy_expr (expr);
4137   mapping->syms = sm;
4138 
4139   /* Stabilize the argument's value.  */
4140   if (!sym->attr.function && se)
4141     se->expr = gfc_evaluate_now (se->expr, &se->pre);
4142 
4143   if (sym->ts.type == BT_CHARACTER)
4144     {
4145       /* Create a copy of the dummy argument's length.  */
4146       new_sym->ts.u.cl = gfc_get_interface_mapping_charlen (mapping, sym->ts.u.cl);
4147       sm->expr->ts.u.cl = new_sym->ts.u.cl;
4148 
4149       /* If the length is specified as "*", record the length that
4150 	 the caller is passing.  We should use the callee's length
4151 	 in all other cases.  */
4152       if (!new_sym->ts.u.cl->length && se)
4153 	{
4154 	  se->string_length = gfc_evaluate_now (se->string_length, &se->pre);
4155 	  new_sym->ts.u.cl->backend_decl = se->string_length;
4156 	}
4157     }
4158 
4159   if (!se)
4160     return;
4161 
4162   /* Use the passed value as-is if the argument is a function.  */
4163   if (sym->attr.flavor == FL_PROCEDURE)
4164     value = se->expr;
4165 
4166   /* If the argument is a pass-by-value scalar, use the value as is.  */
4167   else if (!sym->attr.dimension && sym->attr.value)
4168     value = se->expr;
4169 
4170   /* If the argument is either a string or a pointer to a string,
4171      convert it to a boundless character type.  */
4172   else if (!sym->attr.dimension && sym->ts.type == BT_CHARACTER)
4173     {
4174       tmp = gfc_get_character_type_len (sym->ts.kind, NULL);
4175       tmp = build_pointer_type (tmp);
4176       if (sym->attr.pointer)
4177         value = build_fold_indirect_ref_loc (input_location,
4178 					 se->expr);
4179       else
4180         value = se->expr;
4181       value = fold_convert (tmp, value);
4182     }
4183 
4184   /* If the argument is a scalar, a pointer to an array or an allocatable,
4185      dereference it.  */
4186   else if (!sym->attr.dimension || sym->attr.pointer || sym->attr.allocatable)
4187     value = build_fold_indirect_ref_loc (input_location,
4188 				     se->expr);
4189 
4190   /* For character(*), use the actual argument's descriptor.  */
4191   else if (sym->ts.type == BT_CHARACTER && !new_sym->ts.u.cl->length)
4192     value = build_fold_indirect_ref_loc (input_location,
4193 				     se->expr);
4194 
4195   /* If the argument is an array descriptor, use it to determine
4196      information about the actual argument's shape.  */
4197   else if (POINTER_TYPE_P (TREE_TYPE (se->expr))
4198 	   && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (TREE_TYPE (se->expr))))
4199     {
4200       /* Get the actual argument's descriptor.  */
4201       desc = build_fold_indirect_ref_loc (input_location,
4202 				      se->expr);
4203 
4204       /* Create the replacement variable.  */
4205       tmp = gfc_conv_descriptor_data_get (desc);
4206       value = gfc_get_interface_mapping_array (&se->pre, sym,
4207 					       PACKED_NO, tmp);
4208 
4209       /* Use DESC to work out the upper bounds, strides and offset.  */
4210       gfc_set_interface_mapping_bounds (&se->pre, TREE_TYPE (value), desc);
4211     }
4212   else
4213     /* Otherwise we have a packed array.  */
4214     value = gfc_get_interface_mapping_array (&se->pre, sym,
4215 					     PACKED_FULL, se->expr);
4216 
4217   new_sym->backend_decl = value;
4218 }
4219 
4220 
4221 /* Called once all dummy argument mappings have been added to MAPPING,
4222    but before the mapping is used to evaluate expressions.  Pre-evaluate
4223    the length of each argument, adding any initialization code to PRE and
4224    any finalization code to POST.  */
4225 
4226 void
4227 gfc_finish_interface_mapping (gfc_interface_mapping * mapping,
4228 			      stmtblock_t * pre, stmtblock_t * post)
4229 {
4230   gfc_interface_sym_mapping *sym;
4231   gfc_expr *expr;
4232   gfc_se se;
4233 
4234   for (sym = mapping->syms; sym; sym = sym->next)
4235     if (sym->new_sym->n.sym->ts.type == BT_CHARACTER
4236 	&& !sym->new_sym->n.sym->ts.u.cl->backend_decl)
4237       {
4238 	expr = sym->new_sym->n.sym->ts.u.cl->length;
4239 	gfc_apply_interface_mapping_to_expr (mapping, expr);
4240 	gfc_init_se (&se, NULL);
4241 	gfc_conv_expr (&se, expr);
4242 	se.expr = fold_convert (gfc_charlen_type_node, se.expr);
4243 	se.expr = gfc_evaluate_now (se.expr, &se.pre);
4244 	gfc_add_block_to_block (pre, &se.pre);
4245 	gfc_add_block_to_block (post, &se.post);
4246 
4247 	sym->new_sym->n.sym->ts.u.cl->backend_decl = se.expr;
4248       }
4249 }
4250 
4251 
4252 /* Like gfc_apply_interface_mapping_to_expr, but applied to
4253    constructor C.  */
4254 
4255 static void
4256 gfc_apply_interface_mapping_to_cons (gfc_interface_mapping * mapping,
4257 				     gfc_constructor_base base)
4258 {
4259   gfc_constructor *c;
4260   for (c = gfc_constructor_first (base); c; c = gfc_constructor_next (c))
4261     {
4262       gfc_apply_interface_mapping_to_expr (mapping, c->expr);
4263       if (c->iterator)
4264 	{
4265 	  gfc_apply_interface_mapping_to_expr (mapping, c->iterator->start);
4266 	  gfc_apply_interface_mapping_to_expr (mapping, c->iterator->end);
4267 	  gfc_apply_interface_mapping_to_expr (mapping, c->iterator->step);
4268 	}
4269     }
4270 }
4271 
4272 
4273 /* Like gfc_apply_interface_mapping_to_expr, but applied to
4274    reference REF.  */
4275 
4276 static void
4277 gfc_apply_interface_mapping_to_ref (gfc_interface_mapping * mapping,
4278 				    gfc_ref * ref)
4279 {
4280   int n;
4281 
4282   for (; ref; ref = ref->next)
4283     switch (ref->type)
4284       {
4285       case REF_ARRAY:
4286 	for (n = 0; n < ref->u.ar.dimen; n++)
4287 	  {
4288 	    gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.start[n]);
4289 	    gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.end[n]);
4290 	    gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.stride[n]);
4291 	  }
4292 	break;
4293 
4294       case REF_COMPONENT:
4295       case REF_INQUIRY:
4296 	break;
4297 
4298       case REF_SUBSTRING:
4299 	gfc_apply_interface_mapping_to_expr (mapping, ref->u.ss.start);
4300 	gfc_apply_interface_mapping_to_expr (mapping, ref->u.ss.end);
4301 	break;
4302       }
4303 }
4304 
4305 
4306 /* Convert intrinsic function calls into result expressions.  */
4307 
4308 static bool
4309 gfc_map_intrinsic_function (gfc_expr *expr, gfc_interface_mapping *mapping)
4310 {
4311   gfc_symbol *sym;
4312   gfc_expr *new_expr;
4313   gfc_expr *arg1;
4314   gfc_expr *arg2;
4315   int d, dup;
4316 
4317   arg1 = expr->value.function.actual->expr;
4318   if (expr->value.function.actual->next)
4319     arg2 = expr->value.function.actual->next->expr;
4320   else
4321     arg2 = NULL;
4322 
4323   sym = arg1->symtree->n.sym;
4324 
4325   if (sym->attr.dummy)
4326     return false;
4327 
4328   new_expr = NULL;
4329 
4330   switch (expr->value.function.isym->id)
4331     {
4332     case GFC_ISYM_LEN:
4333       /* TODO figure out why this condition is necessary.  */
4334       if (sym->attr.function
4335 	  && (arg1->ts.u.cl->length == NULL
4336 	      || (arg1->ts.u.cl->length->expr_type != EXPR_CONSTANT
4337 		  && arg1->ts.u.cl->length->expr_type != EXPR_VARIABLE)))
4338 	return false;
4339 
4340       new_expr = gfc_copy_expr (arg1->ts.u.cl->length);
4341       break;
4342 
4343     case GFC_ISYM_LEN_TRIM:
4344       new_expr = gfc_copy_expr (arg1);
4345       gfc_apply_interface_mapping_to_expr (mapping, new_expr);
4346 
4347       if (!new_expr)
4348 	return false;
4349 
4350       gfc_replace_expr (arg1, new_expr);
4351       return true;
4352 
4353     case GFC_ISYM_SIZE:
4354       if (!sym->as || sym->as->rank == 0)
4355 	return false;
4356 
4357       if (arg2 && arg2->expr_type == EXPR_CONSTANT)
4358 	{
4359 	  dup = mpz_get_si (arg2->value.integer);
4360 	  d = dup - 1;
4361 	}
4362       else
4363 	{
4364 	  dup = sym->as->rank;
4365 	  d = 0;
4366 	}
4367 
4368       for (; d < dup; d++)
4369 	{
4370 	  gfc_expr *tmp;
4371 
4372 	  if (!sym->as->upper[d] || !sym->as->lower[d])
4373 	    {
4374 	      gfc_free_expr (new_expr);
4375 	      return false;
4376 	    }
4377 
4378 	  tmp = gfc_add (gfc_copy_expr (sym->as->upper[d]),
4379 					gfc_get_int_expr (gfc_default_integer_kind,
4380 							  NULL, 1));
4381 	  tmp = gfc_subtract (tmp, gfc_copy_expr (sym->as->lower[d]));
4382 	  if (new_expr)
4383 	    new_expr = gfc_multiply (new_expr, tmp);
4384 	  else
4385 	    new_expr = tmp;
4386 	}
4387       break;
4388 
4389     case GFC_ISYM_LBOUND:
4390     case GFC_ISYM_UBOUND:
4391 	/* TODO These implementations of lbound and ubound do not limit if
4392 	   the size < 0, according to F95's 13.14.53 and 13.14.113.  */
4393 
4394       if (!sym->as || sym->as->rank == 0)
4395 	return false;
4396 
4397       if (arg2 && arg2->expr_type == EXPR_CONSTANT)
4398 	d = mpz_get_si (arg2->value.integer) - 1;
4399       else
4400 	return false;
4401 
4402       if (expr->value.function.isym->id == GFC_ISYM_LBOUND)
4403 	{
4404 	  if (sym->as->lower[d])
4405 	    new_expr = gfc_copy_expr (sym->as->lower[d]);
4406 	}
4407       else
4408 	{
4409 	  if (sym->as->upper[d])
4410 	    new_expr = gfc_copy_expr (sym->as->upper[d]);
4411 	}
4412       break;
4413 
4414     default:
4415       break;
4416     }
4417 
4418   gfc_apply_interface_mapping_to_expr (mapping, new_expr);
4419   if (!new_expr)
4420     return false;
4421 
4422   gfc_replace_expr (expr, new_expr);
4423   return true;
4424 }
4425 
4426 
4427 static void
4428 gfc_map_fcn_formal_to_actual (gfc_expr *expr, gfc_expr *map_expr,
4429 			      gfc_interface_mapping * mapping)
4430 {
4431   gfc_formal_arglist *f;
4432   gfc_actual_arglist *actual;
4433 
4434   actual = expr->value.function.actual;
4435   f = gfc_sym_get_dummy_args (map_expr->symtree->n.sym);
4436 
4437   for (; f && actual; f = f->next, actual = actual->next)
4438     {
4439       if (!actual->expr)
4440 	continue;
4441 
4442       gfc_add_interface_mapping (mapping, f->sym, NULL, actual->expr);
4443     }
4444 
4445   if (map_expr->symtree->n.sym->attr.dimension)
4446     {
4447       int d;
4448       gfc_array_spec *as;
4449 
4450       as = gfc_copy_array_spec (map_expr->symtree->n.sym->as);
4451 
4452       for (d = 0; d < as->rank; d++)
4453 	{
4454 	  gfc_apply_interface_mapping_to_expr (mapping, as->lower[d]);
4455 	  gfc_apply_interface_mapping_to_expr (mapping, as->upper[d]);
4456 	}
4457 
4458       expr->value.function.esym->as = as;
4459     }
4460 
4461   if (map_expr->symtree->n.sym->ts.type == BT_CHARACTER)
4462     {
4463       expr->value.function.esym->ts.u.cl->length
4464 	= gfc_copy_expr (map_expr->symtree->n.sym->ts.u.cl->length);
4465 
4466       gfc_apply_interface_mapping_to_expr (mapping,
4467 			expr->value.function.esym->ts.u.cl->length);
4468     }
4469 }
4470 
4471 
4472 /* EXPR is a copy of an expression that appeared in the interface
4473    associated with MAPPING.  Walk it recursively looking for references to
4474    dummy arguments that MAPPING maps to actual arguments.  Replace each such
4475    reference with a reference to the associated actual argument.  */
4476 
4477 static void
4478 gfc_apply_interface_mapping_to_expr (gfc_interface_mapping * mapping,
4479 				     gfc_expr * expr)
4480 {
4481   gfc_interface_sym_mapping *sym;
4482   gfc_actual_arglist *actual;
4483 
4484   if (!expr)
4485     return;
4486 
4487   /* Copying an expression does not copy its length, so do that here.  */
4488   if (expr->ts.type == BT_CHARACTER && expr->ts.u.cl)
4489     {
4490       expr->ts.u.cl = gfc_get_interface_mapping_charlen (mapping, expr->ts.u.cl);
4491       gfc_apply_interface_mapping_to_expr (mapping, expr->ts.u.cl->length);
4492     }
4493 
4494   /* Apply the mapping to any references.  */
4495   gfc_apply_interface_mapping_to_ref (mapping, expr->ref);
4496 
4497   /* ...and to the expression's symbol, if it has one.  */
4498   /* TODO Find out why the condition on expr->symtree had to be moved into
4499      the loop rather than being outside it, as originally.  */
4500   for (sym = mapping->syms; sym; sym = sym->next)
4501     if (expr->symtree && sym->old == expr->symtree->n.sym)
4502       {
4503 	if (sym->new_sym->n.sym->backend_decl)
4504 	  expr->symtree = sym->new_sym;
4505 	else if (sym->expr)
4506 	  gfc_replace_expr (expr, gfc_copy_expr (sym->expr));
4507       }
4508 
4509       /* ...and to subexpressions in expr->value.  */
4510   switch (expr->expr_type)
4511     {
4512     case EXPR_VARIABLE:
4513     case EXPR_CONSTANT:
4514     case EXPR_NULL:
4515     case EXPR_SUBSTRING:
4516       break;
4517 
4518     case EXPR_OP:
4519       gfc_apply_interface_mapping_to_expr (mapping, expr->value.op.op1);
4520       gfc_apply_interface_mapping_to_expr (mapping, expr->value.op.op2);
4521       break;
4522 
4523     case EXPR_FUNCTION:
4524       for (actual = expr->value.function.actual; actual; actual = actual->next)
4525 	gfc_apply_interface_mapping_to_expr (mapping, actual->expr);
4526 
4527       if (expr->value.function.esym == NULL
4528 	    && expr->value.function.isym != NULL
4529 	    && expr->value.function.actual
4530 	    && expr->value.function.actual->expr
4531 	    && expr->value.function.actual->expr->symtree
4532 	    && gfc_map_intrinsic_function (expr, mapping))
4533 	break;
4534 
4535       for (sym = mapping->syms; sym; sym = sym->next)
4536 	if (sym->old == expr->value.function.esym)
4537 	  {
4538 	    expr->value.function.esym = sym->new_sym->n.sym;
4539 	    gfc_map_fcn_formal_to_actual (expr, sym->expr, mapping);
4540 	    expr->value.function.esym->result = sym->new_sym->n.sym;
4541 	  }
4542       break;
4543 
4544     case EXPR_ARRAY:
4545     case EXPR_STRUCTURE:
4546       gfc_apply_interface_mapping_to_cons (mapping, expr->value.constructor);
4547       break;
4548 
4549     case EXPR_COMPCALL:
4550     case EXPR_PPC:
4551     case EXPR_UNKNOWN:
4552       gcc_unreachable ();
4553       break;
4554     }
4555 
4556   return;
4557 }
4558 
4559 
4560 /* Evaluate interface expression EXPR using MAPPING.  Store the result
4561    in SE.  */
4562 
4563 void
4564 gfc_apply_interface_mapping (gfc_interface_mapping * mapping,
4565 			     gfc_se * se, gfc_expr * expr)
4566 {
4567   expr = gfc_copy_expr (expr);
4568   gfc_apply_interface_mapping_to_expr (mapping, expr);
4569   gfc_conv_expr (se, expr);
4570   se->expr = gfc_evaluate_now (se->expr, &se->pre);
4571   gfc_free_expr (expr);
4572 }
4573 
4574 
4575 /* Returns a reference to a temporary array into which a component of
4576    an actual argument derived type array is copied and then returned
4577    after the function call.  */
4578 void
4579 gfc_conv_subref_array_arg (gfc_se * parmse, gfc_expr * expr, int g77,
4580 			   sym_intent intent, bool formal_ptr)
4581 {
4582   gfc_se lse;
4583   gfc_se rse;
4584   gfc_ss *lss;
4585   gfc_ss *rss;
4586   gfc_loopinfo loop;
4587   gfc_loopinfo loop2;
4588   gfc_array_info *info;
4589   tree offset;
4590   tree tmp_index;
4591   tree tmp;
4592   tree base_type;
4593   tree size;
4594   stmtblock_t body;
4595   int n;
4596   int dimen;
4597 
4598   gfc_init_se (&lse, NULL);
4599   gfc_init_se (&rse, NULL);
4600 
4601   /* Walk the argument expression.  */
4602   rss = gfc_walk_expr (expr);
4603 
4604   gcc_assert (rss != gfc_ss_terminator);
4605 
4606   /* Initialize the scalarizer.  */
4607   gfc_init_loopinfo (&loop);
4608   gfc_add_ss_to_loop (&loop, rss);
4609 
4610   /* Calculate the bounds of the scalarization.  */
4611   gfc_conv_ss_startstride (&loop);
4612 
4613   /* Build an ss for the temporary.  */
4614   if (expr->ts.type == BT_CHARACTER && !expr->ts.u.cl->backend_decl)
4615     gfc_conv_string_length (expr->ts.u.cl, expr, &parmse->pre);
4616 
4617   base_type = gfc_typenode_for_spec (&expr->ts);
4618   if (GFC_ARRAY_TYPE_P (base_type)
4619 		|| GFC_DESCRIPTOR_TYPE_P (base_type))
4620     base_type = gfc_get_element_type (base_type);
4621 
4622   if (expr->ts.type == BT_CLASS)
4623     base_type = gfc_typenode_for_spec (&CLASS_DATA (expr)->ts);
4624 
4625   loop.temp_ss = gfc_get_temp_ss (base_type, ((expr->ts.type == BT_CHARACTER)
4626 					      ? expr->ts.u.cl->backend_decl
4627 					      : NULL),
4628 				  loop.dimen);
4629 
4630   parmse->string_length = loop.temp_ss->info->string_length;
4631 
4632   /* Associate the SS with the loop.  */
4633   gfc_add_ss_to_loop (&loop, loop.temp_ss);
4634 
4635   /* Setup the scalarizing loops.  */
4636   gfc_conv_loop_setup (&loop, &expr->where);
4637 
4638   /* Pass the temporary descriptor back to the caller.  */
4639   info = &loop.temp_ss->info->data.array;
4640   parmse->expr = info->descriptor;
4641 
4642   /* Setup the gfc_se structures.  */
4643   gfc_copy_loopinfo_to_se (&lse, &loop);
4644   gfc_copy_loopinfo_to_se (&rse, &loop);
4645 
4646   rse.ss = rss;
4647   lse.ss = loop.temp_ss;
4648   gfc_mark_ss_chain_used (rss, 1);
4649   gfc_mark_ss_chain_used (loop.temp_ss, 1);
4650 
4651   /* Start the scalarized loop body.  */
4652   gfc_start_scalarized_body (&loop, &body);
4653 
4654   /* Translate the expression.  */
4655   gfc_conv_expr (&rse, expr);
4656 
4657   /* Reset the offset for the function call since the loop
4658      is zero based on the data pointer.  Note that the temp
4659      comes first in the loop chain since it is added second.  */
4660   if (gfc_is_class_array_function (expr))
4661     {
4662       tmp = loop.ss->loop_chain->info->data.array.descriptor;
4663       gfc_conv_descriptor_offset_set (&loop.pre, tmp,
4664 				      gfc_index_zero_node);
4665     }
4666 
4667   gfc_conv_tmp_array_ref (&lse);
4668 
4669   if (intent != INTENT_OUT)
4670     {
4671       tmp = gfc_trans_scalar_assign (&lse, &rse, expr->ts, false, false);
4672       gfc_add_expr_to_block (&body, tmp);
4673       gcc_assert (rse.ss == gfc_ss_terminator);
4674       gfc_trans_scalarizing_loops (&loop, &body);
4675     }
4676   else
4677     {
4678       /* Make sure that the temporary declaration survives by merging
4679        all the loop declarations into the current context.  */
4680       for (n = 0; n < loop.dimen; n++)
4681 	{
4682 	  gfc_merge_block_scope (&body);
4683 	  body = loop.code[loop.order[n]];
4684 	}
4685       gfc_merge_block_scope (&body);
4686     }
4687 
4688   /* Add the post block after the second loop, so that any
4689      freeing of allocated memory is done at the right time.  */
4690   gfc_add_block_to_block (&parmse->pre, &loop.pre);
4691 
4692   /**********Copy the temporary back again.*********/
4693 
4694   gfc_init_se (&lse, NULL);
4695   gfc_init_se (&rse, NULL);
4696 
4697   /* Walk the argument expression.  */
4698   lss = gfc_walk_expr (expr);
4699   rse.ss = loop.temp_ss;
4700   lse.ss = lss;
4701 
4702   /* Initialize the scalarizer.  */
4703   gfc_init_loopinfo (&loop2);
4704   gfc_add_ss_to_loop (&loop2, lss);
4705 
4706   dimen = rse.ss->dimen;
4707 
4708   /* Skip the write-out loop for this case.  */
4709   if (gfc_is_class_array_function (expr))
4710     goto class_array_fcn;
4711 
4712   /* Calculate the bounds of the scalarization.  */
4713   gfc_conv_ss_startstride (&loop2);
4714 
4715   /* Setup the scalarizing loops.  */
4716   gfc_conv_loop_setup (&loop2, &expr->where);
4717 
4718   gfc_copy_loopinfo_to_se (&lse, &loop2);
4719   gfc_copy_loopinfo_to_se (&rse, &loop2);
4720 
4721   gfc_mark_ss_chain_used (lss, 1);
4722   gfc_mark_ss_chain_used (loop.temp_ss, 1);
4723 
4724   /* Declare the variable to hold the temporary offset and start the
4725      scalarized loop body.  */
4726   offset = gfc_create_var (gfc_array_index_type, NULL);
4727   gfc_start_scalarized_body (&loop2, &body);
4728 
4729   /* Build the offsets for the temporary from the loop variables.  The
4730      temporary array has lbounds of zero and strides of one in all
4731      dimensions, so this is very simple.  The offset is only computed
4732      outside the innermost loop, so the overall transfer could be
4733      optimized further.  */
4734   info = &rse.ss->info->data.array;
4735 
4736   tmp_index = gfc_index_zero_node;
4737   for (n = dimen - 1; n > 0; n--)
4738     {
4739       tree tmp_str;
4740       tmp = rse.loop->loopvar[n];
4741       tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
4742 			     tmp, rse.loop->from[n]);
4743       tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
4744 			     tmp, tmp_index);
4745 
4746       tmp_str = fold_build2_loc (input_location, MINUS_EXPR,
4747 				 gfc_array_index_type,
4748 				 rse.loop->to[n-1], rse.loop->from[n-1]);
4749       tmp_str = fold_build2_loc (input_location, PLUS_EXPR,
4750 				 gfc_array_index_type,
4751 				 tmp_str, gfc_index_one_node);
4752 
4753       tmp_index = fold_build2_loc (input_location, MULT_EXPR,
4754 				   gfc_array_index_type, tmp, tmp_str);
4755     }
4756 
4757   tmp_index = fold_build2_loc (input_location, MINUS_EXPR,
4758 			       gfc_array_index_type,
4759 			       tmp_index, rse.loop->from[0]);
4760   gfc_add_modify (&rse.loop->code[0], offset, tmp_index);
4761 
4762   tmp_index = fold_build2_loc (input_location, PLUS_EXPR,
4763 			       gfc_array_index_type,
4764 			       rse.loop->loopvar[0], offset);
4765 
4766   /* Now use the offset for the reference.  */
4767   tmp = build_fold_indirect_ref_loc (input_location,
4768 				 info->data);
4769   rse.expr = gfc_build_array_ref (tmp, tmp_index, NULL);
4770 
4771   if (expr->ts.type == BT_CHARACTER)
4772     rse.string_length = expr->ts.u.cl->backend_decl;
4773 
4774   gfc_conv_expr (&lse, expr);
4775 
4776   gcc_assert (lse.ss == gfc_ss_terminator);
4777 
4778   tmp = gfc_trans_scalar_assign (&lse, &rse, expr->ts, false, true);
4779   gfc_add_expr_to_block (&body, tmp);
4780 
4781   /* Generate the copying loops.  */
4782   gfc_trans_scalarizing_loops (&loop2, &body);
4783 
4784   /* Wrap the whole thing up by adding the second loop to the post-block
4785      and following it by the post-block of the first loop.  In this way,
4786      if the temporary needs freeing, it is done after use!  */
4787   if (intent != INTENT_IN)
4788     {
4789       gfc_add_block_to_block (&parmse->post, &loop2.pre);
4790       gfc_add_block_to_block (&parmse->post, &loop2.post);
4791     }
4792 
4793 class_array_fcn:
4794 
4795   gfc_add_block_to_block (&parmse->post, &loop.post);
4796 
4797   gfc_cleanup_loop (&loop);
4798   gfc_cleanup_loop (&loop2);
4799 
4800   /* Pass the string length to the argument expression.  */
4801   if (expr->ts.type == BT_CHARACTER)
4802     parmse->string_length = expr->ts.u.cl->backend_decl;
4803 
4804   /* Determine the offset for pointer formal arguments and set the
4805      lbounds to one.  */
4806   if (formal_ptr)
4807     {
4808       size = gfc_index_one_node;
4809       offset = gfc_index_zero_node;
4810       for (n = 0; n < dimen; n++)
4811 	{
4812 	  tmp = gfc_conv_descriptor_ubound_get (parmse->expr,
4813 						gfc_rank_cst[n]);
4814 	  tmp = fold_build2_loc (input_location, PLUS_EXPR,
4815 				 gfc_array_index_type, tmp,
4816 				 gfc_index_one_node);
4817 	  gfc_conv_descriptor_ubound_set (&parmse->pre,
4818 					  parmse->expr,
4819 					  gfc_rank_cst[n],
4820 					  tmp);
4821 	  gfc_conv_descriptor_lbound_set (&parmse->pre,
4822 					  parmse->expr,
4823 					  gfc_rank_cst[n],
4824 					  gfc_index_one_node);
4825 	  size = gfc_evaluate_now (size, &parmse->pre);
4826 	  offset = fold_build2_loc (input_location, MINUS_EXPR,
4827 				    gfc_array_index_type,
4828 				    offset, size);
4829 	  offset = gfc_evaluate_now (offset, &parmse->pre);
4830 	  tmp = fold_build2_loc (input_location, MINUS_EXPR,
4831 				 gfc_array_index_type,
4832 				 rse.loop->to[n], rse.loop->from[n]);
4833 	  tmp = fold_build2_loc (input_location, PLUS_EXPR,
4834 				 gfc_array_index_type,
4835 				 tmp, gfc_index_one_node);
4836 	  size = fold_build2_loc (input_location, MULT_EXPR,
4837 				  gfc_array_index_type, size, tmp);
4838 	}
4839 
4840       gfc_conv_descriptor_offset_set (&parmse->pre, parmse->expr,
4841 				      offset);
4842     }
4843 
4844   /* We want either the address for the data or the address of the descriptor,
4845      depending on the mode of passing array arguments.  */
4846   if (g77)
4847     parmse->expr = gfc_conv_descriptor_data_get (parmse->expr);
4848   else
4849     parmse->expr = gfc_build_addr_expr (NULL_TREE, parmse->expr);
4850 
4851   return;
4852 }
4853 
4854 
4855 /* Generate the code for argument list functions.  */
4856 
4857 static void
4858 conv_arglist_function (gfc_se *se, gfc_expr *expr, const char *name)
4859 {
4860   /* Pass by value for g77 %VAL(arg), pass the address
4861      indirectly for %LOC, else by reference.  Thus %REF
4862      is a "do-nothing" and %LOC is the same as an F95
4863      pointer.  */
4864   if (strcmp (name, "%VAL") == 0)
4865     gfc_conv_expr (se, expr);
4866   else if (strcmp (name, "%LOC") == 0)
4867     {
4868       gfc_conv_expr_reference (se, expr);
4869       se->expr = gfc_build_addr_expr (NULL, se->expr);
4870     }
4871   else if (strcmp (name, "%REF") == 0)
4872     gfc_conv_expr_reference (se, expr);
4873   else
4874     gfc_error ("Unknown argument list function at %L", &expr->where);
4875 }
4876 
4877 
4878 /* This function tells whether the middle-end representation of the expression
4879    E given as input may point to data otherwise accessible through a variable
4880    (sub-)reference.
4881    It is assumed that the only expressions that may alias are variables,
4882    and array constructors if ARRAY_MAY_ALIAS is true and some of its elements
4883    may alias.
4884    This function is used to decide whether freeing an expression's allocatable
4885    components is safe or should be avoided.
4886 
4887    If ARRAY_MAY_ALIAS is true, an array constructor may alias if some of
4888    its elements are copied from a variable.  This ARRAY_MAY_ALIAS trick
4889    is necessary because for array constructors, aliasing depends on how
4890    the array is used:
4891     - If E is an array constructor used as argument to an elemental procedure,
4892       the array, which is generated through shallow copy by the scalarizer,
4893       is used directly and can alias the expressions it was copied from.
4894     - If E is an array constructor used as argument to a non-elemental
4895       procedure,the scalarizer is used in gfc_conv_expr_descriptor to generate
4896       the array as in the previous case, but then that array is used
4897       to initialize a new descriptor through deep copy.  There is no alias
4898       possible in that case.
4899    Thus, the ARRAY_MAY_ALIAS flag is necessary to distinguish the two cases
4900    above.  */
4901 
4902 static bool
4903 expr_may_alias_variables (gfc_expr *e, bool array_may_alias)
4904 {
4905   gfc_constructor *c;
4906 
4907   if (e->expr_type == EXPR_VARIABLE)
4908     return true;
4909   else if (e->expr_type == EXPR_FUNCTION)
4910     {
4911       gfc_symbol *proc_ifc = gfc_get_proc_ifc_for_expr (e);
4912 
4913       if (proc_ifc->result != NULL
4914 	  && ((proc_ifc->result->ts.type == BT_CLASS
4915 	       && proc_ifc->result->ts.u.derived->attr.is_class
4916 	       && CLASS_DATA (proc_ifc->result)->attr.class_pointer)
4917 	      || proc_ifc->result->attr.pointer))
4918 	return true;
4919       else
4920 	return false;
4921     }
4922   else if (e->expr_type != EXPR_ARRAY || !array_may_alias)
4923     return false;
4924 
4925   for (c = gfc_constructor_first (e->value.constructor);
4926        c; c = gfc_constructor_next (c))
4927     if (c->expr
4928 	&& expr_may_alias_variables (c->expr, array_may_alias))
4929       return true;
4930 
4931   return false;
4932 }
4933 
4934 
4935 /* A helper function to set the dtype for unallocated or unassociated
4936    entities.  */
4937 
4938 static void
4939 set_dtype_for_unallocated (gfc_se *parmse, gfc_expr *e)
4940 {
4941   tree tmp;
4942   tree desc;
4943   tree cond;
4944   tree type;
4945   stmtblock_t block;
4946 
4947   /* TODO Figure out how to handle optional dummies.  */
4948   if (e && e->expr_type == EXPR_VARIABLE
4949       && e->symtree->n.sym->attr.optional)
4950     return;
4951 
4952   desc = parmse->expr;
4953   if (desc == NULL_TREE)
4954     return;
4955 
4956   if (POINTER_TYPE_P (TREE_TYPE (desc)))
4957     desc = build_fold_indirect_ref_loc (input_location, desc);
4958 
4959   if (!GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (desc)))
4960     return;
4961 
4962   gfc_init_block (&block);
4963   tmp = gfc_conv_descriptor_data_get (desc);
4964   cond = fold_build2_loc (input_location, EQ_EXPR,
4965 			  logical_type_node, tmp,
4966 			  build_int_cst (TREE_TYPE (tmp), 0));
4967   tmp = gfc_conv_descriptor_dtype (desc);
4968   type = gfc_get_element_type (TREE_TYPE (desc));
4969   tmp = fold_build2_loc (input_location, MODIFY_EXPR,
4970 			 TREE_TYPE (tmp), tmp,
4971 			 gfc_get_dtype_rank_type (e->rank, type));
4972   gfc_add_expr_to_block (&block, tmp);
4973   cond = build3_v (COND_EXPR, cond,
4974 		   gfc_finish_block (&block),
4975 		   build_empty_stmt (input_location));
4976   gfc_add_expr_to_block (&parmse->pre, cond);
4977 }
4978 
4979 
4980 
4981 /* Provide an interface between gfortran array descriptors and the F2018:18.4
4982    ISO_Fortran_binding array descriptors. */
4983 
4984 static void
4985 gfc_conv_gfc_desc_to_cfi_desc (gfc_se *parmse, gfc_expr *e, gfc_symbol *fsym)
4986 {
4987   tree tmp;
4988   tree cfi_desc_ptr;
4989   tree gfc_desc_ptr;
4990   tree type;
4991   tree cond;
4992   tree desc_attr;
4993   int attribute;
4994   int cfi_attribute;
4995   symbol_attribute attr = gfc_expr_attr (e);
4996 
4997   /* If this is a full array or a scalar, the allocatable and pointer
4998      attributes can be passed. Otherwise it is 'CFI_attribute_other'*/
4999   attribute = 2;
5000   if (!e->rank || gfc_get_full_arrayspec_from_expr (e))
5001     {
5002       if (attr.pointer)
5003 	attribute = 0;
5004       else if (attr.allocatable)
5005 	attribute = 1;
5006     }
5007 
5008   /* If the formal argument is assumed shape and neither a pointer nor
5009      allocatable, it is unconditionally CFI_attribute_other.  */
5010   if (fsym->as->type == AS_ASSUMED_SHAPE
5011       && !fsym->attr.pointer && !fsym->attr.allocatable)
5012    cfi_attribute = 2;
5013   else
5014    cfi_attribute = attribute;
5015 
5016   if (e->rank != 0)
5017     {
5018       parmse->force_no_tmp = 1;
5019       if (fsym->attr.contiguous
5020 	  && !gfc_is_simply_contiguous (e, false, true))
5021 	gfc_conv_subref_array_arg (parmse, e, false, fsym->attr.intent,
5022 				   fsym->attr.pointer);
5023       else
5024 	gfc_conv_expr_descriptor (parmse, e);
5025 
5026       if (POINTER_TYPE_P (TREE_TYPE (parmse->expr)))
5027 	parmse->expr = build_fold_indirect_ref_loc (input_location,
5028 						    parmse->expr);
5029 
5030       bool is_artificial = (INDIRECT_REF_P (parmse->expr)
5031 			    ? DECL_ARTIFICIAL (TREE_OPERAND (parmse->expr, 0))
5032 			    : DECL_ARTIFICIAL (parmse->expr));
5033 
5034       /* Unallocated allocatable arrays and unassociated pointer arrays
5035 	 need their dtype setting if they are argument associated with
5036 	 assumed rank dummies.  */
5037       if (fsym && fsym->as
5038 	  && (gfc_expr_attr (e).pointer
5039 	      || gfc_expr_attr (e).allocatable))
5040 	set_dtype_for_unallocated (parmse, e);
5041 
5042       /* All the temporary descriptors are marked as DECL_ARTIFICIAL. If
5043 	 the expression type is different from the descriptor type, then
5044 	 the offset must be found (eg. to a component ref or substring)
5045 	 and the dtype updated.  Assumed type entities are only allowed
5046 	 to be dummies in Fortran. They therefore lack the decl specific
5047 	 appendiges and so must be treated differently from other fortran
5048 	 entities passed to CFI descriptors in the interface decl.  */
5049       type = e->ts.type != BT_ASSUMED ? gfc_typenode_for_spec (&e->ts) :
5050 					NULL_TREE;
5051 
5052       if (type && is_artificial
5053 	  && type != gfc_get_element_type (TREE_TYPE (parmse->expr)))
5054 	{
5055 	  /* Obtain the offset to the data.  */
5056 	  gfc_get_dataptr_offset (&parmse->pre, parmse->expr, parmse->expr,
5057 				  gfc_index_zero_node, true, e);
5058 
5059 	  /* Update the dtype.  */
5060 	  gfc_add_modify (&parmse->pre,
5061 			  gfc_conv_descriptor_dtype (parmse->expr),
5062 			  gfc_get_dtype_rank_type (e->rank, type));
5063 	}
5064       else if (type == NULL_TREE || (!is_subref_array (e) && !is_artificial))
5065 	{
5066 	  /* Make sure that the span is set for expressions where it
5067 	     might not have been done already.  */
5068 	  tmp = gfc_conv_descriptor_elem_len (parmse->expr);
5069 	  tmp = fold_convert (gfc_array_index_type, tmp);
5070 	  gfc_conv_descriptor_span_set (&parmse->pre, parmse->expr, tmp);
5071 	}
5072     }
5073   else
5074     {
5075       gfc_conv_expr (parmse, e);
5076 
5077       if (POINTER_TYPE_P (TREE_TYPE (parmse->expr)))
5078 	parmse->expr = build_fold_indirect_ref_loc (input_location,
5079 						    parmse->expr);
5080 
5081       parmse->expr = gfc_conv_scalar_to_descriptor (parmse,
5082 						    parmse->expr, attr);
5083     }
5084 
5085   /* Set the CFI attribute field through a temporary value for the
5086      gfc attribute.  */
5087   desc_attr = gfc_conv_descriptor_attribute (parmse->expr);
5088   tmp = fold_build2_loc (input_location, MODIFY_EXPR,
5089 			 void_type_node, desc_attr,
5090 			 build_int_cst (TREE_TYPE (desc_attr), cfi_attribute));
5091   gfc_add_expr_to_block (&parmse->pre, tmp);
5092 
5093   /* Now pass the gfc_descriptor by reference.  */
5094   parmse->expr = gfc_build_addr_expr (NULL_TREE, parmse->expr);
5095 
5096   /* Variables to point to the gfc and CFI descriptors; cfi = NULL implies
5097      that the CFI descriptor is allocated by the gfor_fndecl_gfc_to_cfi call.  */
5098   gfc_desc_ptr = parmse->expr;
5099   cfi_desc_ptr = gfc_create_var (pvoid_type_node, "cfi");
5100   gfc_add_modify (&parmse->pre, cfi_desc_ptr, null_pointer_node);
5101 
5102   /* Allocate the CFI descriptor itself and fill the fields.  */
5103   tmp = gfc_build_addr_expr (NULL_TREE, cfi_desc_ptr);
5104   tmp = build_call_expr_loc (input_location,
5105 			     gfor_fndecl_gfc_to_cfi, 2, tmp, gfc_desc_ptr);
5106   gfc_add_expr_to_block (&parmse->pre, tmp);
5107 
5108   /* Now set the gfc descriptor attribute.  */
5109   tmp = fold_build2_loc (input_location, MODIFY_EXPR,
5110 			 void_type_node, desc_attr,
5111 			 build_int_cst (TREE_TYPE (desc_attr), attribute));
5112   gfc_add_expr_to_block (&parmse->pre, tmp);
5113 
5114   /* The CFI descriptor is passed to the bind_C procedure.  */
5115   parmse->expr = cfi_desc_ptr;
5116 
5117   /* Free the CFI descriptor.  */
5118   tmp = gfc_call_free (cfi_desc_ptr);
5119   gfc_prepend_expr_to_block (&parmse->post, tmp);
5120 
5121   /* Transfer values back to gfc descriptor.  */
5122   tmp = gfc_build_addr_expr (NULL_TREE, parmse->expr);
5123   tmp = build_call_expr_loc (input_location,
5124 			     gfor_fndecl_cfi_to_gfc, 2, gfc_desc_ptr, tmp);
5125   gfc_prepend_expr_to_block (&parmse->post, tmp);
5126 
5127   /* Deal with an optional dummy being passed to an optional formal arg
5128      by finishing the pre and post blocks and making their execution
5129      conditional on the dummy being present.  */
5130   if (fsym->attr.optional && e->expr_type == EXPR_VARIABLE
5131       && e->symtree->n.sym->attr.optional)
5132     {
5133       cond = gfc_conv_expr_present (e->symtree->n.sym);
5134       tmp = fold_build2 (MODIFY_EXPR, void_type_node,
5135 			 cfi_desc_ptr,
5136 			 build_int_cst (pvoid_type_node, 0));
5137       tmp = build3_v (COND_EXPR, cond,
5138 		      gfc_finish_block (&parmse->pre), tmp);
5139       gfc_add_expr_to_block (&parmse->pre, tmp);
5140       tmp = build3_v (COND_EXPR, cond,
5141 		      gfc_finish_block (&parmse->post),
5142 		      build_empty_stmt (input_location));
5143       gfc_add_expr_to_block (&parmse->post, tmp);
5144     }
5145 }
5146 
5147 
5148 /* Generate code for a procedure call.  Note can return se->post != NULL.
5149    If se->direct_byref is set then se->expr contains the return parameter.
5150    Return nonzero, if the call has alternate specifiers.
5151    'expr' is only needed for procedure pointer components.  */
5152 
5153 int
5154 gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
5155 			 gfc_actual_arglist * args, gfc_expr * expr,
5156 			 vec<tree, va_gc> *append_args)
5157 {
5158   gfc_interface_mapping mapping;
5159   vec<tree, va_gc> *arglist;
5160   vec<tree, va_gc> *retargs;
5161   tree tmp;
5162   tree fntype;
5163   gfc_se parmse;
5164   gfc_array_info *info;
5165   int byref;
5166   int parm_kind;
5167   tree type;
5168   tree var;
5169   tree len;
5170   tree base_object;
5171   vec<tree, va_gc> *stringargs;
5172   vec<tree, va_gc> *optionalargs;
5173   tree result = NULL;
5174   gfc_formal_arglist *formal;
5175   gfc_actual_arglist *arg;
5176   int has_alternate_specifier = 0;
5177   bool need_interface_mapping;
5178   bool callee_alloc;
5179   bool ulim_copy;
5180   gfc_typespec ts;
5181   gfc_charlen cl;
5182   gfc_expr *e;
5183   gfc_symbol *fsym;
5184   stmtblock_t post;
5185   enum {MISSING = 0, ELEMENTAL, SCALAR, SCALAR_POINTER, ARRAY};
5186   gfc_component *comp = NULL;
5187   int arglen;
5188   unsigned int argc;
5189 
5190   arglist = NULL;
5191   retargs = NULL;
5192   stringargs = NULL;
5193   optionalargs = NULL;
5194   var = NULL_TREE;
5195   len = NULL_TREE;
5196   gfc_clear_ts (&ts);
5197 
5198   comp = gfc_get_proc_ptr_comp (expr);
5199 
5200   bool elemental_proc = (comp
5201 			 && comp->ts.interface
5202 			 && comp->ts.interface->attr.elemental)
5203 			|| (comp && comp->attr.elemental)
5204 			|| sym->attr.elemental;
5205 
5206   if (se->ss != NULL)
5207     {
5208       if (!elemental_proc)
5209 	{
5210 	  gcc_assert (se->ss->info->type == GFC_SS_FUNCTION);
5211 	  if (se->ss->info->useflags)
5212 	    {
5213 	      gcc_assert ((!comp && gfc_return_by_reference (sym)
5214 			   && sym->result->attr.dimension)
5215 			  || (comp && comp->attr.dimension)
5216 			  || gfc_is_class_array_function (expr));
5217 	      gcc_assert (se->loop != NULL);
5218 	      /* Access the previously obtained result.  */
5219 	      gfc_conv_tmp_array_ref (se);
5220 	      return 0;
5221 	    }
5222 	}
5223       info = &se->ss->info->data.array;
5224     }
5225   else
5226     info = NULL;
5227 
5228   gfc_init_block (&post);
5229   gfc_init_interface_mapping (&mapping);
5230   if (!comp)
5231     {
5232       formal = gfc_sym_get_dummy_args (sym);
5233       need_interface_mapping = sym->attr.dimension ||
5234 			       (sym->ts.type == BT_CHARACTER
5235 				&& sym->ts.u.cl->length
5236 				&& sym->ts.u.cl->length->expr_type
5237 				   != EXPR_CONSTANT);
5238     }
5239   else
5240     {
5241       formal = comp->ts.interface ? comp->ts.interface->formal : NULL;
5242       need_interface_mapping = comp->attr.dimension ||
5243 			       (comp->ts.type == BT_CHARACTER
5244 				&& comp->ts.u.cl->length
5245 				&& comp->ts.u.cl->length->expr_type
5246 				   != EXPR_CONSTANT);
5247     }
5248 
5249   base_object = NULL_TREE;
5250   /* For _vprt->_copy () routines no formal symbol is present.  Nevertheless
5251      is the third and fourth argument to such a function call a value
5252      denoting the number of elements to copy (i.e., most of the time the
5253      length of a deferred length string).  */
5254   ulim_copy = (formal == NULL)
5255 	       && UNLIMITED_POLY (sym)
5256 	       && comp && (strcmp ("_copy", comp->name) == 0);
5257 
5258   /* Evaluate the arguments.  */
5259   for (arg = args, argc = 0; arg != NULL;
5260        arg = arg->next, formal = formal ? formal->next : NULL, ++argc)
5261     {
5262       bool finalized = false;
5263       bool non_unity_length_string = false;
5264 
5265       e = arg->expr;
5266       fsym = formal ? formal->sym : NULL;
5267       parm_kind = MISSING;
5268 
5269       if (fsym && fsym->ts.type == BT_CHARACTER && fsym->ts.u.cl
5270 	  && (!fsym->ts.u.cl->length
5271 	      || fsym->ts.u.cl->length->expr_type != EXPR_CONSTANT
5272 	      || mpz_cmp_si (fsym->ts.u.cl->length->value.integer, 1) != 0))
5273 	non_unity_length_string = true;
5274 
5275       /* If the procedure requires an explicit interface, the actual
5276 	 argument is passed according to the corresponding formal
5277 	 argument.  If the corresponding formal argument is a POINTER,
5278 	 ALLOCATABLE or assumed shape, we do not use g77's calling
5279 	 convention, and pass the address of the array descriptor
5280 	 instead.  Otherwise we use g77's calling convention, in other words
5281 	 pass the array data pointer without descriptor.  */
5282       bool nodesc_arg = fsym != NULL
5283 			&& !(fsym->attr.pointer || fsym->attr.allocatable)
5284 			&& fsym->as
5285 			&& fsym->as->type != AS_ASSUMED_SHAPE
5286 			&& fsym->as->type != AS_ASSUMED_RANK;
5287       if (comp)
5288 	nodesc_arg = nodesc_arg || !comp->attr.always_explicit;
5289       else
5290 	nodesc_arg = nodesc_arg || !sym->attr.always_explicit;
5291 
5292       /* Class array expressions are sometimes coming completely unadorned
5293 	 with either arrayspec or _data component.  Correct that here.
5294 	 OOP-TODO: Move this to the frontend.  */
5295       if (e && e->expr_type == EXPR_VARIABLE
5296 	    && !e->ref
5297 	    && e->ts.type == BT_CLASS
5298 	    && (CLASS_DATA (e)->attr.codimension
5299 		|| CLASS_DATA (e)->attr.dimension))
5300 	{
5301 	  gfc_typespec temp_ts = e->ts;
5302 	  gfc_add_class_array_ref (e);
5303 	  e->ts = temp_ts;
5304 	}
5305 
5306       if (e == NULL)
5307 	{
5308 	  if (se->ignore_optional)
5309 	    {
5310 	      /* Some intrinsics have already been resolved to the correct
5311 	         parameters.  */
5312 	      continue;
5313 	    }
5314 	  else if (arg->label)
5315 	    {
5316 	      has_alternate_specifier = 1;
5317 	      continue;
5318 	    }
5319 	  else
5320 	    {
5321 	      gfc_init_se (&parmse, NULL);
5322 
5323 	      /* For scalar arguments with VALUE attribute which are passed by
5324 		 value, pass "0" and a hidden argument gives the optional
5325 		 status.  */
5326 	      if (fsym && fsym->attr.optional && fsym->attr.value
5327 		  && !fsym->attr.dimension && fsym->ts.type != BT_CHARACTER
5328 		  && fsym->ts.type != BT_CLASS && fsym->ts.type != BT_DERIVED)
5329 		{
5330 		  parmse.expr = fold_convert (gfc_sym_type (fsym),
5331 					      integer_zero_node);
5332 		  vec_safe_push (optionalargs, boolean_false_node);
5333 		}
5334 	      else
5335 		{
5336 		  /* Pass a NULL pointer for an absent arg.  */
5337 		  parmse.expr = null_pointer_node;
5338 		  if (arg->missing_arg_type == BT_CHARACTER)
5339 		    parmse.string_length = build_int_cst (gfc_charlen_type_node,
5340 							  0);
5341 		}
5342 	    }
5343 	}
5344       else if (arg->expr->expr_type == EXPR_NULL
5345 	       && fsym && !fsym->attr.pointer
5346 	       && (fsym->ts.type != BT_CLASS
5347 		   || !CLASS_DATA (fsym)->attr.class_pointer))
5348 	{
5349 	  /* Pass a NULL pointer to denote an absent arg.  */
5350 	  gcc_assert (fsym->attr.optional && !fsym->attr.allocatable
5351 		      && (fsym->ts.type != BT_CLASS
5352 			  || !CLASS_DATA (fsym)->attr.allocatable));
5353 	  gfc_init_se (&parmse, NULL);
5354 	  parmse.expr = null_pointer_node;
5355 	  if (arg->missing_arg_type == BT_CHARACTER)
5356 	    parmse.string_length = build_int_cst (gfc_charlen_type_node, 0);
5357 	}
5358       else if (fsym && fsym->ts.type == BT_CLASS
5359 		 && e->ts.type == BT_DERIVED)
5360 	{
5361 	  /* The derived type needs to be converted to a temporary
5362 	     CLASS object.  */
5363 	  gfc_init_se (&parmse, se);
5364 	  gfc_conv_derived_to_class (&parmse, e, fsym->ts, NULL,
5365 				     fsym->attr.optional
5366 				     && e->expr_type == EXPR_VARIABLE
5367 				     && e->symtree->n.sym->attr.optional,
5368 				     CLASS_DATA (fsym)->attr.class_pointer
5369 				     || CLASS_DATA (fsym)->attr.allocatable);
5370 	}
5371       else if (UNLIMITED_POLY (fsym) && e->ts.type != BT_CLASS)
5372 	{
5373 	  /* The intrinsic type needs to be converted to a temporary
5374 	     CLASS object for the unlimited polymorphic formal.  */
5375 	  gfc_init_se (&parmse, se);
5376 	  gfc_conv_intrinsic_to_class (&parmse, e, fsym->ts);
5377 	}
5378       else if (se->ss && se->ss->info->useflags)
5379 	{
5380 	  gfc_ss *ss;
5381 
5382 	  ss = se->ss;
5383 
5384 	  /* An elemental function inside a scalarized loop.  */
5385 	  gfc_init_se (&parmse, se);
5386 	  parm_kind = ELEMENTAL;
5387 
5388 	  /* When no fsym is present, ulim_copy is set and this is a third or
5389 	     fourth argument, use call-by-value instead of by reference to
5390 	     hand the length properties to the copy routine (i.e., most of the
5391 	     time this will be a call to a __copy_character_* routine where the
5392 	     third and fourth arguments are the lengths of a deferred length
5393 	     char array).  */
5394 	  if ((fsym && fsym->attr.value)
5395 	      || (ulim_copy && (argc == 2 || argc == 3)))
5396 	    gfc_conv_expr (&parmse, e);
5397 	  else
5398 	    gfc_conv_expr_reference (&parmse, e);
5399 
5400 	  if (e->ts.type == BT_CHARACTER && !e->rank
5401 	      && e->expr_type == EXPR_FUNCTION)
5402 	    parmse.expr = build_fold_indirect_ref_loc (input_location,
5403 						       parmse.expr);
5404 
5405 	  if (fsym && fsym->ts.type == BT_DERIVED
5406 	      && gfc_is_class_container_ref (e))
5407 	    {
5408 	      parmse.expr = gfc_class_data_get (parmse.expr);
5409 
5410 	      if (fsym->attr.optional && e->expr_type == EXPR_VARIABLE
5411 		  && e->symtree->n.sym->attr.optional)
5412 		{
5413 		  tree cond = gfc_conv_expr_present (e->symtree->n.sym);
5414 		  parmse.expr = build3_loc (input_location, COND_EXPR,
5415 					TREE_TYPE (parmse.expr),
5416 					cond, parmse.expr,
5417 					fold_convert (TREE_TYPE (parmse.expr),
5418 						      null_pointer_node));
5419 		}
5420 	    }
5421 
5422 	  /* If we are passing an absent array as optional dummy to an
5423 	     elemental procedure, make sure that we pass NULL when the data
5424 	     pointer is NULL.  We need this extra conditional because of
5425 	     scalarization which passes arrays elements to the procedure,
5426 	     ignoring the fact that the array can be absent/unallocated/...  */
5427 	  if (ss->info->can_be_null_ref && ss->info->type != GFC_SS_REFERENCE)
5428 	    {
5429 	      tree descriptor_data;
5430 
5431 	      descriptor_data = ss->info->data.array.data;
5432 	      tmp = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
5433 				     descriptor_data,
5434 				     fold_convert (TREE_TYPE (descriptor_data),
5435 						   null_pointer_node));
5436 	      parmse.expr
5437 		= fold_build3_loc (input_location, COND_EXPR,
5438 				   TREE_TYPE (parmse.expr),
5439 				   gfc_unlikely (tmp, PRED_FORTRAN_ABSENT_DUMMY),
5440 				   fold_convert (TREE_TYPE (parmse.expr),
5441 						 null_pointer_node),
5442 				   parmse.expr);
5443 	    }
5444 
5445 	  /* The scalarizer does not repackage the reference to a class
5446 	     array - instead it returns a pointer to the data element.  */
5447 	  if (fsym && fsym->ts.type == BT_CLASS && e->ts.type == BT_CLASS)
5448 	    gfc_conv_class_to_class (&parmse, e, fsym->ts, true,
5449 				     fsym->attr.intent != INTENT_IN
5450 				     && (CLASS_DATA (fsym)->attr.class_pointer
5451 					 || CLASS_DATA (fsym)->attr.allocatable),
5452 				     fsym->attr.optional
5453 				     && e->expr_type == EXPR_VARIABLE
5454 				     && e->symtree->n.sym->attr.optional,
5455 				     CLASS_DATA (fsym)->attr.class_pointer
5456 				     || CLASS_DATA (fsym)->attr.allocatable);
5457 	}
5458       else
5459 	{
5460 	  bool scalar;
5461 	  gfc_ss *argss;
5462 
5463 	  gfc_init_se (&parmse, NULL);
5464 
5465 	  /* Check whether the expression is a scalar or not; we cannot use
5466 	     e->rank as it can be nonzero for functions arguments.  */
5467 	  argss = gfc_walk_expr (e);
5468 	  scalar = argss == gfc_ss_terminator;
5469 	  if (!scalar)
5470 	    gfc_free_ss_chain (argss);
5471 
5472 	  /* Special handling for passing scalar polymorphic coarrays;
5473 	     otherwise one passes "class->_data.data" instead of "&class".  */
5474 	  if (e->rank == 0 && e->ts.type == BT_CLASS
5475 	      && fsym && fsym->ts.type == BT_CLASS
5476 	      && CLASS_DATA (fsym)->attr.codimension
5477 	      && !CLASS_DATA (fsym)->attr.dimension)
5478 	    {
5479 	      gfc_add_class_array_ref (e);
5480               parmse.want_coarray = 1;
5481 	      scalar = false;
5482 	    }
5483 
5484 	  /* A scalar or transformational function.  */
5485 	  if (scalar)
5486 	    {
5487 	      if (e->expr_type == EXPR_VARIABLE
5488 		    && e->symtree->n.sym->attr.cray_pointee
5489 		    && fsym && fsym->attr.flavor == FL_PROCEDURE)
5490 		{
5491 		    /* The Cray pointer needs to be converted to a pointer to
5492 		       a type given by the expression.  */
5493 		    gfc_conv_expr (&parmse, e);
5494 		    type = build_pointer_type (TREE_TYPE (parmse.expr));
5495 		    tmp = gfc_get_symbol_decl (e->symtree->n.sym->cp_pointer);
5496 		    parmse.expr = convert (type, tmp);
5497 		}
5498 
5499 	      else if (sym->attr.is_bind_c && e
5500 		       && (is_CFI_desc (fsym, NULL)
5501 			   || non_unity_length_string))
5502 		/* Implement F2018, C.12.6.1: paragraph (2).  */
5503 		gfc_conv_gfc_desc_to_cfi_desc (&parmse, e, fsym);
5504 
5505 	      else if (fsym && fsym->attr.value)
5506 		{
5507 		  if (fsym->ts.type == BT_CHARACTER
5508 		      && fsym->ts.is_c_interop
5509 		      && fsym->ns->proc_name != NULL
5510 		      && fsym->ns->proc_name->attr.is_bind_c)
5511 		    {
5512 		      parmse.expr = NULL;
5513 		      gfc_conv_scalar_char_value (fsym, &parmse, &e);
5514 		      if (parmse.expr == NULL)
5515 			gfc_conv_expr (&parmse, e);
5516 		    }
5517 		  else
5518 		    {
5519 		    gfc_conv_expr (&parmse, e);
5520 		    if (fsym->attr.optional
5521 			&& fsym->ts.type != BT_CLASS
5522 			&& fsym->ts.type != BT_DERIVED)
5523 		      {
5524 			if (e->expr_type != EXPR_VARIABLE
5525 			    || !e->symtree->n.sym->attr.optional
5526 			    || e->ref != NULL)
5527 			  vec_safe_push (optionalargs, boolean_true_node);
5528 			else
5529 			  {
5530 			    tmp = gfc_conv_expr_present (e->symtree->n.sym);
5531 			    if (!e->symtree->n.sym->attr.value)
5532 			      parmse.expr
5533 				= fold_build3_loc (input_location, COND_EXPR,
5534 					TREE_TYPE (parmse.expr),
5535 					tmp, parmse.expr,
5536 					fold_convert (TREE_TYPE (parmse.expr),
5537 						      integer_zero_node));
5538 
5539 			    vec_safe_push (optionalargs, tmp);
5540 			  }
5541 		      }
5542 		    }
5543 		}
5544 
5545 	      else if (arg->name && arg->name[0] == '%')
5546 		/* Argument list functions %VAL, %LOC and %REF are signalled
5547 		   through arg->name.  */
5548 		conv_arglist_function (&parmse, arg->expr, arg->name);
5549 	      else if ((e->expr_type == EXPR_FUNCTION)
5550 			&& ((e->value.function.esym
5551 			     && e->value.function.esym->result->attr.pointer)
5552 			    || (!e->value.function.esym
5553 				&& e->symtree->n.sym->attr.pointer))
5554 			&& fsym && fsym->attr.target)
5555 		{
5556 		  gfc_conv_expr (&parmse, e);
5557 		  parmse.expr = gfc_build_addr_expr (NULL_TREE, parmse.expr);
5558 		}
5559 
5560 	      else if (e->expr_type == EXPR_FUNCTION
5561 		       && e->symtree->n.sym->result
5562 		       && e->symtree->n.sym->result != e->symtree->n.sym
5563 		       && e->symtree->n.sym->result->attr.proc_pointer)
5564 		{
5565 		  /* Functions returning procedure pointers.  */
5566 		  gfc_conv_expr (&parmse, e);
5567 		  if (fsym && fsym->attr.proc_pointer)
5568 		    parmse.expr = gfc_build_addr_expr (NULL_TREE, parmse.expr);
5569 		}
5570 
5571 	      else
5572 		{
5573 		  if (e->ts.type == BT_CLASS && fsym
5574 		      && fsym->ts.type == BT_CLASS
5575 		      && (!CLASS_DATA (fsym)->as
5576 			  || CLASS_DATA (fsym)->as->type != AS_ASSUMED_RANK)
5577 		      && CLASS_DATA (e)->attr.codimension)
5578 		    {
5579 		      gcc_assert (!CLASS_DATA (fsym)->attr.codimension);
5580 		      gcc_assert (!CLASS_DATA (fsym)->as);
5581 		      gfc_add_class_array_ref (e);
5582 		      parmse.want_coarray = 1;
5583 		      gfc_conv_expr_reference (&parmse, e);
5584 		      class_scalar_coarray_to_class (&parmse, e, fsym->ts,
5585 				     fsym->attr.optional
5586 				     && e->expr_type == EXPR_VARIABLE);
5587 		    }
5588 		  else if (e->ts.type == BT_CLASS && fsym
5589 			   && fsym->ts.type == BT_CLASS
5590 			   && !CLASS_DATA (fsym)->as
5591 			   && !CLASS_DATA (e)->as
5592 			   && strcmp (fsym->ts.u.derived->name,
5593 				      e->ts.u.derived->name))
5594 		    {
5595 		      type = gfc_typenode_for_spec (&fsym->ts);
5596 		      var = gfc_create_var (type, fsym->name);
5597 		      gfc_conv_expr (&parmse, e);
5598 		      if (fsym->attr.optional
5599 			  && e->expr_type == EXPR_VARIABLE
5600 			  && e->symtree->n.sym->attr.optional)
5601 			{
5602 			  stmtblock_t block;
5603 			  tree cond;
5604 			  tmp = gfc_build_addr_expr (NULL_TREE, parmse.expr);
5605 			  cond = fold_build2_loc (input_location, NE_EXPR,
5606 						  logical_type_node, tmp,
5607 						  fold_convert (TREE_TYPE (tmp),
5608 							    null_pointer_node));
5609 			  gfc_start_block (&block);
5610 			  gfc_add_modify (&block, var,
5611 					  fold_build1_loc (input_location,
5612 							   VIEW_CONVERT_EXPR,
5613 							   type, parmse.expr));
5614 			  gfc_add_expr_to_block (&parmse.pre,
5615 				 fold_build3_loc (input_location,
5616 					 COND_EXPR, void_type_node,
5617 					 cond, gfc_finish_block (&block),
5618 					 build_empty_stmt (input_location)));
5619 			  parmse.expr = gfc_build_addr_expr (NULL_TREE, var);
5620 			  parmse.expr = build3_loc (input_location, COND_EXPR,
5621 					 TREE_TYPE (parmse.expr),
5622 					 cond, parmse.expr,
5623 					 fold_convert (TREE_TYPE (parmse.expr),
5624 						       null_pointer_node));
5625 			}
5626 		      else
5627 			{
5628 			  /* Since the internal representation of unlimited
5629 			     polymorphic expressions includes an extra field
5630 			     that other class objects do not, a cast to the
5631 			     formal type does not work.  */
5632 			  if (!UNLIMITED_POLY (e) && UNLIMITED_POLY (fsym))
5633 			    {
5634 			      tree efield;
5635 
5636 			      /* Set the _data field.  */
5637 			      tmp = gfc_class_data_get (var);
5638 			      efield = fold_convert (TREE_TYPE (tmp),
5639 					gfc_class_data_get (parmse.expr));
5640 			      gfc_add_modify (&parmse.pre, tmp, efield);
5641 
5642 			      /* Set the _vptr field.  */
5643 			      tmp = gfc_class_vptr_get (var);
5644 			      efield = fold_convert (TREE_TYPE (tmp),
5645 					gfc_class_vptr_get (parmse.expr));
5646 			      gfc_add_modify (&parmse.pre, tmp, efield);
5647 
5648 			      /* Set the _len field.  */
5649 			      tmp = gfc_class_len_get (var);
5650 			      gfc_add_modify (&parmse.pre, tmp,
5651 					      build_int_cst (TREE_TYPE (tmp), 0));
5652 			    }
5653 			  else
5654 			    {
5655 			      tmp = fold_build1_loc (input_location,
5656 						     VIEW_CONVERT_EXPR,
5657 						     type, parmse.expr);
5658 			      gfc_add_modify (&parmse.pre, var, tmp);
5659 					      ;
5660 			    }
5661 			  parmse.expr = gfc_build_addr_expr (NULL_TREE, var);
5662 			}
5663 		    }
5664 		  else
5665 		    {
5666 		      bool add_clobber;
5667 		      add_clobber = fsym && fsym->attr.intent == INTENT_OUT
5668 			&& !fsym->attr.allocatable && !fsym->attr.pointer
5669 			&& !e->symtree->n.sym->attr.dimension
5670 			&& !e->symtree->n.sym->attr.pointer
5671 			/* See PR 41453.  */
5672 			&& !e->symtree->n.sym->attr.dummy
5673 			/* FIXME - PR 87395 and PR 41453  */
5674 			&& e->symtree->n.sym->attr.save == SAVE_NONE
5675 			&& !e->symtree->n.sym->attr.associate_var
5676 			&& e->ts.type != BT_CHARACTER && e->ts.type != BT_DERIVED
5677 			&& e->ts.type != BT_CLASS && !sym->attr.elemental;
5678 
5679 		      gfc_conv_expr_reference (&parmse, e, add_clobber);
5680 		    }
5681 		  /* Catch base objects that are not variables.  */
5682 		  if (e->ts.type == BT_CLASS
5683 			&& e->expr_type != EXPR_VARIABLE
5684 			&& expr && e == expr->base_expr)
5685 		    base_object = build_fold_indirect_ref_loc (input_location,
5686 							       parmse.expr);
5687 
5688 		  /* A class array element needs converting back to be a
5689 		     class object, if the formal argument is a class object.  */
5690 		  if (fsym && fsym->ts.type == BT_CLASS
5691 			&& e->ts.type == BT_CLASS
5692 			&& ((CLASS_DATA (fsym)->as
5693 			     && CLASS_DATA (fsym)->as->type == AS_ASSUMED_RANK)
5694 			    || CLASS_DATA (e)->attr.dimension))
5695 		    gfc_conv_class_to_class (&parmse, e, fsym->ts, false,
5696 				     fsym->attr.intent != INTENT_IN
5697 				     && (CLASS_DATA (fsym)->attr.class_pointer
5698 					 || CLASS_DATA (fsym)->attr.allocatable),
5699 				     fsym->attr.optional
5700 				     && e->expr_type == EXPR_VARIABLE
5701 				     && e->symtree->n.sym->attr.optional,
5702 				     CLASS_DATA (fsym)->attr.class_pointer
5703 				     || CLASS_DATA (fsym)->attr.allocatable);
5704 
5705 		  /* If an ALLOCATABLE dummy argument has INTENT(OUT) and is
5706 		     allocated on entry, it must be deallocated.  */
5707 		  if (fsym && fsym->attr.intent == INTENT_OUT
5708 		      && (fsym->attr.allocatable
5709 			  || (fsym->ts.type == BT_CLASS
5710 			      && CLASS_DATA (fsym)->attr.allocatable)))
5711 		    {
5712 		      stmtblock_t block;
5713 		      tree ptr;
5714 
5715 		      gfc_init_block  (&block);
5716 		      ptr = parmse.expr;
5717 		      if (e->ts.type == BT_CLASS)
5718 			ptr = gfc_class_data_get (ptr);
5719 
5720 		      tmp = gfc_deallocate_scalar_with_status (ptr, NULL_TREE,
5721 							       NULL_TREE, true,
5722 							       e, e->ts);
5723 		      gfc_add_expr_to_block (&block, tmp);
5724 		      tmp = fold_build2_loc (input_location, MODIFY_EXPR,
5725 					     void_type_node, ptr,
5726 					     null_pointer_node);
5727 		      gfc_add_expr_to_block (&block, tmp);
5728 
5729 		      if (fsym->ts.type == BT_CLASS && UNLIMITED_POLY (fsym))
5730 			{
5731 			  gfc_add_modify (&block, ptr,
5732 					  fold_convert (TREE_TYPE (ptr),
5733 							null_pointer_node));
5734 			  gfc_add_expr_to_block (&block, tmp);
5735 			}
5736 		      else if (fsym->ts.type == BT_CLASS)
5737 			{
5738 			  gfc_symbol *vtab;
5739 			  vtab = gfc_find_derived_vtab (fsym->ts.u.derived);
5740 			  tmp = gfc_get_symbol_decl (vtab);
5741 			  tmp = gfc_build_addr_expr (NULL_TREE, tmp);
5742 			  ptr = gfc_class_vptr_get (parmse.expr);
5743 			  gfc_add_modify (&block, ptr,
5744 					  fold_convert (TREE_TYPE (ptr), tmp));
5745 			  gfc_add_expr_to_block (&block, tmp);
5746 			}
5747 
5748 		      if (fsym->attr.optional
5749 			  && e->expr_type == EXPR_VARIABLE
5750 			  && e->symtree->n.sym->attr.optional)
5751 			{
5752 			  tmp = fold_build3_loc (input_location, COND_EXPR,
5753 				     void_type_node,
5754 				     gfc_conv_expr_present (e->symtree->n.sym),
5755 					    gfc_finish_block (&block),
5756 					    build_empty_stmt (input_location));
5757 			}
5758 		      else
5759 			tmp = gfc_finish_block (&block);
5760 
5761 		      gfc_add_expr_to_block (&se->pre, tmp);
5762 		    }
5763 
5764 		  if (fsym && (fsym->ts.type == BT_DERIVED
5765 			       || fsym->ts.type == BT_ASSUMED)
5766 		      && e->ts.type == BT_CLASS
5767 		      && !CLASS_DATA (e)->attr.dimension
5768 		      && !CLASS_DATA (e)->attr.codimension)
5769 		    {
5770 		      parmse.expr = gfc_class_data_get (parmse.expr);
5771 		      /* The result is a class temporary, whose _data component
5772 			 must be freed to avoid a memory leak.  */
5773 		      if (e->expr_type == EXPR_FUNCTION
5774 			  && CLASS_DATA (e)->attr.allocatable)
5775 			{
5776 			  tree zero;
5777 
5778 			  gfc_expr *var;
5779 
5780 			  /* Borrow the function symbol to make a call to
5781 			     gfc_add_finalizer_call and then restore it.  */
5782 			  tmp = e->symtree->n.sym->backend_decl;
5783 			  e->symtree->n.sym->backend_decl
5784 					= TREE_OPERAND (parmse.expr, 0);
5785 			  e->symtree->n.sym->attr.flavor = FL_VARIABLE;
5786 			  var = gfc_lval_expr_from_sym (e->symtree->n.sym);
5787 			  finalized = gfc_add_finalizer_call (&parmse.post,
5788 							      var);
5789 			  gfc_free_expr (var);
5790 			  e->symtree->n.sym->backend_decl = tmp;
5791 			  e->symtree->n.sym->attr.flavor = FL_PROCEDURE;
5792 
5793 			  /* Then free the class _data.  */
5794 			  zero = build_int_cst (TREE_TYPE (parmse.expr), 0);
5795 			  tmp = fold_build2_loc (input_location, NE_EXPR,
5796 						 logical_type_node,
5797 						 parmse.expr, zero);
5798 			  tmp = build3_v (COND_EXPR, tmp,
5799 					  gfc_call_free (parmse.expr),
5800 					  build_empty_stmt (input_location));
5801 			  gfc_add_expr_to_block (&parmse.post, tmp);
5802 			  gfc_add_modify (&parmse.post, parmse.expr, zero);
5803 			}
5804 		    }
5805 
5806 		  /* Wrap scalar variable in a descriptor. We need to convert
5807 		     the address of a pointer back to the pointer itself before,
5808 		     we can assign it to the data field.  */
5809 
5810 		  if (fsym && fsym->as && fsym->as->type == AS_ASSUMED_RANK
5811 		      && fsym->ts.type != BT_CLASS && e->expr_type != EXPR_NULL)
5812 		    {
5813 		      tmp = parmse.expr;
5814 		      if (TREE_CODE (tmp) == ADDR_EXPR)
5815 			tmp = build_fold_indirect_ref_loc (input_location, tmp);
5816 		      parmse.expr = gfc_conv_scalar_to_descriptor (&parmse, tmp,
5817 								   fsym->attr);
5818 		      parmse.expr = gfc_build_addr_expr (NULL_TREE,
5819 							 parmse.expr);
5820 		    }
5821 		  else if (fsym && e->expr_type != EXPR_NULL
5822 		      && ((fsym->attr.pointer
5823 			   && fsym->attr.flavor != FL_PROCEDURE)
5824 			  || (fsym->attr.proc_pointer
5825 			      && !(e->expr_type == EXPR_VARIABLE
5826 				   && e->symtree->n.sym->attr.dummy))
5827 			  || (fsym->attr.proc_pointer
5828 			      && e->expr_type == EXPR_VARIABLE
5829 			      && gfc_is_proc_ptr_comp (e))
5830 			  || (fsym->attr.allocatable
5831 			      && fsym->attr.flavor != FL_PROCEDURE)))
5832 		    {
5833 		      /* Scalar pointer dummy args require an extra level of
5834 			 indirection. The null pointer already contains
5835 			 this level of indirection.  */
5836 		      parm_kind = SCALAR_POINTER;
5837 		      parmse.expr = gfc_build_addr_expr (NULL_TREE, parmse.expr);
5838 		    }
5839 		}
5840 	    }
5841 	  else if (e->ts.type == BT_CLASS
5842 		    && fsym && fsym->ts.type == BT_CLASS
5843 		    && (CLASS_DATA (fsym)->attr.dimension
5844 			|| CLASS_DATA (fsym)->attr.codimension))
5845 	    {
5846 	      /* Pass a class array.  */
5847 	      parmse.use_offset = 1;
5848 	      gfc_conv_expr_descriptor (&parmse, e);
5849 
5850 	      /* If an ALLOCATABLE dummy argument has INTENT(OUT) and is
5851 		 allocated on entry, it must be deallocated.  */
5852 	      if (fsym->attr.intent == INTENT_OUT
5853 		  && CLASS_DATA (fsym)->attr.allocatable)
5854 		{
5855 		  stmtblock_t block;
5856 		  tree ptr;
5857 
5858 		  gfc_init_block  (&block);
5859 		  ptr = parmse.expr;
5860 		  ptr = gfc_class_data_get (ptr);
5861 
5862 		  tmp = gfc_deallocate_with_status (ptr, NULL_TREE,
5863 						    NULL_TREE, NULL_TREE,
5864 						    NULL_TREE, true, e,
5865 						    GFC_CAF_COARRAY_NOCOARRAY);
5866 		  gfc_add_expr_to_block (&block, tmp);
5867 		  tmp = fold_build2_loc (input_location, MODIFY_EXPR,
5868 					 void_type_node, ptr,
5869 					 null_pointer_node);
5870 		  gfc_add_expr_to_block (&block, tmp);
5871 		  gfc_reset_vptr (&block, e);
5872 
5873 		  if (fsym->attr.optional
5874 		      && e->expr_type == EXPR_VARIABLE
5875 		      && (!e->ref
5876 			  || (e->ref->type == REF_ARRAY
5877 			      && e->ref->u.ar.type != AR_FULL))
5878 		      && e->symtree->n.sym->attr.optional)
5879 		    {
5880 		      tmp = fold_build3_loc (input_location, COND_EXPR,
5881 				    void_type_node,
5882 				    gfc_conv_expr_present (e->symtree->n.sym),
5883 				    gfc_finish_block (&block),
5884 				    build_empty_stmt (input_location));
5885 		    }
5886 		  else
5887 		    tmp = gfc_finish_block (&block);
5888 
5889 		  gfc_add_expr_to_block (&se->pre, tmp);
5890 		}
5891 
5892 	      /* The conversion does not repackage the reference to a class
5893 	         array - _data descriptor.  */
5894 	      gfc_conv_class_to_class (&parmse, e, fsym->ts, false,
5895 				     fsym->attr.intent != INTENT_IN
5896 				     && (CLASS_DATA (fsym)->attr.class_pointer
5897 					 || CLASS_DATA (fsym)->attr.allocatable),
5898 				     fsym->attr.optional
5899 				     && e->expr_type == EXPR_VARIABLE
5900 				     && e->symtree->n.sym->attr.optional,
5901 				     CLASS_DATA (fsym)->attr.class_pointer
5902 				     || CLASS_DATA (fsym)->attr.allocatable);
5903 	    }
5904 	  else
5905 	    {
5906 	      /* If the argument is a function call that may not create
5907 		 a temporary for the result, we have to check that we
5908 		 can do it, i.e. that there is no alias between this
5909 		 argument and another one.  */
5910 	      if (gfc_get_noncopying_intrinsic_argument (e) != NULL)
5911 		{
5912 		  gfc_expr *iarg;
5913 		  sym_intent intent;
5914 
5915 		  if (fsym != NULL)
5916 		    intent = fsym->attr.intent;
5917 		  else
5918 		    intent = INTENT_UNKNOWN;
5919 
5920 		  if (gfc_check_fncall_dependency (e, intent, sym, args,
5921 						   NOT_ELEMENTAL))
5922 		    parmse.force_tmp = 1;
5923 
5924 		  iarg = e->value.function.actual->expr;
5925 
5926 		  /* Temporary needed if aliasing due to host association.  */
5927 		  if (sym->attr.contained
5928 			&& !sym->attr.pure
5929 			&& !sym->attr.implicit_pure
5930 			&& !sym->attr.use_assoc
5931 			&& iarg->expr_type == EXPR_VARIABLE
5932 			&& sym->ns == iarg->symtree->n.sym->ns)
5933 		    parmse.force_tmp = 1;
5934 
5935 		  /* Ditto within module.  */
5936 		  if (sym->attr.use_assoc
5937 			&& !sym->attr.pure
5938 			&& !sym->attr.implicit_pure
5939 			&& iarg->expr_type == EXPR_VARIABLE
5940 			&& sym->module == iarg->symtree->n.sym->module)
5941 		    parmse.force_tmp = 1;
5942 		}
5943 
5944 	      if (sym->attr.is_bind_c && e
5945 		  && (is_CFI_desc (fsym, NULL) || non_unity_length_string))
5946 		/* Implement F2018, C.12.6.1: paragraph (2).  */
5947 		gfc_conv_gfc_desc_to_cfi_desc (&parmse, e, fsym);
5948 
5949 	      else if (e->expr_type == EXPR_VARIABLE
5950 		    && is_subref_array (e)
5951 		    && !(fsym && fsym->attr.pointer))
5952 		/* The actual argument is a component reference to an
5953 		   array of derived types.  In this case, the argument
5954 		   is converted to a temporary, which is passed and then
5955 		   written back after the procedure call.  */
5956 		gfc_conv_subref_array_arg (&parmse, e, nodesc_arg,
5957 				fsym ? fsym->attr.intent : INTENT_INOUT,
5958 				fsym && fsym->attr.pointer);
5959 
5960 	      else if (gfc_is_class_array_ref (e, NULL)
5961 			 && fsym && fsym->ts.type == BT_DERIVED)
5962 		/* The actual argument is a component reference to an
5963 		   array of derived types.  In this case, the argument
5964 		   is converted to a temporary, which is passed and then
5965 		   written back after the procedure call.
5966 		   OOP-TODO: Insert code so that if the dynamic type is
5967 		   the same as the declared type, copy-in/copy-out does
5968 		   not occur.  */
5969 		gfc_conv_subref_array_arg (&parmse, e, nodesc_arg,
5970 				fsym ? fsym->attr.intent : INTENT_INOUT,
5971 				fsym && fsym->attr.pointer);
5972 
5973 	      else if (gfc_is_class_array_function (e)
5974 			 && fsym && fsym->ts.type == BT_DERIVED)
5975 		/* See previous comment.  For function actual argument,
5976 		   the write out is not needed so the intent is set as
5977 		   intent in.  */
5978 		{
5979 		  e->must_finalize = 1;
5980 		  gfc_conv_subref_array_arg (&parmse, e, nodesc_arg,
5981 					     INTENT_IN,
5982 					     fsym && fsym->attr.pointer);
5983 		}
5984 	      else if (fsym && fsym->attr.contiguous
5985 		       && !gfc_is_simply_contiguous (e, false, true))
5986 		{
5987 		  gfc_conv_subref_array_arg (&parmse, e, nodesc_arg,
5988 				fsym ? fsym->attr.intent : INTENT_INOUT,
5989 				fsym && fsym->attr.pointer);
5990 		}
5991 	      else
5992 		gfc_conv_array_parameter (&parmse, e, nodesc_arg, fsym,
5993 					  sym->name, NULL);
5994 
5995 	      /* Unallocated allocatable arrays and unassociated pointer arrays
5996 		 need their dtype setting if they are argument associated with
5997 		 assumed rank dummies.  */
5998 	      if (!sym->attr.is_bind_c && e && fsym && fsym->as
5999 		  && fsym->as->type == AS_ASSUMED_RANK)
6000 		{
6001 		  if (gfc_expr_attr (e).pointer
6002 		      || gfc_expr_attr (e).allocatable)
6003 		    set_dtype_for_unallocated (&parmse, e);
6004 		  else if (e->expr_type == EXPR_VARIABLE
6005 			   && e->symtree->n.sym->attr.dummy
6006 			   && e->symtree->n.sym->as
6007 			   && e->symtree->n.sym->as->type == AS_ASSUMED_SIZE)
6008 		    {
6009 		      tree minus_one;
6010 		      tmp = build_fold_indirect_ref_loc (input_location,
6011 							 parmse.expr);
6012 		      minus_one = build_int_cst (gfc_array_index_type, -1);
6013 		      gfc_conv_descriptor_ubound_set (&parmse.pre, tmp,
6014 						      gfc_rank_cst[e->rank - 1],
6015 						      minus_one);
6016  		    }
6017 		}
6018 
6019 	      /* If an ALLOCATABLE dummy argument has INTENT(OUT) and is
6020 		 allocated on entry, it must be deallocated.  */
6021 	      if (fsym && fsym->attr.allocatable
6022 		  && fsym->attr.intent == INTENT_OUT)
6023 		{
6024 		  if (fsym->ts.type == BT_DERIVED
6025 		      && fsym->ts.u.derived->attr.alloc_comp)
6026 		  {
6027 		    // deallocate the components first
6028 		    tmp = gfc_deallocate_alloc_comp (fsym->ts.u.derived,
6029 						     parmse.expr, e->rank);
6030 		    if (tmp != NULL_TREE)
6031 		      gfc_add_expr_to_block (&se->pre, tmp);
6032 		  }
6033 
6034 		  tmp = parmse.expr;
6035 		  /* With bind(C), the actual argument is replaced by a bind-C
6036 		     descriptor; in this case, the data component arrives here,
6037 		     which shall not be dereferenced, but still freed and
6038 		     nullified.  */
6039 		  if  (TREE_TYPE(tmp) != pvoid_type_node)
6040 		    tmp = build_fold_indirect_ref_loc (input_location,
6041 						       parmse.expr);
6042 		  if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp)))
6043 		    tmp = gfc_conv_descriptor_data_get (tmp);
6044 		  tmp = gfc_deallocate_with_status (tmp, NULL_TREE, NULL_TREE,
6045 						    NULL_TREE, NULL_TREE, true,
6046 						    e,
6047 						    GFC_CAF_COARRAY_NOCOARRAY);
6048 		  if (fsym->attr.optional
6049 		      && e->expr_type == EXPR_VARIABLE
6050 		      && e->symtree->n.sym->attr.optional)
6051 		    tmp = fold_build3_loc (input_location, COND_EXPR,
6052 				     void_type_node,
6053 				     gfc_conv_expr_present (e->symtree->n.sym),
6054 				       tmp, build_empty_stmt (input_location));
6055 		  gfc_add_expr_to_block (&se->pre, tmp);
6056 		}
6057 	    }
6058 	}
6059 
6060       /* The case with fsym->attr.optional is that of a user subroutine
6061 	 with an interface indicating an optional argument.  When we call
6062 	 an intrinsic subroutine, however, fsym is NULL, but we might still
6063 	 have an optional argument, so we proceed to the substitution
6064 	 just in case.  */
6065       if (e && (fsym == NULL || fsym->attr.optional))
6066 	{
6067 	  /* If an optional argument is itself an optional dummy argument,
6068 	     check its presence and substitute a null if absent.  This is
6069 	     only needed when passing an array to an elemental procedure
6070 	     as then array elements are accessed - or no NULL pointer is
6071 	     allowed and a "1" or "0" should be passed if not present.
6072 	     When passing a non-array-descriptor full array to a
6073 	     non-array-descriptor dummy, no check is needed. For
6074 	     array-descriptor actual to array-descriptor dummy, see
6075 	     PR 41911 for why a check has to be inserted.
6076 	     fsym == NULL is checked as intrinsics required the descriptor
6077 	     but do not always set fsym.
6078 	     Also, it is necessary to pass a NULL pointer to library routines
6079 	     which usually ignore optional arguments, so they can handle
6080 	     these themselves.  */
6081 	  if (e->expr_type == EXPR_VARIABLE
6082 	      && e->symtree->n.sym->attr.optional
6083 	      && (((e->rank != 0 && elemental_proc)
6084 		   || e->representation.length || e->ts.type == BT_CHARACTER
6085 		   || (e->rank != 0
6086 		       && (fsym == NULL
6087 			   || (fsym->as
6088 			       && (fsym->as->type == AS_ASSUMED_SHAPE
6089 				   || fsym->as->type == AS_ASSUMED_RANK
6090 				   || fsym->as->type == AS_DEFERRED)))))
6091 		  || se->ignore_optional))
6092 	    gfc_conv_missing_dummy (&parmse, e, fsym ? fsym->ts : e->ts,
6093 				    e->representation.length);
6094 	}
6095 
6096       if (fsym && e)
6097 	{
6098 	  /* Obtain the character length of an assumed character length
6099 	     length procedure from the typespec.  */
6100 	  if (fsym->ts.type == BT_CHARACTER
6101 	      && parmse.string_length == NULL_TREE
6102 	      && e->ts.type == BT_PROCEDURE
6103 	      && e->symtree->n.sym->ts.type == BT_CHARACTER
6104 	      && e->symtree->n.sym->ts.u.cl->length != NULL
6105 	      && e->symtree->n.sym->ts.u.cl->length->expr_type == EXPR_CONSTANT)
6106 	    {
6107 	      gfc_conv_const_charlen (e->symtree->n.sym->ts.u.cl);
6108 	      parmse.string_length = e->symtree->n.sym->ts.u.cl->backend_decl;
6109 	    }
6110 	}
6111 
6112       if (fsym && need_interface_mapping && e)
6113 	gfc_add_interface_mapping (&mapping, fsym, &parmse, e);
6114 
6115       gfc_add_block_to_block (&se->pre, &parmse.pre);
6116       gfc_add_block_to_block (&post, &parmse.post);
6117 
6118       /* Allocated allocatable components of derived types must be
6119 	 deallocated for non-variable scalars, array arguments to elemental
6120 	 procedures, and array arguments with descriptor to non-elemental
6121 	 procedures.  As bounds information for descriptorless arrays is no
6122 	 longer available here, they are dealt with in trans-array.c
6123 	 (gfc_conv_array_parameter).  */
6124       if (e && (e->ts.type == BT_DERIVED || e->ts.type == BT_CLASS)
6125 	    && e->ts.u.derived->attr.alloc_comp
6126 	    && (e->rank == 0 || elemental_proc || !nodesc_arg)
6127 	    && !expr_may_alias_variables (e, elemental_proc))
6128 	{
6129 	  int parm_rank;
6130 	  /* It is known the e returns a structure type with at least one
6131 	     allocatable component.  When e is a function, ensure that the
6132 	     function is called once only by using a temporary variable.  */
6133 	  if (!DECL_P (parmse.expr))
6134 	    parmse.expr = gfc_evaluate_now_loc (input_location,
6135 						parmse.expr, &se->pre);
6136 
6137 	  if (fsym && fsym->attr.value)
6138 	    tmp = parmse.expr;
6139 	  else
6140 	    tmp = build_fold_indirect_ref_loc (input_location,
6141 					       parmse.expr);
6142 
6143 	  parm_rank = e->rank;
6144 	  switch (parm_kind)
6145 	    {
6146 	    case (ELEMENTAL):
6147 	    case (SCALAR):
6148 	      parm_rank = 0;
6149 	      break;
6150 
6151 	    case (SCALAR_POINTER):
6152               tmp = build_fold_indirect_ref_loc (input_location,
6153 					     tmp);
6154 	      break;
6155 	    }
6156 
6157 	  if (e->ts.type == BT_DERIVED && fsym && fsym->ts.type == BT_CLASS)
6158 	    {
6159 	      /* The derived type is passed to gfc_deallocate_alloc_comp.
6160 		 Therefore, class actuals can be handled correctly but derived
6161 		 types passed to class formals need the _data component.  */
6162 	      tmp = gfc_class_data_get (tmp);
6163 	      if (!CLASS_DATA (fsym)->attr.dimension)
6164 		tmp = build_fold_indirect_ref_loc (input_location, tmp);
6165 	    }
6166 
6167 	  if (e->expr_type == EXPR_OP
6168 		&& e->value.op.op == INTRINSIC_PARENTHESES
6169 		&& e->value.op.op1->expr_type == EXPR_VARIABLE)
6170 	    {
6171 	      tree local_tmp;
6172 	      local_tmp = gfc_evaluate_now (tmp, &se->pre);
6173 	      local_tmp = gfc_copy_alloc_comp (e->ts.u.derived, local_tmp, tmp,
6174 					       parm_rank, 0);
6175 	      gfc_add_expr_to_block (&se->post, local_tmp);
6176 	    }
6177 
6178 	  if (!finalized && !e->must_finalize)
6179 	    {
6180 	      if ((e->ts.type == BT_CLASS
6181 		   && GFC_CLASS_TYPE_P (TREE_TYPE (tmp)))
6182 		  || e->ts.type == BT_DERIVED)
6183 		tmp = gfc_deallocate_alloc_comp (e->ts.u.derived, tmp,
6184 						 parm_rank);
6185 	      else if (e->ts.type == BT_CLASS)
6186 		tmp = gfc_deallocate_alloc_comp (CLASS_DATA (e)->ts.u.derived,
6187 						 tmp, parm_rank);
6188 	      gfc_prepend_expr_to_block (&post, tmp);
6189 	    }
6190         }
6191 
6192       /* Add argument checking of passing an unallocated/NULL actual to
6193          a nonallocatable/nonpointer dummy.  */
6194 
6195       if (gfc_option.rtcheck & GFC_RTCHECK_POINTER && e != NULL)
6196         {
6197 	  symbol_attribute attr;
6198 	  char *msg;
6199 	  tree cond;
6200 
6201 	  if (e->expr_type == EXPR_VARIABLE || e->expr_type == EXPR_FUNCTION)
6202 	    attr = gfc_expr_attr (e);
6203 	  else
6204 	    goto end_pointer_check;
6205 
6206 	  /*  In Fortran 2008 it's allowed to pass a NULL pointer/nonallocated
6207 	      allocatable to an optional dummy, cf. 12.5.2.12.  */
6208 	  if (fsym != NULL && fsym->attr.optional && !attr.proc_pointer
6209 	      && (gfc_option.allow_std & GFC_STD_F2008) != 0)
6210 	    goto end_pointer_check;
6211 
6212           if (attr.optional)
6213 	    {
6214               /* If the actual argument is an optional pointer/allocatable and
6215 		 the formal argument takes an nonpointer optional value,
6216 		 it is invalid to pass a non-present argument on, even
6217 		 though there is no technical reason for this in gfortran.
6218 		 See Fortran 2003, Section 12.4.1.6 item (7)+(8).  */
6219 	      tree present, null_ptr, type;
6220 
6221 	      if (attr.allocatable
6222 		  && (fsym == NULL || !fsym->attr.allocatable))
6223 		msg = xasprintf ("Allocatable actual argument '%s' is not "
6224 				 "allocated or not present",
6225 				 e->symtree->n.sym->name);
6226 	      else if (attr.pointer
6227 		       && (fsym == NULL || !fsym->attr.pointer))
6228 		msg = xasprintf ("Pointer actual argument '%s' is not "
6229 				 "associated or not present",
6230 				 e->symtree->n.sym->name);
6231 	      else if (attr.proc_pointer
6232 		       && (fsym == NULL || !fsym->attr.proc_pointer))
6233 		msg = xasprintf ("Proc-pointer actual argument '%s' is not "
6234 				 "associated or not present",
6235 				 e->symtree->n.sym->name);
6236 	      else
6237 		goto end_pointer_check;
6238 
6239 	      present = gfc_conv_expr_present (e->symtree->n.sym);
6240 	      type = TREE_TYPE (present);
6241 	      present = fold_build2_loc (input_location, EQ_EXPR,
6242 					 logical_type_node, present,
6243 					 fold_convert (type,
6244 						       null_pointer_node));
6245 	      type = TREE_TYPE (parmse.expr);
6246 	      null_ptr = fold_build2_loc (input_location, EQ_EXPR,
6247 					  logical_type_node, parmse.expr,
6248 					  fold_convert (type,
6249 							null_pointer_node));
6250 	      cond = fold_build2_loc (input_location, TRUTH_ORIF_EXPR,
6251 				      logical_type_node, present, null_ptr);
6252 	    }
6253           else
6254 	    {
6255 	      if (attr.allocatable
6256 		  && (fsym == NULL || !fsym->attr.allocatable))
6257 		msg = xasprintf ("Allocatable actual argument '%s' is not "
6258 				 "allocated", e->symtree->n.sym->name);
6259 	      else if (attr.pointer
6260 		       && (fsym == NULL || !fsym->attr.pointer))
6261 		msg = xasprintf ("Pointer actual argument '%s' is not "
6262 				 "associated", e->symtree->n.sym->name);
6263 	      else if (attr.proc_pointer
6264 		       && (fsym == NULL || !fsym->attr.proc_pointer))
6265 		msg = xasprintf ("Proc-pointer actual argument '%s' is not "
6266 				 "associated", e->symtree->n.sym->name);
6267 	      else
6268 		goto end_pointer_check;
6269 
6270 	      tmp = parmse.expr;
6271 
6272 	      /* If the argument is passed by value, we need to strip the
6273 		 INDIRECT_REF.  */
6274 	      if (!POINTER_TYPE_P (TREE_TYPE (parmse.expr)))
6275 		tmp = gfc_build_addr_expr (NULL_TREE, tmp);
6276 
6277 	      cond = fold_build2_loc (input_location, EQ_EXPR,
6278 				      logical_type_node, tmp,
6279 				      fold_convert (TREE_TYPE (tmp),
6280 						    null_pointer_node));
6281 	    }
6282 
6283 	  gfc_trans_runtime_check (true, false, cond, &se->pre, &e->where,
6284 				   msg);
6285 	  free (msg);
6286         }
6287       end_pointer_check:
6288 
6289       /* Deferred length dummies pass the character length by reference
6290 	 so that the value can be returned.  */
6291       if (parmse.string_length && fsym && fsym->ts.deferred)
6292 	{
6293 	  if (INDIRECT_REF_P (parmse.string_length))
6294 	    /* In chains of functions/procedure calls the string_length already
6295 	       is a pointer to the variable holding the length.  Therefore
6296 	       remove the deref on call.  */
6297 	    parmse.string_length = TREE_OPERAND (parmse.string_length, 0);
6298 	  else
6299 	    {
6300 	      tmp = parmse.string_length;
6301 	      if (!VAR_P (tmp) && TREE_CODE (tmp) != COMPONENT_REF)
6302 		tmp = gfc_evaluate_now (parmse.string_length, &se->pre);
6303 	      parmse.string_length = gfc_build_addr_expr (NULL_TREE, tmp);
6304 	    }
6305 	}
6306 
6307       /* Character strings are passed as two parameters, a length and a
6308 	 pointer - except for Bind(c) which only passes the pointer.
6309 	 An unlimited polymorphic formal argument likewise does not
6310 	 need the length.  */
6311       if (parmse.string_length != NULL_TREE
6312 	  && !sym->attr.is_bind_c
6313 	  && !(fsym && UNLIMITED_POLY (fsym)))
6314 	vec_safe_push (stringargs, parmse.string_length);
6315 
6316       /* When calling __copy for character expressions to unlimited
6317 	 polymorphic entities, the dst argument needs a string length.  */
6318       if (sym->name[0] == '_' && e && e->ts.type == BT_CHARACTER
6319 	  && gfc_str_startswith (sym->name, "__vtab_CHARACTER")
6320 	  && arg->next && arg->next->expr
6321 	  && (arg->next->expr->ts.type == BT_DERIVED
6322 	      || arg->next->expr->ts.type == BT_CLASS)
6323 	  && arg->next->expr->ts.u.derived->attr.unlimited_polymorphic)
6324 	vec_safe_push (stringargs, parmse.string_length);
6325 
6326       /* For descriptorless coarrays and assumed-shape coarray dummies, we
6327 	 pass the token and the offset as additional arguments.  */
6328       if (fsym && e == NULL && flag_coarray == GFC_FCOARRAY_LIB
6329 	  && ((fsym->ts.type != BT_CLASS && fsym->attr.codimension
6330 	       && !fsym->attr.allocatable)
6331 	      || (fsym->ts.type == BT_CLASS
6332 		  && CLASS_DATA (fsym)->attr.codimension
6333 		  && !CLASS_DATA (fsym)->attr.allocatable)))
6334 	{
6335 	  /* Token and offset.  */
6336 	  vec_safe_push (stringargs, null_pointer_node);
6337 	  vec_safe_push (stringargs, build_int_cst (gfc_array_index_type, 0));
6338 	  gcc_assert (fsym->attr.optional);
6339 	}
6340       else if (fsym && flag_coarray == GFC_FCOARRAY_LIB
6341 	       && ((fsym->ts.type != BT_CLASS && fsym->attr.codimension
6342 		    && !fsym->attr.allocatable)
6343 		   || (fsym->ts.type == BT_CLASS
6344 		       && CLASS_DATA (fsym)->attr.codimension
6345 		       && !CLASS_DATA (fsym)->attr.allocatable)))
6346 	{
6347 	  tree caf_decl, caf_type;
6348 	  tree offset, tmp2;
6349 
6350 	  caf_decl = gfc_get_tree_for_caf_expr (e);
6351 	  caf_type = TREE_TYPE (caf_decl);
6352 
6353 	  if (GFC_DESCRIPTOR_TYPE_P (caf_type)
6354 	      && (GFC_TYPE_ARRAY_AKIND (caf_type) == GFC_ARRAY_ALLOCATABLE
6355 		  || GFC_TYPE_ARRAY_AKIND (caf_type) == GFC_ARRAY_POINTER))
6356 	    tmp = gfc_conv_descriptor_token (caf_decl);
6357 	  else if (DECL_LANG_SPECIFIC (caf_decl)
6358 		   && GFC_DECL_TOKEN (caf_decl) != NULL_TREE)
6359 	    tmp = GFC_DECL_TOKEN (caf_decl);
6360 	  else
6361 	    {
6362 	      gcc_assert (GFC_ARRAY_TYPE_P (caf_type)
6363 			  && GFC_TYPE_ARRAY_CAF_TOKEN (caf_type) != NULL_TREE);
6364 	      tmp = GFC_TYPE_ARRAY_CAF_TOKEN (caf_type);
6365 	    }
6366 
6367 	  vec_safe_push (stringargs, tmp);
6368 
6369 	  if (GFC_DESCRIPTOR_TYPE_P (caf_type)
6370 	      && GFC_TYPE_ARRAY_AKIND (caf_type) == GFC_ARRAY_ALLOCATABLE)
6371 	    offset = build_int_cst (gfc_array_index_type, 0);
6372 	  else if (DECL_LANG_SPECIFIC (caf_decl)
6373 		   && GFC_DECL_CAF_OFFSET (caf_decl) != NULL_TREE)
6374 	    offset = GFC_DECL_CAF_OFFSET (caf_decl);
6375 	  else if (GFC_TYPE_ARRAY_CAF_OFFSET (caf_type) != NULL_TREE)
6376 	    offset = GFC_TYPE_ARRAY_CAF_OFFSET (caf_type);
6377 	  else
6378 	    offset = build_int_cst (gfc_array_index_type, 0);
6379 
6380 	  if (GFC_DESCRIPTOR_TYPE_P (caf_type))
6381 	    tmp = gfc_conv_descriptor_data_get (caf_decl);
6382 	  else
6383 	    {
6384 	      gcc_assert (POINTER_TYPE_P (caf_type));
6385 	      tmp = caf_decl;
6386 	    }
6387 
6388           tmp2 = fsym->ts.type == BT_CLASS
6389 		 ? gfc_class_data_get (parmse.expr) : parmse.expr;
6390           if ((fsym->ts.type != BT_CLASS
6391 	       && (fsym->as->type == AS_ASSUMED_SHAPE
6392 		   || fsym->as->type == AS_ASSUMED_RANK))
6393 	      || (fsym->ts.type == BT_CLASS
6394 		  && (CLASS_DATA (fsym)->as->type == AS_ASSUMED_SHAPE
6395 		      || CLASS_DATA (fsym)->as->type == AS_ASSUMED_RANK)))
6396 	    {
6397 	      if (fsym->ts.type == BT_CLASS)
6398 		gcc_assert (!POINTER_TYPE_P (TREE_TYPE (tmp2)));
6399 	      else
6400 		{
6401 		  gcc_assert (POINTER_TYPE_P (TREE_TYPE (tmp2)));
6402 		  tmp2 = build_fold_indirect_ref_loc (input_location, tmp2);
6403 		}
6404 	      gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp2)));
6405 	      tmp2 = gfc_conv_descriptor_data_get (tmp2);
6406 	    }
6407 	  else if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp2)))
6408 	    tmp2 = gfc_conv_descriptor_data_get (tmp2);
6409 	  else
6410 	    {
6411 	      gcc_assert (POINTER_TYPE_P (TREE_TYPE (tmp2)));
6412 	    }
6413 
6414 	  tmp = fold_build2_loc (input_location, MINUS_EXPR,
6415                                  gfc_array_index_type,
6416                                  fold_convert (gfc_array_index_type, tmp2),
6417                                  fold_convert (gfc_array_index_type, tmp));
6418 	  offset = fold_build2_loc (input_location, PLUS_EXPR,
6419 				    gfc_array_index_type, offset, tmp);
6420 
6421 	  vec_safe_push (stringargs, offset);
6422 	}
6423 
6424       vec_safe_push (arglist, parmse.expr);
6425     }
6426   gfc_finish_interface_mapping (&mapping, &se->pre, &se->post);
6427 
6428   if (comp)
6429     ts = comp->ts;
6430   else if (sym->ts.type == BT_CLASS)
6431     ts = CLASS_DATA (sym)->ts;
6432   else
6433     ts = sym->ts;
6434 
6435   if (ts.type == BT_CHARACTER && sym->attr.is_bind_c)
6436     se->string_length = build_int_cst (gfc_charlen_type_node, 1);
6437   else if (ts.type == BT_CHARACTER)
6438     {
6439       if (ts.u.cl->length == NULL)
6440 	{
6441 	  /* Assumed character length results are not allowed by C418 of the 2003
6442 	     standard and are trapped in resolve.c; except in the case of SPREAD
6443 	     (and other intrinsics?) and dummy functions.  In the case of SPREAD,
6444 	     we take the character length of the first argument for the result.
6445 	     For dummies, we have to look through the formal argument list for
6446 	     this function and use the character length found there.*/
6447 	  if (ts.deferred)
6448 	    cl.backend_decl = gfc_create_var (gfc_charlen_type_node, "slen");
6449 	  else if (!sym->attr.dummy)
6450 	    cl.backend_decl = (*stringargs)[0];
6451 	  else
6452 	    {
6453 	      formal = gfc_sym_get_dummy_args (sym->ns->proc_name);
6454 	      for (; formal; formal = formal->next)
6455 		if (strcmp (formal->sym->name, sym->name) == 0)
6456 		  cl.backend_decl = formal->sym->ts.u.cl->backend_decl;
6457 	    }
6458 	  len = cl.backend_decl;
6459         }
6460       else
6461         {
6462 	  tree tmp;
6463 
6464 	  /* Calculate the length of the returned string.  */
6465 	  gfc_init_se (&parmse, NULL);
6466 	  if (need_interface_mapping)
6467 	    gfc_apply_interface_mapping (&mapping, &parmse, ts.u.cl->length);
6468 	  else
6469 	    gfc_conv_expr (&parmse, ts.u.cl->length);
6470 	  gfc_add_block_to_block (&se->pre, &parmse.pre);
6471 	  gfc_add_block_to_block (&se->post, &parmse.post);
6472 	  tmp = parmse.expr;
6473 	  /* TODO: It would be better to have the charlens as
6474 	     gfc_charlen_type_node already when the interface is
6475 	     created instead of converting it here (see PR 84615).  */
6476 	  tmp = fold_build2_loc (input_location, MAX_EXPR,
6477 				 gfc_charlen_type_node,
6478 				 fold_convert (gfc_charlen_type_node, tmp),
6479 				 build_zero_cst (gfc_charlen_type_node));
6480 	  cl.backend_decl = tmp;
6481 	}
6482 
6483       /* Set up a charlen structure for it.  */
6484       cl.next = NULL;
6485       cl.length = NULL;
6486       ts.u.cl = &cl;
6487 
6488       len = cl.backend_decl;
6489     }
6490 
6491   byref = (comp && (comp->attr.dimension
6492 	   || (comp->ts.type == BT_CHARACTER && !sym->attr.is_bind_c)))
6493 	   || (!comp && gfc_return_by_reference (sym));
6494   if (byref)
6495     {
6496       if (se->direct_byref)
6497 	{
6498 	  /* Sometimes, too much indirection can be applied; e.g. for
6499 	     function_result = array_valued_recursive_function.  */
6500 	  if (TREE_TYPE (TREE_TYPE (se->expr))
6501 		&& TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr)))
6502 		&& GFC_DESCRIPTOR_TYPE_P
6503 			(TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr)))))
6504 	    se->expr = build_fold_indirect_ref_loc (input_location,
6505 						    se->expr);
6506 
6507 	  /* If the lhs of an assignment x = f(..) is allocatable and
6508 	     f2003 is allowed, we must do the automatic reallocation.
6509 	     TODO - deal with intrinsics, without using a temporary.  */
6510 	  if (flag_realloc_lhs
6511 		&& se->ss && se->ss->loop_chain
6512 		&& se->ss->loop_chain->is_alloc_lhs
6513 		&& !expr->value.function.isym
6514 		&& sym->result->as != NULL)
6515 	    {
6516 	      /* Evaluate the bounds of the result, if known.  */
6517 	      gfc_set_loop_bounds_from_array_spec (&mapping, se,
6518 						   sym->result->as);
6519 
6520 	      /* Perform the automatic reallocation.  */
6521 	      tmp = gfc_alloc_allocatable_for_assignment (se->loop,
6522 							  expr, NULL);
6523 	      gfc_add_expr_to_block (&se->pre, tmp);
6524 
6525 	      /* Pass the temporary as the first argument.  */
6526 	      result = info->descriptor;
6527 	    }
6528 	  else
6529 	    result = build_fold_indirect_ref_loc (input_location,
6530 						  se->expr);
6531 	  vec_safe_push (retargs, se->expr);
6532 	}
6533       else if (comp && comp->attr.dimension)
6534 	{
6535 	  gcc_assert (se->loop && info);
6536 
6537 	  /* Set the type of the array.  */
6538 	  tmp = gfc_typenode_for_spec (&comp->ts);
6539 	  gcc_assert (se->ss->dimen == se->loop->dimen);
6540 
6541 	  /* Evaluate the bounds of the result, if known.  */
6542 	  gfc_set_loop_bounds_from_array_spec (&mapping, se, comp->as);
6543 
6544 	  /* If the lhs of an assignment x = f(..) is allocatable and
6545 	     f2003 is allowed, we must not generate the function call
6546 	     here but should just send back the results of the mapping.
6547 	     This is signalled by the function ss being flagged.  */
6548 	  if (flag_realloc_lhs && se->ss && se->ss->is_alloc_lhs)
6549 	    {
6550 	      gfc_free_interface_mapping (&mapping);
6551 	      return has_alternate_specifier;
6552 	    }
6553 
6554 	  /* Create a temporary to store the result.  In case the function
6555 	     returns a pointer, the temporary will be a shallow copy and
6556 	     mustn't be deallocated.  */
6557 	  callee_alloc = comp->attr.allocatable || comp->attr.pointer;
6558 	  gfc_trans_create_temp_array (&se->pre, &se->post, se->ss,
6559 				       tmp, NULL_TREE, false,
6560 				       !comp->attr.pointer, callee_alloc,
6561 				       &se->ss->info->expr->where);
6562 
6563 	  /* Pass the temporary as the first argument.  */
6564 	  result = info->descriptor;
6565 	  tmp = gfc_build_addr_expr (NULL_TREE, result);
6566 	  vec_safe_push (retargs, tmp);
6567 	}
6568       else if (!comp && sym->result->attr.dimension)
6569 	{
6570 	  gcc_assert (se->loop && info);
6571 
6572 	  /* Set the type of the array.  */
6573 	  tmp = gfc_typenode_for_spec (&ts);
6574 	  gcc_assert (se->ss->dimen == se->loop->dimen);
6575 
6576 	  /* Evaluate the bounds of the result, if known.  */
6577 	  gfc_set_loop_bounds_from_array_spec (&mapping, se, sym->result->as);
6578 
6579 	  /* If the lhs of an assignment x = f(..) is allocatable and
6580 	     f2003 is allowed, we must not generate the function call
6581 	     here but should just send back the results of the mapping.
6582 	     This is signalled by the function ss being flagged.  */
6583 	  if (flag_realloc_lhs && se->ss && se->ss->is_alloc_lhs)
6584 	    {
6585 	      gfc_free_interface_mapping (&mapping);
6586 	      return has_alternate_specifier;
6587 	    }
6588 
6589 	  /* Create a temporary to store the result.  In case the function
6590 	     returns a pointer, the temporary will be a shallow copy and
6591 	     mustn't be deallocated.  */
6592 	  callee_alloc = sym->attr.allocatable || sym->attr.pointer;
6593 	  gfc_trans_create_temp_array (&se->pre, &se->post, se->ss,
6594 				       tmp, NULL_TREE, false,
6595 				       !sym->attr.pointer, callee_alloc,
6596 				       &se->ss->info->expr->where);
6597 
6598 	  /* Pass the temporary as the first argument.  */
6599 	  result = info->descriptor;
6600 	  tmp = gfc_build_addr_expr (NULL_TREE, result);
6601 	  vec_safe_push (retargs, tmp);
6602 	}
6603       else if (ts.type == BT_CHARACTER)
6604 	{
6605 	  /* Pass the string length.  */
6606 	  type = gfc_get_character_type (ts.kind, ts.u.cl);
6607 	  type = build_pointer_type (type);
6608 
6609 	  /* Emit a DECL_EXPR for the VLA type.  */
6610 	  tmp = TREE_TYPE (type);
6611 	  if (TYPE_SIZE (tmp)
6612 	      && TREE_CODE (TYPE_SIZE (tmp)) != INTEGER_CST)
6613 	    {
6614 	      tmp = build_decl (input_location, TYPE_DECL, NULL_TREE, tmp);
6615 	      DECL_ARTIFICIAL (tmp) = 1;
6616 	      DECL_IGNORED_P (tmp) = 1;
6617 	      tmp = fold_build1_loc (input_location, DECL_EXPR,
6618 				     TREE_TYPE (tmp), tmp);
6619 	      gfc_add_expr_to_block (&se->pre, tmp);
6620 	    }
6621 
6622 	  /* Return an address to a char[0:len-1]* temporary for
6623 	     character pointers.  */
6624 	  if ((!comp && (sym->attr.pointer || sym->attr.allocatable))
6625 	       || (comp && (comp->attr.pointer || comp->attr.allocatable)))
6626 	    {
6627 	      var = gfc_create_var (type, "pstr");
6628 
6629 	      if ((!comp && sym->attr.allocatable)
6630 		  || (comp && comp->attr.allocatable))
6631 		{
6632 		  gfc_add_modify (&se->pre, var,
6633 				  fold_convert (TREE_TYPE (var),
6634 						null_pointer_node));
6635 		  tmp = gfc_call_free (var);
6636 		  gfc_add_expr_to_block (&se->post, tmp);
6637 		}
6638 
6639 	      /* Provide an address expression for the function arguments.  */
6640 	      var = gfc_build_addr_expr (NULL_TREE, var);
6641 	    }
6642 	  else
6643 	    var = gfc_conv_string_tmp (se, type, len);
6644 
6645 	  vec_safe_push (retargs, var);
6646 	}
6647       else
6648 	{
6649 	  gcc_assert (flag_f2c && ts.type == BT_COMPLEX);
6650 
6651 	  type = gfc_get_complex_type (ts.kind);
6652 	  var = gfc_build_addr_expr (NULL_TREE, gfc_create_var (type, "cmplx"));
6653 	  vec_safe_push (retargs, var);
6654 	}
6655 
6656       /* Add the string length to the argument list.  */
6657       if (ts.type == BT_CHARACTER && ts.deferred)
6658 	{
6659 	  tmp = len;
6660 	  if (!VAR_P (tmp))
6661 	    tmp = gfc_evaluate_now (len, &se->pre);
6662 	  TREE_STATIC (tmp) = 1;
6663 	  gfc_add_modify (&se->pre, tmp,
6664 			  build_int_cst (TREE_TYPE (tmp), 0));
6665 	  tmp = gfc_build_addr_expr (NULL_TREE, tmp);
6666 	  vec_safe_push (retargs, tmp);
6667 	}
6668       else if (ts.type == BT_CHARACTER)
6669 	vec_safe_push (retargs, len);
6670     }
6671   gfc_free_interface_mapping (&mapping);
6672 
6673   /* We need to glom RETARGS + ARGLIST + STRINGARGS + APPEND_ARGS.  */
6674   arglen = (vec_safe_length (arglist) + vec_safe_length (optionalargs)
6675 	    + vec_safe_length (stringargs) + vec_safe_length (append_args));
6676   vec_safe_reserve (retargs, arglen);
6677 
6678   /* Add the return arguments.  */
6679   vec_safe_splice (retargs, arglist);
6680 
6681   /* Add the hidden present status for optional+value to the arguments.  */
6682   vec_safe_splice (retargs, optionalargs);
6683 
6684   /* Add the hidden string length parameters to the arguments.  */
6685   vec_safe_splice (retargs, stringargs);
6686 
6687   /* We may want to append extra arguments here.  This is used e.g. for
6688      calls to libgfortran_matmul_??, which need extra information.  */
6689   vec_safe_splice (retargs, append_args);
6690 
6691   arglist = retargs;
6692 
6693   /* Generate the actual call.  */
6694   if (base_object == NULL_TREE)
6695     conv_function_val (se, sym, expr, args);
6696   else
6697     conv_base_obj_fcn_val (se, base_object, expr);
6698 
6699   /* If there are alternate return labels, function type should be
6700      integer.  Can't modify the type in place though, since it can be shared
6701      with other functions.  For dummy arguments, the typing is done to
6702      this result, even if it has to be repeated for each call.  */
6703   if (has_alternate_specifier
6704       && TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr))) != integer_type_node)
6705     {
6706       if (!sym->attr.dummy)
6707 	{
6708 	  TREE_TYPE (sym->backend_decl)
6709 		= build_function_type (integer_type_node,
6710 		      TYPE_ARG_TYPES (TREE_TYPE (sym->backend_decl)));
6711 	  se->expr = gfc_build_addr_expr (NULL_TREE, sym->backend_decl);
6712 	}
6713       else
6714 	TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr))) = integer_type_node;
6715     }
6716 
6717   fntype = TREE_TYPE (TREE_TYPE (se->expr));
6718   se->expr = build_call_vec (TREE_TYPE (fntype), se->expr, arglist);
6719 
6720   /* Allocatable scalar function results must be freed and nullified
6721      after use. This necessitates the creation of a temporary to
6722      hold the result to prevent duplicate calls.  */
6723   if (!byref && sym->ts.type != BT_CHARACTER
6724       && ((sym->attr.allocatable && !sym->attr.dimension && !comp)
6725 	  || (comp && comp->attr.allocatable && !comp->attr.dimension)))
6726     {
6727       tmp = gfc_create_var (TREE_TYPE (se->expr), NULL);
6728       gfc_add_modify (&se->pre, tmp, se->expr);
6729       se->expr = tmp;
6730       tmp = gfc_call_free (tmp);
6731       gfc_add_expr_to_block (&post, tmp);
6732       gfc_add_modify (&post, se->expr, build_int_cst (TREE_TYPE (se->expr), 0));
6733     }
6734 
6735   /* If we have a pointer function, but we don't want a pointer, e.g.
6736      something like
6737         x = f()
6738      where f is pointer valued, we have to dereference the result.  */
6739   if (!se->want_pointer && !byref
6740       && ((!comp && (sym->attr.pointer || sym->attr.allocatable))
6741 	  || (comp && (comp->attr.pointer || comp->attr.allocatable))))
6742     se->expr = build_fold_indirect_ref_loc (input_location, se->expr);
6743 
6744   /* f2c calling conventions require a scalar default real function to
6745      return a double precision result.  Convert this back to default
6746      real.  We only care about the cases that can happen in Fortran 77.
6747   */
6748   if (flag_f2c && sym->ts.type == BT_REAL
6749       && sym->ts.kind == gfc_default_real_kind
6750       && !sym->attr.always_explicit)
6751     se->expr = fold_convert (gfc_get_real_type (sym->ts.kind), se->expr);
6752 
6753   /* A pure function may still have side-effects - it may modify its
6754      parameters.  */
6755   TREE_SIDE_EFFECTS (se->expr) = 1;
6756 #if 0
6757   if (!sym->attr.pure)
6758     TREE_SIDE_EFFECTS (se->expr) = 1;
6759 #endif
6760 
6761   if (byref)
6762     {
6763       /* Add the function call to the pre chain.  There is no expression.  */
6764       gfc_add_expr_to_block (&se->pre, se->expr);
6765       se->expr = NULL_TREE;
6766 
6767       if (!se->direct_byref)
6768 	{
6769 	  if ((sym->attr.dimension && !comp) || (comp && comp->attr.dimension))
6770 	    {
6771 	      if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
6772 		{
6773 		  /* Check the data pointer hasn't been modified.  This would
6774 		     happen in a function returning a pointer.  */
6775 		  tmp = gfc_conv_descriptor_data_get (info->descriptor);
6776 		  tmp = fold_build2_loc (input_location, NE_EXPR,
6777 					 logical_type_node,
6778 					 tmp, info->data);
6779 		  gfc_trans_runtime_check (true, false, tmp, &se->pre, NULL,
6780 					   gfc_msg_fault);
6781 		}
6782 	      se->expr = info->descriptor;
6783 	      /* Bundle in the string length.  */
6784 	      se->string_length = len;
6785 	    }
6786 	  else if (ts.type == BT_CHARACTER)
6787 	    {
6788 	      /* Dereference for character pointer results.  */
6789 	      if ((!comp && (sym->attr.pointer || sym->attr.allocatable))
6790 		  || (comp && (comp->attr.pointer || comp->attr.allocatable)))
6791 		se->expr = build_fold_indirect_ref_loc (input_location, var);
6792 	      else
6793 	        se->expr = var;
6794 
6795 	      se->string_length = len;
6796 	    }
6797 	  else
6798 	    {
6799 	      gcc_assert (ts.type == BT_COMPLEX && flag_f2c);
6800 	      se->expr = build_fold_indirect_ref_loc (input_location, var);
6801 	    }
6802 	}
6803     }
6804 
6805   /* Associate the rhs class object's meta-data with the result, when the
6806      result is a temporary.  */
6807   if (args && args->expr && args->expr->ts.type == BT_CLASS
6808       && sym->ts.type == BT_CLASS && result != NULL_TREE && DECL_P (result)
6809       && !GFC_CLASS_TYPE_P (TREE_TYPE (result)))
6810     {
6811       gfc_se parmse;
6812       gfc_expr *class_expr = gfc_find_and_cut_at_last_class_ref (args->expr);
6813 
6814       gfc_init_se (&parmse, NULL);
6815       parmse.data_not_needed = 1;
6816       gfc_conv_expr (&parmse, class_expr);
6817       if (!DECL_LANG_SPECIFIC (result))
6818 	gfc_allocate_lang_decl (result);
6819       GFC_DECL_SAVED_DESCRIPTOR (result) = parmse.expr;
6820       gfc_free_expr (class_expr);
6821       /* -fcheck= can add diagnostic code, which has to be placed before
6822 	 the call. */
6823       if (parmse.pre.head != NULL)
6824 	  gfc_add_expr_to_block (&se->pre, parmse.pre.head);
6825       gcc_assert (parmse.post.head == NULL_TREE);
6826     }
6827 
6828   /* Follow the function call with the argument post block.  */
6829   if (byref)
6830     {
6831       gfc_add_block_to_block (&se->pre, &post);
6832 
6833       /* Transformational functions of derived types with allocatable
6834 	 components must have the result allocatable components copied when the
6835 	 argument is actually given.  */
6836       arg = expr->value.function.actual;
6837       if (result && arg && expr->rank
6838 	  && expr->value.function.isym
6839 	  && expr->value.function.isym->transformational
6840 	  && arg->expr
6841 	  && arg->expr->ts.type == BT_DERIVED
6842 	  && arg->expr->ts.u.derived->attr.alloc_comp)
6843 	{
6844 	  tree tmp2;
6845 	  /* Copy the allocatable components.  We have to use a
6846 	     temporary here to prevent source allocatable components
6847 	     from being corrupted.  */
6848 	  tmp2 = gfc_evaluate_now (result, &se->pre);
6849 	  tmp = gfc_copy_alloc_comp (arg->expr->ts.u.derived,
6850 				     result, tmp2, expr->rank, 0);
6851 	  gfc_add_expr_to_block (&se->pre, tmp);
6852 	  tmp = gfc_copy_allocatable_data (result, tmp2, TREE_TYPE(tmp2),
6853 				           expr->rank);
6854 	  gfc_add_expr_to_block (&se->pre, tmp);
6855 
6856 	  /* Finally free the temporary's data field.  */
6857 	  tmp = gfc_conv_descriptor_data_get (tmp2);
6858 	  tmp = gfc_deallocate_with_status (tmp, NULL_TREE, NULL_TREE,
6859 					    NULL_TREE, NULL_TREE, true,
6860 					    NULL, GFC_CAF_COARRAY_NOCOARRAY);
6861 	  gfc_add_expr_to_block (&se->pre, tmp);
6862 	}
6863     }
6864   else
6865     {
6866       /* For a function with a class array result, save the result as
6867 	 a temporary, set the info fields needed by the scalarizer and
6868 	 call the finalization function of the temporary. Note that the
6869 	 nullification of allocatable components needed by the result
6870 	 is done in gfc_trans_assignment_1.  */
6871       if (expr && ((gfc_is_class_array_function (expr)
6872 		    && se->ss && se->ss->loop)
6873 		   || gfc_is_alloc_class_scalar_function (expr))
6874 	  && se->expr && GFC_CLASS_TYPE_P (TREE_TYPE (se->expr))
6875 	  && expr->must_finalize)
6876 	{
6877 	  tree final_fndecl;
6878 	  tree is_final;
6879 	  int n;
6880 	  if (se->ss && se->ss->loop)
6881 	    {
6882 	      gfc_add_block_to_block (&se->ss->loop->pre, &se->pre);
6883 	      se->expr = gfc_evaluate_now (se->expr, &se->ss->loop->pre);
6884 	      tmp = gfc_class_data_get (se->expr);
6885 	      info->descriptor = tmp;
6886 	      info->data = gfc_conv_descriptor_data_get (tmp);
6887 	      info->offset = gfc_conv_descriptor_offset_get (tmp);
6888 	      for (n = 0; n < se->ss->loop->dimen; n++)
6889 		{
6890 		  tree dim = gfc_rank_cst[n];
6891 		  se->ss->loop->to[n] = gfc_conv_descriptor_ubound_get (tmp, dim);
6892 		  se->ss->loop->from[n] = gfc_conv_descriptor_lbound_get (tmp, dim);
6893 		}
6894 	    }
6895 	  else
6896 	    {
6897 	      /* TODO Eliminate the doubling of temporaries. This
6898 		 one is necessary to ensure no memory leakage.  */
6899 	      se->expr = gfc_evaluate_now (se->expr, &se->pre);
6900 	      tmp = gfc_class_data_get (se->expr);
6901 	      tmp = gfc_conv_scalar_to_descriptor (se, tmp,
6902 			CLASS_DATA (expr->value.function.esym->result)->attr);
6903 	    }
6904 
6905 	  if ((gfc_is_class_array_function (expr)
6906 	       || gfc_is_alloc_class_scalar_function (expr))
6907 	      && CLASS_DATA (expr->value.function.esym->result)->attr.pointer)
6908 	    goto no_finalization;
6909 
6910 	  final_fndecl = gfc_class_vtab_final_get (se->expr);
6911 	  is_final = fold_build2_loc (input_location, NE_EXPR,
6912 				      logical_type_node,
6913 				      final_fndecl,
6914 				      fold_convert (TREE_TYPE (final_fndecl),
6915 					   	    null_pointer_node));
6916 	  final_fndecl = build_fold_indirect_ref_loc (input_location,
6917 						      final_fndecl);
6918  	  tmp = build_call_expr_loc (input_location,
6919 				     final_fndecl, 3,
6920 				     gfc_build_addr_expr (NULL, tmp),
6921 				     gfc_class_vtab_size_get (se->expr),
6922 				     boolean_false_node);
6923 	  tmp = fold_build3_loc (input_location, COND_EXPR,
6924 				 void_type_node, is_final, tmp,
6925 				 build_empty_stmt (input_location));
6926 
6927 	  if (se->ss && se->ss->loop)
6928 	    {
6929 	      gfc_prepend_expr_to_block (&se->ss->loop->post, tmp);
6930 	      tmp = fold_build2_loc (input_location, NE_EXPR,
6931 				     logical_type_node,
6932 				     info->data,
6933 				     fold_convert (TREE_TYPE (info->data),
6934 					   	    null_pointer_node));
6935 	      tmp = fold_build3_loc (input_location, COND_EXPR,
6936 				     void_type_node, tmp,
6937 				     gfc_call_free (info->data),
6938 				     build_empty_stmt (input_location));
6939 	      gfc_add_expr_to_block (&se->ss->loop->post, tmp);
6940 	    }
6941 	  else
6942 	    {
6943 	      tree classdata;
6944 	      gfc_prepend_expr_to_block (&se->post, tmp);
6945 	      classdata = gfc_class_data_get (se->expr);
6946 	      tmp = fold_build2_loc (input_location, NE_EXPR,
6947 				     logical_type_node,
6948 				     classdata,
6949 				     fold_convert (TREE_TYPE (classdata),
6950 					   	    null_pointer_node));
6951 	      tmp = fold_build3_loc (input_location, COND_EXPR,
6952 				     void_type_node, tmp,
6953 				     gfc_call_free (classdata),
6954 				     build_empty_stmt (input_location));
6955 	      gfc_add_expr_to_block (&se->post, tmp);
6956 	    }
6957 	}
6958 
6959 no_finalization:
6960       gfc_add_block_to_block (&se->post, &post);
6961     }
6962 
6963   return has_alternate_specifier;
6964 }
6965 
6966 
6967 /* Fill a character string with spaces.  */
6968 
6969 static tree
6970 fill_with_spaces (tree start, tree type, tree size)
6971 {
6972   stmtblock_t block, loop;
6973   tree i, el, exit_label, cond, tmp;
6974 
6975   /* For a simple char type, we can call memset().  */
6976   if (compare_tree_int (TYPE_SIZE_UNIT (type), 1) == 0)
6977     return build_call_expr_loc (input_location,
6978 			    builtin_decl_explicit (BUILT_IN_MEMSET),
6979 			    3, start,
6980 			    build_int_cst (gfc_get_int_type (gfc_c_int_kind),
6981 					   lang_hooks.to_target_charset (' ')),
6982 				fold_convert (size_type_node, size));
6983 
6984   /* Otherwise, we use a loop:
6985 	for (el = start, i = size; i > 0; el--, i+= TYPE_SIZE_UNIT (type))
6986 	  *el = (type) ' ';
6987    */
6988 
6989   /* Initialize variables.  */
6990   gfc_init_block (&block);
6991   i = gfc_create_var (sizetype, "i");
6992   gfc_add_modify (&block, i, fold_convert (sizetype, size));
6993   el = gfc_create_var (build_pointer_type (type), "el");
6994   gfc_add_modify (&block, el, fold_convert (TREE_TYPE (el), start));
6995   exit_label = gfc_build_label_decl (NULL_TREE);
6996   TREE_USED (exit_label) = 1;
6997 
6998 
6999   /* Loop body.  */
7000   gfc_init_block (&loop);
7001 
7002   /* Exit condition.  */
7003   cond = fold_build2_loc (input_location, LE_EXPR, logical_type_node, i,
7004 			  build_zero_cst (sizetype));
7005   tmp = build1_v (GOTO_EXPR, exit_label);
7006   tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond, tmp,
7007 			 build_empty_stmt (input_location));
7008   gfc_add_expr_to_block (&loop, tmp);
7009 
7010   /* Assignment.  */
7011   gfc_add_modify (&loop,
7012 		  fold_build1_loc (input_location, INDIRECT_REF, type, el),
7013 		  build_int_cst (type, lang_hooks.to_target_charset (' ')));
7014 
7015   /* Increment loop variables.  */
7016   gfc_add_modify (&loop, i,
7017 		  fold_build2_loc (input_location, MINUS_EXPR, sizetype, i,
7018 				   TYPE_SIZE_UNIT (type)));
7019   gfc_add_modify (&loop, el,
7020 		  fold_build_pointer_plus_loc (input_location,
7021 					       el, TYPE_SIZE_UNIT (type)));
7022 
7023   /* Making the loop... actually loop!  */
7024   tmp = gfc_finish_block (&loop);
7025   tmp = build1_v (LOOP_EXPR, tmp);
7026   gfc_add_expr_to_block (&block, tmp);
7027 
7028   /* The exit label.  */
7029   tmp = build1_v (LABEL_EXPR, exit_label);
7030   gfc_add_expr_to_block (&block, tmp);
7031 
7032 
7033   return gfc_finish_block (&block);
7034 }
7035 
7036 
7037 /* Generate code to copy a string.  */
7038 
7039 void
7040 gfc_trans_string_copy (stmtblock_t * block, tree dlength, tree dest,
7041 		       int dkind, tree slength, tree src, int skind)
7042 {
7043   tree tmp, dlen, slen;
7044   tree dsc;
7045   tree ssc;
7046   tree cond;
7047   tree cond2;
7048   tree tmp2;
7049   tree tmp3;
7050   tree tmp4;
7051   tree chartype;
7052   stmtblock_t tempblock;
7053 
7054   gcc_assert (dkind == skind);
7055 
7056   if (slength != NULL_TREE)
7057     {
7058       slen = gfc_evaluate_now (fold_convert (gfc_charlen_type_node, slength), block);
7059       ssc = gfc_string_to_single_character (slen, src, skind);
7060     }
7061   else
7062     {
7063       slen = build_one_cst (gfc_charlen_type_node);
7064       ssc =  src;
7065     }
7066 
7067   if (dlength != NULL_TREE)
7068     {
7069       dlen = gfc_evaluate_now (fold_convert (gfc_charlen_type_node, dlength), block);
7070       dsc = gfc_string_to_single_character (dlen, dest, dkind);
7071     }
7072   else
7073     {
7074       dlen = build_one_cst (gfc_charlen_type_node);
7075       dsc =  dest;
7076     }
7077 
7078   /* Assign directly if the types are compatible.  */
7079   if (dsc != NULL_TREE && ssc != NULL_TREE
7080       && TREE_TYPE (dsc) == TREE_TYPE (ssc))
7081     {
7082       gfc_add_modify (block, dsc, ssc);
7083       return;
7084     }
7085 
7086   /* The string copy algorithm below generates code like
7087 
7088      if (destlen > 0)
7089        {
7090          if (srclen < destlen)
7091            {
7092              memmove (dest, src, srclen);
7093              // Pad with spaces.
7094              memset (&dest[srclen], ' ', destlen - srclen);
7095            }
7096          else
7097            {
7098              // Truncate if too long.
7099              memmove (dest, src, destlen);
7100            }
7101        }
7102   */
7103 
7104   /* Do nothing if the destination length is zero.  */
7105   cond = fold_build2_loc (input_location, GT_EXPR, logical_type_node, dlen,
7106 			  build_zero_cst (TREE_TYPE (dlen)));
7107 
7108   /* For non-default character kinds, we have to multiply the string
7109      length by the base type size.  */
7110   chartype = gfc_get_char_type (dkind);
7111   slen = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (slen),
7112 			  slen,
7113 			  fold_convert (TREE_TYPE (slen),
7114 					TYPE_SIZE_UNIT (chartype)));
7115   dlen = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (dlen),
7116 			  dlen,
7117 			  fold_convert (TREE_TYPE (dlen),
7118 					TYPE_SIZE_UNIT (chartype)));
7119 
7120   if (dlength && POINTER_TYPE_P (TREE_TYPE (dest)))
7121     dest = fold_convert (pvoid_type_node, dest);
7122   else
7123     dest = gfc_build_addr_expr (pvoid_type_node, dest);
7124 
7125   if (slength && POINTER_TYPE_P (TREE_TYPE (src)))
7126     src = fold_convert (pvoid_type_node, src);
7127   else
7128     src = gfc_build_addr_expr (pvoid_type_node, src);
7129 
7130   /* Truncate string if source is too long.  */
7131   cond2 = fold_build2_loc (input_location, LT_EXPR, logical_type_node, slen,
7132 			   dlen);
7133 
7134   /* Copy and pad with spaces.  */
7135   tmp3 = build_call_expr_loc (input_location,
7136 			      builtin_decl_explicit (BUILT_IN_MEMMOVE),
7137 			      3, dest, src,
7138 			      fold_convert (size_type_node, slen));
7139 
7140   /* Wstringop-overflow appears at -O3 even though this warning is not
7141      explicitly available in fortran nor can it be switched off. If the
7142      source length is a constant, its negative appears as a very large
7143      postive number and triggers the warning in BUILTIN_MEMSET. Fixing
7144      the result of the MINUS_EXPR suppresses this spurious warning.  */
7145   tmp = fold_build2_loc (input_location, MINUS_EXPR,
7146 			 TREE_TYPE(dlen), dlen, slen);
7147   if (slength && TREE_CONSTANT (slength))
7148     tmp = gfc_evaluate_now (tmp, block);
7149 
7150   tmp4 = fold_build_pointer_plus_loc (input_location, dest, slen);
7151   tmp4 = fill_with_spaces (tmp4, chartype, tmp);
7152 
7153   gfc_init_block (&tempblock);
7154   gfc_add_expr_to_block (&tempblock, tmp3);
7155   gfc_add_expr_to_block (&tempblock, tmp4);
7156   tmp3 = gfc_finish_block (&tempblock);
7157 
7158   /* The truncated memmove if the slen >= dlen.  */
7159   tmp2 = build_call_expr_loc (input_location,
7160 			      builtin_decl_explicit (BUILT_IN_MEMMOVE),
7161 			      3, dest, src,
7162 			      fold_convert (size_type_node, dlen));
7163 
7164   /* The whole copy_string function is there.  */
7165   tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond2,
7166 			 tmp3, tmp2);
7167   tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond, tmp,
7168 			 build_empty_stmt (input_location));
7169   gfc_add_expr_to_block (block, tmp);
7170 }
7171 
7172 
7173 /* Translate a statement function.
7174    The value of a statement function reference is obtained by evaluating the
7175    expression using the values of the actual arguments for the values of the
7176    corresponding dummy arguments.  */
7177 
7178 static void
7179 gfc_conv_statement_function (gfc_se * se, gfc_expr * expr)
7180 {
7181   gfc_symbol *sym;
7182   gfc_symbol *fsym;
7183   gfc_formal_arglist *fargs;
7184   gfc_actual_arglist *args;
7185   gfc_se lse;
7186   gfc_se rse;
7187   gfc_saved_var *saved_vars;
7188   tree *temp_vars;
7189   tree type;
7190   tree tmp;
7191   int n;
7192 
7193   sym = expr->symtree->n.sym;
7194   args = expr->value.function.actual;
7195   gfc_init_se (&lse, NULL);
7196   gfc_init_se (&rse, NULL);
7197 
7198   n = 0;
7199   for (fargs = gfc_sym_get_dummy_args (sym); fargs; fargs = fargs->next)
7200     n++;
7201   saved_vars = XCNEWVEC (gfc_saved_var, n);
7202   temp_vars = XCNEWVEC (tree, n);
7203 
7204   for (fargs = gfc_sym_get_dummy_args (sym), n = 0; fargs;
7205        fargs = fargs->next, n++)
7206     {
7207       /* Each dummy shall be specified, explicitly or implicitly, to be
7208          scalar.  */
7209       gcc_assert (fargs->sym->attr.dimension == 0);
7210       fsym = fargs->sym;
7211 
7212       if (fsym->ts.type == BT_CHARACTER)
7213         {
7214 	  /* Copy string arguments.  */
7215 	  tree arglen;
7216 
7217 	  gcc_assert (fsym->ts.u.cl && fsym->ts.u.cl->length
7218 		      && fsym->ts.u.cl->length->expr_type == EXPR_CONSTANT);
7219 
7220 	  /* Create a temporary to hold the value.  */
7221           if (fsym->ts.u.cl->backend_decl == NULL_TREE)
7222 	     fsym->ts.u.cl->backend_decl
7223 		= gfc_conv_constant_to_tree (fsym->ts.u.cl->length);
7224 
7225 	  type = gfc_get_character_type (fsym->ts.kind, fsym->ts.u.cl);
7226 	  temp_vars[n] = gfc_create_var (type, fsym->name);
7227 
7228 	  arglen = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
7229 
7230 	  gfc_conv_expr (&rse, args->expr);
7231 	  gfc_conv_string_parameter (&rse);
7232 	  gfc_add_block_to_block (&se->pre, &lse.pre);
7233 	  gfc_add_block_to_block (&se->pre, &rse.pre);
7234 
7235 	  gfc_trans_string_copy (&se->pre, arglen, temp_vars[n], fsym->ts.kind,
7236 				 rse.string_length, rse.expr, fsym->ts.kind);
7237 	  gfc_add_block_to_block (&se->pre, &lse.post);
7238 	  gfc_add_block_to_block (&se->pre, &rse.post);
7239         }
7240       else
7241         {
7242           /* For everything else, just evaluate the expression.  */
7243 
7244 	  /* Create a temporary to hold the value.  */
7245 	  type = gfc_typenode_for_spec (&fsym->ts);
7246 	  temp_vars[n] = gfc_create_var (type, fsym->name);
7247 
7248           gfc_conv_expr (&lse, args->expr);
7249 
7250           gfc_add_block_to_block (&se->pre, &lse.pre);
7251           gfc_add_modify (&se->pre, temp_vars[n], lse.expr);
7252           gfc_add_block_to_block (&se->pre, &lse.post);
7253         }
7254 
7255       args = args->next;
7256     }
7257 
7258   /* Use the temporary variables in place of the real ones.  */
7259   for (fargs = gfc_sym_get_dummy_args (sym), n = 0; fargs;
7260        fargs = fargs->next, n++)
7261     gfc_shadow_sym (fargs->sym, temp_vars[n], &saved_vars[n]);
7262 
7263   gfc_conv_expr (se, sym->value);
7264 
7265   if (sym->ts.type == BT_CHARACTER)
7266     {
7267       gfc_conv_const_charlen (sym->ts.u.cl);
7268 
7269       /* Force the expression to the correct length.  */
7270       if (!INTEGER_CST_P (se->string_length)
7271 	  || tree_int_cst_lt (se->string_length,
7272 			      sym->ts.u.cl->backend_decl))
7273 	{
7274 	  type = gfc_get_character_type (sym->ts.kind, sym->ts.u.cl);
7275 	  tmp = gfc_create_var (type, sym->name);
7276 	  tmp = gfc_build_addr_expr (build_pointer_type (type), tmp);
7277 	  gfc_trans_string_copy (&se->pre, sym->ts.u.cl->backend_decl, tmp,
7278 				 sym->ts.kind, se->string_length, se->expr,
7279 				 sym->ts.kind);
7280 	  se->expr = tmp;
7281 	}
7282       se->string_length = sym->ts.u.cl->backend_decl;
7283     }
7284 
7285   /* Restore the original variables.  */
7286   for (fargs = gfc_sym_get_dummy_args (sym), n = 0; fargs;
7287        fargs = fargs->next, n++)
7288     gfc_restore_sym (fargs->sym, &saved_vars[n]);
7289   free (temp_vars);
7290   free (saved_vars);
7291 }
7292 
7293 
7294 /* Translate a function expression.  */
7295 
7296 static void
7297 gfc_conv_function_expr (gfc_se * se, gfc_expr * expr)
7298 {
7299   gfc_symbol *sym;
7300 
7301   if (expr->value.function.isym)
7302     {
7303       gfc_conv_intrinsic_function (se, expr);
7304       return;
7305     }
7306 
7307   /* expr.value.function.esym is the resolved (specific) function symbol for
7308      most functions.  However this isn't set for dummy procedures.  */
7309   sym = expr->value.function.esym;
7310   if (!sym)
7311     sym = expr->symtree->n.sym;
7312 
7313   /* The IEEE_ARITHMETIC functions are caught here. */
7314   if (sym->from_intmod == INTMOD_IEEE_ARITHMETIC)
7315     if (gfc_conv_ieee_arithmetic_function (se, expr))
7316       return;
7317 
7318   /* We distinguish statement functions from general functions to improve
7319      runtime performance.  */
7320   if (sym->attr.proc == PROC_ST_FUNCTION)
7321     {
7322       gfc_conv_statement_function (se, expr);
7323       return;
7324     }
7325 
7326   gfc_conv_procedure_call (se, sym, expr->value.function.actual, expr,
7327 			   NULL);
7328 }
7329 
7330 
7331 /* Determine whether the given EXPR_CONSTANT is a zero initializer.  */
7332 
7333 static bool
7334 is_zero_initializer_p (gfc_expr * expr)
7335 {
7336   if (expr->expr_type != EXPR_CONSTANT)
7337     return false;
7338 
7339   /* We ignore constants with prescribed memory representations for now.  */
7340   if (expr->representation.string)
7341     return false;
7342 
7343   switch (expr->ts.type)
7344     {
7345     case BT_INTEGER:
7346       return mpz_cmp_si (expr->value.integer, 0) == 0;
7347 
7348     case BT_REAL:
7349       return mpfr_zero_p (expr->value.real)
7350 	     && MPFR_SIGN (expr->value.real) >= 0;
7351 
7352     case BT_LOGICAL:
7353       return expr->value.logical == 0;
7354 
7355     case BT_COMPLEX:
7356       return mpfr_zero_p (mpc_realref (expr->value.complex))
7357 	     && MPFR_SIGN (mpc_realref (expr->value.complex)) >= 0
7358              && mpfr_zero_p (mpc_imagref (expr->value.complex))
7359 	     && MPFR_SIGN (mpc_imagref (expr->value.complex)) >= 0;
7360 
7361     default:
7362       break;
7363     }
7364   return false;
7365 }
7366 
7367 
7368 static void
7369 gfc_conv_array_constructor_expr (gfc_se * se, gfc_expr * expr)
7370 {
7371   gfc_ss *ss;
7372 
7373   ss = se->ss;
7374   gcc_assert (ss != NULL && ss != gfc_ss_terminator);
7375   gcc_assert (ss->info->expr == expr && ss->info->type == GFC_SS_CONSTRUCTOR);
7376 
7377   gfc_conv_tmp_array_ref (se);
7378 }
7379 
7380 
7381 /* Build a static initializer.  EXPR is the expression for the initial value.
7382    The other parameters describe the variable of the component being
7383    initialized. EXPR may be null.  */
7384 
7385 tree
7386 gfc_conv_initializer (gfc_expr * expr, gfc_typespec * ts, tree type,
7387 		      bool array, bool pointer, bool procptr)
7388 {
7389   gfc_se se;
7390 
7391   if (flag_coarray != GFC_FCOARRAY_LIB && ts->type == BT_DERIVED
7392       && ts->u.derived->from_intmod == INTMOD_ISO_FORTRAN_ENV
7393       && ts->u.derived->intmod_sym_id == ISOFORTRAN_EVENT_TYPE)
7394     return build_constructor (type, NULL);
7395 
7396   if (!(expr || pointer || procptr))
7397     return NULL_TREE;
7398 
7399   /* Check if we have ISOCBINDING_NULL_PTR or ISOCBINDING_NULL_FUNPTR
7400      (these are the only two iso_c_binding derived types that can be
7401      used as initialization expressions).  If so, we need to modify
7402      the 'expr' to be that for a (void *).  */
7403   if (expr != NULL && expr->ts.type == BT_DERIVED
7404       && expr->ts.is_iso_c && expr->ts.u.derived)
7405     {
7406       if (TREE_CODE (type) == ARRAY_TYPE)
7407 	return build_constructor (type, NULL);
7408       else if (POINTER_TYPE_P (type))
7409 	return build_int_cst (type, 0);
7410       else
7411 	gcc_unreachable ();
7412     }
7413 
7414   if (array && !procptr)
7415     {
7416       tree ctor;
7417       /* Arrays need special handling.  */
7418       if (pointer)
7419 	ctor = gfc_build_null_descriptor (type);
7420       /* Special case assigning an array to zero.  */
7421       else if (is_zero_initializer_p (expr))
7422         ctor = build_constructor (type, NULL);
7423       else
7424 	ctor = gfc_conv_array_initializer (type, expr);
7425       TREE_STATIC (ctor) = 1;
7426       return ctor;
7427     }
7428   else if (pointer || procptr)
7429     {
7430       if (ts->type == BT_CLASS && !procptr)
7431 	{
7432 	  gfc_init_se (&se, NULL);
7433 	  gfc_conv_structure (&se, gfc_class_initializer (ts, expr), 1);
7434 	  gcc_assert (TREE_CODE (se.expr) == CONSTRUCTOR);
7435 	  TREE_STATIC (se.expr) = 1;
7436 	  return se.expr;
7437 	}
7438       else if (!expr || expr->expr_type == EXPR_NULL)
7439 	return fold_convert (type, null_pointer_node);
7440       else
7441 	{
7442 	  gfc_init_se (&se, NULL);
7443 	  se.want_pointer = 1;
7444 	  gfc_conv_expr (&se, expr);
7445           gcc_assert (TREE_CODE (se.expr) != CONSTRUCTOR);
7446 	  return se.expr;
7447 	}
7448     }
7449   else
7450     {
7451       switch (ts->type)
7452 	{
7453 	case_bt_struct:
7454 	case BT_CLASS:
7455 	  gfc_init_se (&se, NULL);
7456 	  if (ts->type == BT_CLASS && expr->expr_type == EXPR_NULL)
7457 	    gfc_conv_structure (&se, gfc_class_initializer (ts, expr), 1);
7458 	  else
7459 	    gfc_conv_structure (&se, expr, 1);
7460 	  gcc_assert (TREE_CODE (se.expr) == CONSTRUCTOR);
7461 	  TREE_STATIC (se.expr) = 1;
7462 	  return se.expr;
7463 
7464 	case BT_CHARACTER:
7465 	  {
7466 	    tree ctor = gfc_conv_string_init (ts->u.cl->backend_decl,expr);
7467 	    TREE_STATIC (ctor) = 1;
7468 	    return ctor;
7469 	  }
7470 
7471 	default:
7472 	  gfc_init_se (&se, NULL);
7473 	  gfc_conv_constant (&se, expr);
7474 	  gcc_assert (TREE_CODE (se.expr) != CONSTRUCTOR);
7475 	  return se.expr;
7476 	}
7477     }
7478 }
7479 
7480 static tree
7481 gfc_trans_subarray_assign (tree dest, gfc_component * cm, gfc_expr * expr)
7482 {
7483   gfc_se rse;
7484   gfc_se lse;
7485   gfc_ss *rss;
7486   gfc_ss *lss;
7487   gfc_array_info *lss_array;
7488   stmtblock_t body;
7489   stmtblock_t block;
7490   gfc_loopinfo loop;
7491   int n;
7492   tree tmp;
7493 
7494   gfc_start_block (&block);
7495 
7496   /* Initialize the scalarizer.  */
7497   gfc_init_loopinfo (&loop);
7498 
7499   gfc_init_se (&lse, NULL);
7500   gfc_init_se (&rse, NULL);
7501 
7502   /* Walk the rhs.  */
7503   rss = gfc_walk_expr (expr);
7504   if (rss == gfc_ss_terminator)
7505     /* The rhs is scalar.  Add a ss for the expression.  */
7506     rss = gfc_get_scalar_ss (gfc_ss_terminator, expr);
7507 
7508   /* Create a SS for the destination.  */
7509   lss = gfc_get_array_ss (gfc_ss_terminator, NULL, cm->as->rank,
7510 			  GFC_SS_COMPONENT);
7511   lss_array = &lss->info->data.array;
7512   lss_array->shape = gfc_get_shape (cm->as->rank);
7513   lss_array->descriptor = dest;
7514   lss_array->data = gfc_conv_array_data (dest);
7515   lss_array->offset = gfc_conv_array_offset (dest);
7516   for (n = 0; n < cm->as->rank; n++)
7517     {
7518       lss_array->start[n] = gfc_conv_array_lbound (dest, n);
7519       lss_array->stride[n] = gfc_index_one_node;
7520 
7521       mpz_init (lss_array->shape[n]);
7522       mpz_sub (lss_array->shape[n], cm->as->upper[n]->value.integer,
7523 	       cm->as->lower[n]->value.integer);
7524       mpz_add_ui (lss_array->shape[n], lss_array->shape[n], 1);
7525     }
7526 
7527   /* Associate the SS with the loop.  */
7528   gfc_add_ss_to_loop (&loop, lss);
7529   gfc_add_ss_to_loop (&loop, rss);
7530 
7531   /* Calculate the bounds of the scalarization.  */
7532   gfc_conv_ss_startstride (&loop);
7533 
7534   /* Setup the scalarizing loops.  */
7535   gfc_conv_loop_setup (&loop, &expr->where);
7536 
7537   /* Setup the gfc_se structures.  */
7538   gfc_copy_loopinfo_to_se (&lse, &loop);
7539   gfc_copy_loopinfo_to_se (&rse, &loop);
7540 
7541   rse.ss = rss;
7542   gfc_mark_ss_chain_used (rss, 1);
7543   lse.ss = lss;
7544   gfc_mark_ss_chain_used (lss, 1);
7545 
7546   /* Start the scalarized loop body.  */
7547   gfc_start_scalarized_body (&loop, &body);
7548 
7549   gfc_conv_tmp_array_ref (&lse);
7550   if (cm->ts.type == BT_CHARACTER)
7551     lse.string_length = cm->ts.u.cl->backend_decl;
7552 
7553   gfc_conv_expr (&rse, expr);
7554 
7555   tmp = gfc_trans_scalar_assign (&lse, &rse, cm->ts, true, false);
7556   gfc_add_expr_to_block (&body, tmp);
7557 
7558   gcc_assert (rse.ss == gfc_ss_terminator);
7559 
7560   /* Generate the copying loops.  */
7561   gfc_trans_scalarizing_loops (&loop, &body);
7562 
7563   /* Wrap the whole thing up.  */
7564   gfc_add_block_to_block (&block, &loop.pre);
7565   gfc_add_block_to_block (&block, &loop.post);
7566 
7567   gcc_assert (lss_array->shape != NULL);
7568   gfc_free_shape (&lss_array->shape, cm->as->rank);
7569   gfc_cleanup_loop (&loop);
7570 
7571   return gfc_finish_block (&block);
7572 }
7573 
7574 
7575 static tree
7576 gfc_trans_alloc_subarray_assign (tree dest, gfc_component * cm,
7577 				 gfc_expr * expr)
7578 {
7579   gfc_se se;
7580   stmtblock_t block;
7581   tree offset;
7582   int n;
7583   tree tmp;
7584   tree tmp2;
7585   gfc_array_spec *as;
7586   gfc_expr *arg = NULL;
7587 
7588   gfc_start_block (&block);
7589   gfc_init_se (&se, NULL);
7590 
7591   /* Get the descriptor for the expressions.  */
7592   se.want_pointer = 0;
7593   gfc_conv_expr_descriptor (&se, expr);
7594   gfc_add_block_to_block (&block, &se.pre);
7595   gfc_add_modify (&block, dest, se.expr);
7596 
7597   /* Deal with arrays of derived types with allocatable components.  */
7598   if (gfc_bt_struct (cm->ts.type)
7599 	&& cm->ts.u.derived->attr.alloc_comp)
7600     // TODO: Fix caf_mode
7601     tmp = gfc_copy_alloc_comp (cm->ts.u.derived,
7602 			       se.expr, dest,
7603 			       cm->as->rank, 0);
7604   else if (cm->ts.type == BT_CLASS && expr->ts.type == BT_DERIVED
7605 	   && CLASS_DATA(cm)->attr.allocatable)
7606     {
7607       if (cm->ts.u.derived->attr.alloc_comp)
7608 	// TODO: Fix caf_mode
7609 	tmp = gfc_copy_alloc_comp (expr->ts.u.derived,
7610 				   se.expr, dest,
7611 				   expr->rank, 0);
7612       else
7613 	{
7614 	  tmp = TREE_TYPE (dest);
7615 	  tmp = gfc_duplicate_allocatable (dest, se.expr,
7616 					   tmp, expr->rank, NULL_TREE);
7617 	}
7618     }
7619   else
7620     tmp = gfc_duplicate_allocatable (dest, se.expr,
7621 				     TREE_TYPE(cm->backend_decl),
7622 				     cm->as->rank, NULL_TREE);
7623 
7624   gfc_add_expr_to_block (&block, tmp);
7625   gfc_add_block_to_block (&block, &se.post);
7626 
7627   if (expr->expr_type != EXPR_VARIABLE)
7628     gfc_conv_descriptor_data_set (&block, se.expr,
7629 				  null_pointer_node);
7630 
7631   /* We need to know if the argument of a conversion function is a
7632      variable, so that the correct lower bound can be used.  */
7633   if (expr->expr_type == EXPR_FUNCTION
7634 	&& expr->value.function.isym
7635 	&& expr->value.function.isym->conversion
7636 	&& expr->value.function.actual->expr
7637 	&& expr->value.function.actual->expr->expr_type == EXPR_VARIABLE)
7638     arg = expr->value.function.actual->expr;
7639 
7640   /* Obtain the array spec of full array references.  */
7641   if (arg)
7642     as = gfc_get_full_arrayspec_from_expr (arg);
7643   else
7644     as = gfc_get_full_arrayspec_from_expr (expr);
7645 
7646   /* Shift the lbound and ubound of temporaries to being unity,
7647      rather than zero, based. Always calculate the offset.  */
7648   offset = gfc_conv_descriptor_offset_get (dest);
7649   gfc_add_modify (&block, offset, gfc_index_zero_node);
7650   tmp2 =gfc_create_var (gfc_array_index_type, NULL);
7651 
7652   for (n = 0; n < expr->rank; n++)
7653     {
7654       tree span;
7655       tree lbound;
7656 
7657       /* Obtain the correct lbound - ISO/IEC TR 15581:2001 page 9.
7658 	 TODO It looks as if gfc_conv_expr_descriptor should return
7659 	 the correct bounds and that the following should not be
7660 	 necessary.  This would simplify gfc_conv_intrinsic_bound
7661 	 as well.  */
7662       if (as && as->lower[n])
7663 	{
7664 	  gfc_se lbse;
7665 	  gfc_init_se (&lbse, NULL);
7666 	  gfc_conv_expr (&lbse, as->lower[n]);
7667 	  gfc_add_block_to_block (&block, &lbse.pre);
7668 	  lbound = gfc_evaluate_now (lbse.expr, &block);
7669 	}
7670       else if (as && arg)
7671 	{
7672 	  tmp = gfc_get_symbol_decl (arg->symtree->n.sym);
7673 	  lbound = gfc_conv_descriptor_lbound_get (tmp,
7674 					gfc_rank_cst[n]);
7675 	}
7676       else if (as)
7677 	lbound = gfc_conv_descriptor_lbound_get (dest,
7678 						gfc_rank_cst[n]);
7679       else
7680 	lbound = gfc_index_one_node;
7681 
7682       lbound = fold_convert (gfc_array_index_type, lbound);
7683 
7684       /* Shift the bounds and set the offset accordingly.  */
7685       tmp = gfc_conv_descriptor_ubound_get (dest, gfc_rank_cst[n]);
7686       span = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
7687 		tmp, gfc_conv_descriptor_lbound_get (dest, gfc_rank_cst[n]));
7688       tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
7689 			     span, lbound);
7690       gfc_conv_descriptor_ubound_set (&block, dest,
7691 				      gfc_rank_cst[n], tmp);
7692       gfc_conv_descriptor_lbound_set (&block, dest,
7693 				      gfc_rank_cst[n], lbound);
7694 
7695       tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
7696 			 gfc_conv_descriptor_lbound_get (dest,
7697 							 gfc_rank_cst[n]),
7698 			 gfc_conv_descriptor_stride_get (dest,
7699 							 gfc_rank_cst[n]));
7700       gfc_add_modify (&block, tmp2, tmp);
7701       tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
7702 			     offset, tmp2);
7703       gfc_conv_descriptor_offset_set (&block, dest, tmp);
7704     }
7705 
7706   if (arg)
7707     {
7708       /* If a conversion expression has a null data pointer
7709 	 argument, nullify the allocatable component.  */
7710       tree non_null_expr;
7711       tree null_expr;
7712 
7713       if (arg->symtree->n.sym->attr.allocatable
7714 	    || arg->symtree->n.sym->attr.pointer)
7715 	{
7716 	  non_null_expr = gfc_finish_block (&block);
7717 	  gfc_start_block (&block);
7718 	  gfc_conv_descriptor_data_set (&block, dest,
7719 					null_pointer_node);
7720 	  null_expr = gfc_finish_block (&block);
7721 	  tmp = gfc_conv_descriptor_data_get (arg->symtree->n.sym->backend_decl);
7722 	  tmp = build2_loc (input_location, EQ_EXPR, logical_type_node, tmp,
7723 			    fold_convert (TREE_TYPE (tmp), null_pointer_node));
7724 	  return build3_v (COND_EXPR, tmp,
7725 			   null_expr, non_null_expr);
7726 	}
7727     }
7728 
7729   return gfc_finish_block (&block);
7730 }
7731 
7732 
7733 /* Allocate or reallocate scalar component, as necessary.  */
7734 
7735 static void
7736 alloc_scalar_allocatable_for_subcomponent_assignment (stmtblock_t *block,
7737 						      tree comp,
7738 						      gfc_component *cm,
7739 						      gfc_expr *expr2,
7740 						      gfc_symbol *sym)
7741 {
7742   tree tmp;
7743   tree ptr;
7744   tree size;
7745   tree size_in_bytes;
7746   tree lhs_cl_size = NULL_TREE;
7747 
7748   if (!comp)
7749     return;
7750 
7751   if (!expr2 || expr2->rank)
7752     return;
7753 
7754   realloc_lhs_warning (expr2->ts.type, false, &expr2->where);
7755 
7756   if (cm->ts.type == BT_CHARACTER && cm->ts.deferred)
7757     {
7758       char name[GFC_MAX_SYMBOL_LEN+9];
7759       gfc_component *strlen;
7760       /* Use the rhs string length and the lhs element size.  */
7761       gcc_assert (expr2->ts.type == BT_CHARACTER);
7762       if (!expr2->ts.u.cl->backend_decl)
7763 	{
7764 	  gfc_conv_string_length (expr2->ts.u.cl, expr2, block);
7765 	  gcc_assert (expr2->ts.u.cl->backend_decl);
7766 	}
7767 
7768       size = expr2->ts.u.cl->backend_decl;
7769 
7770       /* Ensure that cm->ts.u.cl->backend_decl is a componentref to _%s_length
7771 	 component.  */
7772       sprintf (name, "_%s_length", cm->name);
7773       strlen = gfc_find_component (sym, name, true, true, NULL);
7774       lhs_cl_size = fold_build3_loc (input_location, COMPONENT_REF,
7775 				     gfc_charlen_type_node,
7776 				     TREE_OPERAND (comp, 0),
7777 				     strlen->backend_decl, NULL_TREE);
7778 
7779       tmp = TREE_TYPE (gfc_typenode_for_spec (&cm->ts));
7780       tmp = TYPE_SIZE_UNIT (tmp);
7781       size_in_bytes = fold_build2_loc (input_location, MULT_EXPR,
7782 				       TREE_TYPE (tmp), tmp,
7783 				       fold_convert (TREE_TYPE (tmp), size));
7784     }
7785   else if (cm->ts.type == BT_CLASS)
7786     {
7787       gcc_assert (expr2->ts.type == BT_CLASS || expr2->ts.type == BT_DERIVED);
7788       if (expr2->ts.type == BT_DERIVED)
7789 	{
7790 	  tmp = gfc_get_symbol_decl (expr2->ts.u.derived);
7791 	  size = TYPE_SIZE_UNIT (tmp);
7792 	}
7793       else
7794 	{
7795 	  gfc_expr *e2vtab;
7796 	  gfc_se se;
7797 	  e2vtab = gfc_find_and_cut_at_last_class_ref (expr2);
7798 	  gfc_add_vptr_component (e2vtab);
7799 	  gfc_add_size_component (e2vtab);
7800 	  gfc_init_se (&se, NULL);
7801 	  gfc_conv_expr (&se, e2vtab);
7802 	  gfc_add_block_to_block (block, &se.pre);
7803 	  size = fold_convert (size_type_node, se.expr);
7804 	  gfc_free_expr (e2vtab);
7805 	}
7806       size_in_bytes = size;
7807     }
7808   else
7809     {
7810       /* Otherwise use the length in bytes of the rhs.  */
7811       size = TYPE_SIZE_UNIT (gfc_typenode_for_spec (&cm->ts));
7812       size_in_bytes = size;
7813     }
7814 
7815   size_in_bytes = fold_build2_loc (input_location, MAX_EXPR, size_type_node,
7816 				   size_in_bytes, size_one_node);
7817 
7818   if (cm->ts.type == BT_DERIVED && cm->ts.u.derived->attr.alloc_comp)
7819     {
7820       tmp = build_call_expr_loc (input_location,
7821 				 builtin_decl_explicit (BUILT_IN_CALLOC),
7822 				 2, build_one_cst (size_type_node),
7823 				 size_in_bytes);
7824       tmp = fold_convert (TREE_TYPE (comp), tmp);
7825       gfc_add_modify (block, comp, tmp);
7826     }
7827   else
7828     {
7829       tmp = build_call_expr_loc (input_location,
7830 				 builtin_decl_explicit (BUILT_IN_MALLOC),
7831 				 1, size_in_bytes);
7832       if (GFC_CLASS_TYPE_P (TREE_TYPE (comp)))
7833 	ptr = gfc_class_data_get (comp);
7834       else
7835 	ptr = comp;
7836       tmp = fold_convert (TREE_TYPE (ptr), tmp);
7837       gfc_add_modify (block, ptr, tmp);
7838     }
7839 
7840   if (cm->ts.type == BT_CHARACTER && cm->ts.deferred)
7841     /* Update the lhs character length.  */
7842     gfc_add_modify (block, lhs_cl_size,
7843 		    fold_convert (TREE_TYPE (lhs_cl_size), size));
7844 }
7845 
7846 
7847 /* Assign a single component of a derived type constructor.  */
7848 
7849 static tree
7850 gfc_trans_subcomponent_assign (tree dest, gfc_component * cm, gfc_expr * expr,
7851 			       gfc_symbol *sym, bool init)
7852 {
7853   gfc_se se;
7854   gfc_se lse;
7855   stmtblock_t block;
7856   tree tmp;
7857   tree vtab;
7858 
7859   gfc_start_block (&block);
7860 
7861   if (cm->attr.pointer || cm->attr.proc_pointer)
7862     {
7863       /* Only care about pointers here, not about allocatables.  */
7864       gfc_init_se (&se, NULL);
7865       /* Pointer component.  */
7866       if ((cm->attr.dimension || cm->attr.codimension)
7867 	  && !cm->attr.proc_pointer)
7868 	{
7869 	  /* Array pointer.  */
7870 	  if (expr->expr_type == EXPR_NULL)
7871 	    gfc_conv_descriptor_data_set (&block, dest, null_pointer_node);
7872 	  else
7873 	    {
7874 	      se.direct_byref = 1;
7875 	      se.expr = dest;
7876 	      gfc_conv_expr_descriptor (&se, expr);
7877 	      gfc_add_block_to_block (&block, &se.pre);
7878 	      gfc_add_block_to_block (&block, &se.post);
7879 	    }
7880 	}
7881       else
7882 	{
7883 	  /* Scalar pointers.  */
7884 	  se.want_pointer = 1;
7885 	  gfc_conv_expr (&se, expr);
7886 	  gfc_add_block_to_block (&block, &se.pre);
7887 
7888 	  if (expr->symtree && expr->symtree->n.sym->attr.proc_pointer
7889 	      && expr->symtree->n.sym->attr.dummy)
7890 	    se.expr = build_fold_indirect_ref_loc (input_location, se.expr);
7891 
7892 	  gfc_add_modify (&block, dest,
7893 			       fold_convert (TREE_TYPE (dest), se.expr));
7894 	  gfc_add_block_to_block (&block, &se.post);
7895 	}
7896     }
7897   else if (cm->ts.type == BT_CLASS && expr->expr_type == EXPR_NULL)
7898     {
7899       /* NULL initialization for CLASS components.  */
7900       tmp = gfc_trans_structure_assign (dest,
7901 					gfc_class_initializer (&cm->ts, expr),
7902 					false);
7903       gfc_add_expr_to_block (&block, tmp);
7904     }
7905   else if ((cm->attr.dimension || cm->attr.codimension)
7906 	   && !cm->attr.proc_pointer)
7907     {
7908       if (cm->attr.allocatable && expr->expr_type == EXPR_NULL)
7909  	gfc_conv_descriptor_data_set (&block, dest, null_pointer_node);
7910       else if (cm->attr.allocatable || cm->attr.pdt_array)
7911 	{
7912 	  tmp = gfc_trans_alloc_subarray_assign (dest, cm, expr);
7913 	  gfc_add_expr_to_block (&block, tmp);
7914 	}
7915       else
7916 	{
7917 	  tmp = gfc_trans_subarray_assign (dest, cm, expr);
7918 	  gfc_add_expr_to_block (&block, tmp);
7919 	}
7920     }
7921   else if (cm->ts.type == BT_CLASS
7922 	   && CLASS_DATA (cm)->attr.dimension
7923 	   && CLASS_DATA (cm)->attr.allocatable
7924 	   && expr->ts.type == BT_DERIVED)
7925     {
7926       vtab = gfc_get_symbol_decl (gfc_find_vtab (&expr->ts));
7927       vtab = gfc_build_addr_expr (NULL_TREE, vtab);
7928       tmp = gfc_class_vptr_get (dest);
7929       gfc_add_modify (&block, tmp,
7930 		      fold_convert (TREE_TYPE (tmp), vtab));
7931       tmp = gfc_class_data_get (dest);
7932       tmp = gfc_trans_alloc_subarray_assign (tmp, cm, expr);
7933       gfc_add_expr_to_block (&block, tmp);
7934     }
7935   else if (init && cm->attr.allocatable && expr->expr_type == EXPR_NULL)
7936     {
7937       /* NULL initialization for allocatable components.  */
7938       gfc_add_modify (&block, dest, fold_convert (TREE_TYPE (dest),
7939 						  null_pointer_node));
7940     }
7941   else if (init && (cm->attr.allocatable
7942 	   || (cm->ts.type == BT_CLASS && CLASS_DATA (cm)->attr.allocatable
7943 	       && expr->ts.type != BT_CLASS)))
7944     {
7945       /* Take care about non-array allocatable components here.  The alloc_*
7946 	 routine below is motivated by the alloc_scalar_allocatable_for_
7947 	 assignment() routine, but with the realloc portions removed and
7948 	 different input.  */
7949       alloc_scalar_allocatable_for_subcomponent_assignment (&block,
7950 							    dest,
7951 							    cm,
7952 							    expr,
7953 							    sym);
7954       /* The remainder of these instructions follow the if (cm->attr.pointer)
7955 	 if (!cm->attr.dimension) part above.  */
7956       gfc_init_se (&se, NULL);
7957       gfc_conv_expr (&se, expr);
7958       gfc_add_block_to_block (&block, &se.pre);
7959 
7960       if (expr->symtree && expr->symtree->n.sym->attr.proc_pointer
7961 	  && expr->symtree->n.sym->attr.dummy)
7962 	se.expr = build_fold_indirect_ref_loc (input_location, se.expr);
7963 
7964       if (cm->ts.type == BT_CLASS && expr->ts.type == BT_DERIVED)
7965 	{
7966 	  tmp = gfc_class_data_get (dest);
7967 	  tmp = build_fold_indirect_ref_loc (input_location, tmp);
7968 	  vtab = gfc_get_symbol_decl (gfc_find_vtab (&expr->ts));
7969 	  vtab = gfc_build_addr_expr (NULL_TREE, vtab);
7970 	  gfc_add_modify (&block, gfc_class_vptr_get (dest),
7971 		 fold_convert (TREE_TYPE (gfc_class_vptr_get (dest)), vtab));
7972 	}
7973       else
7974 	tmp = build_fold_indirect_ref_loc (input_location, dest);
7975 
7976       /* For deferred strings insert a memcpy.  */
7977       if (cm->ts.type == BT_CHARACTER && cm->ts.deferred)
7978 	{
7979 	  tree size;
7980 	  gcc_assert (se.string_length || expr->ts.u.cl->backend_decl);
7981 	  size = size_of_string_in_bytes (cm->ts.kind, se.string_length
7982 						? se.string_length
7983 						: expr->ts.u.cl->backend_decl);
7984 	  tmp = gfc_build_memcpy_call (tmp, se.expr, size);
7985 	  gfc_add_expr_to_block (&block, tmp);
7986 	}
7987       else
7988 	gfc_add_modify (&block, tmp,
7989 			fold_convert (TREE_TYPE (tmp), se.expr));
7990       gfc_add_block_to_block (&block, &se.post);
7991     }
7992   else if (expr->ts.type == BT_UNION)
7993     {
7994       tree tmp;
7995       gfc_constructor *c = gfc_constructor_first (expr->value.constructor);
7996       /* We mark that the entire union should be initialized with a contrived
7997          EXPR_NULL expression at the beginning.  */
7998       if (c != NULL && c->n.component == NULL
7999 	  && c->expr != NULL && c->expr->expr_type == EXPR_NULL)
8000         {
8001           tmp = build2_loc (input_location, MODIFY_EXPR, void_type_node,
8002 		            dest, build_constructor (TREE_TYPE (dest), NULL));
8003 	  gfc_add_expr_to_block (&block, tmp);
8004           c = gfc_constructor_next (c);
8005         }
8006       /* The following constructor expression, if any, represents a specific
8007          map intializer, as given by the user.  */
8008       if (c != NULL && c->expr != NULL)
8009         {
8010           gcc_assert (expr->expr_type == EXPR_STRUCTURE);
8011 	  tmp = gfc_trans_structure_assign (dest, expr, expr->symtree != NULL);
8012 	  gfc_add_expr_to_block (&block, tmp);
8013         }
8014     }
8015   else if (expr->ts.type == BT_DERIVED && expr->ts.f90_type != BT_VOID)
8016     {
8017       if (expr->expr_type != EXPR_STRUCTURE)
8018 	{
8019 	  tree dealloc = NULL_TREE;
8020 	  gfc_init_se (&se, NULL);
8021 	  gfc_conv_expr (&se, expr);
8022 	  gfc_add_block_to_block (&block, &se.pre);
8023 	  /* Prevent repeat evaluations in gfc_copy_alloc_comp by fixing the
8024 	     expression in  a temporary variable and deallocate the allocatable
8025 	     components. Then we can the copy the expression to the result.  */
8026 	  if (cm->ts.u.derived->attr.alloc_comp
8027 	      && expr->expr_type != EXPR_VARIABLE)
8028 	    {
8029 	      se.expr = gfc_evaluate_now (se.expr, &block);
8030 	      dealloc = gfc_deallocate_alloc_comp (cm->ts.u.derived, se.expr,
8031 						   expr->rank);
8032 	    }
8033 	  gfc_add_modify (&block, dest,
8034 			  fold_convert (TREE_TYPE (dest), se.expr));
8035 	  if (cm->ts.u.derived->attr.alloc_comp
8036 	      && expr->expr_type != EXPR_NULL)
8037 	    {
8038 	      // TODO: Fix caf_mode
8039 	      tmp = gfc_copy_alloc_comp (cm->ts.u.derived, se.expr,
8040 					 dest, expr->rank, 0);
8041 	      gfc_add_expr_to_block (&block, tmp);
8042 	      if (dealloc != NULL_TREE)
8043 		gfc_add_expr_to_block (&block, dealloc);
8044 	    }
8045 	  gfc_add_block_to_block (&block, &se.post);
8046 	}
8047       else
8048 	{
8049 	  /* Nested constructors.  */
8050 	  tmp = gfc_trans_structure_assign (dest, expr, expr->symtree != NULL);
8051 	  gfc_add_expr_to_block (&block, tmp);
8052 	}
8053     }
8054   else if (gfc_deferred_strlen (cm, &tmp))
8055     {
8056       tree strlen;
8057       strlen = tmp;
8058       gcc_assert (strlen);
8059       strlen = fold_build3_loc (input_location, COMPONENT_REF,
8060 				TREE_TYPE (strlen),
8061 				TREE_OPERAND (dest, 0),
8062 				strlen, NULL_TREE);
8063 
8064       if (expr->expr_type == EXPR_NULL)
8065 	{
8066 	  tmp = build_int_cst (TREE_TYPE (cm->backend_decl), 0);
8067 	  gfc_add_modify (&block, dest, tmp);
8068 	  tmp = build_int_cst (TREE_TYPE (strlen), 0);
8069 	  gfc_add_modify (&block, strlen, tmp);
8070 	}
8071       else
8072 	{
8073 	  tree size;
8074 	  gfc_init_se (&se, NULL);
8075 	  gfc_conv_expr (&se, expr);
8076 	  size = size_of_string_in_bytes (cm->ts.kind, se.string_length);
8077 	  tmp = build_call_expr_loc (input_location,
8078 				     builtin_decl_explicit (BUILT_IN_MALLOC),
8079 				     1, size);
8080 	  gfc_add_modify (&block, dest,
8081 			  fold_convert (TREE_TYPE (dest), tmp));
8082 	  gfc_add_modify (&block, strlen,
8083 			  fold_convert (TREE_TYPE (strlen), se.string_length));
8084 	  tmp = gfc_build_memcpy_call (dest, se.expr, size);
8085 	  gfc_add_expr_to_block (&block, tmp);
8086 	}
8087     }
8088   else if (!cm->attr.artificial)
8089     {
8090       /* Scalar component (excluding deferred parameters).  */
8091       gfc_init_se (&se, NULL);
8092       gfc_init_se (&lse, NULL);
8093 
8094       gfc_conv_expr (&se, expr);
8095       if (cm->ts.type == BT_CHARACTER)
8096 	lse.string_length = cm->ts.u.cl->backend_decl;
8097       lse.expr = dest;
8098       tmp = gfc_trans_scalar_assign (&lse, &se, cm->ts, false, false);
8099       gfc_add_expr_to_block (&block, tmp);
8100     }
8101   return gfc_finish_block (&block);
8102 }
8103 
8104 /* Assign a derived type constructor to a variable.  */
8105 
8106 tree
8107 gfc_trans_structure_assign (tree dest, gfc_expr * expr, bool init, bool coarray)
8108 {
8109   gfc_constructor *c;
8110   gfc_component *cm;
8111   stmtblock_t block;
8112   tree field;
8113   tree tmp;
8114   gfc_se se;
8115 
8116   gfc_start_block (&block);
8117   cm = expr->ts.u.derived->components;
8118 
8119   if (expr->ts.u.derived->from_intmod == INTMOD_ISO_C_BINDING
8120       && (expr->ts.u.derived->intmod_sym_id == ISOCBINDING_PTR
8121           || expr->ts.u.derived->intmod_sym_id == ISOCBINDING_FUNPTR))
8122     {
8123       gfc_se lse;
8124 
8125       gfc_init_se (&se, NULL);
8126       gfc_init_se (&lse, NULL);
8127       gfc_conv_expr (&se, gfc_constructor_first (expr->value.constructor)->expr);
8128       lse.expr = dest;
8129       gfc_add_modify (&block, lse.expr,
8130 		      fold_convert (TREE_TYPE (lse.expr), se.expr));
8131 
8132       return gfc_finish_block (&block);
8133     }
8134 
8135   if (coarray)
8136     gfc_init_se (&se, NULL);
8137 
8138   for (c = gfc_constructor_first (expr->value.constructor);
8139        c; c = gfc_constructor_next (c), cm = cm->next)
8140     {
8141       /* Skip absent members in default initializers.  */
8142       if (!c->expr && !cm->attr.allocatable)
8143 	continue;
8144 
8145       /* Register the component with the caf-lib before it is initialized.
8146 	 Register only allocatable components, that are not coarray'ed
8147 	 components (%comp[*]).  Only register when the constructor is not the
8148 	 null-expression.  */
8149       if (coarray && !cm->attr.codimension
8150 	  && (cm->attr.allocatable || cm->attr.pointer)
8151 	  && (!c->expr || c->expr->expr_type == EXPR_NULL))
8152 	{
8153 	  tree token, desc, size;
8154 	  bool is_array = cm->ts.type == BT_CLASS
8155 	      ? CLASS_DATA (cm)->attr.dimension : cm->attr.dimension;
8156 
8157 	  field = cm->backend_decl;
8158 	  field = fold_build3_loc (input_location, COMPONENT_REF,
8159 				   TREE_TYPE (field), dest, field, NULL_TREE);
8160 	  if (cm->ts.type == BT_CLASS)
8161 	    field = gfc_class_data_get (field);
8162 
8163 	  token = is_array ? gfc_conv_descriptor_token (field)
8164 			   : fold_build3_loc (input_location, COMPONENT_REF,
8165 					      TREE_TYPE (cm->caf_token), dest,
8166 					      cm->caf_token, NULL_TREE);
8167 
8168 	  if (is_array)
8169 	    {
8170 	      /* The _caf_register routine looks at the rank of the array
8171 		 descriptor to decide whether the data registered is an array
8172 		 or not.  */
8173 	      int rank = cm->ts.type == BT_CLASS ? CLASS_DATA (cm)->as->rank
8174 						 : cm->as->rank;
8175 	      /* When the rank is not known just set a positive rank, which
8176 		 suffices to recognize the data as array.  */
8177 	      if (rank < 0)
8178 		rank = 1;
8179 	      size = build_zero_cst (size_type_node);
8180 	      desc = field;
8181 	      gfc_add_modify (&block, gfc_conv_descriptor_rank (desc),
8182 			      build_int_cst (signed_char_type_node, rank));
8183 	    }
8184 	  else
8185 	    {
8186 	      desc = gfc_conv_scalar_to_descriptor (&se, field,
8187 						    cm->ts.type == BT_CLASS
8188 						    ? CLASS_DATA (cm)->attr
8189 						    : cm->attr);
8190 	      size = TYPE_SIZE_UNIT (TREE_TYPE (field));
8191 	    }
8192 	  gfc_add_block_to_block (&block, &se.pre);
8193 	  tmp =  build_call_expr_loc (input_location, gfor_fndecl_caf_register,
8194 				      7, size, build_int_cst (
8195 					integer_type_node,
8196 					GFC_CAF_COARRAY_ALLOC_REGISTER_ONLY),
8197 				      gfc_build_addr_expr (pvoid_type_node,
8198 							   token),
8199 				      gfc_build_addr_expr (NULL_TREE, desc),
8200 				      null_pointer_node, null_pointer_node,
8201 				      integer_zero_node);
8202 	  gfc_add_expr_to_block (&block, tmp);
8203 	}
8204       field = cm->backend_decl;
8205       tmp = fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field),
8206 			     dest, field, NULL_TREE);
8207       if (!c->expr)
8208 	{
8209 	  gfc_expr *e = gfc_get_null_expr (NULL);
8210 	  tmp = gfc_trans_subcomponent_assign (tmp, cm, e, expr->ts.u.derived,
8211 					       init);
8212 	  gfc_free_expr (e);
8213 	}
8214       else
8215         tmp = gfc_trans_subcomponent_assign (tmp, cm, c->expr,
8216                                              expr->ts.u.derived, init);
8217       gfc_add_expr_to_block (&block, tmp);
8218     }
8219   return gfc_finish_block (&block);
8220 }
8221 
8222 void
8223 gfc_conv_union_initializer (vec<constructor_elt, va_gc> *v,
8224                             gfc_component *un, gfc_expr *init)
8225 {
8226   gfc_constructor *ctor;
8227 
8228   if (un->ts.type != BT_UNION || un == NULL || init == NULL)
8229     return;
8230 
8231   ctor = gfc_constructor_first (init->value.constructor);
8232 
8233   if (ctor == NULL || ctor->expr == NULL)
8234     return;
8235 
8236   gcc_assert (init->expr_type == EXPR_STRUCTURE);
8237 
8238   /* If we have an 'initialize all' constructor, do it first.  */
8239   if (ctor->expr->expr_type == EXPR_NULL)
8240     {
8241       tree union_type = TREE_TYPE (un->backend_decl);
8242       tree val = build_constructor (union_type, NULL);
8243       CONSTRUCTOR_APPEND_ELT (v, un->backend_decl, val);
8244       ctor = gfc_constructor_next (ctor);
8245     }
8246 
8247   /* Add the map initializer on top.  */
8248   if (ctor != NULL && ctor->expr != NULL)
8249     {
8250       gcc_assert (ctor->expr->expr_type == EXPR_STRUCTURE);
8251       tree val = gfc_conv_initializer (ctor->expr, &un->ts,
8252                                        TREE_TYPE (un->backend_decl),
8253                                        un->attr.dimension, un->attr.pointer,
8254                                        un->attr.proc_pointer);
8255       CONSTRUCTOR_APPEND_ELT (v, un->backend_decl, val);
8256     }
8257 }
8258 
8259 /* Build an expression for a constructor. If init is nonzero then
8260    this is part of a static variable initializer.  */
8261 
8262 void
8263 gfc_conv_structure (gfc_se * se, gfc_expr * expr, int init)
8264 {
8265   gfc_constructor *c;
8266   gfc_component *cm;
8267   tree val;
8268   tree type;
8269   tree tmp;
8270   vec<constructor_elt, va_gc> *v = NULL;
8271 
8272   gcc_assert (se->ss == NULL);
8273   gcc_assert (expr->expr_type == EXPR_STRUCTURE);
8274   type = gfc_typenode_for_spec (&expr->ts);
8275 
8276   if (!init)
8277     {
8278       /* Create a temporary variable and fill it in.  */
8279       se->expr = gfc_create_var (type, expr->ts.u.derived->name);
8280       /* The symtree in expr is NULL, if the code to generate is for
8281 	 initializing the static members only.  */
8282       tmp = gfc_trans_structure_assign (se->expr, expr, expr->symtree != NULL,
8283 					se->want_coarray);
8284       gfc_add_expr_to_block (&se->pre, tmp);
8285       return;
8286     }
8287 
8288   cm = expr->ts.u.derived->components;
8289 
8290   for (c = gfc_constructor_first (expr->value.constructor);
8291        c; c = gfc_constructor_next (c), cm = cm->next)
8292     {
8293       /* Skip absent members in default initializers and allocatable
8294 	 components.  Although the latter have a default initializer
8295 	 of EXPR_NULL,... by default, the static nullify is not needed
8296 	 since this is done every time we come into scope.  */
8297       if (!c->expr || (cm->attr.allocatable && cm->attr.flavor != FL_PROCEDURE))
8298 	continue;
8299 
8300       if (cm->initializer && cm->initializer->expr_type != EXPR_NULL
8301 	  && strcmp (cm->name, "_extends") == 0
8302 	  && cm->initializer->symtree)
8303 	{
8304 	  tree vtab;
8305 	  gfc_symbol *vtabs;
8306 	  vtabs = cm->initializer->symtree->n.sym;
8307 	  vtab = gfc_build_addr_expr (NULL_TREE, gfc_get_symbol_decl (vtabs));
8308 	  vtab = unshare_expr_without_location (vtab);
8309 	  CONSTRUCTOR_APPEND_ELT (v, cm->backend_decl, vtab);
8310 	}
8311       else if (cm->ts.u.derived && strcmp (cm->name, "_size") == 0)
8312 	{
8313 	  val = TYPE_SIZE_UNIT (gfc_get_derived_type (cm->ts.u.derived));
8314 	  CONSTRUCTOR_APPEND_ELT (v, cm->backend_decl,
8315 				  fold_convert (TREE_TYPE (cm->backend_decl),
8316 						val));
8317 	}
8318       else if (cm->ts.type == BT_INTEGER && strcmp (cm->name, "_len") == 0)
8319 	CONSTRUCTOR_APPEND_ELT (v, cm->backend_decl,
8320 				fold_convert (TREE_TYPE (cm->backend_decl),
8321 					      integer_zero_node));
8322       else if (cm->ts.type == BT_UNION)
8323         gfc_conv_union_initializer (v, cm, c->expr);
8324       else
8325 	{
8326 	  val = gfc_conv_initializer (c->expr, &cm->ts,
8327 				      TREE_TYPE (cm->backend_decl),
8328 				      cm->attr.dimension, cm->attr.pointer,
8329 				      cm->attr.proc_pointer);
8330 	  val = unshare_expr_without_location (val);
8331 
8332 	  /* Append it to the constructor list.  */
8333 	  CONSTRUCTOR_APPEND_ELT (v, cm->backend_decl, val);
8334 	}
8335     }
8336 
8337   se->expr = build_constructor (type, v);
8338   if (init)
8339     TREE_CONSTANT (se->expr) = 1;
8340 }
8341 
8342 
8343 /* Translate a substring expression.  */
8344 
8345 static void
8346 gfc_conv_substring_expr (gfc_se * se, gfc_expr * expr)
8347 {
8348   gfc_ref *ref;
8349 
8350   ref = expr->ref;
8351 
8352   gcc_assert (ref == NULL || ref->type == REF_SUBSTRING);
8353 
8354   se->expr = gfc_build_wide_string_const (expr->ts.kind,
8355 					  expr->value.character.length,
8356 					  expr->value.character.string);
8357 
8358   se->string_length = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (se->expr)));
8359   TYPE_STRING_FLAG (TREE_TYPE (se->expr)) = 1;
8360 
8361   if (ref)
8362     gfc_conv_substring (se, ref, expr->ts.kind, NULL, &expr->where);
8363 }
8364 
8365 
8366 /* Entry point for expression translation.  Evaluates a scalar quantity.
8367    EXPR is the expression to be translated, and SE is the state structure if
8368    called from within the scalarized.  */
8369 
8370 void
8371 gfc_conv_expr (gfc_se * se, gfc_expr * expr)
8372 {
8373   gfc_ss *ss;
8374 
8375   ss = se->ss;
8376   if (ss && ss->info->expr == expr
8377       && (ss->info->type == GFC_SS_SCALAR
8378 	  || ss->info->type == GFC_SS_REFERENCE))
8379     {
8380       gfc_ss_info *ss_info;
8381 
8382       ss_info = ss->info;
8383       /* Substitute a scalar expression evaluated outside the scalarization
8384 	 loop.  */
8385       se->expr = ss_info->data.scalar.value;
8386       if (gfc_scalar_elemental_arg_saved_as_reference (ss_info))
8387 	se->expr = build_fold_indirect_ref_loc (input_location, se->expr);
8388 
8389       se->string_length = ss_info->string_length;
8390       gfc_advance_se_ss_chain (se);
8391       return;
8392     }
8393 
8394   /* We need to convert the expressions for the iso_c_binding derived types.
8395      C_NULL_PTR and C_NULL_FUNPTR will be made EXPR_NULL, which evaluates to
8396      null_pointer_node.  C_PTR and C_FUNPTR are converted to match the
8397      typespec for the C_PTR and C_FUNPTR symbols, which has already been
8398      updated to be an integer with a kind equal to the size of a (void *).  */
8399   if (expr->ts.type == BT_DERIVED && expr->ts.u.derived->ts.f90_type == BT_VOID
8400       && expr->ts.u.derived->attr.is_bind_c)
8401     {
8402       if (expr->expr_type == EXPR_VARIABLE
8403 	  && (expr->symtree->n.sym->intmod_sym_id == ISOCBINDING_NULL_PTR
8404 	      || expr->symtree->n.sym->intmod_sym_id
8405 		 == ISOCBINDING_NULL_FUNPTR))
8406         {
8407 	  /* Set expr_type to EXPR_NULL, which will result in
8408 	     null_pointer_node being used below.  */
8409           expr->expr_type = EXPR_NULL;
8410         }
8411       else
8412         {
8413           /* Update the type/kind of the expression to be what the new
8414              type/kind are for the updated symbols of C_PTR/C_FUNPTR.  */
8415           expr->ts.type = BT_INTEGER;
8416           expr->ts.f90_type = BT_VOID;
8417           expr->ts.kind = gfc_index_integer_kind;
8418         }
8419     }
8420 
8421   gfc_fix_class_refs (expr);
8422 
8423   switch (expr->expr_type)
8424     {
8425     case EXPR_OP:
8426       gfc_conv_expr_op (se, expr);
8427       break;
8428 
8429     case EXPR_FUNCTION:
8430       gfc_conv_function_expr (se, expr);
8431       break;
8432 
8433     case EXPR_CONSTANT:
8434       gfc_conv_constant (se, expr);
8435       break;
8436 
8437     case EXPR_VARIABLE:
8438       gfc_conv_variable (se, expr);
8439       break;
8440 
8441     case EXPR_NULL:
8442       se->expr = null_pointer_node;
8443       break;
8444 
8445     case EXPR_SUBSTRING:
8446       gfc_conv_substring_expr (se, expr);
8447       break;
8448 
8449     case EXPR_STRUCTURE:
8450       gfc_conv_structure (se, expr, 0);
8451       break;
8452 
8453     case EXPR_ARRAY:
8454       gfc_conv_array_constructor_expr (se, expr);
8455       break;
8456 
8457     default:
8458       gcc_unreachable ();
8459       break;
8460     }
8461 }
8462 
8463 /* Like gfc_conv_expr_val, but the value is also suitable for use in the lhs
8464    of an assignment.  */
8465 void
8466 gfc_conv_expr_lhs (gfc_se * se, gfc_expr * expr)
8467 {
8468   gfc_conv_expr (se, expr);
8469   /* All numeric lvalues should have empty post chains.  If not we need to
8470      figure out a way of rewriting an lvalue so that it has no post chain.  */
8471   gcc_assert (expr->ts.type == BT_CHARACTER || !se->post.head);
8472 }
8473 
8474 /* Like gfc_conv_expr, but the POST block is guaranteed to be empty for
8475    numeric expressions.  Used for scalar values where inserting cleanup code
8476    is inconvenient.  */
8477 void
8478 gfc_conv_expr_val (gfc_se * se, gfc_expr * expr)
8479 {
8480   tree val;
8481 
8482   gcc_assert (expr->ts.type != BT_CHARACTER);
8483   gfc_conv_expr (se, expr);
8484   if (se->post.head)
8485     {
8486       val = gfc_create_var (TREE_TYPE (se->expr), NULL);
8487       gfc_add_modify (&se->pre, val, se->expr);
8488       se->expr = val;
8489       gfc_add_block_to_block (&se->pre, &se->post);
8490     }
8491 }
8492 
8493 /* Helper to translate an expression and convert it to a particular type.  */
8494 void
8495 gfc_conv_expr_type (gfc_se * se, gfc_expr * expr, tree type)
8496 {
8497   gfc_conv_expr_val (se, expr);
8498   se->expr = convert (type, se->expr);
8499 }
8500 
8501 
8502 /* Converts an expression so that it can be passed by reference.  Scalar
8503    values only.  */
8504 
8505 void
8506 gfc_conv_expr_reference (gfc_se * se, gfc_expr * expr, bool add_clobber)
8507 {
8508   gfc_ss *ss;
8509   tree var;
8510 
8511   ss = se->ss;
8512   if (ss && ss->info->expr == expr
8513       && ss->info->type == GFC_SS_REFERENCE)
8514     {
8515       /* Returns a reference to the scalar evaluated outside the loop
8516 	 for this case.  */
8517       gfc_conv_expr (se, expr);
8518 
8519       if (expr->ts.type == BT_CHARACTER
8520 	  && expr->expr_type != EXPR_FUNCTION)
8521 	gfc_conv_string_parameter (se);
8522      else
8523 	se->expr = gfc_build_addr_expr (NULL_TREE, se->expr);
8524 
8525       return;
8526     }
8527 
8528   if (expr->ts.type == BT_CHARACTER)
8529     {
8530       gfc_conv_expr (se, expr);
8531       gfc_conv_string_parameter (se);
8532       return;
8533     }
8534 
8535   if (expr->expr_type == EXPR_VARIABLE)
8536     {
8537       se->want_pointer = 1;
8538       gfc_conv_expr (se, expr);
8539       if (se->post.head)
8540 	{
8541 	  var = gfc_create_var (TREE_TYPE (se->expr), NULL);
8542 	  gfc_add_modify (&se->pre, var, se->expr);
8543 	  gfc_add_block_to_block (&se->pre, &se->post);
8544 	  se->expr = var;
8545 	}
8546       else if (add_clobber && expr->ref == NULL)
8547 	{
8548 	  tree clobber;
8549 	  tree var;
8550 	  /* FIXME: This fails if var is passed by reference, see PR
8551 	     41453.  */
8552 	  var = expr->symtree->n.sym->backend_decl;
8553 	  clobber = build_clobber (TREE_TYPE (var));
8554 	  gfc_add_modify (&se->pre, var, clobber);
8555 	}
8556       return;
8557     }
8558 
8559   if (expr->expr_type == EXPR_FUNCTION
8560       && ((expr->value.function.esym
8561 	   && expr->value.function.esym->result->attr.pointer
8562 	   && !expr->value.function.esym->result->attr.dimension)
8563 	  || (!expr->value.function.esym && !expr->ref
8564 	      && expr->symtree->n.sym->attr.pointer
8565 	      && !expr->symtree->n.sym->attr.dimension)))
8566     {
8567       se->want_pointer = 1;
8568       gfc_conv_expr (se, expr);
8569       var = gfc_create_var (TREE_TYPE (se->expr), NULL);
8570       gfc_add_modify (&se->pre, var, se->expr);
8571       se->expr = var;
8572       return;
8573     }
8574 
8575   gfc_conv_expr (se, expr);
8576 
8577   /* Create a temporary var to hold the value.  */
8578   if (TREE_CONSTANT (se->expr))
8579     {
8580       tree tmp = se->expr;
8581       STRIP_TYPE_NOPS (tmp);
8582       var = build_decl (input_location,
8583 			CONST_DECL, NULL, TREE_TYPE (tmp));
8584       DECL_INITIAL (var) = tmp;
8585       TREE_STATIC (var) = 1;
8586       pushdecl (var);
8587     }
8588   else
8589     {
8590       var = gfc_create_var (TREE_TYPE (se->expr), NULL);
8591       gfc_add_modify (&se->pre, var, se->expr);
8592     }
8593 
8594   if (!expr->must_finalize)
8595     gfc_add_block_to_block (&se->pre, &se->post);
8596 
8597   /* Take the address of that value.  */
8598   se->expr = gfc_build_addr_expr (NULL_TREE, var);
8599 }
8600 
8601 
8602 /* Get the _len component for an unlimited polymorphic expression.  */
8603 
8604 static tree
8605 trans_get_upoly_len (stmtblock_t *block, gfc_expr *expr)
8606 {
8607   gfc_se se;
8608   gfc_ref *ref = expr->ref;
8609 
8610   gfc_init_se (&se, NULL);
8611   while (ref && ref->next)
8612     ref = ref->next;
8613   gfc_add_len_component (expr);
8614   gfc_conv_expr (&se, expr);
8615   gfc_add_block_to_block (block, &se.pre);
8616   gcc_assert (se.post.head == NULL_TREE);
8617   if (ref)
8618     {
8619       gfc_free_ref_list (ref->next);
8620       ref->next = NULL;
8621     }
8622   else
8623     {
8624       gfc_free_ref_list (expr->ref);
8625       expr->ref = NULL;
8626     }
8627   return se.expr;
8628 }
8629 
8630 
8631 /* Assign _vptr and _len components as appropriate.  BLOCK should be a
8632    statement-list outside of the scalarizer-loop.  When code is generated, that
8633    depends on the scalarized expression, it is added to RSE.PRE.
8634    Returns le's _vptr tree and when set the len expressions in to_lenp and
8635    from_lenp to form a le%_vptr%_copy (re, le, [from_lenp, to_lenp])
8636    expression.  */
8637 
8638 static tree
8639 trans_class_vptr_len_assignment (stmtblock_t *block, gfc_expr * le,
8640 				 gfc_expr * re, gfc_se *rse,
8641 				 tree * to_lenp, tree * from_lenp)
8642 {
8643   gfc_se se;
8644   gfc_expr * vptr_expr;
8645   tree tmp, to_len = NULL_TREE, from_len = NULL_TREE, lhs_vptr;
8646   bool set_vptr = false, temp_rhs = false;
8647   stmtblock_t *pre = block;
8648 
8649   /* Create a temporary for complicated expressions.  */
8650   if (re->expr_type != EXPR_VARIABLE && re->expr_type != EXPR_NULL
8651       && rse->expr != NULL_TREE && !DECL_P (rse->expr))
8652     {
8653       tmp = gfc_create_var (TREE_TYPE (rse->expr), "rhs");
8654       pre = &rse->pre;
8655       gfc_add_modify (&rse->pre, tmp, rse->expr);
8656       rse->expr = tmp;
8657       temp_rhs = true;
8658     }
8659 
8660   /* Get the _vptr for the left-hand side expression.  */
8661   gfc_init_se (&se, NULL);
8662   vptr_expr = gfc_find_and_cut_at_last_class_ref (le);
8663   if (vptr_expr != NULL && gfc_expr_attr (vptr_expr).class_ok)
8664     {
8665       /* Care about _len for unlimited polymorphic entities.  */
8666       if (UNLIMITED_POLY (vptr_expr)
8667 	  || (vptr_expr->ts.type == BT_DERIVED
8668 	      && vptr_expr->ts.u.derived->attr.unlimited_polymorphic))
8669 	to_len = trans_get_upoly_len (block, vptr_expr);
8670       gfc_add_vptr_component (vptr_expr);
8671       set_vptr = true;
8672     }
8673   else
8674     vptr_expr = gfc_lval_expr_from_sym (gfc_find_vtab (&le->ts));
8675   se.want_pointer = 1;
8676   gfc_conv_expr (&se, vptr_expr);
8677   gfc_free_expr (vptr_expr);
8678   gfc_add_block_to_block (block, &se.pre);
8679   gcc_assert (se.post.head == NULL_TREE);
8680   lhs_vptr = se.expr;
8681   STRIP_NOPS (lhs_vptr);
8682 
8683   /* Set the _vptr only when the left-hand side of the assignment is a
8684      class-object.  */
8685   if (set_vptr)
8686     {
8687       /* Get the vptr from the rhs expression only, when it is variable.
8688 	 Functions are expected to be assigned to a temporary beforehand.  */
8689       vptr_expr = (re->expr_type == EXPR_VARIABLE && re->ts.type == BT_CLASS)
8690 	  ? gfc_find_and_cut_at_last_class_ref (re)
8691 	  : NULL;
8692       if (vptr_expr != NULL && vptr_expr->ts.type == BT_CLASS)
8693 	{
8694 	  if (to_len != NULL_TREE)
8695 	    {
8696 	      /* Get the _len information from the rhs.  */
8697 	      if (UNLIMITED_POLY (vptr_expr)
8698 		  || (vptr_expr->ts.type == BT_DERIVED
8699 		      && vptr_expr->ts.u.derived->attr.unlimited_polymorphic))
8700 		from_len = trans_get_upoly_len (block, vptr_expr);
8701 	    }
8702 	  gfc_add_vptr_component (vptr_expr);
8703 	}
8704       else
8705 	{
8706 	  if (re->expr_type == EXPR_VARIABLE
8707 	      && DECL_P (re->symtree->n.sym->backend_decl)
8708 	      && DECL_LANG_SPECIFIC (re->symtree->n.sym->backend_decl)
8709 	      && GFC_DECL_SAVED_DESCRIPTOR (re->symtree->n.sym->backend_decl)
8710 	      && GFC_CLASS_TYPE_P (TREE_TYPE (GFC_DECL_SAVED_DESCRIPTOR (
8711 					   re->symtree->n.sym->backend_decl))))
8712 	    {
8713 	      vptr_expr = NULL;
8714 	      se.expr = gfc_class_vptr_get (GFC_DECL_SAVED_DESCRIPTOR (
8715 					     re->symtree->n.sym->backend_decl));
8716 	      if (to_len)
8717 		from_len = gfc_class_len_get (GFC_DECL_SAVED_DESCRIPTOR (
8718 					     re->symtree->n.sym->backend_decl));
8719 	    }
8720 	  else if (temp_rhs && re->ts.type == BT_CLASS)
8721 	    {
8722 	      vptr_expr = NULL;
8723 	      se.expr = gfc_class_vptr_get (rse->expr);
8724 	      if (UNLIMITED_POLY (re))
8725 		from_len = gfc_class_len_get (rse->expr);
8726 	    }
8727 	  else if (re->expr_type != EXPR_NULL)
8728 	    /* Only when rhs is non-NULL use its declared type for vptr
8729 	       initialisation.  */
8730 	    vptr_expr = gfc_lval_expr_from_sym (gfc_find_vtab (&re->ts));
8731 	  else
8732 	    /* When the rhs is NULL use the vtab of lhs' declared type.  */
8733 	    vptr_expr = gfc_lval_expr_from_sym (gfc_find_vtab (&le->ts));
8734 	}
8735 
8736       if (vptr_expr)
8737 	{
8738 	  gfc_init_se (&se, NULL);
8739 	  se.want_pointer = 1;
8740 	  gfc_conv_expr (&se, vptr_expr);
8741 	  gfc_free_expr (vptr_expr);
8742 	  gfc_add_block_to_block (block, &se.pre);
8743 	  gcc_assert (se.post.head == NULL_TREE);
8744 	}
8745       gfc_add_modify (pre, lhs_vptr, fold_convert (TREE_TYPE (lhs_vptr),
8746 						se.expr));
8747 
8748       if (to_len != NULL_TREE)
8749 	{
8750 	  /* The _len component needs to be set.  Figure how to get the
8751 	     value of the right-hand side.  */
8752 	  if (from_len == NULL_TREE)
8753 	    {
8754 	      if (rse->string_length != NULL_TREE)
8755 		from_len = rse->string_length;
8756 	      else if (re->ts.type == BT_CHARACTER && re->ts.u.cl->length)
8757 		{
8758 		  from_len = gfc_get_expr_charlen (re);
8759 		  gfc_init_se (&se, NULL);
8760 		  gfc_conv_expr (&se, re->ts.u.cl->length);
8761 		  gfc_add_block_to_block (block, &se.pre);
8762 		  gcc_assert (se.post.head == NULL_TREE);
8763 		  from_len = gfc_evaluate_now (se.expr, block);
8764 		}
8765 	      else
8766 		from_len = build_zero_cst (gfc_charlen_type_node);
8767 	    }
8768 	  gfc_add_modify (pre, to_len, fold_convert (TREE_TYPE (to_len),
8769 						     from_len));
8770 	}
8771     }
8772 
8773   /* Return the _len trees only, when requested.  */
8774   if (to_lenp)
8775     *to_lenp = to_len;
8776   if (from_lenp)
8777     *from_lenp = from_len;
8778   return lhs_vptr;
8779 }
8780 
8781 
8782 /* Assign tokens for pointer components.  */
8783 
8784 static void
8785 trans_caf_token_assign (gfc_se *lse, gfc_se *rse, gfc_expr *expr1,
8786 			gfc_expr *expr2)
8787 {
8788   symbol_attribute lhs_attr, rhs_attr;
8789   tree tmp, lhs_tok, rhs_tok;
8790   /* Flag to indicated component refs on the rhs.  */
8791   bool rhs_cr;
8792 
8793   lhs_attr = gfc_caf_attr (expr1);
8794   if (expr2->expr_type != EXPR_NULL)
8795     {
8796       rhs_attr = gfc_caf_attr (expr2, false, &rhs_cr);
8797       if (lhs_attr.codimension && rhs_attr.codimension)
8798 	{
8799 	  lhs_tok = gfc_get_ultimate_alloc_ptr_comps_caf_token (lse, expr1);
8800 	  lhs_tok = build_fold_indirect_ref (lhs_tok);
8801 
8802 	  if (rhs_cr)
8803 	    rhs_tok = gfc_get_ultimate_alloc_ptr_comps_caf_token (rse, expr2);
8804 	  else
8805 	    {
8806 	      tree caf_decl;
8807 	      caf_decl = gfc_get_tree_for_caf_expr (expr2);
8808 	      gfc_get_caf_token_offset (rse, &rhs_tok, NULL, caf_decl,
8809 					NULL_TREE, NULL);
8810 	    }
8811 	  tmp = build2_loc (input_location, MODIFY_EXPR, void_type_node,
8812 			    lhs_tok,
8813 			    fold_convert (TREE_TYPE (lhs_tok), rhs_tok));
8814 	  gfc_prepend_expr_to_block (&lse->post, tmp);
8815 	}
8816     }
8817   else if (lhs_attr.codimension)
8818     {
8819       lhs_tok = gfc_get_ultimate_alloc_ptr_comps_caf_token (lse, expr1);
8820       lhs_tok = build_fold_indirect_ref (lhs_tok);
8821       tmp = build2_loc (input_location, MODIFY_EXPR, void_type_node,
8822 			lhs_tok, null_pointer_node);
8823       gfc_prepend_expr_to_block (&lse->post, tmp);
8824     }
8825 }
8826 
8827 
8828 /* Do everything that is needed for a CLASS function expr2.  */
8829 
8830 static tree
8831 trans_class_pointer_fcn (stmtblock_t *block, gfc_se *lse, gfc_se *rse,
8832 			 gfc_expr *expr1, gfc_expr *expr2)
8833 {
8834   tree expr1_vptr = NULL_TREE;
8835   tree tmp;
8836 
8837   gfc_conv_function_expr (rse, expr2);
8838   rse->expr = gfc_evaluate_now (rse->expr, &rse->pre);
8839 
8840   if (expr1->ts.type != BT_CLASS)
8841       rse->expr = gfc_class_data_get (rse->expr);
8842   else
8843     {
8844       expr1_vptr = trans_class_vptr_len_assignment (block, expr1,
8845 						    expr2, rse,
8846 						    NULL, NULL);
8847       gfc_add_block_to_block (block, &rse->pre);
8848       tmp = gfc_create_var (TREE_TYPE (rse->expr), "ptrtemp");
8849       gfc_add_modify (&lse->pre, tmp, rse->expr);
8850 
8851       gfc_add_modify (&lse->pre, expr1_vptr,
8852 		      fold_convert (TREE_TYPE (expr1_vptr),
8853 		      gfc_class_vptr_get (tmp)));
8854       rse->expr = gfc_class_data_get (tmp);
8855     }
8856 
8857   return expr1_vptr;
8858 }
8859 
8860 
8861 tree
8862 gfc_trans_pointer_assign (gfc_code * code)
8863 {
8864   return gfc_trans_pointer_assignment (code->expr1, code->expr2);
8865 }
8866 
8867 
8868 /* Generate code for a pointer assignment.  */
8869 
8870 tree
8871 gfc_trans_pointer_assignment (gfc_expr * expr1, gfc_expr * expr2)
8872 {
8873   gfc_se lse;
8874   gfc_se rse;
8875   stmtblock_t block;
8876   tree desc;
8877   tree tmp;
8878   tree expr1_vptr = NULL_TREE;
8879   bool scalar, non_proc_ptr_assign;
8880   gfc_ss *ss;
8881 
8882   gfc_start_block (&block);
8883 
8884   gfc_init_se (&lse, NULL);
8885 
8886   /* Usually testing whether this is not a proc pointer assignment.  */
8887   non_proc_ptr_assign = !(gfc_expr_attr (expr1).proc_pointer
8888 			&& expr2->expr_type == EXPR_VARIABLE
8889 			&& expr2->symtree->n.sym->attr.flavor == FL_PROCEDURE);
8890 
8891   /* Check whether the expression is a scalar or not; we cannot use
8892      expr1->rank as it can be nonzero for proc pointers.  */
8893   ss = gfc_walk_expr (expr1);
8894   scalar = ss == gfc_ss_terminator;
8895   if (!scalar)
8896     gfc_free_ss_chain (ss);
8897 
8898   if (expr1->ts.type == BT_DERIVED && expr2->ts.type == BT_CLASS
8899       && expr2->expr_type != EXPR_FUNCTION && non_proc_ptr_assign)
8900     {
8901       gfc_add_data_component (expr2);
8902       /* The following is required as gfc_add_data_component doesn't
8903 	 update ts.type if there is a tailing REF_ARRAY.  */
8904       expr2->ts.type = BT_DERIVED;
8905     }
8906 
8907   if (scalar)
8908     {
8909       /* Scalar pointers.  */
8910       lse.want_pointer = 1;
8911       gfc_conv_expr (&lse, expr1);
8912       gfc_init_se (&rse, NULL);
8913       rse.want_pointer = 1;
8914       if (expr2->expr_type == EXPR_FUNCTION && expr2->ts.type == BT_CLASS)
8915 	trans_class_pointer_fcn (&block, &lse, &rse, expr1, expr2);
8916       else
8917 	gfc_conv_expr (&rse, expr2);
8918 
8919       if (non_proc_ptr_assign && expr1->ts.type == BT_CLASS)
8920 	{
8921 	  trans_class_vptr_len_assignment (&block, expr1, expr2, &rse, NULL,
8922 					   NULL);
8923 	  lse.expr = gfc_class_data_get (lse.expr);
8924 	}
8925 
8926       if (expr1->symtree->n.sym->attr.proc_pointer
8927 	  && expr1->symtree->n.sym->attr.dummy)
8928 	lse.expr = build_fold_indirect_ref_loc (input_location,
8929 						lse.expr);
8930 
8931       if (expr2->symtree && expr2->symtree->n.sym->attr.proc_pointer
8932 	  && expr2->symtree->n.sym->attr.dummy)
8933 	rse.expr = build_fold_indirect_ref_loc (input_location,
8934 						rse.expr);
8935 
8936       gfc_add_block_to_block (&block, &lse.pre);
8937       gfc_add_block_to_block (&block, &rse.pre);
8938 
8939       /* Check character lengths if character expression.  The test is only
8940 	 really added if -fbounds-check is enabled.  Exclude deferred
8941 	 character length lefthand sides.  */
8942       if (expr1->ts.type == BT_CHARACTER && expr2->expr_type != EXPR_NULL
8943 	  && !expr1->ts.deferred
8944 	  && !expr1->symtree->n.sym->attr.proc_pointer
8945 	  && !gfc_is_proc_ptr_comp (expr1))
8946 	{
8947 	  gcc_assert (expr2->ts.type == BT_CHARACTER);
8948 	  gcc_assert (lse.string_length && rse.string_length);
8949 	  gfc_trans_same_strlen_check ("pointer assignment", &expr1->where,
8950 				       lse.string_length, rse.string_length,
8951 				       &block);
8952 	}
8953 
8954       /* The assignment to an deferred character length sets the string
8955 	 length to that of the rhs.  */
8956       if (expr1->ts.deferred)
8957 	{
8958 	  if (expr2->expr_type != EXPR_NULL && lse.string_length != NULL)
8959 	    gfc_add_modify (&block, lse.string_length,
8960 			    fold_convert (TREE_TYPE (lse.string_length),
8961 					  rse.string_length));
8962 	  else if (lse.string_length != NULL)
8963 	    gfc_add_modify (&block, lse.string_length,
8964 			    build_zero_cst (TREE_TYPE (lse.string_length)));
8965 	}
8966 
8967       gfc_add_modify (&block, lse.expr,
8968 		      fold_convert (TREE_TYPE (lse.expr), rse.expr));
8969 
8970       /* Also set the tokens for pointer components in derived typed
8971 	 coarrays.  */
8972       if (flag_coarray == GFC_FCOARRAY_LIB)
8973 	trans_caf_token_assign (&lse, &rse, expr1, expr2);
8974 
8975       gfc_add_block_to_block (&block, &rse.post);
8976       gfc_add_block_to_block (&block, &lse.post);
8977     }
8978   else
8979     {
8980       gfc_ref* remap;
8981       bool rank_remap;
8982       tree strlen_lhs;
8983       tree strlen_rhs = NULL_TREE;
8984 
8985       /* Array pointer.  Find the last reference on the LHS and if it is an
8986 	 array section ref, we're dealing with bounds remapping.  In this case,
8987 	 set it to AR_FULL so that gfc_conv_expr_descriptor does
8988 	 not see it and process the bounds remapping afterwards explicitly.  */
8989       for (remap = expr1->ref; remap; remap = remap->next)
8990 	if (!remap->next && remap->type == REF_ARRAY
8991 	    && remap->u.ar.type == AR_SECTION)
8992 	  break;
8993       rank_remap = (remap && remap->u.ar.end[0]);
8994 
8995       gfc_init_se (&lse, NULL);
8996       if (remap)
8997 	lse.descriptor_only = 1;
8998       gfc_conv_expr_descriptor (&lse, expr1);
8999       strlen_lhs = lse.string_length;
9000       desc = lse.expr;
9001 
9002       if (expr2->expr_type == EXPR_NULL)
9003 	{
9004 	  /* Just set the data pointer to null.  */
9005 	  gfc_conv_descriptor_data_set (&lse.pre, lse.expr, null_pointer_node);
9006 	}
9007       else if (rank_remap)
9008 	{
9009 	  /* If we are rank-remapping, just get the RHS's descriptor and
9010 	     process this later on.  */
9011 	  gfc_init_se (&rse, NULL);
9012 	  rse.direct_byref = 1;
9013 	  rse.byref_noassign = 1;
9014 
9015 	  if (expr2->expr_type == EXPR_FUNCTION && expr2->ts.type == BT_CLASS)
9016 	    expr1_vptr = trans_class_pointer_fcn (&block, &lse, &rse,
9017 						  expr1, expr2);
9018 	  else if (expr2->expr_type == EXPR_FUNCTION)
9019 	    {
9020 	      tree bound[GFC_MAX_DIMENSIONS];
9021 	      int i;
9022 
9023 	      for (i = 0; i < expr2->rank; i++)
9024 		bound[i] = NULL_TREE;
9025 	      tmp = gfc_typenode_for_spec (&expr2->ts);
9026 	      tmp = gfc_get_array_type_bounds (tmp, expr2->rank, 0,
9027 					       bound, bound, 0,
9028 					       GFC_ARRAY_POINTER_CONT, false);
9029 	      tmp = gfc_create_var (tmp, "ptrtemp");
9030 	      rse.descriptor_only = 0;
9031 	      rse.expr = tmp;
9032 	      rse.direct_byref = 1;
9033 	      gfc_conv_expr_descriptor (&rse, expr2);
9034 	      strlen_rhs = rse.string_length;
9035 	      rse.expr = tmp;
9036 	    }
9037 	  else
9038 	    {
9039 	      gfc_conv_expr_descriptor (&rse, expr2);
9040 	      strlen_rhs = rse.string_length;
9041 	      if (expr1->ts.type == BT_CLASS)
9042 		expr1_vptr = trans_class_vptr_len_assignment (&block, expr1,
9043 							      expr2, &rse,
9044 							      NULL, NULL);
9045 	    }
9046 	}
9047       else if (expr2->expr_type == EXPR_VARIABLE)
9048 	{
9049 	  /* Assign directly to the LHS's descriptor.  */
9050 	  lse.descriptor_only = 0;
9051 	  lse.direct_byref = 1;
9052 	  gfc_conv_expr_descriptor (&lse, expr2);
9053 	  strlen_rhs = lse.string_length;
9054 
9055 	  if (expr1->ts.type == BT_CLASS)
9056 	    {
9057 	      rse.expr = NULL_TREE;
9058 	      rse.string_length = NULL_TREE;
9059 	      trans_class_vptr_len_assignment (&block, expr1, expr2, &rse,
9060 					       NULL, NULL);
9061 	    }
9062 
9063 	  if (remap == NULL)
9064 	    {
9065 	      /* If the target is not a whole array, use the target array
9066 		 reference for remap.  */
9067 	      for (remap = expr2->ref; remap; remap = remap->next)
9068 		if (remap->type == REF_ARRAY
9069 		    && remap->u.ar.type == AR_FULL
9070 		    && remap->next)
9071 		  break;
9072 	    }
9073 	}
9074       else if (expr2->expr_type == EXPR_FUNCTION && expr2->ts.type == BT_CLASS)
9075 	{
9076 	  gfc_init_se (&rse, NULL);
9077 	  rse.want_pointer = 1;
9078 	  gfc_conv_function_expr (&rse, expr2);
9079 	  if (expr1->ts.type != BT_CLASS)
9080 	    {
9081 	      rse.expr = gfc_class_data_get (rse.expr);
9082 	      gfc_add_modify (&lse.pre, desc, rse.expr);
9083 	      /* Set the lhs span.  */
9084 	      tmp = TREE_TYPE (rse.expr);
9085 	      tmp = TYPE_SIZE_UNIT (gfc_get_element_type (tmp));
9086 	      tmp = fold_convert (gfc_array_index_type, tmp);
9087 	      gfc_conv_descriptor_span_set (&lse.pre, desc, tmp);
9088  	    }
9089 	  else
9090 	    {
9091 	      expr1_vptr = trans_class_vptr_len_assignment (&block, expr1,
9092 							    expr2, &rse, NULL,
9093 							    NULL);
9094 	      gfc_add_block_to_block (&block, &rse.pre);
9095 	      tmp = gfc_create_var (TREE_TYPE (rse.expr), "ptrtemp");
9096 	      gfc_add_modify (&lse.pre, tmp, rse.expr);
9097 
9098 	      gfc_add_modify (&lse.pre, expr1_vptr,
9099 			      fold_convert (TREE_TYPE (expr1_vptr),
9100 					gfc_class_vptr_get (tmp)));
9101 	      rse.expr = gfc_class_data_get (tmp);
9102 	      gfc_add_modify (&lse.pre, desc, rse.expr);
9103 	    }
9104 	}
9105       else
9106 	{
9107 	  /* Assign to a temporary descriptor and then copy that
9108 	     temporary to the pointer.  */
9109 	  tmp = gfc_create_var (TREE_TYPE (desc), "ptrtemp");
9110 	  lse.descriptor_only = 0;
9111 	  lse.expr = tmp;
9112 	  lse.direct_byref = 1;
9113 	  gfc_conv_expr_descriptor (&lse, expr2);
9114 	  strlen_rhs = lse.string_length;
9115 	  gfc_add_modify (&lse.pre, desc, tmp);
9116 	}
9117 
9118       gfc_add_block_to_block (&block, &lse.pre);
9119       if (rank_remap)
9120 	gfc_add_block_to_block (&block, &rse.pre);
9121 
9122       /* If we do bounds remapping, update LHS descriptor accordingly.  */
9123       if (remap)
9124 	{
9125 	  int dim;
9126 	  gcc_assert (remap->u.ar.dimen == expr1->rank);
9127 
9128 	  if (rank_remap)
9129 	    {
9130 	      /* Do rank remapping.  We already have the RHS's descriptor
9131 		 converted in rse and now have to build the correct LHS
9132 		 descriptor for it.  */
9133 
9134 	      tree dtype, data, span;
9135 	      tree offs, stride;
9136 	      tree lbound, ubound;
9137 
9138 	      /* Set dtype.  */
9139 	      dtype = gfc_conv_descriptor_dtype (desc);
9140 	      tmp = gfc_get_dtype (TREE_TYPE (desc));
9141 	      gfc_add_modify (&block, dtype, tmp);
9142 
9143 	      /* Copy data pointer.  */
9144 	      data = gfc_conv_descriptor_data_get (rse.expr);
9145 	      gfc_conv_descriptor_data_set (&block, desc, data);
9146 
9147 	      /* Copy the span.  */
9148 	      if (TREE_CODE (rse.expr) == VAR_DECL
9149 		  && GFC_DECL_PTR_ARRAY_P (rse.expr))
9150 		span = gfc_conv_descriptor_span_get (rse.expr);
9151 	      else
9152 		{
9153 		  tmp = TREE_TYPE (rse.expr);
9154 		  tmp = TYPE_SIZE_UNIT (gfc_get_element_type (tmp));
9155 		  span = fold_convert (gfc_array_index_type, tmp);
9156 		}
9157 	      gfc_conv_descriptor_span_set (&block, desc, span);
9158 
9159 	      /* Copy offset but adjust it such that it would correspond
9160 		 to a lbound of zero.  */
9161 	      offs = gfc_conv_descriptor_offset_get (rse.expr);
9162 	      for (dim = 0; dim < expr2->rank; ++dim)
9163 		{
9164 		  stride = gfc_conv_descriptor_stride_get (rse.expr,
9165 							   gfc_rank_cst[dim]);
9166 		  lbound = gfc_conv_descriptor_lbound_get (rse.expr,
9167 							   gfc_rank_cst[dim]);
9168 		  tmp = fold_build2_loc (input_location, MULT_EXPR,
9169 					 gfc_array_index_type, stride, lbound);
9170 		  offs = fold_build2_loc (input_location, PLUS_EXPR,
9171 					  gfc_array_index_type, offs, tmp);
9172 		}
9173 	      gfc_conv_descriptor_offset_set (&block, desc, offs);
9174 
9175 	      /* Set the bounds as declared for the LHS and calculate strides as
9176 		 well as another offset update accordingly.  */
9177 	      stride = gfc_conv_descriptor_stride_get (rse.expr,
9178 						       gfc_rank_cst[0]);
9179 	      for (dim = 0; dim < expr1->rank; ++dim)
9180 		{
9181 		  gfc_se lower_se;
9182 		  gfc_se upper_se;
9183 
9184 		  gcc_assert (remap->u.ar.start[dim] && remap->u.ar.end[dim]);
9185 
9186 		  /* Convert declared bounds.  */
9187 		  gfc_init_se (&lower_se, NULL);
9188 		  gfc_init_se (&upper_se, NULL);
9189 		  gfc_conv_expr (&lower_se, remap->u.ar.start[dim]);
9190 		  gfc_conv_expr (&upper_se, remap->u.ar.end[dim]);
9191 
9192 		  gfc_add_block_to_block (&block, &lower_se.pre);
9193 		  gfc_add_block_to_block (&block, &upper_se.pre);
9194 
9195 		  lbound = fold_convert (gfc_array_index_type, lower_se.expr);
9196 		  ubound = fold_convert (gfc_array_index_type, upper_se.expr);
9197 
9198 		  lbound = gfc_evaluate_now (lbound, &block);
9199 		  ubound = gfc_evaluate_now (ubound, &block);
9200 
9201 		  gfc_add_block_to_block (&block, &lower_se.post);
9202 		  gfc_add_block_to_block (&block, &upper_se.post);
9203 
9204 		  /* Set bounds in descriptor.  */
9205 		  gfc_conv_descriptor_lbound_set (&block, desc,
9206 						  gfc_rank_cst[dim], lbound);
9207 		  gfc_conv_descriptor_ubound_set (&block, desc,
9208 						  gfc_rank_cst[dim], ubound);
9209 
9210 		  /* Set stride.  */
9211 		  stride = gfc_evaluate_now (stride, &block);
9212 		  gfc_conv_descriptor_stride_set (&block, desc,
9213 						  gfc_rank_cst[dim], stride);
9214 
9215 		  /* Update offset.  */
9216 		  offs = gfc_conv_descriptor_offset_get (desc);
9217 		  tmp = fold_build2_loc (input_location, MULT_EXPR,
9218 					 gfc_array_index_type, lbound, stride);
9219 		  offs = fold_build2_loc (input_location, MINUS_EXPR,
9220 					  gfc_array_index_type, offs, tmp);
9221 		  offs = gfc_evaluate_now (offs, &block);
9222 		  gfc_conv_descriptor_offset_set (&block, desc, offs);
9223 
9224 		  /* Update stride.  */
9225 		  tmp = gfc_conv_array_extent_dim (lbound, ubound, NULL);
9226 		  stride = fold_build2_loc (input_location, MULT_EXPR,
9227 					    gfc_array_index_type, stride, tmp);
9228 		}
9229 	    }
9230 	  else
9231 	    {
9232 	      /* Bounds remapping.  Just shift the lower bounds.  */
9233 
9234 	      gcc_assert (expr1->rank == expr2->rank);
9235 
9236 	      for (dim = 0; dim < remap->u.ar.dimen; ++dim)
9237 		{
9238 		  gfc_se lbound_se;
9239 
9240 		  gcc_assert (!remap->u.ar.end[dim]);
9241 		  gfc_init_se (&lbound_se, NULL);
9242 		  if (remap->u.ar.start[dim])
9243 		    {
9244 		      gfc_conv_expr (&lbound_se, remap->u.ar.start[dim]);
9245 		      gfc_add_block_to_block (&block, &lbound_se.pre);
9246 		    }
9247 		  else
9248 		    /* This remap arises from a target that is not a whole
9249 		       array. The start expressions will be NULL but we need
9250 		       the lbounds to be one.  */
9251 		    lbound_se.expr = gfc_index_one_node;
9252 		  gfc_conv_shift_descriptor_lbound (&block, desc,
9253 						    dim, lbound_se.expr);
9254 		  gfc_add_block_to_block (&block, &lbound_se.post);
9255 		}
9256 	    }
9257 	}
9258 
9259       /* If rank remapping was done, check with -fcheck=bounds that
9260 	 the target is at least as large as the pointer.  */
9261       if (rank_remap && (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS))
9262 	{
9263 	  tree lsize, rsize;
9264 	  tree fault;
9265 	  const char* msg;
9266 
9267 	  lsize = gfc_conv_descriptor_size (lse.expr, expr1->rank);
9268 	  rsize = gfc_conv_descriptor_size (rse.expr, expr2->rank);
9269 
9270 	  lsize = gfc_evaluate_now (lsize, &block);
9271 	  rsize = gfc_evaluate_now (rsize, &block);
9272 	  fault = fold_build2_loc (input_location, LT_EXPR, logical_type_node,
9273 				   rsize, lsize);
9274 
9275 	  msg = _("Target of rank remapping is too small (%ld < %ld)");
9276 	  gfc_trans_runtime_check (true, false, fault, &block, &expr2->where,
9277 				   msg, rsize, lsize);
9278 	}
9279 
9280       if (expr1->ts.type == BT_CHARACTER
9281 	  && expr1->symtree->n.sym->ts.deferred
9282 	  && expr1->symtree->n.sym->ts.u.cl->backend_decl
9283 	  && VAR_P (expr1->symtree->n.sym->ts.u.cl->backend_decl))
9284 	{
9285 	  tmp = expr1->symtree->n.sym->ts.u.cl->backend_decl;
9286 	  if (expr2->expr_type != EXPR_NULL)
9287 	    gfc_add_modify (&block, tmp,
9288 			    fold_convert (TREE_TYPE (tmp), strlen_rhs));
9289 	  else
9290 	    gfc_add_modify (&block, tmp, build_zero_cst (TREE_TYPE (tmp)));
9291 	}
9292 
9293       /* Check string lengths if applicable.  The check is only really added
9294 	 to the output code if -fbounds-check is enabled.  */
9295       if (expr1->ts.type == BT_CHARACTER && expr2->expr_type != EXPR_NULL)
9296 	{
9297 	  gcc_assert (expr2->ts.type == BT_CHARACTER);
9298 	  gcc_assert (strlen_lhs && strlen_rhs);
9299 	  gfc_trans_same_strlen_check ("pointer assignment", &expr1->where,
9300 				       strlen_lhs, strlen_rhs, &block);
9301 	}
9302 
9303       gfc_add_block_to_block (&block, &lse.post);
9304       if (rank_remap)
9305 	gfc_add_block_to_block (&block, &rse.post);
9306     }
9307 
9308   return gfc_finish_block (&block);
9309 }
9310 
9311 
9312 /* Makes sure se is suitable for passing as a function string parameter.  */
9313 /* TODO: Need to check all callers of this function.  It may be abused.  */
9314 
9315 void
9316 gfc_conv_string_parameter (gfc_se * se)
9317 {
9318   tree type;
9319 
9320   if (TREE_CODE (se->expr) == STRING_CST)
9321     {
9322       type = TREE_TYPE (TREE_TYPE (se->expr));
9323       se->expr = gfc_build_addr_expr (build_pointer_type (type), se->expr);
9324       return;
9325     }
9326 
9327   if (TYPE_STRING_FLAG (TREE_TYPE (se->expr)))
9328     {
9329       if (TREE_CODE (se->expr) != INDIRECT_REF)
9330 	{
9331 	  type = TREE_TYPE (se->expr);
9332           se->expr = gfc_build_addr_expr (build_pointer_type (type), se->expr);
9333 	}
9334       else
9335 	{
9336 	  type = gfc_get_character_type_len (gfc_default_character_kind,
9337 					     se->string_length);
9338 	  type = build_pointer_type (type);
9339 	  se->expr = gfc_build_addr_expr (type, se->expr);
9340 	}
9341     }
9342 
9343   gcc_assert (POINTER_TYPE_P (TREE_TYPE (se->expr)));
9344 }
9345 
9346 
9347 /* Generate code for assignment of scalar variables.  Includes character
9348    strings and derived types with allocatable components.
9349    If you know that the LHS has no allocations, set dealloc to false.
9350 
9351    DEEP_COPY has no effect if the typespec TS is not a derived type with
9352    allocatable components.  Otherwise, if it is set, an explicit copy of each
9353    allocatable component is made.  This is necessary as a simple copy of the
9354    whole object would copy array descriptors as is, so that the lhs's
9355    allocatable components would point to the rhs's after the assignment.
9356    Typically, setting DEEP_COPY is necessary if the rhs is a variable, and not
9357    necessary if the rhs is a non-pointer function, as the allocatable components
9358    are not accessible by other means than the function's result after the
9359    function has returned.  It is even more subtle when temporaries are involved,
9360    as the two following examples show:
9361     1.  When we evaluate an array constructor, a temporary is created.  Thus
9362       there is theoretically no alias possible.  However, no deep copy is
9363       made for this temporary, so that if the constructor is made of one or
9364       more variable with allocatable components, those components still point
9365       to the variable's: DEEP_COPY should be set for the assignment from the
9366       temporary to the lhs in that case.
9367     2.  When assigning a scalar to an array, we evaluate the scalar value out
9368       of the loop, store it into a temporary variable, and assign from that.
9369       In that case, deep copying when assigning to the temporary would be a
9370       waste of resources; however deep copies should happen when assigning from
9371       the temporary to each array element: again DEEP_COPY should be set for
9372       the assignment from the temporary to the lhs.  */
9373 
9374 tree
9375 gfc_trans_scalar_assign (gfc_se * lse, gfc_se * rse, gfc_typespec ts,
9376 			 bool deep_copy, bool dealloc, bool in_coarray)
9377 {
9378   stmtblock_t block;
9379   tree tmp;
9380   tree cond;
9381 
9382   gfc_init_block (&block);
9383 
9384   if (ts.type == BT_CHARACTER)
9385     {
9386       tree rlen = NULL;
9387       tree llen = NULL;
9388 
9389       if (lse->string_length != NULL_TREE)
9390 	{
9391 	  gfc_conv_string_parameter (lse);
9392 	  gfc_add_block_to_block (&block, &lse->pre);
9393 	  llen = lse->string_length;
9394 	}
9395 
9396       if (rse->string_length != NULL_TREE)
9397 	{
9398 	  gfc_conv_string_parameter (rse);
9399 	  gfc_add_block_to_block (&block, &rse->pre);
9400 	  rlen = rse->string_length;
9401 	}
9402 
9403       gfc_trans_string_copy (&block, llen, lse->expr, ts.kind, rlen,
9404 			     rse->expr, ts.kind);
9405     }
9406   else if (gfc_bt_struct (ts.type)
9407 	   && (ts.u.derived->attr.alloc_comp
9408 		|| (deep_copy && ts.u.derived->attr.pdt_type)))
9409     {
9410       tree tmp_var = NULL_TREE;
9411       cond = NULL_TREE;
9412 
9413       /* Are the rhs and the lhs the same?  */
9414       if (deep_copy)
9415 	{
9416 	  cond = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
9417 				  gfc_build_addr_expr (NULL_TREE, lse->expr),
9418 				  gfc_build_addr_expr (NULL_TREE, rse->expr));
9419 	  cond = gfc_evaluate_now (cond, &lse->pre);
9420 	}
9421 
9422       /* Deallocate the lhs allocated components as long as it is not
9423 	 the same as the rhs.  This must be done following the assignment
9424 	 to prevent deallocating data that could be used in the rhs
9425 	 expression.  */
9426       if (dealloc)
9427 	{
9428 	  tmp_var = gfc_evaluate_now (lse->expr, &lse->pre);
9429 	  tmp = gfc_deallocate_alloc_comp_no_caf (ts.u.derived, tmp_var, 0);
9430 	  if (deep_copy)
9431 	    tmp = build3_v (COND_EXPR, cond, build_empty_stmt (input_location),
9432 			    tmp);
9433 	  gfc_add_expr_to_block (&lse->post, tmp);
9434 	}
9435 
9436       gfc_add_block_to_block (&block, &rse->pre);
9437       gfc_add_block_to_block (&block, &lse->pre);
9438 
9439       gfc_add_modify (&block, lse->expr,
9440 			   fold_convert (TREE_TYPE (lse->expr), rse->expr));
9441 
9442       /* Restore pointer address of coarray components.  */
9443       if (ts.u.derived->attr.coarray_comp && deep_copy && tmp_var != NULL_TREE)
9444 	{
9445 	  tmp = gfc_reassign_alloc_comp_caf (ts.u.derived, tmp_var, lse->expr);
9446 	  tmp = build3_v (COND_EXPR, cond, build_empty_stmt (input_location),
9447 			  tmp);
9448 	  gfc_add_expr_to_block (&block, tmp);
9449 	}
9450 
9451       /* Do a deep copy if the rhs is a variable, if it is not the
9452 	 same as the lhs.  */
9453       if (deep_copy)
9454 	{
9455 	  int caf_mode = in_coarray ? (GFC_STRUCTURE_CAF_MODE_ENABLE_COARRAY
9456 				       | GFC_STRUCTURE_CAF_MODE_IN_COARRAY) : 0;
9457 	  tmp = gfc_copy_alloc_comp (ts.u.derived, rse->expr, lse->expr, 0,
9458 				     caf_mode);
9459 	  tmp = build3_v (COND_EXPR, cond, build_empty_stmt (input_location),
9460 			  tmp);
9461 	  gfc_add_expr_to_block (&block, tmp);
9462 	}
9463     }
9464   else if (gfc_bt_struct (ts.type) || ts.type == BT_CLASS)
9465     {
9466       gfc_add_block_to_block (&block, &lse->pre);
9467       gfc_add_block_to_block (&block, &rse->pre);
9468       tmp = fold_build1_loc (input_location, VIEW_CONVERT_EXPR,
9469 			     TREE_TYPE (lse->expr), rse->expr);
9470       gfc_add_modify (&block, lse->expr, tmp);
9471     }
9472   else
9473     {
9474       gfc_add_block_to_block (&block, &lse->pre);
9475       gfc_add_block_to_block (&block, &rse->pre);
9476 
9477       gfc_add_modify (&block, lse->expr,
9478 		      fold_convert (TREE_TYPE (lse->expr), rse->expr));
9479     }
9480 
9481   gfc_add_block_to_block (&block, &lse->post);
9482   gfc_add_block_to_block (&block, &rse->post);
9483 
9484   return gfc_finish_block (&block);
9485 }
9486 
9487 
9488 /* There are quite a lot of restrictions on the optimisation in using an
9489    array function assign without a temporary.  */
9490 
9491 static bool
9492 arrayfunc_assign_needs_temporary (gfc_expr * expr1, gfc_expr * expr2)
9493 {
9494   gfc_ref * ref;
9495   bool seen_array_ref;
9496   bool c = false;
9497   gfc_symbol *sym = expr1->symtree->n.sym;
9498 
9499   /* Play it safe with class functions assigned to a derived type.  */
9500   if (gfc_is_class_array_function (expr2)
9501       && expr1->ts.type == BT_DERIVED)
9502     return true;
9503 
9504   /* The caller has already checked rank>0 and expr_type == EXPR_FUNCTION.  */
9505   if (expr2->value.function.isym && !gfc_is_intrinsic_libcall (expr2))
9506     return true;
9507 
9508   /* Elemental functions are scalarized so that they don't need a
9509      temporary in gfc_trans_assignment_1, so return a true.  Otherwise,
9510      they would need special treatment in gfc_trans_arrayfunc_assign.  */
9511   if (expr2->value.function.esym != NULL
9512       && expr2->value.function.esym->attr.elemental)
9513     return true;
9514 
9515   /* Need a temporary if rhs is not FULL or a contiguous section.  */
9516   if (expr1->ref && !(gfc_full_array_ref_p (expr1->ref, &c) || c))
9517     return true;
9518 
9519   /* Need a temporary if EXPR1 can't be expressed as a descriptor.  */
9520   if (gfc_ref_needs_temporary_p (expr1->ref))
9521     return true;
9522 
9523   /* Functions returning pointers or allocatables need temporaries.  */
9524   c = expr2->value.function.esym
9525       ? (expr2->value.function.esym->attr.pointer
9526 	 || expr2->value.function.esym->attr.allocatable)
9527       : (expr2->symtree->n.sym->attr.pointer
9528 	 || expr2->symtree->n.sym->attr.allocatable);
9529   if (c)
9530     return true;
9531 
9532   /* Character array functions need temporaries unless the
9533      character lengths are the same.  */
9534   if (expr2->ts.type == BT_CHARACTER && expr2->rank > 0)
9535     {
9536       if (expr1->ts.u.cl->length == NULL
9537 	    || expr1->ts.u.cl->length->expr_type != EXPR_CONSTANT)
9538 	return true;
9539 
9540       if (expr2->ts.u.cl->length == NULL
9541 	    || expr2->ts.u.cl->length->expr_type != EXPR_CONSTANT)
9542 	return true;
9543 
9544       if (mpz_cmp (expr1->ts.u.cl->length->value.integer,
9545 		     expr2->ts.u.cl->length->value.integer) != 0)
9546 	return true;
9547     }
9548 
9549   /* Check that no LHS component references appear during an array
9550      reference. This is needed because we do not have the means to
9551      span any arbitrary stride with an array descriptor. This check
9552      is not needed for the rhs because the function result has to be
9553      a complete type.  */
9554   seen_array_ref = false;
9555   for (ref = expr1->ref; ref; ref = ref->next)
9556     {
9557       if (ref->type == REF_ARRAY)
9558 	seen_array_ref= true;
9559       else if (ref->type == REF_COMPONENT && seen_array_ref)
9560 	return true;
9561     }
9562 
9563   /* Check for a dependency.  */
9564   if (gfc_check_fncall_dependency (expr1, INTENT_OUT,
9565 				   expr2->value.function.esym,
9566 				   expr2->value.function.actual,
9567 				   NOT_ELEMENTAL))
9568     return true;
9569 
9570   /* If we have reached here with an intrinsic function, we do not
9571      need a temporary except in the particular case that reallocation
9572      on assignment is active and the lhs is allocatable and a target.  */
9573   if (expr2->value.function.isym)
9574     return (flag_realloc_lhs && sym->attr.allocatable && sym->attr.target);
9575 
9576   /* If the LHS is a dummy, we need a temporary if it is not
9577      INTENT(OUT).  */
9578   if (sym->attr.dummy && sym->attr.intent != INTENT_OUT)
9579     return true;
9580 
9581   /* If the lhs has been host_associated, is in common, a pointer or is
9582      a target and the function is not using a RESULT variable, aliasing
9583      can occur and a temporary is needed.  */
9584   if ((sym->attr.host_assoc
9585 	   || sym->attr.in_common
9586 	   || sym->attr.pointer
9587 	   || sym->attr.cray_pointee
9588 	   || sym->attr.target)
9589 	&& expr2->symtree != NULL
9590 	&& expr2->symtree->n.sym == expr2->symtree->n.sym->result)
9591     return true;
9592 
9593   /* A PURE function can unconditionally be called without a temporary.  */
9594   if (expr2->value.function.esym != NULL
9595       && expr2->value.function.esym->attr.pure)
9596     return false;
9597 
9598   /* Implicit_pure functions are those which could legally be declared
9599      to be PURE.  */
9600   if (expr2->value.function.esym != NULL
9601       && expr2->value.function.esym->attr.implicit_pure)
9602     return false;
9603 
9604   if (!sym->attr.use_assoc
9605 	&& !sym->attr.in_common
9606 	&& !sym->attr.pointer
9607 	&& !sym->attr.target
9608 	&& !sym->attr.cray_pointee
9609 	&& expr2->value.function.esym)
9610     {
9611       /* A temporary is not needed if the function is not contained and
9612 	 the variable is local or host associated and not a pointer or
9613 	 a target.  */
9614       if (!expr2->value.function.esym->attr.contained)
9615 	return false;
9616 
9617       /* A temporary is not needed if the lhs has never been host
9618 	 associated and the procedure is contained.  */
9619       else if (!sym->attr.host_assoc)
9620 	return false;
9621 
9622       /* A temporary is not needed if the variable is local and not
9623 	 a pointer, a target or a result.  */
9624       if (sym->ns->parent
9625 	    && expr2->value.function.esym->ns == sym->ns->parent)
9626 	return false;
9627     }
9628 
9629   /* Default to temporary use.  */
9630   return true;
9631 }
9632 
9633 
9634 /* Provide the loop info so that the lhs descriptor can be built for
9635    reallocatable assignments from extrinsic function calls.  */
9636 
9637 static void
9638 realloc_lhs_loop_for_fcn_call (gfc_se *se, locus *where, gfc_ss **ss,
9639 			       gfc_loopinfo *loop)
9640 {
9641   /* Signal that the function call should not be made by
9642      gfc_conv_loop_setup.  */
9643   se->ss->is_alloc_lhs = 1;
9644   gfc_init_loopinfo (loop);
9645   gfc_add_ss_to_loop (loop, *ss);
9646   gfc_add_ss_to_loop (loop, se->ss);
9647   gfc_conv_ss_startstride (loop);
9648   gfc_conv_loop_setup (loop, where);
9649   gfc_copy_loopinfo_to_se (se, loop);
9650   gfc_add_block_to_block (&se->pre, &loop->pre);
9651   gfc_add_block_to_block (&se->pre, &loop->post);
9652   se->ss->is_alloc_lhs = 0;
9653 }
9654 
9655 
9656 /* For assignment to a reallocatable lhs from intrinsic functions,
9657    replace the se.expr (ie. the result) with a temporary descriptor.
9658    Null the data field so that the library allocates space for the
9659    result. Free the data of the original descriptor after the function,
9660    in case it appears in an argument expression and transfer the
9661    result to the original descriptor.  */
9662 
9663 static void
9664 fcncall_realloc_result (gfc_se *se, int rank)
9665 {
9666   tree desc;
9667   tree res_desc;
9668   tree tmp;
9669   tree offset;
9670   tree zero_cond;
9671   int n;
9672 
9673   /* Use the allocation done by the library.  Substitute the lhs
9674      descriptor with a copy, whose data field is nulled.*/
9675   desc = build_fold_indirect_ref_loc (input_location, se->expr);
9676   if (POINTER_TYPE_P (TREE_TYPE (desc)))
9677     desc = build_fold_indirect_ref_loc (input_location, desc);
9678 
9679   /* Unallocated, the descriptor does not have a dtype.  */
9680   tmp = gfc_conv_descriptor_dtype (desc);
9681   gfc_add_modify (&se->pre, tmp, gfc_get_dtype (TREE_TYPE (desc)));
9682 
9683   res_desc = gfc_evaluate_now (desc, &se->pre);
9684   gfc_conv_descriptor_data_set (&se->pre, res_desc, null_pointer_node);
9685   se->expr = gfc_build_addr_expr (NULL_TREE, res_desc);
9686 
9687   /* Free the lhs after the function call and copy the result data to
9688      the lhs descriptor.  */
9689   tmp = gfc_conv_descriptor_data_get (desc);
9690   zero_cond = fold_build2_loc (input_location, EQ_EXPR,
9691 			       logical_type_node, tmp,
9692 			       build_int_cst (TREE_TYPE (tmp), 0));
9693   zero_cond = gfc_evaluate_now (zero_cond, &se->post);
9694   tmp = gfc_call_free (tmp);
9695   gfc_add_expr_to_block (&se->post, tmp);
9696 
9697   tmp = gfc_conv_descriptor_data_get (res_desc);
9698   gfc_conv_descriptor_data_set (&se->post, desc, tmp);
9699 
9700   /* Check that the shapes are the same between lhs and expression.  */
9701   for (n = 0 ; n < rank; n++)
9702     {
9703       tree tmp1;
9704       tmp = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[n]);
9705       tmp1 = gfc_conv_descriptor_lbound_get (res_desc, gfc_rank_cst[n]);
9706       tmp = fold_build2_loc (input_location, MINUS_EXPR,
9707 			     gfc_array_index_type, tmp, tmp1);
9708       tmp1 = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[n]);
9709       tmp = fold_build2_loc (input_location, MINUS_EXPR,
9710 			     gfc_array_index_type, tmp, tmp1);
9711       tmp1 = gfc_conv_descriptor_ubound_get (res_desc, gfc_rank_cst[n]);
9712       tmp = fold_build2_loc (input_location, PLUS_EXPR,
9713 			     gfc_array_index_type, tmp, tmp1);
9714       tmp = fold_build2_loc (input_location, NE_EXPR,
9715 			     logical_type_node, tmp,
9716 			     gfc_index_zero_node);
9717       tmp = gfc_evaluate_now (tmp, &se->post);
9718       zero_cond = fold_build2_loc (input_location, TRUTH_OR_EXPR,
9719 				   logical_type_node, tmp,
9720 				   zero_cond);
9721     }
9722 
9723   /* 'zero_cond' being true is equal to lhs not being allocated or the
9724      shapes being different.  */
9725   zero_cond = gfc_evaluate_now (zero_cond, &se->post);
9726 
9727   /* Now reset the bounds returned from the function call to bounds based
9728      on the lhs lbounds, except where the lhs is not allocated or the shapes
9729      of 'variable and 'expr' are different. Set the offset accordingly.  */
9730   offset = gfc_index_zero_node;
9731   for (n = 0 ; n < rank; n++)
9732     {
9733       tree lbound;
9734 
9735       lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[n]);
9736       lbound = fold_build3_loc (input_location, COND_EXPR,
9737 				gfc_array_index_type, zero_cond,
9738 				gfc_index_one_node, lbound);
9739       lbound = gfc_evaluate_now (lbound, &se->post);
9740 
9741       tmp = gfc_conv_descriptor_ubound_get (res_desc, gfc_rank_cst[n]);
9742       tmp = fold_build2_loc (input_location, PLUS_EXPR,
9743 			     gfc_array_index_type, tmp, lbound);
9744       gfc_conv_descriptor_lbound_set (&se->post, desc,
9745 				      gfc_rank_cst[n], lbound);
9746       gfc_conv_descriptor_ubound_set (&se->post, desc,
9747 				      gfc_rank_cst[n], tmp);
9748 
9749       /* Set stride and accumulate the offset.  */
9750       tmp = gfc_conv_descriptor_stride_get (res_desc, gfc_rank_cst[n]);
9751       gfc_conv_descriptor_stride_set (&se->post, desc,
9752 				      gfc_rank_cst[n], tmp);
9753       tmp = fold_build2_loc (input_location, MULT_EXPR,
9754 			     gfc_array_index_type, lbound, tmp);
9755       offset = fold_build2_loc (input_location, MINUS_EXPR,
9756 				gfc_array_index_type, offset, tmp);
9757       offset = gfc_evaluate_now (offset, &se->post);
9758     }
9759 
9760   gfc_conv_descriptor_offset_set (&se->post, desc, offset);
9761 }
9762 
9763 
9764 
9765 /* Try to translate array(:) = func (...), where func is a transformational
9766    array function, without using a temporary.  Returns NULL if this isn't the
9767    case.  */
9768 
9769 static tree
9770 gfc_trans_arrayfunc_assign (gfc_expr * expr1, gfc_expr * expr2)
9771 {
9772   gfc_se se;
9773   gfc_ss *ss = NULL;
9774   gfc_component *comp = NULL;
9775   gfc_loopinfo loop;
9776 
9777   if (arrayfunc_assign_needs_temporary (expr1, expr2))
9778     return NULL;
9779 
9780   /* The frontend doesn't seem to bother filling in expr->symtree for intrinsic
9781      functions.  */
9782   comp = gfc_get_proc_ptr_comp (expr2);
9783 
9784   if (!(expr2->value.function.isym
9785 	      || (comp && comp->attr.dimension)
9786 	      || (!comp && gfc_return_by_reference (expr2->value.function.esym)
9787 		  && expr2->value.function.esym->result->attr.dimension)))
9788     return NULL;
9789 
9790   gfc_init_se (&se, NULL);
9791   gfc_start_block (&se.pre);
9792   se.want_pointer = 1;
9793 
9794   gfc_conv_array_parameter (&se, expr1, false, NULL, NULL, NULL);
9795 
9796   if (expr1->ts.type == BT_DERIVED
9797 	&& expr1->ts.u.derived->attr.alloc_comp)
9798     {
9799       tree tmp;
9800       tmp = gfc_deallocate_alloc_comp_no_caf (expr1->ts.u.derived, se.expr,
9801 					      expr1->rank);
9802       gfc_add_expr_to_block (&se.pre, tmp);
9803     }
9804 
9805   se.direct_byref = 1;
9806   se.ss = gfc_walk_expr (expr2);
9807   gcc_assert (se.ss != gfc_ss_terminator);
9808 
9809   /* Reallocate on assignment needs the loopinfo for extrinsic functions.
9810      This is signalled to gfc_conv_procedure_call by setting is_alloc_lhs.
9811      Clearly, this cannot be done for an allocatable function result, since
9812      the shape of the result is unknown and, in any case, the function must
9813      correctly take care of the reallocation internally. For intrinsic
9814      calls, the array data is freed and the library takes care of allocation.
9815      TODO: Add logic of trans-array.c: gfc_alloc_allocatable_for_assignment
9816      to the library.  */
9817   if (flag_realloc_lhs
9818 	&& gfc_is_reallocatable_lhs (expr1)
9819 	&& !gfc_expr_attr (expr1).codimension
9820 	&& !gfc_is_coindexed (expr1)
9821 	&& !(expr2->value.function.esym
9822 	    && expr2->value.function.esym->result->attr.allocatable))
9823     {
9824       realloc_lhs_warning (expr1->ts.type, true, &expr1->where);
9825 
9826       if (!expr2->value.function.isym)
9827 	{
9828 	  ss = gfc_walk_expr (expr1);
9829 	  gcc_assert (ss != gfc_ss_terminator);
9830 
9831 	  realloc_lhs_loop_for_fcn_call (&se, &expr1->where, &ss, &loop);
9832 	  ss->is_alloc_lhs = 1;
9833 	}
9834       else
9835 	fcncall_realloc_result (&se, expr1->rank);
9836     }
9837 
9838   gfc_conv_function_expr (&se, expr2);
9839   gfc_add_block_to_block (&se.pre, &se.post);
9840 
9841   if (ss)
9842     gfc_cleanup_loop (&loop);
9843   else
9844     gfc_free_ss_chain (se.ss);
9845 
9846   return gfc_finish_block (&se.pre);
9847 }
9848 
9849 
9850 /* Try to efficiently translate array(:) = 0.  Return NULL if this
9851    can't be done.  */
9852 
9853 static tree
9854 gfc_trans_zero_assign (gfc_expr * expr)
9855 {
9856   tree dest, len, type;
9857   tree tmp;
9858   gfc_symbol *sym;
9859 
9860   sym = expr->symtree->n.sym;
9861   dest = gfc_get_symbol_decl (sym);
9862 
9863   type = TREE_TYPE (dest);
9864   if (POINTER_TYPE_P (type))
9865     type = TREE_TYPE (type);
9866   if (!GFC_ARRAY_TYPE_P (type))
9867     return NULL_TREE;
9868 
9869   /* Determine the length of the array.  */
9870   len = GFC_TYPE_ARRAY_SIZE (type);
9871   if (!len || TREE_CODE (len) != INTEGER_CST)
9872     return NULL_TREE;
9873 
9874   tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type));
9875   len = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type, len,
9876 			 fold_convert (gfc_array_index_type, tmp));
9877 
9878   /* If we are zeroing a local array avoid taking its address by emitting
9879      a = {} instead.  */
9880   if (!POINTER_TYPE_P (TREE_TYPE (dest)))
9881     return build2_loc (input_location, MODIFY_EXPR, void_type_node,
9882 		       dest, build_constructor (TREE_TYPE (dest),
9883 					      NULL));
9884 
9885   /* Convert arguments to the correct types.  */
9886   dest = fold_convert (pvoid_type_node, dest);
9887   len = fold_convert (size_type_node, len);
9888 
9889   /* Construct call to __builtin_memset.  */
9890   tmp = build_call_expr_loc (input_location,
9891 			     builtin_decl_explicit (BUILT_IN_MEMSET),
9892 			     3, dest, integer_zero_node, len);
9893   return fold_convert (void_type_node, tmp);
9894 }
9895 
9896 
9897 /* Helper for gfc_trans_array_copy and gfc_trans_array_constructor_copy
9898    that constructs the call to __builtin_memcpy.  */
9899 
9900 tree
9901 gfc_build_memcpy_call (tree dst, tree src, tree len)
9902 {
9903   tree tmp;
9904 
9905   /* Convert arguments to the correct types.  */
9906   if (!POINTER_TYPE_P (TREE_TYPE (dst)))
9907     dst = gfc_build_addr_expr (pvoid_type_node, dst);
9908   else
9909     dst = fold_convert (pvoid_type_node, dst);
9910 
9911   if (!POINTER_TYPE_P (TREE_TYPE (src)))
9912     src = gfc_build_addr_expr (pvoid_type_node, src);
9913   else
9914     src = fold_convert (pvoid_type_node, src);
9915 
9916   len = fold_convert (size_type_node, len);
9917 
9918   /* Construct call to __builtin_memcpy.  */
9919   tmp = build_call_expr_loc (input_location,
9920 			     builtin_decl_explicit (BUILT_IN_MEMCPY),
9921 			     3, dst, src, len);
9922   return fold_convert (void_type_node, tmp);
9923 }
9924 
9925 
9926 /* Try to efficiently translate dst(:) = src(:).  Return NULL if this
9927    can't be done.  EXPR1 is the destination/lhs and EXPR2 is the
9928    source/rhs, both are gfc_full_array_ref_p which have been checked for
9929    dependencies.  */
9930 
9931 static tree
9932 gfc_trans_array_copy (gfc_expr * expr1, gfc_expr * expr2)
9933 {
9934   tree dst, dlen, dtype;
9935   tree src, slen, stype;
9936   tree tmp;
9937 
9938   dst = gfc_get_symbol_decl (expr1->symtree->n.sym);
9939   src = gfc_get_symbol_decl (expr2->symtree->n.sym);
9940 
9941   dtype = TREE_TYPE (dst);
9942   if (POINTER_TYPE_P (dtype))
9943     dtype = TREE_TYPE (dtype);
9944   stype = TREE_TYPE (src);
9945   if (POINTER_TYPE_P (stype))
9946     stype = TREE_TYPE (stype);
9947 
9948   if (!GFC_ARRAY_TYPE_P (dtype) || !GFC_ARRAY_TYPE_P (stype))
9949     return NULL_TREE;
9950 
9951   /* Determine the lengths of the arrays.  */
9952   dlen = GFC_TYPE_ARRAY_SIZE (dtype);
9953   if (!dlen || TREE_CODE (dlen) != INTEGER_CST)
9954     return NULL_TREE;
9955   tmp = TYPE_SIZE_UNIT (gfc_get_element_type (dtype));
9956   dlen = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
9957 			  dlen, fold_convert (gfc_array_index_type, tmp));
9958 
9959   slen = GFC_TYPE_ARRAY_SIZE (stype);
9960   if (!slen || TREE_CODE (slen) != INTEGER_CST)
9961     return NULL_TREE;
9962   tmp = TYPE_SIZE_UNIT (gfc_get_element_type (stype));
9963   slen = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
9964 			  slen, fold_convert (gfc_array_index_type, tmp));
9965 
9966   /* Sanity check that they are the same.  This should always be
9967      the case, as we should already have checked for conformance.  */
9968   if (!tree_int_cst_equal (slen, dlen))
9969     return NULL_TREE;
9970 
9971   return gfc_build_memcpy_call (dst, src, dlen);
9972 }
9973 
9974 
9975 /* Try to efficiently translate array(:) = (/ ... /).  Return NULL if
9976    this can't be done.  EXPR1 is the destination/lhs for which
9977    gfc_full_array_ref_p is true, and EXPR2 is the source/rhs.  */
9978 
9979 static tree
9980 gfc_trans_array_constructor_copy (gfc_expr * expr1, gfc_expr * expr2)
9981 {
9982   unsigned HOST_WIDE_INT nelem;
9983   tree dst, dtype;
9984   tree src, stype;
9985   tree len;
9986   tree tmp;
9987 
9988   nelem = gfc_constant_array_constructor_p (expr2->value.constructor);
9989   if (nelem == 0)
9990     return NULL_TREE;
9991 
9992   dst = gfc_get_symbol_decl (expr1->symtree->n.sym);
9993   dtype = TREE_TYPE (dst);
9994   if (POINTER_TYPE_P (dtype))
9995     dtype = TREE_TYPE (dtype);
9996   if (!GFC_ARRAY_TYPE_P (dtype))
9997     return NULL_TREE;
9998 
9999   /* Determine the lengths of the array.  */
10000   len = GFC_TYPE_ARRAY_SIZE (dtype);
10001   if (!len || TREE_CODE (len) != INTEGER_CST)
10002     return NULL_TREE;
10003 
10004   /* Confirm that the constructor is the same size.  */
10005   if (compare_tree_int (len, nelem) != 0)
10006     return NULL_TREE;
10007 
10008   tmp = TYPE_SIZE_UNIT (gfc_get_element_type (dtype));
10009   len = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type, len,
10010 			 fold_convert (gfc_array_index_type, tmp));
10011 
10012   stype = gfc_typenode_for_spec (&expr2->ts);
10013   src = gfc_build_constant_array_constructor (expr2, stype);
10014 
10015   stype = TREE_TYPE (src);
10016   if (POINTER_TYPE_P (stype))
10017     stype = TREE_TYPE (stype);
10018 
10019   return gfc_build_memcpy_call (dst, src, len);
10020 }
10021 
10022 
10023 /* Tells whether the expression is to be treated as a variable reference.  */
10024 
10025 bool
10026 gfc_expr_is_variable (gfc_expr *expr)
10027 {
10028   gfc_expr *arg;
10029   gfc_component *comp;
10030   gfc_symbol *func_ifc;
10031 
10032   if (expr->expr_type == EXPR_VARIABLE)
10033     return true;
10034 
10035   arg = gfc_get_noncopying_intrinsic_argument (expr);
10036   if (arg)
10037     {
10038       gcc_assert (expr->value.function.isym->id == GFC_ISYM_TRANSPOSE);
10039       return gfc_expr_is_variable (arg);
10040     }
10041 
10042   /* A data-pointer-returning function should be considered as a variable
10043      too.  */
10044   if (expr->expr_type == EXPR_FUNCTION
10045       && expr->ref == NULL)
10046     {
10047       if (expr->value.function.isym != NULL)
10048 	return false;
10049 
10050       if (expr->value.function.esym != NULL)
10051 	{
10052 	  func_ifc = expr->value.function.esym;
10053 	  goto found_ifc;
10054 	}
10055       else
10056 	{
10057 	  gcc_assert (expr->symtree);
10058 	  func_ifc = expr->symtree->n.sym;
10059 	  goto found_ifc;
10060 	}
10061 
10062       gcc_unreachable ();
10063     }
10064 
10065   comp = gfc_get_proc_ptr_comp (expr);
10066   if ((expr->expr_type == EXPR_PPC || expr->expr_type == EXPR_FUNCTION)
10067       && comp)
10068     {
10069       func_ifc = comp->ts.interface;
10070       goto found_ifc;
10071     }
10072 
10073   if (expr->expr_type == EXPR_COMPCALL)
10074     {
10075       gcc_assert (!expr->value.compcall.tbp->is_generic);
10076       func_ifc = expr->value.compcall.tbp->u.specific->n.sym;
10077       goto found_ifc;
10078     }
10079 
10080   return false;
10081 
10082 found_ifc:
10083   gcc_assert (func_ifc->attr.function
10084 	      && func_ifc->result != NULL);
10085   return func_ifc->result->attr.pointer;
10086 }
10087 
10088 
10089 /* Is the lhs OK for automatic reallocation?  */
10090 
10091 static bool
10092 is_scalar_reallocatable_lhs (gfc_expr *expr)
10093 {
10094   gfc_ref * ref;
10095 
10096   /* An allocatable variable with no reference.  */
10097   if (expr->symtree->n.sym->attr.allocatable
10098 	&& !expr->ref)
10099     return true;
10100 
10101   /* All that can be left are allocatable components.  However, we do
10102      not check for allocatable components here because the expression
10103      could be an allocatable component of a pointer component.  */
10104   if (expr->symtree->n.sym->ts.type != BT_DERIVED
10105 	&& expr->symtree->n.sym->ts.type != BT_CLASS)
10106     return false;
10107 
10108   /* Find an allocatable component ref last.  */
10109   for (ref = expr->ref; ref; ref = ref->next)
10110     if (ref->type == REF_COMPONENT
10111 	  && !ref->next
10112 	  && ref->u.c.component->attr.allocatable)
10113       return true;
10114 
10115   return false;
10116 }
10117 
10118 
10119 /* Allocate or reallocate scalar lhs, as necessary.  */
10120 
10121 static void
10122 alloc_scalar_allocatable_for_assignment (stmtblock_t *block,
10123 					 tree string_length,
10124 					 gfc_expr *expr1,
10125 					 gfc_expr *expr2)
10126 
10127 {
10128   tree cond;
10129   tree tmp;
10130   tree size;
10131   tree size_in_bytes;
10132   tree jump_label1;
10133   tree jump_label2;
10134   gfc_se lse;
10135   gfc_ref *ref;
10136 
10137   if (!expr1 || expr1->rank)
10138     return;
10139 
10140   if (!expr2 || expr2->rank)
10141     return;
10142 
10143   for (ref = expr1->ref; ref; ref = ref->next)
10144     if (ref->type == REF_SUBSTRING)
10145       return;
10146 
10147   realloc_lhs_warning (expr2->ts.type, false, &expr2->where);
10148 
10149   /* Since this is a scalar lhs, we can afford to do this.  That is,
10150      there is no risk of side effects being repeated.  */
10151   gfc_init_se (&lse, NULL);
10152   lse.want_pointer = 1;
10153   gfc_conv_expr (&lse, expr1);
10154 
10155   jump_label1 = gfc_build_label_decl (NULL_TREE);
10156   jump_label2 = gfc_build_label_decl (NULL_TREE);
10157 
10158   /* Do the allocation if the lhs is NULL. Otherwise go to label 1.  */
10159   tmp = build_int_cst (TREE_TYPE (lse.expr), 0);
10160   cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
10161 			  lse.expr, tmp);
10162   tmp = build3_v (COND_EXPR, cond,
10163 		  build1_v (GOTO_EXPR, jump_label1),
10164 		  build_empty_stmt (input_location));
10165   gfc_add_expr_to_block (block, tmp);
10166 
10167   if (expr1->ts.type == BT_CHARACTER && expr1->ts.deferred)
10168     {
10169       /* Use the rhs string length and the lhs element size.  */
10170       size = string_length;
10171       tmp = TREE_TYPE (gfc_typenode_for_spec (&expr1->ts));
10172       tmp = TYPE_SIZE_UNIT (tmp);
10173       size_in_bytes = fold_build2_loc (input_location, MULT_EXPR,
10174 				       TREE_TYPE (tmp), tmp,
10175 				       fold_convert (TREE_TYPE (tmp), size));
10176     }
10177   else
10178     {
10179       /* Otherwise use the length in bytes of the rhs.  */
10180       size = TYPE_SIZE_UNIT (gfc_typenode_for_spec (&expr1->ts));
10181       size_in_bytes = size;
10182     }
10183 
10184   size_in_bytes = fold_build2_loc (input_location, MAX_EXPR, size_type_node,
10185 				   size_in_bytes, size_one_node);
10186 
10187   if (gfc_caf_attr (expr1).codimension && flag_coarray == GFC_FCOARRAY_LIB)
10188     {
10189       tree caf_decl, token;
10190       gfc_se caf_se;
10191       symbol_attribute attr;
10192 
10193       gfc_clear_attr (&attr);
10194       gfc_init_se (&caf_se, NULL);
10195 
10196       caf_decl = gfc_get_tree_for_caf_expr (expr1);
10197       gfc_get_caf_token_offset (&caf_se, &token, NULL, caf_decl, NULL_TREE,
10198 				NULL);
10199       gfc_add_block_to_block (block, &caf_se.pre);
10200       gfc_allocate_allocatable (block, lse.expr, size_in_bytes,
10201 				gfc_build_addr_expr (NULL_TREE, token),
10202 				NULL_TREE, NULL_TREE, NULL_TREE, jump_label1,
10203 				expr1, 1);
10204     }
10205   else if (expr1->ts.type == BT_DERIVED && expr1->ts.u.derived->attr.alloc_comp)
10206     {
10207       tmp = build_call_expr_loc (input_location,
10208 				 builtin_decl_explicit (BUILT_IN_CALLOC),
10209 				 2, build_one_cst (size_type_node),
10210 				 size_in_bytes);
10211       tmp = fold_convert (TREE_TYPE (lse.expr), tmp);
10212       gfc_add_modify (block, lse.expr, tmp);
10213     }
10214   else
10215     {
10216       tmp = build_call_expr_loc (input_location,
10217 				 builtin_decl_explicit (BUILT_IN_MALLOC),
10218 				 1, size_in_bytes);
10219       tmp = fold_convert (TREE_TYPE (lse.expr), tmp);
10220       gfc_add_modify (block, lse.expr, tmp);
10221     }
10222 
10223   if (expr1->ts.type == BT_CHARACTER && expr1->ts.deferred)
10224     {
10225       /* Deferred characters need checking for lhs and rhs string
10226 	 length.  Other deferred parameter variables will have to
10227 	 come here too.  */
10228       tmp = build1_v (GOTO_EXPR, jump_label2);
10229       gfc_add_expr_to_block (block, tmp);
10230     }
10231   tmp = build1_v (LABEL_EXPR, jump_label1);
10232   gfc_add_expr_to_block (block, tmp);
10233 
10234   /* For a deferred length character, reallocate if lengths of lhs and
10235      rhs are different.  */
10236   if (expr1->ts.type == BT_CHARACTER && expr1->ts.deferred)
10237     {
10238       cond = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
10239 			      lse.string_length,
10240 			      fold_convert (TREE_TYPE (lse.string_length),
10241 					    size));
10242       /* Jump past the realloc if the lengths are the same.  */
10243       tmp = build3_v (COND_EXPR, cond,
10244 		      build1_v (GOTO_EXPR, jump_label2),
10245 		      build_empty_stmt (input_location));
10246       gfc_add_expr_to_block (block, tmp);
10247       tmp = build_call_expr_loc (input_location,
10248 				 builtin_decl_explicit (BUILT_IN_REALLOC),
10249 				 2, fold_convert (pvoid_type_node, lse.expr),
10250 				 size_in_bytes);
10251       tmp = fold_convert (TREE_TYPE (lse.expr), tmp);
10252       gfc_add_modify (block, lse.expr, tmp);
10253       tmp = build1_v (LABEL_EXPR, jump_label2);
10254       gfc_add_expr_to_block (block, tmp);
10255 
10256       /* Update the lhs character length.  */
10257       size = string_length;
10258       gfc_add_modify (block, lse.string_length,
10259 		      fold_convert (TREE_TYPE (lse.string_length), size));
10260     }
10261 }
10262 
10263 /* Check for assignments of the type
10264 
10265    a = a + 4
10266 
10267    to make sure we do not check for reallocation unneccessarily.  */
10268 
10269 
10270 static bool
10271 is_runtime_conformable (gfc_expr *expr1, gfc_expr *expr2)
10272 {
10273   gfc_actual_arglist *a;
10274   gfc_expr *e1, *e2;
10275 
10276   switch (expr2->expr_type)
10277     {
10278     case EXPR_VARIABLE:
10279       return gfc_dep_compare_expr (expr1, expr2) == 0;
10280 
10281     case EXPR_FUNCTION:
10282       if (expr2->value.function.esym
10283 	  && expr2->value.function.esym->attr.elemental)
10284 	{
10285 	  for (a = expr2->value.function.actual; a != NULL; a = a->next)
10286 	    {
10287 	      e1 = a->expr;
10288 	      if (e1 && e1->rank > 0 && !is_runtime_conformable (expr1, e1))
10289 		return false;
10290 	    }
10291 	  return true;
10292 	}
10293       else if (expr2->value.function.isym
10294 	       && expr2->value.function.isym->elemental)
10295 	{
10296 	  for (a = expr2->value.function.actual; a != NULL; a = a->next)
10297 	    {
10298 	      e1 = a->expr;
10299 	      if (e1 && e1->rank > 0 && !is_runtime_conformable (expr1, e1))
10300 		return false;
10301 	    }
10302 	  return true;
10303 	}
10304 
10305       break;
10306 
10307     case EXPR_OP:
10308       switch (expr2->value.op.op)
10309 	{
10310 	case INTRINSIC_NOT:
10311 	case INTRINSIC_UPLUS:
10312 	case INTRINSIC_UMINUS:
10313 	case INTRINSIC_PARENTHESES:
10314 	  return is_runtime_conformable (expr1, expr2->value.op.op1);
10315 
10316 	case INTRINSIC_PLUS:
10317 	case INTRINSIC_MINUS:
10318 	case INTRINSIC_TIMES:
10319 	case INTRINSIC_DIVIDE:
10320 	case INTRINSIC_POWER:
10321 	case INTRINSIC_AND:
10322 	case INTRINSIC_OR:
10323 	case INTRINSIC_EQV:
10324 	case INTRINSIC_NEQV:
10325 	case INTRINSIC_EQ:
10326 	case INTRINSIC_NE:
10327 	case INTRINSIC_GT:
10328 	case INTRINSIC_GE:
10329 	case INTRINSIC_LT:
10330 	case INTRINSIC_LE:
10331 	case INTRINSIC_EQ_OS:
10332 	case INTRINSIC_NE_OS:
10333 	case INTRINSIC_GT_OS:
10334 	case INTRINSIC_GE_OS:
10335 	case INTRINSIC_LT_OS:
10336 	case INTRINSIC_LE_OS:
10337 
10338 	  e1 = expr2->value.op.op1;
10339 	  e2 = expr2->value.op.op2;
10340 
10341 	  if (e1->rank == 0 && e2->rank > 0)
10342 	    return is_runtime_conformable (expr1, e2);
10343 	  else if (e1->rank > 0 && e2->rank == 0)
10344 	    return is_runtime_conformable (expr1, e1);
10345 	  else if (e1->rank > 0 && e2->rank > 0)
10346 	    return is_runtime_conformable (expr1, e1)
10347 	      && is_runtime_conformable (expr1, e2);
10348 	  break;
10349 
10350 	default:
10351 	  break;
10352 
10353 	}
10354 
10355       break;
10356 
10357     default:
10358       break;
10359     }
10360   return false;
10361 }
10362 
10363 
10364 static tree
10365 trans_class_assignment (stmtblock_t *block, gfc_expr *lhs, gfc_expr *rhs,
10366 			gfc_se *lse, gfc_se *rse, bool use_vptr_copy,
10367 			bool class_realloc)
10368 {
10369   tree tmp, fcn, stdcopy, to_len, from_len, vptr;
10370   vec<tree, va_gc> *args = NULL;
10371 
10372   vptr = trans_class_vptr_len_assignment (block, lhs, rhs, rse, &to_len,
10373 					 &from_len);
10374 
10375   /* Generate allocation of the lhs.  */
10376   if (class_realloc)
10377     {
10378       stmtblock_t alloc;
10379       tree class_han;
10380 
10381       tmp = gfc_vptr_size_get (vptr);
10382       class_han = GFC_CLASS_TYPE_P (TREE_TYPE (lse->expr))
10383 	  ? gfc_class_data_get (lse->expr) : lse->expr;
10384       gfc_init_block (&alloc);
10385       gfc_allocate_using_malloc (&alloc, class_han, tmp, NULL_TREE);
10386       tmp = fold_build2_loc (input_location, EQ_EXPR,
10387 			     logical_type_node, class_han,
10388 			     build_int_cst (prvoid_type_node, 0));
10389       tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
10390 			     gfc_unlikely (tmp,
10391 					   PRED_FORTRAN_FAIL_ALLOC),
10392 			     gfc_finish_block (&alloc),
10393 			     build_empty_stmt (input_location));
10394       gfc_add_expr_to_block (&lse->pre, tmp);
10395     }
10396 
10397   fcn = gfc_vptr_copy_get (vptr);
10398 
10399   tmp = GFC_CLASS_TYPE_P (TREE_TYPE (rse->expr))
10400       ? gfc_class_data_get (rse->expr) : rse->expr;
10401   if (use_vptr_copy)
10402     {
10403       if (!POINTER_TYPE_P (TREE_TYPE (tmp))
10404 	  || INDIRECT_REF_P (tmp)
10405 	  || (rhs->ts.type == BT_DERIVED
10406 	      && rhs->ts.u.derived->attr.unlimited_polymorphic
10407 	      && !rhs->ts.u.derived->attr.pointer
10408 	      && !rhs->ts.u.derived->attr.allocatable)
10409 	  || (UNLIMITED_POLY (rhs)
10410 	      && !CLASS_DATA (rhs)->attr.pointer
10411 	      && !CLASS_DATA (rhs)->attr.allocatable))
10412 	vec_safe_push (args, gfc_build_addr_expr (NULL_TREE, tmp));
10413       else
10414 	vec_safe_push (args, tmp);
10415       tmp = GFC_CLASS_TYPE_P (TREE_TYPE (lse->expr))
10416 	  ? gfc_class_data_get (lse->expr) : lse->expr;
10417       if (!POINTER_TYPE_P (TREE_TYPE (tmp))
10418 	  || INDIRECT_REF_P (tmp)
10419 	  || (lhs->ts.type == BT_DERIVED
10420 	      && lhs->ts.u.derived->attr.unlimited_polymorphic
10421 	      && !lhs->ts.u.derived->attr.pointer
10422 	      && !lhs->ts.u.derived->attr.allocatable)
10423 	  || (UNLIMITED_POLY (lhs)
10424 	      && !CLASS_DATA (lhs)->attr.pointer
10425 	      && !CLASS_DATA (lhs)->attr.allocatable))
10426 	vec_safe_push (args, gfc_build_addr_expr (NULL_TREE, tmp));
10427       else
10428 	vec_safe_push (args, tmp);
10429 
10430       stdcopy = build_call_vec (TREE_TYPE (TREE_TYPE (fcn)), fcn, args);
10431 
10432       if (to_len != NULL_TREE && !integer_zerop (from_len))
10433 	{
10434 	  tree extcopy;
10435 	  vec_safe_push (args, from_len);
10436 	  vec_safe_push (args, to_len);
10437 	  extcopy = build_call_vec (TREE_TYPE (TREE_TYPE (fcn)), fcn, args);
10438 
10439 	  tmp = fold_build2_loc (input_location, GT_EXPR,
10440 				 logical_type_node, from_len,
10441 				 build_zero_cst (TREE_TYPE (from_len)));
10442 	  return fold_build3_loc (input_location, COND_EXPR,
10443 				  void_type_node, tmp,
10444 				  extcopy, stdcopy);
10445 	}
10446       else
10447 	return stdcopy;
10448     }
10449   else
10450     {
10451       tree rhst = GFC_CLASS_TYPE_P (TREE_TYPE (lse->expr))
10452 	  ? gfc_class_data_get (lse->expr) : lse->expr;
10453       stmtblock_t tblock;
10454       gfc_init_block (&tblock);
10455       if (!POINTER_TYPE_P (TREE_TYPE (tmp)))
10456 	tmp = gfc_build_addr_expr (NULL_TREE, tmp);
10457       if (!POINTER_TYPE_P (TREE_TYPE (rhst)))
10458 	rhst = gfc_build_addr_expr (NULL_TREE, rhst);
10459       /* When coming from a ptr_copy lhs and rhs are swapped.  */
10460       gfc_add_modify_loc (input_location, &tblock, rhst,
10461 			  fold_convert (TREE_TYPE (rhst), tmp));
10462       return gfc_finish_block (&tblock);
10463     }
10464 }
10465 
10466 /* Subroutine of gfc_trans_assignment that actually scalarizes the
10467    assignment.  EXPR1 is the destination/LHS and EXPR2 is the source/RHS.
10468    init_flag indicates initialization expressions and dealloc that no
10469    deallocate prior assignment is needed (if in doubt, set true).
10470    When PTR_COPY is set and expr1 is a class type, then use the _vptr-copy
10471    routine instead of a pointer assignment.  Alias resolution is only done,
10472    when MAY_ALIAS is set (the default).  This flag is used by ALLOCATE()
10473    where it is known, that newly allocated memory on the lhs can never be
10474    an alias of the rhs.  */
10475 
10476 static tree
10477 gfc_trans_assignment_1 (gfc_expr * expr1, gfc_expr * expr2, bool init_flag,
10478 			bool dealloc, bool use_vptr_copy, bool may_alias)
10479 {
10480   gfc_se lse;
10481   gfc_se rse;
10482   gfc_ss *lss;
10483   gfc_ss *lss_section;
10484   gfc_ss *rss;
10485   gfc_loopinfo loop;
10486   tree tmp;
10487   stmtblock_t block;
10488   stmtblock_t body;
10489   bool l_is_temp;
10490   bool scalar_to_array;
10491   tree string_length;
10492   int n;
10493   bool maybe_workshare = false, lhs_refs_comp = false, rhs_refs_comp = false;
10494   symbol_attribute lhs_caf_attr, rhs_caf_attr, lhs_attr;
10495   bool is_poly_assign;
10496 
10497   /* Assignment of the form lhs = rhs.  */
10498   gfc_start_block (&block);
10499 
10500   gfc_init_se (&lse, NULL);
10501   gfc_init_se (&rse, NULL);
10502 
10503   /* Walk the lhs.  */
10504   lss = gfc_walk_expr (expr1);
10505   if (gfc_is_reallocatable_lhs (expr1))
10506     {
10507       lss->no_bounds_check = 1;
10508       if (!(expr2->expr_type == EXPR_FUNCTION
10509 	    && expr2->value.function.isym != NULL
10510 	    && !(expr2->value.function.isym->elemental
10511 		 || expr2->value.function.isym->conversion)))
10512 	lss->is_alloc_lhs = 1;
10513     }
10514   else
10515     lss->no_bounds_check = expr1->no_bounds_check;
10516 
10517   rss = NULL;
10518 
10519   if ((expr1->ts.type == BT_DERIVED)
10520       && (gfc_is_class_array_function (expr2)
10521 	  || gfc_is_alloc_class_scalar_function (expr2)))
10522     expr2->must_finalize = 1;
10523 
10524   /* Checking whether a class assignment is desired is quite complicated and
10525      needed at two locations, so do it once only before the information is
10526      needed.  */
10527   lhs_attr = gfc_expr_attr (expr1);
10528   is_poly_assign = (use_vptr_copy || lhs_attr.pointer
10529 		    || (lhs_attr.allocatable && !lhs_attr.dimension))
10530 		   && (expr1->ts.type == BT_CLASS
10531 		       || gfc_is_class_array_ref (expr1, NULL)
10532 		       || gfc_is_class_scalar_expr (expr1)
10533 		       || gfc_is_class_array_ref (expr2, NULL)
10534 		       || gfc_is_class_scalar_expr (expr2));
10535 
10536 
10537   /* Only analyze the expressions for coarray properties, when in coarray-lib
10538      mode.  */
10539   if (flag_coarray == GFC_FCOARRAY_LIB)
10540     {
10541       lhs_caf_attr = gfc_caf_attr (expr1, false, &lhs_refs_comp);
10542       rhs_caf_attr = gfc_caf_attr (expr2, false, &rhs_refs_comp);
10543     }
10544 
10545   if (lss != gfc_ss_terminator)
10546     {
10547       /* The assignment needs scalarization.  */
10548       lss_section = lss;
10549 
10550       /* Find a non-scalar SS from the lhs.  */
10551       while (lss_section != gfc_ss_terminator
10552 	     && lss_section->info->type != GFC_SS_SECTION)
10553 	lss_section = lss_section->next;
10554 
10555       gcc_assert (lss_section != gfc_ss_terminator);
10556 
10557       /* Initialize the scalarizer.  */
10558       gfc_init_loopinfo (&loop);
10559 
10560       /* Walk the rhs.  */
10561       rss = gfc_walk_expr (expr2);
10562       if (rss == gfc_ss_terminator)
10563 	/* The rhs is scalar.  Add a ss for the expression.  */
10564 	rss = gfc_get_scalar_ss (gfc_ss_terminator, expr2);
10565       /* When doing a class assign, then the handle to the rhs needs to be a
10566 	 pointer to allow for polymorphism.  */
10567       if (is_poly_assign && expr2->rank == 0 && !UNLIMITED_POLY (expr2))
10568 	rss->info->type = GFC_SS_REFERENCE;
10569 
10570       rss->no_bounds_check = expr2->no_bounds_check;
10571       /* Associate the SS with the loop.  */
10572       gfc_add_ss_to_loop (&loop, lss);
10573       gfc_add_ss_to_loop (&loop, rss);
10574 
10575       /* Calculate the bounds of the scalarization.  */
10576       gfc_conv_ss_startstride (&loop);
10577       /* Enable loop reversal.  */
10578       for (n = 0; n < GFC_MAX_DIMENSIONS; n++)
10579 	loop.reverse[n] = GFC_ENABLE_REVERSE;
10580       /* Resolve any data dependencies in the statement.  */
10581       if (may_alias)
10582 	gfc_conv_resolve_dependencies (&loop, lss, rss);
10583       /* Setup the scalarizing loops.  */
10584       gfc_conv_loop_setup (&loop, &expr2->where);
10585 
10586       /* Setup the gfc_se structures.  */
10587       gfc_copy_loopinfo_to_se (&lse, &loop);
10588       gfc_copy_loopinfo_to_se (&rse, &loop);
10589 
10590       rse.ss = rss;
10591       gfc_mark_ss_chain_used (rss, 1);
10592       if (loop.temp_ss == NULL)
10593 	{
10594 	  lse.ss = lss;
10595 	  gfc_mark_ss_chain_used (lss, 1);
10596 	}
10597       else
10598 	{
10599 	  lse.ss = loop.temp_ss;
10600 	  gfc_mark_ss_chain_used (lss, 3);
10601 	  gfc_mark_ss_chain_used (loop.temp_ss, 3);
10602 	}
10603 
10604       /* Allow the scalarizer to workshare array assignments.  */
10605       if ((ompws_flags & (OMPWS_WORKSHARE_FLAG | OMPWS_SCALARIZER_BODY))
10606 	  == OMPWS_WORKSHARE_FLAG
10607 	  && loop.temp_ss == NULL)
10608 	{
10609 	  maybe_workshare = true;
10610 	  ompws_flags |= OMPWS_SCALARIZER_WS | OMPWS_SCALARIZER_BODY;
10611 	}
10612 
10613       /* Start the scalarized loop body.  */
10614       gfc_start_scalarized_body (&loop, &body);
10615     }
10616   else
10617     gfc_init_block (&body);
10618 
10619   l_is_temp = (lss != gfc_ss_terminator && loop.temp_ss != NULL);
10620 
10621   /* Translate the expression.  */
10622   rse.want_coarray = flag_coarray == GFC_FCOARRAY_LIB && init_flag
10623       && lhs_caf_attr.codimension;
10624   gfc_conv_expr (&rse, expr2);
10625 
10626   /* Deal with the case of a scalar class function assigned to a derived type.  */
10627   if (gfc_is_alloc_class_scalar_function (expr2)
10628       && expr1->ts.type == BT_DERIVED)
10629     {
10630       rse.expr = gfc_class_data_get (rse.expr);
10631       rse.expr = build_fold_indirect_ref_loc (input_location, rse.expr);
10632     }
10633 
10634   /* Stabilize a string length for temporaries.  */
10635   if (expr2->ts.type == BT_CHARACTER && !expr1->ts.deferred
10636       && !(VAR_P (rse.string_length)
10637 	   || TREE_CODE (rse.string_length) == PARM_DECL
10638 	   || TREE_CODE (rse.string_length) == INDIRECT_REF))
10639     string_length = gfc_evaluate_now (rse.string_length, &rse.pre);
10640   else if (expr2->ts.type == BT_CHARACTER)
10641     {
10642       if (expr1->ts.deferred
10643 	  && gfc_expr_attr (expr1).allocatable
10644 	  && gfc_check_dependency (expr1, expr2, true))
10645 	rse.string_length =
10646 	  gfc_evaluate_now_function_scope (rse.string_length, &rse.pre);
10647       string_length = rse.string_length;
10648     }
10649   else
10650     string_length = NULL_TREE;
10651 
10652   if (l_is_temp)
10653     {
10654       gfc_conv_tmp_array_ref (&lse);
10655       if (expr2->ts.type == BT_CHARACTER)
10656 	lse.string_length = string_length;
10657     }
10658   else
10659     {
10660       gfc_conv_expr (&lse, expr1);
10661       if (gfc_option.rtcheck & GFC_RTCHECK_MEM
10662 	  && !init_flag
10663 	  && gfc_expr_attr (expr1).allocatable
10664 	  && expr1->rank
10665 	  && !expr2->rank)
10666 	{
10667 	  tree cond;
10668 	  const char* msg;
10669 
10670 	  tmp = INDIRECT_REF_P (lse.expr)
10671 	      ? gfc_build_addr_expr (NULL_TREE, lse.expr) : lse.expr;
10672 
10673 	  /* We should only get array references here.  */
10674 	  gcc_assert (TREE_CODE (tmp) == POINTER_PLUS_EXPR
10675 		      || TREE_CODE (tmp) == ARRAY_REF);
10676 
10677 	  /* 'tmp' is either the pointer to the array(POINTER_PLUS_EXPR)
10678 	     or the array itself(ARRAY_REF).  */
10679 	  tmp = TREE_OPERAND (tmp, 0);
10680 
10681 	  /* Provide the address of the array.  */
10682 	  if (TREE_CODE (lse.expr) == ARRAY_REF)
10683 	    tmp = gfc_build_addr_expr (NULL_TREE, tmp);
10684 
10685 	  cond = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
10686 				  tmp, build_int_cst (TREE_TYPE (tmp), 0));
10687 	  msg = _("Assignment of scalar to unallocated array");
10688 	  gfc_trans_runtime_check (true, false, cond, &loop.pre,
10689 				   &expr1->where, msg);
10690 	}
10691 
10692       /* Deallocate the lhs parameterized components if required.  */
10693       if (dealloc && expr2->expr_type == EXPR_FUNCTION
10694 	  && !expr1->symtree->n.sym->attr.associate_var)
10695 	{
10696 	  if (expr1->ts.type == BT_DERIVED
10697 	      && expr1->ts.u.derived
10698 	      && expr1->ts.u.derived->attr.pdt_type)
10699 	    {
10700 	      tmp = gfc_deallocate_pdt_comp (expr1->ts.u.derived, lse.expr,
10701 					     expr1->rank);
10702 	      gfc_add_expr_to_block (&lse.pre, tmp);
10703 	    }
10704 	  else if (expr1->ts.type == BT_CLASS
10705 		   && CLASS_DATA (expr1)->ts.u.derived
10706 		   && CLASS_DATA (expr1)->ts.u.derived->attr.pdt_type)
10707 	    {
10708 	      tmp = gfc_class_data_get (lse.expr);
10709 	      tmp = gfc_deallocate_pdt_comp (CLASS_DATA (expr1)->ts.u.derived,
10710 					     tmp, expr1->rank);
10711 	      gfc_add_expr_to_block (&lse.pre, tmp);
10712 	    }
10713 	}
10714     }
10715 
10716   /* Assignments of scalar derived types with allocatable components
10717      to arrays must be done with a deep copy and the rhs temporary
10718      must have its components deallocated afterwards.  */
10719   scalar_to_array = (expr2->ts.type == BT_DERIVED
10720 		       && expr2->ts.u.derived->attr.alloc_comp
10721 		       && !gfc_expr_is_variable (expr2)
10722 		       && expr1->rank && !expr2->rank);
10723   scalar_to_array |= (expr1->ts.type == BT_DERIVED
10724 				    && expr1->rank
10725 				    && expr1->ts.u.derived->attr.alloc_comp
10726 				    && gfc_is_alloc_class_scalar_function (expr2));
10727   if (scalar_to_array && dealloc)
10728     {
10729       tmp = gfc_deallocate_alloc_comp_no_caf (expr2->ts.u.derived, rse.expr, 0);
10730       gfc_prepend_expr_to_block (&loop.post, tmp);
10731     }
10732 
10733   /* When assigning a character function result to a deferred-length variable,
10734      the function call must happen before the (re)allocation of the lhs -
10735      otherwise the character length of the result is not known.
10736      NOTE 1: This relies on having the exact dependence of the length type
10737      parameter available to the caller; gfortran saves it in the .mod files.
10738      NOTE 2: Vector array references generate an index temporary that must
10739      not go outside the loop. Otherwise, variables should not generate
10740      a pre block.
10741      NOTE 3: The concatenation operation generates a temporary pointer,
10742      whose allocation must go to the innermost loop.
10743      NOTE 4: Elemental functions may generate a temporary, too.  */
10744   if (flag_realloc_lhs
10745       && expr2->ts.type == BT_CHARACTER && expr1->ts.deferred
10746       && !(lss != gfc_ss_terminator
10747 	   && rss != gfc_ss_terminator
10748 	   && ((expr2->expr_type == EXPR_VARIABLE && expr2->rank)
10749 	       || (expr2->expr_type == EXPR_FUNCTION
10750 		   && expr2->value.function.esym != NULL
10751 		   && expr2->value.function.esym->attr.elemental)
10752 	       || (expr2->expr_type == EXPR_FUNCTION
10753 		   && expr2->value.function.isym != NULL
10754 		   && expr2->value.function.isym->elemental)
10755 	       || (expr2->expr_type == EXPR_OP
10756 		   && expr2->value.op.op == INTRINSIC_CONCAT))))
10757     gfc_add_block_to_block (&block, &rse.pre);
10758 
10759   /* Nullify the allocatable components corresponding to those of the lhs
10760      derived type, so that the finalization of the function result does not
10761      affect the lhs of the assignment. Prepend is used to ensure that the
10762      nullification occurs before the call to the finalizer. In the case of
10763      a scalar to array assignment, this is done in gfc_trans_scalar_assign
10764      as part of the deep copy.  */
10765   if (!scalar_to_array && expr1->ts.type == BT_DERIVED
10766 		       && (gfc_is_class_array_function (expr2)
10767 			   || gfc_is_alloc_class_scalar_function (expr2)))
10768     {
10769       tmp = rse.expr;
10770       tmp = gfc_nullify_alloc_comp (expr1->ts.u.derived, rse.expr, 0);
10771       gfc_prepend_expr_to_block (&rse.post, tmp);
10772       if (lss != gfc_ss_terminator && rss == gfc_ss_terminator)
10773 	gfc_add_block_to_block (&loop.post, &rse.post);
10774     }
10775 
10776   tmp = NULL_TREE;
10777 
10778   if (is_poly_assign)
10779     tmp = trans_class_assignment (&body, expr1, expr2, &lse, &rse,
10780 				  use_vptr_copy || (lhs_attr.allocatable
10781 						    && !lhs_attr.dimension),
10782 				  flag_realloc_lhs && !lhs_attr.pointer);
10783   else if (flag_coarray == GFC_FCOARRAY_LIB
10784 	   && lhs_caf_attr.codimension && rhs_caf_attr.codimension
10785 	   && ((lhs_caf_attr.allocatable && lhs_refs_comp)
10786 	       || (rhs_caf_attr.allocatable && rhs_refs_comp)))
10787     {
10788       /* Only detour to caf_send[get][_by_ref] () when the lhs or rhs is an
10789 	 allocatable component, because those need to be accessed via the
10790 	 caf-runtime.  No need to check for coindexes here, because resolve
10791 	 has rewritten those already.  */
10792       gfc_code code;
10793       gfc_actual_arglist a1, a2;
10794       /* Clear the structures to prevent accessing garbage.  */
10795       memset (&code, '\0', sizeof (gfc_code));
10796       memset (&a1, '\0', sizeof (gfc_actual_arglist));
10797       memset (&a2, '\0', sizeof (gfc_actual_arglist));
10798       a1.expr = expr1;
10799       a1.next = &a2;
10800       a2.expr = expr2;
10801       a2.next = NULL;
10802       code.ext.actual = &a1;
10803       code.resolved_isym = gfc_intrinsic_subroutine_by_id (GFC_ISYM_CAF_SEND);
10804       tmp = gfc_conv_intrinsic_subroutine (&code);
10805     }
10806   else if (!is_poly_assign && expr2->must_finalize
10807 	   && expr1->ts.type == BT_CLASS
10808 	   && expr2->ts.type == BT_CLASS)
10809     {
10810       /* This case comes about when the scalarizer provides array element
10811 	 references. Use the vptr copy function, since this does a deep
10812 	 copy of allocatable components, without which the finalizer call */
10813       tmp = gfc_get_vptr_from_expr (rse.expr);
10814       if (tmp != NULL_TREE)
10815 	{
10816 	  tree fcn = gfc_vptr_copy_get (tmp);
10817 	  if (POINTER_TYPE_P (TREE_TYPE (fcn)))
10818 	    fcn = build_fold_indirect_ref_loc (input_location, fcn);
10819 	  tmp = build_call_expr_loc (input_location,
10820 				     fcn, 2,
10821 				     gfc_build_addr_expr (NULL, rse.expr),
10822 				     gfc_build_addr_expr (NULL, lse.expr));
10823 	}
10824     }
10825 
10826   /* If nothing else works, do it the old fashioned way!  */
10827   if (tmp == NULL_TREE)
10828     tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts,
10829 				   gfc_expr_is_variable (expr2)
10830 				   || scalar_to_array
10831 				   || expr2->expr_type == EXPR_ARRAY,
10832 				   !(l_is_temp || init_flag) && dealloc,
10833 				   expr1->symtree->n.sym->attr.codimension);
10834 
10835   /* Add the pre blocks to the body.  */
10836   gfc_add_block_to_block (&body, &rse.pre);
10837   gfc_add_block_to_block (&body, &lse.pre);
10838   gfc_add_expr_to_block (&body, tmp);
10839   /* Add the post blocks to the body.  */
10840   gfc_add_block_to_block (&body, &rse.post);
10841   gfc_add_block_to_block (&body, &lse.post);
10842 
10843   if (lss == gfc_ss_terminator)
10844     {
10845       /* F2003: Add the code for reallocation on assignment.  */
10846       if (flag_realloc_lhs && is_scalar_reallocatable_lhs (expr1)
10847 	  && !is_poly_assign)
10848 	alloc_scalar_allocatable_for_assignment (&block, string_length,
10849 						 expr1, expr2);
10850 
10851       /* Use the scalar assignment as is.  */
10852       gfc_add_block_to_block (&block, &body);
10853     }
10854   else
10855     {
10856       gcc_assert (lse.ss == gfc_ss_terminator
10857 		  && rse.ss == gfc_ss_terminator);
10858 
10859       if (l_is_temp)
10860 	{
10861 	  gfc_trans_scalarized_loop_boundary (&loop, &body);
10862 
10863 	  /* We need to copy the temporary to the actual lhs.  */
10864 	  gfc_init_se (&lse, NULL);
10865 	  gfc_init_se (&rse, NULL);
10866 	  gfc_copy_loopinfo_to_se (&lse, &loop);
10867 	  gfc_copy_loopinfo_to_se (&rse, &loop);
10868 
10869 	  rse.ss = loop.temp_ss;
10870 	  lse.ss = lss;
10871 
10872 	  gfc_conv_tmp_array_ref (&rse);
10873 	  gfc_conv_expr (&lse, expr1);
10874 
10875 	  gcc_assert (lse.ss == gfc_ss_terminator
10876 		      && rse.ss == gfc_ss_terminator);
10877 
10878 	  if (expr2->ts.type == BT_CHARACTER)
10879 	    rse.string_length = string_length;
10880 
10881 	  tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts,
10882 					 false, dealloc);
10883 	  gfc_add_expr_to_block (&body, tmp);
10884 	}
10885 
10886       /* F2003: Allocate or reallocate lhs of allocatable array.  */
10887       if (flag_realloc_lhs
10888 	  && gfc_is_reallocatable_lhs (expr1)
10889 	  && expr2->rank
10890 	  && !is_runtime_conformable (expr1, expr2))
10891 	{
10892 	  realloc_lhs_warning (expr1->ts.type, true, &expr1->where);
10893 	  ompws_flags &= ~OMPWS_SCALARIZER_WS;
10894 	  tmp = gfc_alloc_allocatable_for_assignment (&loop, expr1, expr2);
10895 	  if (tmp != NULL_TREE)
10896 	    gfc_add_expr_to_block (&loop.code[expr1->rank - 1], tmp);
10897 	}
10898 
10899       if (maybe_workshare)
10900 	ompws_flags &= ~OMPWS_SCALARIZER_BODY;
10901 
10902       /* Generate the copying loops.  */
10903       gfc_trans_scalarizing_loops (&loop, &body);
10904 
10905       /* Wrap the whole thing up.  */
10906       gfc_add_block_to_block (&block, &loop.pre);
10907       gfc_add_block_to_block (&block, &loop.post);
10908 
10909       gfc_cleanup_loop (&loop);
10910     }
10911 
10912   return gfc_finish_block (&block);
10913 }
10914 
10915 
10916 /* Check whether EXPR is a copyable array.  */
10917 
10918 static bool
10919 copyable_array_p (gfc_expr * expr)
10920 {
10921   if (expr->expr_type != EXPR_VARIABLE)
10922     return false;
10923 
10924   /* First check it's an array.  */
10925   if (expr->rank < 1 || !expr->ref || expr->ref->next)
10926     return false;
10927 
10928   if (!gfc_full_array_ref_p (expr->ref, NULL))
10929     return false;
10930 
10931   /* Next check that it's of a simple enough type.  */
10932   switch (expr->ts.type)
10933     {
10934     case BT_INTEGER:
10935     case BT_REAL:
10936     case BT_COMPLEX:
10937     case BT_LOGICAL:
10938       return true;
10939 
10940     case BT_CHARACTER:
10941       return false;
10942 
10943     case_bt_struct:
10944       return !expr->ts.u.derived->attr.alloc_comp;
10945 
10946     default:
10947       break;
10948     }
10949 
10950   return false;
10951 }
10952 
10953 /* Translate an assignment.  */
10954 
10955 tree
10956 gfc_trans_assignment (gfc_expr * expr1, gfc_expr * expr2, bool init_flag,
10957 		      bool dealloc, bool use_vptr_copy, bool may_alias)
10958 {
10959   tree tmp;
10960 
10961   /* Special case a single function returning an array.  */
10962   if (expr2->expr_type == EXPR_FUNCTION && expr2->rank > 0)
10963     {
10964       tmp = gfc_trans_arrayfunc_assign (expr1, expr2);
10965       if (tmp)
10966 	return tmp;
10967     }
10968 
10969   /* Special case assigning an array to zero.  */
10970   if (copyable_array_p (expr1)
10971       && is_zero_initializer_p (expr2))
10972     {
10973       tmp = gfc_trans_zero_assign (expr1);
10974       if (tmp)
10975         return tmp;
10976     }
10977 
10978   /* Special case copying one array to another.  */
10979   if (copyable_array_p (expr1)
10980       && copyable_array_p (expr2)
10981       && gfc_compare_types (&expr1->ts, &expr2->ts)
10982       && !gfc_check_dependency (expr1, expr2, 0))
10983     {
10984       tmp = gfc_trans_array_copy (expr1, expr2);
10985       if (tmp)
10986         return tmp;
10987     }
10988 
10989   /* Special case initializing an array from a constant array constructor.  */
10990   if (copyable_array_p (expr1)
10991       && expr2->expr_type == EXPR_ARRAY
10992       && gfc_compare_types (&expr1->ts, &expr2->ts))
10993     {
10994       tmp = gfc_trans_array_constructor_copy (expr1, expr2);
10995       if (tmp)
10996 	return tmp;
10997     }
10998 
10999   if (UNLIMITED_POLY (expr1) && expr1->rank
11000       && expr2->ts.type != BT_CLASS)
11001     use_vptr_copy = true;
11002 
11003   /* Fallback to the scalarizer to generate explicit loops.  */
11004   return gfc_trans_assignment_1 (expr1, expr2, init_flag, dealloc,
11005 				 use_vptr_copy, may_alias);
11006 }
11007 
11008 tree
11009 gfc_trans_init_assign (gfc_code * code)
11010 {
11011   return gfc_trans_assignment (code->expr1, code->expr2, true, false, true);
11012 }
11013 
11014 tree
11015 gfc_trans_assign (gfc_code * code)
11016 {
11017   return gfc_trans_assignment (code->expr1, code->expr2, false, true);
11018 }
11019