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