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