xref: /netbsd-src/external/gpl3/gcc/dist/gcc/fortran/trans-expr.cc (revision 0a3071956a3a9fdebdbf7f338cf2d439b45fc728)
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       se->string_length = NULL_TREE;
2858       break;
2859 
2860     case INQUIRY_LEN:
2861       res = fold_convert (gfc_typenode_for_spec (&expr->ts),
2862 			  se->string_length);
2863       se->string_length = NULL_TREE;
2864       break;
2865 
2866     default:
2867       gcc_unreachable ();
2868     }
2869   se->expr = res;
2870 }
2871 
2872 /* Dereference VAR where needed if it is a pointer, reference, etc.
2873    according to Fortran semantics.  */
2874 
2875 tree
gfc_maybe_dereference_var(gfc_symbol * sym,tree var,bool descriptor_only_p,bool is_classarray)2876 gfc_maybe_dereference_var (gfc_symbol *sym, tree var, bool descriptor_only_p,
2877 			   bool is_classarray)
2878 {
2879   if (!POINTER_TYPE_P (TREE_TYPE (var)))
2880     return var;
2881   if (is_CFI_desc (sym, NULL))
2882     return build_fold_indirect_ref_loc (input_location, var);
2883 
2884   /* Characters are entirely different from other types, they are treated
2885      separately.  */
2886   if (sym->ts.type == BT_CHARACTER)
2887     {
2888       /* Dereference character pointer dummy arguments
2889 	 or results.  */
2890       if ((sym->attr.pointer || sym->attr.allocatable
2891 	   || (sym->as && sym->as->type == AS_ASSUMED_RANK))
2892 	  && (sym->attr.dummy
2893 	      || sym->attr.function
2894 	      || sym->attr.result))
2895 	var = build_fold_indirect_ref_loc (input_location, var);
2896     }
2897   else if (!sym->attr.value)
2898     {
2899       /* Dereference temporaries for class array dummy arguments.  */
2900       if (sym->attr.dummy && is_classarray
2901 	  && GFC_ARRAY_TYPE_P (TREE_TYPE (var)))
2902 	{
2903 	  if (!descriptor_only_p)
2904 	    var = GFC_DECL_SAVED_DESCRIPTOR (var);
2905 
2906 	  var = build_fold_indirect_ref_loc (input_location, var);
2907 	}
2908 
2909       /* Dereference non-character scalar dummy arguments.  */
2910       if (sym->attr.dummy && !sym->attr.dimension
2911 	  && !(sym->attr.codimension && sym->attr.allocatable)
2912 	  && (sym->ts.type != BT_CLASS
2913 	      || (!CLASS_DATA (sym)->attr.dimension
2914 		  && !(CLASS_DATA (sym)->attr.codimension
2915 		       && CLASS_DATA (sym)->attr.allocatable))))
2916 	var = build_fold_indirect_ref_loc (input_location, var);
2917 
2918       /* Dereference scalar hidden result.  */
2919       if (flag_f2c && sym->ts.type == BT_COMPLEX
2920 	  && (sym->attr.function || sym->attr.result)
2921 	  && !sym->attr.dimension && !sym->attr.pointer
2922 	  && !sym->attr.always_explicit)
2923 	var = build_fold_indirect_ref_loc (input_location, var);
2924 
2925       /* Dereference non-character, non-class pointer variables.
2926 	 These must be dummies, results, or scalars.  */
2927       if (!is_classarray
2928 	  && (sym->attr.pointer || sym->attr.allocatable
2929 	      || gfc_is_associate_pointer (sym)
2930 	      || (sym->as && sym->as->type == AS_ASSUMED_RANK))
2931 	  && (sym->attr.dummy
2932 	      || sym->attr.function
2933 	      || sym->attr.result
2934 	      || (!sym->attr.dimension
2935 		  && (!sym->attr.codimension || !sym->attr.allocatable))))
2936 	var = build_fold_indirect_ref_loc (input_location, var);
2937       /* Now treat the class array pointer variables accordingly.  */
2938       else if (sym->ts.type == BT_CLASS
2939 	       && sym->attr.dummy
2940 	       && (CLASS_DATA (sym)->attr.dimension
2941 		   || CLASS_DATA (sym)->attr.codimension)
2942 	       && ((CLASS_DATA (sym)->as
2943 		    && CLASS_DATA (sym)->as->type == AS_ASSUMED_RANK)
2944 		   || CLASS_DATA (sym)->attr.allocatable
2945 		   || CLASS_DATA (sym)->attr.class_pointer))
2946 	var = build_fold_indirect_ref_loc (input_location, var);
2947       /* And the case where a non-dummy, non-result, non-function,
2948 	 non-allocable and non-pointer classarray is present.  This case was
2949 	 previously covered by the first if, but with introducing the
2950 	 condition !is_classarray there, that case has to be covered
2951 	 explicitly.  */
2952       else if (sym->ts.type == BT_CLASS
2953 	       && !sym->attr.dummy
2954 	       && !sym->attr.function
2955 	       && !sym->attr.result
2956 	       && (CLASS_DATA (sym)->attr.dimension
2957 		   || CLASS_DATA (sym)->attr.codimension)
2958 	       && (sym->assoc
2959 		   || !CLASS_DATA (sym)->attr.allocatable)
2960 	       && !CLASS_DATA (sym)->attr.class_pointer)
2961 	var = build_fold_indirect_ref_loc (input_location, var);
2962     }
2963 
2964   return var;
2965 }
2966 
2967 /* Return the contents of a variable. Also handles reference/pointer
2968    variables (all Fortran pointer references are implicit).  */
2969 
2970 static void
gfc_conv_variable(gfc_se * se,gfc_expr * expr)2971 gfc_conv_variable (gfc_se * se, gfc_expr * expr)
2972 {
2973   gfc_ss *ss;
2974   gfc_ref *ref;
2975   gfc_symbol *sym;
2976   tree parent_decl = NULL_TREE;
2977   int parent_flag;
2978   bool return_value;
2979   bool alternate_entry;
2980   bool entry_master;
2981   bool is_classarray;
2982   bool first_time = true;
2983 
2984   sym = expr->symtree->n.sym;
2985   is_classarray = IS_CLASS_ARRAY (sym);
2986   ss = se->ss;
2987   if (ss != NULL)
2988     {
2989       gfc_ss_info *ss_info = ss->info;
2990 
2991       /* Check that something hasn't gone horribly wrong.  */
2992       gcc_assert (ss != gfc_ss_terminator);
2993       gcc_assert (ss_info->expr == expr);
2994 
2995       /* A scalarized term.  We already know the descriptor.  */
2996       se->expr = ss_info->data.array.descriptor;
2997       se->string_length = ss_info->string_length;
2998       ref = ss_info->data.array.ref;
2999       if (ref)
3000 	gcc_assert (ref->type == REF_ARRAY
3001 		    && ref->u.ar.type != AR_ELEMENT);
3002       else
3003 	gfc_conv_tmp_array_ref (se);
3004     }
3005   else
3006     {
3007       tree se_expr = NULL_TREE;
3008 
3009       se->expr = gfc_get_symbol_decl (sym);
3010 
3011       /* Deal with references to a parent results or entries by storing
3012 	 the current_function_decl and moving to the parent_decl.  */
3013       return_value = sym->attr.function && sym->result == sym;
3014       alternate_entry = sym->attr.function && sym->attr.entry
3015 			&& sym->result == sym;
3016       entry_master = sym->attr.result
3017 		     && sym->ns->proc_name->attr.entry_master
3018 		     && !gfc_return_by_reference (sym->ns->proc_name);
3019       if (current_function_decl)
3020 	parent_decl = DECL_CONTEXT (current_function_decl);
3021 
3022       if ((se->expr == parent_decl && return_value)
3023 	   || (sym->ns && sym->ns->proc_name
3024 	       && parent_decl
3025 	       && sym->ns->proc_name->backend_decl == parent_decl
3026 	       && (alternate_entry || entry_master)))
3027 	parent_flag = 1;
3028       else
3029 	parent_flag = 0;
3030 
3031       /* Special case for assigning the return value of a function.
3032 	 Self recursive functions must have an explicit return value.  */
3033       if (return_value && (se->expr == current_function_decl || parent_flag))
3034 	se_expr = gfc_get_fake_result_decl (sym, parent_flag);
3035 
3036       /* Similarly for alternate entry points.  */
3037       else if (alternate_entry
3038 	       && (sym->ns->proc_name->backend_decl == current_function_decl
3039 		   || parent_flag))
3040 	{
3041 	  gfc_entry_list *el = NULL;
3042 
3043 	  for (el = sym->ns->entries; el; el = el->next)
3044 	    if (sym == el->sym)
3045 	      {
3046 		se_expr = gfc_get_fake_result_decl (sym, parent_flag);
3047 		break;
3048 	      }
3049 	}
3050 
3051       else if (entry_master
3052 	       && (sym->ns->proc_name->backend_decl == current_function_decl
3053 		   || parent_flag))
3054 	se_expr = gfc_get_fake_result_decl (sym, parent_flag);
3055 
3056       if (se_expr)
3057 	se->expr = se_expr;
3058 
3059       /* Procedure actual arguments.  Look out for temporary variables
3060 	 with the same attributes as function values.  */
3061       else if (!sym->attr.temporary
3062 	       && sym->attr.flavor == FL_PROCEDURE
3063 	       && se->expr != current_function_decl)
3064 	{
3065 	  if (!sym->attr.dummy && !sym->attr.proc_pointer)
3066 	    {
3067 	      gcc_assert (TREE_CODE (se->expr) == FUNCTION_DECL);
3068 	      se->expr = gfc_build_addr_expr (NULL_TREE, se->expr);
3069 	    }
3070 	  return;
3071 	}
3072 
3073       /* Dereference the expression, where needed.  */
3074       se->expr = gfc_maybe_dereference_var (sym, se->expr, se->descriptor_only,
3075 					    is_classarray);
3076 
3077       ref = expr->ref;
3078     }
3079 
3080   /* For character variables, also get the length.  */
3081   if (sym->ts.type == BT_CHARACTER)
3082     {
3083       /* If the character length of an entry isn't set, get the length from
3084          the master function instead.  */
3085       if (sym->attr.entry && !sym->ts.u.cl->backend_decl)
3086         se->string_length = sym->ns->proc_name->ts.u.cl->backend_decl;
3087       else
3088         se->string_length = sym->ts.u.cl->backend_decl;
3089       gcc_assert (se->string_length);
3090     }
3091 
3092   gfc_typespec *ts = &sym->ts;
3093   while (ref)
3094     {
3095       switch (ref->type)
3096 	{
3097 	case REF_ARRAY:
3098 	  /* Return the descriptor if that's what we want and this is an array
3099 	     section reference.  */
3100 	  if (se->descriptor_only && ref->u.ar.type != AR_ELEMENT)
3101 	    return;
3102 /* TODO: Pointers to single elements of array sections, eg elemental subs.  */
3103 	  /* Return the descriptor for array pointers and allocations.  */
3104 	  if (se->want_pointer
3105 	      && ref->next == NULL && (se->descriptor_only))
3106 	    return;
3107 
3108 	  gfc_conv_array_ref (se, &ref->u.ar, expr, &expr->where);
3109 	  /* Return a pointer to an element.  */
3110 	  break;
3111 
3112 	case REF_COMPONENT:
3113 	  ts = &ref->u.c.component->ts;
3114 	  if (first_time && is_classarray && sym->attr.dummy
3115 	      && se->descriptor_only
3116 	      && !CLASS_DATA (sym)->attr.allocatable
3117 	      && !CLASS_DATA (sym)->attr.class_pointer
3118 	      && CLASS_DATA (sym)->as
3119 	      && CLASS_DATA (sym)->as->type != AS_ASSUMED_RANK
3120 	      && strcmp ("_data", ref->u.c.component->name) == 0)
3121 	    /* Skip the first ref of a _data component, because for class
3122 	       arrays that one is already done by introducing a temporary
3123 	       array descriptor.  */
3124 	    break;
3125 
3126 	  if (ref->u.c.sym->attr.extension)
3127 	    conv_parent_component_references (se, ref);
3128 
3129 	  gfc_conv_component_ref (se, ref);
3130 	  if (!ref->next && ref->u.c.sym->attr.codimension
3131 	      && se->want_pointer && se->descriptor_only)
3132 	    return;
3133 
3134 	  break;
3135 
3136 	case REF_SUBSTRING:
3137 	  gfc_conv_substring (se, ref, expr->ts.kind,
3138 			      expr->symtree->name, &expr->where);
3139 	  break;
3140 
3141 	case REF_INQUIRY:
3142 	  conv_inquiry (se, ref, expr, ts);
3143 	  break;
3144 
3145 	default:
3146 	  gcc_unreachable ();
3147 	  break;
3148 	}
3149       first_time = false;
3150       ref = ref->next;
3151     }
3152   /* Pointer assignment, allocation or pass by reference.  Arrays are handled
3153      separately.  */
3154   if (se->want_pointer)
3155     {
3156       if (expr->ts.type == BT_CHARACTER && !gfc_is_proc_ptr_comp (expr))
3157 	gfc_conv_string_parameter (se);
3158       else
3159 	se->expr = gfc_build_addr_expr (NULL_TREE, se->expr);
3160     }
3161 }
3162 
3163 
3164 /* Unary ops are easy... Or they would be if ! was a valid op.  */
3165 
3166 static void
gfc_conv_unary_op(enum tree_code code,gfc_se * se,gfc_expr * expr)3167 gfc_conv_unary_op (enum tree_code code, gfc_se * se, gfc_expr * expr)
3168 {
3169   gfc_se operand;
3170   tree type;
3171 
3172   gcc_assert (expr->ts.type != BT_CHARACTER);
3173   /* Initialize the operand.  */
3174   gfc_init_se (&operand, se);
3175   gfc_conv_expr_val (&operand, expr->value.op.op1);
3176   gfc_add_block_to_block (&se->pre, &operand.pre);
3177 
3178   type = gfc_typenode_for_spec (&expr->ts);
3179 
3180   /* TRUTH_NOT_EXPR is not a "true" unary operator in GCC.
3181      We must convert it to a compare to 0 (e.g. EQ_EXPR (op1, 0)).
3182      All other unary operators have an equivalent GIMPLE unary operator.  */
3183   if (code == TRUTH_NOT_EXPR)
3184     se->expr = fold_build2_loc (input_location, EQ_EXPR, type, operand.expr,
3185 				build_int_cst (type, 0));
3186   else
3187     se->expr = fold_build1_loc (input_location, code, type, operand.expr);
3188 
3189 }
3190 
3191 /* Expand power operator to optimal multiplications when a value is raised
3192    to a constant integer n. See section 4.6.3, "Evaluation of Powers" of
3193    Donald E. Knuth, "Seminumerical Algorithms", Vol. 2, "The Art of Computer
3194    Programming", 3rd Edition, 1998.  */
3195 
3196 /* This code is mostly duplicated from expand_powi in the backend.
3197    We establish the "optimal power tree" lookup table with the defined size.
3198    The items in the table are the exponents used to calculate the index
3199    exponents. Any integer n less than the value can get an "addition chain",
3200    with the first node being one.  */
3201 #define POWI_TABLE_SIZE 256
3202 
3203 /* The table is from builtins.cc.  */
3204 static const unsigned char powi_table[POWI_TABLE_SIZE] =
3205   {
3206       0,   1,   1,   2,   2,   3,   3,   4,  /*   0 -   7 */
3207       4,   6,   5,   6,   6,  10,   7,   9,  /*   8 -  15 */
3208       8,  16,   9,  16,  10,  12,  11,  13,  /*  16 -  23 */
3209      12,  17,  13,  18,  14,  24,  15,  26,  /*  24 -  31 */
3210      16,  17,  17,  19,  18,  33,  19,  26,  /*  32 -  39 */
3211      20,  25,  21,  40,  22,  27,  23,  44,  /*  40 -  47 */
3212      24,  32,  25,  34,  26,  29,  27,  44,  /*  48 -  55 */
3213      28,  31,  29,  34,  30,  60,  31,  36,  /*  56 -  63 */
3214      32,  64,  33,  34,  34,  46,  35,  37,  /*  64 -  71 */
3215      36,  65,  37,  50,  38,  48,  39,  69,  /*  72 -  79 */
3216      40,  49,  41,  43,  42,  51,  43,  58,  /*  80 -  87 */
3217      44,  64,  45,  47,  46,  59,  47,  76,  /*  88 -  95 */
3218      48,  65,  49,  66,  50,  67,  51,  66,  /*  96 - 103 */
3219      52,  70,  53,  74,  54, 104,  55,  74,  /* 104 - 111 */
3220      56,  64,  57,  69,  58,  78,  59,  68,  /* 112 - 119 */
3221      60,  61,  61,  80,  62,  75,  63,  68,  /* 120 - 127 */
3222      64,  65,  65, 128,  66, 129,  67,  90,  /* 128 - 135 */
3223      68,  73,  69, 131,  70,  94,  71,  88,  /* 136 - 143 */
3224      72, 128,  73,  98,  74, 132,  75, 121,  /* 144 - 151 */
3225      76, 102,  77, 124,  78, 132,  79, 106,  /* 152 - 159 */
3226      80,  97,  81, 160,  82,  99,  83, 134,  /* 160 - 167 */
3227      84,  86,  85,  95,  86, 160,  87, 100,  /* 168 - 175 */
3228      88, 113,  89,  98,  90, 107,  91, 122,  /* 176 - 183 */
3229      92, 111,  93, 102,  94, 126,  95, 150,  /* 184 - 191 */
3230      96, 128,  97, 130,  98, 133,  99, 195,  /* 192 - 199 */
3231     100, 128, 101, 123, 102, 164, 103, 138,  /* 200 - 207 */
3232     104, 145, 105, 146, 106, 109, 107, 149,  /* 208 - 215 */
3233     108, 200, 109, 146, 110, 170, 111, 157,  /* 216 - 223 */
3234     112, 128, 113, 130, 114, 182, 115, 132,  /* 224 - 231 */
3235     116, 200, 117, 132, 118, 158, 119, 206,  /* 232 - 239 */
3236     120, 240, 121, 162, 122, 147, 123, 152,  /* 240 - 247 */
3237     124, 166, 125, 214, 126, 138, 127, 153,  /* 248 - 255 */
3238   };
3239 
3240 /* If n is larger than lookup table's max index, we use the "window
3241    method".  */
3242 #define POWI_WINDOW_SIZE 3
3243 
3244 /* Recursive function to expand the power operator. The temporary
3245    values are put in tmpvar. The function returns tmpvar[1] ** n.  */
3246 static tree
gfc_conv_powi(gfc_se * se,unsigned HOST_WIDE_INT n,tree * tmpvar)3247 gfc_conv_powi (gfc_se * se, unsigned HOST_WIDE_INT n, tree * tmpvar)
3248 {
3249   tree op0;
3250   tree op1;
3251   tree tmp;
3252   int digit;
3253 
3254   if (n < POWI_TABLE_SIZE)
3255     {
3256       if (tmpvar[n])
3257         return tmpvar[n];
3258 
3259       op0 = gfc_conv_powi (se, n - powi_table[n], tmpvar);
3260       op1 = gfc_conv_powi (se, powi_table[n], tmpvar);
3261     }
3262   else if (n & 1)
3263     {
3264       digit = n & ((1 << POWI_WINDOW_SIZE) - 1);
3265       op0 = gfc_conv_powi (se, n - digit, tmpvar);
3266       op1 = gfc_conv_powi (se, digit, tmpvar);
3267     }
3268   else
3269     {
3270       op0 = gfc_conv_powi (se, n >> 1, tmpvar);
3271       op1 = op0;
3272     }
3273 
3274   tmp = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (op0), op0, op1);
3275   tmp = gfc_evaluate_now (tmp, &se->pre);
3276 
3277   if (n < POWI_TABLE_SIZE)
3278     tmpvar[n] = tmp;
3279 
3280   return tmp;
3281 }
3282 
3283 
3284 /* Expand lhs ** rhs. rhs is a constant integer. If it expands successfully,
3285    return 1. Else return 0 and a call to runtime library functions
3286    will have to be built.  */
3287 static int
gfc_conv_cst_int_power(gfc_se * se,tree lhs,tree rhs)3288 gfc_conv_cst_int_power (gfc_se * se, tree lhs, tree rhs)
3289 {
3290   tree cond;
3291   tree tmp;
3292   tree type;
3293   tree vartmp[POWI_TABLE_SIZE];
3294   HOST_WIDE_INT m;
3295   unsigned HOST_WIDE_INT n;
3296   int sgn;
3297   wi::tree_to_wide_ref wrhs = wi::to_wide (rhs);
3298 
3299   /* If exponent is too large, we won't expand it anyway, so don't bother
3300      with large integer values.  */
3301   if (!wi::fits_shwi_p (wrhs))
3302     return 0;
3303 
3304   m = wrhs.to_shwi ();
3305   /* Use the wide_int's routine to reliably get the absolute value on all
3306      platforms.  Then convert it to a HOST_WIDE_INT like above.  */
3307   n = wi::abs (wrhs).to_shwi ();
3308 
3309   type = TREE_TYPE (lhs);
3310   sgn = tree_int_cst_sgn (rhs);
3311 
3312   if (((FLOAT_TYPE_P (type) && !flag_unsafe_math_optimizations)
3313        || optimize_size) && (m > 2 || m < -1))
3314     return 0;
3315 
3316   /* rhs == 0  */
3317   if (sgn == 0)
3318     {
3319       se->expr = gfc_build_const (type, integer_one_node);
3320       return 1;
3321     }
3322 
3323   /* If rhs < 0 and lhs is an integer, the result is -1, 0 or 1.  */
3324   if ((sgn == -1) && (TREE_CODE (type) == INTEGER_TYPE))
3325     {
3326       tmp = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
3327 			     lhs, build_int_cst (TREE_TYPE (lhs), -1));
3328       cond = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
3329 			      lhs, build_int_cst (TREE_TYPE (lhs), 1));
3330 
3331       /* If rhs is even,
3332 	 result = (lhs == 1 || lhs == -1) ? 1 : 0.  */
3333       if ((n & 1) == 0)
3334         {
3335 	  tmp = fold_build2_loc (input_location, TRUTH_OR_EXPR,
3336 				 logical_type_node, tmp, cond);
3337 	  se->expr = fold_build3_loc (input_location, COND_EXPR, type,
3338 				      tmp, build_int_cst (type, 1),
3339 				      build_int_cst (type, 0));
3340 	  return 1;
3341 	}
3342       /* If rhs is odd,
3343 	 result = (lhs == 1) ? 1 : (lhs == -1) ? -1 : 0.  */
3344       tmp = fold_build3_loc (input_location, COND_EXPR, type, tmp,
3345 			     build_int_cst (type, -1),
3346 			     build_int_cst (type, 0));
3347       se->expr = fold_build3_loc (input_location, COND_EXPR, type,
3348 				  cond, build_int_cst (type, 1), tmp);
3349       return 1;
3350     }
3351 
3352   memset (vartmp, 0, sizeof (vartmp));
3353   vartmp[1] = lhs;
3354   if (sgn == -1)
3355     {
3356       tmp = gfc_build_const (type, integer_one_node);
3357       vartmp[1] = fold_build2_loc (input_location, RDIV_EXPR, type, tmp,
3358 				   vartmp[1]);
3359     }
3360 
3361   se->expr = gfc_conv_powi (se, n, vartmp);
3362 
3363   return 1;
3364 }
3365 
3366 
3367 /* Power op (**).  Constant integer exponent has special handling.  */
3368 
3369 static void
gfc_conv_power_op(gfc_se * se,gfc_expr * expr)3370 gfc_conv_power_op (gfc_se * se, gfc_expr * expr)
3371 {
3372   tree gfc_int4_type_node;
3373   int kind;
3374   int ikind;
3375   int res_ikind_1, res_ikind_2;
3376   gfc_se lse;
3377   gfc_se rse;
3378   tree fndecl = NULL;
3379 
3380   gfc_init_se (&lse, se);
3381   gfc_conv_expr_val (&lse, expr->value.op.op1);
3382   lse.expr = gfc_evaluate_now (lse.expr, &lse.pre);
3383   gfc_add_block_to_block (&se->pre, &lse.pre);
3384 
3385   gfc_init_se (&rse, se);
3386   gfc_conv_expr_val (&rse, expr->value.op.op2);
3387   gfc_add_block_to_block (&se->pre, &rse.pre);
3388 
3389   if (expr->value.op.op2->ts.type == BT_INTEGER
3390       && expr->value.op.op2->expr_type == EXPR_CONSTANT)
3391     if (gfc_conv_cst_int_power (se, lse.expr, rse.expr))
3392       return;
3393 
3394   if (INTEGER_CST_P (lse.expr)
3395       && TREE_CODE (TREE_TYPE (rse.expr)) == INTEGER_TYPE)
3396     {
3397       wi::tree_to_wide_ref wlhs = wi::to_wide (lse.expr);
3398       HOST_WIDE_INT v, w;
3399       int kind, ikind, bit_size;
3400 
3401       v = wlhs.to_shwi ();
3402       w = abs (v);
3403 
3404       kind = expr->value.op.op1->ts.kind;
3405       ikind = gfc_validate_kind (BT_INTEGER, kind, false);
3406       bit_size = gfc_integer_kinds[ikind].bit_size;
3407 
3408       if (v == 1)
3409 	{
3410 	  /* 1**something is always 1.  */
3411 	  se->expr = build_int_cst (TREE_TYPE (lse.expr), 1);
3412 	  return;
3413 	}
3414       else if (v == -1)
3415 	{
3416 	  /* (-1)**n is 1 - ((n & 1) << 1) */
3417 	  tree type;
3418 	  tree tmp;
3419 
3420 	  type = TREE_TYPE (lse.expr);
3421 	  tmp = fold_build2_loc (input_location, BIT_AND_EXPR, type,
3422 				 rse.expr, build_int_cst (type, 1));
3423 	  tmp = fold_build2_loc (input_location, LSHIFT_EXPR, type,
3424 				 tmp, build_int_cst (type, 1));
3425 	  tmp = fold_build2_loc (input_location, MINUS_EXPR, type,
3426 				 build_int_cst (type, 1), tmp);
3427 	  se->expr = tmp;
3428 	  return;
3429 	}
3430       else if (w > 0 && ((w & (w-1)) == 0) && ((w >> (bit_size-1)) == 0))
3431 	{
3432 	  /* Here v is +/- 2**e.  The further simplification uses
3433 	     2**n = 1<<n, 4**n = 1<<(n+n), 8**n = 1 <<(3*n), 16**n =
3434 	     1<<(4*n), etc., but we have to make sure to return zero
3435 	     if the number of bits is too large. */
3436 	  tree lshift;
3437 	  tree type;
3438 	  tree shift;
3439 	  tree ge;
3440 	  tree cond;
3441 	  tree num_bits;
3442 	  tree cond2;
3443 	  tree tmp1;
3444 
3445 	  type = TREE_TYPE (lse.expr);
3446 
3447 	  if (w == 2)
3448 	    shift = rse.expr;
3449 	  else if (w == 4)
3450 	    shift = fold_build2_loc (input_location, PLUS_EXPR,
3451 				     TREE_TYPE (rse.expr),
3452 				       rse.expr, rse.expr);
3453 	  else
3454 	    {
3455 	      /* use popcount for fast log2(w) */
3456 	      int e = wi::popcount (w-1);
3457 	      shift = fold_build2_loc (input_location, MULT_EXPR,
3458 				       TREE_TYPE (rse.expr),
3459 				       build_int_cst (TREE_TYPE (rse.expr), e),
3460 				       rse.expr);
3461 	    }
3462 
3463 	  lshift = fold_build2_loc (input_location, LSHIFT_EXPR, type,
3464 				    build_int_cst (type, 1), shift);
3465 	  ge = fold_build2_loc (input_location, GE_EXPR, logical_type_node,
3466 				rse.expr, build_int_cst (type, 0));
3467 	  cond = fold_build3_loc (input_location, COND_EXPR, type, ge, lshift,
3468 				 build_int_cst (type, 0));
3469 	  num_bits = build_int_cst (TREE_TYPE (rse.expr), TYPE_PRECISION (type));
3470 	  cond2 = fold_build2_loc (input_location, GE_EXPR, logical_type_node,
3471 				   rse.expr, num_bits);
3472 	  tmp1 = fold_build3_loc (input_location, COND_EXPR, type, cond2,
3473 				  build_int_cst (type, 0), cond);
3474 	  if (v > 0)
3475 	    {
3476 	      se->expr = tmp1;
3477 	    }
3478 	  else
3479 	    {
3480 	      /* for v < 0, calculate v**n = |v|**n * (-1)**n */
3481 	      tree tmp2;
3482 	      tmp2 = fold_build2_loc (input_location, BIT_AND_EXPR, type,
3483 				      rse.expr, build_int_cst (type, 1));
3484 	      tmp2 = fold_build2_loc (input_location, LSHIFT_EXPR, type,
3485 				      tmp2, build_int_cst (type, 1));
3486 	      tmp2 = fold_build2_loc (input_location, MINUS_EXPR, type,
3487 				      build_int_cst (type, 1), tmp2);
3488 	      se->expr = fold_build2_loc (input_location, MULT_EXPR, type,
3489 					  tmp1, tmp2);
3490 	    }
3491 	  return;
3492 	}
3493     }
3494 
3495   gfc_int4_type_node = gfc_get_int_type (4);
3496 
3497   /* In case of integer operands with kinds 1 or 2, we call the integer kind 4
3498      library routine.  But in the end, we have to convert the result back
3499      if this case applies -- with res_ikind_K, we keep track whether operand K
3500      falls into this case.  */
3501   res_ikind_1 = -1;
3502   res_ikind_2 = -1;
3503 
3504   kind = expr->value.op.op1->ts.kind;
3505   switch (expr->value.op.op2->ts.type)
3506     {
3507     case BT_INTEGER:
3508       ikind = expr->value.op.op2->ts.kind;
3509       switch (ikind)
3510 	{
3511 	case 1:
3512 	case 2:
3513 	  rse.expr = convert (gfc_int4_type_node, rse.expr);
3514 	  res_ikind_2 = ikind;
3515 	  /* Fall through.  */
3516 
3517 	case 4:
3518 	  ikind = 0;
3519 	  break;
3520 
3521 	case 8:
3522 	  ikind = 1;
3523 	  break;
3524 
3525 	case 16:
3526 	  ikind = 2;
3527 	  break;
3528 
3529 	default:
3530 	  gcc_unreachable ();
3531 	}
3532       switch (kind)
3533 	{
3534 	case 1:
3535 	case 2:
3536 	  if (expr->value.op.op1->ts.type == BT_INTEGER)
3537 	    {
3538 	      lse.expr = convert (gfc_int4_type_node, lse.expr);
3539 	      res_ikind_1 = kind;
3540 	    }
3541 	  else
3542 	    gcc_unreachable ();
3543 	  /* Fall through.  */
3544 
3545 	case 4:
3546 	  kind = 0;
3547 	  break;
3548 
3549 	case 8:
3550 	  kind = 1;
3551 	  break;
3552 
3553 	case 10:
3554 	  kind = 2;
3555 	  break;
3556 
3557 	case 16:
3558 	  kind = 3;
3559 	  break;
3560 
3561 	default:
3562 	  gcc_unreachable ();
3563 	}
3564 
3565       switch (expr->value.op.op1->ts.type)
3566 	{
3567 	case BT_INTEGER:
3568 	  if (kind == 3) /* Case 16 was not handled properly above.  */
3569 	    kind = 2;
3570 	  fndecl = gfor_fndecl_math_powi[kind][ikind].integer;
3571 	  break;
3572 
3573 	case BT_REAL:
3574 	  /* Use builtins for real ** int4.  */
3575 	  if (ikind == 0)
3576 	    {
3577 	      switch (kind)
3578 		{
3579 		case 0:
3580 		  fndecl = builtin_decl_explicit (BUILT_IN_POWIF);
3581 		  break;
3582 
3583 		case 1:
3584 		  fndecl = builtin_decl_explicit (BUILT_IN_POWI);
3585 		  break;
3586 
3587 		case 2:
3588 		  fndecl = builtin_decl_explicit (BUILT_IN_POWIL);
3589 		  break;
3590 
3591 		case 3:
3592 		  /* Use the __builtin_powil() only if real(kind=16) is
3593 		     actually the C long double type.  */
3594 		  if (!gfc_real16_is_float128)
3595 		    fndecl = builtin_decl_explicit (BUILT_IN_POWIL);
3596 		  break;
3597 
3598 		default:
3599 		  gcc_unreachable ();
3600 		}
3601 	    }
3602 
3603 	  /* If we don't have a good builtin for this, go for the
3604 	     library function.  */
3605 	  if (!fndecl)
3606 	    fndecl = gfor_fndecl_math_powi[kind][ikind].real;
3607 	  break;
3608 
3609 	case BT_COMPLEX:
3610 	  fndecl = gfor_fndecl_math_powi[kind][ikind].cmplx;
3611 	  break;
3612 
3613 	default:
3614 	  gcc_unreachable ();
3615  	}
3616       break;
3617 
3618     case BT_REAL:
3619       fndecl = gfc_builtin_decl_for_float_kind (BUILT_IN_POW, kind);
3620       break;
3621 
3622     case BT_COMPLEX:
3623       fndecl = gfc_builtin_decl_for_float_kind (BUILT_IN_CPOW, kind);
3624       break;
3625 
3626     default:
3627       gcc_unreachable ();
3628       break;
3629     }
3630 
3631   se->expr = build_call_expr_loc (input_location,
3632 			      fndecl, 2, lse.expr, rse.expr);
3633 
3634   /* Convert the result back if it is of wrong integer kind.  */
3635   if (res_ikind_1 != -1 && res_ikind_2 != -1)
3636     {
3637       /* We want the maximum of both operand kinds as result.  */
3638       if (res_ikind_1 < res_ikind_2)
3639 	res_ikind_1 = res_ikind_2;
3640       se->expr = convert (gfc_get_int_type (res_ikind_1), se->expr);
3641     }
3642 }
3643 
3644 
3645 /* Generate code to allocate a string temporary.  */
3646 
3647 tree
gfc_conv_string_tmp(gfc_se * se,tree type,tree len)3648 gfc_conv_string_tmp (gfc_se * se, tree type, tree len)
3649 {
3650   tree var;
3651   tree tmp;
3652 
3653   if (gfc_can_put_var_on_stack (len))
3654     {
3655       /* Create a temporary variable to hold the result.  */
3656       tmp = fold_build2_loc (input_location, MINUS_EXPR,
3657 			     TREE_TYPE (len), len,
3658 			     build_int_cst (TREE_TYPE (len), 1));
3659       tmp = build_range_type (gfc_charlen_type_node, size_zero_node, tmp);
3660 
3661       if (TREE_CODE (TREE_TYPE (type)) == ARRAY_TYPE)
3662 	tmp = build_array_type (TREE_TYPE (TREE_TYPE (type)), tmp);
3663       else
3664 	tmp = build_array_type (TREE_TYPE (type), tmp);
3665 
3666       var = gfc_create_var (tmp, "str");
3667       var = gfc_build_addr_expr (type, var);
3668     }
3669   else
3670     {
3671       /* Allocate a temporary to hold the result.  */
3672       var = gfc_create_var (type, "pstr");
3673       gcc_assert (POINTER_TYPE_P (type));
3674       tmp = TREE_TYPE (type);
3675       if (TREE_CODE (tmp) == ARRAY_TYPE)
3676         tmp = TREE_TYPE (tmp);
3677       tmp = TYPE_SIZE_UNIT (tmp);
3678       tmp = fold_build2_loc (input_location, MULT_EXPR, size_type_node,
3679 			    fold_convert (size_type_node, len),
3680 			    fold_convert (size_type_node, tmp));
3681       tmp = gfc_call_malloc (&se->pre, type, tmp);
3682       gfc_add_modify (&se->pre, var, tmp);
3683 
3684       /* Free the temporary afterwards.  */
3685       tmp = gfc_call_free (var);
3686       gfc_add_expr_to_block (&se->post, tmp);
3687     }
3688 
3689   return var;
3690 }
3691 
3692 
3693 /* Handle a string concatenation operation.  A temporary will be allocated to
3694    hold the result.  */
3695 
3696 static void
gfc_conv_concat_op(gfc_se * se,gfc_expr * expr)3697 gfc_conv_concat_op (gfc_se * se, gfc_expr * expr)
3698 {
3699   gfc_se lse, rse;
3700   tree len, type, var, tmp, fndecl;
3701 
3702   gcc_assert (expr->value.op.op1->ts.type == BT_CHARACTER
3703 	      && expr->value.op.op2->ts.type == BT_CHARACTER);
3704   gcc_assert (expr->value.op.op1->ts.kind == expr->value.op.op2->ts.kind);
3705 
3706   gfc_init_se (&lse, se);
3707   gfc_conv_expr (&lse, expr->value.op.op1);
3708   gfc_conv_string_parameter (&lse);
3709   gfc_init_se (&rse, se);
3710   gfc_conv_expr (&rse, expr->value.op.op2);
3711   gfc_conv_string_parameter (&rse);
3712 
3713   gfc_add_block_to_block (&se->pre, &lse.pre);
3714   gfc_add_block_to_block (&se->pre, &rse.pre);
3715 
3716   type = gfc_get_character_type (expr->ts.kind, expr->ts.u.cl);
3717   len = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
3718   if (len == NULL_TREE)
3719     {
3720       len = fold_build2_loc (input_location, PLUS_EXPR,
3721 			     gfc_charlen_type_node,
3722 			     fold_convert (gfc_charlen_type_node,
3723 					   lse.string_length),
3724 			     fold_convert (gfc_charlen_type_node,
3725 					   rse.string_length));
3726     }
3727 
3728   type = build_pointer_type (type);
3729 
3730   var = gfc_conv_string_tmp (se, type, len);
3731 
3732   /* Do the actual concatenation.  */
3733   if (expr->ts.kind == 1)
3734     fndecl = gfor_fndecl_concat_string;
3735   else if (expr->ts.kind == 4)
3736     fndecl = gfor_fndecl_concat_string_char4;
3737   else
3738     gcc_unreachable ();
3739 
3740   tmp = build_call_expr_loc (input_location,
3741 			 fndecl, 6, len, var, lse.string_length, lse.expr,
3742 			 rse.string_length, rse.expr);
3743   gfc_add_expr_to_block (&se->pre, tmp);
3744 
3745   /* Add the cleanup for the operands.  */
3746   gfc_add_block_to_block (&se->pre, &rse.post);
3747   gfc_add_block_to_block (&se->pre, &lse.post);
3748 
3749   se->expr = var;
3750   se->string_length = len;
3751 }
3752 
3753 /* Translates an op expression. Common (binary) cases are handled by this
3754    function, others are passed on. Recursion is used in either case.
3755    We use the fact that (op1.ts == op2.ts) (except for the power
3756    operator **).
3757    Operators need no special handling for scalarized expressions as long as
3758    they call gfc_conv_simple_val to get their operands.
3759    Character strings get special handling.  */
3760 
3761 static void
gfc_conv_expr_op(gfc_se * se,gfc_expr * expr)3762 gfc_conv_expr_op (gfc_se * se, gfc_expr * expr)
3763 {
3764   enum tree_code code;
3765   gfc_se lse;
3766   gfc_se rse;
3767   tree tmp, type;
3768   int lop;
3769   int checkstring;
3770 
3771   checkstring = 0;
3772   lop = 0;
3773   switch (expr->value.op.op)
3774     {
3775     case INTRINSIC_PARENTHESES:
3776       if ((expr->ts.type == BT_REAL || expr->ts.type == BT_COMPLEX)
3777 	  && flag_protect_parens)
3778 	{
3779 	  gfc_conv_unary_op (PAREN_EXPR, se, expr);
3780 	  gcc_assert (FLOAT_TYPE_P (TREE_TYPE (se->expr)));
3781 	  return;
3782 	}
3783 
3784       /* Fallthrough.  */
3785     case INTRINSIC_UPLUS:
3786       gfc_conv_expr (se, expr->value.op.op1);
3787       return;
3788 
3789     case INTRINSIC_UMINUS:
3790       gfc_conv_unary_op (NEGATE_EXPR, se, expr);
3791       return;
3792 
3793     case INTRINSIC_NOT:
3794       gfc_conv_unary_op (TRUTH_NOT_EXPR, se, expr);
3795       return;
3796 
3797     case INTRINSIC_PLUS:
3798       code = PLUS_EXPR;
3799       break;
3800 
3801     case INTRINSIC_MINUS:
3802       code = MINUS_EXPR;
3803       break;
3804 
3805     case INTRINSIC_TIMES:
3806       code = MULT_EXPR;
3807       break;
3808 
3809     case INTRINSIC_DIVIDE:
3810       /* If expr is a real or complex expr, use an RDIV_EXPR. If op1 is
3811          an integer, we must round towards zero, so we use a
3812          TRUNC_DIV_EXPR.  */
3813       if (expr->ts.type == BT_INTEGER)
3814 	code = TRUNC_DIV_EXPR;
3815       else
3816 	code = RDIV_EXPR;
3817       break;
3818 
3819     case INTRINSIC_POWER:
3820       gfc_conv_power_op (se, expr);
3821       return;
3822 
3823     case INTRINSIC_CONCAT:
3824       gfc_conv_concat_op (se, expr);
3825       return;
3826 
3827     case INTRINSIC_AND:
3828       code = flag_frontend_optimize ? TRUTH_ANDIF_EXPR : TRUTH_AND_EXPR;
3829       lop = 1;
3830       break;
3831 
3832     case INTRINSIC_OR:
3833       code = flag_frontend_optimize ? TRUTH_ORIF_EXPR : TRUTH_OR_EXPR;
3834       lop = 1;
3835       break;
3836 
3837       /* EQV and NEQV only work on logicals, but since we represent them
3838          as integers, we can use EQ_EXPR and NE_EXPR for them in GIMPLE.  */
3839     case INTRINSIC_EQ:
3840     case INTRINSIC_EQ_OS:
3841     case INTRINSIC_EQV:
3842       code = EQ_EXPR;
3843       checkstring = 1;
3844       lop = 1;
3845       break;
3846 
3847     case INTRINSIC_NE:
3848     case INTRINSIC_NE_OS:
3849     case INTRINSIC_NEQV:
3850       code = NE_EXPR;
3851       checkstring = 1;
3852       lop = 1;
3853       break;
3854 
3855     case INTRINSIC_GT:
3856     case INTRINSIC_GT_OS:
3857       code = GT_EXPR;
3858       checkstring = 1;
3859       lop = 1;
3860       break;
3861 
3862     case INTRINSIC_GE:
3863     case INTRINSIC_GE_OS:
3864       code = GE_EXPR;
3865       checkstring = 1;
3866       lop = 1;
3867       break;
3868 
3869     case INTRINSIC_LT:
3870     case INTRINSIC_LT_OS:
3871       code = LT_EXPR;
3872       checkstring = 1;
3873       lop = 1;
3874       break;
3875 
3876     case INTRINSIC_LE:
3877     case INTRINSIC_LE_OS:
3878       code = LE_EXPR;
3879       checkstring = 1;
3880       lop = 1;
3881       break;
3882 
3883     case INTRINSIC_USER:
3884     case INTRINSIC_ASSIGN:
3885       /* These should be converted into function calls by the frontend.  */
3886       gcc_unreachable ();
3887 
3888     default:
3889       fatal_error (input_location, "Unknown intrinsic op");
3890       return;
3891     }
3892 
3893   /* The only exception to this is **, which is handled separately anyway.  */
3894   gcc_assert (expr->value.op.op1->ts.type == expr->value.op.op2->ts.type);
3895 
3896   if (checkstring && expr->value.op.op1->ts.type != BT_CHARACTER)
3897     checkstring = 0;
3898 
3899   /* lhs */
3900   gfc_init_se (&lse, se);
3901   gfc_conv_expr (&lse, expr->value.op.op1);
3902   gfc_add_block_to_block (&se->pre, &lse.pre);
3903 
3904   /* rhs */
3905   gfc_init_se (&rse, se);
3906   gfc_conv_expr (&rse, expr->value.op.op2);
3907   gfc_add_block_to_block (&se->pre, &rse.pre);
3908 
3909   if (checkstring)
3910     {
3911       gfc_conv_string_parameter (&lse);
3912       gfc_conv_string_parameter (&rse);
3913 
3914       lse.expr = gfc_build_compare_string (lse.string_length, lse.expr,
3915 					   rse.string_length, rse.expr,
3916 					   expr->value.op.op1->ts.kind,
3917 					   code);
3918       rse.expr = build_int_cst (TREE_TYPE (lse.expr), 0);
3919       gfc_add_block_to_block (&lse.post, &rse.post);
3920     }
3921 
3922   type = gfc_typenode_for_spec (&expr->ts);
3923 
3924   if (lop)
3925     {
3926       /* The result of logical ops is always logical_type_node.  */
3927       tmp = fold_build2_loc (input_location, code, logical_type_node,
3928 			     lse.expr, rse.expr);
3929       se->expr = convert (type, tmp);
3930     }
3931   else
3932     se->expr = fold_build2_loc (input_location, code, type, lse.expr, rse.expr);
3933 
3934   /* Add the post blocks.  */
3935   gfc_add_block_to_block (&se->post, &rse.post);
3936   gfc_add_block_to_block (&se->post, &lse.post);
3937 }
3938 
3939 /* If a string's length is one, we convert it to a single character.  */
3940 
3941 tree
gfc_string_to_single_character(tree len,tree str,int kind)3942 gfc_string_to_single_character (tree len, tree str, int kind)
3943 {
3944 
3945   if (len == NULL
3946       || !tree_fits_uhwi_p (len)
3947       || !POINTER_TYPE_P (TREE_TYPE (str)))
3948     return NULL_TREE;
3949 
3950   if (TREE_INT_CST_LOW (len) == 1)
3951     {
3952       str = fold_convert (gfc_get_pchar_type (kind), str);
3953       return build_fold_indirect_ref_loc (input_location, str);
3954     }
3955 
3956   if (kind == 1
3957       && TREE_CODE (str) == ADDR_EXPR
3958       && TREE_CODE (TREE_OPERAND (str, 0)) == ARRAY_REF
3959       && TREE_CODE (TREE_OPERAND (TREE_OPERAND (str, 0), 0)) == STRING_CST
3960       && array_ref_low_bound (TREE_OPERAND (str, 0))
3961 	 == TREE_OPERAND (TREE_OPERAND (str, 0), 1)
3962       && TREE_INT_CST_LOW (len) > 1
3963       && TREE_INT_CST_LOW (len)
3964 	 == (unsigned HOST_WIDE_INT)
3965 	    TREE_STRING_LENGTH (TREE_OPERAND (TREE_OPERAND (str, 0), 0)))
3966     {
3967       tree ret = fold_convert (gfc_get_pchar_type (kind), str);
3968       ret = build_fold_indirect_ref_loc (input_location, ret);
3969       if (TREE_CODE (ret) == INTEGER_CST)
3970 	{
3971 	  tree string_cst = TREE_OPERAND (TREE_OPERAND (str, 0), 0);
3972 	  int i, length = TREE_STRING_LENGTH (string_cst);
3973 	  const char *ptr = TREE_STRING_POINTER (string_cst);
3974 
3975 	  for (i = 1; i < length; i++)
3976 	    if (ptr[i] != ' ')
3977 	      return NULL_TREE;
3978 
3979 	  return ret;
3980 	}
3981     }
3982 
3983   return NULL_TREE;
3984 }
3985 
3986 
3987 static void
conv_scalar_char_value(gfc_symbol * sym,gfc_se * se,gfc_expr ** expr)3988 conv_scalar_char_value (gfc_symbol *sym, gfc_se *se, gfc_expr **expr)
3989 {
3990   gcc_assert (expr);
3991 
3992   /* We used to modify the tree here. Now it is done earlier in
3993      the front-end, so we only check it here to avoid regressions.  */
3994   if (sym->backend_decl)
3995     {
3996       gcc_assert (TREE_CODE (TREE_TYPE (sym->backend_decl)) == INTEGER_TYPE);
3997       gcc_assert (TYPE_UNSIGNED (TREE_TYPE (sym->backend_decl)) == 1);
3998       gcc_assert (TYPE_PRECISION (TREE_TYPE (sym->backend_decl)) == CHAR_TYPE_SIZE);
3999       gcc_assert (DECL_BY_REFERENCE (sym->backend_decl) == 0);
4000     }
4001 
4002   /* If we have a constant character expression, make it into an
4003       integer of type C char.  */
4004   if ((*expr)->expr_type == EXPR_CONSTANT)
4005     {
4006       gfc_typespec ts;
4007       gfc_clear_ts (&ts);
4008 
4009       *expr = gfc_get_int_expr (gfc_default_character_kind, NULL,
4010 				(*expr)->value.character.string[0]);
4011     }
4012   else if (se != NULL && (*expr)->expr_type == EXPR_VARIABLE)
4013     {
4014       if ((*expr)->ref == NULL)
4015 	{
4016 	  se->expr = gfc_string_to_single_character
4017 	    (build_int_cst (integer_type_node, 1),
4018 	      gfc_build_addr_expr (gfc_get_pchar_type ((*expr)->ts.kind),
4019 				  gfc_get_symbol_decl
4020 				  ((*expr)->symtree->n.sym)),
4021 	      (*expr)->ts.kind);
4022 	}
4023       else
4024 	{
4025 	  gfc_conv_variable (se, *expr);
4026 	  se->expr = gfc_string_to_single_character
4027 	    (build_int_cst (integer_type_node, 1),
4028 	      gfc_build_addr_expr (gfc_get_pchar_type ((*expr)->ts.kind),
4029 				  se->expr),
4030 	      (*expr)->ts.kind);
4031 	}
4032     }
4033 }
4034 
4035 /* Helper function for gfc_build_compare_string.  Return LEN_TRIM value
4036    if STR is a string literal, otherwise return -1.  */
4037 
4038 static int
gfc_optimize_len_trim(tree len,tree str,int kind)4039 gfc_optimize_len_trim (tree len, tree str, int kind)
4040 {
4041   if (kind == 1
4042       && TREE_CODE (str) == ADDR_EXPR
4043       && TREE_CODE (TREE_OPERAND (str, 0)) == ARRAY_REF
4044       && TREE_CODE (TREE_OPERAND (TREE_OPERAND (str, 0), 0)) == STRING_CST
4045       && array_ref_low_bound (TREE_OPERAND (str, 0))
4046 	 == TREE_OPERAND (TREE_OPERAND (str, 0), 1)
4047       && tree_fits_uhwi_p (len)
4048       && tree_to_uhwi (len) >= 1
4049       && tree_to_uhwi (len)
4050 	 == (unsigned HOST_WIDE_INT)
4051 	    TREE_STRING_LENGTH (TREE_OPERAND (TREE_OPERAND (str, 0), 0)))
4052     {
4053       tree folded = fold_convert (gfc_get_pchar_type (kind), str);
4054       folded = build_fold_indirect_ref_loc (input_location, folded);
4055       if (TREE_CODE (folded) == INTEGER_CST)
4056 	{
4057 	  tree string_cst = TREE_OPERAND (TREE_OPERAND (str, 0), 0);
4058 	  int length = TREE_STRING_LENGTH (string_cst);
4059 	  const char *ptr = TREE_STRING_POINTER (string_cst);
4060 
4061 	  for (; length > 0; length--)
4062 	    if (ptr[length - 1] != ' ')
4063 	      break;
4064 
4065 	  return length;
4066 	}
4067     }
4068   return -1;
4069 }
4070 
4071 /* Helper to build a call to memcmp.  */
4072 
4073 static tree
build_memcmp_call(tree s1,tree s2,tree n)4074 build_memcmp_call (tree s1, tree s2, tree n)
4075 {
4076   tree tmp;
4077 
4078   if (!POINTER_TYPE_P (TREE_TYPE (s1)))
4079     s1 = gfc_build_addr_expr (pvoid_type_node, s1);
4080   else
4081     s1 = fold_convert (pvoid_type_node, s1);
4082 
4083   if (!POINTER_TYPE_P (TREE_TYPE (s2)))
4084     s2 = gfc_build_addr_expr (pvoid_type_node, s2);
4085   else
4086     s2 = fold_convert (pvoid_type_node, s2);
4087 
4088   n = fold_convert (size_type_node, n);
4089 
4090   tmp = build_call_expr_loc (input_location,
4091 			     builtin_decl_explicit (BUILT_IN_MEMCMP),
4092 			     3, s1, s2, n);
4093 
4094   return fold_convert (integer_type_node, tmp);
4095 }
4096 
4097 /* Compare two strings. If they are all single characters, the result is the
4098    subtraction of them. Otherwise, we build a library call.  */
4099 
4100 tree
gfc_build_compare_string(tree len1,tree str1,tree len2,tree str2,int kind,enum tree_code code)4101 gfc_build_compare_string (tree len1, tree str1, tree len2, tree str2, int kind,
4102 			  enum tree_code code)
4103 {
4104   tree sc1;
4105   tree sc2;
4106   tree fndecl;
4107 
4108   gcc_assert (POINTER_TYPE_P (TREE_TYPE (str1)));
4109   gcc_assert (POINTER_TYPE_P (TREE_TYPE (str2)));
4110 
4111   sc1 = gfc_string_to_single_character (len1, str1, kind);
4112   sc2 = gfc_string_to_single_character (len2, str2, kind);
4113 
4114   if (sc1 != NULL_TREE && sc2 != NULL_TREE)
4115     {
4116       /* Deal with single character specially.  */
4117       sc1 = fold_convert (integer_type_node, sc1);
4118       sc2 = fold_convert (integer_type_node, sc2);
4119       return fold_build2_loc (input_location, MINUS_EXPR, integer_type_node,
4120 			      sc1, sc2);
4121     }
4122 
4123   if ((code == EQ_EXPR || code == NE_EXPR)
4124       && optimize
4125       && INTEGER_CST_P (len1) && INTEGER_CST_P (len2))
4126     {
4127       /* If one string is a string literal with LEN_TRIM longer
4128 	 than the length of the second string, the strings
4129 	 compare unequal.  */
4130       int len = gfc_optimize_len_trim (len1, str1, kind);
4131       if (len > 0 && compare_tree_int (len2, len) < 0)
4132 	return integer_one_node;
4133       len = gfc_optimize_len_trim (len2, str2, kind);
4134       if (len > 0 && compare_tree_int (len1, len) < 0)
4135 	return integer_one_node;
4136     }
4137 
4138   /* We can compare via memcpy if the strings are known to be equal
4139      in length and they are
4140      - kind=1
4141      - kind=4 and the comparison is for (in)equality.  */
4142 
4143   if (INTEGER_CST_P (len1) && INTEGER_CST_P (len2)
4144       && tree_int_cst_equal (len1, len2)
4145       && (kind == 1 || code == EQ_EXPR || code == NE_EXPR))
4146     {
4147       tree tmp;
4148       tree chartype;
4149 
4150       chartype = gfc_get_char_type (kind);
4151       tmp = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE(len1),
4152 			     fold_convert (TREE_TYPE(len1),
4153 					   TYPE_SIZE_UNIT(chartype)),
4154 			     len1);
4155       return build_memcmp_call (str1, str2, tmp);
4156     }
4157 
4158   /* Build a call for the comparison.  */
4159   if (kind == 1)
4160     fndecl = gfor_fndecl_compare_string;
4161   else if (kind == 4)
4162     fndecl = gfor_fndecl_compare_string_char4;
4163   else
4164     gcc_unreachable ();
4165 
4166   return build_call_expr_loc (input_location, fndecl, 4,
4167 			      len1, str1, len2, str2);
4168 }
4169 
4170 
4171 /* Return the backend_decl for a procedure pointer component.  */
4172 
4173 static tree
get_proc_ptr_comp(gfc_expr * e)4174 get_proc_ptr_comp (gfc_expr *e)
4175 {
4176   gfc_se comp_se;
4177   gfc_expr *e2;
4178   expr_t old_type;
4179 
4180   gfc_init_se (&comp_se, NULL);
4181   e2 = gfc_copy_expr (e);
4182   /* We have to restore the expr type later so that gfc_free_expr frees
4183      the exact same thing that was allocated.
4184      TODO: This is ugly.  */
4185   old_type = e2->expr_type;
4186   e2->expr_type = EXPR_VARIABLE;
4187   gfc_conv_expr (&comp_se, e2);
4188   e2->expr_type = old_type;
4189   gfc_free_expr (e2);
4190   return build_fold_addr_expr_loc (input_location, comp_se.expr);
4191 }
4192 
4193 
4194 /* Convert a typebound function reference from a class object.  */
4195 static void
conv_base_obj_fcn_val(gfc_se * se,tree base_object,gfc_expr * expr)4196 conv_base_obj_fcn_val (gfc_se * se, tree base_object, gfc_expr * expr)
4197 {
4198   gfc_ref *ref;
4199   tree var;
4200 
4201   if (!VAR_P (base_object))
4202     {
4203       var = gfc_create_var (TREE_TYPE (base_object), NULL);
4204       gfc_add_modify (&se->pre, var, base_object);
4205     }
4206   se->expr = gfc_class_vptr_get (base_object);
4207   se->expr = build_fold_indirect_ref_loc (input_location, se->expr);
4208   ref = expr->ref;
4209   while (ref && ref->next)
4210     ref = ref->next;
4211   gcc_assert (ref && ref->type == REF_COMPONENT);
4212   if (ref->u.c.sym->attr.extension)
4213     conv_parent_component_references (se, ref);
4214   gfc_conv_component_ref (se, ref);
4215   se->expr = build_fold_addr_expr_loc (input_location, se->expr);
4216 }
4217 
4218 
4219 static void
conv_function_val(gfc_se * se,gfc_symbol * sym,gfc_expr * expr,gfc_actual_arglist * actual_args)4220 conv_function_val (gfc_se * se, gfc_symbol * sym, gfc_expr * expr,
4221 		   gfc_actual_arglist *actual_args)
4222 {
4223   tree tmp;
4224 
4225   if (gfc_is_proc_ptr_comp (expr))
4226     tmp = get_proc_ptr_comp (expr);
4227   else if (sym->attr.dummy)
4228     {
4229       tmp = gfc_get_symbol_decl (sym);
4230       if (sym->attr.proc_pointer)
4231         tmp = build_fold_indirect_ref_loc (input_location,
4232 				       tmp);
4233       gcc_assert (TREE_CODE (TREE_TYPE (tmp)) == POINTER_TYPE
4234 	      && TREE_CODE (TREE_TYPE (TREE_TYPE (tmp))) == FUNCTION_TYPE);
4235     }
4236   else
4237     {
4238       if (!sym->backend_decl)
4239 	sym->backend_decl = gfc_get_extern_function_decl (sym, actual_args);
4240 
4241       TREE_USED (sym->backend_decl) = 1;
4242 
4243       tmp = sym->backend_decl;
4244 
4245       if (sym->attr.cray_pointee)
4246 	{
4247 	  /* TODO - make the cray pointee a pointer to a procedure,
4248 	     assign the pointer to it and use it for the call.  This
4249 	     will do for now!  */
4250 	  tmp = convert (build_pointer_type (TREE_TYPE (tmp)),
4251 			 gfc_get_symbol_decl (sym->cp_pointer));
4252 	  tmp = gfc_evaluate_now (tmp, &se->pre);
4253 	}
4254 
4255       if (!POINTER_TYPE_P (TREE_TYPE (tmp)))
4256 	{
4257 	  gcc_assert (TREE_CODE (tmp) == FUNCTION_DECL);
4258 	  tmp = gfc_build_addr_expr (NULL_TREE, tmp);
4259 	}
4260     }
4261   se->expr = tmp;
4262 }
4263 
4264 
4265 /* Initialize MAPPING.  */
4266 
4267 void
gfc_init_interface_mapping(gfc_interface_mapping * mapping)4268 gfc_init_interface_mapping (gfc_interface_mapping * mapping)
4269 {
4270   mapping->syms = NULL;
4271   mapping->charlens = NULL;
4272 }
4273 
4274 
4275 /* Free all memory held by MAPPING (but not MAPPING itself).  */
4276 
4277 void
gfc_free_interface_mapping(gfc_interface_mapping * mapping)4278 gfc_free_interface_mapping (gfc_interface_mapping * mapping)
4279 {
4280   gfc_interface_sym_mapping *sym;
4281   gfc_interface_sym_mapping *nextsym;
4282   gfc_charlen *cl;
4283   gfc_charlen *nextcl;
4284 
4285   for (sym = mapping->syms; sym; sym = nextsym)
4286     {
4287       nextsym = sym->next;
4288       sym->new_sym->n.sym->formal = NULL;
4289       gfc_free_symbol (sym->new_sym->n.sym);
4290       gfc_free_expr (sym->expr);
4291       free (sym->new_sym);
4292       free (sym);
4293     }
4294   for (cl = mapping->charlens; cl; cl = nextcl)
4295     {
4296       nextcl = cl->next;
4297       gfc_free_expr (cl->length);
4298       free (cl);
4299     }
4300 }
4301 
4302 
4303 /* Return a copy of gfc_charlen CL.  Add the returned structure to
4304    MAPPING so that it will be freed by gfc_free_interface_mapping.  */
4305 
4306 static gfc_charlen *
gfc_get_interface_mapping_charlen(gfc_interface_mapping * mapping,gfc_charlen * cl)4307 gfc_get_interface_mapping_charlen (gfc_interface_mapping * mapping,
4308 				   gfc_charlen * cl)
4309 {
4310   gfc_charlen *new_charlen;
4311 
4312   new_charlen = gfc_get_charlen ();
4313   new_charlen->next = mapping->charlens;
4314   new_charlen->length = gfc_copy_expr (cl->length);
4315 
4316   mapping->charlens = new_charlen;
4317   return new_charlen;
4318 }
4319 
4320 
4321 /* A subroutine of gfc_add_interface_mapping.  Return a descriptorless
4322    array variable that can be used as the actual argument for dummy
4323    argument SYM.  Add any initialization code to BLOCK.  PACKED is as
4324    for gfc_get_nodesc_array_type and DATA points to the first element
4325    in the passed array.  */
4326 
4327 static tree
gfc_get_interface_mapping_array(stmtblock_t * block,gfc_symbol * sym,gfc_packed packed,tree data)4328 gfc_get_interface_mapping_array (stmtblock_t * block, gfc_symbol * sym,
4329 				 gfc_packed packed, tree data)
4330 {
4331   tree type;
4332   tree var;
4333 
4334   type = gfc_typenode_for_spec (&sym->ts);
4335   type = gfc_get_nodesc_array_type (type, sym->as, packed,
4336 				    !sym->attr.target && !sym->attr.pointer
4337 				    && !sym->attr.proc_pointer);
4338 
4339   var = gfc_create_var (type, "ifm");
4340   gfc_add_modify (block, var, fold_convert (type, data));
4341 
4342   return var;
4343 }
4344 
4345 
4346 /* A subroutine of gfc_add_interface_mapping.  Set the stride, upper bounds
4347    and offset of descriptorless array type TYPE given that it has the same
4348    size as DESC.  Add any set-up code to BLOCK.  */
4349 
4350 static void
gfc_set_interface_mapping_bounds(stmtblock_t * block,tree type,tree desc)4351 gfc_set_interface_mapping_bounds (stmtblock_t * block, tree type, tree desc)
4352 {
4353   int n;
4354   tree dim;
4355   tree offset;
4356   tree tmp;
4357 
4358   offset = gfc_index_zero_node;
4359   for (n = 0; n < GFC_TYPE_ARRAY_RANK (type); n++)
4360     {
4361       dim = gfc_rank_cst[n];
4362       GFC_TYPE_ARRAY_STRIDE (type, n) = gfc_conv_array_stride (desc, n);
4363       if (GFC_TYPE_ARRAY_LBOUND (type, n) == NULL_TREE)
4364 	{
4365 	  GFC_TYPE_ARRAY_LBOUND (type, n)
4366 		= gfc_conv_descriptor_lbound_get (desc, dim);
4367 	  GFC_TYPE_ARRAY_UBOUND (type, n)
4368 		= gfc_conv_descriptor_ubound_get (desc, dim);
4369 	}
4370       else if (GFC_TYPE_ARRAY_UBOUND (type, n) == NULL_TREE)
4371 	{
4372 	  tmp = fold_build2_loc (input_location, MINUS_EXPR,
4373 				 gfc_array_index_type,
4374 				 gfc_conv_descriptor_ubound_get (desc, dim),
4375 				 gfc_conv_descriptor_lbound_get (desc, dim));
4376 	  tmp = fold_build2_loc (input_location, PLUS_EXPR,
4377 				 gfc_array_index_type,
4378 				 GFC_TYPE_ARRAY_LBOUND (type, n), tmp);
4379 	  tmp = gfc_evaluate_now (tmp, block);
4380 	  GFC_TYPE_ARRAY_UBOUND (type, n) = tmp;
4381 	}
4382       tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
4383 			     GFC_TYPE_ARRAY_LBOUND (type, n),
4384 			     GFC_TYPE_ARRAY_STRIDE (type, n));
4385       offset = fold_build2_loc (input_location, MINUS_EXPR,
4386 				gfc_array_index_type, offset, tmp);
4387     }
4388   offset = gfc_evaluate_now (offset, block);
4389   GFC_TYPE_ARRAY_OFFSET (type) = offset;
4390 }
4391 
4392 
4393 /* Extend MAPPING so that it maps dummy argument SYM to the value stored
4394    in SE.  The caller may still use se->expr and se->string_length after
4395    calling this function.  */
4396 
4397 void
gfc_add_interface_mapping(gfc_interface_mapping * mapping,gfc_symbol * sym,gfc_se * se,gfc_expr * expr)4398 gfc_add_interface_mapping (gfc_interface_mapping * mapping,
4399 			   gfc_symbol * sym, gfc_se * se,
4400 			   gfc_expr *expr)
4401 {
4402   gfc_interface_sym_mapping *sm;
4403   tree desc;
4404   tree tmp;
4405   tree value;
4406   gfc_symbol *new_sym;
4407   gfc_symtree *root;
4408   gfc_symtree *new_symtree;
4409 
4410   /* Create a new symbol to represent the actual argument.  */
4411   new_sym = gfc_new_symbol (sym->name, NULL);
4412   new_sym->ts = sym->ts;
4413   new_sym->as = gfc_copy_array_spec (sym->as);
4414   new_sym->attr.referenced = 1;
4415   new_sym->attr.dimension = sym->attr.dimension;
4416   new_sym->attr.contiguous = sym->attr.contiguous;
4417   new_sym->attr.codimension = sym->attr.codimension;
4418   new_sym->attr.pointer = sym->attr.pointer;
4419   new_sym->attr.allocatable = sym->attr.allocatable;
4420   new_sym->attr.flavor = sym->attr.flavor;
4421   new_sym->attr.function = sym->attr.function;
4422 
4423   /* Ensure that the interface is available and that
4424      descriptors are passed for array actual arguments.  */
4425   if (sym->attr.flavor == FL_PROCEDURE)
4426     {
4427       new_sym->formal = expr->symtree->n.sym->formal;
4428       new_sym->attr.always_explicit
4429 	    = expr->symtree->n.sym->attr.always_explicit;
4430     }
4431 
4432   /* Create a fake symtree for it.  */
4433   root = NULL;
4434   new_symtree = gfc_new_symtree (&root, sym->name);
4435   new_symtree->n.sym = new_sym;
4436   gcc_assert (new_symtree == root);
4437 
4438   /* Create a dummy->actual mapping.  */
4439   sm = XCNEW (gfc_interface_sym_mapping);
4440   sm->next = mapping->syms;
4441   sm->old = sym;
4442   sm->new_sym = new_symtree;
4443   sm->expr = gfc_copy_expr (expr);
4444   mapping->syms = sm;
4445 
4446   /* Stabilize the argument's value.  */
4447   if (!sym->attr.function && se)
4448     se->expr = gfc_evaluate_now (se->expr, &se->pre);
4449 
4450   if (sym->ts.type == BT_CHARACTER)
4451     {
4452       /* Create a copy of the dummy argument's length.  */
4453       new_sym->ts.u.cl = gfc_get_interface_mapping_charlen (mapping, sym->ts.u.cl);
4454       sm->expr->ts.u.cl = new_sym->ts.u.cl;
4455 
4456       /* If the length is specified as "*", record the length that
4457 	 the caller is passing.  We should use the callee's length
4458 	 in all other cases.  */
4459       if (!new_sym->ts.u.cl->length && se)
4460 	{
4461 	  se->string_length = gfc_evaluate_now (se->string_length, &se->pre);
4462 	  new_sym->ts.u.cl->backend_decl = se->string_length;
4463 	}
4464     }
4465 
4466   if (!se)
4467     return;
4468 
4469   /* Use the passed value as-is if the argument is a function.  */
4470   if (sym->attr.flavor == FL_PROCEDURE)
4471     value = se->expr;
4472 
4473   /* If the argument is a pass-by-value scalar, use the value as is.  */
4474   else if (!sym->attr.dimension && sym->attr.value)
4475     value = se->expr;
4476 
4477   /* If the argument is either a string or a pointer to a string,
4478      convert it to a boundless character type.  */
4479   else if (!sym->attr.dimension && sym->ts.type == BT_CHARACTER)
4480     {
4481       tmp = gfc_get_character_type_len (sym->ts.kind, NULL);
4482       tmp = build_pointer_type (tmp);
4483       if (sym->attr.pointer)
4484         value = build_fold_indirect_ref_loc (input_location,
4485 					 se->expr);
4486       else
4487         value = se->expr;
4488       value = fold_convert (tmp, value);
4489     }
4490 
4491   /* If the argument is a scalar, a pointer to an array or an allocatable,
4492      dereference it.  */
4493   else if (!sym->attr.dimension || sym->attr.pointer || sym->attr.allocatable)
4494     value = build_fold_indirect_ref_loc (input_location,
4495 				     se->expr);
4496 
4497   /* For character(*), use the actual argument's descriptor.  */
4498   else if (sym->ts.type == BT_CHARACTER && !new_sym->ts.u.cl->length)
4499     value = build_fold_indirect_ref_loc (input_location,
4500 				     se->expr);
4501 
4502   /* If the argument is an array descriptor, use it to determine
4503      information about the actual argument's shape.  */
4504   else if (POINTER_TYPE_P (TREE_TYPE (se->expr))
4505 	   && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (TREE_TYPE (se->expr))))
4506     {
4507       /* Get the actual argument's descriptor.  */
4508       desc = build_fold_indirect_ref_loc (input_location,
4509 				      se->expr);
4510 
4511       /* Create the replacement variable.  */
4512       tmp = gfc_conv_descriptor_data_get (desc);
4513       value = gfc_get_interface_mapping_array (&se->pre, sym,
4514 					       PACKED_NO, tmp);
4515 
4516       /* Use DESC to work out the upper bounds, strides and offset.  */
4517       gfc_set_interface_mapping_bounds (&se->pre, TREE_TYPE (value), desc);
4518     }
4519   else
4520     /* Otherwise we have a packed array.  */
4521     value = gfc_get_interface_mapping_array (&se->pre, sym,
4522 					     PACKED_FULL, se->expr);
4523 
4524   new_sym->backend_decl = value;
4525 }
4526 
4527 
4528 /* Called once all dummy argument mappings have been added to MAPPING,
4529    but before the mapping is used to evaluate expressions.  Pre-evaluate
4530    the length of each argument, adding any initialization code to PRE and
4531    any finalization code to POST.  */
4532 
4533 static void
gfc_finish_interface_mapping(gfc_interface_mapping * mapping,stmtblock_t * pre,stmtblock_t * post)4534 gfc_finish_interface_mapping (gfc_interface_mapping * mapping,
4535 			      stmtblock_t * pre, stmtblock_t * post)
4536 {
4537   gfc_interface_sym_mapping *sym;
4538   gfc_expr *expr;
4539   gfc_se se;
4540 
4541   for (sym = mapping->syms; sym; sym = sym->next)
4542     if (sym->new_sym->n.sym->ts.type == BT_CHARACTER
4543 	&& !sym->new_sym->n.sym->ts.u.cl->backend_decl)
4544       {
4545 	expr = sym->new_sym->n.sym->ts.u.cl->length;
4546 	gfc_apply_interface_mapping_to_expr (mapping, expr);
4547 	gfc_init_se (&se, NULL);
4548 	gfc_conv_expr (&se, expr);
4549 	se.expr = fold_convert (gfc_charlen_type_node, se.expr);
4550 	se.expr = gfc_evaluate_now (se.expr, &se.pre);
4551 	gfc_add_block_to_block (pre, &se.pre);
4552 	gfc_add_block_to_block (post, &se.post);
4553 
4554 	sym->new_sym->n.sym->ts.u.cl->backend_decl = se.expr;
4555       }
4556 }
4557 
4558 
4559 /* Like gfc_apply_interface_mapping_to_expr, but applied to
4560    constructor C.  */
4561 
4562 static void
gfc_apply_interface_mapping_to_cons(gfc_interface_mapping * mapping,gfc_constructor_base base)4563 gfc_apply_interface_mapping_to_cons (gfc_interface_mapping * mapping,
4564 				     gfc_constructor_base base)
4565 {
4566   gfc_constructor *c;
4567   for (c = gfc_constructor_first (base); c; c = gfc_constructor_next (c))
4568     {
4569       gfc_apply_interface_mapping_to_expr (mapping, c->expr);
4570       if (c->iterator)
4571 	{
4572 	  gfc_apply_interface_mapping_to_expr (mapping, c->iterator->start);
4573 	  gfc_apply_interface_mapping_to_expr (mapping, c->iterator->end);
4574 	  gfc_apply_interface_mapping_to_expr (mapping, c->iterator->step);
4575 	}
4576     }
4577 }
4578 
4579 
4580 /* Like gfc_apply_interface_mapping_to_expr, but applied to
4581    reference REF.  */
4582 
4583 static void
gfc_apply_interface_mapping_to_ref(gfc_interface_mapping * mapping,gfc_ref * ref)4584 gfc_apply_interface_mapping_to_ref (gfc_interface_mapping * mapping,
4585 				    gfc_ref * ref)
4586 {
4587   int n;
4588 
4589   for (; ref; ref = ref->next)
4590     switch (ref->type)
4591       {
4592       case REF_ARRAY:
4593 	for (n = 0; n < ref->u.ar.dimen; n++)
4594 	  {
4595 	    gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.start[n]);
4596 	    gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.end[n]);
4597 	    gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.stride[n]);
4598 	  }
4599 	break;
4600 
4601       case REF_COMPONENT:
4602       case REF_INQUIRY:
4603 	break;
4604 
4605       case REF_SUBSTRING:
4606 	gfc_apply_interface_mapping_to_expr (mapping, ref->u.ss.start);
4607 	gfc_apply_interface_mapping_to_expr (mapping, ref->u.ss.end);
4608 	break;
4609       }
4610 }
4611 
4612 
4613 /* Convert intrinsic function calls into result expressions.  */
4614 
4615 static bool
gfc_map_intrinsic_function(gfc_expr * expr,gfc_interface_mapping * mapping)4616 gfc_map_intrinsic_function (gfc_expr *expr, gfc_interface_mapping *mapping)
4617 {
4618   gfc_symbol *sym;
4619   gfc_expr *new_expr;
4620   gfc_expr *arg1;
4621   gfc_expr *arg2;
4622   int d, dup;
4623 
4624   arg1 = expr->value.function.actual->expr;
4625   if (expr->value.function.actual->next)
4626     arg2 = expr->value.function.actual->next->expr;
4627   else
4628     arg2 = NULL;
4629 
4630   sym = arg1->symtree->n.sym;
4631 
4632   if (sym->attr.dummy)
4633     return false;
4634 
4635   new_expr = NULL;
4636 
4637   switch (expr->value.function.isym->id)
4638     {
4639     case GFC_ISYM_LEN:
4640       /* TODO figure out why this condition is necessary.  */
4641       if (sym->attr.function
4642 	  && (arg1->ts.u.cl->length == NULL
4643 	      || (arg1->ts.u.cl->length->expr_type != EXPR_CONSTANT
4644 		  && arg1->ts.u.cl->length->expr_type != EXPR_VARIABLE)))
4645 	return false;
4646 
4647       new_expr = gfc_copy_expr (arg1->ts.u.cl->length);
4648       break;
4649 
4650     case GFC_ISYM_LEN_TRIM:
4651       new_expr = gfc_copy_expr (arg1);
4652       gfc_apply_interface_mapping_to_expr (mapping, new_expr);
4653 
4654       if (!new_expr)
4655 	return false;
4656 
4657       gfc_replace_expr (arg1, new_expr);
4658       return true;
4659 
4660     case GFC_ISYM_SIZE:
4661       if (!sym->as || sym->as->rank == 0)
4662 	return false;
4663 
4664       if (arg2 && arg2->expr_type == EXPR_CONSTANT)
4665 	{
4666 	  dup = mpz_get_si (arg2->value.integer);
4667 	  d = dup - 1;
4668 	}
4669       else
4670 	{
4671 	  dup = sym->as->rank;
4672 	  d = 0;
4673 	}
4674 
4675       for (; d < dup; d++)
4676 	{
4677 	  gfc_expr *tmp;
4678 
4679 	  if (!sym->as->upper[d] || !sym->as->lower[d])
4680 	    {
4681 	      gfc_free_expr (new_expr);
4682 	      return false;
4683 	    }
4684 
4685 	  tmp = gfc_add (gfc_copy_expr (sym->as->upper[d]),
4686 					gfc_get_int_expr (gfc_default_integer_kind,
4687 							  NULL, 1));
4688 	  tmp = gfc_subtract (tmp, gfc_copy_expr (sym->as->lower[d]));
4689 	  if (new_expr)
4690 	    new_expr = gfc_multiply (new_expr, tmp);
4691 	  else
4692 	    new_expr = tmp;
4693 	}
4694       break;
4695 
4696     case GFC_ISYM_LBOUND:
4697     case GFC_ISYM_UBOUND:
4698 	/* TODO These implementations of lbound and ubound do not limit if
4699 	   the size < 0, according to F95's 13.14.53 and 13.14.113.  */
4700 
4701       if (!sym->as || sym->as->rank == 0)
4702 	return false;
4703 
4704       if (arg2 && arg2->expr_type == EXPR_CONSTANT)
4705 	d = mpz_get_si (arg2->value.integer) - 1;
4706       else
4707 	return false;
4708 
4709       if (expr->value.function.isym->id == GFC_ISYM_LBOUND)
4710 	{
4711 	  if (sym->as->lower[d])
4712 	    new_expr = gfc_copy_expr (sym->as->lower[d]);
4713 	}
4714       else
4715 	{
4716 	  if (sym->as->upper[d])
4717 	    new_expr = gfc_copy_expr (sym->as->upper[d]);
4718 	}
4719       break;
4720 
4721     default:
4722       break;
4723     }
4724 
4725   gfc_apply_interface_mapping_to_expr (mapping, new_expr);
4726   if (!new_expr)
4727     return false;
4728 
4729   gfc_replace_expr (expr, new_expr);
4730   return true;
4731 }
4732 
4733 
4734 static void
gfc_map_fcn_formal_to_actual(gfc_expr * expr,gfc_expr * map_expr,gfc_interface_mapping * mapping)4735 gfc_map_fcn_formal_to_actual (gfc_expr *expr, gfc_expr *map_expr,
4736 			      gfc_interface_mapping * mapping)
4737 {
4738   gfc_formal_arglist *f;
4739   gfc_actual_arglist *actual;
4740 
4741   actual = expr->value.function.actual;
4742   f = gfc_sym_get_dummy_args (map_expr->symtree->n.sym);
4743 
4744   for (; f && actual; f = f->next, actual = actual->next)
4745     {
4746       if (!actual->expr)
4747 	continue;
4748 
4749       gfc_add_interface_mapping (mapping, f->sym, NULL, actual->expr);
4750     }
4751 
4752   if (map_expr->symtree->n.sym->attr.dimension)
4753     {
4754       int d;
4755       gfc_array_spec *as;
4756 
4757       as = gfc_copy_array_spec (map_expr->symtree->n.sym->as);
4758 
4759       for (d = 0; d < as->rank; d++)
4760 	{
4761 	  gfc_apply_interface_mapping_to_expr (mapping, as->lower[d]);
4762 	  gfc_apply_interface_mapping_to_expr (mapping, as->upper[d]);
4763 	}
4764 
4765       expr->value.function.esym->as = as;
4766     }
4767 
4768   if (map_expr->symtree->n.sym->ts.type == BT_CHARACTER)
4769     {
4770       expr->value.function.esym->ts.u.cl->length
4771 	= gfc_copy_expr (map_expr->symtree->n.sym->ts.u.cl->length);
4772 
4773       gfc_apply_interface_mapping_to_expr (mapping,
4774 			expr->value.function.esym->ts.u.cl->length);
4775     }
4776 }
4777 
4778 
4779 /* EXPR is a copy of an expression that appeared in the interface
4780    associated with MAPPING.  Walk it recursively looking for references to
4781    dummy arguments that MAPPING maps to actual arguments.  Replace each such
4782    reference with a reference to the associated actual argument.  */
4783 
4784 static void
gfc_apply_interface_mapping_to_expr(gfc_interface_mapping * mapping,gfc_expr * expr)4785 gfc_apply_interface_mapping_to_expr (gfc_interface_mapping * mapping,
4786 				     gfc_expr * expr)
4787 {
4788   gfc_interface_sym_mapping *sym;
4789   gfc_actual_arglist *actual;
4790 
4791   if (!expr)
4792     return;
4793 
4794   /* Copying an expression does not copy its length, so do that here.  */
4795   if (expr->ts.type == BT_CHARACTER && expr->ts.u.cl)
4796     {
4797       expr->ts.u.cl = gfc_get_interface_mapping_charlen (mapping, expr->ts.u.cl);
4798       gfc_apply_interface_mapping_to_expr (mapping, expr->ts.u.cl->length);
4799     }
4800 
4801   /* Apply the mapping to any references.  */
4802   gfc_apply_interface_mapping_to_ref (mapping, expr->ref);
4803 
4804   /* ...and to the expression's symbol, if it has one.  */
4805   /* TODO Find out why the condition on expr->symtree had to be moved into
4806      the loop rather than being outside it, as originally.  */
4807   for (sym = mapping->syms; sym; sym = sym->next)
4808     if (expr->symtree && sym->old == expr->symtree->n.sym)
4809       {
4810 	if (sym->new_sym->n.sym->backend_decl)
4811 	  expr->symtree = sym->new_sym;
4812 	else if (sym->expr)
4813 	  gfc_replace_expr (expr, gfc_copy_expr (sym->expr));
4814       }
4815 
4816       /* ...and to subexpressions in expr->value.  */
4817   switch (expr->expr_type)
4818     {
4819     case EXPR_VARIABLE:
4820     case EXPR_CONSTANT:
4821     case EXPR_NULL:
4822     case EXPR_SUBSTRING:
4823       break;
4824 
4825     case EXPR_OP:
4826       gfc_apply_interface_mapping_to_expr (mapping, expr->value.op.op1);
4827       gfc_apply_interface_mapping_to_expr (mapping, expr->value.op.op2);
4828       break;
4829 
4830     case EXPR_FUNCTION:
4831       for (actual = expr->value.function.actual; actual; actual = actual->next)
4832 	gfc_apply_interface_mapping_to_expr (mapping, actual->expr);
4833 
4834       if (expr->value.function.esym == NULL
4835 	    && expr->value.function.isym != NULL
4836 	    && expr->value.function.actual
4837 	    && expr->value.function.actual->expr
4838 	    && expr->value.function.actual->expr->symtree
4839 	    && gfc_map_intrinsic_function (expr, mapping))
4840 	break;
4841 
4842       for (sym = mapping->syms; sym; sym = sym->next)
4843 	if (sym->old == expr->value.function.esym)
4844 	  {
4845 	    expr->value.function.esym = sym->new_sym->n.sym;
4846 	    gfc_map_fcn_formal_to_actual (expr, sym->expr, mapping);
4847 	    expr->value.function.esym->result = sym->new_sym->n.sym;
4848 	  }
4849       break;
4850 
4851     case EXPR_ARRAY:
4852     case EXPR_STRUCTURE:
4853       gfc_apply_interface_mapping_to_cons (mapping, expr->value.constructor);
4854       break;
4855 
4856     case EXPR_COMPCALL:
4857     case EXPR_PPC:
4858     case EXPR_UNKNOWN:
4859       gcc_unreachable ();
4860       break;
4861     }
4862 
4863   return;
4864 }
4865 
4866 
4867 /* Evaluate interface expression EXPR using MAPPING.  Store the result
4868    in SE.  */
4869 
4870 void
gfc_apply_interface_mapping(gfc_interface_mapping * mapping,gfc_se * se,gfc_expr * expr)4871 gfc_apply_interface_mapping (gfc_interface_mapping * mapping,
4872 			     gfc_se * se, gfc_expr * expr)
4873 {
4874   expr = gfc_copy_expr (expr);
4875   gfc_apply_interface_mapping_to_expr (mapping, expr);
4876   gfc_conv_expr (se, expr);
4877   se->expr = gfc_evaluate_now (se->expr, &se->pre);
4878   gfc_free_expr (expr);
4879 }
4880 
4881 
4882 /* Returns a reference to a temporary array into which a component of
4883    an actual argument derived type array is copied and then returned
4884    after the function call.  */
4885 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)4886 gfc_conv_subref_array_arg (gfc_se *se, gfc_expr * expr, int g77,
4887 			   sym_intent intent, bool formal_ptr,
4888 			   const gfc_symbol *fsym, const char *proc_name,
4889 			   gfc_symbol *sym, bool check_contiguous)
4890 {
4891   gfc_se lse;
4892   gfc_se rse;
4893   gfc_ss *lss;
4894   gfc_ss *rss;
4895   gfc_loopinfo loop;
4896   gfc_loopinfo loop2;
4897   gfc_array_info *info;
4898   tree offset;
4899   tree tmp_index;
4900   tree tmp;
4901   tree base_type;
4902   tree size;
4903   stmtblock_t body;
4904   int n;
4905   int dimen;
4906   gfc_se work_se;
4907   gfc_se *parmse;
4908   bool pass_optional;
4909 
4910   pass_optional = fsym && fsym->attr.optional && sym && sym->attr.optional;
4911 
4912   if (pass_optional || check_contiguous)
4913     {
4914       gfc_init_se (&work_se, NULL);
4915       parmse = &work_se;
4916     }
4917   else
4918     parmse = se;
4919 
4920   if (gfc_option.rtcheck & GFC_RTCHECK_ARRAY_TEMPS)
4921     {
4922       /* We will create a temporary array, so let us warn.  */
4923       char * msg;
4924 
4925       if (fsym && proc_name)
4926 	msg = xasprintf ("An array temporary was created for argument "
4927 			 "'%s' of procedure '%s'", fsym->name, proc_name);
4928       else
4929 	msg = xasprintf ("An array temporary was created");
4930 
4931       tmp = build_int_cst (logical_type_node, 1);
4932       gfc_trans_runtime_check (false, true, tmp, &parmse->pre,
4933 			       &expr->where, msg);
4934       free (msg);
4935     }
4936 
4937   gfc_init_se (&lse, NULL);
4938   gfc_init_se (&rse, NULL);
4939 
4940   /* Walk the argument expression.  */
4941   rss = gfc_walk_expr (expr);
4942 
4943   gcc_assert (rss != gfc_ss_terminator);
4944 
4945   /* Initialize the scalarizer.  */
4946   gfc_init_loopinfo (&loop);
4947   gfc_add_ss_to_loop (&loop, rss);
4948 
4949   /* Calculate the bounds of the scalarization.  */
4950   gfc_conv_ss_startstride (&loop);
4951 
4952   /* Build an ss for the temporary.  */
4953   if (expr->ts.type == BT_CHARACTER && !expr->ts.u.cl->backend_decl)
4954     gfc_conv_string_length (expr->ts.u.cl, expr, &parmse->pre);
4955 
4956   base_type = gfc_typenode_for_spec (&expr->ts);
4957   if (GFC_ARRAY_TYPE_P (base_type)
4958 		|| GFC_DESCRIPTOR_TYPE_P (base_type))
4959     base_type = gfc_get_element_type (base_type);
4960 
4961   if (expr->ts.type == BT_CLASS)
4962     base_type = gfc_typenode_for_spec (&CLASS_DATA (expr)->ts);
4963 
4964   loop.temp_ss = gfc_get_temp_ss (base_type, ((expr->ts.type == BT_CHARACTER)
4965 					      ? expr->ts.u.cl->backend_decl
4966 					      : NULL),
4967 				  loop.dimen);
4968 
4969   parmse->string_length = loop.temp_ss->info->string_length;
4970 
4971   /* Associate the SS with the loop.  */
4972   gfc_add_ss_to_loop (&loop, loop.temp_ss);
4973 
4974   /* Setup the scalarizing loops.  */
4975   gfc_conv_loop_setup (&loop, &expr->where);
4976 
4977   /* Pass the temporary descriptor back to the caller.  */
4978   info = &loop.temp_ss->info->data.array;
4979   parmse->expr = info->descriptor;
4980 
4981   /* Setup the gfc_se structures.  */
4982   gfc_copy_loopinfo_to_se (&lse, &loop);
4983   gfc_copy_loopinfo_to_se (&rse, &loop);
4984 
4985   rse.ss = rss;
4986   lse.ss = loop.temp_ss;
4987   gfc_mark_ss_chain_used (rss, 1);
4988   gfc_mark_ss_chain_used (loop.temp_ss, 1);
4989 
4990   /* Start the scalarized loop body.  */
4991   gfc_start_scalarized_body (&loop, &body);
4992 
4993   /* Translate the expression.  */
4994   gfc_conv_expr (&rse, expr);
4995 
4996   /* Reset the offset for the function call since the loop
4997      is zero based on the data pointer.  Note that the temp
4998      comes first in the loop chain since it is added second.  */
4999   if (gfc_is_class_array_function (expr))
5000     {
5001       tmp = loop.ss->loop_chain->info->data.array.descriptor;
5002       gfc_conv_descriptor_offset_set (&loop.pre, tmp,
5003 				      gfc_index_zero_node);
5004     }
5005 
5006   gfc_conv_tmp_array_ref (&lse);
5007 
5008   if (intent != INTENT_OUT)
5009     {
5010       tmp = gfc_trans_scalar_assign (&lse, &rse, expr->ts, false, false);
5011       gfc_add_expr_to_block (&body, tmp);
5012       gcc_assert (rse.ss == gfc_ss_terminator);
5013       gfc_trans_scalarizing_loops (&loop, &body);
5014     }
5015   else
5016     {
5017       /* Make sure that the temporary declaration survives by merging
5018        all the loop declarations into the current context.  */
5019       for (n = 0; n < loop.dimen; n++)
5020 	{
5021 	  gfc_merge_block_scope (&body);
5022 	  body = loop.code[loop.order[n]];
5023 	}
5024       gfc_merge_block_scope (&body);
5025     }
5026 
5027   /* Add the post block after the second loop, so that any
5028      freeing of allocated memory is done at the right time.  */
5029   gfc_add_block_to_block (&parmse->pre, &loop.pre);
5030 
5031   /**********Copy the temporary back again.*********/
5032 
5033   gfc_init_se (&lse, NULL);
5034   gfc_init_se (&rse, NULL);
5035 
5036   /* Walk the argument expression.  */
5037   lss = gfc_walk_expr (expr);
5038   rse.ss = loop.temp_ss;
5039   lse.ss = lss;
5040 
5041   /* Initialize the scalarizer.  */
5042   gfc_init_loopinfo (&loop2);
5043   gfc_add_ss_to_loop (&loop2, lss);
5044 
5045   dimen = rse.ss->dimen;
5046 
5047   /* Skip the write-out loop for this case.  */
5048   if (gfc_is_class_array_function (expr))
5049     goto class_array_fcn;
5050 
5051   /* Calculate the bounds of the scalarization.  */
5052   gfc_conv_ss_startstride (&loop2);
5053 
5054   /* Setup the scalarizing loops.  */
5055   gfc_conv_loop_setup (&loop2, &expr->where);
5056 
5057   gfc_copy_loopinfo_to_se (&lse, &loop2);
5058   gfc_copy_loopinfo_to_se (&rse, &loop2);
5059 
5060   gfc_mark_ss_chain_used (lss, 1);
5061   gfc_mark_ss_chain_used (loop.temp_ss, 1);
5062 
5063   /* Declare the variable to hold the temporary offset and start the
5064      scalarized loop body.  */
5065   offset = gfc_create_var (gfc_array_index_type, NULL);
5066   gfc_start_scalarized_body (&loop2, &body);
5067 
5068   /* Build the offsets for the temporary from the loop variables.  The
5069      temporary array has lbounds of zero and strides of one in all
5070      dimensions, so this is very simple.  The offset is only computed
5071      outside the innermost loop, so the overall transfer could be
5072      optimized further.  */
5073   info = &rse.ss->info->data.array;
5074 
5075   tmp_index = gfc_index_zero_node;
5076   for (n = dimen - 1; n > 0; n--)
5077     {
5078       tree tmp_str;
5079       tmp = rse.loop->loopvar[n];
5080       tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
5081 			     tmp, rse.loop->from[n]);
5082       tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
5083 			     tmp, tmp_index);
5084 
5085       tmp_str = fold_build2_loc (input_location, MINUS_EXPR,
5086 				 gfc_array_index_type,
5087 				 rse.loop->to[n-1], rse.loop->from[n-1]);
5088       tmp_str = fold_build2_loc (input_location, PLUS_EXPR,
5089 				 gfc_array_index_type,
5090 				 tmp_str, gfc_index_one_node);
5091 
5092       tmp_index = fold_build2_loc (input_location, MULT_EXPR,
5093 				   gfc_array_index_type, tmp, tmp_str);
5094     }
5095 
5096   tmp_index = fold_build2_loc (input_location, MINUS_EXPR,
5097 			       gfc_array_index_type,
5098 			       tmp_index, rse.loop->from[0]);
5099   gfc_add_modify (&rse.loop->code[0], offset, tmp_index);
5100 
5101   tmp_index = fold_build2_loc (input_location, PLUS_EXPR,
5102 			       gfc_array_index_type,
5103 			       rse.loop->loopvar[0], offset);
5104 
5105   /* Now use the offset for the reference.  */
5106   tmp = build_fold_indirect_ref_loc (input_location,
5107 				 info->data);
5108   rse.expr = gfc_build_array_ref (tmp, tmp_index, NULL);
5109 
5110   if (expr->ts.type == BT_CHARACTER)
5111     rse.string_length = expr->ts.u.cl->backend_decl;
5112 
5113   gfc_conv_expr (&lse, expr);
5114 
5115   gcc_assert (lse.ss == gfc_ss_terminator);
5116 
5117   tmp = gfc_trans_scalar_assign (&lse, &rse, expr->ts, false, true);
5118   gfc_add_expr_to_block (&body, tmp);
5119 
5120   /* Generate the copying loops.  */
5121   gfc_trans_scalarizing_loops (&loop2, &body);
5122 
5123   /* Wrap the whole thing up by adding the second loop to the post-block
5124      and following it by the post-block of the first loop.  In this way,
5125      if the temporary needs freeing, it is done after use!  */
5126   if (intent != INTENT_IN)
5127     {
5128       gfc_add_block_to_block (&parmse->post, &loop2.pre);
5129       gfc_add_block_to_block (&parmse->post, &loop2.post);
5130     }
5131 
5132 class_array_fcn:
5133 
5134   gfc_add_block_to_block (&parmse->post, &loop.post);
5135 
5136   gfc_cleanup_loop (&loop);
5137   gfc_cleanup_loop (&loop2);
5138 
5139   /* Pass the string length to the argument expression.  */
5140   if (expr->ts.type == BT_CHARACTER)
5141     parmse->string_length = expr->ts.u.cl->backend_decl;
5142 
5143   /* Determine the offset for pointer formal arguments and set the
5144      lbounds to one.  */
5145   if (formal_ptr)
5146     {
5147       size = gfc_index_one_node;
5148       offset = gfc_index_zero_node;
5149       for (n = 0; n < dimen; n++)
5150 	{
5151 	  tmp = gfc_conv_descriptor_ubound_get (parmse->expr,
5152 						gfc_rank_cst[n]);
5153 	  tmp = fold_build2_loc (input_location, PLUS_EXPR,
5154 				 gfc_array_index_type, tmp,
5155 				 gfc_index_one_node);
5156 	  gfc_conv_descriptor_ubound_set (&parmse->pre,
5157 					  parmse->expr,
5158 					  gfc_rank_cst[n],
5159 					  tmp);
5160 	  gfc_conv_descriptor_lbound_set (&parmse->pre,
5161 					  parmse->expr,
5162 					  gfc_rank_cst[n],
5163 					  gfc_index_one_node);
5164 	  size = gfc_evaluate_now (size, &parmse->pre);
5165 	  offset = fold_build2_loc (input_location, MINUS_EXPR,
5166 				    gfc_array_index_type,
5167 				    offset, size);
5168 	  offset = gfc_evaluate_now (offset, &parmse->pre);
5169 	  tmp = fold_build2_loc (input_location, MINUS_EXPR,
5170 				 gfc_array_index_type,
5171 				 rse.loop->to[n], rse.loop->from[n]);
5172 	  tmp = fold_build2_loc (input_location, PLUS_EXPR,
5173 				 gfc_array_index_type,
5174 				 tmp, gfc_index_one_node);
5175 	  size = fold_build2_loc (input_location, MULT_EXPR,
5176 				  gfc_array_index_type, size, tmp);
5177 	}
5178 
5179       gfc_conv_descriptor_offset_set (&parmse->pre, parmse->expr,
5180 				      offset);
5181     }
5182 
5183   /* We want either the address for the data or the address of the descriptor,
5184      depending on the mode of passing array arguments.  */
5185   if (g77)
5186     parmse->expr = gfc_conv_descriptor_data_get (parmse->expr);
5187   else
5188     parmse->expr = gfc_build_addr_expr (NULL_TREE, parmse->expr);
5189 
5190   /* Basically make this into
5191 
5192      if (present)
5193        {
5194 	 if (contiguous)
5195 	   {
5196 	     pointer = a;
5197 	   }
5198 	 else
5199 	   {
5200 	     parmse->pre();
5201 	     pointer = parmse->expr;
5202 	   }
5203        }
5204      else
5205        pointer = NULL;
5206 
5207      foo (pointer);
5208      if (present && !contiguous)
5209 	   se->post();
5210 
5211      */
5212 
5213   if (pass_optional || check_contiguous)
5214     {
5215       tree type;
5216       stmtblock_t else_block;
5217       tree pre_stmts, post_stmts;
5218       tree pointer;
5219       tree else_stmt;
5220       tree present_var = NULL_TREE;
5221       tree cont_var = NULL_TREE;
5222       tree post_cond;
5223 
5224       type = TREE_TYPE (parmse->expr);
5225       if (POINTER_TYPE_P (type) && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (type)))
5226 	type = TREE_TYPE (type);
5227       pointer = gfc_create_var (type, "arg_ptr");
5228 
5229       if (check_contiguous)
5230 	{
5231 	  gfc_se cont_se, array_se;
5232 	  stmtblock_t if_block, else_block;
5233 	  tree if_stmt, else_stmt;
5234 	  mpz_t size;
5235 	  bool size_set;
5236 
5237 	  cont_var = gfc_create_var (boolean_type_node, "contiguous");
5238 
5239 	  /* If the size is known to be one at compile-time, set
5240 	     cont_var to true unconditionally.  This may look
5241 	     inelegant, but we're only doing this during
5242 	     optimization, so the statements will be optimized away,
5243 	     and this saves complexity here.  */
5244 
5245 	  size_set = gfc_array_size (expr, &size);
5246 	  if (size_set && mpz_cmp_ui (size, 1) == 0)
5247 	    {
5248 	      gfc_add_modify (&se->pre, cont_var,
5249 			      build_one_cst (boolean_type_node));
5250 	    }
5251 	  else
5252 	    {
5253 	      /* cont_var = is_contiguous (expr); .  */
5254 	      gfc_init_se (&cont_se, parmse);
5255 	      gfc_conv_is_contiguous_expr (&cont_se, expr);
5256 	      gfc_add_block_to_block (&se->pre, &(&cont_se)->pre);
5257 	      gfc_add_modify (&se->pre, cont_var, cont_se.expr);
5258 	      gfc_add_block_to_block (&se->pre, &(&cont_se)->post);
5259 	    }
5260 
5261 	  if (size_set)
5262 	    mpz_clear (size);
5263 
5264 	  /* arrayse->expr = descriptor of a.  */
5265 	  gfc_init_se (&array_se, se);
5266 	  gfc_conv_expr_descriptor (&array_se, expr);
5267 	  gfc_add_block_to_block (&se->pre, &(&array_se)->pre);
5268 	  gfc_add_block_to_block (&se->pre, &(&array_se)->post);
5269 
5270 	  /* if_stmt = { descriptor ? pointer = a : pointer = &a[0]; } .  */
5271 	  gfc_init_block (&if_block);
5272 	  if (GFC_DESCRIPTOR_TYPE_P (type))
5273 	    gfc_add_modify (&if_block, pointer, array_se.expr);
5274 	  else
5275 	    {
5276 	      tmp = gfc_conv_array_data (array_se.expr);
5277 	      tmp = fold_convert (type, tmp);
5278 	      gfc_add_modify (&if_block, pointer, tmp);
5279 	    }
5280 	  if_stmt = gfc_finish_block (&if_block);
5281 
5282 	  /* else_stmt = { parmse->pre(); pointer = parmse->expr; } .  */
5283 	  gfc_init_block (&else_block);
5284 	  gfc_add_block_to_block (&else_block, &parmse->pre);
5285 	  tmp = (GFC_DESCRIPTOR_TYPE_P (type)
5286 		 ? build_fold_indirect_ref_loc (input_location, parmse->expr)
5287 		 : parmse->expr);
5288 	  gfc_add_modify (&else_block, pointer, tmp);
5289 	  else_stmt = gfc_finish_block (&else_block);
5290 
5291 	  /* And put the above into an if statement.  */
5292 	  pre_stmts = fold_build3_loc (input_location, COND_EXPR, void_type_node,
5293 				       gfc_likely (cont_var,
5294 						   PRED_FORTRAN_CONTIGUOUS),
5295 				       if_stmt, else_stmt);
5296 	}
5297       else
5298 	{
5299 	  /* pointer = pramse->expr;  .  */
5300 	  gfc_add_modify (&parmse->pre, pointer, parmse->expr);
5301 	  pre_stmts = gfc_finish_block (&parmse->pre);
5302 	}
5303 
5304       if (pass_optional)
5305 	{
5306 	  present_var = gfc_create_var (boolean_type_node, "present");
5307 
5308 	  /* present_var = present(sym); .  */
5309 	  tmp = gfc_conv_expr_present (sym);
5310 	  tmp = fold_convert (boolean_type_node, tmp);
5311 	  gfc_add_modify (&se->pre, present_var, tmp);
5312 
5313 	  /* else_stmt = { pointer = NULL; } .  */
5314 	  gfc_init_block (&else_block);
5315 	  if (GFC_DESCRIPTOR_TYPE_P (type))
5316 	    gfc_conv_descriptor_data_set (&else_block, pointer,
5317 					  null_pointer_node);
5318 	  else
5319 	    gfc_add_modify (&else_block, pointer, build_int_cst (type, 0));
5320 	  else_stmt = gfc_finish_block (&else_block);
5321 
5322 	  tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
5323 				 gfc_likely (present_var,
5324 					     PRED_FORTRAN_ABSENT_DUMMY),
5325 				 pre_stmts, else_stmt);
5326 	  gfc_add_expr_to_block (&se->pre, tmp);
5327 	}
5328       else
5329 	gfc_add_expr_to_block (&se->pre, pre_stmts);
5330 
5331       post_stmts = gfc_finish_block (&parmse->post);
5332 
5333       /* Put together the post stuff, plus the optional
5334 	 deallocation.  */
5335       if (check_contiguous)
5336 	{
5337 	  /* !cont_var.  */
5338 	  tmp = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
5339 				 cont_var,
5340 				 build_zero_cst (boolean_type_node));
5341 	  tmp = gfc_unlikely (tmp, PRED_FORTRAN_CONTIGUOUS);
5342 
5343 	  if (pass_optional)
5344 	    {
5345 	      tree present_likely = gfc_likely (present_var,
5346 						PRED_FORTRAN_ABSENT_DUMMY);
5347 	      post_cond = fold_build2_loc (input_location, TRUTH_ANDIF_EXPR,
5348 					   boolean_type_node, present_likely,
5349 					   tmp);
5350 	    }
5351 	  else
5352 	    post_cond = tmp;
5353 	}
5354       else
5355 	{
5356 	  gcc_assert (pass_optional);
5357 	  post_cond = present_var;
5358 	}
5359 
5360       tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, post_cond,
5361 			     post_stmts, build_empty_stmt (input_location));
5362       gfc_add_expr_to_block (&se->post, tmp);
5363       if (GFC_DESCRIPTOR_TYPE_P (type))
5364 	{
5365 	  type = TREE_TYPE (parmse->expr);
5366 	  if (POINTER_TYPE_P (type))
5367 	    {
5368 	      pointer = gfc_build_addr_expr (type, pointer);
5369 	      if (pass_optional)
5370 		{
5371 		  tmp = gfc_likely (present_var, PRED_FORTRAN_ABSENT_DUMMY);
5372 		  pointer = fold_build3_loc (input_location, COND_EXPR, type,
5373 					     tmp, pointer,
5374 					     fold_convert (type,
5375 							   null_pointer_node));
5376 		}
5377 	    }
5378 	  else
5379 	    gcc_assert (!pass_optional);
5380 	}
5381       se->expr = pointer;
5382     }
5383 
5384   return;
5385 }
5386 
5387 
5388 /* Generate the code for argument list functions.  */
5389 
5390 static void
conv_arglist_function(gfc_se * se,gfc_expr * expr,const char * name)5391 conv_arglist_function (gfc_se *se, gfc_expr *expr, const char *name)
5392 {
5393   /* Pass by value for g77 %VAL(arg), pass the address
5394      indirectly for %LOC, else by reference.  Thus %REF
5395      is a "do-nothing" and %LOC is the same as an F95
5396      pointer.  */
5397   if (strcmp (name, "%VAL") == 0)
5398     gfc_conv_expr (se, expr);
5399   else if (strcmp (name, "%LOC") == 0)
5400     {
5401       gfc_conv_expr_reference (se, expr);
5402       se->expr = gfc_build_addr_expr (NULL, se->expr);
5403     }
5404   else if (strcmp (name, "%REF") == 0)
5405     gfc_conv_expr_reference (se, expr);
5406   else
5407     gfc_error ("Unknown argument list function at %L", &expr->where);
5408 }
5409 
5410 
5411 /* This function tells whether the middle-end representation of the expression
5412    E given as input may point to data otherwise accessible through a variable
5413    (sub-)reference.
5414    It is assumed that the only expressions that may alias are variables,
5415    and array constructors if ARRAY_MAY_ALIAS is true and some of its elements
5416    may alias.
5417    This function is used to decide whether freeing an expression's allocatable
5418    components is safe or should be avoided.
5419 
5420    If ARRAY_MAY_ALIAS is true, an array constructor may alias if some of
5421    its elements are copied from a variable.  This ARRAY_MAY_ALIAS trick
5422    is necessary because for array constructors, aliasing depends on how
5423    the array is used:
5424     - If E is an array constructor used as argument to an elemental procedure,
5425       the array, which is generated through shallow copy by the scalarizer,
5426       is used directly and can alias the expressions it was copied from.
5427     - If E is an array constructor used as argument to a non-elemental
5428       procedure,the scalarizer is used in gfc_conv_expr_descriptor to generate
5429       the array as in the previous case, but then that array is used
5430       to initialize a new descriptor through deep copy.  There is no alias
5431       possible in that case.
5432    Thus, the ARRAY_MAY_ALIAS flag is necessary to distinguish the two cases
5433    above.  */
5434 
5435 static bool
expr_may_alias_variables(gfc_expr * e,bool array_may_alias)5436 expr_may_alias_variables (gfc_expr *e, bool array_may_alias)
5437 {
5438   gfc_constructor *c;
5439 
5440   if (e->expr_type == EXPR_VARIABLE)
5441     return true;
5442   else if (e->expr_type == EXPR_FUNCTION)
5443     {
5444       gfc_symbol *proc_ifc = gfc_get_proc_ifc_for_expr (e);
5445 
5446       if (proc_ifc->result != NULL
5447 	  && ((proc_ifc->result->ts.type == BT_CLASS
5448 	       && proc_ifc->result->ts.u.derived->attr.is_class
5449 	       && CLASS_DATA (proc_ifc->result)->attr.class_pointer)
5450 	      || proc_ifc->result->attr.pointer))
5451 	return true;
5452       else
5453 	return false;
5454     }
5455   else if (e->expr_type != EXPR_ARRAY || !array_may_alias)
5456     return false;
5457 
5458   for (c = gfc_constructor_first (e->value.constructor);
5459        c; c = gfc_constructor_next (c))
5460     if (c->expr
5461 	&& expr_may_alias_variables (c->expr, array_may_alias))
5462       return true;
5463 
5464   return false;
5465 }
5466 
5467 
5468 /* A helper function to set the dtype for unallocated or unassociated
5469    entities.  */
5470 
5471 static void
set_dtype_for_unallocated(gfc_se * parmse,gfc_expr * e)5472 set_dtype_for_unallocated (gfc_se *parmse, gfc_expr *e)
5473 {
5474   tree tmp;
5475   tree desc;
5476   tree cond;
5477   tree type;
5478   stmtblock_t block;
5479 
5480   /* TODO Figure out how to handle optional dummies.  */
5481   if (e && e->expr_type == EXPR_VARIABLE
5482       && e->symtree->n.sym->attr.optional)
5483     return;
5484 
5485   desc = parmse->expr;
5486   if (desc == NULL_TREE)
5487     return;
5488 
5489   if (POINTER_TYPE_P (TREE_TYPE (desc)))
5490     desc = build_fold_indirect_ref_loc (input_location, desc);
5491   if (GFC_CLASS_TYPE_P (TREE_TYPE (desc)))
5492     desc = gfc_class_data_get (desc);
5493   if (!GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (desc)))
5494     return;
5495 
5496   gfc_init_block (&block);
5497   tmp = gfc_conv_descriptor_data_get (desc);
5498   cond = fold_build2_loc (input_location, EQ_EXPR,
5499 			  logical_type_node, tmp,
5500 			  build_int_cst (TREE_TYPE (tmp), 0));
5501   tmp = gfc_conv_descriptor_dtype (desc);
5502   type = gfc_get_element_type (TREE_TYPE (desc));
5503   tmp = fold_build2_loc (input_location, MODIFY_EXPR,
5504 			 TREE_TYPE (tmp), tmp,
5505 			 gfc_get_dtype_rank_type (e->rank, type));
5506   gfc_add_expr_to_block (&block, tmp);
5507   cond = build3_v (COND_EXPR, cond,
5508 		   gfc_finish_block (&block),
5509 		   build_empty_stmt (input_location));
5510   gfc_add_expr_to_block (&parmse->pre, cond);
5511 }
5512 
5513 
5514 
5515 /* Provide an interface between gfortran array descriptors and the F2018:18.4
5516    ISO_Fortran_binding array descriptors. */
5517 
5518 static void
gfc_conv_gfc_desc_to_cfi_desc(gfc_se * parmse,gfc_expr * e,gfc_symbol * fsym)5519 gfc_conv_gfc_desc_to_cfi_desc (gfc_se *parmse, gfc_expr *e, gfc_symbol *fsym)
5520 {
5521   stmtblock_t block, block2;
5522   tree cfi, gfc, tmp, tmp2;
5523   tree present = NULL;
5524   tree gfc_strlen = NULL;
5525   tree rank;
5526   gfc_se se;
5527 
5528   if (fsym->attr.optional
5529       && e->expr_type == EXPR_VARIABLE
5530       && e->symtree->n.sym->attr.optional)
5531     present = gfc_conv_expr_present (e->symtree->n.sym);
5532 
5533   gfc_init_block (&block);
5534 
5535   /* Convert original argument to a tree. */
5536   gfc_init_se (&se, NULL);
5537   if (e->rank == 0)
5538     {
5539       se.want_pointer = 1;
5540       gfc_conv_expr (&se, e);
5541       gfc = se.expr;
5542       /* gfc_conv_constant ignores se.want_poiner, e.g. for string_cst.  */
5543       if (!POINTER_TYPE_P (TREE_TYPE (gfc)))
5544 	gfc = gfc_build_addr_expr (NULL, gfc);
5545     }
5546   else
5547     {
5548       /* If the actual argument can be noncontiguous, copy-in/out is required,
5549 	 if the dummy has either the CONTIGUOUS attribute or is an assumed-
5550 	 length assumed-length/assumed-size CHARACTER array.  This only
5551 	 applies if the actual argument is a "variable"; if it's some
5552 	 non-lvalue expression, we are going to evaluate it to a
5553 	 temporary below anyway.  */
5554       se.force_no_tmp = 1;
5555       if ((fsym->attr.contiguous
5556 	   || (fsym->ts.type == BT_CHARACTER && !fsym->ts.u.cl->length
5557 	       && (fsym->as->type == AS_ASSUMED_SIZE
5558 		   || fsym->as->type == AS_EXPLICIT)))
5559 	  && !gfc_is_simply_contiguous (e, false, true)
5560 	  && gfc_expr_is_variable (e))
5561 	{
5562 	  bool optional = fsym->attr.optional;
5563 	  fsym->attr.optional = 0;
5564 	  gfc_conv_subref_array_arg (&se, e, false, fsym->attr.intent,
5565 				     fsym->attr.pointer, fsym,
5566 				     fsym->ns->proc_name->name, NULL,
5567 				     /* check_contiguous= */ true);
5568 	  fsym->attr.optional = optional;
5569 	}
5570       else
5571 	gfc_conv_expr_descriptor (&se, e);
5572       gfc = se.expr;
5573       /* For dt(:)%var the elem_len*stride != sm, hence, GFC uses
5574 	 elem_len = sizeof(dt) and base_addr = dt(lb) instead.
5575 	 gfc_get_dataptr_offset fixes the base_addr; for elem_len, see below.
5576 	 While sm is fine as it uses span*stride and not elem_len.  */
5577       if (POINTER_TYPE_P (TREE_TYPE (gfc)))
5578 	gfc = build_fold_indirect_ref_loc (input_location, gfc);
5579       else if (is_subref_array (e) && e->ts.type != BT_CHARACTER)
5580 	 gfc_get_dataptr_offset (&se.pre, gfc, gfc, NULL, true, e);
5581     }
5582   if (e->ts.type == BT_CHARACTER)
5583     {
5584       if (se.string_length)
5585 	gfc_strlen = se.string_length;
5586       else if (e->ts.u.cl->backend_decl)
5587 	gfc_strlen = e->ts.u.cl->backend_decl;
5588       else
5589 	gcc_unreachable ();
5590     }
5591   gfc_add_block_to_block (&block, &se.pre);
5592 
5593   /* Create array decriptor and set version, rank, attribute, type. */
5594   cfi = gfc_create_var (gfc_get_cfi_type (e->rank < 0
5595 					  ? GFC_MAX_DIMENSIONS : e->rank,
5596 					  false), "cfi");
5597   /* Convert to CFI_cdesc_t, which has dim[] to avoid TBAA issues,*/
5598   if (fsym->attr.dimension && fsym->as->type == AS_ASSUMED_RANK)
5599     {
5600       tmp = gfc_get_cfi_type (-1, !fsym->attr.pointer && !fsym->attr.target);
5601       tmp = build_pointer_type (tmp);
5602       parmse->expr = cfi = gfc_build_addr_expr (tmp, cfi);
5603       cfi = build_fold_indirect_ref_loc (input_location, cfi);
5604     }
5605   else
5606     parmse->expr = gfc_build_addr_expr (NULL, cfi);
5607 
5608   tmp = gfc_get_cfi_desc_version (cfi);
5609   gfc_add_modify (&block, tmp,
5610 		  build_int_cst (TREE_TYPE (tmp), CFI_VERSION));
5611   if (e->rank < 0)
5612     rank = fold_convert (signed_char_type_node, gfc_conv_descriptor_rank (gfc));
5613   else
5614     rank = build_int_cst (signed_char_type_node, e->rank);
5615   tmp = gfc_get_cfi_desc_rank (cfi);
5616   gfc_add_modify (&block, tmp, rank);
5617   int itype = CFI_type_other;
5618   if (e->ts.f90_type == BT_VOID)
5619     itype = (e->ts.u.derived->intmod_sym_id == ISOCBINDING_FUNPTR
5620 	     ? CFI_type_cfunptr : CFI_type_cptr);
5621   else
5622     {
5623       if (e->expr_type == EXPR_NULL && e->ts.type == BT_UNKNOWN)
5624 	e->ts = fsym->ts;
5625       switch (e->ts.type)
5626 	{
5627 	case BT_INTEGER:
5628 	case BT_LOGICAL:
5629 	case BT_REAL:
5630 	case BT_COMPLEX:
5631 	  itype = CFI_type_from_type_kind (e->ts.type, e->ts.kind);
5632 	  break;
5633 	case BT_CHARACTER:
5634 	  itype = CFI_type_from_type_kind (CFI_type_Character, e->ts.kind);
5635 	  break;
5636 	case BT_DERIVED:
5637 	  itype = CFI_type_struct;
5638 	  break;
5639 	case BT_VOID:
5640 	  itype = (e->ts.u.derived->intmod_sym_id == ISOCBINDING_FUNPTR
5641 		   ? CFI_type_cfunptr : CFI_type_cptr);
5642 	  break;
5643 	case BT_ASSUMED:
5644 	  itype = CFI_type_other;  // FIXME: Or CFI_type_cptr ?
5645 	  break;
5646 	case BT_CLASS:
5647 	  if (UNLIMITED_POLY (e) && fsym->ts.type == BT_ASSUMED)
5648 	    {
5649 	      // F2017: 7.3.2.2: "An entity that is declared using the TYPE(*)
5650 	      // type specifier is assumed-type and is an unlimited polymorphic
5651 	      //  entity." The actual argument _data component is passed.
5652 	      itype = CFI_type_other;  // FIXME: Or CFI_type_cptr ?
5653 	      break;
5654 	    }
5655 	  else
5656 	    gcc_unreachable ();
5657 	case BT_PROCEDURE:
5658 	case BT_HOLLERITH:
5659 	case BT_UNION:
5660 	case BT_BOZ:
5661 	case BT_UNKNOWN:
5662 	  // FIXME: Really unreachable? Or reachable for type(*) ? If so, CFI_type_other?
5663 	  gcc_unreachable ();
5664 	}
5665     }
5666 
5667   tmp = gfc_get_cfi_desc_type (cfi);
5668   gfc_add_modify (&block, tmp,
5669 		  build_int_cst (TREE_TYPE (tmp), itype));
5670 
5671   int attr = CFI_attribute_other;
5672   if (fsym->attr.pointer)
5673     attr = CFI_attribute_pointer;
5674   else if (fsym->attr.allocatable)
5675     attr = CFI_attribute_allocatable;
5676   tmp = gfc_get_cfi_desc_attribute (cfi);
5677   gfc_add_modify (&block, tmp,
5678 		  build_int_cst (TREE_TYPE (tmp), attr));
5679 
5680   if (e->rank == 0)
5681     {
5682       tmp = gfc_get_cfi_desc_base_addr (cfi);
5683       gfc_add_modify (&block, tmp, fold_convert (TREE_TYPE (tmp), gfc));
5684     }
5685   else
5686     {
5687       tmp = gfc_get_cfi_desc_base_addr (cfi);
5688       tmp2 = gfc_conv_descriptor_data_get (gfc);
5689       gfc_add_modify (&block, tmp, fold_convert (TREE_TYPE (tmp), tmp2));
5690     }
5691 
5692   /* Set elem_len if known - must be before the next if block.
5693      Note that allocatable implies 'len=:'.  */
5694   if (e->ts.type != BT_ASSUMED && e->ts.type != BT_CHARACTER )
5695     {
5696       /* Length is known at compile time; use 'block' for it.  */
5697       tmp = size_in_bytes (gfc_typenode_for_spec (&e->ts));
5698       tmp2 = gfc_get_cfi_desc_elem_len (cfi);
5699       gfc_add_modify (&block, tmp2, fold_convert (TREE_TYPE (tmp2), tmp));
5700     }
5701 
5702   /* When allocatable + intent out, free the cfi descriptor.  */
5703   if (fsym->attr.allocatable && fsym->attr.intent == INTENT_OUT)
5704     {
5705       tmp = gfc_get_cfi_desc_base_addr (cfi);
5706       tree call = builtin_decl_explicit (BUILT_IN_FREE);
5707       call = build_call_expr_loc (input_location, call, 1, tmp);
5708       gfc_add_expr_to_block (&block, fold_convert (void_type_node, call));
5709       gfc_add_modify (&block, tmp,
5710 		      fold_convert (TREE_TYPE (tmp), null_pointer_node));
5711       goto done;
5712     }
5713 
5714   /* If not unallocated/unassociated. */
5715   gfc_init_block (&block2);
5716 
5717   /* Set elem_len, which may be only known at run time. */
5718   if (e->ts.type == BT_CHARACTER
5719       && (e->expr_type != EXPR_NULL || gfc_strlen != NULL_TREE))
5720     {
5721       gcc_assert (gfc_strlen);
5722       tmp = gfc_strlen;
5723       if (e->ts.kind != 1)
5724 	tmp = fold_build2_loc (input_location, MULT_EXPR,
5725 			       gfc_charlen_type_node, tmp,
5726 			       build_int_cst (gfc_charlen_type_node,
5727 					      e->ts.kind));
5728       tmp2 = gfc_get_cfi_desc_elem_len (cfi);
5729       gfc_add_modify (&block2, tmp2, fold_convert (TREE_TYPE (tmp2), tmp));
5730     }
5731   else if (e->ts.type == BT_ASSUMED)
5732     {
5733       tmp = gfc_conv_descriptor_elem_len (gfc);
5734       tmp2 = gfc_get_cfi_desc_elem_len (cfi);
5735       gfc_add_modify (&block2, tmp2, fold_convert (TREE_TYPE (tmp2), tmp));
5736     }
5737 
5738   if (e->ts.type == BT_ASSUMED)
5739     {
5740       /* Note: type(*) implies assumed-shape/assumed-rank if fsym requires
5741 	 an CFI descriptor.  Use the type in the descritor as it provide
5742 	 mode information. (Quality of implementation feature.)  */
5743       tree cond;
5744       tree ctype = gfc_get_cfi_desc_type (cfi);
5745       tree type = fold_convert (TREE_TYPE (ctype),
5746 				gfc_conv_descriptor_type (gfc));
5747       tree kind = fold_convert (TREE_TYPE (ctype),
5748 				gfc_conv_descriptor_elem_len (gfc));
5749       kind = fold_build2_loc (input_location, LSHIFT_EXPR, TREE_TYPE (type),
5750 			      kind, build_int_cst (TREE_TYPE (type),
5751 						   CFI_type_kind_shift));
5752 
5753       /* if (BT_VOID) CFI_type_cptr else CFI_type_other  */
5754       /* Note: BT_VOID is could also be CFI_type_funcptr, but assume c_ptr. */
5755       cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, type,
5756 			      build_int_cst (TREE_TYPE (type), BT_VOID));
5757       tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node, ctype,
5758 			     build_int_cst (TREE_TYPE (type), CFI_type_cptr));
5759       tmp2 = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node,
5760 			      ctype,
5761 			      build_int_cst (TREE_TYPE (type), CFI_type_other));
5762       tmp2 = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond,
5763 			      tmp, tmp2);
5764       /* if (BT_DERIVED) CFI_type_struct else  < tmp2 >  */
5765       cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, type,
5766 			      build_int_cst (TREE_TYPE (type), BT_DERIVED));
5767       tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node, ctype,
5768 			     build_int_cst (TREE_TYPE (type), CFI_type_struct));
5769       tmp2 = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond,
5770 			      tmp, tmp2);
5771       /* if (BT_CHARACTER) CFI_type_Character + kind=1 else  < tmp2 >  */
5772       /* Note: could also be kind=4, with cfi->elem_len = gfc->elem_len*4.  */
5773       cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, type,
5774 			      build_int_cst (TREE_TYPE (type), BT_CHARACTER));
5775       tmp = build_int_cst (TREE_TYPE (type),
5776 			   CFI_type_from_type_kind (CFI_type_Character, 1));
5777       tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node,
5778 			     ctype, tmp);
5779       tmp2 = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond,
5780 			      tmp, tmp2);
5781       /* if (BT_COMPLEX) CFI_type_Complex + kind/2 else  < tmp2 >  */
5782       cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, type,
5783 			      build_int_cst (TREE_TYPE (type), BT_COMPLEX));
5784       tmp = fold_build2_loc (input_location, TRUNC_DIV_EXPR, TREE_TYPE (type),
5785 			     kind, build_int_cst (TREE_TYPE (type), 2));
5786       tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (type), tmp,
5787 			     build_int_cst (TREE_TYPE (type),
5788 					    CFI_type_Complex));
5789       tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node,
5790 			     ctype, tmp);
5791       tmp2 = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond,
5792 			      tmp, tmp2);
5793       /* if (BT_INTEGER || BT_LOGICAL || BT_REAL) type + kind else  <tmp2>  */
5794       cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, type,
5795 			      build_int_cst (TREE_TYPE (type), BT_INTEGER));
5796       tmp = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, type,
5797 			      build_int_cst (TREE_TYPE (type), BT_LOGICAL));
5798       cond = fold_build2_loc (input_location, TRUTH_OR_EXPR, boolean_type_node,
5799 			      cond, tmp);
5800       tmp = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, type,
5801 			      build_int_cst (TREE_TYPE (type), BT_REAL));
5802       cond = fold_build2_loc (input_location, TRUTH_OR_EXPR, boolean_type_node,
5803 			      cond, tmp);
5804       tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (type),
5805 			     type, kind);
5806       tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node,
5807 			     ctype, tmp);
5808       tmp2 = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond,
5809 			      tmp, tmp2);
5810       gfc_add_expr_to_block (&block2, tmp2);
5811     }
5812 
5813   if (e->rank != 0)
5814     {
5815       /* Loop: for (i = 0; i < rank; ++i).  */
5816       tree idx = gfc_create_var (TREE_TYPE (rank), "idx");
5817       /* Loop body.  */
5818       stmtblock_t loop_body;
5819       gfc_init_block (&loop_body);
5820       /* cfi->dim[i].lower_bound = (allocatable/pointer)
5821 				   ? gfc->dim[i].lbound : 0 */
5822       if (fsym->attr.pointer || fsym->attr.allocatable)
5823 	tmp = gfc_conv_descriptor_lbound_get (gfc, idx);
5824       else
5825 	tmp = gfc_index_zero_node;
5826       gfc_add_modify (&loop_body, gfc_get_cfi_dim_lbound (cfi, idx), tmp);
5827       /* cfi->dim[i].extent = gfc->dim[i].ubound - gfc->dim[i].lbound + 1.  */
5828       tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
5829 			     gfc_conv_descriptor_ubound_get (gfc, idx),
5830 			     gfc_conv_descriptor_lbound_get (gfc, idx));
5831       tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
5832 			     tmp, gfc_index_one_node);
5833       gfc_add_modify (&loop_body, gfc_get_cfi_dim_extent (cfi, idx), tmp);
5834       /* d->dim[n].sm = gfc->dim[i].stride  * gfc->span); */
5835       tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
5836 			     gfc_conv_descriptor_stride_get (gfc, idx),
5837 			     gfc_conv_descriptor_span_get (gfc));
5838       gfc_add_modify (&loop_body, gfc_get_cfi_dim_sm (cfi, idx), tmp);
5839 
5840       /* Generate loop.  */
5841       gfc_simple_for_loop (&block2, idx, build_int_cst (TREE_TYPE (idx), 0),
5842 			   rank, LT_EXPR, build_int_cst (TREE_TYPE (idx), 1),
5843 			   gfc_finish_block (&loop_body));
5844 
5845       if (e->expr_type == EXPR_VARIABLE
5846 	  && e->ref
5847 	  && e->ref->u.ar.type == AR_FULL
5848 	  && e->symtree->n.sym->attr.dummy
5849 	  && e->symtree->n.sym->as
5850 	  && e->symtree->n.sym->as->type == AS_ASSUMED_SIZE)
5851 	{
5852 	  tmp = gfc_get_cfi_dim_extent (cfi, gfc_rank_cst[e->rank-1]),
5853 	  gfc_add_modify (&block2, tmp, build_int_cst (TREE_TYPE (tmp), -1));
5854 	}
5855     }
5856 
5857   if (fsym->attr.allocatable || fsym->attr.pointer)
5858     {
5859       tmp = gfc_get_cfi_desc_base_addr (cfi),
5860       tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
5861 			     tmp, null_pointer_node);
5862       tmp = build3_v (COND_EXPR, tmp, gfc_finish_block (&block2),
5863 		      build_empty_stmt (input_location));
5864       gfc_add_expr_to_block (&block, tmp);
5865     }
5866   else
5867     gfc_add_block_to_block (&block, &block2);
5868 
5869 
5870 done:
5871   if (present)
5872     {
5873       parmse->expr = build3_loc (input_location, COND_EXPR,
5874 				 TREE_TYPE (parmse->expr),
5875 				 present, parmse->expr, null_pointer_node);
5876       tmp = build3_v (COND_EXPR, present, gfc_finish_block (&block),
5877 		      build_empty_stmt (input_location));
5878       gfc_add_expr_to_block (&parmse->pre, tmp);
5879     }
5880   else
5881     gfc_add_block_to_block (&parmse->pre, &block);
5882 
5883   gfc_init_block (&block);
5884 
5885   if ((!fsym->attr.allocatable && !fsym->attr.pointer)
5886       || fsym->attr.intent == INTENT_IN)
5887     goto post_call;
5888 
5889   gfc_init_block (&block2);
5890   if (e->rank == 0)
5891     {
5892       tmp = gfc_get_cfi_desc_base_addr (cfi);
5893       gfc_add_modify (&block, gfc, fold_convert (TREE_TYPE (gfc), tmp));
5894     }
5895   else
5896     {
5897       tmp = gfc_get_cfi_desc_base_addr (cfi);
5898       gfc_conv_descriptor_data_set (&block, gfc, tmp);
5899 
5900       if (fsym->attr.allocatable)
5901 	{
5902 	  /* gfc->span = cfi->elem_len.  */
5903 	  tmp = fold_convert (gfc_array_index_type,
5904 			      gfc_get_cfi_dim_sm (cfi, gfc_rank_cst[0]));
5905 	}
5906       else
5907 	{
5908 	  /* gfc->span = ((cfi->dim[0].sm % cfi->elem_len)
5909 			  ? cfi->dim[0].sm : cfi->elem_len).  */
5910 	  tmp = gfc_get_cfi_dim_sm (cfi, gfc_rank_cst[0]);
5911 	  tmp2 = fold_convert (gfc_array_index_type,
5912 			       gfc_get_cfi_desc_elem_len (cfi));
5913 	  tmp = fold_build2_loc (input_location, TRUNC_MOD_EXPR,
5914 				 gfc_array_index_type, tmp, tmp2);
5915 	  tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
5916 			     tmp, gfc_index_zero_node);
5917 	  tmp = build3_loc (input_location, COND_EXPR, gfc_array_index_type, tmp,
5918 			    gfc_get_cfi_dim_sm (cfi, gfc_rank_cst[0]), tmp2);
5919 	}
5920       gfc_conv_descriptor_span_set (&block2, gfc, tmp);
5921 
5922       /* Calculate offset + set lbound, ubound and stride.  */
5923       gfc_conv_descriptor_offset_set (&block2, gfc, gfc_index_zero_node);
5924       /* Loop: for (i = 0; i < rank; ++i).  */
5925       tree idx = gfc_create_var (TREE_TYPE (rank), "idx");
5926       /* Loop body.  */
5927       stmtblock_t loop_body;
5928       gfc_init_block (&loop_body);
5929       /* gfc->dim[i].lbound = ... */
5930       tmp = gfc_get_cfi_dim_lbound (cfi, idx);
5931       gfc_conv_descriptor_lbound_set (&loop_body, gfc, idx, tmp);
5932 
5933       /* gfc->dim[i].ubound = gfc->dim[i].lbound + cfi->dim[i].extent - 1. */
5934       tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
5935 			     gfc_conv_descriptor_lbound_get (gfc, idx),
5936 			     gfc_index_one_node);
5937       tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
5938 			     gfc_get_cfi_dim_extent (cfi, idx), tmp);
5939       gfc_conv_descriptor_ubound_set (&loop_body, gfc, idx, tmp);
5940 
5941       /* gfc->dim[i].stride = cfi->dim[i].sm / cfi>elem_len */
5942       tmp = gfc_get_cfi_dim_sm (cfi, idx);
5943       tmp = fold_build2_loc (input_location, TRUNC_DIV_EXPR,
5944 			     gfc_array_index_type, tmp,
5945 			     fold_convert (gfc_array_index_type,
5946 					   gfc_get_cfi_desc_elem_len (cfi)));
5947       gfc_conv_descriptor_stride_set (&loop_body, gfc, idx, tmp);
5948 
5949       /* gfc->offset -= gfc->dim[i].stride * gfc->dim[i].lbound. */
5950       tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
5951 			     gfc_conv_descriptor_stride_get (gfc, idx),
5952 			     gfc_conv_descriptor_lbound_get (gfc, idx));
5953       tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
5954 			     gfc_conv_descriptor_offset_get (gfc), tmp);
5955       gfc_conv_descriptor_offset_set (&loop_body, gfc, tmp);
5956       /* Generate loop.  */
5957       gfc_simple_for_loop (&block2, idx, build_int_cst (TREE_TYPE (idx), 0),
5958 			   rank, LT_EXPR, build_int_cst (TREE_TYPE (idx), 1),
5959 			   gfc_finish_block (&loop_body));
5960     }
5961 
5962   if (e->ts.type == BT_CHARACTER && !e->ts.u.cl->length)
5963     {
5964       tmp = fold_convert (gfc_charlen_type_node,
5965 			  gfc_get_cfi_desc_elem_len (cfi));
5966       if (e->ts.kind != 1)
5967 	tmp = fold_build2_loc (input_location, TRUNC_DIV_EXPR,
5968 			       gfc_charlen_type_node, tmp,
5969 			       build_int_cst (gfc_charlen_type_node,
5970 					      e->ts.kind));
5971       gfc_add_modify (&block2, gfc_strlen, tmp);
5972     }
5973 
5974   tmp = gfc_get_cfi_desc_base_addr (cfi),
5975   tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
5976 			 tmp, null_pointer_node);
5977   tmp = build3_v (COND_EXPR, tmp, gfc_finish_block (&block2),
5978 		  build_empty_stmt (input_location));
5979   gfc_add_expr_to_block (&block, tmp);
5980 
5981 post_call:
5982   gfc_add_block_to_block (&block, &se.post);
5983   if (present && block.head)
5984     {
5985       tmp = build3_v (COND_EXPR, present, gfc_finish_block (&block),
5986 		      build_empty_stmt (input_location));
5987       gfc_add_expr_to_block (&parmse->post, tmp);
5988     }
5989   else if (block.head)
5990     gfc_add_block_to_block (&parmse->post, &block);
5991 }
5992 
5993 
5994 /* Generate code for a procedure call.  Note can return se->post != NULL.
5995    If se->direct_byref is set then se->expr contains the return parameter.
5996    Return nonzero, if the call has alternate specifiers.
5997    'expr' is only needed for procedure pointer components.  */
5998 
5999 int
gfc_conv_procedure_call(gfc_se * se,gfc_symbol * sym,gfc_actual_arglist * args,gfc_expr * expr,vec<tree,va_gc> * append_args)6000 gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
6001 			 gfc_actual_arglist * args, gfc_expr * expr,
6002 			 vec<tree, va_gc> *append_args)
6003 {
6004   gfc_interface_mapping mapping;
6005   vec<tree, va_gc> *arglist;
6006   vec<tree, va_gc> *retargs;
6007   tree tmp;
6008   tree fntype;
6009   gfc_se parmse;
6010   gfc_array_info *info;
6011   int byref;
6012   int parm_kind;
6013   tree type;
6014   tree var;
6015   tree len;
6016   tree base_object;
6017   vec<tree, va_gc> *stringargs;
6018   vec<tree, va_gc> *optionalargs;
6019   tree result = NULL;
6020   gfc_formal_arglist *formal;
6021   gfc_actual_arglist *arg;
6022   int has_alternate_specifier = 0;
6023   bool need_interface_mapping;
6024   bool callee_alloc;
6025   bool ulim_copy;
6026   gfc_typespec ts;
6027   gfc_charlen cl;
6028   gfc_expr *e;
6029   gfc_symbol *fsym;
6030   enum {MISSING = 0, ELEMENTAL, SCALAR, SCALAR_POINTER, ARRAY};
6031   gfc_component *comp = NULL;
6032   int arglen;
6033   unsigned int argc;
6034 
6035   arglist = NULL;
6036   retargs = NULL;
6037   stringargs = NULL;
6038   optionalargs = NULL;
6039   var = NULL_TREE;
6040   len = NULL_TREE;
6041   gfc_clear_ts (&ts);
6042 
6043   comp = gfc_get_proc_ptr_comp (expr);
6044 
6045   bool elemental_proc = (comp
6046 			 && comp->ts.interface
6047 			 && comp->ts.interface->attr.elemental)
6048 			|| (comp && comp->attr.elemental)
6049 			|| sym->attr.elemental;
6050 
6051   if (se->ss != NULL)
6052     {
6053       if (!elemental_proc)
6054 	{
6055 	  gcc_assert (se->ss->info->type == GFC_SS_FUNCTION);
6056 	  if (se->ss->info->useflags)
6057 	    {
6058 	      gcc_assert ((!comp && gfc_return_by_reference (sym)
6059 			   && sym->result->attr.dimension)
6060 			  || (comp && comp->attr.dimension)
6061 			  || gfc_is_class_array_function (expr));
6062 	      gcc_assert (se->loop != NULL);
6063 	      /* Access the previously obtained result.  */
6064 	      gfc_conv_tmp_array_ref (se);
6065 	      return 0;
6066 	    }
6067 	}
6068       info = &se->ss->info->data.array;
6069     }
6070   else
6071     info = NULL;
6072 
6073   stmtblock_t post, clobbers;
6074   gfc_init_block (&post);
6075   gfc_init_block (&clobbers);
6076   gfc_init_interface_mapping (&mapping);
6077   if (!comp)
6078     {
6079       formal = gfc_sym_get_dummy_args (sym);
6080       need_interface_mapping = sym->attr.dimension ||
6081 			       (sym->ts.type == BT_CHARACTER
6082 				&& sym->ts.u.cl->length
6083 				&& sym->ts.u.cl->length->expr_type
6084 				   != EXPR_CONSTANT);
6085     }
6086   else
6087     {
6088       formal = comp->ts.interface ? comp->ts.interface->formal : NULL;
6089       need_interface_mapping = comp->attr.dimension ||
6090 			       (comp->ts.type == BT_CHARACTER
6091 				&& comp->ts.u.cl->length
6092 				&& comp->ts.u.cl->length->expr_type
6093 				   != EXPR_CONSTANT);
6094     }
6095 
6096   base_object = NULL_TREE;
6097   /* For _vprt->_copy () routines no formal symbol is present.  Nevertheless
6098      is the third and fourth argument to such a function call a value
6099      denoting the number of elements to copy (i.e., most of the time the
6100      length of a deferred length string).  */
6101   ulim_copy = (formal == NULL)
6102 	       && UNLIMITED_POLY (sym)
6103 	       && comp && (strcmp ("_copy", comp->name) == 0);
6104 
6105   /* Evaluate the arguments.  */
6106   for (arg = args, argc = 0; arg != NULL;
6107        arg = arg->next, formal = formal ? formal->next : NULL, ++argc)
6108     {
6109       bool finalized = false;
6110       tree derived_array = NULL_TREE;
6111 
6112       e = arg->expr;
6113       fsym = formal ? formal->sym : NULL;
6114       parm_kind = MISSING;
6115 
6116       /* If the procedure requires an explicit interface, the actual
6117 	 argument is passed according to the corresponding formal
6118 	 argument.  If the corresponding formal argument is a POINTER,
6119 	 ALLOCATABLE or assumed shape, we do not use g77's calling
6120 	 convention, and pass the address of the array descriptor
6121 	 instead.  Otherwise we use g77's calling convention, in other words
6122 	 pass the array data pointer without descriptor.  */
6123       bool nodesc_arg = fsym != NULL
6124 			&& !(fsym->attr.pointer || fsym->attr.allocatable)
6125 			&& fsym->as
6126 			&& fsym->as->type != AS_ASSUMED_SHAPE
6127 			&& fsym->as->type != AS_ASSUMED_RANK;
6128       if (comp)
6129 	nodesc_arg = nodesc_arg || !comp->attr.always_explicit;
6130       else
6131 	nodesc_arg = nodesc_arg || !sym->attr.always_explicit;
6132 
6133       /* Class array expressions are sometimes coming completely unadorned
6134 	 with either arrayspec or _data component.  Correct that here.
6135 	 OOP-TODO: Move this to the frontend.  */
6136       if (e && e->expr_type == EXPR_VARIABLE
6137 	    && !e->ref
6138 	    && e->ts.type == BT_CLASS
6139 	    && (CLASS_DATA (e)->attr.codimension
6140 		|| CLASS_DATA (e)->attr.dimension))
6141 	{
6142 	  gfc_typespec temp_ts = e->ts;
6143 	  gfc_add_class_array_ref (e);
6144 	  e->ts = temp_ts;
6145 	}
6146 
6147       if (e == NULL)
6148 	{
6149 	  if (se->ignore_optional)
6150 	    {
6151 	      /* Some intrinsics have already been resolved to the correct
6152 	         parameters.  */
6153 	      continue;
6154 	    }
6155 	  else if (arg->label)
6156 	    {
6157 	      has_alternate_specifier = 1;
6158 	      continue;
6159 	    }
6160 	  else
6161 	    {
6162 	      gfc_init_se (&parmse, NULL);
6163 
6164 	      /* For scalar arguments with VALUE attribute which are passed by
6165 		 value, pass "0" and a hidden argument gives the optional
6166 		 status.  */
6167 	      if (fsym && fsym->attr.optional && fsym->attr.value
6168 		  && !fsym->attr.dimension && fsym->ts.type != BT_CHARACTER
6169 		  && fsym->ts.type != BT_CLASS && fsym->ts.type != BT_DERIVED)
6170 		{
6171 		  parmse.expr = fold_convert (gfc_sym_type (fsym),
6172 					      integer_zero_node);
6173 		  vec_safe_push (optionalargs, boolean_false_node);
6174 		}
6175 	      else
6176 		{
6177 		  /* Pass a NULL pointer for an absent arg.  */
6178 		  parmse.expr = null_pointer_node;
6179 		  gfc_dummy_arg * const dummy_arg = arg->associated_dummy;
6180 		  if (dummy_arg
6181 		      && gfc_dummy_arg_get_typespec (*dummy_arg).type
6182 			 == BT_CHARACTER)
6183 		    parmse.string_length = build_int_cst (gfc_charlen_type_node,
6184 							  0);
6185 		}
6186 	    }
6187 	}
6188       else if (arg->expr->expr_type == EXPR_NULL
6189 	       && fsym && !fsym->attr.pointer
6190 	       && (fsym->ts.type != BT_CLASS
6191 		   || !CLASS_DATA (fsym)->attr.class_pointer))
6192 	{
6193 	  /* Pass a NULL pointer to denote an absent arg.  */
6194 	  gcc_assert (fsym->attr.optional && !fsym->attr.allocatable
6195 		      && (fsym->ts.type != BT_CLASS
6196 			  || !CLASS_DATA (fsym)->attr.allocatable));
6197 	  gfc_init_se (&parmse, NULL);
6198 	  parmse.expr = null_pointer_node;
6199 	  if (arg->associated_dummy
6200 	      && gfc_dummy_arg_get_typespec (*arg->associated_dummy).type
6201 		 == BT_CHARACTER)
6202 	    parmse.string_length = build_int_cst (gfc_charlen_type_node, 0);
6203 	}
6204       else if (fsym && fsym->ts.type == BT_CLASS
6205 		 && e->ts.type == BT_DERIVED)
6206 	{
6207 	  /* The derived type needs to be converted to a temporary
6208 	     CLASS object.  */
6209 	  gfc_init_se (&parmse, se);
6210 	  gfc_conv_derived_to_class (&parmse, e, fsym->ts, NULL,
6211 				     fsym->attr.optional
6212 				     && e->expr_type == EXPR_VARIABLE
6213 				     && e->symtree->n.sym->attr.optional,
6214 				     CLASS_DATA (fsym)->attr.class_pointer
6215 				     || CLASS_DATA (fsym)->attr.allocatable,
6216 				     &derived_array);
6217 	}
6218       else if (UNLIMITED_POLY (fsym) && e->ts.type != BT_CLASS
6219 	       && e->ts.type != BT_PROCEDURE
6220 	       && (gfc_expr_attr (e).flavor != FL_PROCEDURE
6221 		   || gfc_expr_attr (e).proc != PROC_UNKNOWN))
6222 	{
6223 	  /* The intrinsic type needs to be converted to a temporary
6224 	     CLASS object for the unlimited polymorphic formal.  */
6225 	  gfc_find_vtab (&e->ts);
6226 	  gfc_init_se (&parmse, se);
6227 	  gfc_conv_intrinsic_to_class (&parmse, e, fsym->ts);
6228 
6229 	}
6230       else if (se->ss && se->ss->info->useflags)
6231 	{
6232 	  gfc_ss *ss;
6233 
6234 	  ss = se->ss;
6235 
6236 	  /* An elemental function inside a scalarized loop.  */
6237 	  gfc_init_se (&parmse, se);
6238 	  parm_kind = ELEMENTAL;
6239 
6240 	  /* When no fsym is present, ulim_copy is set and this is a third or
6241 	     fourth argument, use call-by-value instead of by reference to
6242 	     hand the length properties to the copy routine (i.e., most of the
6243 	     time this will be a call to a __copy_character_* routine where the
6244 	     third and fourth arguments are the lengths of a deferred length
6245 	     char array).  */
6246 	  if ((fsym && fsym->attr.value)
6247 	      || (ulim_copy && (argc == 2 || argc == 3)))
6248 	    gfc_conv_expr (&parmse, e);
6249 	  else
6250 	    gfc_conv_expr_reference (&parmse, e);
6251 
6252 	  if (e->ts.type == BT_CHARACTER && !e->rank
6253 	      && e->expr_type == EXPR_FUNCTION)
6254 	    parmse.expr = build_fold_indirect_ref_loc (input_location,
6255 						       parmse.expr);
6256 
6257 	  if (fsym && fsym->ts.type == BT_DERIVED
6258 	      && gfc_is_class_container_ref (e))
6259 	    {
6260 	      parmse.expr = gfc_class_data_get (parmse.expr);
6261 
6262 	      if (fsym->attr.optional && e->expr_type == EXPR_VARIABLE
6263 		  && e->symtree->n.sym->attr.optional)
6264 		{
6265 		  tree cond = gfc_conv_expr_present (e->symtree->n.sym);
6266 		  parmse.expr = build3_loc (input_location, COND_EXPR,
6267 					TREE_TYPE (parmse.expr),
6268 					cond, parmse.expr,
6269 					fold_convert (TREE_TYPE (parmse.expr),
6270 						      null_pointer_node));
6271 		}
6272 	    }
6273 
6274 	  /* If we are passing an absent array as optional dummy to an
6275 	     elemental procedure, make sure that we pass NULL when the data
6276 	     pointer is NULL.  We need this extra conditional because of
6277 	     scalarization which passes arrays elements to the procedure,
6278 	     ignoring the fact that the array can be absent/unallocated/...  */
6279 	  if (ss->info->can_be_null_ref && ss->info->type != GFC_SS_REFERENCE)
6280 	    {
6281 	      tree descriptor_data;
6282 
6283 	      descriptor_data = ss->info->data.array.data;
6284 	      tmp = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
6285 				     descriptor_data,
6286 				     fold_convert (TREE_TYPE (descriptor_data),
6287 						   null_pointer_node));
6288 	      parmse.expr
6289 		= fold_build3_loc (input_location, COND_EXPR,
6290 				   TREE_TYPE (parmse.expr),
6291 				   gfc_unlikely (tmp, PRED_FORTRAN_ABSENT_DUMMY),
6292 				   fold_convert (TREE_TYPE (parmse.expr),
6293 						 null_pointer_node),
6294 				   parmse.expr);
6295 	    }
6296 
6297 	  /* The scalarizer does not repackage the reference to a class
6298 	     array - instead it returns a pointer to the data element.  */
6299 	  if (fsym && fsym->ts.type == BT_CLASS && e->ts.type == BT_CLASS)
6300 	    gfc_conv_class_to_class (&parmse, e, fsym->ts, true,
6301 				     fsym->attr.intent != INTENT_IN
6302 				     && (CLASS_DATA (fsym)->attr.class_pointer
6303 					 || CLASS_DATA (fsym)->attr.allocatable),
6304 				     fsym->attr.optional
6305 				     && e->expr_type == EXPR_VARIABLE
6306 				     && e->symtree->n.sym->attr.optional,
6307 				     CLASS_DATA (fsym)->attr.class_pointer
6308 				     || CLASS_DATA (fsym)->attr.allocatable);
6309 	}
6310       else
6311 	{
6312 	  bool scalar;
6313 	  gfc_ss *argss;
6314 
6315 	  gfc_init_se (&parmse, NULL);
6316 
6317 	  /* Check whether the expression is a scalar or not; we cannot use
6318 	     e->rank as it can be nonzero for functions arguments.  */
6319 	  argss = gfc_walk_expr (e);
6320 	  scalar = argss == gfc_ss_terminator;
6321 	  if (!scalar)
6322 	    gfc_free_ss_chain (argss);
6323 
6324 	  /* Special handling for passing scalar polymorphic coarrays;
6325 	     otherwise one passes "class->_data.data" instead of "&class".  */
6326 	  if (e->rank == 0 && e->ts.type == BT_CLASS
6327 	      && fsym && fsym->ts.type == BT_CLASS
6328 	      && CLASS_DATA (fsym)->attr.codimension
6329 	      && !CLASS_DATA (fsym)->attr.dimension)
6330 	    {
6331 	      gfc_add_class_array_ref (e);
6332               parmse.want_coarray = 1;
6333 	      scalar = false;
6334 	    }
6335 
6336 	  /* A scalar or transformational function.  */
6337 	  if (scalar)
6338 	    {
6339 	      if (e->expr_type == EXPR_VARIABLE
6340 		    && e->symtree->n.sym->attr.cray_pointee
6341 		    && fsym && fsym->attr.flavor == FL_PROCEDURE)
6342 		{
6343 		    /* The Cray pointer needs to be converted to a pointer to
6344 		       a type given by the expression.  */
6345 		    gfc_conv_expr (&parmse, e);
6346 		    type = build_pointer_type (TREE_TYPE (parmse.expr));
6347 		    tmp = gfc_get_symbol_decl (e->symtree->n.sym->cp_pointer);
6348 		    parmse.expr = convert (type, tmp);
6349 		}
6350 
6351 	      else if (sym->attr.is_bind_c && e && is_CFI_desc (fsym, NULL))
6352 		/* Implement F2018, 18.3.6, list item (5), bullet point 2.  */
6353 		gfc_conv_gfc_desc_to_cfi_desc (&parmse, e, fsym);
6354 
6355 	      else if (fsym && fsym->attr.value)
6356 		{
6357 		  if (fsym->ts.type == BT_CHARACTER
6358 		      && fsym->ts.is_c_interop
6359 		      && fsym->ns->proc_name != NULL
6360 		      && fsym->ns->proc_name->attr.is_bind_c)
6361 		    {
6362 		      parmse.expr = NULL;
6363 		      conv_scalar_char_value (fsym, &parmse, &e);
6364 		      if (parmse.expr == NULL)
6365 			gfc_conv_expr (&parmse, e);
6366 		    }
6367 		  else
6368 		    {
6369 		    gfc_conv_expr (&parmse, e);
6370 		    if (fsym->attr.optional
6371 			&& fsym->ts.type != BT_CLASS
6372 			&& fsym->ts.type != BT_DERIVED)
6373 		      {
6374 			if (e->expr_type != EXPR_VARIABLE
6375 			    || !e->symtree->n.sym->attr.optional
6376 			    || e->ref != NULL)
6377 			  vec_safe_push (optionalargs, boolean_true_node);
6378 			else
6379 			  {
6380 			    tmp = gfc_conv_expr_present (e->symtree->n.sym);
6381 			    if (!e->symtree->n.sym->attr.value)
6382 			      parmse.expr
6383 				= fold_build3_loc (input_location, COND_EXPR,
6384 					TREE_TYPE (parmse.expr),
6385 					tmp, parmse.expr,
6386 					fold_convert (TREE_TYPE (parmse.expr),
6387 						      integer_zero_node));
6388 
6389 			    vec_safe_push (optionalargs,
6390 					   fold_convert (boolean_type_node,
6391 							 tmp));
6392 			  }
6393 		      }
6394 		    }
6395 		}
6396 
6397 	      else if (arg->name && arg->name[0] == '%')
6398 		/* Argument list functions %VAL, %LOC and %REF are signalled
6399 		   through arg->name.  */
6400 		conv_arglist_function (&parmse, arg->expr, arg->name);
6401 	      else if ((e->expr_type == EXPR_FUNCTION)
6402 			&& ((e->value.function.esym
6403 			     && e->value.function.esym->result->attr.pointer)
6404 			    || (!e->value.function.esym
6405 				&& e->symtree->n.sym->attr.pointer))
6406 			&& fsym && fsym->attr.target)
6407 		/* Make sure the function only gets called once.  */
6408 		gfc_conv_expr_reference (&parmse, e);
6409 	      else if (e->expr_type == EXPR_FUNCTION
6410 		       && e->symtree->n.sym->result
6411 		       && e->symtree->n.sym->result != e->symtree->n.sym
6412 		       && e->symtree->n.sym->result->attr.proc_pointer)
6413 		{
6414 		  /* Functions returning procedure pointers.  */
6415 		  gfc_conv_expr (&parmse, e);
6416 		  if (fsym && fsym->attr.proc_pointer)
6417 		    parmse.expr = gfc_build_addr_expr (NULL_TREE, parmse.expr);
6418 		}
6419 
6420 	      else
6421 		{
6422 		  if (e->ts.type == BT_CLASS && fsym
6423 		      && fsym->ts.type == BT_CLASS
6424 		      && (!CLASS_DATA (fsym)->as
6425 			  || CLASS_DATA (fsym)->as->type != AS_ASSUMED_RANK)
6426 		      && CLASS_DATA (e)->attr.codimension)
6427 		    {
6428 		      gcc_assert (!CLASS_DATA (fsym)->attr.codimension);
6429 		      gcc_assert (!CLASS_DATA (fsym)->as);
6430 		      gfc_add_class_array_ref (e);
6431 		      parmse.want_coarray = 1;
6432 		      gfc_conv_expr_reference (&parmse, e);
6433 		      class_scalar_coarray_to_class (&parmse, e, fsym->ts,
6434 				     fsym->attr.optional
6435 				     && e->expr_type == EXPR_VARIABLE);
6436 		    }
6437 		  else if (e->ts.type == BT_CLASS && fsym
6438 			   && fsym->ts.type == BT_CLASS
6439 			   && !CLASS_DATA (fsym)->as
6440 			   && !CLASS_DATA (e)->as
6441 			   && strcmp (fsym->ts.u.derived->name,
6442 				      e->ts.u.derived->name))
6443 		    {
6444 		      type = gfc_typenode_for_spec (&fsym->ts);
6445 		      var = gfc_create_var (type, fsym->name);
6446 		      gfc_conv_expr (&parmse, e);
6447 		      if (fsym->attr.optional
6448 			  && e->expr_type == EXPR_VARIABLE
6449 			  && e->symtree->n.sym->attr.optional)
6450 			{
6451 			  stmtblock_t block;
6452 			  tree cond;
6453 			  tmp = gfc_build_addr_expr (NULL_TREE, parmse.expr);
6454 			  cond = fold_build2_loc (input_location, NE_EXPR,
6455 						  logical_type_node, tmp,
6456 						  fold_convert (TREE_TYPE (tmp),
6457 							    null_pointer_node));
6458 			  gfc_start_block (&block);
6459 			  gfc_add_modify (&block, var,
6460 					  fold_build1_loc (input_location,
6461 							   VIEW_CONVERT_EXPR,
6462 							   type, parmse.expr));
6463 			  gfc_add_expr_to_block (&parmse.pre,
6464 				 fold_build3_loc (input_location,
6465 					 COND_EXPR, void_type_node,
6466 					 cond, gfc_finish_block (&block),
6467 					 build_empty_stmt (input_location)));
6468 			  parmse.expr = gfc_build_addr_expr (NULL_TREE, var);
6469 			  parmse.expr = build3_loc (input_location, COND_EXPR,
6470 					 TREE_TYPE (parmse.expr),
6471 					 cond, parmse.expr,
6472 					 fold_convert (TREE_TYPE (parmse.expr),
6473 						       null_pointer_node));
6474 			}
6475 		      else
6476 			{
6477 			  /* Since the internal representation of unlimited
6478 			     polymorphic expressions includes an extra field
6479 			     that other class objects do not, a cast to the
6480 			     formal type does not work.  */
6481 			  if (!UNLIMITED_POLY (e) && UNLIMITED_POLY (fsym))
6482 			    {
6483 			      tree efield;
6484 
6485 			      /* Set the _data field.  */
6486 			      tmp = gfc_class_data_get (var);
6487 			      efield = fold_convert (TREE_TYPE (tmp),
6488 					gfc_class_data_get (parmse.expr));
6489 			      gfc_add_modify (&parmse.pre, tmp, efield);
6490 
6491 			      /* Set the _vptr field.  */
6492 			      tmp = gfc_class_vptr_get (var);
6493 			      efield = fold_convert (TREE_TYPE (tmp),
6494 					gfc_class_vptr_get (parmse.expr));
6495 			      gfc_add_modify (&parmse.pre, tmp, efield);
6496 
6497 			      /* Set the _len field.  */
6498 			      tmp = gfc_class_len_get (var);
6499 			      gfc_add_modify (&parmse.pre, tmp,
6500 					      build_int_cst (TREE_TYPE (tmp), 0));
6501 			    }
6502 			  else
6503 			    {
6504 			      tmp = fold_build1_loc (input_location,
6505 						     VIEW_CONVERT_EXPR,
6506 						     type, parmse.expr);
6507 			      gfc_add_modify (&parmse.pre, var, tmp);
6508 					      ;
6509 			    }
6510 			  parmse.expr = gfc_build_addr_expr (NULL_TREE, var);
6511 			}
6512 		    }
6513 		  else
6514 		    {
6515 		      gfc_conv_expr_reference (&parmse, e);
6516 
6517 		      if (fsym
6518 			  && fsym->attr.intent == INTENT_OUT
6519 			  && !fsym->attr.allocatable
6520 			  && !fsym->attr.pointer
6521 			  && e->expr_type == EXPR_VARIABLE
6522 			  && e->ref == NULL
6523 			  && e->symtree
6524 			  && e->symtree->n.sym
6525 			  && !e->symtree->n.sym->attr.dimension
6526 			  && !e->symtree->n.sym->attr.pointer
6527 			  && !e->symtree->n.sym->attr.allocatable
6528 			  /* See PR 41453.  */
6529 			  && !e->symtree->n.sym->attr.dummy
6530 			  /* FIXME - PR 87395 and PR 41453  */
6531 			  && e->symtree->n.sym->attr.save == SAVE_NONE
6532 			  && !e->symtree->n.sym->attr.associate_var
6533 			  && e->ts.type != BT_CHARACTER
6534 			  && e->ts.type != BT_DERIVED
6535 			  && e->ts.type != BT_CLASS
6536 			  && !sym->attr.elemental)
6537 			{
6538 			  tree var;
6539 			  /* FIXME: This fails if var is passed by reference, see PR
6540 			     41453.  */
6541 			  var = build_fold_indirect_ref_loc (input_location,
6542 							     parmse.expr);
6543 			  tree clobber = build_clobber (TREE_TYPE (var));
6544 			  gfc_add_modify (&clobbers, var, clobber);
6545 			}
6546 		    }
6547 		  /* Catch base objects that are not variables.  */
6548 		  if (e->ts.type == BT_CLASS
6549 			&& e->expr_type != EXPR_VARIABLE
6550 			&& expr && e == expr->base_expr)
6551 		    base_object = build_fold_indirect_ref_loc (input_location,
6552 							       parmse.expr);
6553 
6554 		  /* If an ALLOCATABLE dummy argument has INTENT(OUT) and is
6555 		     allocated on entry, it must be deallocated.  */
6556 		  if (fsym && fsym->attr.intent == INTENT_OUT
6557 		      && (fsym->attr.allocatable
6558 			  || (fsym->ts.type == BT_CLASS
6559 			      && CLASS_DATA (fsym)->attr.allocatable))
6560 		      && !is_CFI_desc (fsym, NULL))
6561 		    {
6562 		      stmtblock_t block;
6563 		      tree ptr;
6564 
6565 		      gfc_init_block  (&block);
6566 		      ptr = parmse.expr;
6567 		      if (e->ts.type == BT_CLASS)
6568 			ptr = gfc_class_data_get (ptr);
6569 
6570 		      tmp = gfc_deallocate_scalar_with_status (ptr, NULL_TREE,
6571 							       NULL_TREE, true,
6572 							       e, e->ts);
6573 		      gfc_add_expr_to_block (&block, tmp);
6574 		      tmp = fold_build2_loc (input_location, MODIFY_EXPR,
6575 					     void_type_node, ptr,
6576 					     null_pointer_node);
6577 		      gfc_add_expr_to_block (&block, tmp);
6578 
6579 		      if (fsym->ts.type == BT_CLASS && UNLIMITED_POLY (fsym))
6580 			{
6581 			  gfc_add_modify (&block, ptr,
6582 					  fold_convert (TREE_TYPE (ptr),
6583 							null_pointer_node));
6584 			  gfc_add_expr_to_block (&block, tmp);
6585 			}
6586 		      else if (fsym->ts.type == BT_CLASS)
6587 			{
6588 			  gfc_symbol *vtab;
6589 			  vtab = gfc_find_derived_vtab (fsym->ts.u.derived);
6590 			  tmp = gfc_get_symbol_decl (vtab);
6591 			  tmp = gfc_build_addr_expr (NULL_TREE, tmp);
6592 			  ptr = gfc_class_vptr_get (parmse.expr);
6593 			  gfc_add_modify (&block, ptr,
6594 					  fold_convert (TREE_TYPE (ptr), tmp));
6595 			  gfc_add_expr_to_block (&block, tmp);
6596 			}
6597 
6598 		      if (fsym->attr.optional
6599 			  && e->expr_type == EXPR_VARIABLE
6600 			  && e->symtree->n.sym->attr.optional)
6601 			{
6602 			  tmp = fold_build3_loc (input_location, COND_EXPR,
6603 				     void_type_node,
6604 				     gfc_conv_expr_present (e->symtree->n.sym),
6605 					    gfc_finish_block (&block),
6606 					    build_empty_stmt (input_location));
6607 			}
6608 		      else
6609 			tmp = gfc_finish_block (&block);
6610 
6611 		      gfc_add_expr_to_block (&se->pre, tmp);
6612 		    }
6613 
6614 		  /* A class array element needs converting back to be a
6615 		     class object, if the formal argument is a class object.  */
6616 		  if (fsym && fsym->ts.type == BT_CLASS
6617 			&& e->ts.type == BT_CLASS
6618 			&& ((CLASS_DATA (fsym)->as
6619 			     && CLASS_DATA (fsym)->as->type == AS_ASSUMED_RANK)
6620 			    || CLASS_DATA (e)->attr.dimension))
6621 		    gfc_conv_class_to_class (&parmse, e, fsym->ts, false,
6622 				     fsym->attr.intent != INTENT_IN
6623 				     && (CLASS_DATA (fsym)->attr.class_pointer
6624 					 || CLASS_DATA (fsym)->attr.allocatable),
6625 				     fsym->attr.optional
6626 				     && e->expr_type == EXPR_VARIABLE
6627 				     && e->symtree->n.sym->attr.optional,
6628 				     CLASS_DATA (fsym)->attr.class_pointer
6629 				     || CLASS_DATA (fsym)->attr.allocatable);
6630 
6631 		  if (fsym && (fsym->ts.type == BT_DERIVED
6632 			       || fsym->ts.type == BT_ASSUMED)
6633 		      && e->ts.type == BT_CLASS
6634 		      && !CLASS_DATA (e)->attr.dimension
6635 		      && !CLASS_DATA (e)->attr.codimension)
6636 		    {
6637 		      parmse.expr = gfc_class_data_get (parmse.expr);
6638 		      /* The result is a class temporary, whose _data component
6639 			 must be freed to avoid a memory leak.  */
6640 		      if (e->expr_type == EXPR_FUNCTION
6641 			  && CLASS_DATA (e)->attr.allocatable)
6642 			{
6643 			  tree zero;
6644 
6645 			  gfc_expr *var;
6646 
6647 			  /* Borrow the function symbol to make a call to
6648 			     gfc_add_finalizer_call and then restore it.  */
6649 			  tmp = e->symtree->n.sym->backend_decl;
6650 			  e->symtree->n.sym->backend_decl
6651 					= TREE_OPERAND (parmse.expr, 0);
6652 			  e->symtree->n.sym->attr.flavor = FL_VARIABLE;
6653 			  var = gfc_lval_expr_from_sym (e->symtree->n.sym);
6654 			  finalized = gfc_add_finalizer_call (&parmse.post,
6655 							      var);
6656 			  gfc_free_expr (var);
6657 			  e->symtree->n.sym->backend_decl = tmp;
6658 			  e->symtree->n.sym->attr.flavor = FL_PROCEDURE;
6659 
6660 			  /* Then free the class _data.  */
6661 			  zero = build_int_cst (TREE_TYPE (parmse.expr), 0);
6662 			  tmp = fold_build2_loc (input_location, NE_EXPR,
6663 						 logical_type_node,
6664 						 parmse.expr, zero);
6665 			  tmp = build3_v (COND_EXPR, tmp,
6666 					  gfc_call_free (parmse.expr),
6667 					  build_empty_stmt (input_location));
6668 			  gfc_add_expr_to_block (&parmse.post, tmp);
6669 			  gfc_add_modify (&parmse.post, parmse.expr, zero);
6670 			}
6671 		    }
6672 
6673 		  /* Wrap scalar variable in a descriptor. We need to convert
6674 		     the address of a pointer back to the pointer itself before,
6675 		     we can assign it to the data field.  */
6676 
6677 		  if (fsym && fsym->as && fsym->as->type == AS_ASSUMED_RANK
6678 		      && fsym->ts.type != BT_CLASS && e->expr_type != EXPR_NULL)
6679 		    {
6680 		      tmp = parmse.expr;
6681 		      if (TREE_CODE (tmp) == ADDR_EXPR)
6682 			tmp = TREE_OPERAND (tmp, 0);
6683 		      parmse.expr = gfc_conv_scalar_to_descriptor (&parmse, tmp,
6684 								   fsym->attr);
6685 		      parmse.expr = gfc_build_addr_expr (NULL_TREE,
6686 							 parmse.expr);
6687 		    }
6688 		  else if (fsym && e->expr_type != EXPR_NULL
6689 		      && ((fsym->attr.pointer
6690 			   && fsym->attr.flavor != FL_PROCEDURE)
6691 			  || (fsym->attr.proc_pointer
6692 			      && !(e->expr_type == EXPR_VARIABLE
6693 				   && e->symtree->n.sym->attr.dummy))
6694 			  || (fsym->attr.proc_pointer
6695 			      && e->expr_type == EXPR_VARIABLE
6696 			      && gfc_is_proc_ptr_comp (e))
6697 			  || (fsym->attr.allocatable
6698 			      && fsym->attr.flavor != FL_PROCEDURE)))
6699 		    {
6700 		      /* Scalar pointer dummy args require an extra level of
6701 			 indirection. The null pointer already contains
6702 			 this level of indirection.  */
6703 		      parm_kind = SCALAR_POINTER;
6704 		      parmse.expr = gfc_build_addr_expr (NULL_TREE, parmse.expr);
6705 		    }
6706 		}
6707 	    }
6708 	  else if (e->ts.type == BT_CLASS
6709 		    && fsym && fsym->ts.type == BT_CLASS
6710 		    && (CLASS_DATA (fsym)->attr.dimension
6711 			|| CLASS_DATA (fsym)->attr.codimension))
6712 	    {
6713 	      /* Pass a class array.  */
6714 	      parmse.use_offset = 1;
6715 	      gfc_conv_expr_descriptor (&parmse, e);
6716 
6717 	      /* If an ALLOCATABLE dummy argument has INTENT(OUT) and is
6718 		 allocated on entry, it must be deallocated.  */
6719 	      if (fsym->attr.intent == INTENT_OUT
6720 		  && CLASS_DATA (fsym)->attr.allocatable)
6721 		{
6722 		  stmtblock_t block;
6723 		  tree ptr;
6724 
6725 		  gfc_init_block  (&block);
6726 		  ptr = parmse.expr;
6727 		  ptr = gfc_class_data_get (ptr);
6728 
6729 		  tmp = gfc_deallocate_with_status (ptr, NULL_TREE,
6730 						    NULL_TREE, NULL_TREE,
6731 						    NULL_TREE, true, e,
6732 						    GFC_CAF_COARRAY_NOCOARRAY);
6733 		  gfc_add_expr_to_block (&block, tmp);
6734 		  tmp = fold_build2_loc (input_location, MODIFY_EXPR,
6735 					 void_type_node, ptr,
6736 					 null_pointer_node);
6737 		  gfc_add_expr_to_block (&block, tmp);
6738 		  gfc_reset_vptr (&block, e);
6739 
6740 		  if (fsym->attr.optional
6741 		      && e->expr_type == EXPR_VARIABLE
6742 		      && (!e->ref
6743 			  || (e->ref->type == REF_ARRAY
6744 			      && e->ref->u.ar.type != AR_FULL))
6745 		      && e->symtree->n.sym->attr.optional)
6746 		    {
6747 		      tmp = fold_build3_loc (input_location, COND_EXPR,
6748 				    void_type_node,
6749 				    gfc_conv_expr_present (e->symtree->n.sym),
6750 				    gfc_finish_block (&block),
6751 				    build_empty_stmt (input_location));
6752 		    }
6753 		  else
6754 		    tmp = gfc_finish_block (&block);
6755 
6756 		  gfc_add_expr_to_block (&se->pre, tmp);
6757 		}
6758 
6759 	      /* The conversion does not repackage the reference to a class
6760 	         array - _data descriptor.  */
6761 	      gfc_conv_class_to_class (&parmse, e, fsym->ts, false,
6762 				     fsym->attr.intent != INTENT_IN
6763 				     && (CLASS_DATA (fsym)->attr.class_pointer
6764 					 || CLASS_DATA (fsym)->attr.allocatable),
6765 				     fsym->attr.optional
6766 				     && e->expr_type == EXPR_VARIABLE
6767 				     && e->symtree->n.sym->attr.optional,
6768 				     CLASS_DATA (fsym)->attr.class_pointer
6769 				     || CLASS_DATA (fsym)->attr.allocatable);
6770 	    }
6771 	  else
6772 	    {
6773 	      /* If the argument is a function call that may not create
6774 		 a temporary for the result, we have to check that we
6775 		 can do it, i.e. that there is no alias between this
6776 		 argument and another one.  */
6777 	      if (gfc_get_noncopying_intrinsic_argument (e) != NULL)
6778 		{
6779 		  gfc_expr *iarg;
6780 		  sym_intent intent;
6781 
6782 		  if (fsym != NULL)
6783 		    intent = fsym->attr.intent;
6784 		  else
6785 		    intent = INTENT_UNKNOWN;
6786 
6787 		  if (gfc_check_fncall_dependency (e, intent, sym, args,
6788 						   NOT_ELEMENTAL))
6789 		    parmse.force_tmp = 1;
6790 
6791 		  iarg = e->value.function.actual->expr;
6792 
6793 		  /* Temporary needed if aliasing due to host association.  */
6794 		  if (sym->attr.contained
6795 			&& !sym->attr.pure
6796 			&& !sym->attr.implicit_pure
6797 			&& !sym->attr.use_assoc
6798 			&& iarg->expr_type == EXPR_VARIABLE
6799 			&& sym->ns == iarg->symtree->n.sym->ns)
6800 		    parmse.force_tmp = 1;
6801 
6802 		  /* Ditto within module.  */
6803 		  if (sym->attr.use_assoc
6804 			&& !sym->attr.pure
6805 			&& !sym->attr.implicit_pure
6806 			&& iarg->expr_type == EXPR_VARIABLE
6807 			&& sym->module == iarg->symtree->n.sym->module)
6808 		    parmse.force_tmp = 1;
6809 		}
6810 
6811 	      /* Special case for assumed-rank arrays: when passing an
6812 		 argument to a nonallocatable/nonpointer dummy, the bounds have
6813 		 to be reset as otherwise a last-dim ubound of -1 is
6814 		 indistinguishable from an assumed-size array in the callee.  */
6815 	      if (!sym->attr.is_bind_c && e && fsym && fsym->as
6816 		  && fsym->as->type == AS_ASSUMED_RANK
6817 		  && e->rank != -1
6818 		  && e->expr_type == EXPR_VARIABLE
6819 		  && ((fsym->ts.type == BT_CLASS
6820 		       && !CLASS_DATA (fsym)->attr.class_pointer
6821 		       && !CLASS_DATA (fsym)->attr.allocatable)
6822 		      || (fsym->ts.type != BT_CLASS
6823 			  && !fsym->attr.pointer && !fsym->attr.allocatable)))
6824 		{
6825 		  /* Change AR_FULL to a (:,:,:) ref to force bounds update. */
6826 		  gfc_ref *ref;
6827 		  for (ref = e->ref; ref->next; ref = ref->next)
6828 		    ;
6829 		  if (ref->u.ar.type == AR_FULL
6830 		      && ref->u.ar.as->type != AS_ASSUMED_SIZE)
6831 		    ref->u.ar.type = AR_SECTION;
6832 		}
6833 
6834 	      if (sym->attr.is_bind_c && e && is_CFI_desc (fsym, NULL))
6835 		/* Implement F2018, 18.3.6, list item (5), bullet point 2.  */
6836 		gfc_conv_gfc_desc_to_cfi_desc (&parmse, e, fsym);
6837 
6838 	      else if (e->expr_type == EXPR_VARIABLE
6839 		    && is_subref_array (e)
6840 		    && !(fsym && fsym->attr.pointer))
6841 		/* The actual argument is a component reference to an
6842 		   array of derived types.  In this case, the argument
6843 		   is converted to a temporary, which is passed and then
6844 		   written back after the procedure call.  */
6845 		gfc_conv_subref_array_arg (&parmse, e, nodesc_arg,
6846 				fsym ? fsym->attr.intent : INTENT_INOUT,
6847 				fsym && fsym->attr.pointer);
6848 
6849 	      else if (e->ts.type == BT_CLASS && CLASS_DATA (e)->as
6850 		       && CLASS_DATA (e)->as->type == AS_ASSUMED_SIZE
6851 		       && nodesc_arg && fsym->ts.type == BT_DERIVED)
6852 		/* An assumed size class actual argument being passed to
6853 		   a 'no descriptor' formal argument just requires the
6854 		   data pointer to be passed. For class dummy arguments
6855 		   this is stored in the symbol backend decl..  */
6856 		parmse.expr = e->symtree->n.sym->backend_decl;
6857 
6858 	      else if (gfc_is_class_array_ref (e, NULL)
6859 		       && fsym && fsym->ts.type == BT_DERIVED)
6860 		/* The actual argument is a component reference to an
6861 		   array of derived types.  In this case, the argument
6862 		   is converted to a temporary, which is passed and then
6863 		   written back after the procedure call.
6864 		   OOP-TODO: Insert code so that if the dynamic type is
6865 		   the same as the declared type, copy-in/copy-out does
6866 		   not occur.  */
6867 		gfc_conv_subref_array_arg (&parmse, e, nodesc_arg,
6868 					   fsym->attr.intent,
6869 					   fsym->attr.pointer);
6870 
6871 	      else if (gfc_is_class_array_function (e)
6872 		       && fsym && fsym->ts.type == BT_DERIVED)
6873 		/* See previous comment.  For function actual argument,
6874 		   the write out is not needed so the intent is set as
6875 		   intent in.  */
6876 		{
6877 		  e->must_finalize = 1;
6878 		  gfc_conv_subref_array_arg (&parmse, e, nodesc_arg,
6879 					     INTENT_IN, fsym->attr.pointer);
6880 		}
6881 	      else if (fsym && fsym->attr.contiguous
6882 		       && !gfc_is_simply_contiguous (e, false, true)
6883 		       && gfc_expr_is_variable (e))
6884 		{
6885 		  gfc_conv_subref_array_arg (&parmse, e, nodesc_arg,
6886 					     fsym->attr.intent,
6887 					     fsym->attr.pointer);
6888 		}
6889 	      else
6890 		/* This is where we introduce a temporary to store the
6891 		   result of a non-lvalue array expression.  */
6892 		gfc_conv_array_parameter (&parmse, e, nodesc_arg, fsym,
6893 					  sym->name, NULL);
6894 
6895 	      /* If an ALLOCATABLE dummy argument has INTENT(OUT) and is
6896 		 allocated on entry, it must be deallocated.
6897 		 CFI descriptors are handled elsewhere.  */
6898 	      if (fsym && fsym->attr.allocatable
6899 		  && fsym->attr.intent == INTENT_OUT
6900 		  && !is_CFI_desc (fsym, NULL))
6901 		{
6902 		  if (fsym->ts.type == BT_DERIVED
6903 		      && fsym->ts.u.derived->attr.alloc_comp)
6904 		  {
6905 		    // deallocate the components first
6906 		    tmp = gfc_deallocate_alloc_comp (fsym->ts.u.derived,
6907 						     parmse.expr, e->rank);
6908 		    /* But check whether dummy argument is optional.  */
6909 		    if (tmp != NULL_TREE
6910 			&& fsym->attr.optional
6911 			&& e->expr_type == EXPR_VARIABLE
6912 			&& e->symtree->n.sym->attr.optional)
6913 		      {
6914 			tree present;
6915 			present = gfc_conv_expr_present (e->symtree->n.sym);
6916 			tmp = build3_v (COND_EXPR, present, tmp,
6917 					build_empty_stmt (input_location));
6918 		      }
6919 		    if (tmp != NULL_TREE)
6920 		      gfc_add_expr_to_block (&se->pre, tmp);
6921 		  }
6922 
6923 		  tmp = parmse.expr;
6924 		  /* With bind(C), the actual argument is replaced by a bind-C
6925 		     descriptor; in this case, the data component arrives here,
6926 		     which shall not be dereferenced, but still freed and
6927 		     nullified.  */
6928 		  if  (TREE_TYPE(tmp) != pvoid_type_node)
6929 		    tmp = build_fold_indirect_ref_loc (input_location,
6930 						       parmse.expr);
6931 		  if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp)))
6932 		    tmp = gfc_conv_descriptor_data_get (tmp);
6933 		  tmp = gfc_deallocate_with_status (tmp, NULL_TREE, NULL_TREE,
6934 						    NULL_TREE, NULL_TREE, true,
6935 						    e,
6936 						    GFC_CAF_COARRAY_NOCOARRAY);
6937 		  if (fsym->attr.optional
6938 		      && e->expr_type == EXPR_VARIABLE
6939 		      && e->symtree->n.sym->attr.optional)
6940 		    tmp = fold_build3_loc (input_location, COND_EXPR,
6941 				     void_type_node,
6942 				     gfc_conv_expr_present (e->symtree->n.sym),
6943 				       tmp, build_empty_stmt (input_location));
6944 		  gfc_add_expr_to_block (&se->pre, tmp);
6945 		}
6946 	    }
6947 	}
6948       /* Special case for an assumed-rank dummy argument. */
6949       if (!sym->attr.is_bind_c && e && fsym && e->rank > 0
6950 	  && (fsym->ts.type == BT_CLASS
6951 	      ? (CLASS_DATA (fsym)->as
6952 		 && CLASS_DATA (fsym)->as->type == AS_ASSUMED_RANK)
6953 	      : (fsym->as && fsym->as->type == AS_ASSUMED_RANK)))
6954 	{
6955 	  if (fsym->ts.type == BT_CLASS
6956 	      ? (CLASS_DATA (fsym)->attr.class_pointer
6957 		 || CLASS_DATA (fsym)->attr.allocatable)
6958 	      : (fsym->attr.pointer || fsym->attr.allocatable))
6959 	    {
6960 	      /* Unallocated allocatable arrays and unassociated pointer
6961 		 arrays need their dtype setting if they are argument
6962 		 associated with assumed rank dummies to set the rank.  */
6963 	      set_dtype_for_unallocated (&parmse, e);
6964 	    }
6965 	  else if (e->expr_type == EXPR_VARIABLE
6966 		   && e->symtree->n.sym->attr.dummy
6967 		   && (e->ts.type == BT_CLASS
6968 		       ? (e->ref && e->ref->next
6969 			  && e->ref->next->type == REF_ARRAY
6970 			  && e->ref->next->u.ar.type == AR_FULL
6971 			  && e->ref->next->u.ar.as->type == AS_ASSUMED_SIZE)
6972 		       : (e->ref && e->ref->type == REF_ARRAY
6973 			  && e->ref->u.ar.type == AR_FULL
6974 			  && e->ref->u.ar.as->type == AS_ASSUMED_SIZE)))
6975 	    {
6976 	      /* Assumed-size actual to assumed-rank dummy requires
6977 		 dim[rank-1].ubound = -1. */
6978 	      tree minus_one;
6979 	      tmp = build_fold_indirect_ref_loc (input_location, parmse.expr);
6980 	      if (fsym->ts.type == BT_CLASS)
6981 		tmp = gfc_class_data_get (tmp);
6982 	      minus_one = build_int_cst (gfc_array_index_type, -1);
6983 	      gfc_conv_descriptor_ubound_set (&parmse.pre, tmp,
6984 					      gfc_rank_cst[e->rank - 1],
6985 					      minus_one);
6986 	    }
6987 	}
6988 
6989       /* The case with fsym->attr.optional is that of a user subroutine
6990 	 with an interface indicating an optional argument.  When we call
6991 	 an intrinsic subroutine, however, fsym is NULL, but we might still
6992 	 have an optional argument, so we proceed to the substitution
6993 	 just in case.  */
6994       if (e && (fsym == NULL || fsym->attr.optional))
6995 	{
6996 	  /* If an optional argument is itself an optional dummy argument,
6997 	     check its presence and substitute a null if absent.  This is
6998 	     only needed when passing an array to an elemental procedure
6999 	     as then array elements are accessed - or no NULL pointer is
7000 	     allowed and a "1" or "0" should be passed if not present.
7001 	     When passing a non-array-descriptor full array to a
7002 	     non-array-descriptor dummy, no check is needed. For
7003 	     array-descriptor actual to array-descriptor dummy, see
7004 	     PR 41911 for why a check has to be inserted.
7005 	     fsym == NULL is checked as intrinsics required the descriptor
7006 	     but do not always set fsym.
7007 	     Also, it is necessary to pass a NULL pointer to library routines
7008 	     which usually ignore optional arguments, so they can handle
7009 	     these themselves.  */
7010 	  if (e->expr_type == EXPR_VARIABLE
7011 	      && e->symtree->n.sym->attr.optional
7012 	      && (((e->rank != 0 && elemental_proc)
7013 		   || e->representation.length || e->ts.type == BT_CHARACTER
7014 		   || (e->rank != 0
7015 		       && (fsym == NULL
7016 			   || (fsym->as
7017 			       && (fsym->as->type == AS_ASSUMED_SHAPE
7018 				   || fsym->as->type == AS_ASSUMED_RANK
7019 				   || fsym->as->type == AS_DEFERRED)))))
7020 		  || se->ignore_optional))
7021 	    gfc_conv_missing_dummy (&parmse, e, fsym ? fsym->ts : e->ts,
7022 				    e->representation.length);
7023 	}
7024 
7025       if (fsym && e)
7026 	{
7027 	  /* Obtain the character length of an assumed character length
7028 	     length procedure from the typespec.  */
7029 	  if (fsym->ts.type == BT_CHARACTER
7030 	      && parmse.string_length == NULL_TREE
7031 	      && e->ts.type == BT_PROCEDURE
7032 	      && e->symtree->n.sym->ts.type == BT_CHARACTER
7033 	      && e->symtree->n.sym->ts.u.cl->length != NULL
7034 	      && e->symtree->n.sym->ts.u.cl->length->expr_type == EXPR_CONSTANT)
7035 	    {
7036 	      gfc_conv_const_charlen (e->symtree->n.sym->ts.u.cl);
7037 	      parmse.string_length = e->symtree->n.sym->ts.u.cl->backend_decl;
7038 	    }
7039 	}
7040 
7041       if (fsym && need_interface_mapping && e)
7042 	gfc_add_interface_mapping (&mapping, fsym, &parmse, e);
7043 
7044       gfc_add_block_to_block (&se->pre, &parmse.pre);
7045       gfc_add_block_to_block (&post, &parmse.post);
7046 
7047       /* Allocated allocatable components of derived types must be
7048 	 deallocated for non-variable scalars, array arguments to elemental
7049 	 procedures, and array arguments with descriptor to non-elemental
7050 	 procedures.  As bounds information for descriptorless arrays is no
7051 	 longer available here, they are dealt with in trans-array.cc
7052 	 (gfc_conv_array_parameter).  */
7053       if (e && (e->ts.type == BT_DERIVED || e->ts.type == BT_CLASS)
7054 	    && e->ts.u.derived->attr.alloc_comp
7055 	    && (e->rank == 0 || elemental_proc || !nodesc_arg)
7056 	    && !expr_may_alias_variables (e, elemental_proc))
7057 	{
7058 	  int parm_rank;
7059 	  /* It is known the e returns a structure type with at least one
7060 	     allocatable component.  When e is a function, ensure that the
7061 	     function is called once only by using a temporary variable.  */
7062 	  if (!DECL_P (parmse.expr))
7063 	    parmse.expr = gfc_evaluate_now_loc (input_location,
7064 						parmse.expr, &se->pre);
7065 
7066 	  if (fsym && fsym->attr.value)
7067 	    tmp = parmse.expr;
7068 	  else
7069 	    tmp = build_fold_indirect_ref_loc (input_location,
7070 					       parmse.expr);
7071 
7072 	  parm_rank = e->rank;
7073 	  switch (parm_kind)
7074 	    {
7075 	    case (ELEMENTAL):
7076 	    case (SCALAR):
7077 	      parm_rank = 0;
7078 	      break;
7079 
7080 	    case (SCALAR_POINTER):
7081               tmp = build_fold_indirect_ref_loc (input_location,
7082 					     tmp);
7083 	      break;
7084 	    }
7085 
7086 	  if (e->ts.type == BT_DERIVED && fsym && fsym->ts.type == BT_CLASS)
7087 	    {
7088 	      /* The derived type is passed to gfc_deallocate_alloc_comp.
7089 		 Therefore, class actuals can be handled correctly but derived
7090 		 types passed to class formals need the _data component.  */
7091 	      tmp = gfc_class_data_get (tmp);
7092 	      if (!CLASS_DATA (fsym)->attr.dimension)
7093 		tmp = build_fold_indirect_ref_loc (input_location, tmp);
7094 	    }
7095 
7096 	  if (e->expr_type == EXPR_OP
7097 		&& e->value.op.op == INTRINSIC_PARENTHESES
7098 		&& e->value.op.op1->expr_type == EXPR_VARIABLE)
7099 	    {
7100 	      tree local_tmp;
7101 	      local_tmp = gfc_evaluate_now (tmp, &se->pre);
7102 	      local_tmp = gfc_copy_alloc_comp (e->ts.u.derived, local_tmp, tmp,
7103 					       parm_rank, 0);
7104 	      gfc_add_expr_to_block (&se->post, local_tmp);
7105 	    }
7106 
7107 	  if (!finalized && !e->must_finalize)
7108 	    {
7109 	      bool scalar_res_outside_loop;
7110 	      scalar_res_outside_loop = e->expr_type == EXPR_FUNCTION
7111 					&& parm_rank == 0
7112 					&& parmse.loop;
7113 
7114 	      /* Scalars passed to an assumed rank argument are converted to
7115 		 a descriptor. Obtain the data field before deallocating any
7116 		 allocatable components.  */
7117 	      if (parm_rank == 0 && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp)))
7118 		tmp = gfc_conv_descriptor_data_get (tmp);
7119 
7120 	      if (scalar_res_outside_loop)
7121 		{
7122 		  /* Go through the ss chain to find the argument and use
7123 		     the stored value.  */
7124 		  gfc_ss *tmp_ss = parmse.loop->ss;
7125 		  for (; tmp_ss; tmp_ss = tmp_ss->next)
7126 		    if (tmp_ss->info
7127 			&& tmp_ss->info->expr == e
7128 			&& tmp_ss->info->data.scalar.value != NULL_TREE)
7129 		      {
7130 			tmp = tmp_ss->info->data.scalar.value;
7131 			break;
7132 		      }
7133 		}
7134 
7135 	      STRIP_NOPS (tmp);
7136 
7137 	      if (derived_array != NULL_TREE)
7138 		tmp = gfc_deallocate_alloc_comp (e->ts.u.derived,
7139 						 derived_array,
7140 						 parm_rank);
7141 	      else if ((e->ts.type == BT_CLASS
7142 			&& GFC_CLASS_TYPE_P (TREE_TYPE (tmp)))
7143 		       || e->ts.type == BT_DERIVED)
7144 		tmp = gfc_deallocate_alloc_comp (e->ts.u.derived, tmp,
7145 						 parm_rank);
7146 	      else if (e->ts.type == BT_CLASS)
7147 		tmp = gfc_deallocate_alloc_comp (CLASS_DATA (e)->ts.u.derived,
7148 						 tmp, parm_rank);
7149 
7150 	      if (scalar_res_outside_loop)
7151 		gfc_add_expr_to_block (&parmse.loop->post, tmp);
7152 	      else
7153 		gfc_prepend_expr_to_block (&post, tmp);
7154 	    }
7155         }
7156 
7157       /* Add argument checking of passing an unallocated/NULL actual to
7158          a nonallocatable/nonpointer dummy.  */
7159 
7160       if (gfc_option.rtcheck & GFC_RTCHECK_POINTER && e != NULL)
7161         {
7162 	  symbol_attribute attr;
7163 	  char *msg;
7164 	  tree cond;
7165 	  tree tmp;
7166 	  symbol_attribute fsym_attr;
7167 
7168 	  if (fsym)
7169 	    {
7170 	      if (fsym->ts.type == BT_CLASS)
7171 		{
7172 		  fsym_attr = CLASS_DATA (fsym)->attr;
7173 		  fsym_attr.pointer = fsym_attr.class_pointer;
7174 		}
7175 	      else
7176 		fsym_attr = fsym->attr;
7177 	    }
7178 
7179 	  if (e->expr_type == EXPR_VARIABLE || e->expr_type == EXPR_FUNCTION)
7180 	    attr = gfc_expr_attr (e);
7181 	  else
7182 	    goto end_pointer_check;
7183 
7184 	  /*  In Fortran 2008 it's allowed to pass a NULL pointer/nonallocated
7185 	      allocatable to an optional dummy, cf. 12.5.2.12.  */
7186 	  if (fsym != NULL && fsym->attr.optional && !attr.proc_pointer
7187 	      && (gfc_option.allow_std & GFC_STD_F2008) != 0)
7188 	    goto end_pointer_check;
7189 
7190           if (attr.optional)
7191 	    {
7192               /* If the actual argument is an optional pointer/allocatable and
7193 		 the formal argument takes an nonpointer optional value,
7194 		 it is invalid to pass a non-present argument on, even
7195 		 though there is no technical reason for this in gfortran.
7196 		 See Fortran 2003, Section 12.4.1.6 item (7)+(8).  */
7197 	      tree present, null_ptr, type;
7198 
7199 	      if (attr.allocatable
7200 		  && (fsym == NULL || !fsym_attr.allocatable))
7201 		msg = xasprintf ("Allocatable actual argument '%s' is not "
7202 				 "allocated or not present",
7203 				 e->symtree->n.sym->name);
7204 	      else if (attr.pointer
7205 		       && (fsym == NULL || !fsym_attr.pointer))
7206 		msg = xasprintf ("Pointer actual argument '%s' is not "
7207 				 "associated or not present",
7208 				 e->symtree->n.sym->name);
7209 	      else if (attr.proc_pointer && !e->value.function.actual
7210 		       && (fsym == NULL || !fsym_attr.proc_pointer))
7211 		msg = xasprintf ("Proc-pointer actual argument '%s' is not "
7212 				 "associated or not present",
7213 				 e->symtree->n.sym->name);
7214 	      else
7215 		goto end_pointer_check;
7216 
7217 	      present = gfc_conv_expr_present (e->symtree->n.sym);
7218 	      type = TREE_TYPE (present);
7219 	      present = fold_build2_loc (input_location, EQ_EXPR,
7220 					 logical_type_node, present,
7221 					 fold_convert (type,
7222 						       null_pointer_node));
7223 	      type = TREE_TYPE (parmse.expr);
7224 	      null_ptr = fold_build2_loc (input_location, EQ_EXPR,
7225 					  logical_type_node, parmse.expr,
7226 					  fold_convert (type,
7227 							null_pointer_node));
7228 	      cond = fold_build2_loc (input_location, TRUTH_ORIF_EXPR,
7229 				      logical_type_node, present, null_ptr);
7230 	    }
7231           else
7232 	    {
7233 	      if (attr.allocatable
7234 		  && (fsym == NULL || !fsym_attr.allocatable))
7235 		msg = xasprintf ("Allocatable actual argument '%s' is not "
7236 				 "allocated", e->symtree->n.sym->name);
7237 	      else if (attr.pointer
7238 		       && (fsym == NULL || !fsym_attr.pointer))
7239 		msg = xasprintf ("Pointer actual argument '%s' is not "
7240 				 "associated", e->symtree->n.sym->name);
7241 	      else if (attr.proc_pointer && !e->value.function.actual
7242 		       && (fsym == NULL || !fsym_attr.proc_pointer))
7243 		msg = xasprintf ("Proc-pointer actual argument '%s' is not "
7244 				 "associated", e->symtree->n.sym->name);
7245 	      else
7246 		goto end_pointer_check;
7247 
7248 	      tmp = parmse.expr;
7249 	      if (fsym && fsym->ts.type == BT_CLASS)
7250 		{
7251 		  if (POINTER_TYPE_P (TREE_TYPE (tmp)))
7252 		    tmp = build_fold_indirect_ref_loc (input_location, tmp);
7253 		  tmp = gfc_class_data_get (tmp);
7254 		  if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp)))
7255 		    tmp = gfc_conv_descriptor_data_get (tmp);
7256 		}
7257 
7258 	      /* If the argument is passed by value, we need to strip the
7259 		 INDIRECT_REF.  */
7260 	      if (!POINTER_TYPE_P (TREE_TYPE (tmp)))
7261 		tmp = gfc_build_addr_expr (NULL_TREE, tmp);
7262 
7263 	      cond = fold_build2_loc (input_location, EQ_EXPR,
7264 				      logical_type_node, tmp,
7265 				      fold_convert (TREE_TYPE (tmp),
7266 						    null_pointer_node));
7267 	    }
7268 
7269 	  gfc_trans_runtime_check (true, false, cond, &se->pre, &e->where,
7270 				   msg);
7271 	  free (msg);
7272         }
7273       end_pointer_check:
7274 
7275       /* Deferred length dummies pass the character length by reference
7276 	 so that the value can be returned.  */
7277       if (parmse.string_length && fsym && fsym->ts.deferred)
7278 	{
7279 	  if (INDIRECT_REF_P (parmse.string_length))
7280 	    /* In chains of functions/procedure calls the string_length already
7281 	       is a pointer to the variable holding the length.  Therefore
7282 	       remove the deref on call.  */
7283 	    parmse.string_length = TREE_OPERAND (parmse.string_length, 0);
7284 	  else
7285 	    {
7286 	      tmp = parmse.string_length;
7287 	      if (!VAR_P (tmp) && TREE_CODE (tmp) != COMPONENT_REF)
7288 		tmp = gfc_evaluate_now (parmse.string_length, &se->pre);
7289 	      parmse.string_length = gfc_build_addr_expr (NULL_TREE, tmp);
7290 	    }
7291 	}
7292 
7293       /* Character strings are passed as two parameters, a length and a
7294 	 pointer - except for Bind(c) which only passes the pointer.
7295 	 An unlimited polymorphic formal argument likewise does not
7296 	 need the length.  */
7297       if (parmse.string_length != NULL_TREE
7298 	  && !sym->attr.is_bind_c
7299 	  && !(fsym && UNLIMITED_POLY (fsym)))
7300 	vec_safe_push (stringargs, parmse.string_length);
7301 
7302       /* When calling __copy for character expressions to unlimited
7303 	 polymorphic entities, the dst argument needs a string length.  */
7304       if (sym->name[0] == '_' && e && e->ts.type == BT_CHARACTER
7305 	  && startswith (sym->name, "__vtab_CHARACTER")
7306 	  && arg->next && arg->next->expr
7307 	  && (arg->next->expr->ts.type == BT_DERIVED
7308 	      || arg->next->expr->ts.type == BT_CLASS)
7309 	  && arg->next->expr->ts.u.derived->attr.unlimited_polymorphic)
7310 	vec_safe_push (stringargs, parmse.string_length);
7311 
7312       /* For descriptorless coarrays and assumed-shape coarray dummies, we
7313 	 pass the token and the offset as additional arguments.  */
7314       if (fsym && e == NULL && flag_coarray == GFC_FCOARRAY_LIB
7315 	  && ((fsym->ts.type != BT_CLASS && fsym->attr.codimension
7316 	       && !fsym->attr.allocatable)
7317 	      || (fsym->ts.type == BT_CLASS
7318 		  && CLASS_DATA (fsym)->attr.codimension
7319 		  && !CLASS_DATA (fsym)->attr.allocatable)))
7320 	{
7321 	  /* Token and offset.  */
7322 	  vec_safe_push (stringargs, null_pointer_node);
7323 	  vec_safe_push (stringargs, build_int_cst (gfc_array_index_type, 0));
7324 	  gcc_assert (fsym->attr.optional);
7325 	}
7326       else if (fsym && flag_coarray == GFC_FCOARRAY_LIB
7327 	       && ((fsym->ts.type != BT_CLASS && fsym->attr.codimension
7328 		    && !fsym->attr.allocatable)
7329 		   || (fsym->ts.type == BT_CLASS
7330 		       && CLASS_DATA (fsym)->attr.codimension
7331 		       && !CLASS_DATA (fsym)->attr.allocatable)))
7332 	{
7333 	  tree caf_decl, caf_type;
7334 	  tree offset, tmp2;
7335 
7336 	  caf_decl = gfc_get_tree_for_caf_expr (e);
7337 	  caf_type = TREE_TYPE (caf_decl);
7338 
7339 	  if (GFC_DESCRIPTOR_TYPE_P (caf_type)
7340 	      && (GFC_TYPE_ARRAY_AKIND (caf_type) == GFC_ARRAY_ALLOCATABLE
7341 		  || GFC_TYPE_ARRAY_AKIND (caf_type) == GFC_ARRAY_POINTER))
7342 	    tmp = gfc_conv_descriptor_token (caf_decl);
7343 	  else if (DECL_LANG_SPECIFIC (caf_decl)
7344 		   && GFC_DECL_TOKEN (caf_decl) != NULL_TREE)
7345 	    tmp = GFC_DECL_TOKEN (caf_decl);
7346 	  else
7347 	    {
7348 	      gcc_assert (GFC_ARRAY_TYPE_P (caf_type)
7349 			  && GFC_TYPE_ARRAY_CAF_TOKEN (caf_type) != NULL_TREE);
7350 	      tmp = GFC_TYPE_ARRAY_CAF_TOKEN (caf_type);
7351 	    }
7352 
7353 	  vec_safe_push (stringargs, tmp);
7354 
7355 	  if (GFC_DESCRIPTOR_TYPE_P (caf_type)
7356 	      && GFC_TYPE_ARRAY_AKIND (caf_type) == GFC_ARRAY_ALLOCATABLE)
7357 	    offset = build_int_cst (gfc_array_index_type, 0);
7358 	  else if (DECL_LANG_SPECIFIC (caf_decl)
7359 		   && GFC_DECL_CAF_OFFSET (caf_decl) != NULL_TREE)
7360 	    offset = GFC_DECL_CAF_OFFSET (caf_decl);
7361 	  else if (GFC_TYPE_ARRAY_CAF_OFFSET (caf_type) != NULL_TREE)
7362 	    offset = GFC_TYPE_ARRAY_CAF_OFFSET (caf_type);
7363 	  else
7364 	    offset = build_int_cst (gfc_array_index_type, 0);
7365 
7366 	  if (GFC_DESCRIPTOR_TYPE_P (caf_type))
7367 	    tmp = gfc_conv_descriptor_data_get (caf_decl);
7368 	  else
7369 	    {
7370 	      gcc_assert (POINTER_TYPE_P (caf_type));
7371 	      tmp = caf_decl;
7372 	    }
7373 
7374           tmp2 = fsym->ts.type == BT_CLASS
7375 		 ? gfc_class_data_get (parmse.expr) : parmse.expr;
7376           if ((fsym->ts.type != BT_CLASS
7377 	       && (fsym->as->type == AS_ASSUMED_SHAPE
7378 		   || fsym->as->type == AS_ASSUMED_RANK))
7379 	      || (fsym->ts.type == BT_CLASS
7380 		  && (CLASS_DATA (fsym)->as->type == AS_ASSUMED_SHAPE
7381 		      || CLASS_DATA (fsym)->as->type == AS_ASSUMED_RANK)))
7382 	    {
7383 	      if (fsym->ts.type == BT_CLASS)
7384 		gcc_assert (!POINTER_TYPE_P (TREE_TYPE (tmp2)));
7385 	      else
7386 		{
7387 		  gcc_assert (POINTER_TYPE_P (TREE_TYPE (tmp2)));
7388 		  tmp2 = build_fold_indirect_ref_loc (input_location, tmp2);
7389 		}
7390 	      gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp2)));
7391 	      tmp2 = gfc_conv_descriptor_data_get (tmp2);
7392 	    }
7393 	  else if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp2)))
7394 	    tmp2 = gfc_conv_descriptor_data_get (tmp2);
7395 	  else
7396 	    {
7397 	      gcc_assert (POINTER_TYPE_P (TREE_TYPE (tmp2)));
7398 	    }
7399 
7400 	  tmp = fold_build2_loc (input_location, MINUS_EXPR,
7401                                  gfc_array_index_type,
7402                                  fold_convert (gfc_array_index_type, tmp2),
7403                                  fold_convert (gfc_array_index_type, tmp));
7404 	  offset = fold_build2_loc (input_location, PLUS_EXPR,
7405 				    gfc_array_index_type, offset, tmp);
7406 
7407 	  vec_safe_push (stringargs, offset);
7408 	}
7409 
7410       vec_safe_push (arglist, parmse.expr);
7411     }
7412   gfc_add_block_to_block (&se->pre, &clobbers);
7413   gfc_finish_interface_mapping (&mapping, &se->pre, &se->post);
7414 
7415   if (comp)
7416     ts = comp->ts;
7417   else if (sym->ts.type == BT_CLASS)
7418     ts = CLASS_DATA (sym)->ts;
7419   else
7420     ts = sym->ts;
7421 
7422   if (ts.type == BT_CHARACTER && sym->attr.is_bind_c)
7423     se->string_length = build_int_cst (gfc_charlen_type_node, 1);
7424   else if (ts.type == BT_CHARACTER)
7425     {
7426       if (ts.u.cl->length == NULL)
7427 	{
7428 	  /* Assumed character length results are not allowed by C418 of the 2003
7429 	     standard and are trapped in resolve.cc; except in the case of SPREAD
7430 	     (and other intrinsics?) and dummy functions.  In the case of SPREAD,
7431 	     we take the character length of the first argument for the result.
7432 	     For dummies, we have to look through the formal argument list for
7433 	     this function and use the character length found there.
7434 	     Likewise, we handle the case of deferred-length character dummy
7435 	     arguments to intrinsics that determine the characteristics of
7436 	     the result, which cannot be deferred-length.  */
7437 	  if (expr->value.function.isym)
7438 	    ts.deferred = false;
7439 	  if (ts.deferred)
7440 	    cl.backend_decl = gfc_create_var (gfc_charlen_type_node, "slen");
7441 	  else if (!sym->attr.dummy)
7442 	    cl.backend_decl = (*stringargs)[0];
7443 	  else
7444 	    {
7445 	      formal = gfc_sym_get_dummy_args (sym->ns->proc_name);
7446 	      for (; formal; formal = formal->next)
7447 		if (strcmp (formal->sym->name, sym->name) == 0)
7448 		  cl.backend_decl = formal->sym->ts.u.cl->backend_decl;
7449 	    }
7450 	  len = cl.backend_decl;
7451         }
7452       else
7453         {
7454 	  tree tmp;
7455 
7456 	  /* Calculate the length of the returned string.  */
7457 	  gfc_init_se (&parmse, NULL);
7458 	  if (need_interface_mapping)
7459 	    gfc_apply_interface_mapping (&mapping, &parmse, ts.u.cl->length);
7460 	  else
7461 	    gfc_conv_expr (&parmse, ts.u.cl->length);
7462 	  gfc_add_block_to_block (&se->pre, &parmse.pre);
7463 	  gfc_add_block_to_block (&se->post, &parmse.post);
7464 	  tmp = parmse.expr;
7465 	  /* TODO: It would be better to have the charlens as
7466 	     gfc_charlen_type_node already when the interface is
7467 	     created instead of converting it here (see PR 84615).  */
7468 	  tmp = fold_build2_loc (input_location, MAX_EXPR,
7469 				 gfc_charlen_type_node,
7470 				 fold_convert (gfc_charlen_type_node, tmp),
7471 				 build_zero_cst (gfc_charlen_type_node));
7472 	  cl.backend_decl = tmp;
7473 	}
7474 
7475       /* Set up a charlen structure for it.  */
7476       cl.next = NULL;
7477       cl.length = NULL;
7478       ts.u.cl = &cl;
7479 
7480       len = cl.backend_decl;
7481     }
7482 
7483   byref = (comp && (comp->attr.dimension
7484 	   || (comp->ts.type == BT_CHARACTER && !sym->attr.is_bind_c)))
7485 	   || (!comp && gfc_return_by_reference (sym));
7486   if (byref)
7487     {
7488       if (se->direct_byref)
7489 	{
7490 	  /* Sometimes, too much indirection can be applied; e.g. for
7491 	     function_result = array_valued_recursive_function.  */
7492 	  if (TREE_TYPE (TREE_TYPE (se->expr))
7493 		&& TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr)))
7494 		&& GFC_DESCRIPTOR_TYPE_P
7495 			(TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr)))))
7496 	    se->expr = build_fold_indirect_ref_loc (input_location,
7497 						    se->expr);
7498 
7499 	  /* If the lhs of an assignment x = f(..) is allocatable and
7500 	     f2003 is allowed, we must do the automatic reallocation.
7501 	     TODO - deal with intrinsics, without using a temporary.  */
7502 	  if (flag_realloc_lhs
7503 		&& se->ss && se->ss->loop_chain
7504 		&& se->ss->loop_chain->is_alloc_lhs
7505 		&& !expr->value.function.isym
7506 		&& sym->result->as != NULL)
7507 	    {
7508 	      /* Evaluate the bounds of the result, if known.  */
7509 	      gfc_set_loop_bounds_from_array_spec (&mapping, se,
7510 						   sym->result->as);
7511 
7512 	      /* Perform the automatic reallocation.  */
7513 	      tmp = gfc_alloc_allocatable_for_assignment (se->loop,
7514 							  expr, NULL);
7515 	      gfc_add_expr_to_block (&se->pre, tmp);
7516 
7517 	      /* Pass the temporary as the first argument.  */
7518 	      result = info->descriptor;
7519 	    }
7520 	  else
7521 	    result = build_fold_indirect_ref_loc (input_location,
7522 						  se->expr);
7523 	  vec_safe_push (retargs, se->expr);
7524 	}
7525       else if (comp && comp->attr.dimension)
7526 	{
7527 	  gcc_assert (se->loop && info);
7528 
7529 	  /* Set the type of the array.  */
7530 	  tmp = gfc_typenode_for_spec (&comp->ts);
7531 	  gcc_assert (se->ss->dimen == se->loop->dimen);
7532 
7533 	  /* Evaluate the bounds of the result, if known.  */
7534 	  gfc_set_loop_bounds_from_array_spec (&mapping, se, comp->as);
7535 
7536 	  /* If the lhs of an assignment x = f(..) is allocatable and
7537 	     f2003 is allowed, we must not generate the function call
7538 	     here but should just send back the results of the mapping.
7539 	     This is signalled by the function ss being flagged.  */
7540 	  if (flag_realloc_lhs && se->ss && se->ss->is_alloc_lhs)
7541 	    {
7542 	      gfc_free_interface_mapping (&mapping);
7543 	      return has_alternate_specifier;
7544 	    }
7545 
7546 	  /* Create a temporary to store the result.  In case the function
7547 	     returns a pointer, the temporary will be a shallow copy and
7548 	     mustn't be deallocated.  */
7549 	  callee_alloc = comp->attr.allocatable || comp->attr.pointer;
7550 	  gfc_trans_create_temp_array (&se->pre, &se->post, se->ss,
7551 				       tmp, NULL_TREE, false,
7552 				       !comp->attr.pointer, callee_alloc,
7553 				       &se->ss->info->expr->where);
7554 
7555 	  /* Pass the temporary as the first argument.  */
7556 	  result = info->descriptor;
7557 	  tmp = gfc_build_addr_expr (NULL_TREE, result);
7558 	  vec_safe_push (retargs, tmp);
7559 	}
7560       else if (!comp && sym->result->attr.dimension)
7561 	{
7562 	  gcc_assert (se->loop && info);
7563 
7564 	  /* Set the type of the array.  */
7565 	  tmp = gfc_typenode_for_spec (&ts);
7566 	  gcc_assert (se->ss->dimen == se->loop->dimen);
7567 
7568 	  /* Evaluate the bounds of the result, if known.  */
7569 	  gfc_set_loop_bounds_from_array_spec (&mapping, se, sym->result->as);
7570 
7571 	  /* If the lhs of an assignment x = f(..) is allocatable and
7572 	     f2003 is allowed, we must not generate the function call
7573 	     here but should just send back the results of the mapping.
7574 	     This is signalled by the function ss being flagged.  */
7575 	  if (flag_realloc_lhs && se->ss && se->ss->is_alloc_lhs)
7576 	    {
7577 	      gfc_free_interface_mapping (&mapping);
7578 	      return has_alternate_specifier;
7579 	    }
7580 
7581 	  /* Create a temporary to store the result.  In case the function
7582 	     returns a pointer, the temporary will be a shallow copy and
7583 	     mustn't be deallocated.  */
7584 	  callee_alloc = sym->attr.allocatable || sym->attr.pointer;
7585 	  gfc_trans_create_temp_array (&se->pre, &se->post, se->ss,
7586 				       tmp, NULL_TREE, false,
7587 				       !sym->attr.pointer, callee_alloc,
7588 				       &se->ss->info->expr->where);
7589 
7590 	  /* Pass the temporary as the first argument.  */
7591 	  result = info->descriptor;
7592 	  tmp = gfc_build_addr_expr (NULL_TREE, result);
7593 	  vec_safe_push (retargs, tmp);
7594 	}
7595       else if (ts.type == BT_CHARACTER)
7596 	{
7597 	  /* Pass the string length.  */
7598 	  type = gfc_get_character_type (ts.kind, ts.u.cl);
7599 	  type = build_pointer_type (type);
7600 
7601 	  /* Emit a DECL_EXPR for the VLA type.  */
7602 	  tmp = TREE_TYPE (type);
7603 	  if (TYPE_SIZE (tmp)
7604 	      && TREE_CODE (TYPE_SIZE (tmp)) != INTEGER_CST)
7605 	    {
7606 	      tmp = build_decl (input_location, TYPE_DECL, NULL_TREE, tmp);
7607 	      DECL_ARTIFICIAL (tmp) = 1;
7608 	      DECL_IGNORED_P (tmp) = 1;
7609 	      tmp = fold_build1_loc (input_location, DECL_EXPR,
7610 				     TREE_TYPE (tmp), tmp);
7611 	      gfc_add_expr_to_block (&se->pre, tmp);
7612 	    }
7613 
7614 	  /* Return an address to a char[0:len-1]* temporary for
7615 	     character pointers.  */
7616 	  if ((!comp && (sym->attr.pointer || sym->attr.allocatable))
7617 	       || (comp && (comp->attr.pointer || comp->attr.allocatable)))
7618 	    {
7619 	      var = gfc_create_var (type, "pstr");
7620 
7621 	      if ((!comp && sym->attr.allocatable)
7622 		  || (comp && comp->attr.allocatable))
7623 		{
7624 		  gfc_add_modify (&se->pre, var,
7625 				  fold_convert (TREE_TYPE (var),
7626 						null_pointer_node));
7627 		  tmp = gfc_call_free (var);
7628 		  gfc_add_expr_to_block (&se->post, tmp);
7629 		}
7630 
7631 	      /* Provide an address expression for the function arguments.  */
7632 	      var = gfc_build_addr_expr (NULL_TREE, var);
7633 	    }
7634 	  else
7635 	    var = gfc_conv_string_tmp (se, type, len);
7636 
7637 	  vec_safe_push (retargs, var);
7638 	}
7639       else
7640 	{
7641 	  gcc_assert (flag_f2c && ts.type == BT_COMPLEX);
7642 
7643 	  type = gfc_get_complex_type (ts.kind);
7644 	  var = gfc_build_addr_expr (NULL_TREE, gfc_create_var (type, "cmplx"));
7645 	  vec_safe_push (retargs, var);
7646 	}
7647 
7648       /* Add the string length to the argument list.  */
7649       if (ts.type == BT_CHARACTER && ts.deferred)
7650 	{
7651 	  tmp = len;
7652 	  if (!VAR_P (tmp))
7653 	    tmp = gfc_evaluate_now (len, &se->pre);
7654 	  TREE_STATIC (tmp) = 1;
7655 	  gfc_add_modify (&se->pre, tmp,
7656 			  build_int_cst (TREE_TYPE (tmp), 0));
7657 	  tmp = gfc_build_addr_expr (NULL_TREE, tmp);
7658 	  vec_safe_push (retargs, tmp);
7659 	}
7660       else if (ts.type == BT_CHARACTER)
7661 	vec_safe_push (retargs, len);
7662     }
7663   gfc_free_interface_mapping (&mapping);
7664 
7665   /* We need to glom RETARGS + ARGLIST + STRINGARGS + APPEND_ARGS.  */
7666   arglen = (vec_safe_length (arglist) + vec_safe_length (optionalargs)
7667 	    + vec_safe_length (stringargs) + vec_safe_length (append_args));
7668   vec_safe_reserve (retargs, arglen);
7669 
7670   /* Add the return arguments.  */
7671   vec_safe_splice (retargs, arglist);
7672 
7673   /* Add the hidden present status for optional+value to the arguments.  */
7674   vec_safe_splice (retargs, optionalargs);
7675 
7676   /* Add the hidden string length parameters to the arguments.  */
7677   vec_safe_splice (retargs, stringargs);
7678 
7679   /* We may want to append extra arguments here.  This is used e.g. for
7680      calls to libgfortran_matmul_??, which need extra information.  */
7681   vec_safe_splice (retargs, append_args);
7682 
7683   arglist = retargs;
7684 
7685   /* Generate the actual call.  */
7686   if (base_object == NULL_TREE)
7687     conv_function_val (se, sym, expr, args);
7688   else
7689     conv_base_obj_fcn_val (se, base_object, expr);
7690 
7691   /* If there are alternate return labels, function type should be
7692      integer.  Can't modify the type in place though, since it can be shared
7693      with other functions.  For dummy arguments, the typing is done to
7694      this result, even if it has to be repeated for each call.  */
7695   if (has_alternate_specifier
7696       && TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr))) != integer_type_node)
7697     {
7698       if (!sym->attr.dummy)
7699 	{
7700 	  TREE_TYPE (sym->backend_decl)
7701 		= build_function_type (integer_type_node,
7702 		      TYPE_ARG_TYPES (TREE_TYPE (sym->backend_decl)));
7703 	  se->expr = gfc_build_addr_expr (NULL_TREE, sym->backend_decl);
7704 	}
7705       else
7706 	TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr))) = integer_type_node;
7707     }
7708 
7709   fntype = TREE_TYPE (TREE_TYPE (se->expr));
7710   se->expr = build_call_vec (TREE_TYPE (fntype), se->expr, arglist);
7711 
7712   /* Allocatable scalar function results must be freed and nullified
7713      after use. This necessitates the creation of a temporary to
7714      hold the result to prevent duplicate calls.  */
7715   if (!byref && sym->ts.type != BT_CHARACTER
7716       && ((sym->attr.allocatable && !sym->attr.dimension && !comp)
7717 	  || (comp && comp->attr.allocatable && !comp->attr.dimension)))
7718     {
7719       tmp = gfc_create_var (TREE_TYPE (se->expr), NULL);
7720       gfc_add_modify (&se->pre, tmp, se->expr);
7721       se->expr = tmp;
7722       tmp = gfc_call_free (tmp);
7723       gfc_add_expr_to_block (&post, tmp);
7724       gfc_add_modify (&post, se->expr, build_int_cst (TREE_TYPE (se->expr), 0));
7725     }
7726 
7727   /* If we have a pointer function, but we don't want a pointer, e.g.
7728      something like
7729         x = f()
7730      where f is pointer valued, we have to dereference the result.  */
7731   if (!se->want_pointer && !byref
7732       && ((!comp && (sym->attr.pointer || sym->attr.allocatable))
7733 	  || (comp && (comp->attr.pointer || comp->attr.allocatable))))
7734     se->expr = build_fold_indirect_ref_loc (input_location, se->expr);
7735 
7736   /* f2c calling conventions require a scalar default real function to
7737      return a double precision result.  Convert this back to default
7738      real.  We only care about the cases that can happen in Fortran 77.
7739   */
7740   if (flag_f2c && sym->ts.type == BT_REAL
7741       && sym->ts.kind == gfc_default_real_kind
7742       && !sym->attr.always_explicit)
7743     se->expr = fold_convert (gfc_get_real_type (sym->ts.kind), se->expr);
7744 
7745   /* A pure function may still have side-effects - it may modify its
7746      parameters.  */
7747   TREE_SIDE_EFFECTS (se->expr) = 1;
7748 #if 0
7749   if (!sym->attr.pure)
7750     TREE_SIDE_EFFECTS (se->expr) = 1;
7751 #endif
7752 
7753   if (byref)
7754     {
7755       /* Add the function call to the pre chain.  There is no expression.  */
7756       gfc_add_expr_to_block (&se->pre, se->expr);
7757       se->expr = NULL_TREE;
7758 
7759       if (!se->direct_byref)
7760 	{
7761 	  if ((sym->attr.dimension && !comp) || (comp && comp->attr.dimension))
7762 	    {
7763 	      if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
7764 		{
7765 		  /* Check the data pointer hasn't been modified.  This would
7766 		     happen in a function returning a pointer.  */
7767 		  tmp = gfc_conv_descriptor_data_get (info->descriptor);
7768 		  tmp = fold_build2_loc (input_location, NE_EXPR,
7769 					 logical_type_node,
7770 					 tmp, info->data);
7771 		  gfc_trans_runtime_check (true, false, tmp, &se->pre, NULL,
7772 					   gfc_msg_fault);
7773 		}
7774 	      se->expr = info->descriptor;
7775 	      /* Bundle in the string length.  */
7776 	      se->string_length = len;
7777 	    }
7778 	  else if (ts.type == BT_CHARACTER)
7779 	    {
7780 	      /* Dereference for character pointer results.  */
7781 	      if ((!comp && (sym->attr.pointer || sym->attr.allocatable))
7782 		  || (comp && (comp->attr.pointer || comp->attr.allocatable)))
7783 		se->expr = build_fold_indirect_ref_loc (input_location, var);
7784 	      else
7785 	        se->expr = var;
7786 
7787 	      se->string_length = len;
7788 	    }
7789 	  else
7790 	    {
7791 	      gcc_assert (ts.type == BT_COMPLEX && flag_f2c);
7792 	      se->expr = build_fold_indirect_ref_loc (input_location, var);
7793 	    }
7794 	}
7795     }
7796 
7797   /* Associate the rhs class object's meta-data with the result, when the
7798      result is a temporary.  */
7799   if (args && args->expr && args->expr->ts.type == BT_CLASS
7800       && sym->ts.type == BT_CLASS && result != NULL_TREE && DECL_P (result)
7801       && !GFC_CLASS_TYPE_P (TREE_TYPE (result)))
7802     {
7803       gfc_se parmse;
7804       gfc_expr *class_expr = gfc_find_and_cut_at_last_class_ref (args->expr);
7805 
7806       gfc_init_se (&parmse, NULL);
7807       parmse.data_not_needed = 1;
7808       gfc_conv_expr (&parmse, class_expr);
7809       if (!DECL_LANG_SPECIFIC (result))
7810 	gfc_allocate_lang_decl (result);
7811       GFC_DECL_SAVED_DESCRIPTOR (result) = parmse.expr;
7812       gfc_free_expr (class_expr);
7813       /* -fcheck= can add diagnostic code, which has to be placed before
7814 	 the call. */
7815       if (parmse.pre.head != NULL)
7816 	  gfc_add_expr_to_block (&se->pre, parmse.pre.head);
7817       gcc_assert (parmse.post.head == NULL_TREE);
7818     }
7819 
7820   /* Follow the function call with the argument post block.  */
7821   if (byref)
7822     {
7823       gfc_add_block_to_block (&se->pre, &post);
7824 
7825       /* Transformational functions of derived types with allocatable
7826 	 components must have the result allocatable components copied when the
7827 	 argument is actually given.  */
7828       arg = expr->value.function.actual;
7829       if (result && arg && expr->rank
7830 	  && expr->value.function.isym
7831 	  && expr->value.function.isym->transformational
7832 	  && arg->expr
7833 	  && arg->expr->ts.type == BT_DERIVED
7834 	  && arg->expr->ts.u.derived->attr.alloc_comp)
7835 	{
7836 	  tree tmp2;
7837 	  /* Copy the allocatable components.  We have to use a
7838 	     temporary here to prevent source allocatable components
7839 	     from being corrupted.  */
7840 	  tmp2 = gfc_evaluate_now (result, &se->pre);
7841 	  tmp = gfc_copy_alloc_comp (arg->expr->ts.u.derived,
7842 				     result, tmp2, expr->rank, 0);
7843 	  gfc_add_expr_to_block (&se->pre, tmp);
7844 	  tmp = gfc_copy_allocatable_data (result, tmp2, TREE_TYPE(tmp2),
7845 				           expr->rank);
7846 	  gfc_add_expr_to_block (&se->pre, tmp);
7847 
7848 	  /* Finally free the temporary's data field.  */
7849 	  tmp = gfc_conv_descriptor_data_get (tmp2);
7850 	  tmp = gfc_deallocate_with_status (tmp, NULL_TREE, NULL_TREE,
7851 					    NULL_TREE, NULL_TREE, true,
7852 					    NULL, GFC_CAF_COARRAY_NOCOARRAY);
7853 	  gfc_add_expr_to_block (&se->pre, tmp);
7854 	}
7855     }
7856   else
7857     {
7858       /* For a function with a class array result, save the result as
7859 	 a temporary, set the info fields needed by the scalarizer and
7860 	 call the finalization function of the temporary. Note that the
7861 	 nullification of allocatable components needed by the result
7862 	 is done in gfc_trans_assignment_1.  */
7863       if (expr && ((gfc_is_class_array_function (expr)
7864 		    && se->ss && se->ss->loop)
7865 		   || gfc_is_alloc_class_scalar_function (expr))
7866 	  && se->expr && GFC_CLASS_TYPE_P (TREE_TYPE (se->expr))
7867 	  && expr->must_finalize)
7868 	{
7869 	  tree final_fndecl;
7870 	  tree is_final;
7871 	  int n;
7872 	  if (se->ss && se->ss->loop)
7873 	    {
7874 	      gfc_add_block_to_block (&se->ss->loop->pre, &se->pre);
7875 	      se->expr = gfc_evaluate_now (se->expr, &se->ss->loop->pre);
7876 	      tmp = gfc_class_data_get (se->expr);
7877 	      info->descriptor = tmp;
7878 	      info->data = gfc_conv_descriptor_data_get (tmp);
7879 	      info->offset = gfc_conv_descriptor_offset_get (tmp);
7880 	      for (n = 0; n < se->ss->loop->dimen; n++)
7881 		{
7882 		  tree dim = gfc_rank_cst[n];
7883 		  se->ss->loop->to[n] = gfc_conv_descriptor_ubound_get (tmp, dim);
7884 		  se->ss->loop->from[n] = gfc_conv_descriptor_lbound_get (tmp, dim);
7885 		}
7886 	    }
7887 	  else
7888 	    {
7889 	      /* TODO Eliminate the doubling of temporaries. This
7890 		 one is necessary to ensure no memory leakage.  */
7891 	      se->expr = gfc_evaluate_now (se->expr, &se->pre);
7892 	      tmp = gfc_class_data_get (se->expr);
7893 	      tmp = gfc_conv_scalar_to_descriptor (se, tmp,
7894 			CLASS_DATA (expr->value.function.esym->result)->attr);
7895 	    }
7896 
7897 	  if ((gfc_is_class_array_function (expr)
7898 	       || gfc_is_alloc_class_scalar_function (expr))
7899 	      && CLASS_DATA (expr->value.function.esym->result)->attr.pointer)
7900 	    goto no_finalization;
7901 
7902 	  final_fndecl = gfc_class_vtab_final_get (se->expr);
7903 	  is_final = fold_build2_loc (input_location, NE_EXPR,
7904 				      logical_type_node,
7905 				      final_fndecl,
7906 				      fold_convert (TREE_TYPE (final_fndecl),
7907 					   	    null_pointer_node));
7908 	  final_fndecl = build_fold_indirect_ref_loc (input_location,
7909 						      final_fndecl);
7910  	  tmp = build_call_expr_loc (input_location,
7911 				     final_fndecl, 3,
7912 				     gfc_build_addr_expr (NULL, tmp),
7913 				     gfc_class_vtab_size_get (se->expr),
7914 				     boolean_false_node);
7915 	  tmp = fold_build3_loc (input_location, COND_EXPR,
7916 				 void_type_node, is_final, tmp,
7917 				 build_empty_stmt (input_location));
7918 
7919 	  if (se->ss && se->ss->loop)
7920 	    {
7921 	      gfc_prepend_expr_to_block (&se->ss->loop->post, tmp);
7922 	      tmp = fold_build2_loc (input_location, NE_EXPR,
7923 				     logical_type_node,
7924 				     info->data,
7925 				     fold_convert (TREE_TYPE (info->data),
7926 					   	    null_pointer_node));
7927 	      tmp = fold_build3_loc (input_location, COND_EXPR,
7928 				     void_type_node, tmp,
7929 				     gfc_call_free (info->data),
7930 				     build_empty_stmt (input_location));
7931 	      gfc_add_expr_to_block (&se->ss->loop->post, tmp);
7932 	    }
7933 	  else
7934 	    {
7935 	      tree classdata;
7936 	      gfc_prepend_expr_to_block (&se->post, tmp);
7937 	      classdata = gfc_class_data_get (se->expr);
7938 	      tmp = fold_build2_loc (input_location, NE_EXPR,
7939 				     logical_type_node,
7940 				     classdata,
7941 				     fold_convert (TREE_TYPE (classdata),
7942 					   	    null_pointer_node));
7943 	      tmp = fold_build3_loc (input_location, COND_EXPR,
7944 				     void_type_node, tmp,
7945 				     gfc_call_free (classdata),
7946 				     build_empty_stmt (input_location));
7947 	      gfc_add_expr_to_block (&se->post, tmp);
7948 	    }
7949 	}
7950 
7951 no_finalization:
7952       gfc_add_block_to_block (&se->post, &post);
7953     }
7954 
7955   return has_alternate_specifier;
7956 }
7957 
7958 
7959 /* Fill a character string with spaces.  */
7960 
7961 static tree
fill_with_spaces(tree start,tree type,tree size)7962 fill_with_spaces (tree start, tree type, tree size)
7963 {
7964   stmtblock_t block, loop;
7965   tree i, el, exit_label, cond, tmp;
7966 
7967   /* For a simple char type, we can call memset().  */
7968   if (compare_tree_int (TYPE_SIZE_UNIT (type), 1) == 0)
7969     return build_call_expr_loc (input_location,
7970 			    builtin_decl_explicit (BUILT_IN_MEMSET),
7971 			    3, start,
7972 			    build_int_cst (gfc_get_int_type (gfc_c_int_kind),
7973 					   lang_hooks.to_target_charset (' ')),
7974 				fold_convert (size_type_node, size));
7975 
7976   /* Otherwise, we use a loop:
7977 	for (el = start, i = size; i > 0; el--, i+= TYPE_SIZE_UNIT (type))
7978 	  *el = (type) ' ';
7979    */
7980 
7981   /* Initialize variables.  */
7982   gfc_init_block (&block);
7983   i = gfc_create_var (sizetype, "i");
7984   gfc_add_modify (&block, i, fold_convert (sizetype, size));
7985   el = gfc_create_var (build_pointer_type (type), "el");
7986   gfc_add_modify (&block, el, fold_convert (TREE_TYPE (el), start));
7987   exit_label = gfc_build_label_decl (NULL_TREE);
7988   TREE_USED (exit_label) = 1;
7989 
7990 
7991   /* Loop body.  */
7992   gfc_init_block (&loop);
7993 
7994   /* Exit condition.  */
7995   cond = fold_build2_loc (input_location, LE_EXPR, logical_type_node, i,
7996 			  build_zero_cst (sizetype));
7997   tmp = build1_v (GOTO_EXPR, exit_label);
7998   tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond, tmp,
7999 			 build_empty_stmt (input_location));
8000   gfc_add_expr_to_block (&loop, tmp);
8001 
8002   /* Assignment.  */
8003   gfc_add_modify (&loop,
8004 		  fold_build1_loc (input_location, INDIRECT_REF, type, el),
8005 		  build_int_cst (type, lang_hooks.to_target_charset (' ')));
8006 
8007   /* Increment loop variables.  */
8008   gfc_add_modify (&loop, i,
8009 		  fold_build2_loc (input_location, MINUS_EXPR, sizetype, i,
8010 				   TYPE_SIZE_UNIT (type)));
8011   gfc_add_modify (&loop, el,
8012 		  fold_build_pointer_plus_loc (input_location,
8013 					       el, TYPE_SIZE_UNIT (type)));
8014 
8015   /* Making the loop... actually loop!  */
8016   tmp = gfc_finish_block (&loop);
8017   tmp = build1_v (LOOP_EXPR, tmp);
8018   gfc_add_expr_to_block (&block, tmp);
8019 
8020   /* The exit label.  */
8021   tmp = build1_v (LABEL_EXPR, exit_label);
8022   gfc_add_expr_to_block (&block, tmp);
8023 
8024 
8025   return gfc_finish_block (&block);
8026 }
8027 
8028 
8029 /* Generate code to copy a string.  */
8030 
8031 void
gfc_trans_string_copy(stmtblock_t * block,tree dlength,tree dest,int dkind,tree slength,tree src,int skind)8032 gfc_trans_string_copy (stmtblock_t * block, tree dlength, tree dest,
8033 		       int dkind, tree slength, tree src, int skind)
8034 {
8035   tree tmp, dlen, slen;
8036   tree dsc;
8037   tree ssc;
8038   tree cond;
8039   tree cond2;
8040   tree tmp2;
8041   tree tmp3;
8042   tree tmp4;
8043   tree chartype;
8044   stmtblock_t tempblock;
8045 
8046   gcc_assert (dkind == skind);
8047 
8048   if (slength != NULL_TREE)
8049     {
8050       slen = gfc_evaluate_now (fold_convert (gfc_charlen_type_node, slength), block);
8051       ssc = gfc_string_to_single_character (slen, src, skind);
8052     }
8053   else
8054     {
8055       slen = build_one_cst (gfc_charlen_type_node);
8056       ssc =  src;
8057     }
8058 
8059   if (dlength != NULL_TREE)
8060     {
8061       dlen = gfc_evaluate_now (fold_convert (gfc_charlen_type_node, dlength), block);
8062       dsc = gfc_string_to_single_character (dlen, dest, dkind);
8063     }
8064   else
8065     {
8066       dlen = build_one_cst (gfc_charlen_type_node);
8067       dsc =  dest;
8068     }
8069 
8070   /* Assign directly if the types are compatible.  */
8071   if (dsc != NULL_TREE && ssc != NULL_TREE
8072       && TREE_TYPE (dsc) == TREE_TYPE (ssc))
8073     {
8074       gfc_add_modify (block, dsc, ssc);
8075       return;
8076     }
8077 
8078   /* The string copy algorithm below generates code like
8079 
8080      if (destlen > 0)
8081        {
8082          if (srclen < destlen)
8083            {
8084              memmove (dest, src, srclen);
8085              // Pad with spaces.
8086              memset (&dest[srclen], ' ', destlen - srclen);
8087            }
8088          else
8089            {
8090              // Truncate if too long.
8091              memmove (dest, src, destlen);
8092            }
8093        }
8094   */
8095 
8096   /* Do nothing if the destination length is zero.  */
8097   cond = fold_build2_loc (input_location, GT_EXPR, logical_type_node, dlen,
8098 			  build_zero_cst (TREE_TYPE (dlen)));
8099 
8100   /* For non-default character kinds, we have to multiply the string
8101      length by the base type size.  */
8102   chartype = gfc_get_char_type (dkind);
8103   slen = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (slen),
8104 			  slen,
8105 			  fold_convert (TREE_TYPE (slen),
8106 					TYPE_SIZE_UNIT (chartype)));
8107   dlen = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (dlen),
8108 			  dlen,
8109 			  fold_convert (TREE_TYPE (dlen),
8110 					TYPE_SIZE_UNIT (chartype)));
8111 
8112   if (dlength && POINTER_TYPE_P (TREE_TYPE (dest)))
8113     dest = fold_convert (pvoid_type_node, dest);
8114   else
8115     dest = gfc_build_addr_expr (pvoid_type_node, dest);
8116 
8117   if (slength && POINTER_TYPE_P (TREE_TYPE (src)))
8118     src = fold_convert (pvoid_type_node, src);
8119   else
8120     src = gfc_build_addr_expr (pvoid_type_node, src);
8121 
8122   /* Truncate string if source is too long.  */
8123   cond2 = fold_build2_loc (input_location, LT_EXPR, logical_type_node, slen,
8124 			   dlen);
8125 
8126   /* Pre-evaluate pointers unless one of the IF arms will be optimized away.  */
8127   if (!CONSTANT_CLASS_P (cond2))
8128     {
8129       dest = gfc_evaluate_now (dest, block);
8130       src = gfc_evaluate_now (src, block);
8131     }
8132 
8133   /* Copy and pad with spaces.  */
8134   tmp3 = build_call_expr_loc (input_location,
8135 			      builtin_decl_explicit (BUILT_IN_MEMMOVE),
8136 			      3, dest, src,
8137 			      fold_convert (size_type_node, slen));
8138 
8139   /* Wstringop-overflow appears at -O3 even though this warning is not
8140      explicitly available in fortran nor can it be switched off. If the
8141      source length is a constant, its negative appears as a very large
8142      postive number and triggers the warning in BUILTIN_MEMSET. Fixing
8143      the result of the MINUS_EXPR suppresses this spurious warning.  */
8144   tmp = fold_build2_loc (input_location, MINUS_EXPR,
8145 			 TREE_TYPE(dlen), dlen, slen);
8146   if (slength && TREE_CONSTANT (slength))
8147     tmp = gfc_evaluate_now (tmp, block);
8148 
8149   tmp4 = fold_build_pointer_plus_loc (input_location, dest, slen);
8150   tmp4 = fill_with_spaces (tmp4, chartype, tmp);
8151 
8152   gfc_init_block (&tempblock);
8153   gfc_add_expr_to_block (&tempblock, tmp3);
8154   gfc_add_expr_to_block (&tempblock, tmp4);
8155   tmp3 = gfc_finish_block (&tempblock);
8156 
8157   /* The truncated memmove if the slen >= dlen.  */
8158   tmp2 = build_call_expr_loc (input_location,
8159 			      builtin_decl_explicit (BUILT_IN_MEMMOVE),
8160 			      3, dest, src,
8161 			      fold_convert (size_type_node, dlen));
8162 
8163   /* The whole copy_string function is there.  */
8164   tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond2,
8165 			 tmp3, tmp2);
8166   tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond, tmp,
8167 			 build_empty_stmt (input_location));
8168   gfc_add_expr_to_block (block, tmp);
8169 }
8170 
8171 
8172 /* Translate a statement function.
8173    The value of a statement function reference is obtained by evaluating the
8174    expression using the values of the actual arguments for the values of the
8175    corresponding dummy arguments.  */
8176 
8177 static void
gfc_conv_statement_function(gfc_se * se,gfc_expr * expr)8178 gfc_conv_statement_function (gfc_se * se, gfc_expr * expr)
8179 {
8180   gfc_symbol *sym;
8181   gfc_symbol *fsym;
8182   gfc_formal_arglist *fargs;
8183   gfc_actual_arglist *args;
8184   gfc_se lse;
8185   gfc_se rse;
8186   gfc_saved_var *saved_vars;
8187   tree *temp_vars;
8188   tree type;
8189   tree tmp;
8190   int n;
8191 
8192   sym = expr->symtree->n.sym;
8193   args = expr->value.function.actual;
8194   gfc_init_se (&lse, NULL);
8195   gfc_init_se (&rse, NULL);
8196 
8197   n = 0;
8198   for (fargs = gfc_sym_get_dummy_args (sym); fargs; fargs = fargs->next)
8199     n++;
8200   saved_vars = XCNEWVEC (gfc_saved_var, n);
8201   temp_vars = XCNEWVEC (tree, n);
8202 
8203   for (fargs = gfc_sym_get_dummy_args (sym), n = 0; fargs;
8204        fargs = fargs->next, n++)
8205     {
8206       /* Each dummy shall be specified, explicitly or implicitly, to be
8207          scalar.  */
8208       gcc_assert (fargs->sym->attr.dimension == 0);
8209       fsym = fargs->sym;
8210 
8211       if (fsym->ts.type == BT_CHARACTER)
8212         {
8213 	  /* Copy string arguments.  */
8214 	  tree arglen;
8215 
8216 	  gcc_assert (fsym->ts.u.cl && fsym->ts.u.cl->length
8217 		      && fsym->ts.u.cl->length->expr_type == EXPR_CONSTANT);
8218 
8219 	  /* Create a temporary to hold the value.  */
8220           if (fsym->ts.u.cl->backend_decl == NULL_TREE)
8221 	     fsym->ts.u.cl->backend_decl
8222 		= gfc_conv_constant_to_tree (fsym->ts.u.cl->length);
8223 
8224 	  type = gfc_get_character_type (fsym->ts.kind, fsym->ts.u.cl);
8225 	  temp_vars[n] = gfc_create_var (type, fsym->name);
8226 
8227 	  arglen = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
8228 
8229 	  gfc_conv_expr (&rse, args->expr);
8230 	  gfc_conv_string_parameter (&rse);
8231 	  gfc_add_block_to_block (&se->pre, &lse.pre);
8232 	  gfc_add_block_to_block (&se->pre, &rse.pre);
8233 
8234 	  gfc_trans_string_copy (&se->pre, arglen, temp_vars[n], fsym->ts.kind,
8235 				 rse.string_length, rse.expr, fsym->ts.kind);
8236 	  gfc_add_block_to_block (&se->pre, &lse.post);
8237 	  gfc_add_block_to_block (&se->pre, &rse.post);
8238         }
8239       else
8240         {
8241           /* For everything else, just evaluate the expression.  */
8242 
8243 	  /* Create a temporary to hold the value.  */
8244 	  type = gfc_typenode_for_spec (&fsym->ts);
8245 	  temp_vars[n] = gfc_create_var (type, fsym->name);
8246 
8247           gfc_conv_expr (&lse, args->expr);
8248 
8249           gfc_add_block_to_block (&se->pre, &lse.pre);
8250           gfc_add_modify (&se->pre, temp_vars[n], lse.expr);
8251           gfc_add_block_to_block (&se->pre, &lse.post);
8252         }
8253 
8254       args = args->next;
8255     }
8256 
8257   /* Use the temporary variables in place of the real ones.  */
8258   for (fargs = gfc_sym_get_dummy_args (sym), n = 0; fargs;
8259        fargs = fargs->next, n++)
8260     gfc_shadow_sym (fargs->sym, temp_vars[n], &saved_vars[n]);
8261 
8262   gfc_conv_expr (se, sym->value);
8263 
8264   if (sym->ts.type == BT_CHARACTER)
8265     {
8266       gfc_conv_const_charlen (sym->ts.u.cl);
8267 
8268       /* Force the expression to the correct length.  */
8269       if (!INTEGER_CST_P (se->string_length)
8270 	  || tree_int_cst_lt (se->string_length,
8271 			      sym->ts.u.cl->backend_decl))
8272 	{
8273 	  type = gfc_get_character_type (sym->ts.kind, sym->ts.u.cl);
8274 	  tmp = gfc_create_var (type, sym->name);
8275 	  tmp = gfc_build_addr_expr (build_pointer_type (type), tmp);
8276 	  gfc_trans_string_copy (&se->pre, sym->ts.u.cl->backend_decl, tmp,
8277 				 sym->ts.kind, se->string_length, se->expr,
8278 				 sym->ts.kind);
8279 	  se->expr = tmp;
8280 	}
8281       se->string_length = sym->ts.u.cl->backend_decl;
8282     }
8283 
8284   /* Restore the original variables.  */
8285   for (fargs = gfc_sym_get_dummy_args (sym), n = 0; fargs;
8286        fargs = fargs->next, n++)
8287     gfc_restore_sym (fargs->sym, &saved_vars[n]);
8288   free (temp_vars);
8289   free (saved_vars);
8290 }
8291 
8292 
8293 /* Translate a function expression.  */
8294 
8295 static void
gfc_conv_function_expr(gfc_se * se,gfc_expr * expr)8296 gfc_conv_function_expr (gfc_se * se, gfc_expr * expr)
8297 {
8298   gfc_symbol *sym;
8299 
8300   if (expr->value.function.isym)
8301     {
8302       gfc_conv_intrinsic_function (se, expr);
8303       return;
8304     }
8305 
8306   /* expr.value.function.esym is the resolved (specific) function symbol for
8307      most functions.  However this isn't set for dummy procedures.  */
8308   sym = expr->value.function.esym;
8309   if (!sym)
8310     sym = expr->symtree->n.sym;
8311 
8312   /* The IEEE_ARITHMETIC functions are caught here. */
8313   if (sym->from_intmod == INTMOD_IEEE_ARITHMETIC)
8314     if (gfc_conv_ieee_arithmetic_function (se, expr))
8315       return;
8316 
8317   /* We distinguish statement functions from general functions to improve
8318      runtime performance.  */
8319   if (sym->attr.proc == PROC_ST_FUNCTION)
8320     {
8321       gfc_conv_statement_function (se, expr);
8322       return;
8323     }
8324 
8325   gfc_conv_procedure_call (se, sym, expr->value.function.actual, expr,
8326 			   NULL);
8327 }
8328 
8329 
8330 /* Determine whether the given EXPR_CONSTANT is a zero initializer.  */
8331 
8332 static bool
is_zero_initializer_p(gfc_expr * expr)8333 is_zero_initializer_p (gfc_expr * expr)
8334 {
8335   if (expr->expr_type != EXPR_CONSTANT)
8336     return false;
8337 
8338   /* We ignore constants with prescribed memory representations for now.  */
8339   if (expr->representation.string)
8340     return false;
8341 
8342   switch (expr->ts.type)
8343     {
8344     case BT_INTEGER:
8345       return mpz_cmp_si (expr->value.integer, 0) == 0;
8346 
8347     case BT_REAL:
8348       return mpfr_zero_p (expr->value.real)
8349 	     && MPFR_SIGN (expr->value.real) >= 0;
8350 
8351     case BT_LOGICAL:
8352       return expr->value.logical == 0;
8353 
8354     case BT_COMPLEX:
8355       return mpfr_zero_p (mpc_realref (expr->value.complex))
8356 	     && MPFR_SIGN (mpc_realref (expr->value.complex)) >= 0
8357              && mpfr_zero_p (mpc_imagref (expr->value.complex))
8358 	     && MPFR_SIGN (mpc_imagref (expr->value.complex)) >= 0;
8359 
8360     default:
8361       break;
8362     }
8363   return false;
8364 }
8365 
8366 
8367 static void
gfc_conv_array_constructor_expr(gfc_se * se,gfc_expr * expr)8368 gfc_conv_array_constructor_expr (gfc_se * se, gfc_expr * expr)
8369 {
8370   gfc_ss *ss;
8371 
8372   ss = se->ss;
8373   gcc_assert (ss != NULL && ss != gfc_ss_terminator);
8374   gcc_assert (ss->info->expr == expr && ss->info->type == GFC_SS_CONSTRUCTOR);
8375 
8376   gfc_conv_tmp_array_ref (se);
8377 }
8378 
8379 
8380 /* Build a static initializer.  EXPR is the expression for the initial value.
8381    The other parameters describe the variable of the component being
8382    initialized. EXPR may be null.  */
8383 
8384 tree
gfc_conv_initializer(gfc_expr * expr,gfc_typespec * ts,tree type,bool array,bool pointer,bool procptr)8385 gfc_conv_initializer (gfc_expr * expr, gfc_typespec * ts, tree type,
8386 		      bool array, bool pointer, bool procptr)
8387 {
8388   gfc_se se;
8389 
8390   if (flag_coarray != GFC_FCOARRAY_LIB && ts->type == BT_DERIVED
8391       && ts->u.derived->from_intmod == INTMOD_ISO_FORTRAN_ENV
8392       && ts->u.derived->intmod_sym_id == ISOFORTRAN_EVENT_TYPE)
8393     return build_constructor (type, NULL);
8394 
8395   if (!(expr || pointer || procptr))
8396     return NULL_TREE;
8397 
8398   /* Check if we have ISOCBINDING_NULL_PTR or ISOCBINDING_NULL_FUNPTR
8399      (these are the only two iso_c_binding derived types that can be
8400      used as initialization expressions).  If so, we need to modify
8401      the 'expr' to be that for a (void *).  */
8402   if (expr != NULL && expr->ts.type == BT_DERIVED
8403       && expr->ts.is_iso_c && expr->ts.u.derived)
8404     {
8405       if (TREE_CODE (type) == ARRAY_TYPE)
8406 	return build_constructor (type, NULL);
8407       else if (POINTER_TYPE_P (type))
8408 	return build_int_cst (type, 0);
8409       else
8410 	gcc_unreachable ();
8411     }
8412 
8413   if (array && !procptr)
8414     {
8415       tree ctor;
8416       /* Arrays need special handling.  */
8417       if (pointer)
8418 	ctor = gfc_build_null_descriptor (type);
8419       /* Special case assigning an array to zero.  */
8420       else if (is_zero_initializer_p (expr))
8421         ctor = build_constructor (type, NULL);
8422       else
8423 	ctor = gfc_conv_array_initializer (type, expr);
8424       TREE_STATIC (ctor) = 1;
8425       return ctor;
8426     }
8427   else if (pointer || procptr)
8428     {
8429       if (ts->type == BT_CLASS && !procptr)
8430 	{
8431 	  gfc_init_se (&se, NULL);
8432 	  gfc_conv_structure (&se, gfc_class_initializer (ts, expr), 1);
8433 	  gcc_assert (TREE_CODE (se.expr) == CONSTRUCTOR);
8434 	  TREE_STATIC (se.expr) = 1;
8435 	  return se.expr;
8436 	}
8437       else if (!expr || expr->expr_type == EXPR_NULL)
8438 	return fold_convert (type, null_pointer_node);
8439       else
8440 	{
8441 	  gfc_init_se (&se, NULL);
8442 	  se.want_pointer = 1;
8443 	  gfc_conv_expr (&se, expr);
8444           gcc_assert (TREE_CODE (se.expr) != CONSTRUCTOR);
8445 	  return se.expr;
8446 	}
8447     }
8448   else
8449     {
8450       switch (ts->type)
8451 	{
8452 	case_bt_struct:
8453 	case BT_CLASS:
8454 	  gfc_init_se (&se, NULL);
8455 	  if (ts->type == BT_CLASS && expr->expr_type == EXPR_NULL)
8456 	    gfc_conv_structure (&se, gfc_class_initializer (ts, expr), 1);
8457 	  else
8458 	    gfc_conv_structure (&se, expr, 1);
8459 	  gcc_assert (TREE_CODE (se.expr) == CONSTRUCTOR);
8460 	  TREE_STATIC (se.expr) = 1;
8461 	  return se.expr;
8462 
8463 	case BT_CHARACTER:
8464 	  if (expr->expr_type == EXPR_CONSTANT)
8465 	    {
8466 	      tree ctor = gfc_conv_string_init (ts->u.cl->backend_decl, expr);
8467 	      TREE_STATIC (ctor) = 1;
8468 	      return ctor;
8469 	    }
8470 
8471 	  /* Fallthrough.  */
8472 	default:
8473 	  gfc_init_se (&se, NULL);
8474 	  gfc_conv_constant (&se, expr);
8475 	  gcc_assert (TREE_CODE (se.expr) != CONSTRUCTOR);
8476 	  return se.expr;
8477 	}
8478     }
8479 }
8480 
8481 static tree
gfc_trans_subarray_assign(tree dest,gfc_component * cm,gfc_expr * expr)8482 gfc_trans_subarray_assign (tree dest, gfc_component * cm, gfc_expr * expr)
8483 {
8484   gfc_se rse;
8485   gfc_se lse;
8486   gfc_ss *rss;
8487   gfc_ss *lss;
8488   gfc_array_info *lss_array;
8489   stmtblock_t body;
8490   stmtblock_t block;
8491   gfc_loopinfo loop;
8492   int n;
8493   tree tmp;
8494 
8495   gfc_start_block (&block);
8496 
8497   /* Initialize the scalarizer.  */
8498   gfc_init_loopinfo (&loop);
8499 
8500   gfc_init_se (&lse, NULL);
8501   gfc_init_se (&rse, NULL);
8502 
8503   /* Walk the rhs.  */
8504   rss = gfc_walk_expr (expr);
8505   if (rss == gfc_ss_terminator)
8506     /* The rhs is scalar.  Add a ss for the expression.  */
8507     rss = gfc_get_scalar_ss (gfc_ss_terminator, expr);
8508 
8509   /* Create a SS for the destination.  */
8510   lss = gfc_get_array_ss (gfc_ss_terminator, NULL, cm->as->rank,
8511 			  GFC_SS_COMPONENT);
8512   lss_array = &lss->info->data.array;
8513   lss_array->shape = gfc_get_shape (cm->as->rank);
8514   lss_array->descriptor = dest;
8515   lss_array->data = gfc_conv_array_data (dest);
8516   lss_array->offset = gfc_conv_array_offset (dest);
8517   for (n = 0; n < cm->as->rank; n++)
8518     {
8519       lss_array->start[n] = gfc_conv_array_lbound (dest, n);
8520       lss_array->stride[n] = gfc_index_one_node;
8521 
8522       mpz_init (lss_array->shape[n]);
8523       mpz_sub (lss_array->shape[n], cm->as->upper[n]->value.integer,
8524 	       cm->as->lower[n]->value.integer);
8525       mpz_add_ui (lss_array->shape[n], lss_array->shape[n], 1);
8526     }
8527 
8528   /* Associate the SS with the loop.  */
8529   gfc_add_ss_to_loop (&loop, lss);
8530   gfc_add_ss_to_loop (&loop, rss);
8531 
8532   /* Calculate the bounds of the scalarization.  */
8533   gfc_conv_ss_startstride (&loop);
8534 
8535   /* Setup the scalarizing loops.  */
8536   gfc_conv_loop_setup (&loop, &expr->where);
8537 
8538   /* Setup the gfc_se structures.  */
8539   gfc_copy_loopinfo_to_se (&lse, &loop);
8540   gfc_copy_loopinfo_to_se (&rse, &loop);
8541 
8542   rse.ss = rss;
8543   gfc_mark_ss_chain_used (rss, 1);
8544   lse.ss = lss;
8545   gfc_mark_ss_chain_used (lss, 1);
8546 
8547   /* Start the scalarized loop body.  */
8548   gfc_start_scalarized_body (&loop, &body);
8549 
8550   gfc_conv_tmp_array_ref (&lse);
8551   if (cm->ts.type == BT_CHARACTER)
8552     lse.string_length = cm->ts.u.cl->backend_decl;
8553 
8554   gfc_conv_expr (&rse, expr);
8555 
8556   tmp = gfc_trans_scalar_assign (&lse, &rse, cm->ts, true, false);
8557   gfc_add_expr_to_block (&body, tmp);
8558 
8559   gcc_assert (rse.ss == gfc_ss_terminator);
8560 
8561   /* Generate the copying loops.  */
8562   gfc_trans_scalarizing_loops (&loop, &body);
8563 
8564   /* Wrap the whole thing up.  */
8565   gfc_add_block_to_block (&block, &loop.pre);
8566   gfc_add_block_to_block (&block, &loop.post);
8567 
8568   gcc_assert (lss_array->shape != NULL);
8569   gfc_free_shape (&lss_array->shape, cm->as->rank);
8570   gfc_cleanup_loop (&loop);
8571 
8572   return gfc_finish_block (&block);
8573 }
8574 
8575 
8576 static tree
gfc_trans_alloc_subarray_assign(tree dest,gfc_component * cm,gfc_expr * expr)8577 gfc_trans_alloc_subarray_assign (tree dest, gfc_component * cm,
8578 				 gfc_expr * expr)
8579 {
8580   gfc_se se;
8581   stmtblock_t block;
8582   tree offset;
8583   int n;
8584   tree tmp;
8585   tree tmp2;
8586   gfc_array_spec *as;
8587   gfc_expr *arg = NULL;
8588 
8589   gfc_start_block (&block);
8590   gfc_init_se (&se, NULL);
8591 
8592   /* Get the descriptor for the expressions.  */
8593   se.want_pointer = 0;
8594   gfc_conv_expr_descriptor (&se, expr);
8595   gfc_add_block_to_block (&block, &se.pre);
8596   gfc_add_modify (&block, dest, se.expr);
8597 
8598   /* Deal with arrays of derived types with allocatable components.  */
8599   if (gfc_bt_struct (cm->ts.type)
8600 	&& cm->ts.u.derived->attr.alloc_comp)
8601     // TODO: Fix caf_mode
8602     tmp = gfc_copy_alloc_comp (cm->ts.u.derived,
8603 			       se.expr, dest,
8604 			       cm->as->rank, 0);
8605   else if (cm->ts.type == BT_CLASS && expr->ts.type == BT_DERIVED
8606 	   && CLASS_DATA(cm)->attr.allocatable)
8607     {
8608       if (cm->ts.u.derived->attr.alloc_comp)
8609 	// TODO: Fix caf_mode
8610 	tmp = gfc_copy_alloc_comp (expr->ts.u.derived,
8611 				   se.expr, dest,
8612 				   expr->rank, 0);
8613       else
8614 	{
8615 	  tmp = TREE_TYPE (dest);
8616 	  tmp = gfc_duplicate_allocatable (dest, se.expr,
8617 					   tmp, expr->rank, NULL_TREE);
8618 	}
8619     }
8620   else
8621     tmp = gfc_duplicate_allocatable (dest, se.expr,
8622 				     TREE_TYPE(cm->backend_decl),
8623 				     cm->as->rank, NULL_TREE);
8624 
8625   gfc_add_expr_to_block (&block, tmp);
8626   gfc_add_block_to_block (&block, &se.post);
8627 
8628   if (expr->expr_type != EXPR_VARIABLE)
8629     gfc_conv_descriptor_data_set (&block, se.expr,
8630 				  null_pointer_node);
8631 
8632   /* We need to know if the argument of a conversion function is a
8633      variable, so that the correct lower bound can be used.  */
8634   if (expr->expr_type == EXPR_FUNCTION
8635 	&& expr->value.function.isym
8636 	&& expr->value.function.isym->conversion
8637 	&& expr->value.function.actual->expr
8638 	&& expr->value.function.actual->expr->expr_type == EXPR_VARIABLE)
8639     arg = expr->value.function.actual->expr;
8640 
8641   /* Obtain the array spec of full array references.  */
8642   if (arg)
8643     as = gfc_get_full_arrayspec_from_expr (arg);
8644   else
8645     as = gfc_get_full_arrayspec_from_expr (expr);
8646 
8647   /* Shift the lbound and ubound of temporaries to being unity,
8648      rather than zero, based. Always calculate the offset.  */
8649   offset = gfc_conv_descriptor_offset_get (dest);
8650   gfc_add_modify (&block, offset, gfc_index_zero_node);
8651   tmp2 =gfc_create_var (gfc_array_index_type, NULL);
8652 
8653   for (n = 0; n < expr->rank; n++)
8654     {
8655       tree span;
8656       tree lbound;
8657 
8658       /* Obtain the correct lbound - ISO/IEC TR 15581:2001 page 9.
8659 	 TODO It looks as if gfc_conv_expr_descriptor should return
8660 	 the correct bounds and that the following should not be
8661 	 necessary.  This would simplify gfc_conv_intrinsic_bound
8662 	 as well.  */
8663       if (as && as->lower[n])
8664 	{
8665 	  gfc_se lbse;
8666 	  gfc_init_se (&lbse, NULL);
8667 	  gfc_conv_expr (&lbse, as->lower[n]);
8668 	  gfc_add_block_to_block (&block, &lbse.pre);
8669 	  lbound = gfc_evaluate_now (lbse.expr, &block);
8670 	}
8671       else if (as && arg)
8672 	{
8673 	  tmp = gfc_get_symbol_decl (arg->symtree->n.sym);
8674 	  lbound = gfc_conv_descriptor_lbound_get (tmp,
8675 					gfc_rank_cst[n]);
8676 	}
8677       else if (as)
8678 	lbound = gfc_conv_descriptor_lbound_get (dest,
8679 						gfc_rank_cst[n]);
8680       else
8681 	lbound = gfc_index_one_node;
8682 
8683       lbound = fold_convert (gfc_array_index_type, lbound);
8684 
8685       /* Shift the bounds and set the offset accordingly.  */
8686       tmp = gfc_conv_descriptor_ubound_get (dest, gfc_rank_cst[n]);
8687       span = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
8688 		tmp, gfc_conv_descriptor_lbound_get (dest, gfc_rank_cst[n]));
8689       tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
8690 			     span, lbound);
8691       gfc_conv_descriptor_ubound_set (&block, dest,
8692 				      gfc_rank_cst[n], tmp);
8693       gfc_conv_descriptor_lbound_set (&block, dest,
8694 				      gfc_rank_cst[n], lbound);
8695 
8696       tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
8697 			 gfc_conv_descriptor_lbound_get (dest,
8698 							 gfc_rank_cst[n]),
8699 			 gfc_conv_descriptor_stride_get (dest,
8700 							 gfc_rank_cst[n]));
8701       gfc_add_modify (&block, tmp2, tmp);
8702       tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
8703 			     offset, tmp2);
8704       gfc_conv_descriptor_offset_set (&block, dest, tmp);
8705     }
8706 
8707   if (arg)
8708     {
8709       /* If a conversion expression has a null data pointer
8710 	 argument, nullify the allocatable component.  */
8711       tree non_null_expr;
8712       tree null_expr;
8713 
8714       if (arg->symtree->n.sym->attr.allocatable
8715 	    || arg->symtree->n.sym->attr.pointer)
8716 	{
8717 	  non_null_expr = gfc_finish_block (&block);
8718 	  gfc_start_block (&block);
8719 	  gfc_conv_descriptor_data_set (&block, dest,
8720 					null_pointer_node);
8721 	  null_expr = gfc_finish_block (&block);
8722 	  tmp = gfc_conv_descriptor_data_get (arg->symtree->n.sym->backend_decl);
8723 	  tmp = build2_loc (input_location, EQ_EXPR, logical_type_node, tmp,
8724 			    fold_convert (TREE_TYPE (tmp), null_pointer_node));
8725 	  return build3_v (COND_EXPR, tmp,
8726 			   null_expr, non_null_expr);
8727 	}
8728     }
8729 
8730   return gfc_finish_block (&block);
8731 }
8732 
8733 
8734 /* Allocate or reallocate scalar component, as necessary.  */
8735 
8736 static void
alloc_scalar_allocatable_for_subcomponent_assignment(stmtblock_t * block,tree comp,gfc_component * cm,gfc_expr * expr2,gfc_symbol * sym)8737 alloc_scalar_allocatable_for_subcomponent_assignment (stmtblock_t *block,
8738 						      tree comp,
8739 						      gfc_component *cm,
8740 						      gfc_expr *expr2,
8741 						      gfc_symbol *sym)
8742 {
8743   tree tmp;
8744   tree ptr;
8745   tree size;
8746   tree size_in_bytes;
8747   tree lhs_cl_size = NULL_TREE;
8748 
8749   if (!comp)
8750     return;
8751 
8752   if (!expr2 || expr2->rank)
8753     return;
8754 
8755   realloc_lhs_warning (expr2->ts.type, false, &expr2->where);
8756 
8757   if (cm->ts.type == BT_CHARACTER && cm->ts.deferred)
8758     {
8759       char name[GFC_MAX_SYMBOL_LEN+9];
8760       gfc_component *strlen;
8761       /* Use the rhs string length and the lhs element size.  */
8762       gcc_assert (expr2->ts.type == BT_CHARACTER);
8763       if (!expr2->ts.u.cl->backend_decl)
8764 	{
8765 	  gfc_conv_string_length (expr2->ts.u.cl, expr2, block);
8766 	  gcc_assert (expr2->ts.u.cl->backend_decl);
8767 	}
8768 
8769       size = expr2->ts.u.cl->backend_decl;
8770 
8771       /* Ensure that cm->ts.u.cl->backend_decl is a componentref to _%s_length
8772 	 component.  */
8773       sprintf (name, "_%s_length", cm->name);
8774       strlen = gfc_find_component (sym, name, true, true, NULL);
8775       lhs_cl_size = fold_build3_loc (input_location, COMPONENT_REF,
8776 				     gfc_charlen_type_node,
8777 				     TREE_OPERAND (comp, 0),
8778 				     strlen->backend_decl, NULL_TREE);
8779 
8780       tmp = TREE_TYPE (gfc_typenode_for_spec (&cm->ts));
8781       tmp = TYPE_SIZE_UNIT (tmp);
8782       size_in_bytes = fold_build2_loc (input_location, MULT_EXPR,
8783 				       TREE_TYPE (tmp), tmp,
8784 				       fold_convert (TREE_TYPE (tmp), size));
8785     }
8786   else if (cm->ts.type == BT_CLASS)
8787     {
8788       gcc_assert (expr2->ts.type == BT_CLASS || expr2->ts.type == BT_DERIVED);
8789       if (expr2->ts.type == BT_DERIVED)
8790 	{
8791 	  tmp = gfc_get_symbol_decl (expr2->ts.u.derived);
8792 	  size = TYPE_SIZE_UNIT (tmp);
8793 	}
8794       else
8795 	{
8796 	  gfc_expr *e2vtab;
8797 	  gfc_se se;
8798 	  e2vtab = gfc_find_and_cut_at_last_class_ref (expr2);
8799 	  gfc_add_vptr_component (e2vtab);
8800 	  gfc_add_size_component (e2vtab);
8801 	  gfc_init_se (&se, NULL);
8802 	  gfc_conv_expr (&se, e2vtab);
8803 	  gfc_add_block_to_block (block, &se.pre);
8804 	  size = fold_convert (size_type_node, se.expr);
8805 	  gfc_free_expr (e2vtab);
8806 	}
8807       size_in_bytes = size;
8808     }
8809   else
8810     {
8811       /* Otherwise use the length in bytes of the rhs.  */
8812       size = TYPE_SIZE_UNIT (gfc_typenode_for_spec (&cm->ts));
8813       size_in_bytes = size;
8814     }
8815 
8816   size_in_bytes = fold_build2_loc (input_location, MAX_EXPR, size_type_node,
8817 				   size_in_bytes, size_one_node);
8818 
8819   if (cm->ts.type == BT_DERIVED && cm->ts.u.derived->attr.alloc_comp)
8820     {
8821       tmp = build_call_expr_loc (input_location,
8822 				 builtin_decl_explicit (BUILT_IN_CALLOC),
8823 				 2, build_one_cst (size_type_node),
8824 				 size_in_bytes);
8825       tmp = fold_convert (TREE_TYPE (comp), tmp);
8826       gfc_add_modify (block, comp, tmp);
8827     }
8828   else
8829     {
8830       tmp = build_call_expr_loc (input_location,
8831 				 builtin_decl_explicit (BUILT_IN_MALLOC),
8832 				 1, size_in_bytes);
8833       if (GFC_CLASS_TYPE_P (TREE_TYPE (comp)))
8834 	ptr = gfc_class_data_get (comp);
8835       else
8836 	ptr = comp;
8837       tmp = fold_convert (TREE_TYPE (ptr), tmp);
8838       gfc_add_modify (block, ptr, tmp);
8839     }
8840 
8841   if (cm->ts.type == BT_CHARACTER && cm->ts.deferred)
8842     /* Update the lhs character length.  */
8843     gfc_add_modify (block, lhs_cl_size,
8844 		    fold_convert (TREE_TYPE (lhs_cl_size), size));
8845 }
8846 
8847 
8848 /* Assign a single component of a derived type constructor.  */
8849 
8850 static tree
gfc_trans_subcomponent_assign(tree dest,gfc_component * cm,gfc_expr * expr,gfc_symbol * sym,bool init)8851 gfc_trans_subcomponent_assign (tree dest, gfc_component * cm, gfc_expr * expr,
8852 			       gfc_symbol *sym, bool init)
8853 {
8854   gfc_se se;
8855   gfc_se lse;
8856   stmtblock_t block;
8857   tree tmp;
8858   tree vtab;
8859 
8860   gfc_start_block (&block);
8861 
8862   if (cm->attr.pointer || cm->attr.proc_pointer)
8863     {
8864       /* Only care about pointers here, not about allocatables.  */
8865       gfc_init_se (&se, NULL);
8866       /* Pointer component.  */
8867       if ((cm->attr.dimension || cm->attr.codimension)
8868 	  && !cm->attr.proc_pointer)
8869 	{
8870 	  /* Array pointer.  */
8871 	  if (expr->expr_type == EXPR_NULL)
8872 	    gfc_conv_descriptor_data_set (&block, dest, null_pointer_node);
8873 	  else
8874 	    {
8875 	      se.direct_byref = 1;
8876 	      se.expr = dest;
8877 	      gfc_conv_expr_descriptor (&se, expr);
8878 	      gfc_add_block_to_block (&block, &se.pre);
8879 	      gfc_add_block_to_block (&block, &se.post);
8880 	    }
8881 	}
8882       else
8883 	{
8884 	  /* Scalar pointers.  */
8885 	  se.want_pointer = 1;
8886 	  gfc_conv_expr (&se, expr);
8887 	  gfc_add_block_to_block (&block, &se.pre);
8888 
8889 	  if (expr->symtree && expr->symtree->n.sym->attr.proc_pointer
8890 	      && expr->symtree->n.sym->attr.dummy)
8891 	    se.expr = build_fold_indirect_ref_loc (input_location, se.expr);
8892 
8893 	  gfc_add_modify (&block, dest,
8894 			       fold_convert (TREE_TYPE (dest), se.expr));
8895 	  gfc_add_block_to_block (&block, &se.post);
8896 	}
8897     }
8898   else if (cm->ts.type == BT_CLASS && expr->expr_type == EXPR_NULL)
8899     {
8900       /* NULL initialization for CLASS components.  */
8901       tmp = gfc_trans_structure_assign (dest,
8902 					gfc_class_initializer (&cm->ts, expr),
8903 					false);
8904       gfc_add_expr_to_block (&block, tmp);
8905     }
8906   else if ((cm->attr.dimension || cm->attr.codimension)
8907 	   && !cm->attr.proc_pointer)
8908     {
8909       if (cm->attr.allocatable && expr->expr_type == EXPR_NULL)
8910  	gfc_conv_descriptor_data_set (&block, dest, null_pointer_node);
8911       else if (cm->attr.allocatable || cm->attr.pdt_array)
8912 	{
8913 	  tmp = gfc_trans_alloc_subarray_assign (dest, cm, expr);
8914 	  gfc_add_expr_to_block (&block, tmp);
8915 	}
8916       else
8917 	{
8918 	  tmp = gfc_trans_subarray_assign (dest, cm, expr);
8919 	  gfc_add_expr_to_block (&block, tmp);
8920 	}
8921     }
8922   else if (cm->ts.type == BT_CLASS
8923 	   && CLASS_DATA (cm)->attr.dimension
8924 	   && CLASS_DATA (cm)->attr.allocatable
8925 	   && expr->ts.type == BT_DERIVED)
8926     {
8927       vtab = gfc_get_symbol_decl (gfc_find_vtab (&expr->ts));
8928       vtab = gfc_build_addr_expr (NULL_TREE, vtab);
8929       tmp = gfc_class_vptr_get (dest);
8930       gfc_add_modify (&block, tmp,
8931 		      fold_convert (TREE_TYPE (tmp), vtab));
8932       tmp = gfc_class_data_get (dest);
8933       tmp = gfc_trans_alloc_subarray_assign (tmp, cm, expr);
8934       gfc_add_expr_to_block (&block, tmp);
8935     }
8936   else if (init && cm->attr.allocatable && expr->expr_type == EXPR_NULL)
8937     {
8938       /* NULL initialization for allocatable components.  */
8939       gfc_add_modify (&block, dest, fold_convert (TREE_TYPE (dest),
8940 						  null_pointer_node));
8941     }
8942   else if (init && (cm->attr.allocatable
8943 	   || (cm->ts.type == BT_CLASS && CLASS_DATA (cm)->attr.allocatable
8944 	       && expr->ts.type != BT_CLASS)))
8945     {
8946       /* Take care about non-array allocatable components here.  The alloc_*
8947 	 routine below is motivated by the alloc_scalar_allocatable_for_
8948 	 assignment() routine, but with the realloc portions removed and
8949 	 different input.  */
8950       alloc_scalar_allocatable_for_subcomponent_assignment (&block,
8951 							    dest,
8952 							    cm,
8953 							    expr,
8954 							    sym);
8955       /* The remainder of these instructions follow the if (cm->attr.pointer)
8956 	 if (!cm->attr.dimension) part above.  */
8957       gfc_init_se (&se, NULL);
8958       gfc_conv_expr (&se, expr);
8959       gfc_add_block_to_block (&block, &se.pre);
8960 
8961       if (expr->symtree && expr->symtree->n.sym->attr.proc_pointer
8962 	  && expr->symtree->n.sym->attr.dummy)
8963 	se.expr = build_fold_indirect_ref_loc (input_location, se.expr);
8964 
8965       if (cm->ts.type == BT_CLASS && expr->ts.type == BT_DERIVED)
8966 	{
8967 	  tmp = gfc_class_data_get (dest);
8968 	  tmp = build_fold_indirect_ref_loc (input_location, tmp);
8969 	  vtab = gfc_get_symbol_decl (gfc_find_vtab (&expr->ts));
8970 	  vtab = gfc_build_addr_expr (NULL_TREE, vtab);
8971 	  gfc_add_modify (&block, gfc_class_vptr_get (dest),
8972 		 fold_convert (TREE_TYPE (gfc_class_vptr_get (dest)), vtab));
8973 	}
8974       else
8975 	tmp = build_fold_indirect_ref_loc (input_location, dest);
8976 
8977       /* For deferred strings insert a memcpy.  */
8978       if (cm->ts.type == BT_CHARACTER && cm->ts.deferred)
8979 	{
8980 	  tree size;
8981 	  gcc_assert (se.string_length || expr->ts.u.cl->backend_decl);
8982 	  size = size_of_string_in_bytes (cm->ts.kind, se.string_length
8983 						? se.string_length
8984 						: expr->ts.u.cl->backend_decl);
8985 	  tmp = gfc_build_memcpy_call (tmp, se.expr, size);
8986 	  gfc_add_expr_to_block (&block, tmp);
8987 	}
8988       else
8989 	gfc_add_modify (&block, tmp,
8990 			fold_convert (TREE_TYPE (tmp), se.expr));
8991       gfc_add_block_to_block (&block, &se.post);
8992     }
8993   else if (expr->ts.type == BT_UNION)
8994     {
8995       tree tmp;
8996       gfc_constructor *c = gfc_constructor_first (expr->value.constructor);
8997       /* We mark that the entire union should be initialized with a contrived
8998          EXPR_NULL expression at the beginning.  */
8999       if (c != NULL && c->n.component == NULL
9000 	  && c->expr != NULL && c->expr->expr_type == EXPR_NULL)
9001         {
9002           tmp = build2_loc (input_location, MODIFY_EXPR, void_type_node,
9003 		            dest, build_constructor (TREE_TYPE (dest), NULL));
9004 	  gfc_add_expr_to_block (&block, tmp);
9005           c = gfc_constructor_next (c);
9006         }
9007       /* The following constructor expression, if any, represents a specific
9008          map intializer, as given by the user.  */
9009       if (c != NULL && c->expr != NULL)
9010         {
9011           gcc_assert (expr->expr_type == EXPR_STRUCTURE);
9012 	  tmp = gfc_trans_structure_assign (dest, expr, expr->symtree != NULL);
9013 	  gfc_add_expr_to_block (&block, tmp);
9014         }
9015     }
9016   else if (expr->ts.type == BT_DERIVED && expr->ts.f90_type != BT_VOID)
9017     {
9018       if (expr->expr_type != EXPR_STRUCTURE)
9019 	{
9020 	  tree dealloc = NULL_TREE;
9021 	  gfc_init_se (&se, NULL);
9022 	  gfc_conv_expr (&se, expr);
9023 	  gfc_add_block_to_block (&block, &se.pre);
9024 	  /* Prevent repeat evaluations in gfc_copy_alloc_comp by fixing the
9025 	     expression in  a temporary variable and deallocate the allocatable
9026 	     components. Then we can the copy the expression to the result.  */
9027 	  if (cm->ts.u.derived->attr.alloc_comp
9028 	      && expr->expr_type != EXPR_VARIABLE)
9029 	    {
9030 	      se.expr = gfc_evaluate_now (se.expr, &block);
9031 	      dealloc = gfc_deallocate_alloc_comp (cm->ts.u.derived, se.expr,
9032 						   expr->rank);
9033 	    }
9034 	  gfc_add_modify (&block, dest,
9035 			  fold_convert (TREE_TYPE (dest), se.expr));
9036 	  if (cm->ts.u.derived->attr.alloc_comp
9037 	      && expr->expr_type != EXPR_NULL)
9038 	    {
9039 	      // TODO: Fix caf_mode
9040 	      tmp = gfc_copy_alloc_comp (cm->ts.u.derived, se.expr,
9041 					 dest, expr->rank, 0);
9042 	      gfc_add_expr_to_block (&block, tmp);
9043 	      if (dealloc != NULL_TREE)
9044 		gfc_add_expr_to_block (&block, dealloc);
9045 	    }
9046 	  gfc_add_block_to_block (&block, &se.post);
9047 	}
9048       else
9049 	{
9050 	  /* Nested constructors.  */
9051 	  tmp = gfc_trans_structure_assign (dest, expr, expr->symtree != NULL);
9052 	  gfc_add_expr_to_block (&block, tmp);
9053 	}
9054     }
9055   else if (gfc_deferred_strlen (cm, &tmp))
9056     {
9057       tree strlen;
9058       strlen = tmp;
9059       gcc_assert (strlen);
9060       strlen = fold_build3_loc (input_location, COMPONENT_REF,
9061 				TREE_TYPE (strlen),
9062 				TREE_OPERAND (dest, 0),
9063 				strlen, NULL_TREE);
9064 
9065       if (expr->expr_type == EXPR_NULL)
9066 	{
9067 	  tmp = build_int_cst (TREE_TYPE (cm->backend_decl), 0);
9068 	  gfc_add_modify (&block, dest, tmp);
9069 	  tmp = build_int_cst (TREE_TYPE (strlen), 0);
9070 	  gfc_add_modify (&block, strlen, tmp);
9071 	}
9072       else
9073 	{
9074 	  tree size;
9075 	  gfc_init_se (&se, NULL);
9076 	  gfc_conv_expr (&se, expr);
9077 	  size = size_of_string_in_bytes (cm->ts.kind, se.string_length);
9078 	  tmp = build_call_expr_loc (input_location,
9079 				     builtin_decl_explicit (BUILT_IN_MALLOC),
9080 				     1, size);
9081 	  gfc_add_modify (&block, dest,
9082 			  fold_convert (TREE_TYPE (dest), tmp));
9083 	  gfc_add_modify (&block, strlen,
9084 			  fold_convert (TREE_TYPE (strlen), se.string_length));
9085 	  tmp = gfc_build_memcpy_call (dest, se.expr, size);
9086 	  gfc_add_expr_to_block (&block, tmp);
9087 	}
9088     }
9089   else if (!cm->attr.artificial)
9090     {
9091       /* Scalar component (excluding deferred parameters).  */
9092       gfc_init_se (&se, NULL);
9093       gfc_init_se (&lse, NULL);
9094 
9095       gfc_conv_expr (&se, expr);
9096       if (cm->ts.type == BT_CHARACTER)
9097 	lse.string_length = cm->ts.u.cl->backend_decl;
9098       lse.expr = dest;
9099       tmp = gfc_trans_scalar_assign (&lse, &se, cm->ts, false, false);
9100       gfc_add_expr_to_block (&block, tmp);
9101     }
9102   return gfc_finish_block (&block);
9103 }
9104 
9105 /* Assign a derived type constructor to a variable.  */
9106 
9107 tree
gfc_trans_structure_assign(tree dest,gfc_expr * expr,bool init,bool coarray)9108 gfc_trans_structure_assign (tree dest, gfc_expr * expr, bool init, bool coarray)
9109 {
9110   gfc_constructor *c;
9111   gfc_component *cm;
9112   stmtblock_t block;
9113   tree field;
9114   tree tmp;
9115   gfc_se se;
9116 
9117   gfc_start_block (&block);
9118 
9119   if (expr->ts.u.derived->from_intmod == INTMOD_ISO_C_BINDING
9120       && (expr->ts.u.derived->intmod_sym_id == ISOCBINDING_PTR
9121           || expr->ts.u.derived->intmod_sym_id == ISOCBINDING_FUNPTR))
9122     {
9123       gfc_se lse;
9124 
9125       gfc_init_se (&se, NULL);
9126       gfc_init_se (&lse, NULL);
9127       gfc_conv_expr (&se, gfc_constructor_first (expr->value.constructor)->expr);
9128       lse.expr = dest;
9129       gfc_add_modify (&block, lse.expr,
9130 		      fold_convert (TREE_TYPE (lse.expr), se.expr));
9131 
9132       return gfc_finish_block (&block);
9133     }
9134 
9135   /* Make sure that the derived type has been completely built.  */
9136   if (!expr->ts.u.derived->backend_decl
9137       || !TYPE_FIELDS (expr->ts.u.derived->backend_decl))
9138     {
9139       tmp = gfc_typenode_for_spec (&expr->ts);
9140       gcc_assert (tmp);
9141     }
9142 
9143   cm = expr->ts.u.derived->components;
9144 
9145 
9146   if (coarray)
9147     gfc_init_se (&se, NULL);
9148 
9149   for (c = gfc_constructor_first (expr->value.constructor);
9150        c; c = gfc_constructor_next (c), cm = cm->next)
9151     {
9152       /* Skip absent members in default initializers.  */
9153       if (!c->expr && !cm->attr.allocatable)
9154 	continue;
9155 
9156       /* Register the component with the caf-lib before it is initialized.
9157 	 Register only allocatable components, that are not coarray'ed
9158 	 components (%comp[*]).  Only register when the constructor is not the
9159 	 null-expression.  */
9160       if (coarray && !cm->attr.codimension
9161 	  && (cm->attr.allocatable || cm->attr.pointer)
9162 	  && (!c->expr || c->expr->expr_type == EXPR_NULL))
9163 	{
9164 	  tree token, desc, size;
9165 	  bool is_array = cm->ts.type == BT_CLASS
9166 	      ? CLASS_DATA (cm)->attr.dimension : cm->attr.dimension;
9167 
9168 	  field = cm->backend_decl;
9169 	  field = fold_build3_loc (input_location, COMPONENT_REF,
9170 				   TREE_TYPE (field), dest, field, NULL_TREE);
9171 	  if (cm->ts.type == BT_CLASS)
9172 	    field = gfc_class_data_get (field);
9173 
9174 	  token = is_array ? gfc_conv_descriptor_token (field)
9175 			   : fold_build3_loc (input_location, COMPONENT_REF,
9176 					      TREE_TYPE (cm->caf_token), dest,
9177 					      cm->caf_token, NULL_TREE);
9178 
9179 	  if (is_array)
9180 	    {
9181 	      /* The _caf_register routine looks at the rank of the array
9182 		 descriptor to decide whether the data registered is an array
9183 		 or not.  */
9184 	      int rank = cm->ts.type == BT_CLASS ? CLASS_DATA (cm)->as->rank
9185 						 : cm->as->rank;
9186 	      /* When the rank is not known just set a positive rank, which
9187 		 suffices to recognize the data as array.  */
9188 	      if (rank < 0)
9189 		rank = 1;
9190 	      size = build_zero_cst (size_type_node);
9191 	      desc = field;
9192 	      gfc_add_modify (&block, gfc_conv_descriptor_rank (desc),
9193 			      build_int_cst (signed_char_type_node, rank));
9194 	    }
9195 	  else
9196 	    {
9197 	      desc = gfc_conv_scalar_to_descriptor (&se, field,
9198 						    cm->ts.type == BT_CLASS
9199 						    ? CLASS_DATA (cm)->attr
9200 						    : cm->attr);
9201 	      size = TYPE_SIZE_UNIT (TREE_TYPE (field));
9202 	    }
9203 	  gfc_add_block_to_block (&block, &se.pre);
9204 	  tmp =  build_call_expr_loc (input_location, gfor_fndecl_caf_register,
9205 				      7, size, build_int_cst (
9206 					integer_type_node,
9207 					GFC_CAF_COARRAY_ALLOC_REGISTER_ONLY),
9208 				      gfc_build_addr_expr (pvoid_type_node,
9209 							   token),
9210 				      gfc_build_addr_expr (NULL_TREE, desc),
9211 				      null_pointer_node, null_pointer_node,
9212 				      integer_zero_node);
9213 	  gfc_add_expr_to_block (&block, tmp);
9214 	}
9215       field = cm->backend_decl;
9216       gcc_assert(field);
9217       tmp = fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field),
9218 			     dest, field, NULL_TREE);
9219       if (!c->expr)
9220 	{
9221 	  gfc_expr *e = gfc_get_null_expr (NULL);
9222 	  tmp = gfc_trans_subcomponent_assign (tmp, cm, e, expr->ts.u.derived,
9223 					       init);
9224 	  gfc_free_expr (e);
9225 	}
9226       else
9227         tmp = gfc_trans_subcomponent_assign (tmp, cm, c->expr,
9228                                              expr->ts.u.derived, init);
9229       gfc_add_expr_to_block (&block, tmp);
9230     }
9231   return gfc_finish_block (&block);
9232 }
9233 
9234 static void
gfc_conv_union_initializer(vec<constructor_elt,va_gc> * & v,gfc_component * un,gfc_expr * init)9235 gfc_conv_union_initializer (vec<constructor_elt, va_gc> *&v,
9236                             gfc_component *un, gfc_expr *init)
9237 {
9238   gfc_constructor *ctor;
9239 
9240   if (un->ts.type != BT_UNION || un == NULL || init == NULL)
9241     return;
9242 
9243   ctor = gfc_constructor_first (init->value.constructor);
9244 
9245   if (ctor == NULL || ctor->expr == NULL)
9246     return;
9247 
9248   gcc_assert (init->expr_type == EXPR_STRUCTURE);
9249 
9250   /* If we have an 'initialize all' constructor, do it first.  */
9251   if (ctor->expr->expr_type == EXPR_NULL)
9252     {
9253       tree union_type = TREE_TYPE (un->backend_decl);
9254       tree val = build_constructor (union_type, NULL);
9255       CONSTRUCTOR_APPEND_ELT (v, un->backend_decl, val);
9256       ctor = gfc_constructor_next (ctor);
9257     }
9258 
9259   /* Add the map initializer on top.  */
9260   if (ctor != NULL && ctor->expr != NULL)
9261     {
9262       gcc_assert (ctor->expr->expr_type == EXPR_STRUCTURE);
9263       tree val = gfc_conv_initializer (ctor->expr, &un->ts,
9264                                        TREE_TYPE (un->backend_decl),
9265                                        un->attr.dimension, un->attr.pointer,
9266                                        un->attr.proc_pointer);
9267       CONSTRUCTOR_APPEND_ELT (v, un->backend_decl, val);
9268     }
9269 }
9270 
9271 /* Build an expression for a constructor. If init is nonzero then
9272    this is part of a static variable initializer.  */
9273 
9274 void
gfc_conv_structure(gfc_se * se,gfc_expr * expr,int init)9275 gfc_conv_structure (gfc_se * se, gfc_expr * expr, int init)
9276 {
9277   gfc_constructor *c;
9278   gfc_component *cm;
9279   tree val;
9280   tree type;
9281   tree tmp;
9282   vec<constructor_elt, va_gc> *v = NULL;
9283 
9284   gcc_assert (se->ss == NULL);
9285   gcc_assert (expr->expr_type == EXPR_STRUCTURE);
9286   type = gfc_typenode_for_spec (&expr->ts);
9287 
9288   if (!init)
9289     {
9290       /* Create a temporary variable and fill it in.  */
9291       se->expr = gfc_create_var (type, expr->ts.u.derived->name);
9292       /* The symtree in expr is NULL, if the code to generate is for
9293 	 initializing the static members only.  */
9294       tmp = gfc_trans_structure_assign (se->expr, expr, expr->symtree != NULL,
9295 					se->want_coarray);
9296       gfc_add_expr_to_block (&se->pre, tmp);
9297       return;
9298     }
9299 
9300   cm = expr->ts.u.derived->components;
9301 
9302   for (c = gfc_constructor_first (expr->value.constructor);
9303        c && cm; c = gfc_constructor_next (c), cm = cm->next)
9304     {
9305       /* Skip absent members in default initializers and allocatable
9306 	 components.  Although the latter have a default initializer
9307 	 of EXPR_NULL,... by default, the static nullify is not needed
9308 	 since this is done every time we come into scope.  */
9309       if (!c->expr || (cm->attr.allocatable && cm->attr.flavor != FL_PROCEDURE))
9310 	continue;
9311 
9312       if (cm->initializer && cm->initializer->expr_type != EXPR_NULL
9313 	  && strcmp (cm->name, "_extends") == 0
9314 	  && cm->initializer->symtree)
9315 	{
9316 	  tree vtab;
9317 	  gfc_symbol *vtabs;
9318 	  vtabs = cm->initializer->symtree->n.sym;
9319 	  vtab = gfc_build_addr_expr (NULL_TREE, gfc_get_symbol_decl (vtabs));
9320 	  vtab = unshare_expr_without_location (vtab);
9321 	  CONSTRUCTOR_APPEND_ELT (v, cm->backend_decl, vtab);
9322 	}
9323       else if (cm->ts.u.derived && strcmp (cm->name, "_size") == 0)
9324 	{
9325 	  val = TYPE_SIZE_UNIT (gfc_get_derived_type (cm->ts.u.derived));
9326 	  CONSTRUCTOR_APPEND_ELT (v, cm->backend_decl,
9327 				  fold_convert (TREE_TYPE (cm->backend_decl),
9328 						val));
9329 	}
9330       else if (cm->ts.type == BT_INTEGER && strcmp (cm->name, "_len") == 0)
9331 	CONSTRUCTOR_APPEND_ELT (v, cm->backend_decl,
9332 				fold_convert (TREE_TYPE (cm->backend_decl),
9333 					      integer_zero_node));
9334       else if (cm->ts.type == BT_UNION)
9335         gfc_conv_union_initializer (v, cm, c->expr);
9336       else
9337 	{
9338 	  val = gfc_conv_initializer (c->expr, &cm->ts,
9339 				      TREE_TYPE (cm->backend_decl),
9340 				      cm->attr.dimension, cm->attr.pointer,
9341 				      cm->attr.proc_pointer);
9342 	  val = unshare_expr_without_location (val);
9343 
9344 	  /* Append it to the constructor list.  */
9345 	  CONSTRUCTOR_APPEND_ELT (v, cm->backend_decl, val);
9346 	}
9347     }
9348 
9349   se->expr = build_constructor (type, v);
9350   if (init)
9351     TREE_CONSTANT (se->expr) = 1;
9352 }
9353 
9354 
9355 /* Translate a substring expression.  */
9356 
9357 static void
gfc_conv_substring_expr(gfc_se * se,gfc_expr * expr)9358 gfc_conv_substring_expr (gfc_se * se, gfc_expr * expr)
9359 {
9360   gfc_ref *ref;
9361 
9362   ref = expr->ref;
9363 
9364   gcc_assert (ref == NULL || ref->type == REF_SUBSTRING);
9365 
9366   se->expr = gfc_build_wide_string_const (expr->ts.kind,
9367 					  expr->value.character.length,
9368 					  expr->value.character.string);
9369 
9370   se->string_length = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (se->expr)));
9371   TYPE_STRING_FLAG (TREE_TYPE (se->expr)) = 1;
9372 
9373   if (ref)
9374     gfc_conv_substring (se, ref, expr->ts.kind, NULL, &expr->where);
9375 }
9376 
9377 
9378 /* Entry point for expression translation.  Evaluates a scalar quantity.
9379    EXPR is the expression to be translated, and SE is the state structure if
9380    called from within the scalarized.  */
9381 
9382 void
gfc_conv_expr(gfc_se * se,gfc_expr * expr)9383 gfc_conv_expr (gfc_se * se, gfc_expr * expr)
9384 {
9385   gfc_ss *ss;
9386 
9387   ss = se->ss;
9388   if (ss && ss->info->expr == expr
9389       && (ss->info->type == GFC_SS_SCALAR
9390 	  || ss->info->type == GFC_SS_REFERENCE))
9391     {
9392       gfc_ss_info *ss_info;
9393 
9394       ss_info = ss->info;
9395       /* Substitute a scalar expression evaluated outside the scalarization
9396 	 loop.  */
9397       se->expr = ss_info->data.scalar.value;
9398       if (gfc_scalar_elemental_arg_saved_as_reference (ss_info))
9399 	se->expr = build_fold_indirect_ref_loc (input_location, se->expr);
9400 
9401       se->string_length = ss_info->string_length;
9402       gfc_advance_se_ss_chain (se);
9403       return;
9404     }
9405 
9406   /* We need to convert the expressions for the iso_c_binding derived types.
9407      C_NULL_PTR and C_NULL_FUNPTR will be made EXPR_NULL, which evaluates to
9408      null_pointer_node.  C_PTR and C_FUNPTR are converted to match the
9409      typespec for the C_PTR and C_FUNPTR symbols, which has already been
9410      updated to be an integer with a kind equal to the size of a (void *).  */
9411   if (expr->ts.type == BT_DERIVED && expr->ts.u.derived->ts.f90_type == BT_VOID
9412       && expr->ts.u.derived->attr.is_bind_c)
9413     {
9414       if (expr->expr_type == EXPR_VARIABLE
9415 	  && (expr->symtree->n.sym->intmod_sym_id == ISOCBINDING_NULL_PTR
9416 	      || expr->symtree->n.sym->intmod_sym_id
9417 		 == ISOCBINDING_NULL_FUNPTR))
9418         {
9419 	  /* Set expr_type to EXPR_NULL, which will result in
9420 	     null_pointer_node being used below.  */
9421           expr->expr_type = EXPR_NULL;
9422         }
9423       else
9424         {
9425           /* Update the type/kind of the expression to be what the new
9426              type/kind are for the updated symbols of C_PTR/C_FUNPTR.  */
9427           expr->ts.type = BT_INTEGER;
9428           expr->ts.f90_type = BT_VOID;
9429           expr->ts.kind = gfc_index_integer_kind;
9430         }
9431     }
9432 
9433   gfc_fix_class_refs (expr);
9434 
9435   switch (expr->expr_type)
9436     {
9437     case EXPR_OP:
9438       gfc_conv_expr_op (se, expr);
9439       break;
9440 
9441     case EXPR_FUNCTION:
9442       gfc_conv_function_expr (se, expr);
9443       break;
9444 
9445     case EXPR_CONSTANT:
9446       gfc_conv_constant (se, expr);
9447       break;
9448 
9449     case EXPR_VARIABLE:
9450       gfc_conv_variable (se, expr);
9451       break;
9452 
9453     case EXPR_NULL:
9454       se->expr = null_pointer_node;
9455       break;
9456 
9457     case EXPR_SUBSTRING:
9458       gfc_conv_substring_expr (se, expr);
9459       break;
9460 
9461     case EXPR_STRUCTURE:
9462       gfc_conv_structure (se, expr, 0);
9463       break;
9464 
9465     case EXPR_ARRAY:
9466       gfc_conv_array_constructor_expr (se, expr);
9467       break;
9468 
9469     default:
9470       gcc_unreachable ();
9471       break;
9472     }
9473 }
9474 
9475 /* Like gfc_conv_expr_val, but the value is also suitable for use in the lhs
9476    of an assignment.  */
9477 void
gfc_conv_expr_lhs(gfc_se * se,gfc_expr * expr)9478 gfc_conv_expr_lhs (gfc_se * se, gfc_expr * expr)
9479 {
9480   gfc_conv_expr (se, expr);
9481   /* All numeric lvalues should have empty post chains.  If not we need to
9482      figure out a way of rewriting an lvalue so that it has no post chain.  */
9483   gcc_assert (expr->ts.type == BT_CHARACTER || !se->post.head);
9484 }
9485 
9486 /* Like gfc_conv_expr, but the POST block is guaranteed to be empty for
9487    numeric expressions.  Used for scalar values where inserting cleanup code
9488    is inconvenient.  */
9489 void
gfc_conv_expr_val(gfc_se * se,gfc_expr * expr)9490 gfc_conv_expr_val (gfc_se * se, gfc_expr * expr)
9491 {
9492   tree val;
9493 
9494   gcc_assert (expr->ts.type != BT_CHARACTER);
9495   gfc_conv_expr (se, expr);
9496   if (se->post.head)
9497     {
9498       val = gfc_create_var (TREE_TYPE (se->expr), NULL);
9499       gfc_add_modify (&se->pre, val, se->expr);
9500       se->expr = val;
9501       gfc_add_block_to_block (&se->pre, &se->post);
9502     }
9503 }
9504 
9505 /* Helper to translate an expression and convert it to a particular type.  */
9506 void
gfc_conv_expr_type(gfc_se * se,gfc_expr * expr,tree type)9507 gfc_conv_expr_type (gfc_se * se, gfc_expr * expr, tree type)
9508 {
9509   gfc_conv_expr_val (se, expr);
9510   se->expr = convert (type, se->expr);
9511 }
9512 
9513 
9514 /* Converts an expression so that it can be passed by reference.  Scalar
9515    values only.  */
9516 
9517 void
gfc_conv_expr_reference(gfc_se * se,gfc_expr * expr)9518 gfc_conv_expr_reference (gfc_se * se, gfc_expr * expr)
9519 {
9520   gfc_ss *ss;
9521   tree var;
9522 
9523   ss = se->ss;
9524   if (ss && ss->info->expr == expr
9525       && ss->info->type == GFC_SS_REFERENCE)
9526     {
9527       /* Returns a reference to the scalar evaluated outside the loop
9528 	 for this case.  */
9529       gfc_conv_expr (se, expr);
9530 
9531       if (expr->ts.type == BT_CHARACTER
9532 	  && expr->expr_type != EXPR_FUNCTION)
9533 	gfc_conv_string_parameter (se);
9534      else
9535 	se->expr = gfc_build_addr_expr (NULL_TREE, se->expr);
9536 
9537       return;
9538     }
9539 
9540   if (expr->ts.type == BT_CHARACTER)
9541     {
9542       gfc_conv_expr (se, expr);
9543       gfc_conv_string_parameter (se);
9544       return;
9545     }
9546 
9547   if (expr->expr_type == EXPR_VARIABLE)
9548     {
9549       se->want_pointer = 1;
9550       gfc_conv_expr (se, expr);
9551       if (se->post.head)
9552 	{
9553 	  var = gfc_create_var (TREE_TYPE (se->expr), NULL);
9554 	  gfc_add_modify (&se->pre, var, se->expr);
9555 	  gfc_add_block_to_block (&se->pre, &se->post);
9556 	  se->expr = var;
9557 	}
9558       return;
9559     }
9560 
9561   if (expr->expr_type == EXPR_FUNCTION
9562       && ((expr->value.function.esym
9563 	   && expr->value.function.esym->result
9564 	   && expr->value.function.esym->result->attr.pointer
9565 	   && !expr->value.function.esym->result->attr.dimension)
9566 	  || (!expr->value.function.esym && !expr->ref
9567 	      && expr->symtree->n.sym->attr.pointer
9568 	      && !expr->symtree->n.sym->attr.dimension)))
9569     {
9570       se->want_pointer = 1;
9571       gfc_conv_expr (se, expr);
9572       var = gfc_create_var (TREE_TYPE (se->expr), NULL);
9573       gfc_add_modify (&se->pre, var, se->expr);
9574       se->expr = var;
9575       return;
9576     }
9577 
9578   gfc_conv_expr (se, expr);
9579 
9580   /* Create a temporary var to hold the value.  */
9581   if (TREE_CONSTANT (se->expr))
9582     {
9583       tree tmp = se->expr;
9584       STRIP_TYPE_NOPS (tmp);
9585       var = build_decl (input_location,
9586 			CONST_DECL, NULL, TREE_TYPE (tmp));
9587       DECL_INITIAL (var) = tmp;
9588       TREE_STATIC (var) = 1;
9589       pushdecl (var);
9590     }
9591   else
9592     {
9593       var = gfc_create_var (TREE_TYPE (se->expr), NULL);
9594       gfc_add_modify (&se->pre, var, se->expr);
9595     }
9596 
9597   if (!expr->must_finalize)
9598     gfc_add_block_to_block (&se->pre, &se->post);
9599 
9600   /* Take the address of that value.  */
9601   se->expr = gfc_build_addr_expr (NULL_TREE, var);
9602 }
9603 
9604 
9605 /* Get the _len component for an unlimited polymorphic expression.  */
9606 
9607 static tree
trans_get_upoly_len(stmtblock_t * block,gfc_expr * expr)9608 trans_get_upoly_len (stmtblock_t *block, gfc_expr *expr)
9609 {
9610   gfc_se se;
9611   gfc_ref *ref = expr->ref;
9612 
9613   gfc_init_se (&se, NULL);
9614   while (ref && ref->next)
9615     ref = ref->next;
9616   gfc_add_len_component (expr);
9617   gfc_conv_expr (&se, expr);
9618   gfc_add_block_to_block (block, &se.pre);
9619   gcc_assert (se.post.head == NULL_TREE);
9620   if (ref)
9621     {
9622       gfc_free_ref_list (ref->next);
9623       ref->next = NULL;
9624     }
9625   else
9626     {
9627       gfc_free_ref_list (expr->ref);
9628       expr->ref = NULL;
9629     }
9630   return se.expr;
9631 }
9632 
9633 
9634 /* Assign _vptr and _len components as appropriate.  BLOCK should be a
9635    statement-list outside of the scalarizer-loop.  When code is generated, that
9636    depends on the scalarized expression, it is added to RSE.PRE.
9637    Returns le's _vptr tree and when set the len expressions in to_lenp and
9638    from_lenp to form a le%_vptr%_copy (re, le, [from_lenp, to_lenp])
9639    expression.  */
9640 
9641 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)9642 trans_class_vptr_len_assignment (stmtblock_t *block, gfc_expr * le,
9643 				 gfc_expr * re, gfc_se *rse,
9644 				 tree * to_lenp, tree * from_lenp)
9645 {
9646   gfc_se se;
9647   gfc_expr * vptr_expr;
9648   tree tmp, to_len = NULL_TREE, from_len = NULL_TREE, lhs_vptr;
9649   bool set_vptr = false, temp_rhs = false;
9650   stmtblock_t *pre = block;
9651   tree class_expr = NULL_TREE;
9652 
9653   /* Create a temporary for complicated expressions.  */
9654   if (re->expr_type != EXPR_VARIABLE && re->expr_type != EXPR_NULL
9655       && rse->expr != NULL_TREE && !DECL_P (rse->expr))
9656     {
9657       if (re->ts.type == BT_CLASS && !GFC_CLASS_TYPE_P (TREE_TYPE (rse->expr)))
9658 	class_expr = gfc_get_class_from_expr (rse->expr);
9659 
9660       if (rse->loop)
9661 	pre = &rse->loop->pre;
9662       else
9663 	pre = &rse->pre;
9664 
9665       if (class_expr != NULL_TREE && UNLIMITED_POLY (re))
9666 	{
9667 	  tmp = TREE_OPERAND (rse->expr, 0);
9668 	  tmp = gfc_create_var (TREE_TYPE (tmp), "rhs");
9669 	  gfc_add_modify (&rse->pre, tmp, TREE_OPERAND (rse->expr, 0));
9670 	}
9671       else
9672 	{
9673 	  tmp = gfc_create_var (TREE_TYPE (rse->expr), "rhs");
9674 	  gfc_add_modify (&rse->pre, tmp, rse->expr);
9675 	}
9676 
9677       rse->expr = tmp;
9678       temp_rhs = true;
9679     }
9680 
9681   /* Get the _vptr for the left-hand side expression.  */
9682   gfc_init_se (&se, NULL);
9683   vptr_expr = gfc_find_and_cut_at_last_class_ref (le);
9684   if (vptr_expr != NULL && gfc_expr_attr (vptr_expr).class_ok)
9685     {
9686       /* Care about _len for unlimited polymorphic entities.  */
9687       if (UNLIMITED_POLY (vptr_expr)
9688 	  || (vptr_expr->ts.type == BT_DERIVED
9689 	      && vptr_expr->ts.u.derived->attr.unlimited_polymorphic))
9690 	to_len = trans_get_upoly_len (block, vptr_expr);
9691       gfc_add_vptr_component (vptr_expr);
9692       set_vptr = true;
9693     }
9694   else
9695     vptr_expr = gfc_lval_expr_from_sym (gfc_find_vtab (&le->ts));
9696   se.want_pointer = 1;
9697   gfc_conv_expr (&se, vptr_expr);
9698   gfc_free_expr (vptr_expr);
9699   gfc_add_block_to_block (block, &se.pre);
9700   gcc_assert (se.post.head == NULL_TREE);
9701   lhs_vptr = se.expr;
9702   STRIP_NOPS (lhs_vptr);
9703 
9704   /* Set the _vptr only when the left-hand side of the assignment is a
9705      class-object.  */
9706   if (set_vptr)
9707     {
9708       /* Get the vptr from the rhs expression only, when it is variable.
9709 	 Functions are expected to be assigned to a temporary beforehand.  */
9710       vptr_expr = (re->expr_type == EXPR_VARIABLE && re->ts.type == BT_CLASS)
9711 	  ? gfc_find_and_cut_at_last_class_ref (re)
9712 	  : NULL;
9713       if (vptr_expr != NULL && vptr_expr->ts.type == BT_CLASS)
9714 	{
9715 	  if (to_len != NULL_TREE)
9716 	    {
9717 	      /* Get the _len information from the rhs.  */
9718 	      if (UNLIMITED_POLY (vptr_expr)
9719 		  || (vptr_expr->ts.type == BT_DERIVED
9720 		      && vptr_expr->ts.u.derived->attr.unlimited_polymorphic))
9721 		from_len = trans_get_upoly_len (block, vptr_expr);
9722 	    }
9723 	  gfc_add_vptr_component (vptr_expr);
9724 	}
9725       else
9726 	{
9727 	  if (re->expr_type == EXPR_VARIABLE
9728 	      && DECL_P (re->symtree->n.sym->backend_decl)
9729 	      && DECL_LANG_SPECIFIC (re->symtree->n.sym->backend_decl)
9730 	      && GFC_DECL_SAVED_DESCRIPTOR (re->symtree->n.sym->backend_decl)
9731 	      && GFC_CLASS_TYPE_P (TREE_TYPE (GFC_DECL_SAVED_DESCRIPTOR (
9732 					   re->symtree->n.sym->backend_decl))))
9733 	    {
9734 	      vptr_expr = NULL;
9735 	      se.expr = gfc_class_vptr_get (GFC_DECL_SAVED_DESCRIPTOR (
9736 					     re->symtree->n.sym->backend_decl));
9737 	      if (to_len)
9738 		from_len = gfc_class_len_get (GFC_DECL_SAVED_DESCRIPTOR (
9739 					     re->symtree->n.sym->backend_decl));
9740 	    }
9741 	  else if (temp_rhs && re->ts.type == BT_CLASS)
9742 	    {
9743 	      vptr_expr = NULL;
9744 	      if (class_expr)
9745 		tmp = class_expr;
9746 	      else if (!GFC_CLASS_TYPE_P (TREE_TYPE (rse->expr)))
9747 		tmp = gfc_get_class_from_expr (rse->expr);
9748 	      else
9749 		tmp = rse->expr;
9750 
9751 	      se.expr = gfc_class_vptr_get (tmp);
9752 	      if (UNLIMITED_POLY (re))
9753 		from_len = gfc_class_len_get (tmp);
9754 
9755 	    }
9756 	  else if (re->expr_type != EXPR_NULL)
9757 	    /* Only when rhs is non-NULL use its declared type for vptr
9758 	       initialisation.  */
9759 	    vptr_expr = gfc_lval_expr_from_sym (gfc_find_vtab (&re->ts));
9760 	  else
9761 	    /* When the rhs is NULL use the vtab of lhs' declared type.  */
9762 	    vptr_expr = gfc_lval_expr_from_sym (gfc_find_vtab (&le->ts));
9763 	}
9764 
9765       if (vptr_expr)
9766 	{
9767 	  gfc_init_se (&se, NULL);
9768 	  se.want_pointer = 1;
9769 	  gfc_conv_expr (&se, vptr_expr);
9770 	  gfc_free_expr (vptr_expr);
9771 	  gfc_add_block_to_block (block, &se.pre);
9772 	  gcc_assert (se.post.head == NULL_TREE);
9773 	}
9774       gfc_add_modify (pre, lhs_vptr, fold_convert (TREE_TYPE (lhs_vptr),
9775 						se.expr));
9776 
9777       if (to_len != NULL_TREE)
9778 	{
9779 	  /* The _len component needs to be set.  Figure how to get the
9780 	     value of the right-hand side.  */
9781 	  if (from_len == NULL_TREE)
9782 	    {
9783 	      if (rse->string_length != NULL_TREE)
9784 		from_len = rse->string_length;
9785 	      else if (re->ts.type == BT_CHARACTER && re->ts.u.cl->length)
9786 		{
9787 		  gfc_init_se (&se, NULL);
9788 		  gfc_conv_expr (&se, re->ts.u.cl->length);
9789 		  gfc_add_block_to_block (block, &se.pre);
9790 		  gcc_assert (se.post.head == NULL_TREE);
9791 		  from_len = gfc_evaluate_now (se.expr, block);
9792 		}
9793 	      else
9794 		from_len = build_zero_cst (gfc_charlen_type_node);
9795 	    }
9796 	  gfc_add_modify (pre, to_len, fold_convert (TREE_TYPE (to_len),
9797 						     from_len));
9798 	}
9799     }
9800 
9801   /* Return the _len trees only, when requested.  */
9802   if (to_lenp)
9803     *to_lenp = to_len;
9804   if (from_lenp)
9805     *from_lenp = from_len;
9806   return lhs_vptr;
9807 }
9808 
9809 
9810 /* Assign tokens for pointer components.  */
9811 
9812 static void
trans_caf_token_assign(gfc_se * lse,gfc_se * rse,gfc_expr * expr1,gfc_expr * expr2)9813 trans_caf_token_assign (gfc_se *lse, gfc_se *rse, gfc_expr *expr1,
9814 			gfc_expr *expr2)
9815 {
9816   symbol_attribute lhs_attr, rhs_attr;
9817   tree tmp, lhs_tok, rhs_tok;
9818   /* Flag to indicated component refs on the rhs.  */
9819   bool rhs_cr;
9820 
9821   lhs_attr = gfc_caf_attr (expr1);
9822   if (expr2->expr_type != EXPR_NULL)
9823     {
9824       rhs_attr = gfc_caf_attr (expr2, false, &rhs_cr);
9825       if (lhs_attr.codimension && rhs_attr.codimension)
9826 	{
9827 	  lhs_tok = gfc_get_ultimate_alloc_ptr_comps_caf_token (lse, expr1);
9828 	  lhs_tok = build_fold_indirect_ref (lhs_tok);
9829 
9830 	  if (rhs_cr)
9831 	    rhs_tok = gfc_get_ultimate_alloc_ptr_comps_caf_token (rse, expr2);
9832 	  else
9833 	    {
9834 	      tree caf_decl;
9835 	      caf_decl = gfc_get_tree_for_caf_expr (expr2);
9836 	      gfc_get_caf_token_offset (rse, &rhs_tok, NULL, caf_decl,
9837 					NULL_TREE, NULL);
9838 	    }
9839 	  tmp = build2_loc (input_location, MODIFY_EXPR, void_type_node,
9840 			    lhs_tok,
9841 			    fold_convert (TREE_TYPE (lhs_tok), rhs_tok));
9842 	  gfc_prepend_expr_to_block (&lse->post, tmp);
9843 	}
9844     }
9845   else if (lhs_attr.codimension)
9846     {
9847       lhs_tok = gfc_get_ultimate_alloc_ptr_comps_caf_token (lse, expr1);
9848       lhs_tok = build_fold_indirect_ref (lhs_tok);
9849       tmp = build2_loc (input_location, MODIFY_EXPR, void_type_node,
9850 			lhs_tok, null_pointer_node);
9851       gfc_prepend_expr_to_block (&lse->post, tmp);
9852     }
9853 }
9854 
9855 
9856 /* Do everything that is needed for a CLASS function expr2.  */
9857 
9858 static tree
trans_class_pointer_fcn(stmtblock_t * block,gfc_se * lse,gfc_se * rse,gfc_expr * expr1,gfc_expr * expr2)9859 trans_class_pointer_fcn (stmtblock_t *block, gfc_se *lse, gfc_se *rse,
9860 			 gfc_expr *expr1, gfc_expr *expr2)
9861 {
9862   tree expr1_vptr = NULL_TREE;
9863   tree tmp;
9864 
9865   gfc_conv_function_expr (rse, expr2);
9866   rse->expr = gfc_evaluate_now (rse->expr, &rse->pre);
9867 
9868   if (expr1->ts.type != BT_CLASS)
9869       rse->expr = gfc_class_data_get (rse->expr);
9870   else
9871     {
9872       expr1_vptr = trans_class_vptr_len_assignment (block, expr1,
9873 						    expr2, rse,
9874 						    NULL, NULL);
9875       gfc_add_block_to_block (block, &rse->pre);
9876       tmp = gfc_create_var (TREE_TYPE (rse->expr), "ptrtemp");
9877       gfc_add_modify (&lse->pre, tmp, rse->expr);
9878 
9879       gfc_add_modify (&lse->pre, expr1_vptr,
9880 		      fold_convert (TREE_TYPE (expr1_vptr),
9881 		      gfc_class_vptr_get (tmp)));
9882       rse->expr = gfc_class_data_get (tmp);
9883     }
9884 
9885   return expr1_vptr;
9886 }
9887 
9888 
9889 tree
gfc_trans_pointer_assign(gfc_code * code)9890 gfc_trans_pointer_assign (gfc_code * code)
9891 {
9892   return gfc_trans_pointer_assignment (code->expr1, code->expr2);
9893 }
9894 
9895 
9896 /* Generate code for a pointer assignment.  */
9897 
9898 tree
gfc_trans_pointer_assignment(gfc_expr * expr1,gfc_expr * expr2)9899 gfc_trans_pointer_assignment (gfc_expr * expr1, gfc_expr * expr2)
9900 {
9901   gfc_se lse;
9902   gfc_se rse;
9903   stmtblock_t block;
9904   tree desc;
9905   tree tmp;
9906   tree expr1_vptr = NULL_TREE;
9907   bool scalar, non_proc_ptr_assign;
9908   gfc_ss *ss;
9909 
9910   gfc_start_block (&block);
9911 
9912   gfc_init_se (&lse, NULL);
9913 
9914   /* Usually testing whether this is not a proc pointer assignment.  */
9915   non_proc_ptr_assign = !(gfc_expr_attr (expr1).proc_pointer
9916 			&& expr2->expr_type == EXPR_VARIABLE
9917 			&& expr2->symtree->n.sym->attr.flavor == FL_PROCEDURE);
9918 
9919   /* Check whether the expression is a scalar or not; we cannot use
9920      expr1->rank as it can be nonzero for proc pointers.  */
9921   ss = gfc_walk_expr (expr1);
9922   scalar = ss == gfc_ss_terminator;
9923   if (!scalar)
9924     gfc_free_ss_chain (ss);
9925 
9926   if (expr1->ts.type == BT_DERIVED && expr2->ts.type == BT_CLASS
9927       && expr2->expr_type != EXPR_FUNCTION && non_proc_ptr_assign)
9928     {
9929       gfc_add_data_component (expr2);
9930       /* The following is required as gfc_add_data_component doesn't
9931 	 update ts.type if there is a trailing REF_ARRAY.  */
9932       expr2->ts.type = BT_DERIVED;
9933     }
9934 
9935   if (scalar)
9936     {
9937       /* Scalar pointers.  */
9938       lse.want_pointer = 1;
9939       gfc_conv_expr (&lse, expr1);
9940       gfc_init_se (&rse, NULL);
9941       rse.want_pointer = 1;
9942       if (expr2->expr_type == EXPR_FUNCTION && expr2->ts.type == BT_CLASS)
9943 	trans_class_pointer_fcn (&block, &lse, &rse, expr1, expr2);
9944       else
9945 	gfc_conv_expr (&rse, expr2);
9946 
9947       if (non_proc_ptr_assign && expr1->ts.type == BT_CLASS)
9948 	{
9949 	  trans_class_vptr_len_assignment (&block, expr1, expr2, &rse, NULL,
9950 					   NULL);
9951 	  lse.expr = gfc_class_data_get (lse.expr);
9952 	}
9953 
9954       if (expr1->symtree->n.sym->attr.proc_pointer
9955 	  && expr1->symtree->n.sym->attr.dummy)
9956 	lse.expr = build_fold_indirect_ref_loc (input_location,
9957 						lse.expr);
9958 
9959       if (expr2->symtree && expr2->symtree->n.sym->attr.proc_pointer
9960 	  && expr2->symtree->n.sym->attr.dummy)
9961 	rse.expr = build_fold_indirect_ref_loc (input_location,
9962 						rse.expr);
9963 
9964       gfc_add_block_to_block (&block, &lse.pre);
9965       gfc_add_block_to_block (&block, &rse.pre);
9966 
9967       /* Check character lengths if character expression.  The test is only
9968 	 really added if -fbounds-check is enabled.  Exclude deferred
9969 	 character length lefthand sides.  */
9970       if (expr1->ts.type == BT_CHARACTER && expr2->expr_type != EXPR_NULL
9971 	  && !expr1->ts.deferred
9972 	  && !expr1->symtree->n.sym->attr.proc_pointer
9973 	  && !gfc_is_proc_ptr_comp (expr1))
9974 	{
9975 	  gcc_assert (expr2->ts.type == BT_CHARACTER);
9976 	  gcc_assert (lse.string_length && rse.string_length);
9977 	  gfc_trans_same_strlen_check ("pointer assignment", &expr1->where,
9978 				       lse.string_length, rse.string_length,
9979 				       &block);
9980 	}
9981 
9982       /* The assignment to an deferred character length sets the string
9983 	 length to that of the rhs.  */
9984       if (expr1->ts.deferred)
9985 	{
9986 	  if (expr2->expr_type != EXPR_NULL && lse.string_length != NULL)
9987 	    gfc_add_modify (&block, lse.string_length,
9988 			    fold_convert (TREE_TYPE (lse.string_length),
9989 					  rse.string_length));
9990 	  else if (lse.string_length != NULL)
9991 	    gfc_add_modify (&block, lse.string_length,
9992 			    build_zero_cst (TREE_TYPE (lse.string_length)));
9993 	}
9994 
9995       gfc_add_modify (&block, lse.expr,
9996 		      fold_convert (TREE_TYPE (lse.expr), rse.expr));
9997 
9998       /* Also set the tokens for pointer components in derived typed
9999 	 coarrays.  */
10000       if (flag_coarray == GFC_FCOARRAY_LIB)
10001 	trans_caf_token_assign (&lse, &rse, expr1, expr2);
10002 
10003       gfc_add_block_to_block (&block, &rse.post);
10004       gfc_add_block_to_block (&block, &lse.post);
10005     }
10006   else
10007     {
10008       gfc_ref* remap;
10009       bool rank_remap;
10010       tree strlen_lhs;
10011       tree strlen_rhs = NULL_TREE;
10012 
10013       /* Array pointer.  Find the last reference on the LHS and if it is an
10014 	 array section ref, we're dealing with bounds remapping.  In this case,
10015 	 set it to AR_FULL so that gfc_conv_expr_descriptor does
10016 	 not see it and process the bounds remapping afterwards explicitly.  */
10017       for (remap = expr1->ref; remap; remap = remap->next)
10018 	if (!remap->next && remap->type == REF_ARRAY
10019 	    && remap->u.ar.type == AR_SECTION)
10020 	  break;
10021       rank_remap = (remap && remap->u.ar.end[0]);
10022 
10023       if (remap && expr2->expr_type == EXPR_NULL)
10024 	{
10025 	  gfc_error ("If bounds remapping is specified at %L, "
10026 		     "the pointer target shall not be NULL", &expr1->where);
10027 	  return NULL_TREE;
10028 	}
10029 
10030       gfc_init_se (&lse, NULL);
10031       if (remap)
10032 	lse.descriptor_only = 1;
10033       gfc_conv_expr_descriptor (&lse, expr1);
10034       strlen_lhs = lse.string_length;
10035       desc = lse.expr;
10036 
10037       if (expr2->expr_type == EXPR_NULL)
10038 	{
10039 	  /* Just set the data pointer to null.  */
10040 	  gfc_conv_descriptor_data_set (&lse.pre, lse.expr, null_pointer_node);
10041 	}
10042       else if (rank_remap)
10043 	{
10044 	  /* If we are rank-remapping, just get the RHS's descriptor and
10045 	     process this later on.  */
10046 	  gfc_init_se (&rse, NULL);
10047 	  rse.direct_byref = 1;
10048 	  rse.byref_noassign = 1;
10049 
10050 	  if (expr2->expr_type == EXPR_FUNCTION && expr2->ts.type == BT_CLASS)
10051 	    expr1_vptr = trans_class_pointer_fcn (&block, &lse, &rse,
10052 						  expr1, expr2);
10053 	  else if (expr2->expr_type == EXPR_FUNCTION)
10054 	    {
10055 	      tree bound[GFC_MAX_DIMENSIONS];
10056 	      int i;
10057 
10058 	      for (i = 0; i < expr2->rank; i++)
10059 		bound[i] = NULL_TREE;
10060 	      tmp = gfc_typenode_for_spec (&expr2->ts);
10061 	      tmp = gfc_get_array_type_bounds (tmp, expr2->rank, 0,
10062 					       bound, bound, 0,
10063 					       GFC_ARRAY_POINTER_CONT, false);
10064 	      tmp = gfc_create_var (tmp, "ptrtemp");
10065 	      rse.descriptor_only = 0;
10066 	      rse.expr = tmp;
10067 	      rse.direct_byref = 1;
10068 	      gfc_conv_expr_descriptor (&rse, expr2);
10069 	      strlen_rhs = rse.string_length;
10070 	      rse.expr = tmp;
10071 	    }
10072 	  else
10073 	    {
10074 	      gfc_conv_expr_descriptor (&rse, expr2);
10075 	      strlen_rhs = rse.string_length;
10076 	      if (expr1->ts.type == BT_CLASS)
10077 		expr1_vptr = trans_class_vptr_len_assignment (&block, expr1,
10078 							      expr2, &rse,
10079 							      NULL, NULL);
10080 	    }
10081 	}
10082       else if (expr2->expr_type == EXPR_VARIABLE)
10083 	{
10084 	  /* Assign directly to the LHS's descriptor.  */
10085 	  lse.descriptor_only = 0;
10086 	  lse.direct_byref = 1;
10087 	  gfc_conv_expr_descriptor (&lse, expr2);
10088 	  strlen_rhs = lse.string_length;
10089 	  gfc_init_se (&rse, NULL);
10090 
10091 	  if (expr1->ts.type == BT_CLASS)
10092 	    {
10093 	      rse.expr = NULL_TREE;
10094 	      rse.string_length = strlen_rhs;
10095 	      trans_class_vptr_len_assignment (&block, expr1, expr2, &rse,
10096 					       NULL, NULL);
10097 	    }
10098 
10099 	  if (remap == NULL)
10100 	    {
10101 	      /* If the target is not a whole array, use the target array
10102 		 reference for remap.  */
10103 	      for (remap = expr2->ref; remap; remap = remap->next)
10104 		if (remap->type == REF_ARRAY
10105 		    && remap->u.ar.type == AR_FULL
10106 		    && remap->next)
10107 		  break;
10108 	    }
10109 	}
10110       else if (expr2->expr_type == EXPR_FUNCTION && expr2->ts.type == BT_CLASS)
10111 	{
10112 	  gfc_init_se (&rse, NULL);
10113 	  rse.want_pointer = 1;
10114 	  gfc_conv_function_expr (&rse, expr2);
10115 	  if (expr1->ts.type != BT_CLASS)
10116 	    {
10117 	      rse.expr = gfc_class_data_get (rse.expr);
10118 	      gfc_add_modify (&lse.pre, desc, rse.expr);
10119 	      /* Set the lhs span.  */
10120 	      tmp = TREE_TYPE (rse.expr);
10121 	      tmp = TYPE_SIZE_UNIT (gfc_get_element_type (tmp));
10122 	      tmp = fold_convert (gfc_array_index_type, tmp);
10123 	      gfc_conv_descriptor_span_set (&lse.pre, desc, tmp);
10124  	    }
10125 	  else
10126 	    {
10127 	      expr1_vptr = trans_class_vptr_len_assignment (&block, expr1,
10128 							    expr2, &rse, NULL,
10129 							    NULL);
10130 	      gfc_add_block_to_block (&block, &rse.pre);
10131 	      tmp = gfc_create_var (TREE_TYPE (rse.expr), "ptrtemp");
10132 	      gfc_add_modify (&lse.pre, tmp, rse.expr);
10133 
10134 	      gfc_add_modify (&lse.pre, expr1_vptr,
10135 			      fold_convert (TREE_TYPE (expr1_vptr),
10136 					gfc_class_vptr_get (tmp)));
10137 	      rse.expr = gfc_class_data_get (tmp);
10138 	      gfc_add_modify (&lse.pre, desc, rse.expr);
10139 	    }
10140 	}
10141       else
10142 	{
10143 	  /* Assign to a temporary descriptor and then copy that
10144 	     temporary to the pointer.  */
10145 	  tmp = gfc_create_var (TREE_TYPE (desc), "ptrtemp");
10146 	  lse.descriptor_only = 0;
10147 	  lse.expr = tmp;
10148 	  lse.direct_byref = 1;
10149 	  gfc_conv_expr_descriptor (&lse, expr2);
10150 	  strlen_rhs = lse.string_length;
10151 	  gfc_add_modify (&lse.pre, desc, tmp);
10152 	}
10153 
10154       if (expr1->ts.type == BT_CHARACTER
10155 	  && expr1->symtree->n.sym->ts.deferred
10156 	  && expr1->symtree->n.sym->ts.u.cl->backend_decl
10157 	  && VAR_P (expr1->symtree->n.sym->ts.u.cl->backend_decl))
10158 	{
10159 	  tmp = expr1->symtree->n.sym->ts.u.cl->backend_decl;
10160 	  if (expr2->expr_type != EXPR_NULL)
10161 	    gfc_add_modify (&block, tmp,
10162 			    fold_convert (TREE_TYPE (tmp), strlen_rhs));
10163 	  else
10164 	    gfc_add_modify (&block, tmp, build_zero_cst (TREE_TYPE (tmp)));
10165 	}
10166 
10167       gfc_add_block_to_block (&block, &lse.pre);
10168       if (rank_remap)
10169 	gfc_add_block_to_block (&block, &rse.pre);
10170 
10171       /* If we do bounds remapping, update LHS descriptor accordingly.  */
10172       if (remap)
10173 	{
10174 	  int dim;
10175 	  gcc_assert (remap->u.ar.dimen == expr1->rank);
10176 
10177 	  if (rank_remap)
10178 	    {
10179 	      /* Do rank remapping.  We already have the RHS's descriptor
10180 		 converted in rse and now have to build the correct LHS
10181 		 descriptor for it.  */
10182 
10183 	      tree dtype, data, span;
10184 	      tree offs, stride;
10185 	      tree lbound, ubound;
10186 
10187 	      /* Set dtype.  */
10188 	      dtype = gfc_conv_descriptor_dtype (desc);
10189 	      tmp = gfc_get_dtype (TREE_TYPE (desc));
10190 	      gfc_add_modify (&block, dtype, tmp);
10191 
10192 	      /* Copy data pointer.  */
10193 	      data = gfc_conv_descriptor_data_get (rse.expr);
10194 	      gfc_conv_descriptor_data_set (&block, desc, data);
10195 
10196 	      /* Copy the span.  */
10197 	      if (TREE_CODE (rse.expr) == VAR_DECL
10198 		  && GFC_DECL_PTR_ARRAY_P (rse.expr))
10199 		span = gfc_conv_descriptor_span_get (rse.expr);
10200 	      else
10201 		{
10202 		  tmp = TREE_TYPE (rse.expr);
10203 		  tmp = TYPE_SIZE_UNIT (gfc_get_element_type (tmp));
10204 		  span = fold_convert (gfc_array_index_type, tmp);
10205 		}
10206 	      gfc_conv_descriptor_span_set (&block, desc, span);
10207 
10208 	      /* Copy offset but adjust it such that it would correspond
10209 		 to a lbound of zero.  */
10210 	      offs = gfc_conv_descriptor_offset_get (rse.expr);
10211 	      for (dim = 0; dim < expr2->rank; ++dim)
10212 		{
10213 		  stride = gfc_conv_descriptor_stride_get (rse.expr,
10214 							   gfc_rank_cst[dim]);
10215 		  lbound = gfc_conv_descriptor_lbound_get (rse.expr,
10216 							   gfc_rank_cst[dim]);
10217 		  tmp = fold_build2_loc (input_location, MULT_EXPR,
10218 					 gfc_array_index_type, stride, lbound);
10219 		  offs = fold_build2_loc (input_location, PLUS_EXPR,
10220 					  gfc_array_index_type, offs, tmp);
10221 		}
10222 	      gfc_conv_descriptor_offset_set (&block, desc, offs);
10223 
10224 	      /* Set the bounds as declared for the LHS and calculate strides as
10225 		 well as another offset update accordingly.  */
10226 	      stride = gfc_conv_descriptor_stride_get (rse.expr,
10227 						       gfc_rank_cst[0]);
10228 	      for (dim = 0; dim < expr1->rank; ++dim)
10229 		{
10230 		  gfc_se lower_se;
10231 		  gfc_se upper_se;
10232 
10233 		  gcc_assert (remap->u.ar.start[dim] && remap->u.ar.end[dim]);
10234 
10235 		  /* Convert declared bounds.  */
10236 		  gfc_init_se (&lower_se, NULL);
10237 		  gfc_init_se (&upper_se, NULL);
10238 		  gfc_conv_expr (&lower_se, remap->u.ar.start[dim]);
10239 		  gfc_conv_expr (&upper_se, remap->u.ar.end[dim]);
10240 
10241 		  gfc_add_block_to_block (&block, &lower_se.pre);
10242 		  gfc_add_block_to_block (&block, &upper_se.pre);
10243 
10244 		  lbound = fold_convert (gfc_array_index_type, lower_se.expr);
10245 		  ubound = fold_convert (gfc_array_index_type, upper_se.expr);
10246 
10247 		  lbound = gfc_evaluate_now (lbound, &block);
10248 		  ubound = gfc_evaluate_now (ubound, &block);
10249 
10250 		  gfc_add_block_to_block (&block, &lower_se.post);
10251 		  gfc_add_block_to_block (&block, &upper_se.post);
10252 
10253 		  /* Set bounds in descriptor.  */
10254 		  gfc_conv_descriptor_lbound_set (&block, desc,
10255 						  gfc_rank_cst[dim], lbound);
10256 		  gfc_conv_descriptor_ubound_set (&block, desc,
10257 						  gfc_rank_cst[dim], ubound);
10258 
10259 		  /* Set stride.  */
10260 		  stride = gfc_evaluate_now (stride, &block);
10261 		  gfc_conv_descriptor_stride_set (&block, desc,
10262 						  gfc_rank_cst[dim], stride);
10263 
10264 		  /* Update offset.  */
10265 		  offs = gfc_conv_descriptor_offset_get (desc);
10266 		  tmp = fold_build2_loc (input_location, MULT_EXPR,
10267 					 gfc_array_index_type, lbound, stride);
10268 		  offs = fold_build2_loc (input_location, MINUS_EXPR,
10269 					  gfc_array_index_type, offs, tmp);
10270 		  offs = gfc_evaluate_now (offs, &block);
10271 		  gfc_conv_descriptor_offset_set (&block, desc, offs);
10272 
10273 		  /* Update stride.  */
10274 		  tmp = gfc_conv_array_extent_dim (lbound, ubound, NULL);
10275 		  stride = fold_build2_loc (input_location, MULT_EXPR,
10276 					    gfc_array_index_type, stride, tmp);
10277 		}
10278 	    }
10279 	  else
10280 	    {
10281 	      /* Bounds remapping.  Just shift the lower bounds.  */
10282 
10283 	      gcc_assert (expr1->rank == expr2->rank);
10284 
10285 	      for (dim = 0; dim < remap->u.ar.dimen; ++dim)
10286 		{
10287 		  gfc_se lbound_se;
10288 
10289 		  gcc_assert (!remap->u.ar.end[dim]);
10290 		  gfc_init_se (&lbound_se, NULL);
10291 		  if (remap->u.ar.start[dim])
10292 		    {
10293 		      gfc_conv_expr (&lbound_se, remap->u.ar.start[dim]);
10294 		      gfc_add_block_to_block (&block, &lbound_se.pre);
10295 		    }
10296 		  else
10297 		    /* This remap arises from a target that is not a whole
10298 		       array. The start expressions will be NULL but we need
10299 		       the lbounds to be one.  */
10300 		    lbound_se.expr = gfc_index_one_node;
10301 		  gfc_conv_shift_descriptor_lbound (&block, desc,
10302 						    dim, lbound_se.expr);
10303 		  gfc_add_block_to_block (&block, &lbound_se.post);
10304 		}
10305 	    }
10306 	}
10307 
10308       /* If rank remapping was done, check with -fcheck=bounds that
10309 	 the target is at least as large as the pointer.  */
10310       if (rank_remap && (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS))
10311 	{
10312 	  tree lsize, rsize;
10313 	  tree fault;
10314 	  const char* msg;
10315 
10316 	  lsize = gfc_conv_descriptor_size (lse.expr, expr1->rank);
10317 	  rsize = gfc_conv_descriptor_size (rse.expr, expr2->rank);
10318 
10319 	  lsize = gfc_evaluate_now (lsize, &block);
10320 	  rsize = gfc_evaluate_now (rsize, &block);
10321 	  fault = fold_build2_loc (input_location, LT_EXPR, logical_type_node,
10322 				   rsize, lsize);
10323 
10324 	  msg = _("Target of rank remapping is too small (%ld < %ld)");
10325 	  gfc_trans_runtime_check (true, false, fault, &block, &expr2->where,
10326 				   msg, rsize, lsize);
10327 	}
10328 
10329       /* Check string lengths if applicable.  The check is only really added
10330 	 to the output code if -fbounds-check is enabled.  */
10331       if (expr1->ts.type == BT_CHARACTER && expr2->expr_type != EXPR_NULL)
10332 	{
10333 	  gcc_assert (expr2->ts.type == BT_CHARACTER);
10334 	  gcc_assert (strlen_lhs && strlen_rhs);
10335 	  gfc_trans_same_strlen_check ("pointer assignment", &expr1->where,
10336 				       strlen_lhs, strlen_rhs, &block);
10337 	}
10338 
10339       gfc_add_block_to_block (&block, &lse.post);
10340       if (rank_remap)
10341 	gfc_add_block_to_block (&block, &rse.post);
10342     }
10343 
10344   return gfc_finish_block (&block);
10345 }
10346 
10347 
10348 /* Makes sure se is suitable for passing as a function string parameter.  */
10349 /* TODO: Need to check all callers of this function.  It may be abused.  */
10350 
10351 void
gfc_conv_string_parameter(gfc_se * se)10352 gfc_conv_string_parameter (gfc_se * se)
10353 {
10354   tree type;
10355 
10356   if (TREE_CODE (se->expr) == STRING_CST)
10357     {
10358       type = TREE_TYPE (TREE_TYPE (se->expr));
10359       se->expr = gfc_build_addr_expr (build_pointer_type (type), se->expr);
10360       return;
10361     }
10362 
10363   if ((TREE_CODE (TREE_TYPE (se->expr)) == ARRAY_TYPE
10364        || TREE_CODE (TREE_TYPE (se->expr)) == INTEGER_TYPE)
10365       && TYPE_STRING_FLAG (TREE_TYPE (se->expr)))
10366     {
10367       if (TREE_CODE (se->expr) != INDIRECT_REF)
10368 	{
10369 	  type = TREE_TYPE (se->expr);
10370           se->expr = gfc_build_addr_expr (build_pointer_type (type), se->expr);
10371 	}
10372       else
10373 	{
10374 	  type = gfc_get_character_type_len (gfc_default_character_kind,
10375 					     se->string_length);
10376 	  type = build_pointer_type (type);
10377 	  se->expr = gfc_build_addr_expr (type, se->expr);
10378 	}
10379     }
10380 
10381   gcc_assert (POINTER_TYPE_P (TREE_TYPE (se->expr)));
10382 }
10383 
10384 
10385 /* Generate code for assignment of scalar variables.  Includes character
10386    strings and derived types with allocatable components.
10387    If you know that the LHS has no allocations, set dealloc to false.
10388 
10389    DEEP_COPY has no effect if the typespec TS is not a derived type with
10390    allocatable components.  Otherwise, if it is set, an explicit copy of each
10391    allocatable component is made.  This is necessary as a simple copy of the
10392    whole object would copy array descriptors as is, so that the lhs's
10393    allocatable components would point to the rhs's after the assignment.
10394    Typically, setting DEEP_COPY is necessary if the rhs is a variable, and not
10395    necessary if the rhs is a non-pointer function, as the allocatable components
10396    are not accessible by other means than the function's result after the
10397    function has returned.  It is even more subtle when temporaries are involved,
10398    as the two following examples show:
10399     1.  When we evaluate an array constructor, a temporary is created.  Thus
10400       there is theoretically no alias possible.  However, no deep copy is
10401       made for this temporary, so that if the constructor is made of one or
10402       more variable with allocatable components, those components still point
10403       to the variable's: DEEP_COPY should be set for the assignment from the
10404       temporary to the lhs in that case.
10405     2.  When assigning a scalar to an array, we evaluate the scalar value out
10406       of the loop, store it into a temporary variable, and assign from that.
10407       In that case, deep copying when assigning to the temporary would be a
10408       waste of resources; however deep copies should happen when assigning from
10409       the temporary to each array element: again DEEP_COPY should be set for
10410       the assignment from the temporary to the lhs.  */
10411 
10412 tree
gfc_trans_scalar_assign(gfc_se * lse,gfc_se * rse,gfc_typespec ts,bool deep_copy,bool dealloc,bool in_coarray)10413 gfc_trans_scalar_assign (gfc_se * lse, gfc_se * rse, gfc_typespec ts,
10414 			 bool deep_copy, bool dealloc, bool in_coarray)
10415 {
10416   stmtblock_t block;
10417   tree tmp;
10418   tree cond;
10419 
10420   gfc_init_block (&block);
10421 
10422   if (ts.type == BT_CHARACTER)
10423     {
10424       tree rlen = NULL;
10425       tree llen = NULL;
10426 
10427       if (lse->string_length != NULL_TREE)
10428 	{
10429 	  gfc_conv_string_parameter (lse);
10430 	  gfc_add_block_to_block (&block, &lse->pre);
10431 	  llen = lse->string_length;
10432 	}
10433 
10434       if (rse->string_length != NULL_TREE)
10435 	{
10436 	  gfc_conv_string_parameter (rse);
10437 	  gfc_add_block_to_block (&block, &rse->pre);
10438 	  rlen = rse->string_length;
10439 	}
10440 
10441       gfc_trans_string_copy (&block, llen, lse->expr, ts.kind, rlen,
10442 			     rse->expr, ts.kind);
10443     }
10444   else if (gfc_bt_struct (ts.type)
10445 	   && (ts.u.derived->attr.alloc_comp
10446 		|| (deep_copy && ts.u.derived->attr.pdt_type)))
10447     {
10448       tree tmp_var = NULL_TREE;
10449       cond = NULL_TREE;
10450 
10451       /* Are the rhs and the lhs the same?  */
10452       if (deep_copy)
10453 	{
10454 	  cond = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
10455 				  gfc_build_addr_expr (NULL_TREE, lse->expr),
10456 				  gfc_build_addr_expr (NULL_TREE, rse->expr));
10457 	  cond = gfc_evaluate_now (cond, &lse->pre);
10458 	}
10459 
10460       /* Deallocate the lhs allocated components as long as it is not
10461 	 the same as the rhs.  This must be done following the assignment
10462 	 to prevent deallocating data that could be used in the rhs
10463 	 expression.  */
10464       if (dealloc)
10465 	{
10466 	  tmp_var = gfc_evaluate_now (lse->expr, &lse->pre);
10467 	  tmp = gfc_deallocate_alloc_comp_no_caf (ts.u.derived, tmp_var, 0);
10468 	  if (deep_copy)
10469 	    tmp = build3_v (COND_EXPR, cond, build_empty_stmt (input_location),
10470 			    tmp);
10471 	  gfc_add_expr_to_block (&lse->post, tmp);
10472 	}
10473 
10474       gfc_add_block_to_block (&block, &rse->pre);
10475       gfc_add_block_to_block (&block, &lse->pre);
10476 
10477       gfc_add_modify (&block, lse->expr,
10478 			   fold_convert (TREE_TYPE (lse->expr), rse->expr));
10479 
10480       /* Restore pointer address of coarray components.  */
10481       if (ts.u.derived->attr.coarray_comp && deep_copy && tmp_var != NULL_TREE)
10482 	{
10483 	  tmp = gfc_reassign_alloc_comp_caf (ts.u.derived, tmp_var, lse->expr);
10484 	  tmp = build3_v (COND_EXPR, cond, build_empty_stmt (input_location),
10485 			  tmp);
10486 	  gfc_add_expr_to_block (&block, tmp);
10487 	}
10488 
10489       /* Do a deep copy if the rhs is a variable, if it is not the
10490 	 same as the lhs.  */
10491       if (deep_copy)
10492 	{
10493 	  int caf_mode = in_coarray ? (GFC_STRUCTURE_CAF_MODE_ENABLE_COARRAY
10494 				       | GFC_STRUCTURE_CAF_MODE_IN_COARRAY) : 0;
10495 	  tmp = gfc_copy_alloc_comp (ts.u.derived, rse->expr, lse->expr, 0,
10496 				     caf_mode);
10497 	  tmp = build3_v (COND_EXPR, cond, build_empty_stmt (input_location),
10498 			  tmp);
10499 	  gfc_add_expr_to_block (&block, tmp);
10500 	}
10501     }
10502   else if (gfc_bt_struct (ts.type))
10503     {
10504       gfc_add_block_to_block (&block, &lse->pre);
10505       gfc_add_block_to_block (&block, &rse->pre);
10506       tmp = fold_build1_loc (input_location, VIEW_CONVERT_EXPR,
10507 			     TREE_TYPE (lse->expr), rse->expr);
10508       gfc_add_modify (&block, lse->expr, tmp);
10509     }
10510   /* If possible use the rhs vptr copy with trans_scalar_class_assign....  */
10511   else if (ts.type == BT_CLASS)
10512     {
10513       gfc_add_block_to_block (&block, &lse->pre);
10514       gfc_add_block_to_block (&block, &rse->pre);
10515 
10516       if (!trans_scalar_class_assign (&block, lse, rse))
10517 	{
10518 	  /* ...otherwise assignment suffices. Note the use of VIEW_CONVERT_EXPR
10519 	  for the lhs which ensures that class data rhs cast as a string assigns
10520 	  correctly.  */
10521 	  tmp = fold_build1_loc (input_location, VIEW_CONVERT_EXPR,
10522 				 TREE_TYPE (rse->expr), lse->expr);
10523 	  gfc_add_modify (&block, tmp, rse->expr);
10524 	}
10525     }
10526   else if (ts.type != BT_CLASS)
10527     {
10528       gfc_add_block_to_block (&block, &lse->pre);
10529       gfc_add_block_to_block (&block, &rse->pre);
10530 
10531       gfc_add_modify (&block, lse->expr,
10532 		      fold_convert (TREE_TYPE (lse->expr), rse->expr));
10533     }
10534 
10535   gfc_add_block_to_block (&block, &lse->post);
10536   gfc_add_block_to_block (&block, &rse->post);
10537 
10538   return gfc_finish_block (&block);
10539 }
10540 
10541 
10542 /* There are quite a lot of restrictions on the optimisation in using an
10543    array function assign without a temporary.  */
10544 
10545 static bool
arrayfunc_assign_needs_temporary(gfc_expr * expr1,gfc_expr * expr2)10546 arrayfunc_assign_needs_temporary (gfc_expr * expr1, gfc_expr * expr2)
10547 {
10548   gfc_ref * ref;
10549   bool seen_array_ref;
10550   bool c = false;
10551   gfc_symbol *sym = expr1->symtree->n.sym;
10552 
10553   /* Play it safe with class functions assigned to a derived type.  */
10554   if (gfc_is_class_array_function (expr2)
10555       && expr1->ts.type == BT_DERIVED)
10556     return true;
10557 
10558   /* The caller has already checked rank>0 and expr_type == EXPR_FUNCTION.  */
10559   if (expr2->value.function.isym && !gfc_is_intrinsic_libcall (expr2))
10560     return true;
10561 
10562   /* Elemental functions are scalarized so that they don't need a
10563      temporary in gfc_trans_assignment_1, so return a true.  Otherwise,
10564      they would need special treatment in gfc_trans_arrayfunc_assign.  */
10565   if (expr2->value.function.esym != NULL
10566       && expr2->value.function.esym->attr.elemental)
10567     return true;
10568 
10569   /* Need a temporary if rhs is not FULL or a contiguous section.  */
10570   if (expr1->ref && !(gfc_full_array_ref_p (expr1->ref, &c) || c))
10571     return true;
10572 
10573   /* Need a temporary if EXPR1 can't be expressed as a descriptor.  */
10574   if (gfc_ref_needs_temporary_p (expr1->ref))
10575     return true;
10576 
10577   /* Functions returning pointers or allocatables need temporaries.  */
10578   if (gfc_expr_attr (expr2).pointer
10579       || gfc_expr_attr (expr2).allocatable)
10580     return true;
10581 
10582   /* Character array functions need temporaries unless the
10583      character lengths are the same.  */
10584   if (expr2->ts.type == BT_CHARACTER && expr2->rank > 0)
10585     {
10586       if (expr1->ts.u.cl->length == NULL
10587 	    || expr1->ts.u.cl->length->expr_type != EXPR_CONSTANT)
10588 	return true;
10589 
10590       if (expr2->ts.u.cl->length == NULL
10591 	    || expr2->ts.u.cl->length->expr_type != EXPR_CONSTANT)
10592 	return true;
10593 
10594       if (mpz_cmp (expr1->ts.u.cl->length->value.integer,
10595 		     expr2->ts.u.cl->length->value.integer) != 0)
10596 	return true;
10597     }
10598 
10599   /* Check that no LHS component references appear during an array
10600      reference. This is needed because we do not have the means to
10601      span any arbitrary stride with an array descriptor. This check
10602      is not needed for the rhs because the function result has to be
10603      a complete type.  */
10604   seen_array_ref = false;
10605   for (ref = expr1->ref; ref; ref = ref->next)
10606     {
10607       if (ref->type == REF_ARRAY)
10608 	seen_array_ref= true;
10609       else if (ref->type == REF_COMPONENT && seen_array_ref)
10610 	return true;
10611     }
10612 
10613   /* Check for a dependency.  */
10614   if (gfc_check_fncall_dependency (expr1, INTENT_OUT,
10615 				   expr2->value.function.esym,
10616 				   expr2->value.function.actual,
10617 				   NOT_ELEMENTAL))
10618     return true;
10619 
10620   /* If we have reached here with an intrinsic function, we do not
10621      need a temporary except in the particular case that reallocation
10622      on assignment is active and the lhs is allocatable and a target,
10623      or a pointer which may be a subref pointer.  FIXME: The last
10624      condition can go away when we use span in the intrinsics
10625      directly.*/
10626   if (expr2->value.function.isym)
10627     return (flag_realloc_lhs && sym->attr.allocatable && sym->attr.target)
10628       || (sym->attr.pointer && sym->attr.subref_array_pointer);
10629 
10630   /* If the LHS is a dummy, we need a temporary if it is not
10631      INTENT(OUT).  */
10632   if (sym->attr.dummy && sym->attr.intent != INTENT_OUT)
10633     return true;
10634 
10635   /* If the lhs has been host_associated, is in common, a pointer or is
10636      a target and the function is not using a RESULT variable, aliasing
10637      can occur and a temporary is needed.  */
10638   if ((sym->attr.host_assoc
10639 	   || sym->attr.in_common
10640 	   || sym->attr.pointer
10641 	   || sym->attr.cray_pointee
10642 	   || sym->attr.target)
10643 	&& expr2->symtree != NULL
10644 	&& expr2->symtree->n.sym == expr2->symtree->n.sym->result)
10645     return true;
10646 
10647   /* A PURE function can unconditionally be called without a temporary.  */
10648   if (expr2->value.function.esym != NULL
10649       && expr2->value.function.esym->attr.pure)
10650     return false;
10651 
10652   /* Implicit_pure functions are those which could legally be declared
10653      to be PURE.  */
10654   if (expr2->value.function.esym != NULL
10655       && expr2->value.function.esym->attr.implicit_pure)
10656     return false;
10657 
10658   if (!sym->attr.use_assoc
10659 	&& !sym->attr.in_common
10660 	&& !sym->attr.pointer
10661 	&& !sym->attr.target
10662 	&& !sym->attr.cray_pointee
10663 	&& expr2->value.function.esym)
10664     {
10665       /* A temporary is not needed if the function is not contained and
10666 	 the variable is local or host associated and not a pointer or
10667 	 a target.  */
10668       if (!expr2->value.function.esym->attr.contained)
10669 	return false;
10670 
10671       /* A temporary is not needed if the lhs has never been host
10672 	 associated and the procedure is contained.  */
10673       else if (!sym->attr.host_assoc)
10674 	return false;
10675 
10676       /* A temporary is not needed if the variable is local and not
10677 	 a pointer, a target or a result.  */
10678       if (sym->ns->parent
10679 	    && expr2->value.function.esym->ns == sym->ns->parent)
10680 	return false;
10681     }
10682 
10683   /* Default to temporary use.  */
10684   return true;
10685 }
10686 
10687 
10688 /* Provide the loop info so that the lhs descriptor can be built for
10689    reallocatable assignments from extrinsic function calls.  */
10690 
10691 static void
realloc_lhs_loop_for_fcn_call(gfc_se * se,locus * where,gfc_ss ** ss,gfc_loopinfo * loop)10692 realloc_lhs_loop_for_fcn_call (gfc_se *se, locus *where, gfc_ss **ss,
10693 			       gfc_loopinfo *loop)
10694 {
10695   /* Signal that the function call should not be made by
10696      gfc_conv_loop_setup.  */
10697   se->ss->is_alloc_lhs = 1;
10698   gfc_init_loopinfo (loop);
10699   gfc_add_ss_to_loop (loop, *ss);
10700   gfc_add_ss_to_loop (loop, se->ss);
10701   gfc_conv_ss_startstride (loop);
10702   gfc_conv_loop_setup (loop, where);
10703   gfc_copy_loopinfo_to_se (se, loop);
10704   gfc_add_block_to_block (&se->pre, &loop->pre);
10705   gfc_add_block_to_block (&se->pre, &loop->post);
10706   se->ss->is_alloc_lhs = 0;
10707 }
10708 
10709 
10710 /* For assignment to a reallocatable lhs from intrinsic functions,
10711    replace the se.expr (ie. the result) with a temporary descriptor.
10712    Null the data field so that the library allocates space for the
10713    result. Free the data of the original descriptor after the function,
10714    in case it appears in an argument expression and transfer the
10715    result to the original descriptor.  */
10716 
10717 static void
fcncall_realloc_result(gfc_se * se,int rank)10718 fcncall_realloc_result (gfc_se *se, int rank)
10719 {
10720   tree desc;
10721   tree res_desc;
10722   tree tmp;
10723   tree offset;
10724   tree zero_cond;
10725   tree not_same_shape;
10726   stmtblock_t shape_block;
10727   int n;
10728 
10729   /* Use the allocation done by the library.  Substitute the lhs
10730      descriptor with a copy, whose data field is nulled.*/
10731   desc = build_fold_indirect_ref_loc (input_location, se->expr);
10732   if (POINTER_TYPE_P (TREE_TYPE (desc)))
10733     desc = build_fold_indirect_ref_loc (input_location, desc);
10734 
10735   /* Unallocated, the descriptor does not have a dtype.  */
10736   tmp = gfc_conv_descriptor_dtype (desc);
10737   gfc_add_modify (&se->pre, tmp, gfc_get_dtype (TREE_TYPE (desc)));
10738 
10739   res_desc = gfc_evaluate_now (desc, &se->pre);
10740   gfc_conv_descriptor_data_set (&se->pre, res_desc, null_pointer_node);
10741   se->expr = gfc_build_addr_expr (NULL_TREE, res_desc);
10742 
10743   /* Free the lhs after the function call and copy the result data to
10744      the lhs descriptor.  */
10745   tmp = gfc_conv_descriptor_data_get (desc);
10746   zero_cond = fold_build2_loc (input_location, EQ_EXPR,
10747 			       logical_type_node, tmp,
10748 			       build_int_cst (TREE_TYPE (tmp), 0));
10749   zero_cond = gfc_evaluate_now (zero_cond, &se->post);
10750   tmp = gfc_call_free (tmp);
10751   gfc_add_expr_to_block (&se->post, tmp);
10752 
10753   tmp = gfc_conv_descriptor_data_get (res_desc);
10754   gfc_conv_descriptor_data_set (&se->post, desc, tmp);
10755 
10756   /* Check that the shapes are the same between lhs and expression.
10757      The evaluation of the shape is done in 'shape_block' to avoid
10758      unitialized warnings from the lhs bounds. */
10759   not_same_shape = boolean_false_node;
10760   gfc_start_block (&shape_block);
10761   for (n = 0 ; n < rank; n++)
10762     {
10763       tree tmp1;
10764       tmp = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[n]);
10765       tmp1 = gfc_conv_descriptor_lbound_get (res_desc, gfc_rank_cst[n]);
10766       tmp = fold_build2_loc (input_location, MINUS_EXPR,
10767 			     gfc_array_index_type, tmp, tmp1);
10768       tmp1 = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[n]);
10769       tmp = fold_build2_loc (input_location, MINUS_EXPR,
10770 			     gfc_array_index_type, tmp, tmp1);
10771       tmp1 = gfc_conv_descriptor_ubound_get (res_desc, gfc_rank_cst[n]);
10772       tmp = fold_build2_loc (input_location, PLUS_EXPR,
10773 			     gfc_array_index_type, tmp, tmp1);
10774       tmp = fold_build2_loc (input_location, NE_EXPR,
10775 			     logical_type_node, tmp,
10776 			     gfc_index_zero_node);
10777       tmp = gfc_evaluate_now (tmp, &shape_block);
10778       if (n == 0)
10779 	not_same_shape = tmp;
10780       else
10781 	not_same_shape = fold_build2_loc (input_location, TRUTH_OR_EXPR,
10782 					  logical_type_node, tmp,
10783 					  not_same_shape);
10784     }
10785 
10786   /* 'zero_cond' being true is equal to lhs not being allocated or the
10787      shapes being different.  */
10788   tmp = fold_build2_loc (input_location, TRUTH_OR_EXPR, logical_type_node,
10789 			 zero_cond, not_same_shape);
10790   gfc_add_modify (&shape_block, zero_cond, tmp);
10791   tmp = gfc_finish_block (&shape_block);
10792   tmp = build3_v (COND_EXPR, zero_cond,
10793 		  build_empty_stmt (input_location), tmp);
10794   gfc_add_expr_to_block (&se->post, tmp);
10795 
10796   /* Now reset the bounds returned from the function call to bounds based
10797      on the lhs lbounds, except where the lhs is not allocated or the shapes
10798      of 'variable and 'expr' are different. Set the offset accordingly.  */
10799   offset = gfc_index_zero_node;
10800   for (n = 0 ; n < rank; n++)
10801     {
10802       tree lbound;
10803 
10804       lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[n]);
10805       lbound = fold_build3_loc (input_location, COND_EXPR,
10806 				gfc_array_index_type, zero_cond,
10807 				gfc_index_one_node, lbound);
10808       lbound = gfc_evaluate_now (lbound, &se->post);
10809 
10810       tmp = gfc_conv_descriptor_ubound_get (res_desc, gfc_rank_cst[n]);
10811       tmp = fold_build2_loc (input_location, PLUS_EXPR,
10812 			     gfc_array_index_type, tmp, lbound);
10813       gfc_conv_descriptor_lbound_set (&se->post, desc,
10814 				      gfc_rank_cst[n], lbound);
10815       gfc_conv_descriptor_ubound_set (&se->post, desc,
10816 				      gfc_rank_cst[n], tmp);
10817 
10818       /* Set stride and accumulate the offset.  */
10819       tmp = gfc_conv_descriptor_stride_get (res_desc, gfc_rank_cst[n]);
10820       gfc_conv_descriptor_stride_set (&se->post, desc,
10821 				      gfc_rank_cst[n], tmp);
10822       tmp = fold_build2_loc (input_location, MULT_EXPR,
10823 			     gfc_array_index_type, lbound, tmp);
10824       offset = fold_build2_loc (input_location, MINUS_EXPR,
10825 				gfc_array_index_type, offset, tmp);
10826       offset = gfc_evaluate_now (offset, &se->post);
10827     }
10828 
10829   gfc_conv_descriptor_offset_set (&se->post, desc, offset);
10830 }
10831 
10832 
10833 
10834 /* Try to translate array(:) = func (...), where func is a transformational
10835    array function, without using a temporary.  Returns NULL if this isn't the
10836    case.  */
10837 
10838 static tree
gfc_trans_arrayfunc_assign(gfc_expr * expr1,gfc_expr * expr2)10839 gfc_trans_arrayfunc_assign (gfc_expr * expr1, gfc_expr * expr2)
10840 {
10841   gfc_se se;
10842   gfc_ss *ss = NULL;
10843   gfc_component *comp = NULL;
10844   gfc_loopinfo loop;
10845 
10846   if (arrayfunc_assign_needs_temporary (expr1, expr2))
10847     return NULL;
10848 
10849   /* The frontend doesn't seem to bother filling in expr->symtree for intrinsic
10850      functions.  */
10851   comp = gfc_get_proc_ptr_comp (expr2);
10852 
10853   if (!(expr2->value.function.isym
10854 	      || (comp && comp->attr.dimension)
10855 	      || (!comp && gfc_return_by_reference (expr2->value.function.esym)
10856 		  && expr2->value.function.esym->result->attr.dimension)))
10857     return NULL;
10858 
10859   gfc_init_se (&se, NULL);
10860   gfc_start_block (&se.pre);
10861   se.want_pointer = 1;
10862 
10863   gfc_conv_array_parameter (&se, expr1, false, NULL, NULL, NULL);
10864 
10865   if (expr1->ts.type == BT_DERIVED
10866 	&& expr1->ts.u.derived->attr.alloc_comp)
10867     {
10868       tree tmp;
10869       tmp = gfc_deallocate_alloc_comp_no_caf (expr1->ts.u.derived, se.expr,
10870 					      expr1->rank);
10871       gfc_add_expr_to_block (&se.pre, tmp);
10872     }
10873 
10874   se.direct_byref = 1;
10875   se.ss = gfc_walk_expr (expr2);
10876   gcc_assert (se.ss != gfc_ss_terminator);
10877 
10878   /* Reallocate on assignment needs the loopinfo for extrinsic functions.
10879      This is signalled to gfc_conv_procedure_call by setting is_alloc_lhs.
10880      Clearly, this cannot be done for an allocatable function result, since
10881      the shape of the result is unknown and, in any case, the function must
10882      correctly take care of the reallocation internally. For intrinsic
10883      calls, the array data is freed and the library takes care of allocation.
10884      TODO: Add logic of trans-array.cc: gfc_alloc_allocatable_for_assignment
10885      to the library.  */
10886   if (flag_realloc_lhs
10887 	&& gfc_is_reallocatable_lhs (expr1)
10888 	&& !gfc_expr_attr (expr1).codimension
10889 	&& !gfc_is_coindexed (expr1)
10890 	&& !(expr2->value.function.esym
10891 	    && expr2->value.function.esym->result->attr.allocatable))
10892     {
10893       realloc_lhs_warning (expr1->ts.type, true, &expr1->where);
10894 
10895       if (!expr2->value.function.isym)
10896 	{
10897 	  ss = gfc_walk_expr (expr1);
10898 	  gcc_assert (ss != gfc_ss_terminator);
10899 
10900 	  realloc_lhs_loop_for_fcn_call (&se, &expr1->where, &ss, &loop);
10901 	  ss->is_alloc_lhs = 1;
10902 	}
10903       else
10904 	fcncall_realloc_result (&se, expr1->rank);
10905     }
10906 
10907   gfc_conv_function_expr (&se, expr2);
10908   gfc_add_block_to_block (&se.pre, &se.post);
10909 
10910   if (ss)
10911     gfc_cleanup_loop (&loop);
10912   else
10913     gfc_free_ss_chain (se.ss);
10914 
10915   return gfc_finish_block (&se.pre);
10916 }
10917 
10918 
10919 /* Try to efficiently translate array(:) = 0.  Return NULL if this
10920    can't be done.  */
10921 
10922 static tree
gfc_trans_zero_assign(gfc_expr * expr)10923 gfc_trans_zero_assign (gfc_expr * expr)
10924 {
10925   tree dest, len, type;
10926   tree tmp;
10927   gfc_symbol *sym;
10928 
10929   sym = expr->symtree->n.sym;
10930   dest = gfc_get_symbol_decl (sym);
10931 
10932   type = TREE_TYPE (dest);
10933   if (POINTER_TYPE_P (type))
10934     type = TREE_TYPE (type);
10935   if (!GFC_ARRAY_TYPE_P (type))
10936     return NULL_TREE;
10937 
10938   /* Determine the length of the array.  */
10939   len = GFC_TYPE_ARRAY_SIZE (type);
10940   if (!len || TREE_CODE (len) != INTEGER_CST)
10941     return NULL_TREE;
10942 
10943   tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type));
10944   len = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type, len,
10945 			 fold_convert (gfc_array_index_type, tmp));
10946 
10947   /* If we are zeroing a local array avoid taking its address by emitting
10948      a = {} instead.  */
10949   if (!POINTER_TYPE_P (TREE_TYPE (dest)))
10950     return build2_loc (input_location, MODIFY_EXPR, void_type_node,
10951 		       dest, build_constructor (TREE_TYPE (dest),
10952 					      NULL));
10953 
10954   /* Convert arguments to the correct types.  */
10955   dest = fold_convert (pvoid_type_node, dest);
10956   len = fold_convert (size_type_node, len);
10957 
10958   /* Construct call to __builtin_memset.  */
10959   tmp = build_call_expr_loc (input_location,
10960 			     builtin_decl_explicit (BUILT_IN_MEMSET),
10961 			     3, dest, integer_zero_node, len);
10962   return fold_convert (void_type_node, tmp);
10963 }
10964 
10965 
10966 /* Helper for gfc_trans_array_copy and gfc_trans_array_constructor_copy
10967    that constructs the call to __builtin_memcpy.  */
10968 
10969 tree
gfc_build_memcpy_call(tree dst,tree src,tree len)10970 gfc_build_memcpy_call (tree dst, tree src, tree len)
10971 {
10972   tree tmp;
10973 
10974   /* Convert arguments to the correct types.  */
10975   if (!POINTER_TYPE_P (TREE_TYPE (dst)))
10976     dst = gfc_build_addr_expr (pvoid_type_node, dst);
10977   else
10978     dst = fold_convert (pvoid_type_node, dst);
10979 
10980   if (!POINTER_TYPE_P (TREE_TYPE (src)))
10981     src = gfc_build_addr_expr (pvoid_type_node, src);
10982   else
10983     src = fold_convert (pvoid_type_node, src);
10984 
10985   len = fold_convert (size_type_node, len);
10986 
10987   /* Construct call to __builtin_memcpy.  */
10988   tmp = build_call_expr_loc (input_location,
10989 			     builtin_decl_explicit (BUILT_IN_MEMCPY),
10990 			     3, dst, src, len);
10991   return fold_convert (void_type_node, tmp);
10992 }
10993 
10994 
10995 /* Try to efficiently translate dst(:) = src(:).  Return NULL if this
10996    can't be done.  EXPR1 is the destination/lhs and EXPR2 is the
10997    source/rhs, both are gfc_full_array_ref_p which have been checked for
10998    dependencies.  */
10999 
11000 static tree
gfc_trans_array_copy(gfc_expr * expr1,gfc_expr * expr2)11001 gfc_trans_array_copy (gfc_expr * expr1, gfc_expr * expr2)
11002 {
11003   tree dst, dlen, dtype;
11004   tree src, slen, stype;
11005   tree tmp;
11006 
11007   dst = gfc_get_symbol_decl (expr1->symtree->n.sym);
11008   src = gfc_get_symbol_decl (expr2->symtree->n.sym);
11009 
11010   dtype = TREE_TYPE (dst);
11011   if (POINTER_TYPE_P (dtype))
11012     dtype = TREE_TYPE (dtype);
11013   stype = TREE_TYPE (src);
11014   if (POINTER_TYPE_P (stype))
11015     stype = TREE_TYPE (stype);
11016 
11017   if (!GFC_ARRAY_TYPE_P (dtype) || !GFC_ARRAY_TYPE_P (stype))
11018     return NULL_TREE;
11019 
11020   /* Determine the lengths of the arrays.  */
11021   dlen = GFC_TYPE_ARRAY_SIZE (dtype);
11022   if (!dlen || TREE_CODE (dlen) != INTEGER_CST)
11023     return NULL_TREE;
11024   tmp = TYPE_SIZE_UNIT (gfc_get_element_type (dtype));
11025   dlen = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
11026 			  dlen, fold_convert (gfc_array_index_type, tmp));
11027 
11028   slen = GFC_TYPE_ARRAY_SIZE (stype);
11029   if (!slen || TREE_CODE (slen) != INTEGER_CST)
11030     return NULL_TREE;
11031   tmp = TYPE_SIZE_UNIT (gfc_get_element_type (stype));
11032   slen = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
11033 			  slen, fold_convert (gfc_array_index_type, tmp));
11034 
11035   /* Sanity check that they are the same.  This should always be
11036      the case, as we should already have checked for conformance.  */
11037   if (!tree_int_cst_equal (slen, dlen))
11038     return NULL_TREE;
11039 
11040   return gfc_build_memcpy_call (dst, src, dlen);
11041 }
11042 
11043 
11044 /* Try to efficiently translate array(:) = (/ ... /).  Return NULL if
11045    this can't be done.  EXPR1 is the destination/lhs for which
11046    gfc_full_array_ref_p is true, and EXPR2 is the source/rhs.  */
11047 
11048 static tree
gfc_trans_array_constructor_copy(gfc_expr * expr1,gfc_expr * expr2)11049 gfc_trans_array_constructor_copy (gfc_expr * expr1, gfc_expr * expr2)
11050 {
11051   unsigned HOST_WIDE_INT nelem;
11052   tree dst, dtype;
11053   tree src, stype;
11054   tree len;
11055   tree tmp;
11056 
11057   nelem = gfc_constant_array_constructor_p (expr2->value.constructor);
11058   if (nelem == 0)
11059     return NULL_TREE;
11060 
11061   dst = gfc_get_symbol_decl (expr1->symtree->n.sym);
11062   dtype = TREE_TYPE (dst);
11063   if (POINTER_TYPE_P (dtype))
11064     dtype = TREE_TYPE (dtype);
11065   if (!GFC_ARRAY_TYPE_P (dtype))
11066     return NULL_TREE;
11067 
11068   /* Determine the lengths of the array.  */
11069   len = GFC_TYPE_ARRAY_SIZE (dtype);
11070   if (!len || TREE_CODE (len) != INTEGER_CST)
11071     return NULL_TREE;
11072 
11073   /* Confirm that the constructor is the same size.  */
11074   if (compare_tree_int (len, nelem) != 0)
11075     return NULL_TREE;
11076 
11077   tmp = TYPE_SIZE_UNIT (gfc_get_element_type (dtype));
11078   len = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type, len,
11079 			 fold_convert (gfc_array_index_type, tmp));
11080 
11081   stype = gfc_typenode_for_spec (&expr2->ts);
11082   src = gfc_build_constant_array_constructor (expr2, stype);
11083 
11084   return gfc_build_memcpy_call (dst, src, len);
11085 }
11086 
11087 
11088 /* Tells whether the expression is to be treated as a variable reference.  */
11089 
11090 bool
gfc_expr_is_variable(gfc_expr * expr)11091 gfc_expr_is_variable (gfc_expr *expr)
11092 {
11093   gfc_expr *arg;
11094   gfc_component *comp;
11095   gfc_symbol *func_ifc;
11096 
11097   if (expr->expr_type == EXPR_VARIABLE)
11098     return true;
11099 
11100   arg = gfc_get_noncopying_intrinsic_argument (expr);
11101   if (arg)
11102     {
11103       gcc_assert (expr->value.function.isym->id == GFC_ISYM_TRANSPOSE);
11104       return gfc_expr_is_variable (arg);
11105     }
11106 
11107   /* A data-pointer-returning function should be considered as a variable
11108      too.  */
11109   if (expr->expr_type == EXPR_FUNCTION
11110       && expr->ref == NULL)
11111     {
11112       if (expr->value.function.isym != NULL)
11113 	return false;
11114 
11115       if (expr->value.function.esym != NULL)
11116 	{
11117 	  func_ifc = expr->value.function.esym;
11118 	  goto found_ifc;
11119 	}
11120       gcc_assert (expr->symtree);
11121       func_ifc = expr->symtree->n.sym;
11122       goto found_ifc;
11123     }
11124 
11125   comp = gfc_get_proc_ptr_comp (expr);
11126   if ((expr->expr_type == EXPR_PPC || expr->expr_type == EXPR_FUNCTION)
11127       && comp)
11128     {
11129       func_ifc = comp->ts.interface;
11130       goto found_ifc;
11131     }
11132 
11133   if (expr->expr_type == EXPR_COMPCALL)
11134     {
11135       gcc_assert (!expr->value.compcall.tbp->is_generic);
11136       func_ifc = expr->value.compcall.tbp->u.specific->n.sym;
11137       goto found_ifc;
11138     }
11139 
11140   return false;
11141 
11142 found_ifc:
11143   gcc_assert (func_ifc->attr.function
11144 	      && func_ifc->result != NULL);
11145   return func_ifc->result->attr.pointer;
11146 }
11147 
11148 
11149 /* Is the lhs OK for automatic reallocation?  */
11150 
11151 static bool
is_scalar_reallocatable_lhs(gfc_expr * expr)11152 is_scalar_reallocatable_lhs (gfc_expr *expr)
11153 {
11154   gfc_ref * ref;
11155 
11156   /* An allocatable variable with no reference.  */
11157   if (expr->symtree->n.sym->attr.allocatable
11158 	&& !expr->ref)
11159     return true;
11160 
11161   /* All that can be left are allocatable components.  However, we do
11162      not check for allocatable components here because the expression
11163      could be an allocatable component of a pointer component.  */
11164   if (expr->symtree->n.sym->ts.type != BT_DERIVED
11165 	&& expr->symtree->n.sym->ts.type != BT_CLASS)
11166     return false;
11167 
11168   /* Find an allocatable component ref last.  */
11169   for (ref = expr->ref; ref; ref = ref->next)
11170     if (ref->type == REF_COMPONENT
11171 	  && !ref->next
11172 	  && ref->u.c.component->attr.allocatable)
11173       return true;
11174 
11175   return false;
11176 }
11177 
11178 
11179 /* Allocate or reallocate scalar lhs, as necessary.  */
11180 
11181 static void
alloc_scalar_allocatable_for_assignment(stmtblock_t * block,tree string_length,gfc_expr * expr1,gfc_expr * expr2)11182 alloc_scalar_allocatable_for_assignment (stmtblock_t *block,
11183 					 tree string_length,
11184 					 gfc_expr *expr1,
11185 					 gfc_expr *expr2)
11186 
11187 {
11188   tree cond;
11189   tree tmp;
11190   tree size;
11191   tree size_in_bytes;
11192   tree jump_label1;
11193   tree jump_label2;
11194   gfc_se lse;
11195   gfc_ref *ref;
11196 
11197   if (!expr1 || expr1->rank)
11198     return;
11199 
11200   if (!expr2 || expr2->rank)
11201     return;
11202 
11203   for (ref = expr1->ref; ref; ref = ref->next)
11204     if (ref->type == REF_SUBSTRING)
11205       return;
11206 
11207   realloc_lhs_warning (expr2->ts.type, false, &expr2->where);
11208 
11209   /* Since this is a scalar lhs, we can afford to do this.  That is,
11210      there is no risk of side effects being repeated.  */
11211   gfc_init_se (&lse, NULL);
11212   lse.want_pointer = 1;
11213   gfc_conv_expr (&lse, expr1);
11214 
11215   jump_label1 = gfc_build_label_decl (NULL_TREE);
11216   jump_label2 = gfc_build_label_decl (NULL_TREE);
11217 
11218   /* Do the allocation if the lhs is NULL. Otherwise go to label 1.  */
11219   tmp = build_int_cst (TREE_TYPE (lse.expr), 0);
11220   cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
11221 			  lse.expr, tmp);
11222   tmp = build3_v (COND_EXPR, cond,
11223 		  build1_v (GOTO_EXPR, jump_label1),
11224 		  build_empty_stmt (input_location));
11225   gfc_add_expr_to_block (block, tmp);
11226 
11227   if (expr1->ts.type == BT_CHARACTER && expr1->ts.deferred)
11228     {
11229       /* Use the rhs string length and the lhs element size.  */
11230       size = string_length;
11231       tmp = TREE_TYPE (gfc_typenode_for_spec (&expr1->ts));
11232       tmp = TYPE_SIZE_UNIT (tmp);
11233       size_in_bytes = fold_build2_loc (input_location, MULT_EXPR,
11234 				       TREE_TYPE (tmp), tmp,
11235 				       fold_convert (TREE_TYPE (tmp), size));
11236     }
11237   else
11238     {
11239       /* Otherwise use the length in bytes of the rhs.  */
11240       size = TYPE_SIZE_UNIT (gfc_typenode_for_spec (&expr1->ts));
11241       size_in_bytes = size;
11242     }
11243 
11244   size_in_bytes = fold_build2_loc (input_location, MAX_EXPR, size_type_node,
11245 				   size_in_bytes, size_one_node);
11246 
11247   if (gfc_caf_attr (expr1).codimension && flag_coarray == GFC_FCOARRAY_LIB)
11248     {
11249       tree caf_decl, token;
11250       gfc_se caf_se;
11251       symbol_attribute attr;
11252 
11253       gfc_clear_attr (&attr);
11254       gfc_init_se (&caf_se, NULL);
11255 
11256       caf_decl = gfc_get_tree_for_caf_expr (expr1);
11257       gfc_get_caf_token_offset (&caf_se, &token, NULL, caf_decl, NULL_TREE,
11258 				NULL);
11259       gfc_add_block_to_block (block, &caf_se.pre);
11260       gfc_allocate_allocatable (block, lse.expr, size_in_bytes,
11261 				gfc_build_addr_expr (NULL_TREE, token),
11262 				NULL_TREE, NULL_TREE, NULL_TREE, jump_label1,
11263 				expr1, 1);
11264     }
11265   else if (expr1->ts.type == BT_DERIVED && expr1->ts.u.derived->attr.alloc_comp)
11266     {
11267       tmp = build_call_expr_loc (input_location,
11268 				 builtin_decl_explicit (BUILT_IN_CALLOC),
11269 				 2, build_one_cst (size_type_node),
11270 				 size_in_bytes);
11271       tmp = fold_convert (TREE_TYPE (lse.expr), tmp);
11272       gfc_add_modify (block, lse.expr, tmp);
11273     }
11274   else
11275     {
11276       tmp = build_call_expr_loc (input_location,
11277 				 builtin_decl_explicit (BUILT_IN_MALLOC),
11278 				 1, size_in_bytes);
11279       tmp = fold_convert (TREE_TYPE (lse.expr), tmp);
11280       gfc_add_modify (block, lse.expr, tmp);
11281     }
11282 
11283   if (expr1->ts.type == BT_CHARACTER && expr1->ts.deferred)
11284     {
11285       /* Deferred characters need checking for lhs and rhs string
11286 	 length.  Other deferred parameter variables will have to
11287 	 come here too.  */
11288       tmp = build1_v (GOTO_EXPR, jump_label2);
11289       gfc_add_expr_to_block (block, tmp);
11290     }
11291   tmp = build1_v (LABEL_EXPR, jump_label1);
11292   gfc_add_expr_to_block (block, tmp);
11293 
11294   /* For a deferred length character, reallocate if lengths of lhs and
11295      rhs are different.  */
11296   if (expr1->ts.type == BT_CHARACTER && expr1->ts.deferred)
11297     {
11298       cond = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
11299 			      lse.string_length,
11300 			      fold_convert (TREE_TYPE (lse.string_length),
11301 					    size));
11302       /* Jump past the realloc if the lengths are the same.  */
11303       tmp = build3_v (COND_EXPR, cond,
11304 		      build1_v (GOTO_EXPR, jump_label2),
11305 		      build_empty_stmt (input_location));
11306       gfc_add_expr_to_block (block, tmp);
11307       tmp = build_call_expr_loc (input_location,
11308 				 builtin_decl_explicit (BUILT_IN_REALLOC),
11309 				 2, fold_convert (pvoid_type_node, lse.expr),
11310 				 size_in_bytes);
11311       tmp = fold_convert (TREE_TYPE (lse.expr), tmp);
11312       gfc_add_modify (block, lse.expr, tmp);
11313       tmp = build1_v (LABEL_EXPR, jump_label2);
11314       gfc_add_expr_to_block (block, tmp);
11315 
11316       /* Update the lhs character length.  */
11317       size = string_length;
11318       gfc_add_modify (block, lse.string_length,
11319 		      fold_convert (TREE_TYPE (lse.string_length), size));
11320     }
11321 }
11322 
11323 /* Check for assignments of the type
11324 
11325    a = a + 4
11326 
11327    to make sure we do not check for reallocation unneccessarily.  */
11328 
11329 
11330 static bool
is_runtime_conformable(gfc_expr * expr1,gfc_expr * expr2)11331 is_runtime_conformable (gfc_expr *expr1, gfc_expr *expr2)
11332 {
11333   gfc_actual_arglist *a;
11334   gfc_expr *e1, *e2;
11335 
11336   switch (expr2->expr_type)
11337     {
11338     case EXPR_VARIABLE:
11339       return gfc_dep_compare_expr (expr1, expr2) == 0;
11340 
11341     case EXPR_FUNCTION:
11342       if (expr2->value.function.esym
11343 	  && expr2->value.function.esym->attr.elemental)
11344 	{
11345 	  for (a = expr2->value.function.actual; a != NULL; a = a->next)
11346 	    {
11347 	      e1 = a->expr;
11348 	      if (e1 && e1->rank > 0 && !is_runtime_conformable (expr1, e1))
11349 		return false;
11350 	    }
11351 	  return true;
11352 	}
11353       else if (expr2->value.function.isym
11354 	       && expr2->value.function.isym->elemental)
11355 	{
11356 	  for (a = expr2->value.function.actual; a != NULL; a = a->next)
11357 	    {
11358 	      e1 = a->expr;
11359 	      if (e1 && e1->rank > 0 && !is_runtime_conformable (expr1, e1))
11360 		return false;
11361 	    }
11362 	  return true;
11363 	}
11364 
11365       break;
11366 
11367     case EXPR_OP:
11368       switch (expr2->value.op.op)
11369 	{
11370 	case INTRINSIC_NOT:
11371 	case INTRINSIC_UPLUS:
11372 	case INTRINSIC_UMINUS:
11373 	case INTRINSIC_PARENTHESES:
11374 	  return is_runtime_conformable (expr1, expr2->value.op.op1);
11375 
11376 	case INTRINSIC_PLUS:
11377 	case INTRINSIC_MINUS:
11378 	case INTRINSIC_TIMES:
11379 	case INTRINSIC_DIVIDE:
11380 	case INTRINSIC_POWER:
11381 	case INTRINSIC_AND:
11382 	case INTRINSIC_OR:
11383 	case INTRINSIC_EQV:
11384 	case INTRINSIC_NEQV:
11385 	case INTRINSIC_EQ:
11386 	case INTRINSIC_NE:
11387 	case INTRINSIC_GT:
11388 	case INTRINSIC_GE:
11389 	case INTRINSIC_LT:
11390 	case INTRINSIC_LE:
11391 	case INTRINSIC_EQ_OS:
11392 	case INTRINSIC_NE_OS:
11393 	case INTRINSIC_GT_OS:
11394 	case INTRINSIC_GE_OS:
11395 	case INTRINSIC_LT_OS:
11396 	case INTRINSIC_LE_OS:
11397 
11398 	  e1 = expr2->value.op.op1;
11399 	  e2 = expr2->value.op.op2;
11400 
11401 	  if (e1->rank == 0 && e2->rank > 0)
11402 	    return is_runtime_conformable (expr1, e2);
11403 	  else if (e1->rank > 0 && e2->rank == 0)
11404 	    return is_runtime_conformable (expr1, e1);
11405 	  else if (e1->rank > 0 && e2->rank > 0)
11406 	    return is_runtime_conformable (expr1, e1)
11407 	      && is_runtime_conformable (expr1, e2);
11408 	  break;
11409 
11410 	default:
11411 	  break;
11412 
11413 	}
11414 
11415       break;
11416 
11417     default:
11418       break;
11419     }
11420   return false;
11421 }
11422 
11423 
11424 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)11425 trans_class_assignment (stmtblock_t *block, gfc_expr *lhs, gfc_expr *rhs,
11426 			gfc_se *lse, gfc_se *rse, bool use_vptr_copy,
11427 			bool class_realloc)
11428 {
11429   tree tmp, fcn, stdcopy, to_len, from_len, vptr, old_vptr;
11430   vec<tree, va_gc> *args = NULL;
11431 
11432   /* Store the old vptr so that dynamic types can be compared for
11433      reallocation to occur or not.  */
11434   if (class_realloc)
11435     {
11436       tmp = lse->expr;
11437       if (!GFC_CLASS_TYPE_P (TREE_TYPE (tmp)))
11438 	tmp = gfc_get_class_from_expr (tmp);
11439     }
11440 
11441   vptr = trans_class_vptr_len_assignment (block, lhs, rhs, rse, &to_len,
11442 					 &from_len);
11443 
11444   /* Generate (re)allocation of the lhs.  */
11445   if (class_realloc)
11446     {
11447       stmtblock_t alloc, re_alloc;
11448       tree class_han, re, size;
11449 
11450       if (tmp && GFC_CLASS_TYPE_P (TREE_TYPE (tmp)))
11451 	old_vptr = gfc_evaluate_now (gfc_class_vptr_get (tmp), block);
11452       else
11453 	old_vptr = build_int_cst (TREE_TYPE (vptr), 0);
11454 
11455       size = gfc_vptr_size_get (vptr);
11456       class_han = GFC_CLASS_TYPE_P (TREE_TYPE (lse->expr))
11457 	  ? gfc_class_data_get (lse->expr) : lse->expr;
11458 
11459       if (!POINTER_TYPE_P (TREE_TYPE (class_han)))
11460 	class_han = gfc_build_addr_expr (NULL_TREE, class_han);
11461 
11462       /* Allocate block.  */
11463       gfc_init_block (&alloc);
11464       gfc_allocate_using_malloc (&alloc, class_han, size, NULL_TREE);
11465 
11466       /* Reallocate if dynamic types are different. */
11467       gfc_init_block (&re_alloc);
11468       re = build_call_expr_loc (input_location,
11469 				builtin_decl_explicit (BUILT_IN_REALLOC), 2,
11470 				fold_convert (pvoid_type_node, class_han),
11471 				size);
11472       tmp = fold_build2_loc (input_location, NE_EXPR,
11473 			     logical_type_node, vptr, old_vptr);
11474       re = fold_build3_loc (input_location, COND_EXPR, void_type_node,
11475 			    tmp, re, build_empty_stmt (input_location));
11476       gfc_add_expr_to_block (&re_alloc, re);
11477 
11478       /* Allocate if _data is NULL, reallocate otherwise.  */
11479       tmp = fold_build2_loc (input_location, EQ_EXPR,
11480 			     logical_type_node, class_han,
11481 			     build_int_cst (prvoid_type_node, 0));
11482       tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
11483 			     gfc_unlikely (tmp,
11484 					   PRED_FORTRAN_FAIL_ALLOC),
11485 			     gfc_finish_block (&alloc),
11486 			     gfc_finish_block (&re_alloc));
11487       gfc_add_expr_to_block (&lse->pre, tmp);
11488     }
11489 
11490   fcn = gfc_vptr_copy_get (vptr);
11491 
11492   tmp = GFC_CLASS_TYPE_P (TREE_TYPE (rse->expr))
11493       ? gfc_class_data_get (rse->expr) : rse->expr;
11494   if (use_vptr_copy)
11495     {
11496       if (!POINTER_TYPE_P (TREE_TYPE (tmp))
11497 	  || INDIRECT_REF_P (tmp)
11498 	  || (rhs->ts.type == BT_DERIVED
11499 	      && rhs->ts.u.derived->attr.unlimited_polymorphic
11500 	      && !rhs->ts.u.derived->attr.pointer
11501 	      && !rhs->ts.u.derived->attr.allocatable)
11502 	  || (UNLIMITED_POLY (rhs)
11503 	      && !CLASS_DATA (rhs)->attr.pointer
11504 	      && !CLASS_DATA (rhs)->attr.allocatable))
11505 	vec_safe_push (args, gfc_build_addr_expr (NULL_TREE, tmp));
11506       else
11507 	vec_safe_push (args, tmp);
11508       tmp = GFC_CLASS_TYPE_P (TREE_TYPE (lse->expr))
11509 	  ? gfc_class_data_get (lse->expr) : lse->expr;
11510       if (!POINTER_TYPE_P (TREE_TYPE (tmp))
11511 	  || INDIRECT_REF_P (tmp)
11512 	  || (lhs->ts.type == BT_DERIVED
11513 	      && lhs->ts.u.derived->attr.unlimited_polymorphic
11514 	      && !lhs->ts.u.derived->attr.pointer
11515 	      && !lhs->ts.u.derived->attr.allocatable)
11516 	  || (UNLIMITED_POLY (lhs)
11517 	      && !CLASS_DATA (lhs)->attr.pointer
11518 	      && !CLASS_DATA (lhs)->attr.allocatable))
11519 	vec_safe_push (args, gfc_build_addr_expr (NULL_TREE, tmp));
11520       else
11521 	vec_safe_push (args, tmp);
11522 
11523       stdcopy = build_call_vec (TREE_TYPE (TREE_TYPE (fcn)), fcn, args);
11524 
11525       if (to_len != NULL_TREE && !integer_zerop (from_len))
11526 	{
11527 	  tree extcopy;
11528 	  vec_safe_push (args, from_len);
11529 	  vec_safe_push (args, to_len);
11530 	  extcopy = build_call_vec (TREE_TYPE (TREE_TYPE (fcn)), fcn, args);
11531 
11532 	  tmp = fold_build2_loc (input_location, GT_EXPR,
11533 				 logical_type_node, from_len,
11534 				 build_zero_cst (TREE_TYPE (from_len)));
11535 	  return fold_build3_loc (input_location, COND_EXPR,
11536 				  void_type_node, tmp,
11537 				  extcopy, stdcopy);
11538 	}
11539       else
11540 	return stdcopy;
11541     }
11542   else
11543     {
11544       tree rhst = GFC_CLASS_TYPE_P (TREE_TYPE (lse->expr))
11545 	  ? gfc_class_data_get (lse->expr) : lse->expr;
11546       stmtblock_t tblock;
11547       gfc_init_block (&tblock);
11548       if (!POINTER_TYPE_P (TREE_TYPE (tmp)))
11549 	tmp = gfc_build_addr_expr (NULL_TREE, tmp);
11550       if (!POINTER_TYPE_P (TREE_TYPE (rhst)))
11551 	rhst = gfc_build_addr_expr (NULL_TREE, rhst);
11552       /* When coming from a ptr_copy lhs and rhs are swapped.  */
11553       gfc_add_modify_loc (input_location, &tblock, rhst,
11554 			  fold_convert (TREE_TYPE (rhst), tmp));
11555       return gfc_finish_block (&tblock);
11556     }
11557 }
11558 
11559 /* Subroutine of gfc_trans_assignment that actually scalarizes the
11560    assignment.  EXPR1 is the destination/LHS and EXPR2 is the source/RHS.
11561    init_flag indicates initialization expressions and dealloc that no
11562    deallocate prior assignment is needed (if in doubt, set true).
11563    When PTR_COPY is set and expr1 is a class type, then use the _vptr-copy
11564    routine instead of a pointer assignment.  Alias resolution is only done,
11565    when MAY_ALIAS is set (the default).  This flag is used by ALLOCATE()
11566    where it is known, that newly allocated memory on the lhs can never be
11567    an alias of the rhs.  */
11568 
11569 static tree
gfc_trans_assignment_1(gfc_expr * expr1,gfc_expr * expr2,bool init_flag,bool dealloc,bool use_vptr_copy,bool may_alias)11570 gfc_trans_assignment_1 (gfc_expr * expr1, gfc_expr * expr2, bool init_flag,
11571 			bool dealloc, bool use_vptr_copy, bool may_alias)
11572 {
11573   gfc_se lse;
11574   gfc_se rse;
11575   gfc_ss *lss;
11576   gfc_ss *lss_section;
11577   gfc_ss *rss;
11578   gfc_loopinfo loop;
11579   tree tmp;
11580   stmtblock_t block;
11581   stmtblock_t body;
11582   bool l_is_temp;
11583   bool scalar_to_array;
11584   tree string_length;
11585   int n;
11586   bool maybe_workshare = false, lhs_refs_comp = false, rhs_refs_comp = false;
11587   symbol_attribute lhs_caf_attr, rhs_caf_attr, lhs_attr;
11588   bool is_poly_assign;
11589   bool realloc_flag;
11590 
11591   /* Assignment of the form lhs = rhs.  */
11592   gfc_start_block (&block);
11593 
11594   gfc_init_se (&lse, NULL);
11595   gfc_init_se (&rse, NULL);
11596 
11597   /* Walk the lhs.  */
11598   lss = gfc_walk_expr (expr1);
11599   if (gfc_is_reallocatable_lhs (expr1))
11600     {
11601       lss->no_bounds_check = 1;
11602       if (!(expr2->expr_type == EXPR_FUNCTION
11603 	    && expr2->value.function.isym != NULL
11604 	    && !(expr2->value.function.isym->elemental
11605 		 || expr2->value.function.isym->conversion)))
11606 	lss->is_alloc_lhs = 1;
11607     }
11608   else
11609     lss->no_bounds_check = expr1->no_bounds_check;
11610 
11611   rss = NULL;
11612 
11613   if ((expr1->ts.type == BT_DERIVED)
11614       && (gfc_is_class_array_function (expr2)
11615 	  || gfc_is_alloc_class_scalar_function (expr2)))
11616     expr2->must_finalize = 1;
11617 
11618   /* Checking whether a class assignment is desired is quite complicated and
11619      needed at two locations, so do it once only before the information is
11620      needed.  */
11621   lhs_attr = gfc_expr_attr (expr1);
11622   is_poly_assign = (use_vptr_copy || lhs_attr.pointer
11623 		    || (lhs_attr.allocatable && !lhs_attr.dimension))
11624 		   && (expr1->ts.type == BT_CLASS
11625 		       || gfc_is_class_array_ref (expr1, NULL)
11626 		       || gfc_is_class_scalar_expr (expr1)
11627 		       || gfc_is_class_array_ref (expr2, NULL)
11628 		       || gfc_is_class_scalar_expr (expr2))
11629 		   && lhs_attr.flavor != FL_PROCEDURE;
11630 
11631   realloc_flag = flag_realloc_lhs
11632 		 && gfc_is_reallocatable_lhs (expr1)
11633 		 && expr2->rank
11634 		 && !is_runtime_conformable (expr1, expr2);
11635 
11636   /* Only analyze the expressions for coarray properties, when in coarray-lib
11637      mode.  */
11638   if (flag_coarray == GFC_FCOARRAY_LIB)
11639     {
11640       lhs_caf_attr = gfc_caf_attr (expr1, false, &lhs_refs_comp);
11641       rhs_caf_attr = gfc_caf_attr (expr2, false, &rhs_refs_comp);
11642     }
11643 
11644   if (lss != gfc_ss_terminator)
11645     {
11646       /* The assignment needs scalarization.  */
11647       lss_section = lss;
11648 
11649       /* Find a non-scalar SS from the lhs.  */
11650       while (lss_section != gfc_ss_terminator
11651 	     && lss_section->info->type != GFC_SS_SECTION)
11652 	lss_section = lss_section->next;
11653 
11654       gcc_assert (lss_section != gfc_ss_terminator);
11655 
11656       /* Initialize the scalarizer.  */
11657       gfc_init_loopinfo (&loop);
11658 
11659       /* Walk the rhs.  */
11660       rss = gfc_walk_expr (expr2);
11661       if (rss == gfc_ss_terminator)
11662 	/* The rhs is scalar.  Add a ss for the expression.  */
11663 	rss = gfc_get_scalar_ss (gfc_ss_terminator, expr2);
11664       /* When doing a class assign, then the handle to the rhs needs to be a
11665 	 pointer to allow for polymorphism.  */
11666       if (is_poly_assign && expr2->rank == 0 && !UNLIMITED_POLY (expr2))
11667 	rss->info->type = GFC_SS_REFERENCE;
11668 
11669       rss->no_bounds_check = expr2->no_bounds_check;
11670       /* Associate the SS with the loop.  */
11671       gfc_add_ss_to_loop (&loop, lss);
11672       gfc_add_ss_to_loop (&loop, rss);
11673 
11674       /* Calculate the bounds of the scalarization.  */
11675       gfc_conv_ss_startstride (&loop);
11676       /* Enable loop reversal.  */
11677       for (n = 0; n < GFC_MAX_DIMENSIONS; n++)
11678 	loop.reverse[n] = GFC_ENABLE_REVERSE;
11679       /* Resolve any data dependencies in the statement.  */
11680       if (may_alias)
11681 	gfc_conv_resolve_dependencies (&loop, lss, rss);
11682       /* Setup the scalarizing loops.  */
11683       gfc_conv_loop_setup (&loop, &expr2->where);
11684 
11685       /* Setup the gfc_se structures.  */
11686       gfc_copy_loopinfo_to_se (&lse, &loop);
11687       gfc_copy_loopinfo_to_se (&rse, &loop);
11688 
11689       rse.ss = rss;
11690       gfc_mark_ss_chain_used (rss, 1);
11691       if (loop.temp_ss == NULL)
11692 	{
11693 	  lse.ss = lss;
11694 	  gfc_mark_ss_chain_used (lss, 1);
11695 	}
11696       else
11697 	{
11698 	  lse.ss = loop.temp_ss;
11699 	  gfc_mark_ss_chain_used (lss, 3);
11700 	  gfc_mark_ss_chain_used (loop.temp_ss, 3);
11701 	}
11702 
11703       /* Allow the scalarizer to workshare array assignments.  */
11704       if ((ompws_flags & (OMPWS_WORKSHARE_FLAG | OMPWS_SCALARIZER_BODY))
11705 	  == OMPWS_WORKSHARE_FLAG
11706 	  && loop.temp_ss == NULL)
11707 	{
11708 	  maybe_workshare = true;
11709 	  ompws_flags |= OMPWS_SCALARIZER_WS | OMPWS_SCALARIZER_BODY;
11710 	}
11711 
11712       /* Start the scalarized loop body.  */
11713       gfc_start_scalarized_body (&loop, &body);
11714     }
11715   else
11716     gfc_init_block (&body);
11717 
11718   l_is_temp = (lss != gfc_ss_terminator && loop.temp_ss != NULL);
11719 
11720   /* Translate the expression.  */
11721   rse.want_coarray = flag_coarray == GFC_FCOARRAY_LIB && init_flag
11722       && lhs_caf_attr.codimension;
11723   gfc_conv_expr (&rse, expr2);
11724 
11725   /* Deal with the case of a scalar class function assigned to a derived type.  */
11726   if (gfc_is_alloc_class_scalar_function (expr2)
11727       && expr1->ts.type == BT_DERIVED)
11728     {
11729       rse.expr = gfc_class_data_get (rse.expr);
11730       rse.expr = build_fold_indirect_ref_loc (input_location, rse.expr);
11731     }
11732 
11733   /* Stabilize a string length for temporaries.  */
11734   if (expr2->ts.type == BT_CHARACTER && !expr1->ts.deferred
11735       && !(VAR_P (rse.string_length)
11736 	   || TREE_CODE (rse.string_length) == PARM_DECL
11737 	   || TREE_CODE (rse.string_length) == INDIRECT_REF))
11738     string_length = gfc_evaluate_now (rse.string_length, &rse.pre);
11739   else if (expr2->ts.type == BT_CHARACTER)
11740     {
11741       if (expr1->ts.deferred
11742 	  && gfc_expr_attr (expr1).allocatable
11743 	  && gfc_check_dependency (expr1, expr2, true))
11744 	rse.string_length =
11745 	  gfc_evaluate_now_function_scope (rse.string_length, &rse.pre);
11746       string_length = rse.string_length;
11747     }
11748   else
11749     string_length = NULL_TREE;
11750 
11751   if (l_is_temp)
11752     {
11753       gfc_conv_tmp_array_ref (&lse);
11754       if (expr2->ts.type == BT_CHARACTER)
11755 	lse.string_length = string_length;
11756     }
11757   else
11758     {
11759       gfc_conv_expr (&lse, expr1);
11760       if (gfc_option.rtcheck & GFC_RTCHECK_MEM
11761 	  && !init_flag
11762 	  && gfc_expr_attr (expr1).allocatable
11763 	  && expr1->rank
11764 	  && !expr2->rank)
11765 	{
11766 	  tree cond;
11767 	  const char* msg;
11768 
11769 	  tmp = INDIRECT_REF_P (lse.expr)
11770 	      ? gfc_build_addr_expr (NULL_TREE, lse.expr) : lse.expr;
11771 	  STRIP_NOPS (tmp);
11772 
11773 	  /* We should only get array references here.  */
11774 	  gcc_assert (TREE_CODE (tmp) == POINTER_PLUS_EXPR
11775 		      || TREE_CODE (tmp) == ARRAY_REF);
11776 
11777 	  /* 'tmp' is either the pointer to the array(POINTER_PLUS_EXPR)
11778 	     or the array itself(ARRAY_REF).  */
11779 	  tmp = TREE_OPERAND (tmp, 0);
11780 
11781 	  /* Provide the address of the array.  */
11782 	  if (TREE_CODE (lse.expr) == ARRAY_REF)
11783 	    tmp = gfc_build_addr_expr (NULL_TREE, tmp);
11784 
11785 	  cond = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
11786 				  tmp, build_int_cst (TREE_TYPE (tmp), 0));
11787 	  msg = _("Assignment of scalar to unallocated array");
11788 	  gfc_trans_runtime_check (true, false, cond, &loop.pre,
11789 				   &expr1->where, msg);
11790 	}
11791 
11792       /* Deallocate the lhs parameterized components if required.  */
11793       if (dealloc && expr2->expr_type == EXPR_FUNCTION
11794 	  && !expr1->symtree->n.sym->attr.associate_var)
11795 	{
11796 	  if (expr1->ts.type == BT_DERIVED
11797 	      && expr1->ts.u.derived
11798 	      && expr1->ts.u.derived->attr.pdt_type)
11799 	    {
11800 	      tmp = gfc_deallocate_pdt_comp (expr1->ts.u.derived, lse.expr,
11801 					     expr1->rank);
11802 	      gfc_add_expr_to_block (&lse.pre, tmp);
11803 	    }
11804 	  else if (expr1->ts.type == BT_CLASS
11805 		   && CLASS_DATA (expr1)->ts.u.derived
11806 		   && CLASS_DATA (expr1)->ts.u.derived->attr.pdt_type)
11807 	    {
11808 	      tmp = gfc_class_data_get (lse.expr);
11809 	      tmp = gfc_deallocate_pdt_comp (CLASS_DATA (expr1)->ts.u.derived,
11810 					     tmp, expr1->rank);
11811 	      gfc_add_expr_to_block (&lse.pre, tmp);
11812 	    }
11813 	}
11814     }
11815 
11816   /* Assignments of scalar derived types with allocatable components
11817      to arrays must be done with a deep copy and the rhs temporary
11818      must have its components deallocated afterwards.  */
11819   scalar_to_array = (expr2->ts.type == BT_DERIVED
11820 		       && expr2->ts.u.derived->attr.alloc_comp
11821 		       && !gfc_expr_is_variable (expr2)
11822 		       && expr1->rank && !expr2->rank);
11823   scalar_to_array |= (expr1->ts.type == BT_DERIVED
11824 				    && expr1->rank
11825 				    && expr1->ts.u.derived->attr.alloc_comp
11826 				    && gfc_is_alloc_class_scalar_function (expr2));
11827   if (scalar_to_array && dealloc)
11828     {
11829       tmp = gfc_deallocate_alloc_comp_no_caf (expr2->ts.u.derived, rse.expr, 0);
11830       gfc_prepend_expr_to_block (&loop.post, tmp);
11831     }
11832 
11833   /* When assigning a character function result to a deferred-length variable,
11834      the function call must happen before the (re)allocation of the lhs -
11835      otherwise the character length of the result is not known.
11836      NOTE 1: This relies on having the exact dependence of the length type
11837      parameter available to the caller; gfortran saves it in the .mod files.
11838      NOTE 2: Vector array references generate an index temporary that must
11839      not go outside the loop. Otherwise, variables should not generate
11840      a pre block.
11841      NOTE 3: The concatenation operation generates a temporary pointer,
11842      whose allocation must go to the innermost loop.
11843      NOTE 4: Elemental functions may generate a temporary, too.  */
11844   if (flag_realloc_lhs
11845       && expr2->ts.type == BT_CHARACTER && expr1->ts.deferred
11846       && !(lss != gfc_ss_terminator
11847 	   && rss != gfc_ss_terminator
11848 	   && ((expr2->expr_type == EXPR_VARIABLE && expr2->rank)
11849 	       || (expr2->expr_type == EXPR_FUNCTION
11850 		   && expr2->value.function.esym != NULL
11851 		   && expr2->value.function.esym->attr.elemental)
11852 	       || (expr2->expr_type == EXPR_FUNCTION
11853 		   && expr2->value.function.isym != NULL
11854 		   && expr2->value.function.isym->elemental)
11855 	       || (expr2->expr_type == EXPR_OP
11856 		   && expr2->value.op.op == INTRINSIC_CONCAT))))
11857     gfc_add_block_to_block (&block, &rse.pre);
11858 
11859   /* Nullify the allocatable components corresponding to those of the lhs
11860      derived type, so that the finalization of the function result does not
11861      affect the lhs of the assignment. Prepend is used to ensure that the
11862      nullification occurs before the call to the finalizer. In the case of
11863      a scalar to array assignment, this is done in gfc_trans_scalar_assign
11864      as part of the deep copy.  */
11865   if (!scalar_to_array && expr1->ts.type == BT_DERIVED
11866 		       && (gfc_is_class_array_function (expr2)
11867 			   || gfc_is_alloc_class_scalar_function (expr2)))
11868     {
11869       tmp = gfc_nullify_alloc_comp (expr1->ts.u.derived, rse.expr, 0);
11870       gfc_prepend_expr_to_block (&rse.post, tmp);
11871       if (lss != gfc_ss_terminator && rss == gfc_ss_terminator)
11872 	gfc_add_block_to_block (&loop.post, &rse.post);
11873     }
11874 
11875   tmp = NULL_TREE;
11876 
11877   if (is_poly_assign)
11878     {
11879       tmp = trans_class_assignment (&body, expr1, expr2, &lse, &rse,
11880 				    use_vptr_copy || (lhs_attr.allocatable
11881 						      && !lhs_attr.dimension),
11882 				    !realloc_flag && flag_realloc_lhs
11883 				    && !lhs_attr.pointer);
11884       if (expr2->expr_type == EXPR_FUNCTION
11885 	  && expr2->ts.type == BT_DERIVED
11886 	  && expr2->ts.u.derived->attr.alloc_comp)
11887 	{
11888 	  tree tmp2 = gfc_deallocate_alloc_comp (expr2->ts.u.derived,
11889 						 rse.expr, expr2->rank);
11890 	  if (lss == gfc_ss_terminator)
11891 	    gfc_add_expr_to_block (&rse.post, tmp2);
11892 	  else
11893 	    gfc_add_expr_to_block (&loop.post, tmp2);
11894 	}
11895     }
11896   else if (flag_coarray == GFC_FCOARRAY_LIB
11897 	   && lhs_caf_attr.codimension && rhs_caf_attr.codimension
11898 	   && ((lhs_caf_attr.allocatable && lhs_refs_comp)
11899 	       || (rhs_caf_attr.allocatable && rhs_refs_comp)))
11900     {
11901       /* Only detour to caf_send[get][_by_ref] () when the lhs or rhs is an
11902 	 allocatable component, because those need to be accessed via the
11903 	 caf-runtime.  No need to check for coindexes here, because resolve
11904 	 has rewritten those already.  */
11905       gfc_code code;
11906       gfc_actual_arglist a1, a2;
11907       /* Clear the structures to prevent accessing garbage.  */
11908       memset (&code, '\0', sizeof (gfc_code));
11909       memset (&a1, '\0', sizeof (gfc_actual_arglist));
11910       memset (&a2, '\0', sizeof (gfc_actual_arglist));
11911       a1.expr = expr1;
11912       a1.next = &a2;
11913       a2.expr = expr2;
11914       a2.next = NULL;
11915       code.ext.actual = &a1;
11916       code.resolved_isym = gfc_intrinsic_subroutine_by_id (GFC_ISYM_CAF_SEND);
11917       tmp = gfc_conv_intrinsic_subroutine (&code);
11918     }
11919   else if (!is_poly_assign && expr2->must_finalize
11920 	   && expr1->ts.type == BT_CLASS
11921 	   && expr2->ts.type == BT_CLASS)
11922     {
11923       /* This case comes about when the scalarizer provides array element
11924 	 references. Use the vptr copy function, since this does a deep
11925 	 copy of allocatable components, without which the finalizer call
11926 	 will deallocate the components.  */
11927       tmp = gfc_get_vptr_from_expr (rse.expr);
11928       if (tmp != NULL_TREE)
11929 	{
11930 	  tree fcn = gfc_vptr_copy_get (tmp);
11931 	  if (POINTER_TYPE_P (TREE_TYPE (fcn)))
11932 	    fcn = build_fold_indirect_ref_loc (input_location, fcn);
11933 	  tmp = build_call_expr_loc (input_location,
11934 				     fcn, 2,
11935 				     gfc_build_addr_expr (NULL, rse.expr),
11936 				     gfc_build_addr_expr (NULL, lse.expr));
11937 	}
11938     }
11939 
11940   /* If nothing else works, do it the old fashioned way!  */
11941   if (tmp == NULL_TREE)
11942     tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts,
11943 				   gfc_expr_is_variable (expr2)
11944 				   || scalar_to_array
11945 				   || expr2->expr_type == EXPR_ARRAY,
11946 				   !(l_is_temp || init_flag) && dealloc,
11947 				   expr1->symtree->n.sym->attr.codimension);
11948 
11949   /* Add the pre blocks to the body.  */
11950   gfc_add_block_to_block (&body, &rse.pre);
11951   gfc_add_block_to_block (&body, &lse.pre);
11952   gfc_add_expr_to_block (&body, tmp);
11953   /* Add the post blocks to the body.  */
11954   gfc_add_block_to_block (&body, &rse.post);
11955   gfc_add_block_to_block (&body, &lse.post);
11956 
11957   if (lss == gfc_ss_terminator)
11958     {
11959       /* F2003: Add the code for reallocation on assignment.  */
11960       if (flag_realloc_lhs && is_scalar_reallocatable_lhs (expr1)
11961 	  && !is_poly_assign)
11962 	alloc_scalar_allocatable_for_assignment (&block, string_length,
11963 						 expr1, expr2);
11964 
11965       /* Use the scalar assignment as is.  */
11966       gfc_add_block_to_block (&block, &body);
11967     }
11968   else
11969     {
11970       gcc_assert (lse.ss == gfc_ss_terminator
11971 		  && rse.ss == gfc_ss_terminator);
11972 
11973       if (l_is_temp)
11974 	{
11975 	  gfc_trans_scalarized_loop_boundary (&loop, &body);
11976 
11977 	  /* We need to copy the temporary to the actual lhs.  */
11978 	  gfc_init_se (&lse, NULL);
11979 	  gfc_init_se (&rse, NULL);
11980 	  gfc_copy_loopinfo_to_se (&lse, &loop);
11981 	  gfc_copy_loopinfo_to_se (&rse, &loop);
11982 
11983 	  rse.ss = loop.temp_ss;
11984 	  lse.ss = lss;
11985 
11986 	  gfc_conv_tmp_array_ref (&rse);
11987 	  gfc_conv_expr (&lse, expr1);
11988 
11989 	  gcc_assert (lse.ss == gfc_ss_terminator
11990 		      && rse.ss == gfc_ss_terminator);
11991 
11992 	  if (expr2->ts.type == BT_CHARACTER)
11993 	    rse.string_length = string_length;
11994 
11995 	  tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts,
11996 					 false, dealloc);
11997 	  gfc_add_expr_to_block (&body, tmp);
11998 	}
11999 
12000       /* F2003: Allocate or reallocate lhs of allocatable array.  */
12001       if (realloc_flag)
12002 	{
12003 	  realloc_lhs_warning (expr1->ts.type, true, &expr1->where);
12004 	  ompws_flags &= ~OMPWS_SCALARIZER_WS;
12005 	  tmp = gfc_alloc_allocatable_for_assignment (&loop, expr1, expr2);
12006 	  if (tmp != NULL_TREE)
12007 	    gfc_add_expr_to_block (&loop.code[expr1->rank - 1], tmp);
12008 	}
12009 
12010       if (maybe_workshare)
12011 	ompws_flags &= ~OMPWS_SCALARIZER_BODY;
12012 
12013       /* Generate the copying loops.  */
12014       gfc_trans_scalarizing_loops (&loop, &body);
12015 
12016       /* Wrap the whole thing up.  */
12017       gfc_add_block_to_block (&block, &loop.pre);
12018       gfc_add_block_to_block (&block, &loop.post);
12019 
12020       gfc_cleanup_loop (&loop);
12021     }
12022 
12023   return gfc_finish_block (&block);
12024 }
12025 
12026 
12027 /* Check whether EXPR is a copyable array.  */
12028 
12029 static bool
copyable_array_p(gfc_expr * expr)12030 copyable_array_p (gfc_expr * expr)
12031 {
12032   if (expr->expr_type != EXPR_VARIABLE)
12033     return false;
12034 
12035   /* First check it's an array.  */
12036   if (expr->rank < 1 || !expr->ref || expr->ref->next)
12037     return false;
12038 
12039   if (!gfc_full_array_ref_p (expr->ref, NULL))
12040     return false;
12041 
12042   /* Next check that it's of a simple enough type.  */
12043   switch (expr->ts.type)
12044     {
12045     case BT_INTEGER:
12046     case BT_REAL:
12047     case BT_COMPLEX:
12048     case BT_LOGICAL:
12049       return true;
12050 
12051     case BT_CHARACTER:
12052       return false;
12053 
12054     case_bt_struct:
12055       return !expr->ts.u.derived->attr.alloc_comp;
12056 
12057     default:
12058       break;
12059     }
12060 
12061   return false;
12062 }
12063 
12064 /* Translate an assignment.  */
12065 
12066 tree
gfc_trans_assignment(gfc_expr * expr1,gfc_expr * expr2,bool init_flag,bool dealloc,bool use_vptr_copy,bool may_alias)12067 gfc_trans_assignment (gfc_expr * expr1, gfc_expr * expr2, bool init_flag,
12068 		      bool dealloc, bool use_vptr_copy, bool may_alias)
12069 {
12070   tree tmp;
12071 
12072   /* Special case a single function returning an array.  */
12073   if (expr2->expr_type == EXPR_FUNCTION && expr2->rank > 0)
12074     {
12075       tmp = gfc_trans_arrayfunc_assign (expr1, expr2);
12076       if (tmp)
12077 	return tmp;
12078     }
12079 
12080   /* Special case assigning an array to zero.  */
12081   if (copyable_array_p (expr1)
12082       && is_zero_initializer_p (expr2))
12083     {
12084       tmp = gfc_trans_zero_assign (expr1);
12085       if (tmp)
12086         return tmp;
12087     }
12088 
12089   /* Special case copying one array to another.  */
12090   if (copyable_array_p (expr1)
12091       && copyable_array_p (expr2)
12092       && gfc_compare_types (&expr1->ts, &expr2->ts)
12093       && !gfc_check_dependency (expr1, expr2, 0))
12094     {
12095       tmp = gfc_trans_array_copy (expr1, expr2);
12096       if (tmp)
12097         return tmp;
12098     }
12099 
12100   /* Special case initializing an array from a constant array constructor.  */
12101   if (copyable_array_p (expr1)
12102       && expr2->expr_type == EXPR_ARRAY
12103       && gfc_compare_types (&expr1->ts, &expr2->ts))
12104     {
12105       tmp = gfc_trans_array_constructor_copy (expr1, expr2);
12106       if (tmp)
12107 	return tmp;
12108     }
12109 
12110   if (UNLIMITED_POLY (expr1) && expr1->rank)
12111     use_vptr_copy = true;
12112 
12113   /* Fallback to the scalarizer to generate explicit loops.  */
12114   return gfc_trans_assignment_1 (expr1, expr2, init_flag, dealloc,
12115 				 use_vptr_copy, may_alias);
12116 }
12117 
12118 tree
gfc_trans_init_assign(gfc_code * code)12119 gfc_trans_init_assign (gfc_code * code)
12120 {
12121   return gfc_trans_assignment (code->expr1, code->expr2, true, false, true);
12122 }
12123 
12124 tree
gfc_trans_assign(gfc_code * code)12125 gfc_trans_assign (gfc_code * code)
12126 {
12127   return gfc_trans_assignment (code->expr1, code->expr2, false, true);
12128 }
12129 
12130 /* Generate a simple loop for internal use of the form
12131    for (var = begin; var <cond> end; var += step)
12132       body;  */
12133 void
gfc_simple_for_loop(stmtblock_t * block,tree var,tree begin,tree end,enum tree_code cond,tree step,tree body)12134 gfc_simple_for_loop (stmtblock_t *block, tree var, tree begin, tree end,
12135 		     enum tree_code cond, tree step, tree body)
12136 {
12137   tree tmp;
12138 
12139   /* var = begin. */
12140   gfc_add_modify (block, var, begin);
12141 
12142   /* Loop: for (var = begin; var <cond> end; var += step).  */
12143   tree label_loop = gfc_build_label_decl (NULL_TREE);
12144   tree label_cond = gfc_build_label_decl (NULL_TREE);
12145   TREE_USED (label_loop) = 1;
12146   TREE_USED (label_cond) = 1;
12147 
12148   gfc_add_expr_to_block (block, build1_v (GOTO_EXPR, label_cond));
12149   gfc_add_expr_to_block (block, build1_v (LABEL_EXPR, label_loop));
12150 
12151   /* Loop body.  */
12152   gfc_add_expr_to_block (block, body);
12153 
12154   /* End of loop body.  */
12155   tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (var), var, step);
12156   gfc_add_modify (block, var, tmp);
12157   gfc_add_expr_to_block (block, build1_v (LABEL_EXPR, label_cond));
12158   tmp = fold_build2_loc (input_location, cond, boolean_type_node, var, end);
12159   tmp = build3_v (COND_EXPR, tmp, build1_v (GOTO_EXPR, label_loop),
12160 		  build_empty_stmt (input_location));
12161   gfc_add_expr_to_block (block, tmp);
12162 }
12163