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