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