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