pr88074.c: Require c99_runtime.
[official-gcc.git] / gcc / fortran / trans-expr.c
blob9575f391abd4fd4681432325456d5aa41eef0f40
1 /* Expression translation
2 Copyright (C) 2002-2019 Free Software Foundation, Inc.
3 Contributed by Paul Brook <paul@nowt.org>
4 and Steven Bosscher <s.bosscher@student.tudelft.nl>
6 This file is part of GCC.
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.
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.
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/>. */
22 /* trans-expr.c-- generate GENERIC trees for gfc_expr. */
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"
45 /* Convert a scalar to an array descriptor. To be used for assumed-rank
46 arrays. */
48 static tree
49 get_scalar_to_descriptor_type (tree scalar, symbol_attribute attr)
51 enum gfc_array_kind akind;
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;
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));
66 tree
67 gfc_conv_scalar_to_descriptor (gfc_se *se, tree scalar, symbol_attribute attr)
69 tree desc, type, etype;
71 type = get_scalar_to_descriptor_type (scalar, attr);
72 etype = TREE_TYPE (scalar);
73 desc = gfc_create_var (type, "desc");
74 DECL_ARTIFICIAL (desc) = 1;
76 if (CONSTANT_CLASS_P (scalar))
78 tree tmp;
79 tmp = gfc_create_var (TREE_TYPE (scalar), "scalar");
80 gfc_add_modify (&se->pre, tmp, scalar);
81 scalar = tmp;
83 if (!POINTER_TYPE_P (TREE_TYPE (scalar)))
84 scalar = gfc_build_addr_expr (NULL_TREE, scalar);
85 else if (TREE_TYPE (etype) && TREE_CODE (TREE_TYPE (etype)) == ARRAY_TYPE)
86 etype = TREE_TYPE (etype);
87 gfc_add_modify (&se->pre, gfc_conv_descriptor_dtype (desc),
88 gfc_get_dtype_rank_type (0, etype));
89 gfc_conv_descriptor_data_set (&se->pre, desc, scalar);
91 /* Copy pointer address back - but only if it could have changed and
92 if the actual argument is a pointer and not, e.g., NULL(). */
93 if ((attr.pointer || attr.allocatable) && attr.intent != INTENT_IN)
94 gfc_add_modify (&se->post, scalar,
95 fold_convert (TREE_TYPE (scalar),
96 gfc_conv_descriptor_data_get (desc)));
97 return desc;
101 /* Get the coarray token from the ultimate array or component ref.
102 Returns a NULL_TREE, when the ref object is not allocatable or pointer. */
104 tree
105 gfc_get_ultimate_alloc_ptr_comps_caf_token (gfc_se *outerse, gfc_expr *expr)
107 gfc_symbol *sym = expr->symtree->n.sym;
108 bool is_coarray = sym->attr.codimension;
109 gfc_expr *caf_expr = gfc_copy_expr (expr);
110 gfc_ref *ref = caf_expr->ref, *last_caf_ref = NULL;
112 while (ref)
114 if (ref->type == REF_COMPONENT
115 && (ref->u.c.component->attr.allocatable
116 || ref->u.c.component->attr.pointer)
117 && (is_coarray || ref->u.c.component->attr.codimension))
118 last_caf_ref = ref;
119 ref = ref->next;
122 if (last_caf_ref == NULL)
123 return NULL_TREE;
125 tree comp = last_caf_ref->u.c.component->caf_token, caf;
126 gfc_se se;
127 bool comp_ref = !last_caf_ref->u.c.component->attr.dimension;
128 if (comp == NULL_TREE && comp_ref)
129 return NULL_TREE;
130 gfc_init_se (&se, outerse);
131 gfc_free_ref_list (last_caf_ref->next);
132 last_caf_ref->next = NULL;
133 caf_expr->rank = comp_ref ? 0 : last_caf_ref->u.c.component->as->rank;
134 se.want_pointer = comp_ref;
135 gfc_conv_expr (&se, caf_expr);
136 gfc_add_block_to_block (&outerse->pre, &se.pre);
138 if (TREE_CODE (se.expr) == COMPONENT_REF && comp_ref)
139 se.expr = TREE_OPERAND (se.expr, 0);
140 gfc_free_expr (caf_expr);
142 if (comp_ref)
143 caf = fold_build3_loc (input_location, COMPONENT_REF,
144 TREE_TYPE (comp), se.expr, comp, NULL_TREE);
145 else
146 caf = gfc_conv_descriptor_token (se.expr);
147 return gfc_build_addr_expr (NULL_TREE, caf);
151 /* This is the seed for an eventual trans-class.c
153 The following parameters should not be used directly since they might
154 in future implementations. Use the corresponding APIs. */
155 #define CLASS_DATA_FIELD 0
156 #define CLASS_VPTR_FIELD 1
157 #define CLASS_LEN_FIELD 2
158 #define VTABLE_HASH_FIELD 0
159 #define VTABLE_SIZE_FIELD 1
160 #define VTABLE_EXTENDS_FIELD 2
161 #define VTABLE_DEF_INIT_FIELD 3
162 #define VTABLE_COPY_FIELD 4
163 #define VTABLE_FINAL_FIELD 5
164 #define VTABLE_DEALLOCATE_FIELD 6
167 tree
168 gfc_class_set_static_fields (tree decl, tree vptr, tree data)
170 tree tmp;
171 tree field;
172 vec<constructor_elt, va_gc> *init = NULL;
174 field = TYPE_FIELDS (TREE_TYPE (decl));
175 tmp = gfc_advance_chain (field, CLASS_DATA_FIELD);
176 CONSTRUCTOR_APPEND_ELT (init, tmp, data);
178 tmp = gfc_advance_chain (field, CLASS_VPTR_FIELD);
179 CONSTRUCTOR_APPEND_ELT (init, tmp, vptr);
181 return build_constructor (TREE_TYPE (decl), init);
185 tree
186 gfc_class_data_get (tree decl)
188 tree data;
189 if (POINTER_TYPE_P (TREE_TYPE (decl)))
190 decl = build_fold_indirect_ref_loc (input_location, decl);
191 data = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (decl)),
192 CLASS_DATA_FIELD);
193 return fold_build3_loc (input_location, COMPONENT_REF,
194 TREE_TYPE (data), decl, data,
195 NULL_TREE);
199 tree
200 gfc_class_vptr_get (tree decl)
202 tree vptr;
203 /* For class arrays decl may be a temporary descriptor handle, the vptr is
204 then available through the saved descriptor. */
205 if (VAR_P (decl) && DECL_LANG_SPECIFIC (decl)
206 && GFC_DECL_SAVED_DESCRIPTOR (decl))
207 decl = GFC_DECL_SAVED_DESCRIPTOR (decl);
208 if (POINTER_TYPE_P (TREE_TYPE (decl)))
209 decl = build_fold_indirect_ref_loc (input_location, decl);
210 vptr = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (decl)),
211 CLASS_VPTR_FIELD);
212 return fold_build3_loc (input_location, COMPONENT_REF,
213 TREE_TYPE (vptr), decl, vptr,
214 NULL_TREE);
218 tree
219 gfc_class_len_get (tree decl)
221 tree len;
222 /* For class arrays decl may be a temporary descriptor handle, the len is
223 then available through the saved descriptor. */
224 if (VAR_P (decl) && DECL_LANG_SPECIFIC (decl)
225 && GFC_DECL_SAVED_DESCRIPTOR (decl))
226 decl = GFC_DECL_SAVED_DESCRIPTOR (decl);
227 if (POINTER_TYPE_P (TREE_TYPE (decl)))
228 decl = build_fold_indirect_ref_loc (input_location, decl);
229 len = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (decl)),
230 CLASS_LEN_FIELD);
231 return fold_build3_loc (input_location, COMPONENT_REF,
232 TREE_TYPE (len), decl, len,
233 NULL_TREE);
237 /* Try to get the _len component of a class. When the class is not unlimited
238 poly, i.e. no _len field exists, then return a zero node. */
240 tree
241 gfc_class_len_or_zero_get (tree decl)
243 tree len;
244 /* For class arrays decl may be a temporary descriptor handle, the vptr is
245 then available through the saved descriptor. */
246 if (VAR_P (decl) && DECL_LANG_SPECIFIC (decl)
247 && GFC_DECL_SAVED_DESCRIPTOR (decl))
248 decl = GFC_DECL_SAVED_DESCRIPTOR (decl);
249 if (POINTER_TYPE_P (TREE_TYPE (decl)))
250 decl = build_fold_indirect_ref_loc (input_location, decl);
251 len = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (decl)),
252 CLASS_LEN_FIELD);
253 return len != NULL_TREE ? fold_build3_loc (input_location, COMPONENT_REF,
254 TREE_TYPE (len), decl, len,
255 NULL_TREE)
256 : build_zero_cst (gfc_charlen_type_node);
260 /* Get the specified FIELD from the VPTR. */
262 static tree
263 vptr_field_get (tree vptr, int fieldno)
265 tree field;
266 vptr = build_fold_indirect_ref_loc (input_location, vptr);
267 field = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (vptr)),
268 fieldno);
269 field = fold_build3_loc (input_location, COMPONENT_REF,
270 TREE_TYPE (field), vptr, field,
271 NULL_TREE);
272 gcc_assert (field);
273 return field;
277 /* Get the field from the class' vptr. */
279 static tree
280 class_vtab_field_get (tree decl, int fieldno)
282 tree vptr;
283 vptr = gfc_class_vptr_get (decl);
284 return vptr_field_get (vptr, fieldno);
288 /* Define a macro for creating the class_vtab_* and vptr_* accessors in
289 unison. */
290 #define VTAB_GET_FIELD_GEN(name, field) tree \
291 gfc_class_vtab_## name ##_get (tree cl) \
293 return class_vtab_field_get (cl, field); \
296 tree \
297 gfc_vptr_## name ##_get (tree vptr) \
299 return vptr_field_get (vptr, field); \
302 VTAB_GET_FIELD_GEN (hash, VTABLE_HASH_FIELD)
303 VTAB_GET_FIELD_GEN (extends, VTABLE_EXTENDS_FIELD)
304 VTAB_GET_FIELD_GEN (def_init, VTABLE_DEF_INIT_FIELD)
305 VTAB_GET_FIELD_GEN (copy, VTABLE_COPY_FIELD)
306 VTAB_GET_FIELD_GEN (final, VTABLE_FINAL_FIELD)
307 VTAB_GET_FIELD_GEN (deallocate, VTABLE_DEALLOCATE_FIELD)
310 /* The size field is returned as an array index type. Therefore treat
311 it and only it specially. */
313 tree
314 gfc_class_vtab_size_get (tree cl)
316 tree size;
317 size = class_vtab_field_get (cl, VTABLE_SIZE_FIELD);
318 /* Always return size as an array index type. */
319 size = fold_convert (gfc_array_index_type, size);
320 gcc_assert (size);
321 return size;
324 tree
325 gfc_vptr_size_get (tree vptr)
327 tree size;
328 size = vptr_field_get (vptr, VTABLE_SIZE_FIELD);
329 /* Always return size as an array index type. */
330 size = fold_convert (gfc_array_index_type, size);
331 gcc_assert (size);
332 return size;
336 #undef CLASS_DATA_FIELD
337 #undef CLASS_VPTR_FIELD
338 #undef CLASS_LEN_FIELD
339 #undef VTABLE_HASH_FIELD
340 #undef VTABLE_SIZE_FIELD
341 #undef VTABLE_EXTENDS_FIELD
342 #undef VTABLE_DEF_INIT_FIELD
343 #undef VTABLE_COPY_FIELD
344 #undef VTABLE_FINAL_FIELD
347 /* Search for the last _class ref in the chain of references of this
348 expression and cut the chain there. Albeit this routine is similiar
349 to class.c::gfc_add_component_ref (), is there a significant
350 difference: gfc_add_component_ref () concentrates on an array ref to
351 be the last ref in the chain. This routine is oblivious to the kind
352 of refs following. */
354 gfc_expr *
355 gfc_find_and_cut_at_last_class_ref (gfc_expr *e, bool is_mold)
357 gfc_expr *base_expr;
358 gfc_ref *ref, *class_ref, *tail = NULL, *array_ref;
360 /* Find the last class reference. */
361 class_ref = NULL;
362 array_ref = NULL;
363 for (ref = e->ref; ref; ref = ref->next)
365 if (ref->type == REF_ARRAY && ref->u.ar.type != AR_ELEMENT)
366 array_ref = ref;
368 if (ref->type == REF_COMPONENT
369 && ref->u.c.component->ts.type == BT_CLASS)
371 /* Component to the right of a part reference with nonzero rank
372 must not have the ALLOCATABLE attribute. If attempts are
373 made to reference such a component reference, an error results
374 followed by an ICE. */
375 if (array_ref && CLASS_DATA (ref->u.c.component)->attr.allocatable)
376 return NULL;
377 class_ref = ref;
380 if (ref->next == NULL)
381 break;
384 /* Remove and store all subsequent references after the
385 CLASS reference. */
386 if (class_ref)
388 tail = class_ref->next;
389 class_ref->next = NULL;
391 else if (e->symtree && e->symtree->n.sym->ts.type == BT_CLASS)
393 tail = e->ref;
394 e->ref = NULL;
397 if (is_mold)
398 base_expr = gfc_expr_to_initialize (e);
399 else
400 base_expr = gfc_copy_expr (e);
402 /* Restore the original tail expression. */
403 if (class_ref)
405 gfc_free_ref_list (class_ref->next);
406 class_ref->next = tail;
408 else if (e->symtree && e->symtree->n.sym->ts.type == BT_CLASS)
410 gfc_free_ref_list (e->ref);
411 e->ref = tail;
413 return base_expr;
417 /* Reset the vptr to the declared type, e.g. after deallocation. */
419 void
420 gfc_reset_vptr (stmtblock_t *block, gfc_expr *e)
422 gfc_symbol *vtab;
423 tree vptr;
424 tree vtable;
425 gfc_se se;
427 /* Evaluate the expression and obtain the vptr from it. */
428 gfc_init_se (&se, NULL);
429 if (e->rank)
430 gfc_conv_expr_descriptor (&se, e);
431 else
432 gfc_conv_expr (&se, e);
433 gfc_add_block_to_block (block, &se.pre);
434 vptr = gfc_get_vptr_from_expr (se.expr);
436 /* If a vptr is not found, we can do nothing more. */
437 if (vptr == NULL_TREE)
438 return;
440 if (UNLIMITED_POLY (e))
441 gfc_add_modify (block, vptr, build_int_cst (TREE_TYPE (vptr), 0));
442 else
444 /* Return the vptr to the address of the declared type. */
445 vtab = gfc_find_derived_vtab (e->ts.u.derived);
446 vtable = vtab->backend_decl;
447 if (vtable == NULL_TREE)
448 vtable = gfc_get_symbol_decl (vtab);
449 vtable = gfc_build_addr_expr (NULL, vtable);
450 vtable = fold_convert (TREE_TYPE (vptr), vtable);
451 gfc_add_modify (block, vptr, vtable);
456 /* Reset the len for unlimited polymorphic objects. */
458 void
459 gfc_reset_len (stmtblock_t *block, gfc_expr *expr)
461 gfc_expr *e;
462 gfc_se se_len;
463 e = gfc_find_and_cut_at_last_class_ref (expr);
464 if (e == NULL)
465 return;
466 gfc_add_len_component (e);
467 gfc_init_se (&se_len, NULL);
468 gfc_conv_expr (&se_len, e);
469 gfc_add_modify (block, se_len.expr,
470 fold_convert (TREE_TYPE (se_len.expr), integer_zero_node));
471 gfc_free_expr (e);
475 /* Obtain the vptr of the last class reference in an expression.
476 Return NULL_TREE if no class reference is found. */
478 tree
479 gfc_get_vptr_from_expr (tree expr)
481 tree tmp;
482 tree type;
484 for (tmp = expr; tmp; tmp = TREE_OPERAND (tmp, 0))
486 type = TREE_TYPE (tmp);
487 while (type)
489 if (GFC_CLASS_TYPE_P (type))
490 return gfc_class_vptr_get (tmp);
491 if (type != TYPE_CANONICAL (type))
492 type = TYPE_CANONICAL (type);
493 else
494 type = NULL_TREE;
496 if (VAR_P (tmp) || TREE_CODE (tmp) == PARM_DECL)
497 break;
500 if (POINTER_TYPE_P (TREE_TYPE (tmp)))
501 tmp = build_fold_indirect_ref_loc (input_location, tmp);
503 if (GFC_CLASS_TYPE_P (TREE_TYPE (tmp)))
504 return gfc_class_vptr_get (tmp);
506 return NULL_TREE;
510 static void
511 class_array_data_assign (stmtblock_t *block, tree lhs_desc, tree rhs_desc,
512 bool lhs_type)
514 tree tmp, tmp2, type;
516 gfc_conv_descriptor_data_set (block, lhs_desc,
517 gfc_conv_descriptor_data_get (rhs_desc));
518 gfc_conv_descriptor_offset_set (block, lhs_desc,
519 gfc_conv_descriptor_offset_get (rhs_desc));
521 gfc_add_modify (block, gfc_conv_descriptor_dtype (lhs_desc),
522 gfc_conv_descriptor_dtype (rhs_desc));
524 /* Assign the dimension as range-ref. */
525 tmp = gfc_get_descriptor_dimension (lhs_desc);
526 tmp2 = gfc_get_descriptor_dimension (rhs_desc);
528 type = lhs_type ? TREE_TYPE (tmp) : TREE_TYPE (tmp2);
529 tmp = build4_loc (input_location, ARRAY_RANGE_REF, type, tmp,
530 gfc_index_zero_node, NULL_TREE, NULL_TREE);
531 tmp2 = build4_loc (input_location, ARRAY_RANGE_REF, type, tmp2,
532 gfc_index_zero_node, NULL_TREE, NULL_TREE);
533 gfc_add_modify (block, tmp, tmp2);
537 /* Takes a derived type expression and returns the address of a temporary
538 class object of the 'declared' type. If vptr is not NULL, this is
539 used for the temporary class object.
540 optional_alloc_ptr is false when the dummy is neither allocatable
541 nor a pointer; that's only relevant for the optional handling. */
542 void
543 gfc_conv_derived_to_class (gfc_se *parmse, gfc_expr *e,
544 gfc_typespec class_ts, tree vptr, bool optional,
545 bool optional_alloc_ptr)
547 gfc_symbol *vtab;
548 tree cond_optional = NULL_TREE;
549 gfc_ss *ss;
550 tree ctree;
551 tree var;
552 tree tmp;
553 int dim;
555 /* The derived type needs to be converted to a temporary
556 CLASS object. */
557 tmp = gfc_typenode_for_spec (&class_ts);
558 var = gfc_create_var (tmp, "class");
560 /* Set the vptr. */
561 ctree = gfc_class_vptr_get (var);
563 if (vptr != NULL_TREE)
565 /* Use the dynamic vptr. */
566 tmp = vptr;
568 else
570 /* In this case the vtab corresponds to the derived type and the
571 vptr must point to it. */
572 vtab = gfc_find_derived_vtab (e->ts.u.derived);
573 gcc_assert (vtab);
574 tmp = gfc_build_addr_expr (NULL_TREE, gfc_get_symbol_decl (vtab));
576 gfc_add_modify (&parmse->pre, ctree,
577 fold_convert (TREE_TYPE (ctree), tmp));
579 /* Now set the data field. */
580 ctree = gfc_class_data_get (var);
582 if (optional)
583 cond_optional = gfc_conv_expr_present (e->symtree->n.sym);
585 if (parmse->expr && POINTER_TYPE_P (TREE_TYPE (parmse->expr)))
587 /* If there is a ready made pointer to a derived type, use it
588 rather than evaluating the expression again. */
589 tmp = fold_convert (TREE_TYPE (ctree), parmse->expr);
590 gfc_add_modify (&parmse->pre, ctree, tmp);
592 else if (parmse->ss && parmse->ss->info && parmse->ss->info->useflags)
594 /* For an array reference in an elemental procedure call we need
595 to retain the ss to provide the scalarized array reference. */
596 gfc_conv_expr_reference (parmse, e);
597 tmp = fold_convert (TREE_TYPE (ctree), parmse->expr);
598 if (optional)
599 tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp),
600 cond_optional, tmp,
601 fold_convert (TREE_TYPE (tmp), null_pointer_node));
602 gfc_add_modify (&parmse->pre, ctree, tmp);
604 else
606 ss = gfc_walk_expr (e);
607 if (ss == gfc_ss_terminator)
609 parmse->ss = NULL;
610 gfc_conv_expr_reference (parmse, e);
612 /* Scalar to an assumed-rank array. */
613 if (class_ts.u.derived->components->as)
615 tree type;
616 type = get_scalar_to_descriptor_type (parmse->expr,
617 gfc_expr_attr (e));
618 gfc_add_modify (&parmse->pre, gfc_conv_descriptor_dtype (ctree),
619 gfc_get_dtype (type));
620 if (optional)
621 parmse->expr = build3_loc (input_location, COND_EXPR,
622 TREE_TYPE (parmse->expr),
623 cond_optional, parmse->expr,
624 fold_convert (TREE_TYPE (parmse->expr),
625 null_pointer_node));
626 gfc_conv_descriptor_data_set (&parmse->pre, ctree, parmse->expr);
628 else
630 tmp = fold_convert (TREE_TYPE (ctree), parmse->expr);
631 if (optional)
632 tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp),
633 cond_optional, tmp,
634 fold_convert (TREE_TYPE (tmp),
635 null_pointer_node));
636 gfc_add_modify (&parmse->pre, ctree, tmp);
639 else
641 stmtblock_t block;
642 gfc_init_block (&block);
643 gfc_ref *ref;
645 parmse->ss = ss;
646 parmse->use_offset = 1;
647 gfc_conv_expr_descriptor (parmse, e);
649 /* Detect any array references with vector subscripts. */
650 for (ref = e->ref; ref; ref = ref->next)
651 if (ref->type == REF_ARRAY
652 && ref->u.ar.type != AR_ELEMENT
653 && ref->u.ar.type != AR_FULL)
655 for (dim = 0; dim < ref->u.ar.dimen; dim++)
656 if (ref->u.ar.dimen_type[dim] == DIMEN_VECTOR)
657 break;
658 if (dim < ref->u.ar.dimen)
659 break;
662 /* Array references with vector subscripts and non-variable expressions
663 need be converted to a one-based descriptor. */
664 if (ref || e->expr_type != EXPR_VARIABLE)
666 for (dim = 0; dim < e->rank; ++dim)
667 gfc_conv_shift_descriptor_lbound (&block, parmse->expr, dim,
668 gfc_index_one_node);
671 if (e->rank != class_ts.u.derived->components->as->rank)
673 gcc_assert (class_ts.u.derived->components->as->type
674 == AS_ASSUMED_RANK);
675 class_array_data_assign (&block, ctree, parmse->expr, false);
677 else
679 if (gfc_expr_attr (e).codimension)
680 parmse->expr = fold_build1_loc (input_location,
681 VIEW_CONVERT_EXPR,
682 TREE_TYPE (ctree),
683 parmse->expr);
684 gfc_add_modify (&block, ctree, parmse->expr);
687 if (optional)
689 tmp = gfc_finish_block (&block);
691 gfc_init_block (&block);
692 gfc_conv_descriptor_data_set (&block, ctree, null_pointer_node);
694 tmp = build3_v (COND_EXPR, cond_optional, tmp,
695 gfc_finish_block (&block));
696 gfc_add_expr_to_block (&parmse->pre, tmp);
698 else
699 gfc_add_block_to_block (&parmse->pre, &block);
703 if (class_ts.u.derived->components->ts.type == BT_DERIVED
704 && class_ts.u.derived->components->ts.u.derived
705 ->attr.unlimited_polymorphic)
707 /* Take care about initializing the _len component correctly. */
708 ctree = gfc_class_len_get (var);
709 if (UNLIMITED_POLY (e))
711 gfc_expr *len;
712 gfc_se se;
714 len = gfc_copy_expr (e);
715 gfc_add_len_component (len);
716 gfc_init_se (&se, NULL);
717 gfc_conv_expr (&se, len);
718 if (optional)
719 tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (se.expr),
720 cond_optional, se.expr,
721 fold_convert (TREE_TYPE (se.expr),
722 integer_zero_node));
723 else
724 tmp = se.expr;
726 else
727 tmp = integer_zero_node;
728 gfc_add_modify (&parmse->pre, ctree, fold_convert (TREE_TYPE (ctree),
729 tmp));
731 /* Pass the address of the class object. */
732 parmse->expr = gfc_build_addr_expr (NULL_TREE, var);
734 if (optional && optional_alloc_ptr)
735 parmse->expr = build3_loc (input_location, COND_EXPR,
736 TREE_TYPE (parmse->expr),
737 cond_optional, parmse->expr,
738 fold_convert (TREE_TYPE (parmse->expr),
739 null_pointer_node));
743 /* Create a new class container, which is required as scalar coarrays
744 have an array descriptor while normal scalars haven't. Optionally,
745 NULL pointer checks are added if the argument is OPTIONAL. */
747 static void
748 class_scalar_coarray_to_class (gfc_se *parmse, gfc_expr *e,
749 gfc_typespec class_ts, bool optional)
751 tree var, ctree, tmp;
752 stmtblock_t block;
753 gfc_ref *ref;
754 gfc_ref *class_ref;
756 gfc_init_block (&block);
758 class_ref = NULL;
759 for (ref = e->ref; ref; ref = ref->next)
761 if (ref->type == REF_COMPONENT
762 && ref->u.c.component->ts.type == BT_CLASS)
763 class_ref = ref;
766 if (class_ref == NULL
767 && e->symtree && e->symtree->n.sym->ts.type == BT_CLASS)
768 tmp = e->symtree->n.sym->backend_decl;
769 else
771 /* Remove everything after the last class reference, convert the
772 expression and then recover its tailend once more. */
773 gfc_se tmpse;
774 ref = class_ref->next;
775 class_ref->next = NULL;
776 gfc_init_se (&tmpse, NULL);
777 gfc_conv_expr (&tmpse, e);
778 class_ref->next = ref;
779 tmp = tmpse.expr;
782 var = gfc_typenode_for_spec (&class_ts);
783 var = gfc_create_var (var, "class");
785 ctree = gfc_class_vptr_get (var);
786 gfc_add_modify (&block, ctree,
787 fold_convert (TREE_TYPE (ctree), gfc_class_vptr_get (tmp)));
789 ctree = gfc_class_data_get (var);
790 tmp = gfc_conv_descriptor_data_get (gfc_class_data_get (tmp));
791 gfc_add_modify (&block, ctree, fold_convert (TREE_TYPE (ctree), tmp));
793 /* Pass the address of the class object. */
794 parmse->expr = gfc_build_addr_expr (NULL_TREE, var);
796 if (optional)
798 tree cond = gfc_conv_expr_present (e->symtree->n.sym);
799 tree tmp2;
801 tmp = gfc_finish_block (&block);
803 gfc_init_block (&block);
804 tmp2 = gfc_class_data_get (var);
805 gfc_add_modify (&block, tmp2, fold_convert (TREE_TYPE (tmp2),
806 null_pointer_node));
807 tmp2 = gfc_finish_block (&block);
809 tmp = build3_loc (input_location, COND_EXPR, void_type_node,
810 cond, tmp, tmp2);
811 gfc_add_expr_to_block (&parmse->pre, tmp);
813 else
814 gfc_add_block_to_block (&parmse->pre, &block);
818 /* Takes an intrinsic type expression and returns the address of a temporary
819 class object of the 'declared' type. */
820 void
821 gfc_conv_intrinsic_to_class (gfc_se *parmse, gfc_expr *e,
822 gfc_typespec class_ts)
824 gfc_symbol *vtab;
825 gfc_ss *ss;
826 tree ctree;
827 tree var;
828 tree tmp;
830 /* The intrinsic type needs to be converted to a temporary
831 CLASS object. */
832 tmp = gfc_typenode_for_spec (&class_ts);
833 var = gfc_create_var (tmp, "class");
835 /* Set the vptr. */
836 ctree = gfc_class_vptr_get (var);
838 vtab = gfc_find_vtab (&e->ts);
839 gcc_assert (vtab);
840 tmp = gfc_build_addr_expr (NULL_TREE, gfc_get_symbol_decl (vtab));
841 gfc_add_modify (&parmse->pre, ctree,
842 fold_convert (TREE_TYPE (ctree), tmp));
844 /* Now set the data field. */
845 ctree = gfc_class_data_get (var);
846 if (parmse->ss && parmse->ss->info->useflags)
848 /* For an array reference in an elemental procedure call we need
849 to retain the ss to provide the scalarized array reference. */
850 gfc_conv_expr_reference (parmse, e);
851 tmp = fold_convert (TREE_TYPE (ctree), parmse->expr);
852 gfc_add_modify (&parmse->pre, ctree, tmp);
854 else
856 ss = gfc_walk_expr (e);
857 if (ss == gfc_ss_terminator)
859 parmse->ss = NULL;
860 gfc_conv_expr_reference (parmse, e);
861 if (class_ts.u.derived->components->as
862 && class_ts.u.derived->components->as->type == AS_ASSUMED_RANK)
864 tmp = gfc_conv_scalar_to_descriptor (parmse, parmse->expr,
865 gfc_expr_attr (e));
866 tmp = fold_build1_loc (input_location, VIEW_CONVERT_EXPR,
867 TREE_TYPE (ctree), tmp);
869 else
870 tmp = fold_convert (TREE_TYPE (ctree), parmse->expr);
871 gfc_add_modify (&parmse->pre, ctree, tmp);
873 else
875 parmse->ss = ss;
876 parmse->use_offset = 1;
877 gfc_conv_expr_descriptor (parmse, e);
878 if (class_ts.u.derived->components->as->rank != e->rank)
880 tmp = fold_build1_loc (input_location, VIEW_CONVERT_EXPR,
881 TREE_TYPE (ctree), parmse->expr);
882 gfc_add_modify (&parmse->pre, ctree, tmp);
884 else
885 gfc_add_modify (&parmse->pre, ctree, parmse->expr);
889 gcc_assert (class_ts.type == BT_CLASS);
890 if (class_ts.u.derived->components->ts.type == BT_DERIVED
891 && class_ts.u.derived->components->ts.u.derived
892 ->attr.unlimited_polymorphic)
894 ctree = gfc_class_len_get (var);
895 /* When the actual arg is a char array, then set the _len component of the
896 unlimited polymorphic entity to the length of the string. */
897 if (e->ts.type == BT_CHARACTER)
899 /* Start with parmse->string_length because this seems to be set to a
900 correct value more often. */
901 if (parmse->string_length)
902 tmp = parmse->string_length;
903 /* When the string_length is not yet set, then try the backend_decl of
904 the cl. */
905 else if (e->ts.u.cl->backend_decl)
906 tmp = e->ts.u.cl->backend_decl;
907 /* If both of the above approaches fail, then try to generate an
908 expression from the input, which is only feasible currently, when the
909 expression can be evaluated to a constant one. */
910 else
912 /* Try to simplify the expression. */
913 gfc_simplify_expr (e, 0);
914 if (e->expr_type == EXPR_CONSTANT && !e->ts.u.cl->resolved)
916 /* Amazingly all data is present to compute the length of a
917 constant string, but the expression is not yet there. */
918 e->ts.u.cl->length = gfc_get_constant_expr (BT_INTEGER,
919 gfc_charlen_int_kind,
920 &e->where);
921 mpz_set_ui (e->ts.u.cl->length->value.integer,
922 e->value.character.length);
923 gfc_conv_const_charlen (e->ts.u.cl);
924 e->ts.u.cl->resolved = 1;
925 tmp = e->ts.u.cl->backend_decl;
927 else
929 gfc_error ("Cannot compute the length of the char array "
930 "at %L.", &e->where);
934 else
935 tmp = integer_zero_node;
937 gfc_add_modify (&parmse->pre, ctree, fold_convert (TREE_TYPE (ctree), tmp));
939 else if (class_ts.type == BT_CLASS
940 && class_ts.u.derived->components
941 && class_ts.u.derived->components->ts.u
942 .derived->attr.unlimited_polymorphic)
944 ctree = gfc_class_len_get (var);
945 gfc_add_modify (&parmse->pre, ctree,
946 fold_convert (TREE_TYPE (ctree),
947 integer_zero_node));
949 /* Pass the address of the class object. */
950 parmse->expr = gfc_build_addr_expr (NULL_TREE, var);
954 /* Takes a scalarized class array expression and returns the
955 address of a temporary scalar class object of the 'declared'
956 type.
957 OOP-TODO: This could be improved by adding code that branched on
958 the dynamic type being the same as the declared type. In this case
959 the original class expression can be passed directly.
960 optional_alloc_ptr is false when the dummy is neither allocatable
961 nor a pointer; that's relevant for the optional handling.
962 Set copyback to true if class container's _data and _vtab pointers
963 might get modified. */
965 void
966 gfc_conv_class_to_class (gfc_se *parmse, gfc_expr *e, gfc_typespec class_ts,
967 bool elemental, bool copyback, bool optional,
968 bool optional_alloc_ptr)
970 tree ctree;
971 tree var;
972 tree tmp;
973 tree vptr;
974 tree cond = NULL_TREE;
975 tree slen = NULL_TREE;
976 gfc_ref *ref;
977 gfc_ref *class_ref;
978 stmtblock_t block;
979 bool full_array = false;
981 gfc_init_block (&block);
983 class_ref = NULL;
984 for (ref = e->ref; ref; ref = ref->next)
986 if (ref->type == REF_COMPONENT
987 && ref->u.c.component->ts.type == BT_CLASS)
988 class_ref = ref;
990 if (ref->next == NULL)
991 break;
994 if ((ref == NULL || class_ref == ref)
995 && !(gfc_is_class_array_function (e) && parmse->class_vptr != NULL_TREE)
996 && (!class_ts.u.derived->components->as
997 || class_ts.u.derived->components->as->rank != -1))
998 return;
1000 /* Test for FULL_ARRAY. */
1001 if (e->rank == 0 && gfc_expr_attr (e).codimension
1002 && gfc_expr_attr (e).dimension)
1003 full_array = true;
1004 else
1005 gfc_is_class_array_ref (e, &full_array);
1007 /* The derived type needs to be converted to a temporary
1008 CLASS object. */
1009 tmp = gfc_typenode_for_spec (&class_ts);
1010 var = gfc_create_var (tmp, "class");
1012 /* Set the data. */
1013 ctree = gfc_class_data_get (var);
1014 if (class_ts.u.derived->components->as
1015 && e->rank != class_ts.u.derived->components->as->rank)
1017 if (e->rank == 0)
1019 tree type = get_scalar_to_descriptor_type (parmse->expr,
1020 gfc_expr_attr (e));
1021 gfc_add_modify (&block, gfc_conv_descriptor_dtype (ctree),
1022 gfc_get_dtype (type));
1024 tmp = gfc_class_data_get (parmse->expr);
1025 if (!POINTER_TYPE_P (TREE_TYPE (tmp)))
1026 tmp = gfc_build_addr_expr (NULL_TREE, tmp);
1028 gfc_conv_descriptor_data_set (&block, ctree, tmp);
1030 else
1031 class_array_data_assign (&block, ctree, parmse->expr, false);
1033 else
1035 if (TREE_TYPE (parmse->expr) != TREE_TYPE (ctree))
1036 parmse->expr = fold_build1_loc (input_location, VIEW_CONVERT_EXPR,
1037 TREE_TYPE (ctree), parmse->expr);
1038 gfc_add_modify (&block, ctree, parmse->expr);
1041 /* Return the data component, except in the case of scalarized array
1042 references, where nullification of the cannot occur and so there
1043 is no need. */
1044 if (!elemental && full_array && copyback)
1046 if (class_ts.u.derived->components->as
1047 && e->rank != class_ts.u.derived->components->as->rank)
1049 if (e->rank == 0)
1050 gfc_add_modify (&parmse->post, gfc_class_data_get (parmse->expr),
1051 gfc_conv_descriptor_data_get (ctree));
1052 else
1053 class_array_data_assign (&parmse->post, parmse->expr, ctree, true);
1055 else
1056 gfc_add_modify (&parmse->post, parmse->expr, ctree);
1059 /* Set the vptr. */
1060 ctree = gfc_class_vptr_get (var);
1062 /* The vptr is the second field of the actual argument.
1063 First we have to find the corresponding class reference. */
1065 tmp = NULL_TREE;
1066 if (gfc_is_class_array_function (e)
1067 && parmse->class_vptr != NULL_TREE)
1068 tmp = parmse->class_vptr;
1069 else if (class_ref == NULL
1070 && e->symtree && e->symtree->n.sym->ts.type == BT_CLASS)
1072 tmp = e->symtree->n.sym->backend_decl;
1074 if (TREE_CODE (tmp) == FUNCTION_DECL)
1075 tmp = gfc_get_fake_result_decl (e->symtree->n.sym, 0);
1077 if (DECL_LANG_SPECIFIC (tmp) && GFC_DECL_SAVED_DESCRIPTOR (tmp))
1078 tmp = GFC_DECL_SAVED_DESCRIPTOR (tmp);
1080 slen = build_zero_cst (size_type_node);
1082 else
1084 /* Remove everything after the last class reference, convert the
1085 expression and then recover its tailend once more. */
1086 gfc_se tmpse;
1087 ref = class_ref->next;
1088 class_ref->next = NULL;
1089 gfc_init_se (&tmpse, NULL);
1090 gfc_conv_expr (&tmpse, e);
1091 class_ref->next = ref;
1092 tmp = tmpse.expr;
1093 slen = tmpse.string_length;
1096 gcc_assert (tmp != NULL_TREE);
1098 /* Dereference if needs be. */
1099 if (TREE_CODE (TREE_TYPE (tmp)) == REFERENCE_TYPE)
1100 tmp = build_fold_indirect_ref_loc (input_location, tmp);
1102 if (!(gfc_is_class_array_function (e) && parmse->class_vptr))
1103 vptr = gfc_class_vptr_get (tmp);
1104 else
1105 vptr = tmp;
1107 gfc_add_modify (&block, ctree,
1108 fold_convert (TREE_TYPE (ctree), vptr));
1110 /* Return the vptr component, except in the case of scalarized array
1111 references, where the dynamic type cannot change. */
1112 if (!elemental && full_array && copyback)
1113 gfc_add_modify (&parmse->post, vptr,
1114 fold_convert (TREE_TYPE (vptr), ctree));
1116 /* For unlimited polymorphic objects also set the _len component. */
1117 if (class_ts.type == BT_CLASS
1118 && class_ts.u.derived->components
1119 && class_ts.u.derived->components->ts.u
1120 .derived->attr.unlimited_polymorphic)
1122 ctree = gfc_class_len_get (var);
1123 if (UNLIMITED_POLY (e))
1124 tmp = gfc_class_len_get (tmp);
1125 else if (e->ts.type == BT_CHARACTER)
1127 gcc_assert (slen != NULL_TREE);
1128 tmp = slen;
1130 else
1131 tmp = build_zero_cst (size_type_node);
1132 gfc_add_modify (&parmse->pre, ctree,
1133 fold_convert (TREE_TYPE (ctree), tmp));
1135 /* Return the len component, except in the case of scalarized array
1136 references, where the dynamic type cannot change. */
1137 if (!elemental && full_array && copyback
1138 && (UNLIMITED_POLY (e) || VAR_P (tmp)))
1139 gfc_add_modify (&parmse->post, tmp,
1140 fold_convert (TREE_TYPE (tmp), ctree));
1143 if (optional)
1145 tree tmp2;
1147 cond = gfc_conv_expr_present (e->symtree->n.sym);
1148 /* parmse->pre may contain some preparatory instructions for the
1149 temporary array descriptor. Those may only be executed when the
1150 optional argument is set, therefore add parmse->pre's instructions
1151 to block, which is later guarded by an if (optional_arg_given). */
1152 gfc_add_block_to_block (&parmse->pre, &block);
1153 block.head = parmse->pre.head;
1154 parmse->pre.head = NULL_TREE;
1155 tmp = gfc_finish_block (&block);
1157 if (optional_alloc_ptr)
1158 tmp2 = build_empty_stmt (input_location);
1159 else
1161 gfc_init_block (&block);
1163 tmp2 = gfc_conv_descriptor_data_get (gfc_class_data_get (var));
1164 gfc_add_modify (&block, tmp2, fold_convert (TREE_TYPE (tmp2),
1165 null_pointer_node));
1166 tmp2 = gfc_finish_block (&block);
1169 tmp = build3_loc (input_location, COND_EXPR, void_type_node,
1170 cond, tmp, tmp2);
1171 gfc_add_expr_to_block (&parmse->pre, tmp);
1173 else
1174 gfc_add_block_to_block (&parmse->pre, &block);
1176 /* Pass the address of the class object. */
1177 parmse->expr = gfc_build_addr_expr (NULL_TREE, var);
1179 if (optional && optional_alloc_ptr)
1180 parmse->expr = build3_loc (input_location, COND_EXPR,
1181 TREE_TYPE (parmse->expr),
1182 cond, parmse->expr,
1183 fold_convert (TREE_TYPE (parmse->expr),
1184 null_pointer_node));
1188 /* Given a class array declaration and an index, returns the address
1189 of the referenced element. */
1191 tree
1192 gfc_get_class_array_ref (tree index, tree class_decl, tree data_comp,
1193 bool unlimited)
1195 tree data, size, tmp, ctmp, offset, ptr;
1197 data = data_comp != NULL_TREE ? data_comp :
1198 gfc_class_data_get (class_decl);
1199 size = gfc_class_vtab_size_get (class_decl);
1201 if (unlimited)
1203 tmp = fold_convert (gfc_array_index_type,
1204 gfc_class_len_get (class_decl));
1205 ctmp = fold_build2_loc (input_location, MULT_EXPR,
1206 gfc_array_index_type, size, tmp);
1207 tmp = fold_build2_loc (input_location, GT_EXPR,
1208 logical_type_node, tmp,
1209 build_zero_cst (TREE_TYPE (tmp)));
1210 size = fold_build3_loc (input_location, COND_EXPR,
1211 gfc_array_index_type, tmp, ctmp, size);
1214 offset = fold_build2_loc (input_location, MULT_EXPR,
1215 gfc_array_index_type,
1216 index, size);
1218 data = gfc_conv_descriptor_data_get (data);
1219 ptr = fold_convert (pvoid_type_node, data);
1220 ptr = fold_build_pointer_plus_loc (input_location, ptr, offset);
1221 return fold_convert (TREE_TYPE (data), ptr);
1225 /* Copies one class expression to another, assuming that if either
1226 'to' or 'from' are arrays they are packed. Should 'from' be
1227 NULL_TREE, the initialization expression for 'to' is used, assuming
1228 that the _vptr is set. */
1230 tree
1231 gfc_copy_class_to_class (tree from, tree to, tree nelems, bool unlimited)
1233 tree fcn;
1234 tree fcn_type;
1235 tree from_data;
1236 tree from_len;
1237 tree to_data;
1238 tree to_len;
1239 tree to_ref;
1240 tree from_ref;
1241 vec<tree, va_gc> *args;
1242 tree tmp;
1243 tree stdcopy;
1244 tree extcopy;
1245 tree index;
1246 bool is_from_desc = false, is_to_class = false;
1248 args = NULL;
1249 /* To prevent warnings on uninitialized variables. */
1250 from_len = to_len = NULL_TREE;
1252 if (from != NULL_TREE)
1253 fcn = gfc_class_vtab_copy_get (from);
1254 else
1255 fcn = gfc_class_vtab_copy_get (to);
1257 fcn_type = TREE_TYPE (TREE_TYPE (fcn));
1259 if (from != NULL_TREE)
1261 is_from_desc = GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (from));
1262 if (is_from_desc)
1264 from_data = from;
1265 from = GFC_DECL_SAVED_DESCRIPTOR (from);
1267 else
1269 /* Check that from is a class. When the class is part of a coarray,
1270 then from is a common pointer and is to be used as is. */
1271 tmp = POINTER_TYPE_P (TREE_TYPE (from))
1272 ? build_fold_indirect_ref (from) : from;
1273 from_data =
1274 (GFC_CLASS_TYPE_P (TREE_TYPE (tmp))
1275 || (DECL_P (tmp) && GFC_DECL_CLASS (tmp)))
1276 ? gfc_class_data_get (from) : from;
1277 is_from_desc = GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (from_data));
1280 else
1281 from_data = gfc_class_vtab_def_init_get (to);
1283 if (unlimited)
1285 if (from != NULL_TREE && unlimited)
1286 from_len = gfc_class_len_or_zero_get (from);
1287 else
1288 from_len = build_zero_cst (size_type_node);
1291 if (GFC_CLASS_TYPE_P (TREE_TYPE (to)))
1293 is_to_class = true;
1294 to_data = gfc_class_data_get (to);
1295 if (unlimited)
1296 to_len = gfc_class_len_get (to);
1298 else
1299 /* When to is a BT_DERIVED and not a BT_CLASS, then to_data == to. */
1300 to_data = to;
1302 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (to_data)))
1304 stmtblock_t loopbody;
1305 stmtblock_t body;
1306 stmtblock_t ifbody;
1307 gfc_loopinfo loop;
1308 tree orig_nelems = nelems; /* Needed for bounds check. */
1310 gfc_init_block (&body);
1311 tmp = fold_build2_loc (input_location, MINUS_EXPR,
1312 gfc_array_index_type, nelems,
1313 gfc_index_one_node);
1314 nelems = gfc_evaluate_now (tmp, &body);
1315 index = gfc_create_var (gfc_array_index_type, "S");
1317 if (is_from_desc)
1319 from_ref = gfc_get_class_array_ref (index, from, from_data,
1320 unlimited);
1321 vec_safe_push (args, from_ref);
1323 else
1324 vec_safe_push (args, from_data);
1326 if (is_to_class)
1327 to_ref = gfc_get_class_array_ref (index, to, to_data, unlimited);
1328 else
1330 tmp = gfc_conv_array_data (to);
1331 tmp = build_fold_indirect_ref_loc (input_location, tmp);
1332 to_ref = gfc_build_addr_expr (NULL_TREE,
1333 gfc_build_array_ref (tmp, index, to));
1335 vec_safe_push (args, to_ref);
1337 /* Add bounds check. */
1338 if ((gfc_option.rtcheck & GFC_RTCHECK_BOUNDS) > 0 && is_from_desc)
1340 char *msg;
1341 const char *name = "<<unknown>>";
1342 tree from_len;
1344 if (DECL_P (to))
1345 name = (const char *)(DECL_NAME (to)->identifier.id.str);
1347 from_len = gfc_conv_descriptor_size (from_data, 1);
1348 tmp = fold_build2_loc (input_location, NE_EXPR,
1349 logical_type_node, from_len, orig_nelems);
1350 msg = xasprintf ("Array bound mismatch for dimension %d "
1351 "of array '%s' (%%ld/%%ld)",
1352 1, name);
1354 gfc_trans_runtime_check (true, false, tmp, &body,
1355 &gfc_current_locus, msg,
1356 fold_convert (long_integer_type_node, orig_nelems),
1357 fold_convert (long_integer_type_node, from_len));
1359 free (msg);
1362 tmp = build_call_vec (fcn_type, fcn, args);
1364 /* Build the body of the loop. */
1365 gfc_init_block (&loopbody);
1366 gfc_add_expr_to_block (&loopbody, tmp);
1368 /* Build the loop and return. */
1369 gfc_init_loopinfo (&loop);
1370 loop.dimen = 1;
1371 loop.from[0] = gfc_index_zero_node;
1372 loop.loopvar[0] = index;
1373 loop.to[0] = nelems;
1374 gfc_trans_scalarizing_loops (&loop, &loopbody);
1375 gfc_init_block (&ifbody);
1376 gfc_add_block_to_block (&ifbody, &loop.pre);
1377 stdcopy = gfc_finish_block (&ifbody);
1378 /* In initialization mode from_len is a constant zero. */
1379 if (unlimited && !integer_zerop (from_len))
1381 vec_safe_push (args, from_len);
1382 vec_safe_push (args, to_len);
1383 tmp = build_call_vec (fcn_type, fcn, args);
1384 /* Build the body of the loop. */
1385 gfc_init_block (&loopbody);
1386 gfc_add_expr_to_block (&loopbody, tmp);
1388 /* Build the loop and return. */
1389 gfc_init_loopinfo (&loop);
1390 loop.dimen = 1;
1391 loop.from[0] = gfc_index_zero_node;
1392 loop.loopvar[0] = index;
1393 loop.to[0] = nelems;
1394 gfc_trans_scalarizing_loops (&loop, &loopbody);
1395 gfc_init_block (&ifbody);
1396 gfc_add_block_to_block (&ifbody, &loop.pre);
1397 extcopy = gfc_finish_block (&ifbody);
1399 tmp = fold_build2_loc (input_location, GT_EXPR,
1400 logical_type_node, from_len,
1401 build_zero_cst (TREE_TYPE (from_len)));
1402 tmp = fold_build3_loc (input_location, COND_EXPR,
1403 void_type_node, tmp, extcopy, stdcopy);
1404 gfc_add_expr_to_block (&body, tmp);
1405 tmp = gfc_finish_block (&body);
1407 else
1409 gfc_add_expr_to_block (&body, stdcopy);
1410 tmp = gfc_finish_block (&body);
1412 gfc_cleanup_loop (&loop);
1414 else
1416 gcc_assert (!is_from_desc);
1417 vec_safe_push (args, from_data);
1418 vec_safe_push (args, to_data);
1419 stdcopy = build_call_vec (fcn_type, fcn, args);
1421 /* In initialization mode from_len is a constant zero. */
1422 if (unlimited && !integer_zerop (from_len))
1424 vec_safe_push (args, from_len);
1425 vec_safe_push (args, to_len);
1426 extcopy = build_call_vec (fcn_type, fcn, args);
1427 tmp = fold_build2_loc (input_location, GT_EXPR,
1428 logical_type_node, from_len,
1429 build_zero_cst (TREE_TYPE (from_len)));
1430 tmp = fold_build3_loc (input_location, COND_EXPR,
1431 void_type_node, tmp, extcopy, stdcopy);
1433 else
1434 tmp = stdcopy;
1437 /* Only copy _def_init to to_data, when it is not a NULL-pointer. */
1438 if (from == NULL_TREE)
1440 tree cond;
1441 cond = fold_build2_loc (input_location, NE_EXPR,
1442 logical_type_node,
1443 from_data, null_pointer_node);
1444 tmp = fold_build3_loc (input_location, COND_EXPR,
1445 void_type_node, cond,
1446 tmp, build_empty_stmt (input_location));
1449 return tmp;
1453 static tree
1454 gfc_trans_class_array_init_assign (gfc_expr *rhs, gfc_expr *lhs, gfc_expr *obj)
1456 gfc_actual_arglist *actual;
1457 gfc_expr *ppc;
1458 gfc_code *ppc_code;
1459 tree res;
1461 actual = gfc_get_actual_arglist ();
1462 actual->expr = gfc_copy_expr (rhs);
1463 actual->next = gfc_get_actual_arglist ();
1464 actual->next->expr = gfc_copy_expr (lhs);
1465 ppc = gfc_copy_expr (obj);
1466 gfc_add_vptr_component (ppc);
1467 gfc_add_component_ref (ppc, "_copy");
1468 ppc_code = gfc_get_code (EXEC_CALL);
1469 ppc_code->resolved_sym = ppc->symtree->n.sym;
1470 /* Although '_copy' is set to be elemental in class.c, it is
1471 not staying that way. Find out why, sometime.... */
1472 ppc_code->resolved_sym->attr.elemental = 1;
1473 ppc_code->ext.actual = actual;
1474 ppc_code->expr1 = ppc;
1475 /* Since '_copy' is elemental, the scalarizer will take care
1476 of arrays in gfc_trans_call. */
1477 res = gfc_trans_call (ppc_code, false, NULL, NULL, false);
1478 gfc_free_statements (ppc_code);
1480 if (UNLIMITED_POLY(obj))
1482 /* Check if rhs is non-NULL. */
1483 gfc_se src;
1484 gfc_init_se (&src, NULL);
1485 gfc_conv_expr (&src, rhs);
1486 src.expr = gfc_build_addr_expr (NULL_TREE, src.expr);
1487 tree cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
1488 src.expr, fold_convert (TREE_TYPE (src.expr),
1489 null_pointer_node));
1490 res = build3_loc (input_location, COND_EXPR, TREE_TYPE (res), cond, res,
1491 build_empty_stmt (input_location));
1494 return res;
1497 /* Special case for initializing a polymorphic dummy with INTENT(OUT).
1498 A MEMCPY is needed to copy the full data from the default initializer
1499 of the dynamic type. */
1501 tree
1502 gfc_trans_class_init_assign (gfc_code *code)
1504 stmtblock_t block;
1505 tree tmp;
1506 gfc_se dst,src,memsz;
1507 gfc_expr *lhs, *rhs, *sz;
1509 gfc_start_block (&block);
1511 lhs = gfc_copy_expr (code->expr1);
1513 rhs = gfc_copy_expr (code->expr1);
1514 gfc_add_vptr_component (rhs);
1516 /* Make sure that the component backend_decls have been built, which
1517 will not have happened if the derived types concerned have not
1518 been referenced. */
1519 gfc_get_derived_type (rhs->ts.u.derived);
1520 gfc_add_def_init_component (rhs);
1521 /* The _def_init is always scalar. */
1522 rhs->rank = 0;
1524 if (code->expr1->ts.type == BT_CLASS
1525 && CLASS_DATA (code->expr1)->attr.dimension)
1527 gfc_array_spec *tmparr = gfc_get_array_spec ();
1528 *tmparr = *CLASS_DATA (code->expr1)->as;
1529 /* Adding the array ref to the class expression results in correct
1530 indexing to the dynamic type. */
1531 gfc_add_full_array_ref (lhs, tmparr);
1532 tmp = gfc_trans_class_array_init_assign (rhs, lhs, code->expr1);
1534 else
1536 /* Scalar initialization needs the _data component. */
1537 gfc_add_data_component (lhs);
1538 sz = gfc_copy_expr (code->expr1);
1539 gfc_add_vptr_component (sz);
1540 gfc_add_size_component (sz);
1542 gfc_init_se (&dst, NULL);
1543 gfc_init_se (&src, NULL);
1544 gfc_init_se (&memsz, NULL);
1545 gfc_conv_expr (&dst, lhs);
1546 gfc_conv_expr (&src, rhs);
1547 gfc_conv_expr (&memsz, sz);
1548 gfc_add_block_to_block (&block, &src.pre);
1549 src.expr = gfc_build_addr_expr (NULL_TREE, src.expr);
1551 tmp = gfc_build_memcpy_call (dst.expr, src.expr, memsz.expr);
1553 if (UNLIMITED_POLY(code->expr1))
1555 /* Check if _def_init is non-NULL. */
1556 tree cond = fold_build2_loc (input_location, NE_EXPR,
1557 logical_type_node, src.expr,
1558 fold_convert (TREE_TYPE (src.expr),
1559 null_pointer_node));
1560 tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp), cond,
1561 tmp, build_empty_stmt (input_location));
1565 if (code->expr1->symtree->n.sym->attr.optional
1566 || code->expr1->symtree->n.sym->ns->proc_name->attr.entry_master)
1568 tree present = gfc_conv_expr_present (code->expr1->symtree->n.sym);
1569 tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp),
1570 present, tmp,
1571 build_empty_stmt (input_location));
1574 gfc_add_expr_to_block (&block, tmp);
1576 return gfc_finish_block (&block);
1580 /* End of prototype trans-class.c */
1583 static void
1584 realloc_lhs_warning (bt type, bool array, locus *where)
1586 if (array && type != BT_CLASS && type != BT_DERIVED && warn_realloc_lhs)
1587 gfc_warning (OPT_Wrealloc_lhs,
1588 "Code for reallocating the allocatable array at %L will "
1589 "be added", where);
1590 else if (warn_realloc_lhs_all)
1591 gfc_warning (OPT_Wrealloc_lhs_all,
1592 "Code for reallocating the allocatable variable at %L "
1593 "will be added", where);
1597 static void gfc_apply_interface_mapping_to_expr (gfc_interface_mapping *,
1598 gfc_expr *);
1600 /* Copy the scalarization loop variables. */
1602 static void
1603 gfc_copy_se_loopvars (gfc_se * dest, gfc_se * src)
1605 dest->ss = src->ss;
1606 dest->loop = src->loop;
1610 /* Initialize a simple expression holder.
1612 Care must be taken when multiple se are created with the same parent.
1613 The child se must be kept in sync. The easiest way is to delay creation
1614 of a child se until after after the previous se has been translated. */
1616 void
1617 gfc_init_se (gfc_se * se, gfc_se * parent)
1619 memset (se, 0, sizeof (gfc_se));
1620 gfc_init_block (&se->pre);
1621 gfc_init_block (&se->post);
1623 se->parent = parent;
1625 if (parent)
1626 gfc_copy_se_loopvars (se, parent);
1630 /* Advances to the next SS in the chain. Use this rather than setting
1631 se->ss = se->ss->next because all the parents needs to be kept in sync.
1632 See gfc_init_se. */
1634 void
1635 gfc_advance_se_ss_chain (gfc_se * se)
1637 gfc_se *p;
1638 gfc_ss *ss;
1640 gcc_assert (se != NULL && se->ss != NULL && se->ss != gfc_ss_terminator);
1642 p = se;
1643 /* Walk down the parent chain. */
1644 while (p != NULL)
1646 /* Simple consistency check. */
1647 gcc_assert (p->parent == NULL || p->parent->ss == p->ss
1648 || p->parent->ss->nested_ss == p->ss);
1650 /* If we were in a nested loop, the next scalarized expression can be
1651 on the parent ss' next pointer. Thus we should not take the next
1652 pointer blindly, but rather go up one nest level as long as next
1653 is the end of chain. */
1654 ss = p->ss;
1655 while (ss->next == gfc_ss_terminator && ss->parent != NULL)
1656 ss = ss->parent;
1658 p->ss = ss->next;
1660 p = p->parent;
1665 /* Ensures the result of the expression as either a temporary variable
1666 or a constant so that it can be used repeatedly. */
1668 void
1669 gfc_make_safe_expr (gfc_se * se)
1671 tree var;
1673 if (CONSTANT_CLASS_P (se->expr))
1674 return;
1676 /* We need a temporary for this result. */
1677 var = gfc_create_var (TREE_TYPE (se->expr), NULL);
1678 gfc_add_modify (&se->pre, var, se->expr);
1679 se->expr = var;
1683 /* Return an expression which determines if a dummy parameter is present.
1684 Also used for arguments to procedures with multiple entry points. */
1686 tree
1687 gfc_conv_expr_present (gfc_symbol * sym)
1689 tree decl, cond;
1691 gcc_assert (sym->attr.dummy);
1692 decl = gfc_get_symbol_decl (sym);
1694 /* Intrinsic scalars with VALUE attribute which are passed by value
1695 use a hidden argument to denote the present status. */
1696 if (sym->attr.value && sym->ts.type != BT_CHARACTER
1697 && sym->ts.type != BT_CLASS && sym->ts.type != BT_DERIVED
1698 && !sym->attr.dimension)
1700 char name[GFC_MAX_SYMBOL_LEN + 2];
1701 tree tree_name;
1703 gcc_assert (TREE_CODE (decl) == PARM_DECL);
1704 name[0] = '_';
1705 strcpy (&name[1], sym->name);
1706 tree_name = get_identifier (name);
1708 /* Walk function argument list to find hidden arg. */
1709 cond = DECL_ARGUMENTS (DECL_CONTEXT (decl));
1710 for ( ; cond != NULL_TREE; cond = TREE_CHAIN (cond))
1711 if (DECL_NAME (cond) == tree_name)
1712 break;
1714 gcc_assert (cond);
1715 return cond;
1718 if (TREE_CODE (decl) != PARM_DECL)
1720 /* Array parameters use a temporary descriptor, we want the real
1721 parameter. */
1722 gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl))
1723 || GFC_ARRAY_TYPE_P (TREE_TYPE (decl)));
1724 decl = GFC_DECL_SAVED_DESCRIPTOR (decl);
1727 cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node, decl,
1728 fold_convert (TREE_TYPE (decl), null_pointer_node));
1730 /* Fortran 2008 allows to pass null pointers and non-associated pointers
1731 as actual argument to denote absent dummies. For array descriptors,
1732 we thus also need to check the array descriptor. For BT_CLASS, it
1733 can also occur for scalars and F2003 due to type->class wrapping and
1734 class->class wrapping. Note further that BT_CLASS always uses an
1735 array descriptor for arrays, also for explicit-shape/assumed-size. */
1737 if (!sym->attr.allocatable
1738 && ((sym->ts.type != BT_CLASS && !sym->attr.pointer)
1739 || (sym->ts.type == BT_CLASS
1740 && !CLASS_DATA (sym)->attr.allocatable
1741 && !CLASS_DATA (sym)->attr.class_pointer))
1742 && ((gfc_option.allow_std & GFC_STD_F2008) != 0
1743 || sym->ts.type == BT_CLASS))
1745 tree tmp;
1747 if ((sym->as && (sym->as->type == AS_ASSUMED_SHAPE
1748 || sym->as->type == AS_ASSUMED_RANK
1749 || sym->attr.codimension))
1750 || (sym->ts.type == BT_CLASS && CLASS_DATA (sym)->as))
1752 tmp = build_fold_indirect_ref_loc (input_location, decl);
1753 if (sym->ts.type == BT_CLASS)
1754 tmp = gfc_class_data_get (tmp);
1755 tmp = gfc_conv_array_data (tmp);
1757 else if (sym->ts.type == BT_CLASS)
1758 tmp = gfc_class_data_get (decl);
1759 else
1760 tmp = NULL_TREE;
1762 if (tmp != NULL_TREE)
1764 tmp = fold_build2_loc (input_location, NE_EXPR, logical_type_node, tmp,
1765 fold_convert (TREE_TYPE (tmp), null_pointer_node));
1766 cond = fold_build2_loc (input_location, TRUTH_ANDIF_EXPR,
1767 logical_type_node, cond, tmp);
1771 return cond;
1775 /* Converts a missing, dummy argument into a null or zero. */
1777 void
1778 gfc_conv_missing_dummy (gfc_se * se, gfc_expr * arg, gfc_typespec ts, int kind)
1780 tree present;
1781 tree tmp;
1783 present = gfc_conv_expr_present (arg->symtree->n.sym);
1785 if (kind > 0)
1787 /* Create a temporary and convert it to the correct type. */
1788 tmp = gfc_get_int_type (kind);
1789 tmp = fold_convert (tmp, build_fold_indirect_ref_loc (input_location,
1790 se->expr));
1792 /* Test for a NULL value. */
1793 tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp), present,
1794 tmp, fold_convert (TREE_TYPE (tmp), integer_one_node));
1795 tmp = gfc_evaluate_now (tmp, &se->pre);
1796 se->expr = gfc_build_addr_expr (NULL_TREE, tmp);
1798 else
1800 tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (se->expr),
1801 present, se->expr,
1802 build_zero_cst (TREE_TYPE (se->expr)));
1803 tmp = gfc_evaluate_now (tmp, &se->pre);
1804 se->expr = tmp;
1807 if (ts.type == BT_CHARACTER)
1809 tmp = build_int_cst (gfc_charlen_type_node, 0);
1810 tmp = fold_build3_loc (input_location, COND_EXPR, gfc_charlen_type_node,
1811 present, se->string_length, tmp);
1812 tmp = gfc_evaluate_now (tmp, &se->pre);
1813 se->string_length = tmp;
1815 return;
1819 /* Get the character length of an expression, looking through gfc_refs
1820 if necessary. */
1822 tree
1823 gfc_get_expr_charlen (gfc_expr *e)
1825 gfc_ref *r;
1826 tree length;
1828 gcc_assert (e->expr_type == EXPR_VARIABLE
1829 && e->ts.type == BT_CHARACTER);
1831 length = NULL; /* To silence compiler warning. */
1833 if (is_subref_array (e) && e->ts.u.cl->length)
1835 gfc_se tmpse;
1836 gfc_init_se (&tmpse, NULL);
1837 gfc_conv_expr_type (&tmpse, e->ts.u.cl->length, gfc_charlen_type_node);
1838 e->ts.u.cl->backend_decl = tmpse.expr;
1839 return tmpse.expr;
1842 /* First candidate: if the variable is of type CHARACTER, the
1843 expression's length could be the length of the character
1844 variable. */
1845 if (e->symtree->n.sym->ts.type == BT_CHARACTER)
1846 length = e->symtree->n.sym->ts.u.cl->backend_decl;
1848 /* Look through the reference chain for component references. */
1849 for (r = e->ref; r; r = r->next)
1851 switch (r->type)
1853 case REF_COMPONENT:
1854 if (r->u.c.component->ts.type == BT_CHARACTER)
1855 length = r->u.c.component->ts.u.cl->backend_decl;
1856 break;
1858 case REF_ARRAY:
1859 /* Do nothing. */
1860 break;
1862 default:
1863 /* We should never got substring references here. These will be
1864 broken down by the scalarizer. */
1865 gcc_unreachable ();
1866 break;
1870 gcc_assert (length != NULL);
1871 return length;
1875 /* Return for an expression the backend decl of the coarray. */
1877 tree
1878 gfc_get_tree_for_caf_expr (gfc_expr *expr)
1880 tree caf_decl;
1881 bool found = false;
1882 gfc_ref *ref;
1884 gcc_assert (expr && expr->expr_type == EXPR_VARIABLE);
1886 /* Not-implemented diagnostic. */
1887 if (expr->symtree->n.sym->ts.type == BT_CLASS
1888 && UNLIMITED_POLY (expr->symtree->n.sym)
1889 && CLASS_DATA (expr->symtree->n.sym)->attr.codimension)
1890 gfc_error ("Sorry, coindexed access to an unlimited polymorphic object at "
1891 "%L is not supported", &expr->where);
1893 for (ref = expr->ref; ref; ref = ref->next)
1894 if (ref->type == REF_COMPONENT)
1896 if (ref->u.c.component->ts.type == BT_CLASS
1897 && UNLIMITED_POLY (ref->u.c.component)
1898 && CLASS_DATA (ref->u.c.component)->attr.codimension)
1899 gfc_error ("Sorry, coindexed access to an unlimited polymorphic "
1900 "component at %L is not supported", &expr->where);
1903 /* Make sure the backend_decl is present before accessing it. */
1904 caf_decl = expr->symtree->n.sym->backend_decl == NULL_TREE
1905 ? gfc_get_symbol_decl (expr->symtree->n.sym)
1906 : expr->symtree->n.sym->backend_decl;
1908 if (expr->symtree->n.sym->ts.type == BT_CLASS)
1910 if (expr->ref && expr->ref->type == REF_ARRAY)
1912 caf_decl = gfc_class_data_get (caf_decl);
1913 if (CLASS_DATA (expr->symtree->n.sym)->attr.codimension)
1914 return caf_decl;
1916 for (ref = expr->ref; ref; ref = ref->next)
1918 if (ref->type == REF_COMPONENT
1919 && strcmp (ref->u.c.component->name, "_data") != 0)
1921 caf_decl = gfc_class_data_get (caf_decl);
1922 if (CLASS_DATA (expr->symtree->n.sym)->attr.codimension)
1923 return caf_decl;
1924 break;
1926 else if (ref->type == REF_ARRAY && ref->u.ar.dimen)
1927 break;
1930 if (expr->symtree->n.sym->attr.codimension)
1931 return caf_decl;
1933 /* The following code assumes that the coarray is a component reachable via
1934 only scalar components/variables; the Fortran standard guarantees this. */
1936 for (ref = expr->ref; ref; ref = ref->next)
1937 if (ref->type == REF_COMPONENT)
1939 gfc_component *comp = ref->u.c.component;
1941 if (POINTER_TYPE_P (TREE_TYPE (caf_decl)))
1942 caf_decl = build_fold_indirect_ref_loc (input_location, caf_decl);
1943 caf_decl = fold_build3_loc (input_location, COMPONENT_REF,
1944 TREE_TYPE (comp->backend_decl), caf_decl,
1945 comp->backend_decl, NULL_TREE);
1946 if (comp->ts.type == BT_CLASS)
1948 caf_decl = gfc_class_data_get (caf_decl);
1949 if (CLASS_DATA (comp)->attr.codimension)
1951 found = true;
1952 break;
1955 if (comp->attr.codimension)
1957 found = true;
1958 break;
1961 gcc_assert (found && caf_decl);
1962 return caf_decl;
1966 /* Obtain the Coarray token - and optionally also the offset. */
1968 void
1969 gfc_get_caf_token_offset (gfc_se *se, tree *token, tree *offset, tree caf_decl,
1970 tree se_expr, gfc_expr *expr)
1972 tree tmp;
1974 /* Coarray token. */
1975 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (caf_decl)))
1977 gcc_assert (GFC_TYPE_ARRAY_AKIND (TREE_TYPE (caf_decl))
1978 == GFC_ARRAY_ALLOCATABLE
1979 || expr->symtree->n.sym->attr.select_type_temporary);
1980 *token = gfc_conv_descriptor_token (caf_decl);
1982 else if (DECL_LANG_SPECIFIC (caf_decl)
1983 && GFC_DECL_TOKEN (caf_decl) != NULL_TREE)
1984 *token = GFC_DECL_TOKEN (caf_decl);
1985 else
1987 gcc_assert (GFC_ARRAY_TYPE_P (TREE_TYPE (caf_decl))
1988 && GFC_TYPE_ARRAY_CAF_TOKEN (TREE_TYPE (caf_decl)) != NULL_TREE);
1989 *token = GFC_TYPE_ARRAY_CAF_TOKEN (TREE_TYPE (caf_decl));
1992 if (offset == NULL)
1993 return;
1995 /* Offset between the coarray base address and the address wanted. */
1996 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (caf_decl))
1997 && (GFC_TYPE_ARRAY_AKIND (TREE_TYPE (caf_decl)) == GFC_ARRAY_ALLOCATABLE
1998 || GFC_TYPE_ARRAY_AKIND (TREE_TYPE (caf_decl)) == GFC_ARRAY_POINTER))
1999 *offset = build_int_cst (gfc_array_index_type, 0);
2000 else if (DECL_LANG_SPECIFIC (caf_decl)
2001 && GFC_DECL_CAF_OFFSET (caf_decl) != NULL_TREE)
2002 *offset = GFC_DECL_CAF_OFFSET (caf_decl);
2003 else if (GFC_TYPE_ARRAY_CAF_OFFSET (TREE_TYPE (caf_decl)) != NULL_TREE)
2004 *offset = GFC_TYPE_ARRAY_CAF_OFFSET (TREE_TYPE (caf_decl));
2005 else
2006 *offset = build_int_cst (gfc_array_index_type, 0);
2008 if (POINTER_TYPE_P (TREE_TYPE (se_expr))
2009 && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (TREE_TYPE (se_expr))))
2011 tmp = build_fold_indirect_ref_loc (input_location, se_expr);
2012 tmp = gfc_conv_descriptor_data_get (tmp);
2014 else if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se_expr)))
2015 tmp = gfc_conv_descriptor_data_get (se_expr);
2016 else
2018 gcc_assert (POINTER_TYPE_P (TREE_TYPE (se_expr)));
2019 tmp = se_expr;
2022 *offset = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
2023 *offset, fold_convert (gfc_array_index_type, tmp));
2025 if (expr->symtree->n.sym->ts.type == BT_DERIVED
2026 && expr->symtree->n.sym->attr.codimension
2027 && expr->symtree->n.sym->ts.u.derived->attr.alloc_comp)
2029 gfc_expr *base_expr = gfc_copy_expr (expr);
2030 gfc_ref *ref = base_expr->ref;
2031 gfc_se base_se;
2033 // Iterate through the refs until the last one.
2034 while (ref->next)
2035 ref = ref->next;
2037 if (ref->type == REF_ARRAY
2038 && ref->u.ar.type != AR_FULL)
2040 const int ranksum = ref->u.ar.dimen + ref->u.ar.codimen;
2041 int i;
2042 for (i = 0; i < ranksum; ++i)
2044 ref->u.ar.start[i] = NULL;
2045 ref->u.ar.end[i] = NULL;
2047 ref->u.ar.type = AR_FULL;
2049 gfc_init_se (&base_se, NULL);
2050 if (gfc_caf_attr (base_expr).dimension)
2052 gfc_conv_expr_descriptor (&base_se, base_expr);
2053 tmp = gfc_conv_descriptor_data_get (base_se.expr);
2055 else
2057 gfc_conv_expr (&base_se, base_expr);
2058 tmp = base_se.expr;
2061 gfc_free_expr (base_expr);
2062 gfc_add_block_to_block (&se->pre, &base_se.pre);
2063 gfc_add_block_to_block (&se->post, &base_se.post);
2065 else if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (caf_decl)))
2066 tmp = gfc_conv_descriptor_data_get (caf_decl);
2067 else
2069 gcc_assert (POINTER_TYPE_P (TREE_TYPE (caf_decl)));
2070 tmp = caf_decl;
2073 *offset = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
2074 fold_convert (gfc_array_index_type, *offset),
2075 fold_convert (gfc_array_index_type, tmp));
2079 /* Convert the coindex of a coarray into an image index; the result is
2080 image_num = (idx(1)-lcobound(1)+1) + (idx(2)-lcobound(2))*extent(1)
2081 + (idx(3)-lcobound(3))*extend(1)*extent(2) + ... */
2083 tree
2084 gfc_caf_get_image_index (stmtblock_t *block, gfc_expr *e, tree desc)
2086 gfc_ref *ref;
2087 tree lbound, ubound, extent, tmp, img_idx;
2088 gfc_se se;
2089 int i;
2091 for (ref = e->ref; ref; ref = ref->next)
2092 if (ref->type == REF_ARRAY && ref->u.ar.codimen > 0)
2093 break;
2094 gcc_assert (ref != NULL);
2096 if (ref->u.ar.dimen_type[ref->u.ar.dimen] == DIMEN_THIS_IMAGE)
2098 return build_call_expr_loc (input_location, gfor_fndecl_caf_this_image, 1,
2099 integer_zero_node);
2102 img_idx = build_zero_cst (gfc_array_index_type);
2103 extent = build_one_cst (gfc_array_index_type);
2104 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (desc)))
2105 for (i = ref->u.ar.dimen; i < ref->u.ar.dimen + ref->u.ar.codimen; i++)
2107 gfc_init_se (&se, NULL);
2108 gfc_conv_expr_type (&se, ref->u.ar.start[i], gfc_array_index_type);
2109 gfc_add_block_to_block (block, &se.pre);
2110 lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[i]);
2111 tmp = fold_build2_loc (input_location, MINUS_EXPR,
2112 TREE_TYPE (lbound), se.expr, lbound);
2113 tmp = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (tmp),
2114 extent, tmp);
2115 img_idx = fold_build2_loc (input_location, PLUS_EXPR,
2116 TREE_TYPE (tmp), img_idx, tmp);
2117 if (i < ref->u.ar.dimen + ref->u.ar.codimen - 1)
2119 ubound = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[i]);
2120 tmp = gfc_conv_array_extent_dim (lbound, ubound, NULL);
2121 extent = fold_build2_loc (input_location, MULT_EXPR,
2122 TREE_TYPE (tmp), extent, tmp);
2125 else
2126 for (i = ref->u.ar.dimen; i < ref->u.ar.dimen + ref->u.ar.codimen; i++)
2128 gfc_init_se (&se, NULL);
2129 gfc_conv_expr_type (&se, ref->u.ar.start[i], gfc_array_index_type);
2130 gfc_add_block_to_block (block, &se.pre);
2131 lbound = GFC_TYPE_ARRAY_LBOUND (TREE_TYPE (desc), i);
2132 tmp = fold_build2_loc (input_location, MINUS_EXPR,
2133 TREE_TYPE (lbound), se.expr, lbound);
2134 tmp = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (tmp),
2135 extent, tmp);
2136 img_idx = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (tmp),
2137 img_idx, tmp);
2138 if (i < ref->u.ar.dimen + ref->u.ar.codimen - 1)
2140 ubound = GFC_TYPE_ARRAY_UBOUND (TREE_TYPE (desc), i);
2141 tmp = fold_build2_loc (input_location, MINUS_EXPR,
2142 TREE_TYPE (ubound), ubound, lbound);
2143 tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (tmp),
2144 tmp, build_one_cst (TREE_TYPE (tmp)));
2145 extent = fold_build2_loc (input_location, MULT_EXPR,
2146 TREE_TYPE (tmp), extent, tmp);
2149 img_idx = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (img_idx),
2150 img_idx, build_one_cst (TREE_TYPE (img_idx)));
2151 return fold_convert (integer_type_node, img_idx);
2155 /* For each character array constructor subexpression without a ts.u.cl->length,
2156 replace it by its first element (if there aren't any elements, the length
2157 should already be set to zero). */
2159 static void
2160 flatten_array_ctors_without_strlen (gfc_expr* e)
2162 gfc_actual_arglist* arg;
2163 gfc_constructor* c;
2165 if (!e)
2166 return;
2168 switch (e->expr_type)
2171 case EXPR_OP:
2172 flatten_array_ctors_without_strlen (e->value.op.op1);
2173 flatten_array_ctors_without_strlen (e->value.op.op2);
2174 break;
2176 case EXPR_COMPCALL:
2177 /* TODO: Implement as with EXPR_FUNCTION when needed. */
2178 gcc_unreachable ();
2180 case EXPR_FUNCTION:
2181 for (arg = e->value.function.actual; arg; arg = arg->next)
2182 flatten_array_ctors_without_strlen (arg->expr);
2183 break;
2185 case EXPR_ARRAY:
2187 /* We've found what we're looking for. */
2188 if (e->ts.type == BT_CHARACTER && !e->ts.u.cl->length)
2190 gfc_constructor *c;
2191 gfc_expr* new_expr;
2193 gcc_assert (e->value.constructor);
2195 c = gfc_constructor_first (e->value.constructor);
2196 new_expr = c->expr;
2197 c->expr = NULL;
2199 flatten_array_ctors_without_strlen (new_expr);
2200 gfc_replace_expr (e, new_expr);
2201 break;
2204 /* Otherwise, fall through to handle constructor elements. */
2205 gcc_fallthrough ();
2206 case EXPR_STRUCTURE:
2207 for (c = gfc_constructor_first (e->value.constructor);
2208 c; c = gfc_constructor_next (c))
2209 flatten_array_ctors_without_strlen (c->expr);
2210 break;
2212 default:
2213 break;
2219 /* Generate code to initialize a string length variable. Returns the
2220 value. For array constructors, cl->length might be NULL and in this case,
2221 the first element of the constructor is needed. expr is the original
2222 expression so we can access it but can be NULL if this is not needed. */
2224 void
2225 gfc_conv_string_length (gfc_charlen * cl, gfc_expr * expr, stmtblock_t * pblock)
2227 gfc_se se;
2229 gfc_init_se (&se, NULL);
2231 if (!cl->length && cl->backend_decl && VAR_P (cl->backend_decl))
2232 return;
2234 /* If cl->length is NULL, use gfc_conv_expr to obtain the string length but
2235 "flatten" array constructors by taking their first element; all elements
2236 should be the same length or a cl->length should be present. */
2237 if (!cl->length)
2239 gfc_expr* expr_flat;
2240 if (!expr)
2241 return;
2242 expr_flat = gfc_copy_expr (expr);
2243 flatten_array_ctors_without_strlen (expr_flat);
2244 gfc_resolve_expr (expr_flat);
2246 gfc_conv_expr (&se, expr_flat);
2247 gfc_add_block_to_block (pblock, &se.pre);
2248 cl->backend_decl = convert (gfc_charlen_type_node, se.string_length);
2250 gfc_free_expr (expr_flat);
2251 return;
2254 /* Convert cl->length. */
2256 gcc_assert (cl->length);
2258 gfc_conv_expr_type (&se, cl->length, gfc_charlen_type_node);
2259 se.expr = fold_build2_loc (input_location, MAX_EXPR, gfc_charlen_type_node,
2260 se.expr, build_zero_cst (TREE_TYPE (se.expr)));
2261 gfc_add_block_to_block (pblock, &se.pre);
2263 if (cl->backend_decl)
2264 gfc_add_modify (pblock, cl->backend_decl, se.expr);
2265 else
2266 cl->backend_decl = gfc_evaluate_now (se.expr, pblock);
2270 static void
2271 gfc_conv_substring (gfc_se * se, gfc_ref * ref, int kind,
2272 const char *name, locus *where)
2274 tree tmp;
2275 tree type;
2276 tree fault;
2277 gfc_se start;
2278 gfc_se end;
2279 char *msg;
2280 mpz_t length;
2282 type = gfc_get_character_type (kind, ref->u.ss.length);
2283 type = build_pointer_type (type);
2285 gfc_init_se (&start, se);
2286 gfc_conv_expr_type (&start, ref->u.ss.start, gfc_charlen_type_node);
2287 gfc_add_block_to_block (&se->pre, &start.pre);
2289 if (integer_onep (start.expr))
2290 gfc_conv_string_parameter (se);
2291 else
2293 tmp = start.expr;
2294 STRIP_NOPS (tmp);
2295 /* Avoid multiple evaluation of substring start. */
2296 if (!CONSTANT_CLASS_P (tmp) && !DECL_P (tmp))
2297 start.expr = gfc_evaluate_now (start.expr, &se->pre);
2299 /* Change the start of the string. */
2300 if (TYPE_STRING_FLAG (TREE_TYPE (se->expr)))
2301 tmp = se->expr;
2302 else
2303 tmp = build_fold_indirect_ref_loc (input_location,
2304 se->expr);
2305 tmp = gfc_build_array_ref (tmp, start.expr, NULL);
2306 se->expr = gfc_build_addr_expr (type, tmp);
2309 /* Length = end + 1 - start. */
2310 gfc_init_se (&end, se);
2311 if (ref->u.ss.end == NULL)
2312 end.expr = se->string_length;
2313 else
2315 gfc_conv_expr_type (&end, ref->u.ss.end, gfc_charlen_type_node);
2316 gfc_add_block_to_block (&se->pre, &end.pre);
2318 tmp = end.expr;
2319 STRIP_NOPS (tmp);
2320 if (!CONSTANT_CLASS_P (tmp) && !DECL_P (tmp))
2321 end.expr = gfc_evaluate_now (end.expr, &se->pre);
2323 if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
2325 tree nonempty = fold_build2_loc (input_location, LE_EXPR,
2326 logical_type_node, start.expr,
2327 end.expr);
2329 /* Check lower bound. */
2330 fault = fold_build2_loc (input_location, LT_EXPR, logical_type_node,
2331 start.expr,
2332 build_one_cst (TREE_TYPE (start.expr)));
2333 fault = fold_build2_loc (input_location, TRUTH_ANDIF_EXPR,
2334 logical_type_node, nonempty, fault);
2335 if (name)
2336 msg = xasprintf ("Substring out of bounds: lower bound (%%ld) of '%s' "
2337 "is less than one", name);
2338 else
2339 msg = xasprintf ("Substring out of bounds: lower bound (%%ld) "
2340 "is less than one");
2341 gfc_trans_runtime_check (true, false, fault, &se->pre, where, msg,
2342 fold_convert (long_integer_type_node,
2343 start.expr));
2344 free (msg);
2346 /* Check upper bound. */
2347 fault = fold_build2_loc (input_location, GT_EXPR, logical_type_node,
2348 end.expr, se->string_length);
2349 fault = fold_build2_loc (input_location, TRUTH_ANDIF_EXPR,
2350 logical_type_node, nonempty, fault);
2351 if (name)
2352 msg = xasprintf ("Substring out of bounds: upper bound (%%ld) of '%s' "
2353 "exceeds string length (%%ld)", name);
2354 else
2355 msg = xasprintf ("Substring out of bounds: upper bound (%%ld) "
2356 "exceeds string length (%%ld)");
2357 gfc_trans_runtime_check (true, false, fault, &se->pre, where, msg,
2358 fold_convert (long_integer_type_node, end.expr),
2359 fold_convert (long_integer_type_node,
2360 se->string_length));
2361 free (msg);
2364 /* Try to calculate the length from the start and end expressions. */
2365 if (ref->u.ss.end
2366 && gfc_dep_difference (ref->u.ss.end, ref->u.ss.start, &length))
2368 HOST_WIDE_INT i_len;
2370 i_len = gfc_mpz_get_hwi (length) + 1;
2371 if (i_len < 0)
2372 i_len = 0;
2374 tmp = build_int_cst (gfc_charlen_type_node, i_len);
2375 mpz_clear (length); /* Was initialized by gfc_dep_difference. */
2377 else
2379 tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_charlen_type_node,
2380 fold_convert (gfc_charlen_type_node, end.expr),
2381 fold_convert (gfc_charlen_type_node, start.expr));
2382 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_charlen_type_node,
2383 build_int_cst (gfc_charlen_type_node, 1), tmp);
2384 tmp = fold_build2_loc (input_location, MAX_EXPR, gfc_charlen_type_node,
2385 tmp, build_int_cst (gfc_charlen_type_node, 0));
2388 se->string_length = tmp;
2392 /* Convert a derived type component reference. */
2394 static void
2395 gfc_conv_component_ref (gfc_se * se, gfc_ref * ref)
2397 gfc_component *c;
2398 tree tmp;
2399 tree decl;
2400 tree field;
2401 tree context;
2403 c = ref->u.c.component;
2405 if (c->backend_decl == NULL_TREE
2406 && ref->u.c.sym != NULL)
2407 gfc_get_derived_type (ref->u.c.sym);
2409 field = c->backend_decl;
2410 gcc_assert (field && TREE_CODE (field) == FIELD_DECL);
2411 decl = se->expr;
2412 context = DECL_FIELD_CONTEXT (field);
2414 /* Components can correspond to fields of different containing
2415 types, as components are created without context, whereas
2416 a concrete use of a component has the type of decl as context.
2417 So, if the type doesn't match, we search the corresponding
2418 FIELD_DECL in the parent type. To not waste too much time
2419 we cache this result in norestrict_decl.
2420 On the other hand, if the context is a UNION or a MAP (a
2421 RECORD_TYPE within a UNION_TYPE) always use the given FIELD_DECL. */
2423 if (context != TREE_TYPE (decl)
2424 && !( TREE_CODE (TREE_TYPE (field)) == UNION_TYPE /* Field is union */
2425 || TREE_CODE (context) == UNION_TYPE)) /* Field is map */
2427 tree f2 = c->norestrict_decl;
2428 if (!f2 || DECL_FIELD_CONTEXT (f2) != TREE_TYPE (decl))
2429 for (f2 = TYPE_FIELDS (TREE_TYPE (decl)); f2; f2 = DECL_CHAIN (f2))
2430 if (TREE_CODE (f2) == FIELD_DECL
2431 && DECL_NAME (f2) == DECL_NAME (field))
2432 break;
2433 gcc_assert (f2);
2434 c->norestrict_decl = f2;
2435 field = f2;
2438 if (ref->u.c.sym && ref->u.c.sym->ts.type == BT_CLASS
2439 && strcmp ("_data", c->name) == 0)
2441 /* Found a ref to the _data component. Store the associated ref to
2442 the vptr in se->class_vptr. */
2443 se->class_vptr = gfc_class_vptr_get (decl);
2445 else
2446 se->class_vptr = NULL_TREE;
2448 tmp = fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field),
2449 decl, field, NULL_TREE);
2451 se->expr = tmp;
2453 /* Allocatable deferred char arrays are to be handled by the gfc_deferred_
2454 strlen () conditional below. */
2455 if (c->ts.type == BT_CHARACTER && !c->attr.proc_pointer
2456 && !(c->attr.allocatable && c->ts.deferred)
2457 && !c->attr.pdt_string)
2459 tmp = c->ts.u.cl->backend_decl;
2460 /* Components must always be constant length. */
2461 gcc_assert (tmp && INTEGER_CST_P (tmp));
2462 se->string_length = tmp;
2465 if (gfc_deferred_strlen (c, &field))
2467 tmp = fold_build3_loc (input_location, COMPONENT_REF,
2468 TREE_TYPE (field),
2469 decl, field, NULL_TREE);
2470 se->string_length = tmp;
2473 if (((c->attr.pointer || c->attr.allocatable)
2474 && (!c->attr.dimension && !c->attr.codimension)
2475 && c->ts.type != BT_CHARACTER)
2476 || c->attr.proc_pointer)
2477 se->expr = build_fold_indirect_ref_loc (input_location,
2478 se->expr);
2482 /* This function deals with component references to components of the
2483 parent type for derived type extensions. */
2484 static void
2485 conv_parent_component_references (gfc_se * se, gfc_ref * ref)
2487 gfc_component *c;
2488 gfc_component *cmp;
2489 gfc_symbol *dt;
2490 gfc_ref parent;
2492 dt = ref->u.c.sym;
2493 c = ref->u.c.component;
2495 /* Return if the component is in the parent type. */
2496 for (cmp = dt->components; cmp; cmp = cmp->next)
2497 if (strcmp (c->name, cmp->name) == 0)
2498 return;
2500 /* Build a gfc_ref to recursively call gfc_conv_component_ref. */
2501 parent.type = REF_COMPONENT;
2502 parent.next = NULL;
2503 parent.u.c.sym = dt;
2504 parent.u.c.component = dt->components;
2506 if (dt->backend_decl == NULL)
2507 gfc_get_derived_type (dt);
2509 /* Build the reference and call self. */
2510 gfc_conv_component_ref (se, &parent);
2511 parent.u.c.sym = dt->components->ts.u.derived;
2512 parent.u.c.component = c;
2513 conv_parent_component_references (se, &parent);
2517 static void
2518 conv_inquiry (gfc_se * se, gfc_ref * ref, gfc_expr *expr, gfc_typespec *ts)
2520 tree res = se->expr;
2522 switch (ref->u.i)
2524 case INQUIRY_RE:
2525 res = fold_build1_loc (input_location, REALPART_EXPR,
2526 TREE_TYPE (TREE_TYPE (res)), res);
2527 break;
2529 case INQUIRY_IM:
2530 res = fold_build1_loc (input_location, IMAGPART_EXPR,
2531 TREE_TYPE (TREE_TYPE (res)), res);
2532 break;
2534 case INQUIRY_KIND:
2535 res = build_int_cst (gfc_typenode_for_spec (&expr->ts),
2536 ts->kind);
2537 break;
2539 case INQUIRY_LEN:
2540 res = fold_convert (gfc_typenode_for_spec (&expr->ts),
2541 se->string_length);
2542 break;
2544 default:
2545 gcc_unreachable ();
2547 se->expr = res;
2550 /* Return the contents of a variable. Also handles reference/pointer
2551 variables (all Fortran pointer references are implicit). */
2553 static void
2554 gfc_conv_variable (gfc_se * se, gfc_expr * expr)
2556 gfc_ss *ss;
2557 gfc_ref *ref;
2558 gfc_symbol *sym;
2559 tree parent_decl = NULL_TREE;
2560 int parent_flag;
2561 bool return_value;
2562 bool alternate_entry;
2563 bool entry_master;
2564 bool is_classarray;
2565 bool first_time = true;
2567 sym = expr->symtree->n.sym;
2568 is_classarray = IS_CLASS_ARRAY (sym);
2569 ss = se->ss;
2570 if (ss != NULL)
2572 gfc_ss_info *ss_info = ss->info;
2574 /* Check that something hasn't gone horribly wrong. */
2575 gcc_assert (ss != gfc_ss_terminator);
2576 gcc_assert (ss_info->expr == expr);
2578 /* A scalarized term. We already know the descriptor. */
2579 se->expr = ss_info->data.array.descriptor;
2580 se->string_length = ss_info->string_length;
2581 ref = ss_info->data.array.ref;
2582 if (ref)
2583 gcc_assert (ref->type == REF_ARRAY
2584 && ref->u.ar.type != AR_ELEMENT);
2585 else
2586 gfc_conv_tmp_array_ref (se);
2588 else
2590 tree se_expr = NULL_TREE;
2592 se->expr = gfc_get_symbol_decl (sym);
2594 /* Deal with references to a parent results or entries by storing
2595 the current_function_decl and moving to the parent_decl. */
2596 return_value = sym->attr.function && sym->result == sym;
2597 alternate_entry = sym->attr.function && sym->attr.entry
2598 && sym->result == sym;
2599 entry_master = sym->attr.result
2600 && sym->ns->proc_name->attr.entry_master
2601 && !gfc_return_by_reference (sym->ns->proc_name);
2602 if (current_function_decl)
2603 parent_decl = DECL_CONTEXT (current_function_decl);
2605 if ((se->expr == parent_decl && return_value)
2606 || (sym->ns && sym->ns->proc_name
2607 && parent_decl
2608 && sym->ns->proc_name->backend_decl == parent_decl
2609 && (alternate_entry || entry_master)))
2610 parent_flag = 1;
2611 else
2612 parent_flag = 0;
2614 /* Special case for assigning the return value of a function.
2615 Self recursive functions must have an explicit return value. */
2616 if (return_value && (se->expr == current_function_decl || parent_flag))
2617 se_expr = gfc_get_fake_result_decl (sym, parent_flag);
2619 /* Similarly for alternate entry points. */
2620 else if (alternate_entry
2621 && (sym->ns->proc_name->backend_decl == current_function_decl
2622 || parent_flag))
2624 gfc_entry_list *el = NULL;
2626 for (el = sym->ns->entries; el; el = el->next)
2627 if (sym == el->sym)
2629 se_expr = gfc_get_fake_result_decl (sym, parent_flag);
2630 break;
2634 else if (entry_master
2635 && (sym->ns->proc_name->backend_decl == current_function_decl
2636 || parent_flag))
2637 se_expr = gfc_get_fake_result_decl (sym, parent_flag);
2639 if (se_expr)
2640 se->expr = se_expr;
2642 /* Procedure actual arguments. Look out for temporary variables
2643 with the same attributes as function values. */
2644 else if (!sym->attr.temporary
2645 && sym->attr.flavor == FL_PROCEDURE
2646 && se->expr != current_function_decl)
2648 if (!sym->attr.dummy && !sym->attr.proc_pointer)
2650 gcc_assert (TREE_CODE (se->expr) == FUNCTION_DECL);
2651 se->expr = gfc_build_addr_expr (NULL_TREE, se->expr);
2653 return;
2657 /* Dereference the expression, where needed. Since characters
2658 are entirely different from other types, they are treated
2659 separately. */
2660 if (sym->ts.type == BT_CHARACTER)
2662 /* Dereference character pointer dummy arguments
2663 or results. */
2664 if ((sym->attr.pointer || sym->attr.allocatable)
2665 && (sym->attr.dummy
2666 || sym->attr.function
2667 || sym->attr.result))
2668 se->expr = build_fold_indirect_ref_loc (input_location,
2669 se->expr);
2672 else if (!sym->attr.value)
2674 /* Dereference temporaries for class array dummy arguments. */
2675 if (sym->attr.dummy && is_classarray
2676 && GFC_ARRAY_TYPE_P (TREE_TYPE (se->expr)))
2678 if (!se->descriptor_only)
2679 se->expr = GFC_DECL_SAVED_DESCRIPTOR (se->expr);
2681 se->expr = build_fold_indirect_ref_loc (input_location,
2682 se->expr);
2685 /* Dereference non-character scalar dummy arguments. */
2686 if (sym->attr.dummy && !sym->attr.dimension
2687 && !(sym->attr.codimension && sym->attr.allocatable)
2688 && (sym->ts.type != BT_CLASS
2689 || (!CLASS_DATA (sym)->attr.dimension
2690 && !(CLASS_DATA (sym)->attr.codimension
2691 && CLASS_DATA (sym)->attr.allocatable))))
2692 se->expr = build_fold_indirect_ref_loc (input_location,
2693 se->expr);
2695 /* Dereference scalar hidden result. */
2696 if (flag_f2c && sym->ts.type == BT_COMPLEX
2697 && (sym->attr.function || sym->attr.result)
2698 && !sym->attr.dimension && !sym->attr.pointer
2699 && !sym->attr.always_explicit)
2700 se->expr = build_fold_indirect_ref_loc (input_location,
2701 se->expr);
2703 /* Dereference non-character, non-class pointer variables.
2704 These must be dummies, results, or scalars. */
2705 if (!is_classarray
2706 && (sym->attr.pointer || sym->attr.allocatable
2707 || gfc_is_associate_pointer (sym)
2708 || (sym->as && sym->as->type == AS_ASSUMED_RANK))
2709 && (sym->attr.dummy
2710 || sym->attr.function
2711 || sym->attr.result
2712 || (!sym->attr.dimension
2713 && (!sym->attr.codimension || !sym->attr.allocatable))))
2714 se->expr = build_fold_indirect_ref_loc (input_location,
2715 se->expr);
2716 /* Now treat the class array pointer variables accordingly. */
2717 else if (sym->ts.type == BT_CLASS
2718 && sym->attr.dummy
2719 && (CLASS_DATA (sym)->attr.dimension
2720 || CLASS_DATA (sym)->attr.codimension)
2721 && ((CLASS_DATA (sym)->as
2722 && CLASS_DATA (sym)->as->type == AS_ASSUMED_RANK)
2723 || CLASS_DATA (sym)->attr.allocatable
2724 || CLASS_DATA (sym)->attr.class_pointer))
2725 se->expr = build_fold_indirect_ref_loc (input_location,
2726 se->expr);
2727 /* And the case where a non-dummy, non-result, non-function,
2728 non-allotable and non-pointer classarray is present. This case was
2729 previously covered by the first if, but with introducing the
2730 condition !is_classarray there, that case has to be covered
2731 explicitly. */
2732 else if (sym->ts.type == BT_CLASS
2733 && !sym->attr.dummy
2734 && !sym->attr.function
2735 && !sym->attr.result
2736 && (CLASS_DATA (sym)->attr.dimension
2737 || CLASS_DATA (sym)->attr.codimension)
2738 && (sym->assoc
2739 || !CLASS_DATA (sym)->attr.allocatable)
2740 && !CLASS_DATA (sym)->attr.class_pointer)
2741 se->expr = build_fold_indirect_ref_loc (input_location,
2742 se->expr);
2745 ref = expr->ref;
2748 /* For character variables, also get the length. */
2749 if (sym->ts.type == BT_CHARACTER)
2751 /* If the character length of an entry isn't set, get the length from
2752 the master function instead. */
2753 if (sym->attr.entry && !sym->ts.u.cl->backend_decl)
2754 se->string_length = sym->ns->proc_name->ts.u.cl->backend_decl;
2755 else
2756 se->string_length = sym->ts.u.cl->backend_decl;
2757 gcc_assert (se->string_length);
2760 gfc_typespec *ts = &sym->ts;
2761 while (ref)
2763 switch (ref->type)
2765 case REF_ARRAY:
2766 /* Return the descriptor if that's what we want and this is an array
2767 section reference. */
2768 if (se->descriptor_only && ref->u.ar.type != AR_ELEMENT)
2769 return;
2770 /* TODO: Pointers to single elements of array sections, eg elemental subs. */
2771 /* Return the descriptor for array pointers and allocations. */
2772 if (se->want_pointer
2773 && ref->next == NULL && (se->descriptor_only))
2774 return;
2776 gfc_conv_array_ref (se, &ref->u.ar, expr, &expr->where);
2777 /* Return a pointer to an element. */
2778 break;
2780 case REF_COMPONENT:
2781 ts = &ref->u.c.component->ts;
2782 if (first_time && is_classarray && sym->attr.dummy
2783 && se->descriptor_only
2784 && !CLASS_DATA (sym)->attr.allocatable
2785 && !CLASS_DATA (sym)->attr.class_pointer
2786 && CLASS_DATA (sym)->as
2787 && CLASS_DATA (sym)->as->type != AS_ASSUMED_RANK
2788 && strcmp ("_data", ref->u.c.component->name) == 0)
2789 /* Skip the first ref of a _data component, because for class
2790 arrays that one is already done by introducing a temporary
2791 array descriptor. */
2792 break;
2794 if (ref->u.c.sym->attr.extension)
2795 conv_parent_component_references (se, ref);
2797 gfc_conv_component_ref (se, ref);
2798 if (!ref->next && ref->u.c.sym->attr.codimension
2799 && se->want_pointer && se->descriptor_only)
2800 return;
2802 break;
2804 case REF_SUBSTRING:
2805 gfc_conv_substring (se, ref, expr->ts.kind,
2806 expr->symtree->name, &expr->where);
2807 break;
2809 case REF_INQUIRY:
2810 conv_inquiry (se, ref, expr, ts);
2811 break;
2813 default:
2814 gcc_unreachable ();
2815 break;
2817 first_time = false;
2818 ref = ref->next;
2820 /* Pointer assignment, allocation or pass by reference. Arrays are handled
2821 separately. */
2822 if (se->want_pointer)
2824 if (expr->ts.type == BT_CHARACTER && !gfc_is_proc_ptr_comp (expr))
2825 gfc_conv_string_parameter (se);
2826 else
2827 se->expr = gfc_build_addr_expr (NULL_TREE, se->expr);
2832 /* Unary ops are easy... Or they would be if ! was a valid op. */
2834 static void
2835 gfc_conv_unary_op (enum tree_code code, gfc_se * se, gfc_expr * expr)
2837 gfc_se operand;
2838 tree type;
2840 gcc_assert (expr->ts.type != BT_CHARACTER);
2841 /* Initialize the operand. */
2842 gfc_init_se (&operand, se);
2843 gfc_conv_expr_val (&operand, expr->value.op.op1);
2844 gfc_add_block_to_block (&se->pre, &operand.pre);
2846 type = gfc_typenode_for_spec (&expr->ts);
2848 /* TRUTH_NOT_EXPR is not a "true" unary operator in GCC.
2849 We must convert it to a compare to 0 (e.g. EQ_EXPR (op1, 0)).
2850 All other unary operators have an equivalent GIMPLE unary operator. */
2851 if (code == TRUTH_NOT_EXPR)
2852 se->expr = fold_build2_loc (input_location, EQ_EXPR, type, operand.expr,
2853 build_int_cst (type, 0));
2854 else
2855 se->expr = fold_build1_loc (input_location, code, type, operand.expr);
2859 /* Expand power operator to optimal multiplications when a value is raised
2860 to a constant integer n. See section 4.6.3, "Evaluation of Powers" of
2861 Donald E. Knuth, "Seminumerical Algorithms", Vol. 2, "The Art of Computer
2862 Programming", 3rd Edition, 1998. */
2864 /* This code is mostly duplicated from expand_powi in the backend.
2865 We establish the "optimal power tree" lookup table with the defined size.
2866 The items in the table are the exponents used to calculate the index
2867 exponents. Any integer n less than the value can get an "addition chain",
2868 with the first node being one. */
2869 #define POWI_TABLE_SIZE 256
2871 /* The table is from builtins.c. */
2872 static const unsigned char powi_table[POWI_TABLE_SIZE] =
2874 0, 1, 1, 2, 2, 3, 3, 4, /* 0 - 7 */
2875 4, 6, 5, 6, 6, 10, 7, 9, /* 8 - 15 */
2876 8, 16, 9, 16, 10, 12, 11, 13, /* 16 - 23 */
2877 12, 17, 13, 18, 14, 24, 15, 26, /* 24 - 31 */
2878 16, 17, 17, 19, 18, 33, 19, 26, /* 32 - 39 */
2879 20, 25, 21, 40, 22, 27, 23, 44, /* 40 - 47 */
2880 24, 32, 25, 34, 26, 29, 27, 44, /* 48 - 55 */
2881 28, 31, 29, 34, 30, 60, 31, 36, /* 56 - 63 */
2882 32, 64, 33, 34, 34, 46, 35, 37, /* 64 - 71 */
2883 36, 65, 37, 50, 38, 48, 39, 69, /* 72 - 79 */
2884 40, 49, 41, 43, 42, 51, 43, 58, /* 80 - 87 */
2885 44, 64, 45, 47, 46, 59, 47, 76, /* 88 - 95 */
2886 48, 65, 49, 66, 50, 67, 51, 66, /* 96 - 103 */
2887 52, 70, 53, 74, 54, 104, 55, 74, /* 104 - 111 */
2888 56, 64, 57, 69, 58, 78, 59, 68, /* 112 - 119 */
2889 60, 61, 61, 80, 62, 75, 63, 68, /* 120 - 127 */
2890 64, 65, 65, 128, 66, 129, 67, 90, /* 128 - 135 */
2891 68, 73, 69, 131, 70, 94, 71, 88, /* 136 - 143 */
2892 72, 128, 73, 98, 74, 132, 75, 121, /* 144 - 151 */
2893 76, 102, 77, 124, 78, 132, 79, 106, /* 152 - 159 */
2894 80, 97, 81, 160, 82, 99, 83, 134, /* 160 - 167 */
2895 84, 86, 85, 95, 86, 160, 87, 100, /* 168 - 175 */
2896 88, 113, 89, 98, 90, 107, 91, 122, /* 176 - 183 */
2897 92, 111, 93, 102, 94, 126, 95, 150, /* 184 - 191 */
2898 96, 128, 97, 130, 98, 133, 99, 195, /* 192 - 199 */
2899 100, 128, 101, 123, 102, 164, 103, 138, /* 200 - 207 */
2900 104, 145, 105, 146, 106, 109, 107, 149, /* 208 - 215 */
2901 108, 200, 109, 146, 110, 170, 111, 157, /* 216 - 223 */
2902 112, 128, 113, 130, 114, 182, 115, 132, /* 224 - 231 */
2903 116, 200, 117, 132, 118, 158, 119, 206, /* 232 - 239 */
2904 120, 240, 121, 162, 122, 147, 123, 152, /* 240 - 247 */
2905 124, 166, 125, 214, 126, 138, 127, 153, /* 248 - 255 */
2908 /* If n is larger than lookup table's max index, we use the "window
2909 method". */
2910 #define POWI_WINDOW_SIZE 3
2912 /* Recursive function to expand the power operator. The temporary
2913 values are put in tmpvar. The function returns tmpvar[1] ** n. */
2914 static tree
2915 gfc_conv_powi (gfc_se * se, unsigned HOST_WIDE_INT n, tree * tmpvar)
2917 tree op0;
2918 tree op1;
2919 tree tmp;
2920 int digit;
2922 if (n < POWI_TABLE_SIZE)
2924 if (tmpvar[n])
2925 return tmpvar[n];
2927 op0 = gfc_conv_powi (se, n - powi_table[n], tmpvar);
2928 op1 = gfc_conv_powi (se, powi_table[n], tmpvar);
2930 else if (n & 1)
2932 digit = n & ((1 << POWI_WINDOW_SIZE) - 1);
2933 op0 = gfc_conv_powi (se, n - digit, tmpvar);
2934 op1 = gfc_conv_powi (se, digit, tmpvar);
2936 else
2938 op0 = gfc_conv_powi (se, n >> 1, tmpvar);
2939 op1 = op0;
2942 tmp = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (op0), op0, op1);
2943 tmp = gfc_evaluate_now (tmp, &se->pre);
2945 if (n < POWI_TABLE_SIZE)
2946 tmpvar[n] = tmp;
2948 return tmp;
2952 /* Expand lhs ** rhs. rhs is a constant integer. If it expands successfully,
2953 return 1. Else return 0 and a call to runtime library functions
2954 will have to be built. */
2955 static int
2956 gfc_conv_cst_int_power (gfc_se * se, tree lhs, tree rhs)
2958 tree cond;
2959 tree tmp;
2960 tree type;
2961 tree vartmp[POWI_TABLE_SIZE];
2962 HOST_WIDE_INT m;
2963 unsigned HOST_WIDE_INT n;
2964 int sgn;
2965 wi::tree_to_wide_ref wrhs = wi::to_wide (rhs);
2967 /* If exponent is too large, we won't expand it anyway, so don't bother
2968 with large integer values. */
2969 if (!wi::fits_shwi_p (wrhs))
2970 return 0;
2972 m = wrhs.to_shwi ();
2973 /* Use the wide_int's routine to reliably get the absolute value on all
2974 platforms. Then convert it to a HOST_WIDE_INT like above. */
2975 n = wi::abs (wrhs).to_shwi ();
2977 type = TREE_TYPE (lhs);
2978 sgn = tree_int_cst_sgn (rhs);
2980 if (((FLOAT_TYPE_P (type) && !flag_unsafe_math_optimizations)
2981 || optimize_size) && (m > 2 || m < -1))
2982 return 0;
2984 /* rhs == 0 */
2985 if (sgn == 0)
2987 se->expr = gfc_build_const (type, integer_one_node);
2988 return 1;
2991 /* If rhs < 0 and lhs is an integer, the result is -1, 0 or 1. */
2992 if ((sgn == -1) && (TREE_CODE (type) == INTEGER_TYPE))
2994 tmp = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
2995 lhs, build_int_cst (TREE_TYPE (lhs), -1));
2996 cond = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
2997 lhs, build_int_cst (TREE_TYPE (lhs), 1));
2999 /* If rhs is even,
3000 result = (lhs == 1 || lhs == -1) ? 1 : 0. */
3001 if ((n & 1) == 0)
3003 tmp = fold_build2_loc (input_location, TRUTH_OR_EXPR,
3004 logical_type_node, tmp, cond);
3005 se->expr = fold_build3_loc (input_location, COND_EXPR, type,
3006 tmp, build_int_cst (type, 1),
3007 build_int_cst (type, 0));
3008 return 1;
3010 /* If rhs is odd,
3011 result = (lhs == 1) ? 1 : (lhs == -1) ? -1 : 0. */
3012 tmp = fold_build3_loc (input_location, COND_EXPR, type, tmp,
3013 build_int_cst (type, -1),
3014 build_int_cst (type, 0));
3015 se->expr = fold_build3_loc (input_location, COND_EXPR, type,
3016 cond, build_int_cst (type, 1), tmp);
3017 return 1;
3020 memset (vartmp, 0, sizeof (vartmp));
3021 vartmp[1] = lhs;
3022 if (sgn == -1)
3024 tmp = gfc_build_const (type, integer_one_node);
3025 vartmp[1] = fold_build2_loc (input_location, RDIV_EXPR, type, tmp,
3026 vartmp[1]);
3029 se->expr = gfc_conv_powi (se, n, vartmp);
3031 return 1;
3035 /* Power op (**). Constant integer exponent has special handling. */
3037 static void
3038 gfc_conv_power_op (gfc_se * se, gfc_expr * expr)
3040 tree gfc_int4_type_node;
3041 int kind;
3042 int ikind;
3043 int res_ikind_1, res_ikind_2;
3044 gfc_se lse;
3045 gfc_se rse;
3046 tree fndecl = NULL;
3048 gfc_init_se (&lse, se);
3049 gfc_conv_expr_val (&lse, expr->value.op.op1);
3050 lse.expr = gfc_evaluate_now (lse.expr, &lse.pre);
3051 gfc_add_block_to_block (&se->pre, &lse.pre);
3053 gfc_init_se (&rse, se);
3054 gfc_conv_expr_val (&rse, expr->value.op.op2);
3055 gfc_add_block_to_block (&se->pre, &rse.pre);
3057 if (expr->value.op.op2->ts.type == BT_INTEGER
3058 && expr->value.op.op2->expr_type == EXPR_CONSTANT)
3059 if (gfc_conv_cst_int_power (se, lse.expr, rse.expr))
3060 return;
3062 if (INTEGER_CST_P (lse.expr)
3063 && TREE_CODE (TREE_TYPE (rse.expr)) == INTEGER_TYPE)
3065 wi::tree_to_wide_ref wlhs = wi::to_wide (lse.expr);
3066 HOST_WIDE_INT v, w;
3067 int kind, ikind, bit_size;
3069 v = wlhs.to_shwi ();
3070 w = abs (v);
3072 kind = expr->value.op.op1->ts.kind;
3073 ikind = gfc_validate_kind (BT_INTEGER, kind, false);
3074 bit_size = gfc_integer_kinds[ikind].bit_size;
3076 if (v == 1)
3078 /* 1**something is always 1. */
3079 se->expr = build_int_cst (TREE_TYPE (lse.expr), 1);
3080 return;
3082 else if (v == -1)
3084 /* (-1)**n is 1 - ((n & 1) << 1) */
3085 tree type;
3086 tree tmp;
3088 type = TREE_TYPE (lse.expr);
3089 tmp = fold_build2_loc (input_location, BIT_AND_EXPR, type,
3090 rse.expr, build_int_cst (type, 1));
3091 tmp = fold_build2_loc (input_location, LSHIFT_EXPR, type,
3092 tmp, build_int_cst (type, 1));
3093 tmp = fold_build2_loc (input_location, MINUS_EXPR, type,
3094 build_int_cst (type, 1), tmp);
3095 se->expr = tmp;
3096 return;
3098 else if (w > 0 && ((w & (w-1)) == 0) && ((w >> (bit_size-1)) == 0))
3100 /* Here v is +/- 2**e. The further simplification uses
3101 2**n = 1<<n, 4**n = 1<<(n+n), 8**n = 1 <<(3*n), 16**n =
3102 1<<(4*n), etc., but we have to make sure to return zero
3103 if the number of bits is too large. */
3104 tree lshift;
3105 tree type;
3106 tree shift;
3107 tree ge;
3108 tree cond;
3109 tree num_bits;
3110 tree cond2;
3111 tree tmp1;
3113 type = TREE_TYPE (lse.expr);
3115 if (w == 2)
3116 shift = rse.expr;
3117 else if (w == 4)
3118 shift = fold_build2_loc (input_location, PLUS_EXPR,
3119 TREE_TYPE (rse.expr),
3120 rse.expr, rse.expr);
3121 else
3123 /* use popcount for fast log2(w) */
3124 int e = wi::popcount (w-1);
3125 shift = fold_build2_loc (input_location, MULT_EXPR,
3126 TREE_TYPE (rse.expr),
3127 build_int_cst (TREE_TYPE (rse.expr), e),
3128 rse.expr);
3131 lshift = fold_build2_loc (input_location, LSHIFT_EXPR, type,
3132 build_int_cst (type, 1), shift);
3133 ge = fold_build2_loc (input_location, GE_EXPR, logical_type_node,
3134 rse.expr, build_int_cst (type, 0));
3135 cond = fold_build3_loc (input_location, COND_EXPR, type, ge, lshift,
3136 build_int_cst (type, 0));
3137 num_bits = build_int_cst (TREE_TYPE (rse.expr), TYPE_PRECISION (type));
3138 cond2 = fold_build2_loc (input_location, GE_EXPR, logical_type_node,
3139 rse.expr, num_bits);
3140 tmp1 = fold_build3_loc (input_location, COND_EXPR, type, cond2,
3141 build_int_cst (type, 0), cond);
3142 if (v > 0)
3144 se->expr = tmp1;
3146 else
3148 /* for v < 0, calculate v**n = |v|**n * (-1)**n */
3149 tree tmp2;
3150 tmp2 = fold_build2_loc (input_location, BIT_AND_EXPR, type,
3151 rse.expr, build_int_cst (type, 1));
3152 tmp2 = fold_build2_loc (input_location, LSHIFT_EXPR, type,
3153 tmp2, build_int_cst (type, 1));
3154 tmp2 = fold_build2_loc (input_location, MINUS_EXPR, type,
3155 build_int_cst (type, 1), tmp2);
3156 se->expr = fold_build2_loc (input_location, MULT_EXPR, type,
3157 tmp1, tmp2);
3159 return;
3163 gfc_int4_type_node = gfc_get_int_type (4);
3165 /* In case of integer operands with kinds 1 or 2, we call the integer kind 4
3166 library routine. But in the end, we have to convert the result back
3167 if this case applies -- with res_ikind_K, we keep track whether operand K
3168 falls into this case. */
3169 res_ikind_1 = -1;
3170 res_ikind_2 = -1;
3172 kind = expr->value.op.op1->ts.kind;
3173 switch (expr->value.op.op2->ts.type)
3175 case BT_INTEGER:
3176 ikind = expr->value.op.op2->ts.kind;
3177 switch (ikind)
3179 case 1:
3180 case 2:
3181 rse.expr = convert (gfc_int4_type_node, rse.expr);
3182 res_ikind_2 = ikind;
3183 /* Fall through. */
3185 case 4:
3186 ikind = 0;
3187 break;
3189 case 8:
3190 ikind = 1;
3191 break;
3193 case 16:
3194 ikind = 2;
3195 break;
3197 default:
3198 gcc_unreachable ();
3200 switch (kind)
3202 case 1:
3203 case 2:
3204 if (expr->value.op.op1->ts.type == BT_INTEGER)
3206 lse.expr = convert (gfc_int4_type_node, lse.expr);
3207 res_ikind_1 = kind;
3209 else
3210 gcc_unreachable ();
3211 /* Fall through. */
3213 case 4:
3214 kind = 0;
3215 break;
3217 case 8:
3218 kind = 1;
3219 break;
3221 case 10:
3222 kind = 2;
3223 break;
3225 case 16:
3226 kind = 3;
3227 break;
3229 default:
3230 gcc_unreachable ();
3233 switch (expr->value.op.op1->ts.type)
3235 case BT_INTEGER:
3236 if (kind == 3) /* Case 16 was not handled properly above. */
3237 kind = 2;
3238 fndecl = gfor_fndecl_math_powi[kind][ikind].integer;
3239 break;
3241 case BT_REAL:
3242 /* Use builtins for real ** int4. */
3243 if (ikind == 0)
3245 switch (kind)
3247 case 0:
3248 fndecl = builtin_decl_explicit (BUILT_IN_POWIF);
3249 break;
3251 case 1:
3252 fndecl = builtin_decl_explicit (BUILT_IN_POWI);
3253 break;
3255 case 2:
3256 fndecl = builtin_decl_explicit (BUILT_IN_POWIL);
3257 break;
3259 case 3:
3260 /* Use the __builtin_powil() only if real(kind=16) is
3261 actually the C long double type. */
3262 if (!gfc_real16_is_float128)
3263 fndecl = builtin_decl_explicit (BUILT_IN_POWIL);
3264 break;
3266 default:
3267 gcc_unreachable ();
3271 /* If we don't have a good builtin for this, go for the
3272 library function. */
3273 if (!fndecl)
3274 fndecl = gfor_fndecl_math_powi[kind][ikind].real;
3275 break;
3277 case BT_COMPLEX:
3278 fndecl = gfor_fndecl_math_powi[kind][ikind].cmplx;
3279 break;
3281 default:
3282 gcc_unreachable ();
3284 break;
3286 case BT_REAL:
3287 fndecl = gfc_builtin_decl_for_float_kind (BUILT_IN_POW, kind);
3288 break;
3290 case BT_COMPLEX:
3291 fndecl = gfc_builtin_decl_for_float_kind (BUILT_IN_CPOW, kind);
3292 break;
3294 default:
3295 gcc_unreachable ();
3296 break;
3299 se->expr = build_call_expr_loc (input_location,
3300 fndecl, 2, lse.expr, rse.expr);
3302 /* Convert the result back if it is of wrong integer kind. */
3303 if (res_ikind_1 != -1 && res_ikind_2 != -1)
3305 /* We want the maximum of both operand kinds as result. */
3306 if (res_ikind_1 < res_ikind_2)
3307 res_ikind_1 = res_ikind_2;
3308 se->expr = convert (gfc_get_int_type (res_ikind_1), se->expr);
3313 /* Generate code to allocate a string temporary. */
3315 tree
3316 gfc_conv_string_tmp (gfc_se * se, tree type, tree len)
3318 tree var;
3319 tree tmp;
3321 if (gfc_can_put_var_on_stack (len))
3323 /* Create a temporary variable to hold the result. */
3324 tmp = fold_build2_loc (input_location, MINUS_EXPR,
3325 TREE_TYPE (len), len,
3326 build_int_cst (TREE_TYPE (len), 1));
3327 tmp = build_range_type (gfc_charlen_type_node, size_zero_node, tmp);
3329 if (TREE_CODE (TREE_TYPE (type)) == ARRAY_TYPE)
3330 tmp = build_array_type (TREE_TYPE (TREE_TYPE (type)), tmp);
3331 else
3332 tmp = build_array_type (TREE_TYPE (type), tmp);
3334 var = gfc_create_var (tmp, "str");
3335 var = gfc_build_addr_expr (type, var);
3337 else
3339 /* Allocate a temporary to hold the result. */
3340 var = gfc_create_var (type, "pstr");
3341 gcc_assert (POINTER_TYPE_P (type));
3342 tmp = TREE_TYPE (type);
3343 if (TREE_CODE (tmp) == ARRAY_TYPE)
3344 tmp = TREE_TYPE (tmp);
3345 tmp = TYPE_SIZE_UNIT (tmp);
3346 tmp = fold_build2_loc (input_location, MULT_EXPR, size_type_node,
3347 fold_convert (size_type_node, len),
3348 fold_convert (size_type_node, tmp));
3349 tmp = gfc_call_malloc (&se->pre, type, tmp);
3350 gfc_add_modify (&se->pre, var, tmp);
3352 /* Free the temporary afterwards. */
3353 tmp = gfc_call_free (var);
3354 gfc_add_expr_to_block (&se->post, tmp);
3357 return var;
3361 /* Handle a string concatenation operation. A temporary will be allocated to
3362 hold the result. */
3364 static void
3365 gfc_conv_concat_op (gfc_se * se, gfc_expr * expr)
3367 gfc_se lse, rse;
3368 tree len, type, var, tmp, fndecl;
3370 gcc_assert (expr->value.op.op1->ts.type == BT_CHARACTER
3371 && expr->value.op.op2->ts.type == BT_CHARACTER);
3372 gcc_assert (expr->value.op.op1->ts.kind == expr->value.op.op2->ts.kind);
3374 gfc_init_se (&lse, se);
3375 gfc_conv_expr (&lse, expr->value.op.op1);
3376 gfc_conv_string_parameter (&lse);
3377 gfc_init_se (&rse, se);
3378 gfc_conv_expr (&rse, expr->value.op.op2);
3379 gfc_conv_string_parameter (&rse);
3381 gfc_add_block_to_block (&se->pre, &lse.pre);
3382 gfc_add_block_to_block (&se->pre, &rse.pre);
3384 type = gfc_get_character_type (expr->ts.kind, expr->ts.u.cl);
3385 len = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
3386 if (len == NULL_TREE)
3388 len = fold_build2_loc (input_location, PLUS_EXPR,
3389 gfc_charlen_type_node,
3390 fold_convert (gfc_charlen_type_node,
3391 lse.string_length),
3392 fold_convert (gfc_charlen_type_node,
3393 rse.string_length));
3396 type = build_pointer_type (type);
3398 var = gfc_conv_string_tmp (se, type, len);
3400 /* Do the actual concatenation. */
3401 if (expr->ts.kind == 1)
3402 fndecl = gfor_fndecl_concat_string;
3403 else if (expr->ts.kind == 4)
3404 fndecl = gfor_fndecl_concat_string_char4;
3405 else
3406 gcc_unreachable ();
3408 tmp = build_call_expr_loc (input_location,
3409 fndecl, 6, len, var, lse.string_length, lse.expr,
3410 rse.string_length, rse.expr);
3411 gfc_add_expr_to_block (&se->pre, tmp);
3413 /* Add the cleanup for the operands. */
3414 gfc_add_block_to_block (&se->pre, &rse.post);
3415 gfc_add_block_to_block (&se->pre, &lse.post);
3417 se->expr = var;
3418 se->string_length = len;
3421 /* Translates an op expression. Common (binary) cases are handled by this
3422 function, others are passed on. Recursion is used in either case.
3423 We use the fact that (op1.ts == op2.ts) (except for the power
3424 operator **).
3425 Operators need no special handling for scalarized expressions as long as
3426 they call gfc_conv_simple_val to get their operands.
3427 Character strings get special handling. */
3429 static void
3430 gfc_conv_expr_op (gfc_se * se, gfc_expr * expr)
3432 enum tree_code code;
3433 gfc_se lse;
3434 gfc_se rse;
3435 tree tmp, type;
3436 int lop;
3437 int checkstring;
3439 checkstring = 0;
3440 lop = 0;
3441 switch (expr->value.op.op)
3443 case INTRINSIC_PARENTHESES:
3444 if ((expr->ts.type == BT_REAL || expr->ts.type == BT_COMPLEX)
3445 && flag_protect_parens)
3447 gfc_conv_unary_op (PAREN_EXPR, se, expr);
3448 gcc_assert (FLOAT_TYPE_P (TREE_TYPE (se->expr)));
3449 return;
3452 /* Fallthrough. */
3453 case INTRINSIC_UPLUS:
3454 gfc_conv_expr (se, expr->value.op.op1);
3455 return;
3457 case INTRINSIC_UMINUS:
3458 gfc_conv_unary_op (NEGATE_EXPR, se, expr);
3459 return;
3461 case INTRINSIC_NOT:
3462 gfc_conv_unary_op (TRUTH_NOT_EXPR, se, expr);
3463 return;
3465 case INTRINSIC_PLUS:
3466 code = PLUS_EXPR;
3467 break;
3469 case INTRINSIC_MINUS:
3470 code = MINUS_EXPR;
3471 break;
3473 case INTRINSIC_TIMES:
3474 code = MULT_EXPR;
3475 break;
3477 case INTRINSIC_DIVIDE:
3478 /* If expr is a real or complex expr, use an RDIV_EXPR. If op1 is
3479 an integer, we must round towards zero, so we use a
3480 TRUNC_DIV_EXPR. */
3481 if (expr->ts.type == BT_INTEGER)
3482 code = TRUNC_DIV_EXPR;
3483 else
3484 code = RDIV_EXPR;
3485 break;
3487 case INTRINSIC_POWER:
3488 gfc_conv_power_op (se, expr);
3489 return;
3491 case INTRINSIC_CONCAT:
3492 gfc_conv_concat_op (se, expr);
3493 return;
3495 case INTRINSIC_AND:
3496 code = flag_frontend_optimize ? TRUTH_ANDIF_EXPR : TRUTH_AND_EXPR;
3497 lop = 1;
3498 break;
3500 case INTRINSIC_OR:
3501 code = flag_frontend_optimize ? TRUTH_ORIF_EXPR : TRUTH_OR_EXPR;
3502 lop = 1;
3503 break;
3505 /* EQV and NEQV only work on logicals, but since we represent them
3506 as integers, we can use EQ_EXPR and NE_EXPR for them in GIMPLE. */
3507 case INTRINSIC_EQ:
3508 case INTRINSIC_EQ_OS:
3509 case INTRINSIC_EQV:
3510 code = EQ_EXPR;
3511 checkstring = 1;
3512 lop = 1;
3513 break;
3515 case INTRINSIC_NE:
3516 case INTRINSIC_NE_OS:
3517 case INTRINSIC_NEQV:
3518 code = NE_EXPR;
3519 checkstring = 1;
3520 lop = 1;
3521 break;
3523 case INTRINSIC_GT:
3524 case INTRINSIC_GT_OS:
3525 code = GT_EXPR;
3526 checkstring = 1;
3527 lop = 1;
3528 break;
3530 case INTRINSIC_GE:
3531 case INTRINSIC_GE_OS:
3532 code = GE_EXPR;
3533 checkstring = 1;
3534 lop = 1;
3535 break;
3537 case INTRINSIC_LT:
3538 case INTRINSIC_LT_OS:
3539 code = LT_EXPR;
3540 checkstring = 1;
3541 lop = 1;
3542 break;
3544 case INTRINSIC_LE:
3545 case INTRINSIC_LE_OS:
3546 code = LE_EXPR;
3547 checkstring = 1;
3548 lop = 1;
3549 break;
3551 case INTRINSIC_USER:
3552 case INTRINSIC_ASSIGN:
3553 /* These should be converted into function calls by the frontend. */
3554 gcc_unreachable ();
3556 default:
3557 fatal_error (input_location, "Unknown intrinsic op");
3558 return;
3561 /* The only exception to this is **, which is handled separately anyway. */
3562 gcc_assert (expr->value.op.op1->ts.type == expr->value.op.op2->ts.type);
3564 if (checkstring && expr->value.op.op1->ts.type != BT_CHARACTER)
3565 checkstring = 0;
3567 /* lhs */
3568 gfc_init_se (&lse, se);
3569 gfc_conv_expr (&lse, expr->value.op.op1);
3570 gfc_add_block_to_block (&se->pre, &lse.pre);
3572 /* rhs */
3573 gfc_init_se (&rse, se);
3574 gfc_conv_expr (&rse, expr->value.op.op2);
3575 gfc_add_block_to_block (&se->pre, &rse.pre);
3577 if (checkstring)
3579 gfc_conv_string_parameter (&lse);
3580 gfc_conv_string_parameter (&rse);
3582 lse.expr = gfc_build_compare_string (lse.string_length, lse.expr,
3583 rse.string_length, rse.expr,
3584 expr->value.op.op1->ts.kind,
3585 code);
3586 rse.expr = build_int_cst (TREE_TYPE (lse.expr), 0);
3587 gfc_add_block_to_block (&lse.post, &rse.post);
3590 type = gfc_typenode_for_spec (&expr->ts);
3592 if (lop)
3594 /* The result of logical ops is always logical_type_node. */
3595 tmp = fold_build2_loc (input_location, code, logical_type_node,
3596 lse.expr, rse.expr);
3597 se->expr = convert (type, tmp);
3599 else
3600 se->expr = fold_build2_loc (input_location, code, type, lse.expr, rse.expr);
3602 /* Add the post blocks. */
3603 gfc_add_block_to_block (&se->post, &rse.post);
3604 gfc_add_block_to_block (&se->post, &lse.post);
3607 /* If a string's length is one, we convert it to a single character. */
3609 tree
3610 gfc_string_to_single_character (tree len, tree str, int kind)
3613 if (len == NULL
3614 || !tree_fits_uhwi_p (len)
3615 || !POINTER_TYPE_P (TREE_TYPE (str)))
3616 return NULL_TREE;
3618 if (TREE_INT_CST_LOW (len) == 1)
3620 str = fold_convert (gfc_get_pchar_type (kind), str);
3621 return build_fold_indirect_ref_loc (input_location, str);
3624 if (kind == 1
3625 && TREE_CODE (str) == ADDR_EXPR
3626 && TREE_CODE (TREE_OPERAND (str, 0)) == ARRAY_REF
3627 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (str, 0), 0)) == STRING_CST
3628 && array_ref_low_bound (TREE_OPERAND (str, 0))
3629 == TREE_OPERAND (TREE_OPERAND (str, 0), 1)
3630 && TREE_INT_CST_LOW (len) > 1
3631 && TREE_INT_CST_LOW (len)
3632 == (unsigned HOST_WIDE_INT)
3633 TREE_STRING_LENGTH (TREE_OPERAND (TREE_OPERAND (str, 0), 0)))
3635 tree ret = fold_convert (gfc_get_pchar_type (kind), str);
3636 ret = build_fold_indirect_ref_loc (input_location, ret);
3637 if (TREE_CODE (ret) == INTEGER_CST)
3639 tree string_cst = TREE_OPERAND (TREE_OPERAND (str, 0), 0);
3640 int i, length = TREE_STRING_LENGTH (string_cst);
3641 const char *ptr = TREE_STRING_POINTER (string_cst);
3643 for (i = 1; i < length; i++)
3644 if (ptr[i] != ' ')
3645 return NULL_TREE;
3647 return ret;
3651 return NULL_TREE;
3655 void
3656 gfc_conv_scalar_char_value (gfc_symbol *sym, gfc_se *se, gfc_expr **expr)
3659 if (sym->backend_decl)
3661 /* This becomes the nominal_type in
3662 function.c:assign_parm_find_data_types. */
3663 TREE_TYPE (sym->backend_decl) = unsigned_char_type_node;
3664 /* This becomes the passed_type in
3665 function.c:assign_parm_find_data_types. C promotes char to
3666 integer for argument passing. */
3667 DECL_ARG_TYPE (sym->backend_decl) = unsigned_type_node;
3669 DECL_BY_REFERENCE (sym->backend_decl) = 0;
3672 if (expr != NULL)
3674 /* If we have a constant character expression, make it into an
3675 integer. */
3676 if ((*expr)->expr_type == EXPR_CONSTANT)
3678 gfc_typespec ts;
3679 gfc_clear_ts (&ts);
3681 *expr = gfc_get_int_expr (gfc_default_integer_kind, NULL,
3682 (int)(*expr)->value.character.string[0]);
3683 if ((*expr)->ts.kind != gfc_c_int_kind)
3685 /* The expr needs to be compatible with a C int. If the
3686 conversion fails, then the 2 causes an ICE. */
3687 ts.type = BT_INTEGER;
3688 ts.kind = gfc_c_int_kind;
3689 gfc_convert_type (*expr, &ts, 2);
3692 else if (se != NULL && (*expr)->expr_type == EXPR_VARIABLE)
3694 if ((*expr)->ref == NULL)
3696 se->expr = gfc_string_to_single_character
3697 (build_int_cst (integer_type_node, 1),
3698 gfc_build_addr_expr (gfc_get_pchar_type ((*expr)->ts.kind),
3699 gfc_get_symbol_decl
3700 ((*expr)->symtree->n.sym)),
3701 (*expr)->ts.kind);
3703 else
3705 gfc_conv_variable (se, *expr);
3706 se->expr = gfc_string_to_single_character
3707 (build_int_cst (integer_type_node, 1),
3708 gfc_build_addr_expr (gfc_get_pchar_type ((*expr)->ts.kind),
3709 se->expr),
3710 (*expr)->ts.kind);
3716 /* Helper function for gfc_build_compare_string. Return LEN_TRIM value
3717 if STR is a string literal, otherwise return -1. */
3719 static int
3720 gfc_optimize_len_trim (tree len, tree str, int kind)
3722 if (kind == 1
3723 && TREE_CODE (str) == ADDR_EXPR
3724 && TREE_CODE (TREE_OPERAND (str, 0)) == ARRAY_REF
3725 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (str, 0), 0)) == STRING_CST
3726 && array_ref_low_bound (TREE_OPERAND (str, 0))
3727 == TREE_OPERAND (TREE_OPERAND (str, 0), 1)
3728 && tree_fits_uhwi_p (len)
3729 && tree_to_uhwi (len) >= 1
3730 && tree_to_uhwi (len)
3731 == (unsigned HOST_WIDE_INT)
3732 TREE_STRING_LENGTH (TREE_OPERAND (TREE_OPERAND (str, 0), 0)))
3734 tree folded = fold_convert (gfc_get_pchar_type (kind), str);
3735 folded = build_fold_indirect_ref_loc (input_location, folded);
3736 if (TREE_CODE (folded) == INTEGER_CST)
3738 tree string_cst = TREE_OPERAND (TREE_OPERAND (str, 0), 0);
3739 int length = TREE_STRING_LENGTH (string_cst);
3740 const char *ptr = TREE_STRING_POINTER (string_cst);
3742 for (; length > 0; length--)
3743 if (ptr[length - 1] != ' ')
3744 break;
3746 return length;
3749 return -1;
3752 /* Helper to build a call to memcmp. */
3754 static tree
3755 build_memcmp_call (tree s1, tree s2, tree n)
3757 tree tmp;
3759 if (!POINTER_TYPE_P (TREE_TYPE (s1)))
3760 s1 = gfc_build_addr_expr (pvoid_type_node, s1);
3761 else
3762 s1 = fold_convert (pvoid_type_node, s1);
3764 if (!POINTER_TYPE_P (TREE_TYPE (s2)))
3765 s2 = gfc_build_addr_expr (pvoid_type_node, s2);
3766 else
3767 s2 = fold_convert (pvoid_type_node, s2);
3769 n = fold_convert (size_type_node, n);
3771 tmp = build_call_expr_loc (input_location,
3772 builtin_decl_explicit (BUILT_IN_MEMCMP),
3773 3, s1, s2, n);
3775 return fold_convert (integer_type_node, tmp);
3778 /* Compare two strings. If they are all single characters, the result is the
3779 subtraction of them. Otherwise, we build a library call. */
3781 tree
3782 gfc_build_compare_string (tree len1, tree str1, tree len2, tree str2, int kind,
3783 enum tree_code code)
3785 tree sc1;
3786 tree sc2;
3787 tree fndecl;
3789 gcc_assert (POINTER_TYPE_P (TREE_TYPE (str1)));
3790 gcc_assert (POINTER_TYPE_P (TREE_TYPE (str2)));
3792 sc1 = gfc_string_to_single_character (len1, str1, kind);
3793 sc2 = gfc_string_to_single_character (len2, str2, kind);
3795 if (sc1 != NULL_TREE && sc2 != NULL_TREE)
3797 /* Deal with single character specially. */
3798 sc1 = fold_convert (integer_type_node, sc1);
3799 sc2 = fold_convert (integer_type_node, sc2);
3800 return fold_build2_loc (input_location, MINUS_EXPR, integer_type_node,
3801 sc1, sc2);
3804 if ((code == EQ_EXPR || code == NE_EXPR)
3805 && optimize
3806 && INTEGER_CST_P (len1) && INTEGER_CST_P (len2))
3808 /* If one string is a string literal with LEN_TRIM longer
3809 than the length of the second string, the strings
3810 compare unequal. */
3811 int len = gfc_optimize_len_trim (len1, str1, kind);
3812 if (len > 0 && compare_tree_int (len2, len) < 0)
3813 return integer_one_node;
3814 len = gfc_optimize_len_trim (len2, str2, kind);
3815 if (len > 0 && compare_tree_int (len1, len) < 0)
3816 return integer_one_node;
3819 /* We can compare via memcpy if the strings are known to be equal
3820 in length and they are
3821 - kind=1
3822 - kind=4 and the comparison is for (in)equality. */
3824 if (INTEGER_CST_P (len1) && INTEGER_CST_P (len2)
3825 && tree_int_cst_equal (len1, len2)
3826 && (kind == 1 || code == EQ_EXPR || code == NE_EXPR))
3828 tree tmp;
3829 tree chartype;
3831 chartype = gfc_get_char_type (kind);
3832 tmp = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE(len1),
3833 fold_convert (TREE_TYPE(len1),
3834 TYPE_SIZE_UNIT(chartype)),
3835 len1);
3836 return build_memcmp_call (str1, str2, tmp);
3839 /* Build a call for the comparison. */
3840 if (kind == 1)
3841 fndecl = gfor_fndecl_compare_string;
3842 else if (kind == 4)
3843 fndecl = gfor_fndecl_compare_string_char4;
3844 else
3845 gcc_unreachable ();
3847 return build_call_expr_loc (input_location, fndecl, 4,
3848 len1, str1, len2, str2);
3852 /* Return the backend_decl for a procedure pointer component. */
3854 static tree
3855 get_proc_ptr_comp (gfc_expr *e)
3857 gfc_se comp_se;
3858 gfc_expr *e2;
3859 expr_t old_type;
3861 gfc_init_se (&comp_se, NULL);
3862 e2 = gfc_copy_expr (e);
3863 /* We have to restore the expr type later so that gfc_free_expr frees
3864 the exact same thing that was allocated.
3865 TODO: This is ugly. */
3866 old_type = e2->expr_type;
3867 e2->expr_type = EXPR_VARIABLE;
3868 gfc_conv_expr (&comp_se, e2);
3869 e2->expr_type = old_type;
3870 gfc_free_expr (e2);
3871 return build_fold_addr_expr_loc (input_location, comp_se.expr);
3875 /* Convert a typebound function reference from a class object. */
3876 static void
3877 conv_base_obj_fcn_val (gfc_se * se, tree base_object, gfc_expr * expr)
3879 gfc_ref *ref;
3880 tree var;
3882 if (!VAR_P (base_object))
3884 var = gfc_create_var (TREE_TYPE (base_object), NULL);
3885 gfc_add_modify (&se->pre, var, base_object);
3887 se->expr = gfc_class_vptr_get (base_object);
3888 se->expr = build_fold_indirect_ref_loc (input_location, se->expr);
3889 ref = expr->ref;
3890 while (ref && ref->next)
3891 ref = ref->next;
3892 gcc_assert (ref && ref->type == REF_COMPONENT);
3893 if (ref->u.c.sym->attr.extension)
3894 conv_parent_component_references (se, ref);
3895 gfc_conv_component_ref (se, ref);
3896 se->expr = build_fold_addr_expr_loc (input_location, se->expr);
3900 static void
3901 conv_function_val (gfc_se * se, gfc_symbol * sym, gfc_expr * expr,
3902 gfc_actual_arglist *actual_args)
3904 tree tmp;
3906 if (gfc_is_proc_ptr_comp (expr))
3907 tmp = get_proc_ptr_comp (expr);
3908 else if (sym->attr.dummy)
3910 tmp = gfc_get_symbol_decl (sym);
3911 if (sym->attr.proc_pointer)
3912 tmp = build_fold_indirect_ref_loc (input_location,
3913 tmp);
3914 gcc_assert (TREE_CODE (TREE_TYPE (tmp)) == POINTER_TYPE
3915 && TREE_CODE (TREE_TYPE (TREE_TYPE (tmp))) == FUNCTION_TYPE);
3917 else
3919 if (!sym->backend_decl)
3920 sym->backend_decl = gfc_get_extern_function_decl (sym, actual_args);
3922 TREE_USED (sym->backend_decl) = 1;
3924 tmp = sym->backend_decl;
3926 if (sym->attr.cray_pointee)
3928 /* TODO - make the cray pointee a pointer to a procedure,
3929 assign the pointer to it and use it for the call. This
3930 will do for now! */
3931 tmp = convert (build_pointer_type (TREE_TYPE (tmp)),
3932 gfc_get_symbol_decl (sym->cp_pointer));
3933 tmp = gfc_evaluate_now (tmp, &se->pre);
3936 if (!POINTER_TYPE_P (TREE_TYPE (tmp)))
3938 gcc_assert (TREE_CODE (tmp) == FUNCTION_DECL);
3939 tmp = gfc_build_addr_expr (NULL_TREE, tmp);
3942 se->expr = tmp;
3946 /* Initialize MAPPING. */
3948 void
3949 gfc_init_interface_mapping (gfc_interface_mapping * mapping)
3951 mapping->syms = NULL;
3952 mapping->charlens = NULL;
3956 /* Free all memory held by MAPPING (but not MAPPING itself). */
3958 void
3959 gfc_free_interface_mapping (gfc_interface_mapping * mapping)
3961 gfc_interface_sym_mapping *sym;
3962 gfc_interface_sym_mapping *nextsym;
3963 gfc_charlen *cl;
3964 gfc_charlen *nextcl;
3966 for (sym = mapping->syms; sym; sym = nextsym)
3968 nextsym = sym->next;
3969 sym->new_sym->n.sym->formal = NULL;
3970 gfc_free_symbol (sym->new_sym->n.sym);
3971 gfc_free_expr (sym->expr);
3972 free (sym->new_sym);
3973 free (sym);
3975 for (cl = mapping->charlens; cl; cl = nextcl)
3977 nextcl = cl->next;
3978 gfc_free_expr (cl->length);
3979 free (cl);
3984 /* Return a copy of gfc_charlen CL. Add the returned structure to
3985 MAPPING so that it will be freed by gfc_free_interface_mapping. */
3987 static gfc_charlen *
3988 gfc_get_interface_mapping_charlen (gfc_interface_mapping * mapping,
3989 gfc_charlen * cl)
3991 gfc_charlen *new_charlen;
3993 new_charlen = gfc_get_charlen ();
3994 new_charlen->next = mapping->charlens;
3995 new_charlen->length = gfc_copy_expr (cl->length);
3997 mapping->charlens = new_charlen;
3998 return new_charlen;
4002 /* A subroutine of gfc_add_interface_mapping. Return a descriptorless
4003 array variable that can be used as the actual argument for dummy
4004 argument SYM. Add any initialization code to BLOCK. PACKED is as
4005 for gfc_get_nodesc_array_type and DATA points to the first element
4006 in the passed array. */
4008 static tree
4009 gfc_get_interface_mapping_array (stmtblock_t * block, gfc_symbol * sym,
4010 gfc_packed packed, tree data)
4012 tree type;
4013 tree var;
4015 type = gfc_typenode_for_spec (&sym->ts);
4016 type = gfc_get_nodesc_array_type (type, sym->as, packed,
4017 !sym->attr.target && !sym->attr.pointer
4018 && !sym->attr.proc_pointer);
4020 var = gfc_create_var (type, "ifm");
4021 gfc_add_modify (block, var, fold_convert (type, data));
4023 return var;
4027 /* A subroutine of gfc_add_interface_mapping. Set the stride, upper bounds
4028 and offset of descriptorless array type TYPE given that it has the same
4029 size as DESC. Add any set-up code to BLOCK. */
4031 static void
4032 gfc_set_interface_mapping_bounds (stmtblock_t * block, tree type, tree desc)
4034 int n;
4035 tree dim;
4036 tree offset;
4037 tree tmp;
4039 offset = gfc_index_zero_node;
4040 for (n = 0; n < GFC_TYPE_ARRAY_RANK (type); n++)
4042 dim = gfc_rank_cst[n];
4043 GFC_TYPE_ARRAY_STRIDE (type, n) = gfc_conv_array_stride (desc, n);
4044 if (GFC_TYPE_ARRAY_LBOUND (type, n) == NULL_TREE)
4046 GFC_TYPE_ARRAY_LBOUND (type, n)
4047 = gfc_conv_descriptor_lbound_get (desc, dim);
4048 GFC_TYPE_ARRAY_UBOUND (type, n)
4049 = gfc_conv_descriptor_ubound_get (desc, dim);
4051 else if (GFC_TYPE_ARRAY_UBOUND (type, n) == NULL_TREE)
4053 tmp = fold_build2_loc (input_location, MINUS_EXPR,
4054 gfc_array_index_type,
4055 gfc_conv_descriptor_ubound_get (desc, dim),
4056 gfc_conv_descriptor_lbound_get (desc, dim));
4057 tmp = fold_build2_loc (input_location, PLUS_EXPR,
4058 gfc_array_index_type,
4059 GFC_TYPE_ARRAY_LBOUND (type, n), tmp);
4060 tmp = gfc_evaluate_now (tmp, block);
4061 GFC_TYPE_ARRAY_UBOUND (type, n) = tmp;
4063 tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
4064 GFC_TYPE_ARRAY_LBOUND (type, n),
4065 GFC_TYPE_ARRAY_STRIDE (type, n));
4066 offset = fold_build2_loc (input_location, MINUS_EXPR,
4067 gfc_array_index_type, offset, tmp);
4069 offset = gfc_evaluate_now (offset, block);
4070 GFC_TYPE_ARRAY_OFFSET (type) = offset;
4074 /* Extend MAPPING so that it maps dummy argument SYM to the value stored
4075 in SE. The caller may still use se->expr and se->string_length after
4076 calling this function. */
4078 void
4079 gfc_add_interface_mapping (gfc_interface_mapping * mapping,
4080 gfc_symbol * sym, gfc_se * se,
4081 gfc_expr *expr)
4083 gfc_interface_sym_mapping *sm;
4084 tree desc;
4085 tree tmp;
4086 tree value;
4087 gfc_symbol *new_sym;
4088 gfc_symtree *root;
4089 gfc_symtree *new_symtree;
4091 /* Create a new symbol to represent the actual argument. */
4092 new_sym = gfc_new_symbol (sym->name, NULL);
4093 new_sym->ts = sym->ts;
4094 new_sym->as = gfc_copy_array_spec (sym->as);
4095 new_sym->attr.referenced = 1;
4096 new_sym->attr.dimension = sym->attr.dimension;
4097 new_sym->attr.contiguous = sym->attr.contiguous;
4098 new_sym->attr.codimension = sym->attr.codimension;
4099 new_sym->attr.pointer = sym->attr.pointer;
4100 new_sym->attr.allocatable = sym->attr.allocatable;
4101 new_sym->attr.flavor = sym->attr.flavor;
4102 new_sym->attr.function = sym->attr.function;
4104 /* Ensure that the interface is available and that
4105 descriptors are passed for array actual arguments. */
4106 if (sym->attr.flavor == FL_PROCEDURE)
4108 new_sym->formal = expr->symtree->n.sym->formal;
4109 new_sym->attr.always_explicit
4110 = expr->symtree->n.sym->attr.always_explicit;
4113 /* Create a fake symtree for it. */
4114 root = NULL;
4115 new_symtree = gfc_new_symtree (&root, sym->name);
4116 new_symtree->n.sym = new_sym;
4117 gcc_assert (new_symtree == root);
4119 /* Create a dummy->actual mapping. */
4120 sm = XCNEW (gfc_interface_sym_mapping);
4121 sm->next = mapping->syms;
4122 sm->old = sym;
4123 sm->new_sym = new_symtree;
4124 sm->expr = gfc_copy_expr (expr);
4125 mapping->syms = sm;
4127 /* Stabilize the argument's value. */
4128 if (!sym->attr.function && se)
4129 se->expr = gfc_evaluate_now (se->expr, &se->pre);
4131 if (sym->ts.type == BT_CHARACTER)
4133 /* Create a copy of the dummy argument's length. */
4134 new_sym->ts.u.cl = gfc_get_interface_mapping_charlen (mapping, sym->ts.u.cl);
4135 sm->expr->ts.u.cl = new_sym->ts.u.cl;
4137 /* If the length is specified as "*", record the length that
4138 the caller is passing. We should use the callee's length
4139 in all other cases. */
4140 if (!new_sym->ts.u.cl->length && se)
4142 se->string_length = gfc_evaluate_now (se->string_length, &se->pre);
4143 new_sym->ts.u.cl->backend_decl = se->string_length;
4147 if (!se)
4148 return;
4150 /* Use the passed value as-is if the argument is a function. */
4151 if (sym->attr.flavor == FL_PROCEDURE)
4152 value = se->expr;
4154 /* If the argument is a pass-by-value scalar, use the value as is. */
4155 else if (!sym->attr.dimension && sym->attr.value)
4156 value = se->expr;
4158 /* If the argument is either a string or a pointer to a string,
4159 convert it to a boundless character type. */
4160 else if (!sym->attr.dimension && sym->ts.type == BT_CHARACTER)
4162 tmp = gfc_get_character_type_len (sym->ts.kind, NULL);
4163 tmp = build_pointer_type (tmp);
4164 if (sym->attr.pointer)
4165 value = build_fold_indirect_ref_loc (input_location,
4166 se->expr);
4167 else
4168 value = se->expr;
4169 value = fold_convert (tmp, value);
4172 /* If the argument is a scalar, a pointer to an array or an allocatable,
4173 dereference it. */
4174 else if (!sym->attr.dimension || sym->attr.pointer || sym->attr.allocatable)
4175 value = build_fold_indirect_ref_loc (input_location,
4176 se->expr);
4178 /* For character(*), use the actual argument's descriptor. */
4179 else if (sym->ts.type == BT_CHARACTER && !new_sym->ts.u.cl->length)
4180 value = build_fold_indirect_ref_loc (input_location,
4181 se->expr);
4183 /* If the argument is an array descriptor, use it to determine
4184 information about the actual argument's shape. */
4185 else if (POINTER_TYPE_P (TREE_TYPE (se->expr))
4186 && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (TREE_TYPE (se->expr))))
4188 /* Get the actual argument's descriptor. */
4189 desc = build_fold_indirect_ref_loc (input_location,
4190 se->expr);
4192 /* Create the replacement variable. */
4193 tmp = gfc_conv_descriptor_data_get (desc);
4194 value = gfc_get_interface_mapping_array (&se->pre, sym,
4195 PACKED_NO, tmp);
4197 /* Use DESC to work out the upper bounds, strides and offset. */
4198 gfc_set_interface_mapping_bounds (&se->pre, TREE_TYPE (value), desc);
4200 else
4201 /* Otherwise we have a packed array. */
4202 value = gfc_get_interface_mapping_array (&se->pre, sym,
4203 PACKED_FULL, se->expr);
4205 new_sym->backend_decl = value;
4209 /* Called once all dummy argument mappings have been added to MAPPING,
4210 but before the mapping is used to evaluate expressions. Pre-evaluate
4211 the length of each argument, adding any initialization code to PRE and
4212 any finalization code to POST. */
4214 void
4215 gfc_finish_interface_mapping (gfc_interface_mapping * mapping,
4216 stmtblock_t * pre, stmtblock_t * post)
4218 gfc_interface_sym_mapping *sym;
4219 gfc_expr *expr;
4220 gfc_se se;
4222 for (sym = mapping->syms; sym; sym = sym->next)
4223 if (sym->new_sym->n.sym->ts.type == BT_CHARACTER
4224 && !sym->new_sym->n.sym->ts.u.cl->backend_decl)
4226 expr = sym->new_sym->n.sym->ts.u.cl->length;
4227 gfc_apply_interface_mapping_to_expr (mapping, expr);
4228 gfc_init_se (&se, NULL);
4229 gfc_conv_expr (&se, expr);
4230 se.expr = fold_convert (gfc_charlen_type_node, se.expr);
4231 se.expr = gfc_evaluate_now (se.expr, &se.pre);
4232 gfc_add_block_to_block (pre, &se.pre);
4233 gfc_add_block_to_block (post, &se.post);
4235 sym->new_sym->n.sym->ts.u.cl->backend_decl = se.expr;
4240 /* Like gfc_apply_interface_mapping_to_expr, but applied to
4241 constructor C. */
4243 static void
4244 gfc_apply_interface_mapping_to_cons (gfc_interface_mapping * mapping,
4245 gfc_constructor_base base)
4247 gfc_constructor *c;
4248 for (c = gfc_constructor_first (base); c; c = gfc_constructor_next (c))
4250 gfc_apply_interface_mapping_to_expr (mapping, c->expr);
4251 if (c->iterator)
4253 gfc_apply_interface_mapping_to_expr (mapping, c->iterator->start);
4254 gfc_apply_interface_mapping_to_expr (mapping, c->iterator->end);
4255 gfc_apply_interface_mapping_to_expr (mapping, c->iterator->step);
4261 /* Like gfc_apply_interface_mapping_to_expr, but applied to
4262 reference REF. */
4264 static void
4265 gfc_apply_interface_mapping_to_ref (gfc_interface_mapping * mapping,
4266 gfc_ref * ref)
4268 int n;
4270 for (; ref; ref = ref->next)
4271 switch (ref->type)
4273 case REF_ARRAY:
4274 for (n = 0; n < ref->u.ar.dimen; n++)
4276 gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.start[n]);
4277 gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.end[n]);
4278 gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.stride[n]);
4280 break;
4282 case REF_COMPONENT:
4283 case REF_INQUIRY:
4284 break;
4286 case REF_SUBSTRING:
4287 gfc_apply_interface_mapping_to_expr (mapping, ref->u.ss.start);
4288 gfc_apply_interface_mapping_to_expr (mapping, ref->u.ss.end);
4289 break;
4294 /* Convert intrinsic function calls into result expressions. */
4296 static bool
4297 gfc_map_intrinsic_function (gfc_expr *expr, gfc_interface_mapping *mapping)
4299 gfc_symbol *sym;
4300 gfc_expr *new_expr;
4301 gfc_expr *arg1;
4302 gfc_expr *arg2;
4303 int d, dup;
4305 arg1 = expr->value.function.actual->expr;
4306 if (expr->value.function.actual->next)
4307 arg2 = expr->value.function.actual->next->expr;
4308 else
4309 arg2 = NULL;
4311 sym = arg1->symtree->n.sym;
4313 if (sym->attr.dummy)
4314 return false;
4316 new_expr = NULL;
4318 switch (expr->value.function.isym->id)
4320 case GFC_ISYM_LEN:
4321 /* TODO figure out why this condition is necessary. */
4322 if (sym->attr.function
4323 && (arg1->ts.u.cl->length == NULL
4324 || (arg1->ts.u.cl->length->expr_type != EXPR_CONSTANT
4325 && arg1->ts.u.cl->length->expr_type != EXPR_VARIABLE)))
4326 return false;
4328 new_expr = gfc_copy_expr (arg1->ts.u.cl->length);
4329 break;
4331 case GFC_ISYM_LEN_TRIM:
4332 new_expr = gfc_copy_expr (arg1);
4333 gfc_apply_interface_mapping_to_expr (mapping, new_expr);
4335 if (!new_expr)
4336 return false;
4338 gfc_replace_expr (arg1, new_expr);
4339 return true;
4341 case GFC_ISYM_SIZE:
4342 if (!sym->as || sym->as->rank == 0)
4343 return false;
4345 if (arg2 && arg2->expr_type == EXPR_CONSTANT)
4347 dup = mpz_get_si (arg2->value.integer);
4348 d = dup - 1;
4350 else
4352 dup = sym->as->rank;
4353 d = 0;
4356 for (; d < dup; d++)
4358 gfc_expr *tmp;
4360 if (!sym->as->upper[d] || !sym->as->lower[d])
4362 gfc_free_expr (new_expr);
4363 return false;
4366 tmp = gfc_add (gfc_copy_expr (sym->as->upper[d]),
4367 gfc_get_int_expr (gfc_default_integer_kind,
4368 NULL, 1));
4369 tmp = gfc_subtract (tmp, gfc_copy_expr (sym->as->lower[d]));
4370 if (new_expr)
4371 new_expr = gfc_multiply (new_expr, tmp);
4372 else
4373 new_expr = tmp;
4375 break;
4377 case GFC_ISYM_LBOUND:
4378 case GFC_ISYM_UBOUND:
4379 /* TODO These implementations of lbound and ubound do not limit if
4380 the size < 0, according to F95's 13.14.53 and 13.14.113. */
4382 if (!sym->as || sym->as->rank == 0)
4383 return false;
4385 if (arg2 && arg2->expr_type == EXPR_CONSTANT)
4386 d = mpz_get_si (arg2->value.integer) - 1;
4387 else
4388 return false;
4390 if (expr->value.function.isym->id == GFC_ISYM_LBOUND)
4392 if (sym->as->lower[d])
4393 new_expr = gfc_copy_expr (sym->as->lower[d]);
4395 else
4397 if (sym->as->upper[d])
4398 new_expr = gfc_copy_expr (sym->as->upper[d]);
4400 break;
4402 default:
4403 break;
4406 gfc_apply_interface_mapping_to_expr (mapping, new_expr);
4407 if (!new_expr)
4408 return false;
4410 gfc_replace_expr (expr, new_expr);
4411 return true;
4415 static void
4416 gfc_map_fcn_formal_to_actual (gfc_expr *expr, gfc_expr *map_expr,
4417 gfc_interface_mapping * mapping)
4419 gfc_formal_arglist *f;
4420 gfc_actual_arglist *actual;
4422 actual = expr->value.function.actual;
4423 f = gfc_sym_get_dummy_args (map_expr->symtree->n.sym);
4425 for (; f && actual; f = f->next, actual = actual->next)
4427 if (!actual->expr)
4428 continue;
4430 gfc_add_interface_mapping (mapping, f->sym, NULL, actual->expr);
4433 if (map_expr->symtree->n.sym->attr.dimension)
4435 int d;
4436 gfc_array_spec *as;
4438 as = gfc_copy_array_spec (map_expr->symtree->n.sym->as);
4440 for (d = 0; d < as->rank; d++)
4442 gfc_apply_interface_mapping_to_expr (mapping, as->lower[d]);
4443 gfc_apply_interface_mapping_to_expr (mapping, as->upper[d]);
4446 expr->value.function.esym->as = as;
4449 if (map_expr->symtree->n.sym->ts.type == BT_CHARACTER)
4451 expr->value.function.esym->ts.u.cl->length
4452 = gfc_copy_expr (map_expr->symtree->n.sym->ts.u.cl->length);
4454 gfc_apply_interface_mapping_to_expr (mapping,
4455 expr->value.function.esym->ts.u.cl->length);
4460 /* EXPR is a copy of an expression that appeared in the interface
4461 associated with MAPPING. Walk it recursively looking for references to
4462 dummy arguments that MAPPING maps to actual arguments. Replace each such
4463 reference with a reference to the associated actual argument. */
4465 static void
4466 gfc_apply_interface_mapping_to_expr (gfc_interface_mapping * mapping,
4467 gfc_expr * expr)
4469 gfc_interface_sym_mapping *sym;
4470 gfc_actual_arglist *actual;
4472 if (!expr)
4473 return;
4475 /* Copying an expression does not copy its length, so do that here. */
4476 if (expr->ts.type == BT_CHARACTER && expr->ts.u.cl)
4478 expr->ts.u.cl = gfc_get_interface_mapping_charlen (mapping, expr->ts.u.cl);
4479 gfc_apply_interface_mapping_to_expr (mapping, expr->ts.u.cl->length);
4482 /* Apply the mapping to any references. */
4483 gfc_apply_interface_mapping_to_ref (mapping, expr->ref);
4485 /* ...and to the expression's symbol, if it has one. */
4486 /* TODO Find out why the condition on expr->symtree had to be moved into
4487 the loop rather than being outside it, as originally. */
4488 for (sym = mapping->syms; sym; sym = sym->next)
4489 if (expr->symtree && sym->old == expr->symtree->n.sym)
4491 if (sym->new_sym->n.sym->backend_decl)
4492 expr->symtree = sym->new_sym;
4493 else if (sym->expr)
4494 gfc_replace_expr (expr, gfc_copy_expr (sym->expr));
4497 /* ...and to subexpressions in expr->value. */
4498 switch (expr->expr_type)
4500 case EXPR_VARIABLE:
4501 case EXPR_CONSTANT:
4502 case EXPR_NULL:
4503 case EXPR_SUBSTRING:
4504 break;
4506 case EXPR_OP:
4507 gfc_apply_interface_mapping_to_expr (mapping, expr->value.op.op1);
4508 gfc_apply_interface_mapping_to_expr (mapping, expr->value.op.op2);
4509 break;
4511 case EXPR_FUNCTION:
4512 for (actual = expr->value.function.actual; actual; actual = actual->next)
4513 gfc_apply_interface_mapping_to_expr (mapping, actual->expr);
4515 if (expr->value.function.esym == NULL
4516 && expr->value.function.isym != NULL
4517 && expr->value.function.actual
4518 && expr->value.function.actual->expr
4519 && expr->value.function.actual->expr->symtree
4520 && gfc_map_intrinsic_function (expr, mapping))
4521 break;
4523 for (sym = mapping->syms; sym; sym = sym->next)
4524 if (sym->old == expr->value.function.esym)
4526 expr->value.function.esym = sym->new_sym->n.sym;
4527 gfc_map_fcn_formal_to_actual (expr, sym->expr, mapping);
4528 expr->value.function.esym->result = sym->new_sym->n.sym;
4530 break;
4532 case EXPR_ARRAY:
4533 case EXPR_STRUCTURE:
4534 gfc_apply_interface_mapping_to_cons (mapping, expr->value.constructor);
4535 break;
4537 case EXPR_COMPCALL:
4538 case EXPR_PPC:
4539 gcc_unreachable ();
4540 break;
4543 return;
4547 /* Evaluate interface expression EXPR using MAPPING. Store the result
4548 in SE. */
4550 void
4551 gfc_apply_interface_mapping (gfc_interface_mapping * mapping,
4552 gfc_se * se, gfc_expr * expr)
4554 expr = gfc_copy_expr (expr);
4555 gfc_apply_interface_mapping_to_expr (mapping, expr);
4556 gfc_conv_expr (se, expr);
4557 se->expr = gfc_evaluate_now (se->expr, &se->pre);
4558 gfc_free_expr (expr);
4562 /* Returns a reference to a temporary array into which a component of
4563 an actual argument derived type array is copied and then returned
4564 after the function call. */
4565 void
4566 gfc_conv_subref_array_arg (gfc_se * parmse, gfc_expr * expr, int g77,
4567 sym_intent intent, bool formal_ptr)
4569 gfc_se lse;
4570 gfc_se rse;
4571 gfc_ss *lss;
4572 gfc_ss *rss;
4573 gfc_loopinfo loop;
4574 gfc_loopinfo loop2;
4575 gfc_array_info *info;
4576 tree offset;
4577 tree tmp_index;
4578 tree tmp;
4579 tree base_type;
4580 tree size;
4581 stmtblock_t body;
4582 int n;
4583 int dimen;
4585 gfc_init_se (&lse, NULL);
4586 gfc_init_se (&rse, NULL);
4588 /* Walk the argument expression. */
4589 rss = gfc_walk_expr (expr);
4591 gcc_assert (rss != gfc_ss_terminator);
4593 /* Initialize the scalarizer. */
4594 gfc_init_loopinfo (&loop);
4595 gfc_add_ss_to_loop (&loop, rss);
4597 /* Calculate the bounds of the scalarization. */
4598 gfc_conv_ss_startstride (&loop);
4600 /* Build an ss for the temporary. */
4601 if (expr->ts.type == BT_CHARACTER && !expr->ts.u.cl->backend_decl)
4602 gfc_conv_string_length (expr->ts.u.cl, expr, &parmse->pre);
4604 base_type = gfc_typenode_for_spec (&expr->ts);
4605 if (GFC_ARRAY_TYPE_P (base_type)
4606 || GFC_DESCRIPTOR_TYPE_P (base_type))
4607 base_type = gfc_get_element_type (base_type);
4609 if (expr->ts.type == BT_CLASS)
4610 base_type = gfc_typenode_for_spec (&CLASS_DATA (expr)->ts);
4612 loop.temp_ss = gfc_get_temp_ss (base_type, ((expr->ts.type == BT_CHARACTER)
4613 ? expr->ts.u.cl->backend_decl
4614 : NULL),
4615 loop.dimen);
4617 parmse->string_length = loop.temp_ss->info->string_length;
4619 /* Associate the SS with the loop. */
4620 gfc_add_ss_to_loop (&loop, loop.temp_ss);
4622 /* Setup the scalarizing loops. */
4623 gfc_conv_loop_setup (&loop, &expr->where);
4625 /* Pass the temporary descriptor back to the caller. */
4626 info = &loop.temp_ss->info->data.array;
4627 parmse->expr = info->descriptor;
4629 /* Setup the gfc_se structures. */
4630 gfc_copy_loopinfo_to_se (&lse, &loop);
4631 gfc_copy_loopinfo_to_se (&rse, &loop);
4633 rse.ss = rss;
4634 lse.ss = loop.temp_ss;
4635 gfc_mark_ss_chain_used (rss, 1);
4636 gfc_mark_ss_chain_used (loop.temp_ss, 1);
4638 /* Start the scalarized loop body. */
4639 gfc_start_scalarized_body (&loop, &body);
4641 /* Translate the expression. */
4642 gfc_conv_expr (&rse, expr);
4644 /* Reset the offset for the function call since the loop
4645 is zero based on the data pointer. Note that the temp
4646 comes first in the loop chain since it is added second. */
4647 if (gfc_is_class_array_function (expr))
4649 tmp = loop.ss->loop_chain->info->data.array.descriptor;
4650 gfc_conv_descriptor_offset_set (&loop.pre, tmp,
4651 gfc_index_zero_node);
4654 gfc_conv_tmp_array_ref (&lse);
4656 if (intent != INTENT_OUT)
4658 tmp = gfc_trans_scalar_assign (&lse, &rse, expr->ts, false, false);
4659 gfc_add_expr_to_block (&body, tmp);
4660 gcc_assert (rse.ss == gfc_ss_terminator);
4661 gfc_trans_scalarizing_loops (&loop, &body);
4663 else
4665 /* Make sure that the temporary declaration survives by merging
4666 all the loop declarations into the current context. */
4667 for (n = 0; n < loop.dimen; n++)
4669 gfc_merge_block_scope (&body);
4670 body = loop.code[loop.order[n]];
4672 gfc_merge_block_scope (&body);
4675 /* Add the post block after the second loop, so that any
4676 freeing of allocated memory is done at the right time. */
4677 gfc_add_block_to_block (&parmse->pre, &loop.pre);
4679 /**********Copy the temporary back again.*********/
4681 gfc_init_se (&lse, NULL);
4682 gfc_init_se (&rse, NULL);
4684 /* Walk the argument expression. */
4685 lss = gfc_walk_expr (expr);
4686 rse.ss = loop.temp_ss;
4687 lse.ss = lss;
4689 /* Initialize the scalarizer. */
4690 gfc_init_loopinfo (&loop2);
4691 gfc_add_ss_to_loop (&loop2, lss);
4693 dimen = rse.ss->dimen;
4695 /* Skip the write-out loop for this case. */
4696 if (gfc_is_class_array_function (expr))
4697 goto class_array_fcn;
4699 /* Calculate the bounds of the scalarization. */
4700 gfc_conv_ss_startstride (&loop2);
4702 /* Setup the scalarizing loops. */
4703 gfc_conv_loop_setup (&loop2, &expr->where);
4705 gfc_copy_loopinfo_to_se (&lse, &loop2);
4706 gfc_copy_loopinfo_to_se (&rse, &loop2);
4708 gfc_mark_ss_chain_used (lss, 1);
4709 gfc_mark_ss_chain_used (loop.temp_ss, 1);
4711 /* Declare the variable to hold the temporary offset and start the
4712 scalarized loop body. */
4713 offset = gfc_create_var (gfc_array_index_type, NULL);
4714 gfc_start_scalarized_body (&loop2, &body);
4716 /* Build the offsets for the temporary from the loop variables. The
4717 temporary array has lbounds of zero and strides of one in all
4718 dimensions, so this is very simple. The offset is only computed
4719 outside the innermost loop, so the overall transfer could be
4720 optimized further. */
4721 info = &rse.ss->info->data.array;
4723 tmp_index = gfc_index_zero_node;
4724 for (n = dimen - 1; n > 0; n--)
4726 tree tmp_str;
4727 tmp = rse.loop->loopvar[n];
4728 tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
4729 tmp, rse.loop->from[n]);
4730 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
4731 tmp, tmp_index);
4733 tmp_str = fold_build2_loc (input_location, MINUS_EXPR,
4734 gfc_array_index_type,
4735 rse.loop->to[n-1], rse.loop->from[n-1]);
4736 tmp_str = fold_build2_loc (input_location, PLUS_EXPR,
4737 gfc_array_index_type,
4738 tmp_str, gfc_index_one_node);
4740 tmp_index = fold_build2_loc (input_location, MULT_EXPR,
4741 gfc_array_index_type, tmp, tmp_str);
4744 tmp_index = fold_build2_loc (input_location, MINUS_EXPR,
4745 gfc_array_index_type,
4746 tmp_index, rse.loop->from[0]);
4747 gfc_add_modify (&rse.loop->code[0], offset, tmp_index);
4749 tmp_index = fold_build2_loc (input_location, PLUS_EXPR,
4750 gfc_array_index_type,
4751 rse.loop->loopvar[0], offset);
4753 /* Now use the offset for the reference. */
4754 tmp = build_fold_indirect_ref_loc (input_location,
4755 info->data);
4756 rse.expr = gfc_build_array_ref (tmp, tmp_index, NULL);
4758 if (expr->ts.type == BT_CHARACTER)
4759 rse.string_length = expr->ts.u.cl->backend_decl;
4761 gfc_conv_expr (&lse, expr);
4763 gcc_assert (lse.ss == gfc_ss_terminator);
4765 tmp = gfc_trans_scalar_assign (&lse, &rse, expr->ts, false, true);
4766 gfc_add_expr_to_block (&body, tmp);
4768 /* Generate the copying loops. */
4769 gfc_trans_scalarizing_loops (&loop2, &body);
4771 /* Wrap the whole thing up by adding the second loop to the post-block
4772 and following it by the post-block of the first loop. In this way,
4773 if the temporary needs freeing, it is done after use! */
4774 if (intent != INTENT_IN)
4776 gfc_add_block_to_block (&parmse->post, &loop2.pre);
4777 gfc_add_block_to_block (&parmse->post, &loop2.post);
4780 class_array_fcn:
4782 gfc_add_block_to_block (&parmse->post, &loop.post);
4784 gfc_cleanup_loop (&loop);
4785 gfc_cleanup_loop (&loop2);
4787 /* Pass the string length to the argument expression. */
4788 if (expr->ts.type == BT_CHARACTER)
4789 parmse->string_length = expr->ts.u.cl->backend_decl;
4791 /* Determine the offset for pointer formal arguments and set the
4792 lbounds to one. */
4793 if (formal_ptr)
4795 size = gfc_index_one_node;
4796 offset = gfc_index_zero_node;
4797 for (n = 0; n < dimen; n++)
4799 tmp = gfc_conv_descriptor_ubound_get (parmse->expr,
4800 gfc_rank_cst[n]);
4801 tmp = fold_build2_loc (input_location, PLUS_EXPR,
4802 gfc_array_index_type, tmp,
4803 gfc_index_one_node);
4804 gfc_conv_descriptor_ubound_set (&parmse->pre,
4805 parmse->expr,
4806 gfc_rank_cst[n],
4807 tmp);
4808 gfc_conv_descriptor_lbound_set (&parmse->pre,
4809 parmse->expr,
4810 gfc_rank_cst[n],
4811 gfc_index_one_node);
4812 size = gfc_evaluate_now (size, &parmse->pre);
4813 offset = fold_build2_loc (input_location, MINUS_EXPR,
4814 gfc_array_index_type,
4815 offset, size);
4816 offset = gfc_evaluate_now (offset, &parmse->pre);
4817 tmp = fold_build2_loc (input_location, MINUS_EXPR,
4818 gfc_array_index_type,
4819 rse.loop->to[n], rse.loop->from[n]);
4820 tmp = fold_build2_loc (input_location, PLUS_EXPR,
4821 gfc_array_index_type,
4822 tmp, gfc_index_one_node);
4823 size = fold_build2_loc (input_location, MULT_EXPR,
4824 gfc_array_index_type, size, tmp);
4827 gfc_conv_descriptor_offset_set (&parmse->pre, parmse->expr,
4828 offset);
4831 /* We want either the address for the data or the address of the descriptor,
4832 depending on the mode of passing array arguments. */
4833 if (g77)
4834 parmse->expr = gfc_conv_descriptor_data_get (parmse->expr);
4835 else
4836 parmse->expr = gfc_build_addr_expr (NULL_TREE, parmse->expr);
4838 return;
4842 /* Generate the code for argument list functions. */
4844 static void
4845 conv_arglist_function (gfc_se *se, gfc_expr *expr, const char *name)
4847 /* Pass by value for g77 %VAL(arg), pass the address
4848 indirectly for %LOC, else by reference. Thus %REF
4849 is a "do-nothing" and %LOC is the same as an F95
4850 pointer. */
4851 if (strcmp (name, "%VAL") == 0)
4852 gfc_conv_expr (se, expr);
4853 else if (strcmp (name, "%LOC") == 0)
4855 gfc_conv_expr_reference (se, expr);
4856 se->expr = gfc_build_addr_expr (NULL, se->expr);
4858 else if (strcmp (name, "%REF") == 0)
4859 gfc_conv_expr_reference (se, expr);
4860 else
4861 gfc_error ("Unknown argument list function at %L", &expr->where);
4865 /* This function tells whether the middle-end representation of the expression
4866 E given as input may point to data otherwise accessible through a variable
4867 (sub-)reference.
4868 It is assumed that the only expressions that may alias are variables,
4869 and array constructors if ARRAY_MAY_ALIAS is true and some of its elements
4870 may alias.
4871 This function is used to decide whether freeing an expression's allocatable
4872 components is safe or should be avoided.
4874 If ARRAY_MAY_ALIAS is true, an array constructor may alias if some of
4875 its elements are copied from a variable. This ARRAY_MAY_ALIAS trick
4876 is necessary because for array constructors, aliasing depends on how
4877 the array is used:
4878 - If E is an array constructor used as argument to an elemental procedure,
4879 the array, which is generated through shallow copy by the scalarizer,
4880 is used directly and can alias the expressions it was copied from.
4881 - If E is an array constructor used as argument to a non-elemental
4882 procedure,the scalarizer is used in gfc_conv_expr_descriptor to generate
4883 the array as in the previous case, but then that array is used
4884 to initialize a new descriptor through deep copy. There is no alias
4885 possible in that case.
4886 Thus, the ARRAY_MAY_ALIAS flag is necessary to distinguish the two cases
4887 above. */
4889 static bool
4890 expr_may_alias_variables (gfc_expr *e, bool array_may_alias)
4892 gfc_constructor *c;
4894 if (e->expr_type == EXPR_VARIABLE)
4895 return true;
4896 else if (e->expr_type == EXPR_FUNCTION)
4898 gfc_symbol *proc_ifc = gfc_get_proc_ifc_for_expr (e);
4900 if (proc_ifc->result != NULL
4901 && ((proc_ifc->result->ts.type == BT_CLASS
4902 && proc_ifc->result->ts.u.derived->attr.is_class
4903 && CLASS_DATA (proc_ifc->result)->attr.class_pointer)
4904 || proc_ifc->result->attr.pointer))
4905 return true;
4906 else
4907 return false;
4909 else if (e->expr_type != EXPR_ARRAY || !array_may_alias)
4910 return false;
4912 for (c = gfc_constructor_first (e->value.constructor);
4913 c; c = gfc_constructor_next (c))
4914 if (c->expr
4915 && expr_may_alias_variables (c->expr, array_may_alias))
4916 return true;
4918 return false;
4922 /* A helper function to set the dtype for unallocated or unassociated
4923 entities. */
4925 static void
4926 set_dtype_for_unallocated (gfc_se *parmse, gfc_expr *e)
4928 tree tmp;
4929 tree desc;
4930 tree cond;
4931 tree type;
4932 stmtblock_t block;
4934 /* TODO Figure out how to handle optional dummies. */
4935 if (e && e->expr_type == EXPR_VARIABLE
4936 && e->symtree->n.sym->attr.optional)
4937 return;
4939 desc = parmse->expr;
4940 if (desc == NULL_TREE)
4941 return;
4943 if (POINTER_TYPE_P (TREE_TYPE (desc)))
4944 desc = build_fold_indirect_ref_loc (input_location, desc);
4946 if (!GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (desc)))
4947 return;
4949 gfc_init_block (&block);
4950 tmp = gfc_conv_descriptor_data_get (desc);
4951 cond = fold_build2_loc (input_location, EQ_EXPR,
4952 logical_type_node, tmp,
4953 build_int_cst (TREE_TYPE (tmp), 0));
4954 tmp = gfc_conv_descriptor_dtype (desc);
4955 type = gfc_get_element_type (TREE_TYPE (desc));
4956 tmp = fold_build2_loc (input_location, MODIFY_EXPR,
4957 TREE_TYPE (tmp), tmp,
4958 gfc_get_dtype_rank_type (e->rank, type));
4959 gfc_add_expr_to_block (&block, tmp);
4960 cond = build3_v (COND_EXPR, cond,
4961 gfc_finish_block (&block),
4962 build_empty_stmt (input_location));
4963 gfc_add_expr_to_block (&parmse->pre, cond);
4968 /* Provide an interface between gfortran array descriptors and the F2018:18.4
4969 ISO_Fortran_binding array descriptors. */
4971 static void
4972 gfc_conv_gfc_desc_to_cfi_desc (gfc_se *parmse, gfc_expr *e, gfc_symbol *fsym)
4974 tree tmp;
4975 tree cfi_desc_ptr;
4976 tree gfc_desc_ptr;
4977 tree ptr = NULL_TREE;
4978 tree size;
4979 tree type;
4980 int attribute;
4981 symbol_attribute attr = gfc_expr_attr (e);
4983 /* If this is a full array or a scalar, the allocatable and pointer
4984 attributes can be passed. Otherwise it is 'CFI_attribute_other'*/
4985 attribute = 2;
4986 if (!e->rank || gfc_get_full_arrayspec_from_expr (e))
4988 if (attr.pointer)
4989 attribute = 0;
4990 else if (attr.allocatable)
4991 attribute = 1;
4994 if (e->rank != 0)
4996 if (fsym->attr.contiguous
4997 && !gfc_is_simply_contiguous (e, false, true))
4998 gfc_conv_subref_array_arg (parmse, e, false, fsym->attr.intent,
4999 fsym->attr.pointer);
5000 else
5001 gfc_conv_expr_descriptor (parmse, e);
5003 if (POINTER_TYPE_P (TREE_TYPE (parmse->expr)))
5004 parmse->expr = build_fold_indirect_ref_loc (input_location,
5005 parmse->expr);
5007 /* Unallocated allocatable arrays and unassociated pointer arrays
5008 need their dtype setting if they are argument associated with
5009 assumed rank dummies. */
5010 if (fsym && fsym->as
5011 && fsym->as->type == AS_ASSUMED_RANK
5012 && (gfc_expr_attr (e).pointer
5013 || gfc_expr_attr (e).allocatable))
5014 set_dtype_for_unallocated (parmse, e);
5016 /* All the temporary descriptors are marked as DECL_ARTIFICIAL. If
5017 the expression type is different from the descriptor type, then
5018 the offset must be found (eg. to a component ref or substring)
5019 and the dtype updated. Assumed type entities are only allowed
5020 to be dummies in Fortran. They therefore lack the decl specific
5021 appendiges and so must be treated differently from other fortran
5022 entities passed to CFI descriptors in the interface decl. */
5023 type = e->ts.type != BT_ASSUMED ? gfc_typenode_for_spec (&e->ts) :
5024 NULL_TREE;
5026 if (type && DECL_ARTIFICIAL (parmse->expr)
5027 && type != gfc_get_element_type (TREE_TYPE (parmse->expr)))
5029 /* Obtain the offset to the data. */
5030 gfc_get_dataptr_offset (&parmse->pre, parmse->expr, parmse->expr,
5031 gfc_index_zero_node, true, e);
5033 /* Update the dtype. */
5034 gfc_add_modify (&parmse->pre,
5035 gfc_conv_descriptor_dtype (parmse->expr),
5036 gfc_get_dtype_rank_type (e->rank, type));
5038 else if (type == NULL_TREE
5039 || (!is_subref_array (e) && !DECL_ARTIFICIAL (parmse->expr)))
5041 /* Make sure that the span is set for expressions where it
5042 might not have been done already. */
5043 tmp = gfc_conv_descriptor_elem_len (parmse->expr);
5044 tmp = fold_convert (gfc_array_index_type, tmp);
5045 gfc_conv_descriptor_span_set (&parmse->pre, parmse->expr, tmp);
5048 /* INTENT(IN) requires a temporary for the data. Assumed types do not
5049 work with the standard temporary generation schemes. */
5050 if (e->expr_type == EXPR_VARIABLE && fsym->attr.intent == INTENT_IN)
5052 /* Fix the descriptor and determine the size of the data. */
5053 parmse->expr = gfc_evaluate_now (parmse->expr, &parmse->pre);
5054 size = build_call_expr_loc (input_location,
5055 gfor_fndecl_size0, 1,
5056 gfc_build_addr_expr (NULL, parmse->expr));
5057 size = fold_convert (size_type_node, size);
5058 tmp = gfc_conv_descriptor_span_get (parmse->expr);
5059 tmp = fold_convert (size_type_node, tmp);
5060 size = fold_build2_loc (input_location, MULT_EXPR,
5061 size_type_node, size, tmp);
5062 /* Fix the size and allocate. */
5063 size = gfc_evaluate_now (size, &parmse->pre);
5064 tmp = builtin_decl_explicit (BUILT_IN_MALLOC);
5065 ptr = build_call_expr_loc (input_location, tmp, 1, size);
5066 ptr = gfc_evaluate_now (ptr, &parmse->pre);
5067 /* Copy the data to the temporary descriptor. */
5068 tmp = builtin_decl_explicit (BUILT_IN_MEMCPY);
5069 tmp = build_call_expr_loc (input_location, tmp, 3, ptr,
5070 gfc_conv_descriptor_data_get (parmse->expr),
5071 size);
5072 gfc_add_expr_to_block (&parmse->pre, tmp);
5074 /* The temporary 'ptr' is freed below. */
5075 gfc_conv_descriptor_data_set (&parmse->pre, parmse->expr, ptr);
5079 else
5081 gfc_conv_expr (parmse, e);
5083 if (POINTER_TYPE_P (TREE_TYPE (parmse->expr)))
5084 parmse->expr = build_fold_indirect_ref_loc (input_location,
5085 parmse->expr);
5087 /* Copy the scalar for INTENT(IN). */
5088 if (e->expr_type == EXPR_VARIABLE && fsym->attr.intent == INTENT_IN)
5090 if (e->ts.type != BT_CHARACTER)
5091 parmse->expr = gfc_evaluate_now (parmse->expr, &parmse->pre);
5092 else
5094 /* The temporary string 'ptr' is freed below. */
5095 tmp = build_pointer_type (TREE_TYPE (parmse->expr));
5096 ptr = gfc_create_var (tmp, "str");
5097 tmp = build_call_expr_loc (input_location,
5098 builtin_decl_explicit (BUILT_IN_MALLOC),
5099 1, parmse->string_length);
5100 tmp = fold_convert (TREE_TYPE (ptr), tmp);
5101 gfc_add_modify (&parmse->pre, ptr, tmp);
5102 tmp = gfc_build_memcpy_call (ptr, parmse->expr,
5103 parmse->string_length);
5104 gfc_add_expr_to_block (&parmse->pre, tmp);
5105 parmse->expr = ptr;
5109 parmse->expr = gfc_conv_scalar_to_descriptor (parmse,
5110 parmse->expr, attr);
5113 /* Set the CFI attribute field. */
5114 tmp = gfc_conv_descriptor_attribute (parmse->expr);
5115 tmp = fold_build2_loc (input_location, MODIFY_EXPR,
5116 void_type_node, tmp,
5117 build_int_cst (TREE_TYPE (tmp), attribute));
5118 gfc_add_expr_to_block (&parmse->pre, tmp);
5120 /* Now pass the gfc_descriptor by reference. */
5121 parmse->expr = gfc_build_addr_expr (NULL_TREE, parmse->expr);
5123 /* Variables to point to the gfc and CFI descriptors. */
5124 gfc_desc_ptr = parmse->expr;
5125 cfi_desc_ptr = gfc_create_var (pvoid_type_node, "cfi");
5127 /* Allocate the CFI descriptor and fill the fields. */
5128 tmp = gfc_build_addr_expr (NULL_TREE, cfi_desc_ptr);
5129 tmp = build_call_expr_loc (input_location,
5130 gfor_fndecl_gfc_to_cfi, 2, tmp, gfc_desc_ptr);
5131 gfc_add_expr_to_block (&parmse->pre, tmp);
5133 /* The CFI descriptor is passed to the bind_C procedure. */
5134 parmse->expr = cfi_desc_ptr;
5136 if (ptr)
5138 /* Free both the temporary data and the CFI descriptor for
5139 INTENT(IN) arrays. */
5140 tmp = gfc_call_free (ptr);
5141 gfc_prepend_expr_to_block (&parmse->post, tmp);
5142 tmp = gfc_call_free (cfi_desc_ptr);
5143 gfc_prepend_expr_to_block (&parmse->post, tmp);
5144 return;
5147 /* Transfer values back to gfc descriptor and free the CFI descriptor. */
5148 tmp = gfc_build_addr_expr (NULL_TREE, parmse->expr);
5149 tmp = build_call_expr_loc (input_location,
5150 gfor_fndecl_cfi_to_gfc, 2, gfc_desc_ptr, tmp);
5151 gfc_prepend_expr_to_block (&parmse->post, tmp);
5155 /* Generate code for a procedure call. Note can return se->post != NULL.
5156 If se->direct_byref is set then se->expr contains the return parameter.
5157 Return nonzero, if the call has alternate specifiers.
5158 'expr' is only needed for procedure pointer components. */
5161 gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
5162 gfc_actual_arglist * args, gfc_expr * expr,
5163 vec<tree, va_gc> *append_args)
5165 gfc_interface_mapping mapping;
5166 vec<tree, va_gc> *arglist;
5167 vec<tree, va_gc> *retargs;
5168 tree tmp;
5169 tree fntype;
5170 gfc_se parmse;
5171 gfc_array_info *info;
5172 int byref;
5173 int parm_kind;
5174 tree type;
5175 tree var;
5176 tree len;
5177 tree base_object;
5178 vec<tree, va_gc> *stringargs;
5179 vec<tree, va_gc> *optionalargs;
5180 tree result = NULL;
5181 gfc_formal_arglist *formal;
5182 gfc_actual_arglist *arg;
5183 int has_alternate_specifier = 0;
5184 bool need_interface_mapping;
5185 bool callee_alloc;
5186 bool ulim_copy;
5187 gfc_typespec ts;
5188 gfc_charlen cl;
5189 gfc_expr *e;
5190 gfc_symbol *fsym;
5191 stmtblock_t post;
5192 enum {MISSING = 0, ELEMENTAL, SCALAR, SCALAR_POINTER, ARRAY};
5193 gfc_component *comp = NULL;
5194 int arglen;
5195 unsigned int argc;
5197 arglist = NULL;
5198 retargs = NULL;
5199 stringargs = NULL;
5200 optionalargs = NULL;
5201 var = NULL_TREE;
5202 len = NULL_TREE;
5203 gfc_clear_ts (&ts);
5205 comp = gfc_get_proc_ptr_comp (expr);
5207 bool elemental_proc = (comp
5208 && comp->ts.interface
5209 && comp->ts.interface->attr.elemental)
5210 || (comp && comp->attr.elemental)
5211 || sym->attr.elemental;
5213 if (se->ss != NULL)
5215 if (!elemental_proc)
5217 gcc_assert (se->ss->info->type == GFC_SS_FUNCTION);
5218 if (se->ss->info->useflags)
5220 gcc_assert ((!comp && gfc_return_by_reference (sym)
5221 && sym->result->attr.dimension)
5222 || (comp && comp->attr.dimension)
5223 || gfc_is_class_array_function (expr));
5224 gcc_assert (se->loop != NULL);
5225 /* Access the previously obtained result. */
5226 gfc_conv_tmp_array_ref (se);
5227 return 0;
5230 info = &se->ss->info->data.array;
5232 else
5233 info = NULL;
5235 gfc_init_block (&post);
5236 gfc_init_interface_mapping (&mapping);
5237 if (!comp)
5239 formal = gfc_sym_get_dummy_args (sym);
5240 need_interface_mapping = sym->attr.dimension ||
5241 (sym->ts.type == BT_CHARACTER
5242 && sym->ts.u.cl->length
5243 && sym->ts.u.cl->length->expr_type
5244 != EXPR_CONSTANT);
5246 else
5248 formal = comp->ts.interface ? comp->ts.interface->formal : NULL;
5249 need_interface_mapping = comp->attr.dimension ||
5250 (comp->ts.type == BT_CHARACTER
5251 && comp->ts.u.cl->length
5252 && comp->ts.u.cl->length->expr_type
5253 != EXPR_CONSTANT);
5256 base_object = NULL_TREE;
5257 /* For _vprt->_copy () routines no formal symbol is present. Nevertheless
5258 is the third and fourth argument to such a function call a value
5259 denoting the number of elements to copy (i.e., most of the time the
5260 length of a deferred length string). */
5261 ulim_copy = (formal == NULL)
5262 && UNLIMITED_POLY (sym)
5263 && comp && (strcmp ("_copy", comp->name) == 0);
5265 /* Evaluate the arguments. */
5266 for (arg = args, argc = 0; arg != NULL;
5267 arg = arg->next, formal = formal ? formal->next : NULL, ++argc)
5269 bool finalized = false;
5270 bool non_unity_length_string = false;
5272 e = arg->expr;
5273 fsym = formal ? formal->sym : NULL;
5274 parm_kind = MISSING;
5276 if (fsym && fsym->ts.type == BT_CHARACTER && fsym->ts.u.cl
5277 && (!fsym->ts.u.cl->length
5278 || fsym->ts.u.cl->length->expr_type != EXPR_CONSTANT
5279 || mpz_cmp_si (fsym->ts.u.cl->length->value.integer, 1) != 0))
5280 non_unity_length_string = true;
5282 /* If the procedure requires an explicit interface, the actual
5283 argument is passed according to the corresponding formal
5284 argument. If the corresponding formal argument is a POINTER,
5285 ALLOCATABLE or assumed shape, we do not use g77's calling
5286 convention, and pass the address of the array descriptor
5287 instead. Otherwise we use g77's calling convention, in other words
5288 pass the array data pointer without descriptor. */
5289 bool nodesc_arg = fsym != NULL
5290 && !(fsym->attr.pointer || fsym->attr.allocatable)
5291 && fsym->as
5292 && fsym->as->type != AS_ASSUMED_SHAPE
5293 && fsym->as->type != AS_ASSUMED_RANK;
5294 if (comp)
5295 nodesc_arg = nodesc_arg || !comp->attr.always_explicit;
5296 else
5297 nodesc_arg = nodesc_arg || !sym->attr.always_explicit;
5299 /* Class array expressions are sometimes coming completely unadorned
5300 with either arrayspec or _data component. Correct that here.
5301 OOP-TODO: Move this to the frontend. */
5302 if (e && e->expr_type == EXPR_VARIABLE
5303 && !e->ref
5304 && e->ts.type == BT_CLASS
5305 && (CLASS_DATA (e)->attr.codimension
5306 || CLASS_DATA (e)->attr.dimension))
5308 gfc_typespec temp_ts = e->ts;
5309 gfc_add_class_array_ref (e);
5310 e->ts = temp_ts;
5313 if (e == NULL)
5315 if (se->ignore_optional)
5317 /* Some intrinsics have already been resolved to the correct
5318 parameters. */
5319 continue;
5321 else if (arg->label)
5323 has_alternate_specifier = 1;
5324 continue;
5326 else
5328 gfc_init_se (&parmse, NULL);
5330 /* For scalar arguments with VALUE attribute which are passed by
5331 value, pass "0" and a hidden argument gives the optional
5332 status. */
5333 if (fsym && fsym->attr.optional && fsym->attr.value
5334 && !fsym->attr.dimension && fsym->ts.type != BT_CHARACTER
5335 && fsym->ts.type != BT_CLASS && fsym->ts.type != BT_DERIVED)
5337 parmse.expr = fold_convert (gfc_sym_type (fsym),
5338 integer_zero_node);
5339 vec_safe_push (optionalargs, boolean_false_node);
5341 else
5343 /* Pass a NULL pointer for an absent arg. */
5344 parmse.expr = null_pointer_node;
5345 if (arg->missing_arg_type == BT_CHARACTER)
5346 parmse.string_length = build_int_cst (gfc_charlen_type_node,
5351 else if (arg->expr->expr_type == EXPR_NULL
5352 && fsym && !fsym->attr.pointer
5353 && (fsym->ts.type != BT_CLASS
5354 || !CLASS_DATA (fsym)->attr.class_pointer))
5356 /* Pass a NULL pointer to denote an absent arg. */
5357 gcc_assert (fsym->attr.optional && !fsym->attr.allocatable
5358 && (fsym->ts.type != BT_CLASS
5359 || !CLASS_DATA (fsym)->attr.allocatable));
5360 gfc_init_se (&parmse, NULL);
5361 parmse.expr = null_pointer_node;
5362 if (arg->missing_arg_type == BT_CHARACTER)
5363 parmse.string_length = build_int_cst (gfc_charlen_type_node, 0);
5365 else if (fsym && fsym->ts.type == BT_CLASS
5366 && e->ts.type == BT_DERIVED)
5368 /* The derived type needs to be converted to a temporary
5369 CLASS object. */
5370 gfc_init_se (&parmse, se);
5371 gfc_conv_derived_to_class (&parmse, e, fsym->ts, NULL,
5372 fsym->attr.optional
5373 && e->expr_type == EXPR_VARIABLE
5374 && e->symtree->n.sym->attr.optional,
5375 CLASS_DATA (fsym)->attr.class_pointer
5376 || CLASS_DATA (fsym)->attr.allocatable);
5378 else if (UNLIMITED_POLY (fsym) && e->ts.type != BT_CLASS)
5380 /* The intrinsic type needs to be converted to a temporary
5381 CLASS object for the unlimited polymorphic formal. */
5382 gfc_init_se (&parmse, se);
5383 gfc_conv_intrinsic_to_class (&parmse, e, fsym->ts);
5385 else if (se->ss && se->ss->info->useflags)
5387 gfc_ss *ss;
5389 ss = se->ss;
5391 /* An elemental function inside a scalarized loop. */
5392 gfc_init_se (&parmse, se);
5393 parm_kind = ELEMENTAL;
5395 /* When no fsym is present, ulim_copy is set and this is a third or
5396 fourth argument, use call-by-value instead of by reference to
5397 hand the length properties to the copy routine (i.e., most of the
5398 time this will be a call to a __copy_character_* routine where the
5399 third and fourth arguments are the lengths of a deferred length
5400 char array). */
5401 if ((fsym && fsym->attr.value)
5402 || (ulim_copy && (argc == 2 || argc == 3)))
5403 gfc_conv_expr (&parmse, e);
5404 else
5405 gfc_conv_expr_reference (&parmse, e);
5407 if (e->ts.type == BT_CHARACTER && !e->rank
5408 && e->expr_type == EXPR_FUNCTION)
5409 parmse.expr = build_fold_indirect_ref_loc (input_location,
5410 parmse.expr);
5412 if (fsym && fsym->ts.type == BT_DERIVED
5413 && gfc_is_class_container_ref (e))
5415 parmse.expr = gfc_class_data_get (parmse.expr);
5417 if (fsym->attr.optional && e->expr_type == EXPR_VARIABLE
5418 && e->symtree->n.sym->attr.optional)
5420 tree cond = gfc_conv_expr_present (e->symtree->n.sym);
5421 parmse.expr = build3_loc (input_location, COND_EXPR,
5422 TREE_TYPE (parmse.expr),
5423 cond, parmse.expr,
5424 fold_convert (TREE_TYPE (parmse.expr),
5425 null_pointer_node));
5429 /* If we are passing an absent array as optional dummy to an
5430 elemental procedure, make sure that we pass NULL when the data
5431 pointer is NULL. We need this extra conditional because of
5432 scalarization which passes arrays elements to the procedure,
5433 ignoring the fact that the array can be absent/unallocated/... */
5434 if (ss->info->can_be_null_ref && ss->info->type != GFC_SS_REFERENCE)
5436 tree descriptor_data;
5438 descriptor_data = ss->info->data.array.data;
5439 tmp = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
5440 descriptor_data,
5441 fold_convert (TREE_TYPE (descriptor_data),
5442 null_pointer_node));
5443 parmse.expr
5444 = fold_build3_loc (input_location, COND_EXPR,
5445 TREE_TYPE (parmse.expr),
5446 gfc_unlikely (tmp, PRED_FORTRAN_ABSENT_DUMMY),
5447 fold_convert (TREE_TYPE (parmse.expr),
5448 null_pointer_node),
5449 parmse.expr);
5452 /* The scalarizer does not repackage the reference to a class
5453 array - instead it returns a pointer to the data element. */
5454 if (fsym && fsym->ts.type == BT_CLASS && e->ts.type == BT_CLASS)
5455 gfc_conv_class_to_class (&parmse, e, fsym->ts, true,
5456 fsym->attr.intent != INTENT_IN
5457 && (CLASS_DATA (fsym)->attr.class_pointer
5458 || CLASS_DATA (fsym)->attr.allocatable),
5459 fsym->attr.optional
5460 && e->expr_type == EXPR_VARIABLE
5461 && e->symtree->n.sym->attr.optional,
5462 CLASS_DATA (fsym)->attr.class_pointer
5463 || CLASS_DATA (fsym)->attr.allocatable);
5465 else
5467 bool scalar;
5468 gfc_ss *argss;
5470 gfc_init_se (&parmse, NULL);
5472 /* Check whether the expression is a scalar or not; we cannot use
5473 e->rank as it can be nonzero for functions arguments. */
5474 argss = gfc_walk_expr (e);
5475 scalar = argss == gfc_ss_terminator;
5476 if (!scalar)
5477 gfc_free_ss_chain (argss);
5479 /* Special handling for passing scalar polymorphic coarrays;
5480 otherwise one passes "class->_data.data" instead of "&class". */
5481 if (e->rank == 0 && e->ts.type == BT_CLASS
5482 && fsym && fsym->ts.type == BT_CLASS
5483 && CLASS_DATA (fsym)->attr.codimension
5484 && !CLASS_DATA (fsym)->attr.dimension)
5486 gfc_add_class_array_ref (e);
5487 parmse.want_coarray = 1;
5488 scalar = false;
5491 /* A scalar or transformational function. */
5492 if (scalar)
5494 if (e->expr_type == EXPR_VARIABLE
5495 && e->symtree->n.sym->attr.cray_pointee
5496 && fsym && fsym->attr.flavor == FL_PROCEDURE)
5498 /* The Cray pointer needs to be converted to a pointer to
5499 a type given by the expression. */
5500 gfc_conv_expr (&parmse, e);
5501 type = build_pointer_type (TREE_TYPE (parmse.expr));
5502 tmp = gfc_get_symbol_decl (e->symtree->n.sym->cp_pointer);
5503 parmse.expr = convert (type, tmp);
5506 else if (sym->attr.is_bind_c && e
5507 && ((fsym && fsym->attr.dimension
5508 && (fsym->attr.pointer
5509 || fsym->attr.allocatable
5510 || fsym->as->type == AS_ASSUMED_RANK
5511 || fsym->as->type == AS_ASSUMED_SHAPE))
5512 || non_unity_length_string))
5513 /* Implement F2018, C.12.6.1: paragraph (2). */
5514 gfc_conv_gfc_desc_to_cfi_desc (&parmse, e, fsym);
5516 else if (fsym && fsym->attr.value)
5518 if (fsym->ts.type == BT_CHARACTER
5519 && fsym->ts.is_c_interop
5520 && fsym->ns->proc_name != NULL
5521 && fsym->ns->proc_name->attr.is_bind_c)
5523 parmse.expr = NULL;
5524 gfc_conv_scalar_char_value (fsym, &parmse, &e);
5525 if (parmse.expr == NULL)
5526 gfc_conv_expr (&parmse, e);
5528 else
5530 gfc_conv_expr (&parmse, e);
5531 if (fsym->attr.optional
5532 && fsym->ts.type != BT_CLASS
5533 && fsym->ts.type != BT_DERIVED)
5535 if (e->expr_type != EXPR_VARIABLE
5536 || !e->symtree->n.sym->attr.optional
5537 || e->ref != NULL)
5538 vec_safe_push (optionalargs, boolean_true_node);
5539 else
5541 tmp = gfc_conv_expr_present (e->symtree->n.sym);
5542 if (!e->symtree->n.sym->attr.value)
5543 parmse.expr
5544 = fold_build3_loc (input_location, COND_EXPR,
5545 TREE_TYPE (parmse.expr),
5546 tmp, parmse.expr,
5547 fold_convert (TREE_TYPE (parmse.expr),
5548 integer_zero_node));
5550 vec_safe_push (optionalargs, tmp);
5556 else if (arg->name && arg->name[0] == '%')
5557 /* Argument list functions %VAL, %LOC and %REF are signalled
5558 through arg->name. */
5559 conv_arglist_function (&parmse, arg->expr, arg->name);
5560 else if ((e->expr_type == EXPR_FUNCTION)
5561 && ((e->value.function.esym
5562 && e->value.function.esym->result->attr.pointer)
5563 || (!e->value.function.esym
5564 && e->symtree->n.sym->attr.pointer))
5565 && fsym && fsym->attr.target)
5567 gfc_conv_expr (&parmse, e);
5568 parmse.expr = gfc_build_addr_expr (NULL_TREE, parmse.expr);
5571 else if (e->expr_type == EXPR_FUNCTION
5572 && e->symtree->n.sym->result
5573 && e->symtree->n.sym->result != e->symtree->n.sym
5574 && e->symtree->n.sym->result->attr.proc_pointer)
5576 /* Functions returning procedure pointers. */
5577 gfc_conv_expr (&parmse, e);
5578 if (fsym && fsym->attr.proc_pointer)
5579 parmse.expr = gfc_build_addr_expr (NULL_TREE, parmse.expr);
5582 else
5584 if (e->ts.type == BT_CLASS && fsym
5585 && fsym->ts.type == BT_CLASS
5586 && (!CLASS_DATA (fsym)->as
5587 || CLASS_DATA (fsym)->as->type != AS_ASSUMED_RANK)
5588 && CLASS_DATA (e)->attr.codimension)
5590 gcc_assert (!CLASS_DATA (fsym)->attr.codimension);
5591 gcc_assert (!CLASS_DATA (fsym)->as);
5592 gfc_add_class_array_ref (e);
5593 parmse.want_coarray = 1;
5594 gfc_conv_expr_reference (&parmse, e);
5595 class_scalar_coarray_to_class (&parmse, e, fsym->ts,
5596 fsym->attr.optional
5597 && e->expr_type == EXPR_VARIABLE);
5599 else if (e->ts.type == BT_CLASS && fsym
5600 && fsym->ts.type == BT_CLASS
5601 && !CLASS_DATA (fsym)->as
5602 && !CLASS_DATA (e)->as
5603 && strcmp (fsym->ts.u.derived->name,
5604 e->ts.u.derived->name))
5606 type = gfc_typenode_for_spec (&fsym->ts);
5607 var = gfc_create_var (type, fsym->name);
5608 gfc_conv_expr (&parmse, e);
5609 if (fsym->attr.optional
5610 && e->expr_type == EXPR_VARIABLE
5611 && e->symtree->n.sym->attr.optional)
5613 stmtblock_t block;
5614 tree cond;
5615 tmp = gfc_build_addr_expr (NULL_TREE, parmse.expr);
5616 cond = fold_build2_loc (input_location, NE_EXPR,
5617 logical_type_node, tmp,
5618 fold_convert (TREE_TYPE (tmp),
5619 null_pointer_node));
5620 gfc_start_block (&block);
5621 gfc_add_modify (&block, var,
5622 fold_build1_loc (input_location,
5623 VIEW_CONVERT_EXPR,
5624 type, parmse.expr));
5625 gfc_add_expr_to_block (&parmse.pre,
5626 fold_build3_loc (input_location,
5627 COND_EXPR, void_type_node,
5628 cond, gfc_finish_block (&block),
5629 build_empty_stmt (input_location)));
5630 parmse.expr = gfc_build_addr_expr (NULL_TREE, var);
5631 parmse.expr = build3_loc (input_location, COND_EXPR,
5632 TREE_TYPE (parmse.expr),
5633 cond, parmse.expr,
5634 fold_convert (TREE_TYPE (parmse.expr),
5635 null_pointer_node));
5637 else
5639 /* Since the internal representation of unlimited
5640 polymorphic expressions includes an extra field
5641 that other class objects do not, a cast to the
5642 formal type does not work. */
5643 if (!UNLIMITED_POLY (e) && UNLIMITED_POLY (fsym))
5645 tree efield;
5647 /* Set the _data field. */
5648 tmp = gfc_class_data_get (var);
5649 efield = fold_convert (TREE_TYPE (tmp),
5650 gfc_class_data_get (parmse.expr));
5651 gfc_add_modify (&parmse.pre, tmp, efield);
5653 /* Set the _vptr field. */
5654 tmp = gfc_class_vptr_get (var);
5655 efield = fold_convert (TREE_TYPE (tmp),
5656 gfc_class_vptr_get (parmse.expr));
5657 gfc_add_modify (&parmse.pre, tmp, efield);
5659 /* Set the _len field. */
5660 tmp = gfc_class_len_get (var);
5661 gfc_add_modify (&parmse.pre, tmp,
5662 build_int_cst (TREE_TYPE (tmp), 0));
5664 else
5666 tmp = fold_build1_loc (input_location,
5667 VIEW_CONVERT_EXPR,
5668 type, parmse.expr);
5669 gfc_add_modify (&parmse.pre, var, tmp);
5672 parmse.expr = gfc_build_addr_expr (NULL_TREE, var);
5675 else
5677 bool add_clobber;
5678 add_clobber = fsym && fsym->attr.intent == INTENT_OUT
5679 && !fsym->attr.allocatable && !fsym->attr.pointer
5680 && !e->symtree->n.sym->attr.dimension
5681 && !e->symtree->n.sym->attr.pointer
5682 /* See PR 41453. */
5683 && !e->symtree->n.sym->attr.dummy
5684 /* FIXME - PR 87395 and PR 41453 */
5685 && e->symtree->n.sym->attr.save == SAVE_NONE
5686 && !e->symtree->n.sym->attr.associate_var
5687 && e->ts.type != BT_CHARACTER && e->ts.type != BT_DERIVED
5688 && e->ts.type != BT_CLASS && !sym->attr.elemental;
5690 gfc_conv_expr_reference (&parmse, e, add_clobber);
5692 /* Catch base objects that are not variables. */
5693 if (e->ts.type == BT_CLASS
5694 && e->expr_type != EXPR_VARIABLE
5695 && expr && e == expr->base_expr)
5696 base_object = build_fold_indirect_ref_loc (input_location,
5697 parmse.expr);
5699 /* A class array element needs converting back to be a
5700 class object, if the formal argument is a class object. */
5701 if (fsym && fsym->ts.type == BT_CLASS
5702 && e->ts.type == BT_CLASS
5703 && ((CLASS_DATA (fsym)->as
5704 && CLASS_DATA (fsym)->as->type == AS_ASSUMED_RANK)
5705 || CLASS_DATA (e)->attr.dimension))
5706 gfc_conv_class_to_class (&parmse, e, fsym->ts, false,
5707 fsym->attr.intent != INTENT_IN
5708 && (CLASS_DATA (fsym)->attr.class_pointer
5709 || CLASS_DATA (fsym)->attr.allocatable),
5710 fsym->attr.optional
5711 && e->expr_type == EXPR_VARIABLE
5712 && e->symtree->n.sym->attr.optional,
5713 CLASS_DATA (fsym)->attr.class_pointer
5714 || CLASS_DATA (fsym)->attr.allocatable);
5716 /* If an ALLOCATABLE dummy argument has INTENT(OUT) and is
5717 allocated on entry, it must be deallocated. */
5718 if (fsym && fsym->attr.intent == INTENT_OUT
5719 && (fsym->attr.allocatable
5720 || (fsym->ts.type == BT_CLASS
5721 && CLASS_DATA (fsym)->attr.allocatable)))
5723 stmtblock_t block;
5724 tree ptr;
5726 gfc_init_block (&block);
5727 ptr = parmse.expr;
5728 if (e->ts.type == BT_CLASS)
5729 ptr = gfc_class_data_get (ptr);
5731 tmp = gfc_deallocate_scalar_with_status (ptr, NULL_TREE,
5732 NULL_TREE, true,
5733 e, e->ts);
5734 gfc_add_expr_to_block (&block, tmp);
5735 tmp = fold_build2_loc (input_location, MODIFY_EXPR,
5736 void_type_node, ptr,
5737 null_pointer_node);
5738 gfc_add_expr_to_block (&block, tmp);
5740 if (fsym->ts.type == BT_CLASS && UNLIMITED_POLY (fsym))
5742 gfc_add_modify (&block, ptr,
5743 fold_convert (TREE_TYPE (ptr),
5744 null_pointer_node));
5745 gfc_add_expr_to_block (&block, tmp);
5747 else if (fsym->ts.type == BT_CLASS)
5749 gfc_symbol *vtab;
5750 vtab = gfc_find_derived_vtab (fsym->ts.u.derived);
5751 tmp = gfc_get_symbol_decl (vtab);
5752 tmp = gfc_build_addr_expr (NULL_TREE, tmp);
5753 ptr = gfc_class_vptr_get (parmse.expr);
5754 gfc_add_modify (&block, ptr,
5755 fold_convert (TREE_TYPE (ptr), tmp));
5756 gfc_add_expr_to_block (&block, tmp);
5759 if (fsym->attr.optional
5760 && e->expr_type == EXPR_VARIABLE
5761 && e->symtree->n.sym->attr.optional)
5763 tmp = fold_build3_loc (input_location, COND_EXPR,
5764 void_type_node,
5765 gfc_conv_expr_present (e->symtree->n.sym),
5766 gfc_finish_block (&block),
5767 build_empty_stmt (input_location));
5769 else
5770 tmp = gfc_finish_block (&block);
5772 gfc_add_expr_to_block (&se->pre, tmp);
5775 if (fsym && (fsym->ts.type == BT_DERIVED
5776 || fsym->ts.type == BT_ASSUMED)
5777 && e->ts.type == BT_CLASS
5778 && !CLASS_DATA (e)->attr.dimension
5779 && !CLASS_DATA (e)->attr.codimension)
5781 parmse.expr = gfc_class_data_get (parmse.expr);
5782 /* The result is a class temporary, whose _data component
5783 must be freed to avoid a memory leak. */
5784 if (e->expr_type == EXPR_FUNCTION
5785 && CLASS_DATA (e)->attr.allocatable)
5787 tree zero;
5789 gfc_expr *var;
5791 /* Borrow the function symbol to make a call to
5792 gfc_add_finalizer_call and then restore it. */
5793 tmp = e->symtree->n.sym->backend_decl;
5794 e->symtree->n.sym->backend_decl
5795 = TREE_OPERAND (parmse.expr, 0);
5796 e->symtree->n.sym->attr.flavor = FL_VARIABLE;
5797 var = gfc_lval_expr_from_sym (e->symtree->n.sym);
5798 finalized = gfc_add_finalizer_call (&parmse.post,
5799 var);
5800 gfc_free_expr (var);
5801 e->symtree->n.sym->backend_decl = tmp;
5802 e->symtree->n.sym->attr.flavor = FL_PROCEDURE;
5804 /* Then free the class _data. */
5805 zero = build_int_cst (TREE_TYPE (parmse.expr), 0);
5806 tmp = fold_build2_loc (input_location, NE_EXPR,
5807 logical_type_node,
5808 parmse.expr, zero);
5809 tmp = build3_v (COND_EXPR, tmp,
5810 gfc_call_free (parmse.expr),
5811 build_empty_stmt (input_location));
5812 gfc_add_expr_to_block (&parmse.post, tmp);
5813 gfc_add_modify (&parmse.post, parmse.expr, zero);
5817 /* Wrap scalar variable in a descriptor. We need to convert
5818 the address of a pointer back to the pointer itself before,
5819 we can assign it to the data field. */
5821 if (fsym && fsym->as && fsym->as->type == AS_ASSUMED_RANK
5822 && fsym->ts.type != BT_CLASS && e->expr_type != EXPR_NULL)
5824 tmp = parmse.expr;
5825 if (TREE_CODE (tmp) == ADDR_EXPR)
5826 tmp = build_fold_indirect_ref_loc (input_location, tmp);
5827 parmse.expr = gfc_conv_scalar_to_descriptor (&parmse, tmp,
5828 fsym->attr);
5829 parmse.expr = gfc_build_addr_expr (NULL_TREE,
5830 parmse.expr);
5832 else if (fsym && e->expr_type != EXPR_NULL
5833 && ((fsym->attr.pointer
5834 && fsym->attr.flavor != FL_PROCEDURE)
5835 || (fsym->attr.proc_pointer
5836 && !(e->expr_type == EXPR_VARIABLE
5837 && e->symtree->n.sym->attr.dummy))
5838 || (fsym->attr.proc_pointer
5839 && e->expr_type == EXPR_VARIABLE
5840 && gfc_is_proc_ptr_comp (e))
5841 || (fsym->attr.allocatable
5842 && fsym->attr.flavor != FL_PROCEDURE)))
5844 /* Scalar pointer dummy args require an extra level of
5845 indirection. The null pointer already contains
5846 this level of indirection. */
5847 parm_kind = SCALAR_POINTER;
5848 parmse.expr = gfc_build_addr_expr (NULL_TREE, parmse.expr);
5852 else if (e->ts.type == BT_CLASS
5853 && fsym && fsym->ts.type == BT_CLASS
5854 && (CLASS_DATA (fsym)->attr.dimension
5855 || CLASS_DATA (fsym)->attr.codimension))
5857 /* Pass a class array. */
5858 parmse.use_offset = 1;
5859 gfc_conv_expr_descriptor (&parmse, e);
5861 /* If an ALLOCATABLE dummy argument has INTENT(OUT) and is
5862 allocated on entry, it must be deallocated. */
5863 if (fsym->attr.intent == INTENT_OUT
5864 && CLASS_DATA (fsym)->attr.allocatable)
5866 stmtblock_t block;
5867 tree ptr;
5869 gfc_init_block (&block);
5870 ptr = parmse.expr;
5871 ptr = gfc_class_data_get (ptr);
5873 tmp = gfc_deallocate_with_status (ptr, NULL_TREE,
5874 NULL_TREE, NULL_TREE,
5875 NULL_TREE, true, e,
5876 GFC_CAF_COARRAY_NOCOARRAY);
5877 gfc_add_expr_to_block (&block, tmp);
5878 tmp = fold_build2_loc (input_location, MODIFY_EXPR,
5879 void_type_node, ptr,
5880 null_pointer_node);
5881 gfc_add_expr_to_block (&block, tmp);
5882 gfc_reset_vptr (&block, e);
5884 if (fsym->attr.optional
5885 && e->expr_type == EXPR_VARIABLE
5886 && (!e->ref
5887 || (e->ref->type == REF_ARRAY
5888 && e->ref->u.ar.type != AR_FULL))
5889 && e->symtree->n.sym->attr.optional)
5891 tmp = fold_build3_loc (input_location, COND_EXPR,
5892 void_type_node,
5893 gfc_conv_expr_present (e->symtree->n.sym),
5894 gfc_finish_block (&block),
5895 build_empty_stmt (input_location));
5897 else
5898 tmp = gfc_finish_block (&block);
5900 gfc_add_expr_to_block (&se->pre, tmp);
5903 /* The conversion does not repackage the reference to a class
5904 array - _data descriptor. */
5905 gfc_conv_class_to_class (&parmse, e, fsym->ts, false,
5906 fsym->attr.intent != INTENT_IN
5907 && (CLASS_DATA (fsym)->attr.class_pointer
5908 || CLASS_DATA (fsym)->attr.allocatable),
5909 fsym->attr.optional
5910 && e->expr_type == EXPR_VARIABLE
5911 && e->symtree->n.sym->attr.optional,
5912 CLASS_DATA (fsym)->attr.class_pointer
5913 || CLASS_DATA (fsym)->attr.allocatable);
5915 else
5917 /* If the argument is a function call that may not create
5918 a temporary for the result, we have to check that we
5919 can do it, i.e. that there is no alias between this
5920 argument and another one. */
5921 if (gfc_get_noncopying_intrinsic_argument (e) != NULL)
5923 gfc_expr *iarg;
5924 sym_intent intent;
5926 if (fsym != NULL)
5927 intent = fsym->attr.intent;
5928 else
5929 intent = INTENT_UNKNOWN;
5931 if (gfc_check_fncall_dependency (e, intent, sym, args,
5932 NOT_ELEMENTAL))
5933 parmse.force_tmp = 1;
5935 iarg = e->value.function.actual->expr;
5937 /* Temporary needed if aliasing due to host association. */
5938 if (sym->attr.contained
5939 && !sym->attr.pure
5940 && !sym->attr.implicit_pure
5941 && !sym->attr.use_assoc
5942 && iarg->expr_type == EXPR_VARIABLE
5943 && sym->ns == iarg->symtree->n.sym->ns)
5944 parmse.force_tmp = 1;
5946 /* Ditto within module. */
5947 if (sym->attr.use_assoc
5948 && !sym->attr.pure
5949 && !sym->attr.implicit_pure
5950 && iarg->expr_type == EXPR_VARIABLE
5951 && sym->module == iarg->symtree->n.sym->module)
5952 parmse.force_tmp = 1;
5955 if (sym->attr.is_bind_c && e
5956 && fsym && fsym->attr.dimension
5957 && (fsym->attr.pointer
5958 || fsym->attr.allocatable
5959 || fsym->as->type == AS_ASSUMED_RANK
5960 || fsym->as->type == AS_ASSUMED_SHAPE
5961 || non_unity_length_string))
5962 /* Implement F2018, C.12.6.1: paragraph (2). */
5963 gfc_conv_gfc_desc_to_cfi_desc (&parmse, e, fsym);
5965 else if (e->expr_type == EXPR_VARIABLE
5966 && is_subref_array (e)
5967 && !(fsym && fsym->attr.pointer))
5968 /* The actual argument is a component reference to an
5969 array of derived types. In this case, the argument
5970 is converted to a temporary, which is passed and then
5971 written back after the procedure call. */
5972 gfc_conv_subref_array_arg (&parmse, e, nodesc_arg,
5973 fsym ? fsym->attr.intent : INTENT_INOUT,
5974 fsym && fsym->attr.pointer);
5976 else if (gfc_is_class_array_ref (e, NULL)
5977 && fsym && fsym->ts.type == BT_DERIVED)
5978 /* The actual argument is a component reference to an
5979 array of derived types. In this case, the argument
5980 is converted to a temporary, which is passed and then
5981 written back after the procedure call.
5982 OOP-TODO: Insert code so that if the dynamic type is
5983 the same as the declared type, copy-in/copy-out does
5984 not occur. */
5985 gfc_conv_subref_array_arg (&parmse, e, nodesc_arg,
5986 fsym ? fsym->attr.intent : INTENT_INOUT,
5987 fsym && fsym->attr.pointer);
5989 else if (gfc_is_class_array_function (e)
5990 && fsym && fsym->ts.type == BT_DERIVED)
5991 /* See previous comment. For function actual argument,
5992 the write out is not needed so the intent is set as
5993 intent in. */
5995 e->must_finalize = 1;
5996 gfc_conv_subref_array_arg (&parmse, e, nodesc_arg,
5997 INTENT_IN,
5998 fsym && fsym->attr.pointer);
6000 else if (fsym && fsym->attr.contiguous
6001 && !gfc_is_simply_contiguous (e, false, true))
6003 gfc_conv_subref_array_arg (&parmse, e, nodesc_arg,
6004 fsym ? fsym->attr.intent : INTENT_INOUT,
6005 fsym && fsym->attr.pointer);
6007 else
6008 gfc_conv_array_parameter (&parmse, e, nodesc_arg, fsym,
6009 sym->name, NULL);
6011 /* Unallocated allocatable arrays and unassociated pointer arrays
6012 need their dtype setting if they are argument associated with
6013 assumed rank dummies. */
6014 if (!sym->attr.is_bind_c && e && fsym && fsym->as
6015 && fsym->as->type == AS_ASSUMED_RANK)
6017 if (gfc_expr_attr (e).pointer
6018 || gfc_expr_attr (e).allocatable)
6019 set_dtype_for_unallocated (&parmse, e);
6020 else if (e->expr_type == EXPR_VARIABLE
6021 && e->symtree->n.sym->attr.dummy
6022 && e->symtree->n.sym->as
6023 && e->symtree->n.sym->as->type == AS_ASSUMED_SIZE)
6025 tree minus_one;
6026 tmp = build_fold_indirect_ref_loc (input_location,
6027 parmse.expr);
6028 minus_one = build_int_cst (gfc_array_index_type, -1);
6029 gfc_conv_descriptor_ubound_set (&parmse.pre, tmp,
6030 gfc_rank_cst[e->rank - 1],
6031 minus_one);
6035 /* If an ALLOCATABLE dummy argument has INTENT(OUT) and is
6036 allocated on entry, it must be deallocated. */
6037 if (fsym && fsym->attr.allocatable
6038 && fsym->attr.intent == INTENT_OUT)
6040 if (fsym->ts.type == BT_DERIVED
6041 && fsym->ts.u.derived->attr.alloc_comp)
6043 // deallocate the components first
6044 tmp = gfc_deallocate_alloc_comp (fsym->ts.u.derived,
6045 parmse.expr, e->rank);
6046 if (tmp != NULL_TREE)
6047 gfc_add_expr_to_block (&se->pre, tmp);
6050 tmp = build_fold_indirect_ref_loc (input_location,
6051 parmse.expr);
6052 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp)))
6053 tmp = gfc_conv_descriptor_data_get (tmp);
6054 tmp = gfc_deallocate_with_status (tmp, NULL_TREE, NULL_TREE,
6055 NULL_TREE, NULL_TREE, true,
6057 GFC_CAF_COARRAY_NOCOARRAY);
6058 if (fsym->attr.optional
6059 && e->expr_type == EXPR_VARIABLE
6060 && e->symtree->n.sym->attr.optional)
6061 tmp = fold_build3_loc (input_location, COND_EXPR,
6062 void_type_node,
6063 gfc_conv_expr_present (e->symtree->n.sym),
6064 tmp, build_empty_stmt (input_location));
6065 gfc_add_expr_to_block (&se->pre, tmp);
6070 /* The case with fsym->attr.optional is that of a user subroutine
6071 with an interface indicating an optional argument. When we call
6072 an intrinsic subroutine, however, fsym is NULL, but we might still
6073 have an optional argument, so we proceed to the substitution
6074 just in case. */
6075 if (e && (fsym == NULL || fsym->attr.optional))
6077 /* If an optional argument is itself an optional dummy argument,
6078 check its presence and substitute a null if absent. This is
6079 only needed when passing an array to an elemental procedure
6080 as then array elements are accessed - or no NULL pointer is
6081 allowed and a "1" or "0" should be passed if not present.
6082 When passing a non-array-descriptor full array to a
6083 non-array-descriptor dummy, no check is needed. For
6084 array-descriptor actual to array-descriptor dummy, see
6085 PR 41911 for why a check has to be inserted.
6086 fsym == NULL is checked as intrinsics required the descriptor
6087 but do not always set fsym.
6088 Also, it is necessary to pass a NULL pointer to library routines
6089 which usually ignore optional arguments, so they can handle
6090 these themselves. */
6091 if (e->expr_type == EXPR_VARIABLE
6092 && e->symtree->n.sym->attr.optional
6093 && (((e->rank != 0 && elemental_proc)
6094 || e->representation.length || e->ts.type == BT_CHARACTER
6095 || (e->rank != 0
6096 && (fsym == NULL
6097 || (fsym->as
6098 && (fsym->as->type == AS_ASSUMED_SHAPE
6099 || fsym->as->type == AS_ASSUMED_RANK
6100 || fsym->as->type == AS_DEFERRED)))))
6101 || se->ignore_optional))
6102 gfc_conv_missing_dummy (&parmse, e, fsym ? fsym->ts : e->ts,
6103 e->representation.length);
6106 if (fsym && e)
6108 /* Obtain the character length of an assumed character length
6109 length procedure from the typespec. */
6110 if (fsym->ts.type == BT_CHARACTER
6111 && parmse.string_length == NULL_TREE
6112 && e->ts.type == BT_PROCEDURE
6113 && e->symtree->n.sym->ts.type == BT_CHARACTER
6114 && e->symtree->n.sym->ts.u.cl->length != NULL
6115 && e->symtree->n.sym->ts.u.cl->length->expr_type == EXPR_CONSTANT)
6117 gfc_conv_const_charlen (e->symtree->n.sym->ts.u.cl);
6118 parmse.string_length = e->symtree->n.sym->ts.u.cl->backend_decl;
6122 if (fsym && need_interface_mapping && e)
6123 gfc_add_interface_mapping (&mapping, fsym, &parmse, e);
6125 gfc_add_block_to_block (&se->pre, &parmse.pre);
6126 gfc_add_block_to_block (&post, &parmse.post);
6128 /* Allocated allocatable components of derived types must be
6129 deallocated for non-variable scalars, array arguments to elemental
6130 procedures, and array arguments with descriptor to non-elemental
6131 procedures. As bounds information for descriptorless arrays is no
6132 longer available here, they are dealt with in trans-array.c
6133 (gfc_conv_array_parameter). */
6134 if (e && (e->ts.type == BT_DERIVED || e->ts.type == BT_CLASS)
6135 && e->ts.u.derived->attr.alloc_comp
6136 && (e->rank == 0 || elemental_proc || !nodesc_arg)
6137 && !expr_may_alias_variables (e, elemental_proc))
6139 int parm_rank;
6140 /* It is known the e returns a structure type with at least one
6141 allocatable component. When e is a function, ensure that the
6142 function is called once only by using a temporary variable. */
6143 if (!DECL_P (parmse.expr))
6144 parmse.expr = gfc_evaluate_now_loc (input_location,
6145 parmse.expr, &se->pre);
6147 if (fsym && fsym->attr.value)
6148 tmp = parmse.expr;
6149 else
6150 tmp = build_fold_indirect_ref_loc (input_location,
6151 parmse.expr);
6153 parm_rank = e->rank;
6154 switch (parm_kind)
6156 case (ELEMENTAL):
6157 case (SCALAR):
6158 parm_rank = 0;
6159 break;
6161 case (SCALAR_POINTER):
6162 tmp = build_fold_indirect_ref_loc (input_location,
6163 tmp);
6164 break;
6167 if (e->ts.type == BT_DERIVED && fsym && fsym->ts.type == BT_CLASS)
6169 /* The derived type is passed to gfc_deallocate_alloc_comp.
6170 Therefore, class actuals can be handled correctly but derived
6171 types passed to class formals need the _data component. */
6172 tmp = gfc_class_data_get (tmp);
6173 if (!CLASS_DATA (fsym)->attr.dimension)
6174 tmp = build_fold_indirect_ref_loc (input_location, tmp);
6177 if (e->expr_type == EXPR_OP
6178 && e->value.op.op == INTRINSIC_PARENTHESES
6179 && e->value.op.op1->expr_type == EXPR_VARIABLE)
6181 tree local_tmp;
6182 local_tmp = gfc_evaluate_now (tmp, &se->pre);
6183 local_tmp = gfc_copy_alloc_comp (e->ts.u.derived, local_tmp, tmp,
6184 parm_rank, 0);
6185 gfc_add_expr_to_block (&se->post, local_tmp);
6188 if (!finalized && !e->must_finalize)
6190 if ((e->ts.type == BT_CLASS
6191 && GFC_CLASS_TYPE_P (TREE_TYPE (tmp)))
6192 || e->ts.type == BT_DERIVED)
6193 tmp = gfc_deallocate_alloc_comp (e->ts.u.derived, tmp,
6194 parm_rank);
6195 else if (e->ts.type == BT_CLASS)
6196 tmp = gfc_deallocate_alloc_comp (CLASS_DATA (e)->ts.u.derived,
6197 tmp, parm_rank);
6198 gfc_prepend_expr_to_block (&post, tmp);
6202 /* Add argument checking of passing an unallocated/NULL actual to
6203 a nonallocatable/nonpointer dummy. */
6205 if (gfc_option.rtcheck & GFC_RTCHECK_POINTER && e != NULL)
6207 symbol_attribute attr;
6208 char *msg;
6209 tree cond;
6211 if (e->expr_type == EXPR_VARIABLE || e->expr_type == EXPR_FUNCTION)
6212 attr = gfc_expr_attr (e);
6213 else
6214 goto end_pointer_check;
6216 /* In Fortran 2008 it's allowed to pass a NULL pointer/nonallocated
6217 allocatable to an optional dummy, cf. 12.5.2.12. */
6218 if (fsym != NULL && fsym->attr.optional && !attr.proc_pointer
6219 && (gfc_option.allow_std & GFC_STD_F2008) != 0)
6220 goto end_pointer_check;
6222 if (attr.optional)
6224 /* If the actual argument is an optional pointer/allocatable and
6225 the formal argument takes an nonpointer optional value,
6226 it is invalid to pass a non-present argument on, even
6227 though there is no technical reason for this in gfortran.
6228 See Fortran 2003, Section 12.4.1.6 item (7)+(8). */
6229 tree present, null_ptr, type;
6231 if (attr.allocatable
6232 && (fsym == NULL || !fsym->attr.allocatable))
6233 msg = xasprintf ("Allocatable actual argument '%s' is not "
6234 "allocated or not present",
6235 e->symtree->n.sym->name);
6236 else if (attr.pointer
6237 && (fsym == NULL || !fsym->attr.pointer))
6238 msg = xasprintf ("Pointer actual argument '%s' is not "
6239 "associated or not present",
6240 e->symtree->n.sym->name);
6241 else if (attr.proc_pointer
6242 && (fsym == NULL || !fsym->attr.proc_pointer))
6243 msg = xasprintf ("Proc-pointer actual argument '%s' is not "
6244 "associated or not present",
6245 e->symtree->n.sym->name);
6246 else
6247 goto end_pointer_check;
6249 present = gfc_conv_expr_present (e->symtree->n.sym);
6250 type = TREE_TYPE (present);
6251 present = fold_build2_loc (input_location, EQ_EXPR,
6252 logical_type_node, present,
6253 fold_convert (type,
6254 null_pointer_node));
6255 type = TREE_TYPE (parmse.expr);
6256 null_ptr = fold_build2_loc (input_location, EQ_EXPR,
6257 logical_type_node, parmse.expr,
6258 fold_convert (type,
6259 null_pointer_node));
6260 cond = fold_build2_loc (input_location, TRUTH_ORIF_EXPR,
6261 logical_type_node, present, null_ptr);
6263 else
6265 if (attr.allocatable
6266 && (fsym == NULL || !fsym->attr.allocatable))
6267 msg = xasprintf ("Allocatable actual argument '%s' is not "
6268 "allocated", e->symtree->n.sym->name);
6269 else if (attr.pointer
6270 && (fsym == NULL || !fsym->attr.pointer))
6271 msg = xasprintf ("Pointer actual argument '%s' is not "
6272 "associated", e->symtree->n.sym->name);
6273 else if (attr.proc_pointer
6274 && (fsym == NULL || !fsym->attr.proc_pointer))
6275 msg = xasprintf ("Proc-pointer actual argument '%s' is not "
6276 "associated", e->symtree->n.sym->name);
6277 else
6278 goto end_pointer_check;
6280 tmp = parmse.expr;
6282 /* If the argument is passed by value, we need to strip the
6283 INDIRECT_REF. */
6284 if (!POINTER_TYPE_P (TREE_TYPE (parmse.expr)))
6285 tmp = gfc_build_addr_expr (NULL_TREE, tmp);
6287 cond = fold_build2_loc (input_location, EQ_EXPR,
6288 logical_type_node, tmp,
6289 fold_convert (TREE_TYPE (tmp),
6290 null_pointer_node));
6293 gfc_trans_runtime_check (true, false, cond, &se->pre, &e->where,
6294 msg);
6295 free (msg);
6297 end_pointer_check:
6299 /* Deferred length dummies pass the character length by reference
6300 so that the value can be returned. */
6301 if (parmse.string_length && fsym && fsym->ts.deferred)
6303 if (INDIRECT_REF_P (parmse.string_length))
6304 /* In chains of functions/procedure calls the string_length already
6305 is a pointer to the variable holding the length. Therefore
6306 remove the deref on call. */
6307 parmse.string_length = TREE_OPERAND (parmse.string_length, 0);
6308 else
6310 tmp = parmse.string_length;
6311 if (!VAR_P (tmp) && TREE_CODE (tmp) != COMPONENT_REF)
6312 tmp = gfc_evaluate_now (parmse.string_length, &se->pre);
6313 parmse.string_length = gfc_build_addr_expr (NULL_TREE, tmp);
6317 /* Character strings are passed as two parameters, a length and a
6318 pointer - except for Bind(c) which only passes the pointer.
6319 An unlimited polymorphic formal argument likewise does not
6320 need the length. */
6321 if (parmse.string_length != NULL_TREE
6322 && !sym->attr.is_bind_c
6323 && !(fsym && UNLIMITED_POLY (fsym)))
6324 vec_safe_push (stringargs, parmse.string_length);
6326 /* When calling __copy for character expressions to unlimited
6327 polymorphic entities, the dst argument needs a string length. */
6328 if (sym->name[0] == '_' && e && e->ts.type == BT_CHARACTER
6329 && gfc_str_startswith (sym->name, "__vtab_CHARACTER")
6330 && arg->next && arg->next->expr
6331 && (arg->next->expr->ts.type == BT_DERIVED
6332 || arg->next->expr->ts.type == BT_CLASS)
6333 && arg->next->expr->ts.u.derived->attr.unlimited_polymorphic)
6334 vec_safe_push (stringargs, parmse.string_length);
6336 /* For descriptorless coarrays and assumed-shape coarray dummies, we
6337 pass the token and the offset as additional arguments. */
6338 if (fsym && e == NULL && flag_coarray == GFC_FCOARRAY_LIB
6339 && ((fsym->ts.type != BT_CLASS && fsym->attr.codimension
6340 && !fsym->attr.allocatable)
6341 || (fsym->ts.type == BT_CLASS
6342 && CLASS_DATA (fsym)->attr.codimension
6343 && !CLASS_DATA (fsym)->attr.allocatable)))
6345 /* Token and offset. */
6346 vec_safe_push (stringargs, null_pointer_node);
6347 vec_safe_push (stringargs, build_int_cst (gfc_array_index_type, 0));
6348 gcc_assert (fsym->attr.optional);
6350 else if (fsym && flag_coarray == GFC_FCOARRAY_LIB
6351 && ((fsym->ts.type != BT_CLASS && fsym->attr.codimension
6352 && !fsym->attr.allocatable)
6353 || (fsym->ts.type == BT_CLASS
6354 && CLASS_DATA (fsym)->attr.codimension
6355 && !CLASS_DATA (fsym)->attr.allocatable)))
6357 tree caf_decl, caf_type;
6358 tree offset, tmp2;
6360 caf_decl = gfc_get_tree_for_caf_expr (e);
6361 caf_type = TREE_TYPE (caf_decl);
6363 if (GFC_DESCRIPTOR_TYPE_P (caf_type)
6364 && (GFC_TYPE_ARRAY_AKIND (caf_type) == GFC_ARRAY_ALLOCATABLE
6365 || GFC_TYPE_ARRAY_AKIND (caf_type) == GFC_ARRAY_POINTER))
6366 tmp = gfc_conv_descriptor_token (caf_decl);
6367 else if (DECL_LANG_SPECIFIC (caf_decl)
6368 && GFC_DECL_TOKEN (caf_decl) != NULL_TREE)
6369 tmp = GFC_DECL_TOKEN (caf_decl);
6370 else
6372 gcc_assert (GFC_ARRAY_TYPE_P (caf_type)
6373 && GFC_TYPE_ARRAY_CAF_TOKEN (caf_type) != NULL_TREE);
6374 tmp = GFC_TYPE_ARRAY_CAF_TOKEN (caf_type);
6377 vec_safe_push (stringargs, tmp);
6379 if (GFC_DESCRIPTOR_TYPE_P (caf_type)
6380 && GFC_TYPE_ARRAY_AKIND (caf_type) == GFC_ARRAY_ALLOCATABLE)
6381 offset = build_int_cst (gfc_array_index_type, 0);
6382 else if (DECL_LANG_SPECIFIC (caf_decl)
6383 && GFC_DECL_CAF_OFFSET (caf_decl) != NULL_TREE)
6384 offset = GFC_DECL_CAF_OFFSET (caf_decl);
6385 else if (GFC_TYPE_ARRAY_CAF_OFFSET (caf_type) != NULL_TREE)
6386 offset = GFC_TYPE_ARRAY_CAF_OFFSET (caf_type);
6387 else
6388 offset = build_int_cst (gfc_array_index_type, 0);
6390 if (GFC_DESCRIPTOR_TYPE_P (caf_type))
6391 tmp = gfc_conv_descriptor_data_get (caf_decl);
6392 else
6394 gcc_assert (POINTER_TYPE_P (caf_type));
6395 tmp = caf_decl;
6398 tmp2 = fsym->ts.type == BT_CLASS
6399 ? gfc_class_data_get (parmse.expr) : parmse.expr;
6400 if ((fsym->ts.type != BT_CLASS
6401 && (fsym->as->type == AS_ASSUMED_SHAPE
6402 || fsym->as->type == AS_ASSUMED_RANK))
6403 || (fsym->ts.type == BT_CLASS
6404 && (CLASS_DATA (fsym)->as->type == AS_ASSUMED_SHAPE
6405 || CLASS_DATA (fsym)->as->type == AS_ASSUMED_RANK)))
6407 if (fsym->ts.type == BT_CLASS)
6408 gcc_assert (!POINTER_TYPE_P (TREE_TYPE (tmp2)));
6409 else
6411 gcc_assert (POINTER_TYPE_P (TREE_TYPE (tmp2)));
6412 tmp2 = build_fold_indirect_ref_loc (input_location, tmp2);
6414 gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp2)));
6415 tmp2 = gfc_conv_descriptor_data_get (tmp2);
6417 else if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp2)))
6418 tmp2 = gfc_conv_descriptor_data_get (tmp2);
6419 else
6421 gcc_assert (POINTER_TYPE_P (TREE_TYPE (tmp2)));
6424 tmp = fold_build2_loc (input_location, MINUS_EXPR,
6425 gfc_array_index_type,
6426 fold_convert (gfc_array_index_type, tmp2),
6427 fold_convert (gfc_array_index_type, tmp));
6428 offset = fold_build2_loc (input_location, PLUS_EXPR,
6429 gfc_array_index_type, offset, tmp);
6431 vec_safe_push (stringargs, offset);
6434 vec_safe_push (arglist, parmse.expr);
6436 gfc_finish_interface_mapping (&mapping, &se->pre, &se->post);
6438 if (comp)
6439 ts = comp->ts;
6440 else if (sym->ts.type == BT_CLASS)
6441 ts = CLASS_DATA (sym)->ts;
6442 else
6443 ts = sym->ts;
6445 if (ts.type == BT_CHARACTER && sym->attr.is_bind_c)
6446 se->string_length = build_int_cst (gfc_charlen_type_node, 1);
6447 else if (ts.type == BT_CHARACTER)
6449 if (ts.u.cl->length == NULL)
6451 /* Assumed character length results are not allowed by C418 of the 2003
6452 standard and are trapped in resolve.c; except in the case of SPREAD
6453 (and other intrinsics?) and dummy functions. In the case of SPREAD,
6454 we take the character length of the first argument for the result.
6455 For dummies, we have to look through the formal argument list for
6456 this function and use the character length found there.*/
6457 if (ts.deferred)
6458 cl.backend_decl = gfc_create_var (gfc_charlen_type_node, "slen");
6459 else if (!sym->attr.dummy)
6460 cl.backend_decl = (*stringargs)[0];
6461 else
6463 formal = gfc_sym_get_dummy_args (sym->ns->proc_name);
6464 for (; formal; formal = formal->next)
6465 if (strcmp (formal->sym->name, sym->name) == 0)
6466 cl.backend_decl = formal->sym->ts.u.cl->backend_decl;
6468 len = cl.backend_decl;
6470 else
6472 tree tmp;
6474 /* Calculate the length of the returned string. */
6475 gfc_init_se (&parmse, NULL);
6476 if (need_interface_mapping)
6477 gfc_apply_interface_mapping (&mapping, &parmse, ts.u.cl->length);
6478 else
6479 gfc_conv_expr (&parmse, ts.u.cl->length);
6480 gfc_add_block_to_block (&se->pre, &parmse.pre);
6481 gfc_add_block_to_block (&se->post, &parmse.post);
6482 tmp = parmse.expr;
6483 /* TODO: It would be better to have the charlens as
6484 gfc_charlen_type_node already when the interface is
6485 created instead of converting it here (see PR 84615). */
6486 tmp = fold_build2_loc (input_location, MAX_EXPR,
6487 gfc_charlen_type_node,
6488 fold_convert (gfc_charlen_type_node, tmp),
6489 build_zero_cst (gfc_charlen_type_node));
6490 cl.backend_decl = tmp;
6493 /* Set up a charlen structure for it. */
6494 cl.next = NULL;
6495 cl.length = NULL;
6496 ts.u.cl = &cl;
6498 len = cl.backend_decl;
6501 byref = (comp && (comp->attr.dimension
6502 || (comp->ts.type == BT_CHARACTER && !sym->attr.is_bind_c)))
6503 || (!comp && gfc_return_by_reference (sym));
6504 if (byref)
6506 if (se->direct_byref)
6508 /* Sometimes, too much indirection can be applied; e.g. for
6509 function_result = array_valued_recursive_function. */
6510 if (TREE_TYPE (TREE_TYPE (se->expr))
6511 && TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr)))
6512 && GFC_DESCRIPTOR_TYPE_P
6513 (TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr)))))
6514 se->expr = build_fold_indirect_ref_loc (input_location,
6515 se->expr);
6517 /* If the lhs of an assignment x = f(..) is allocatable and
6518 f2003 is allowed, we must do the automatic reallocation.
6519 TODO - deal with intrinsics, without using a temporary. */
6520 if (flag_realloc_lhs
6521 && se->ss && se->ss->loop_chain
6522 && se->ss->loop_chain->is_alloc_lhs
6523 && !expr->value.function.isym
6524 && sym->result->as != NULL)
6526 /* Evaluate the bounds of the result, if known. */
6527 gfc_set_loop_bounds_from_array_spec (&mapping, se,
6528 sym->result->as);
6530 /* Perform the automatic reallocation. */
6531 tmp = gfc_alloc_allocatable_for_assignment (se->loop,
6532 expr, NULL);
6533 gfc_add_expr_to_block (&se->pre, tmp);
6535 /* Pass the temporary as the first argument. */
6536 result = info->descriptor;
6538 else
6539 result = build_fold_indirect_ref_loc (input_location,
6540 se->expr);
6541 vec_safe_push (retargs, se->expr);
6543 else if (comp && comp->attr.dimension)
6545 gcc_assert (se->loop && info);
6547 /* Set the type of the array. */
6548 tmp = gfc_typenode_for_spec (&comp->ts);
6549 gcc_assert (se->ss->dimen == se->loop->dimen);
6551 /* Evaluate the bounds of the result, if known. */
6552 gfc_set_loop_bounds_from_array_spec (&mapping, se, comp->as);
6554 /* If the lhs of an assignment x = f(..) is allocatable and
6555 f2003 is allowed, we must not generate the function call
6556 here but should just send back the results of the mapping.
6557 This is signalled by the function ss being flagged. */
6558 if (flag_realloc_lhs && se->ss && se->ss->is_alloc_lhs)
6560 gfc_free_interface_mapping (&mapping);
6561 return has_alternate_specifier;
6564 /* Create a temporary to store the result. In case the function
6565 returns a pointer, the temporary will be a shallow copy and
6566 mustn't be deallocated. */
6567 callee_alloc = comp->attr.allocatable || comp->attr.pointer;
6568 gfc_trans_create_temp_array (&se->pre, &se->post, se->ss,
6569 tmp, NULL_TREE, false,
6570 !comp->attr.pointer, callee_alloc,
6571 &se->ss->info->expr->where);
6573 /* Pass the temporary as the first argument. */
6574 result = info->descriptor;
6575 tmp = gfc_build_addr_expr (NULL_TREE, result);
6576 vec_safe_push (retargs, tmp);
6578 else if (!comp && sym->result->attr.dimension)
6580 gcc_assert (se->loop && info);
6582 /* Set the type of the array. */
6583 tmp = gfc_typenode_for_spec (&ts);
6584 gcc_assert (se->ss->dimen == se->loop->dimen);
6586 /* Evaluate the bounds of the result, if known. */
6587 gfc_set_loop_bounds_from_array_spec (&mapping, se, sym->result->as);
6589 /* If the lhs of an assignment x = f(..) is allocatable and
6590 f2003 is allowed, we must not generate the function call
6591 here but should just send back the results of the mapping.
6592 This is signalled by the function ss being flagged. */
6593 if (flag_realloc_lhs && se->ss && se->ss->is_alloc_lhs)
6595 gfc_free_interface_mapping (&mapping);
6596 return has_alternate_specifier;
6599 /* Create a temporary to store the result. In case the function
6600 returns a pointer, the temporary will be a shallow copy and
6601 mustn't be deallocated. */
6602 callee_alloc = sym->attr.allocatable || sym->attr.pointer;
6603 gfc_trans_create_temp_array (&se->pre, &se->post, se->ss,
6604 tmp, NULL_TREE, false,
6605 !sym->attr.pointer, callee_alloc,
6606 &se->ss->info->expr->where);
6608 /* Pass the temporary as the first argument. */
6609 result = info->descriptor;
6610 tmp = gfc_build_addr_expr (NULL_TREE, result);
6611 vec_safe_push (retargs, tmp);
6613 else if (ts.type == BT_CHARACTER)
6615 /* Pass the string length. */
6616 type = gfc_get_character_type (ts.kind, ts.u.cl);
6617 type = build_pointer_type (type);
6619 /* Emit a DECL_EXPR for the VLA type. */
6620 tmp = TREE_TYPE (type);
6621 if (TYPE_SIZE (tmp)
6622 && TREE_CODE (TYPE_SIZE (tmp)) != INTEGER_CST)
6624 tmp = build_decl (input_location, TYPE_DECL, NULL_TREE, tmp);
6625 DECL_ARTIFICIAL (tmp) = 1;
6626 DECL_IGNORED_P (tmp) = 1;
6627 tmp = fold_build1_loc (input_location, DECL_EXPR,
6628 TREE_TYPE (tmp), tmp);
6629 gfc_add_expr_to_block (&se->pre, tmp);
6632 /* Return an address to a char[0:len-1]* temporary for
6633 character pointers. */
6634 if ((!comp && (sym->attr.pointer || sym->attr.allocatable))
6635 || (comp && (comp->attr.pointer || comp->attr.allocatable)))
6637 var = gfc_create_var (type, "pstr");
6639 if ((!comp && sym->attr.allocatable)
6640 || (comp && comp->attr.allocatable))
6642 gfc_add_modify (&se->pre, var,
6643 fold_convert (TREE_TYPE (var),
6644 null_pointer_node));
6645 tmp = gfc_call_free (var);
6646 gfc_add_expr_to_block (&se->post, tmp);
6649 /* Provide an address expression for the function arguments. */
6650 var = gfc_build_addr_expr (NULL_TREE, var);
6652 else
6653 var = gfc_conv_string_tmp (se, type, len);
6655 vec_safe_push (retargs, var);
6657 else
6659 gcc_assert (flag_f2c && ts.type == BT_COMPLEX);
6661 type = gfc_get_complex_type (ts.kind);
6662 var = gfc_build_addr_expr (NULL_TREE, gfc_create_var (type, "cmplx"));
6663 vec_safe_push (retargs, var);
6666 /* Add the string length to the argument list. */
6667 if (ts.type == BT_CHARACTER && ts.deferred)
6669 tmp = len;
6670 if (!VAR_P (tmp))
6671 tmp = gfc_evaluate_now (len, &se->pre);
6672 TREE_STATIC (tmp) = 1;
6673 gfc_add_modify (&se->pre, tmp,
6674 build_int_cst (TREE_TYPE (tmp), 0));
6675 tmp = gfc_build_addr_expr (NULL_TREE, tmp);
6676 vec_safe_push (retargs, tmp);
6678 else if (ts.type == BT_CHARACTER)
6679 vec_safe_push (retargs, len);
6681 gfc_free_interface_mapping (&mapping);
6683 /* We need to glom RETARGS + ARGLIST + STRINGARGS + APPEND_ARGS. */
6684 arglen = (vec_safe_length (arglist) + vec_safe_length (optionalargs)
6685 + vec_safe_length (stringargs) + vec_safe_length (append_args));
6686 vec_safe_reserve (retargs, arglen);
6688 /* Add the return arguments. */
6689 vec_safe_splice (retargs, arglist);
6691 /* Add the hidden present status for optional+value to the arguments. */
6692 vec_safe_splice (retargs, optionalargs);
6694 /* Add the hidden string length parameters to the arguments. */
6695 vec_safe_splice (retargs, stringargs);
6697 /* We may want to append extra arguments here. This is used e.g. for
6698 calls to libgfortran_matmul_??, which need extra information. */
6699 vec_safe_splice (retargs, append_args);
6701 arglist = retargs;
6703 /* Generate the actual call. */
6704 if (base_object == NULL_TREE)
6705 conv_function_val (se, sym, expr, args);
6706 else
6707 conv_base_obj_fcn_val (se, base_object, expr);
6709 /* If there are alternate return labels, function type should be
6710 integer. Can't modify the type in place though, since it can be shared
6711 with other functions. For dummy arguments, the typing is done to
6712 this result, even if it has to be repeated for each call. */
6713 if (has_alternate_specifier
6714 && TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr))) != integer_type_node)
6716 if (!sym->attr.dummy)
6718 TREE_TYPE (sym->backend_decl)
6719 = build_function_type (integer_type_node,
6720 TYPE_ARG_TYPES (TREE_TYPE (sym->backend_decl)));
6721 se->expr = gfc_build_addr_expr (NULL_TREE, sym->backend_decl);
6723 else
6724 TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr))) = integer_type_node;
6727 fntype = TREE_TYPE (TREE_TYPE (se->expr));
6728 se->expr = build_call_vec (TREE_TYPE (fntype), se->expr, arglist);
6730 /* Allocatable scalar function results must be freed and nullified
6731 after use. This necessitates the creation of a temporary to
6732 hold the result to prevent duplicate calls. */
6733 if (!byref && sym->ts.type != BT_CHARACTER
6734 && ((sym->attr.allocatable && !sym->attr.dimension && !comp)
6735 || (comp && comp->attr.allocatable && !comp->attr.dimension)))
6737 tmp = gfc_create_var (TREE_TYPE (se->expr), NULL);
6738 gfc_add_modify (&se->pre, tmp, se->expr);
6739 se->expr = tmp;
6740 tmp = gfc_call_free (tmp);
6741 gfc_add_expr_to_block (&post, tmp);
6742 gfc_add_modify (&post, se->expr, build_int_cst (TREE_TYPE (se->expr), 0));
6745 /* If we have a pointer function, but we don't want a pointer, e.g.
6746 something like
6747 x = f()
6748 where f is pointer valued, we have to dereference the result. */
6749 if (!se->want_pointer && !byref
6750 && ((!comp && (sym->attr.pointer || sym->attr.allocatable))
6751 || (comp && (comp->attr.pointer || comp->attr.allocatable))))
6752 se->expr = build_fold_indirect_ref_loc (input_location, se->expr);
6754 /* f2c calling conventions require a scalar default real function to
6755 return a double precision result. Convert this back to default
6756 real. We only care about the cases that can happen in Fortran 77.
6758 if (flag_f2c && sym->ts.type == BT_REAL
6759 && sym->ts.kind == gfc_default_real_kind
6760 && !sym->attr.always_explicit)
6761 se->expr = fold_convert (gfc_get_real_type (sym->ts.kind), se->expr);
6763 /* A pure function may still have side-effects - it may modify its
6764 parameters. */
6765 TREE_SIDE_EFFECTS (se->expr) = 1;
6766 #if 0
6767 if (!sym->attr.pure)
6768 TREE_SIDE_EFFECTS (se->expr) = 1;
6769 #endif
6771 if (byref)
6773 /* Add the function call to the pre chain. There is no expression. */
6774 gfc_add_expr_to_block (&se->pre, se->expr);
6775 se->expr = NULL_TREE;
6777 if (!se->direct_byref)
6779 if ((sym->attr.dimension && !comp) || (comp && comp->attr.dimension))
6781 if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
6783 /* Check the data pointer hasn't been modified. This would
6784 happen in a function returning a pointer. */
6785 tmp = gfc_conv_descriptor_data_get (info->descriptor);
6786 tmp = fold_build2_loc (input_location, NE_EXPR,
6787 logical_type_node,
6788 tmp, info->data);
6789 gfc_trans_runtime_check (true, false, tmp, &se->pre, NULL,
6790 gfc_msg_fault);
6792 se->expr = info->descriptor;
6793 /* Bundle in the string length. */
6794 se->string_length = len;
6796 else if (ts.type == BT_CHARACTER)
6798 /* Dereference for character pointer results. */
6799 if ((!comp && (sym->attr.pointer || sym->attr.allocatable))
6800 || (comp && (comp->attr.pointer || comp->attr.allocatable)))
6801 se->expr = build_fold_indirect_ref_loc (input_location, var);
6802 else
6803 se->expr = var;
6805 se->string_length = len;
6807 else
6809 gcc_assert (ts.type == BT_COMPLEX && flag_f2c);
6810 se->expr = build_fold_indirect_ref_loc (input_location, var);
6815 /* Associate the rhs class object's meta-data with the result, when the
6816 result is a temporary. */
6817 if (args && args->expr && args->expr->ts.type == BT_CLASS
6818 && sym->ts.type == BT_CLASS && result != NULL_TREE && DECL_P (result)
6819 && !GFC_CLASS_TYPE_P (TREE_TYPE (result)))
6821 gfc_se parmse;
6822 gfc_expr *class_expr = gfc_find_and_cut_at_last_class_ref (args->expr);
6824 gfc_init_se (&parmse, NULL);
6825 parmse.data_not_needed = 1;
6826 gfc_conv_expr (&parmse, class_expr);
6827 if (!DECL_LANG_SPECIFIC (result))
6828 gfc_allocate_lang_decl (result);
6829 GFC_DECL_SAVED_DESCRIPTOR (result) = parmse.expr;
6830 gfc_free_expr (class_expr);
6831 gcc_assert (parmse.pre.head == NULL_TREE
6832 && parmse.post.head == NULL_TREE);
6835 /* Follow the function call with the argument post block. */
6836 if (byref)
6838 gfc_add_block_to_block (&se->pre, &post);
6840 /* Transformational functions of derived types with allocatable
6841 components must have the result allocatable components copied when the
6842 argument is actually given. */
6843 arg = expr->value.function.actual;
6844 if (result && arg && expr->rank
6845 && expr->value.function.isym
6846 && expr->value.function.isym->transformational
6847 && arg->expr
6848 && arg->expr->ts.type == BT_DERIVED
6849 && arg->expr->ts.u.derived->attr.alloc_comp)
6851 tree tmp2;
6852 /* Copy the allocatable components. We have to use a
6853 temporary here to prevent source allocatable components
6854 from being corrupted. */
6855 tmp2 = gfc_evaluate_now (result, &se->pre);
6856 tmp = gfc_copy_alloc_comp (arg->expr->ts.u.derived,
6857 result, tmp2, expr->rank, 0);
6858 gfc_add_expr_to_block (&se->pre, tmp);
6859 tmp = gfc_copy_allocatable_data (result, tmp2, TREE_TYPE(tmp2),
6860 expr->rank);
6861 gfc_add_expr_to_block (&se->pre, tmp);
6863 /* Finally free the temporary's data field. */
6864 tmp = gfc_conv_descriptor_data_get (tmp2);
6865 tmp = gfc_deallocate_with_status (tmp, NULL_TREE, NULL_TREE,
6866 NULL_TREE, NULL_TREE, true,
6867 NULL, GFC_CAF_COARRAY_NOCOARRAY);
6868 gfc_add_expr_to_block (&se->pre, tmp);
6871 else
6873 /* For a function with a class array result, save the result as
6874 a temporary, set the info fields needed by the scalarizer and
6875 call the finalization function of the temporary. Note that the
6876 nullification of allocatable components needed by the result
6877 is done in gfc_trans_assignment_1. */
6878 if (expr && ((gfc_is_class_array_function (expr)
6879 && se->ss && se->ss->loop)
6880 || gfc_is_alloc_class_scalar_function (expr))
6881 && se->expr && GFC_CLASS_TYPE_P (TREE_TYPE (se->expr))
6882 && expr->must_finalize)
6884 tree final_fndecl;
6885 tree is_final;
6886 int n;
6887 if (se->ss && se->ss->loop)
6889 gfc_add_block_to_block (&se->ss->loop->pre, &se->pre);
6890 se->expr = gfc_evaluate_now (se->expr, &se->ss->loop->pre);
6891 tmp = gfc_class_data_get (se->expr);
6892 info->descriptor = tmp;
6893 info->data = gfc_conv_descriptor_data_get (tmp);
6894 info->offset = gfc_conv_descriptor_offset_get (tmp);
6895 for (n = 0; n < se->ss->loop->dimen; n++)
6897 tree dim = gfc_rank_cst[n];
6898 se->ss->loop->to[n] = gfc_conv_descriptor_ubound_get (tmp, dim);
6899 se->ss->loop->from[n] = gfc_conv_descriptor_lbound_get (tmp, dim);
6902 else
6904 /* TODO Eliminate the doubling of temporaries. This
6905 one is necessary to ensure no memory leakage. */
6906 se->expr = gfc_evaluate_now (se->expr, &se->pre);
6907 tmp = gfc_class_data_get (se->expr);
6908 tmp = gfc_conv_scalar_to_descriptor (se, tmp,
6909 CLASS_DATA (expr->value.function.esym->result)->attr);
6912 if ((gfc_is_class_array_function (expr)
6913 || gfc_is_alloc_class_scalar_function (expr))
6914 && CLASS_DATA (expr->value.function.esym->result)->attr.pointer)
6915 goto no_finalization;
6917 final_fndecl = gfc_class_vtab_final_get (se->expr);
6918 is_final = fold_build2_loc (input_location, NE_EXPR,
6919 logical_type_node,
6920 final_fndecl,
6921 fold_convert (TREE_TYPE (final_fndecl),
6922 null_pointer_node));
6923 final_fndecl = build_fold_indirect_ref_loc (input_location,
6924 final_fndecl);
6925 tmp = build_call_expr_loc (input_location,
6926 final_fndecl, 3,
6927 gfc_build_addr_expr (NULL, tmp),
6928 gfc_class_vtab_size_get (se->expr),
6929 boolean_false_node);
6930 tmp = fold_build3_loc (input_location, COND_EXPR,
6931 void_type_node, is_final, tmp,
6932 build_empty_stmt (input_location));
6934 if (se->ss && se->ss->loop)
6936 gfc_prepend_expr_to_block (&se->ss->loop->post, tmp);
6937 tmp = fold_build2_loc (input_location, NE_EXPR,
6938 logical_type_node,
6939 info->data,
6940 fold_convert (TREE_TYPE (info->data),
6941 null_pointer_node));
6942 tmp = fold_build3_loc (input_location, COND_EXPR,
6943 void_type_node, tmp,
6944 gfc_call_free (info->data),
6945 build_empty_stmt (input_location));
6946 gfc_add_expr_to_block (&se->ss->loop->post, tmp);
6948 else
6950 tree classdata;
6951 gfc_prepend_expr_to_block (&se->post, tmp);
6952 classdata = gfc_class_data_get (se->expr);
6953 tmp = fold_build2_loc (input_location, NE_EXPR,
6954 logical_type_node,
6955 classdata,
6956 fold_convert (TREE_TYPE (classdata),
6957 null_pointer_node));
6958 tmp = fold_build3_loc (input_location, COND_EXPR,
6959 void_type_node, tmp,
6960 gfc_call_free (classdata),
6961 build_empty_stmt (input_location));
6962 gfc_add_expr_to_block (&se->post, tmp);
6966 no_finalization:
6967 gfc_add_block_to_block (&se->post, &post);
6970 return has_alternate_specifier;
6974 /* Fill a character string with spaces. */
6976 static tree
6977 fill_with_spaces (tree start, tree type, tree size)
6979 stmtblock_t block, loop;
6980 tree i, el, exit_label, cond, tmp;
6982 /* For a simple char type, we can call memset(). */
6983 if (compare_tree_int (TYPE_SIZE_UNIT (type), 1) == 0)
6984 return build_call_expr_loc (input_location,
6985 builtin_decl_explicit (BUILT_IN_MEMSET),
6986 3, start,
6987 build_int_cst (gfc_get_int_type (gfc_c_int_kind),
6988 lang_hooks.to_target_charset (' ')),
6989 fold_convert (size_type_node, size));
6991 /* Otherwise, we use a loop:
6992 for (el = start, i = size; i > 0; el--, i+= TYPE_SIZE_UNIT (type))
6993 *el = (type) ' ';
6996 /* Initialize variables. */
6997 gfc_init_block (&block);
6998 i = gfc_create_var (sizetype, "i");
6999 gfc_add_modify (&block, i, fold_convert (sizetype, size));
7000 el = gfc_create_var (build_pointer_type (type), "el");
7001 gfc_add_modify (&block, el, fold_convert (TREE_TYPE (el), start));
7002 exit_label = gfc_build_label_decl (NULL_TREE);
7003 TREE_USED (exit_label) = 1;
7006 /* Loop body. */
7007 gfc_init_block (&loop);
7009 /* Exit condition. */
7010 cond = fold_build2_loc (input_location, LE_EXPR, logical_type_node, i,
7011 build_zero_cst (sizetype));
7012 tmp = build1_v (GOTO_EXPR, exit_label);
7013 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond, tmp,
7014 build_empty_stmt (input_location));
7015 gfc_add_expr_to_block (&loop, tmp);
7017 /* Assignment. */
7018 gfc_add_modify (&loop,
7019 fold_build1_loc (input_location, INDIRECT_REF, type, el),
7020 build_int_cst (type, lang_hooks.to_target_charset (' ')));
7022 /* Increment loop variables. */
7023 gfc_add_modify (&loop, i,
7024 fold_build2_loc (input_location, MINUS_EXPR, sizetype, i,
7025 TYPE_SIZE_UNIT (type)));
7026 gfc_add_modify (&loop, el,
7027 fold_build_pointer_plus_loc (input_location,
7028 el, TYPE_SIZE_UNIT (type)));
7030 /* Making the loop... actually loop! */
7031 tmp = gfc_finish_block (&loop);
7032 tmp = build1_v (LOOP_EXPR, tmp);
7033 gfc_add_expr_to_block (&block, tmp);
7035 /* The exit label. */
7036 tmp = build1_v (LABEL_EXPR, exit_label);
7037 gfc_add_expr_to_block (&block, tmp);
7040 return gfc_finish_block (&block);
7044 /* Generate code to copy a string. */
7046 void
7047 gfc_trans_string_copy (stmtblock_t * block, tree dlength, tree dest,
7048 int dkind, tree slength, tree src, int skind)
7050 tree tmp, dlen, slen;
7051 tree dsc;
7052 tree ssc;
7053 tree cond;
7054 tree cond2;
7055 tree tmp2;
7056 tree tmp3;
7057 tree tmp4;
7058 tree chartype;
7059 stmtblock_t tempblock;
7061 gcc_assert (dkind == skind);
7063 if (slength != NULL_TREE)
7065 slen = gfc_evaluate_now (fold_convert (gfc_charlen_type_node, slength), block);
7066 ssc = gfc_string_to_single_character (slen, src, skind);
7068 else
7070 slen = build_one_cst (gfc_charlen_type_node);
7071 ssc = src;
7074 if (dlength != NULL_TREE)
7076 dlen = gfc_evaluate_now (fold_convert (gfc_charlen_type_node, dlength), block);
7077 dsc = gfc_string_to_single_character (dlen, dest, dkind);
7079 else
7081 dlen = build_one_cst (gfc_charlen_type_node);
7082 dsc = dest;
7085 /* Assign directly if the types are compatible. */
7086 if (dsc != NULL_TREE && ssc != NULL_TREE
7087 && TREE_TYPE (dsc) == TREE_TYPE (ssc))
7089 gfc_add_modify (block, dsc, ssc);
7090 return;
7093 /* The string copy algorithm below generates code like
7095 if (destlen > 0)
7097 if (srclen < destlen)
7099 memmove (dest, src, srclen);
7100 // Pad with spaces.
7101 memset (&dest[srclen], ' ', destlen - srclen);
7103 else
7105 // Truncate if too long.
7106 memmove (dest, src, destlen);
7111 /* Do nothing if the destination length is zero. */
7112 cond = fold_build2_loc (input_location, GT_EXPR, logical_type_node, dlen,
7113 build_zero_cst (TREE_TYPE (dlen)));
7115 /* For non-default character kinds, we have to multiply the string
7116 length by the base type size. */
7117 chartype = gfc_get_char_type (dkind);
7118 slen = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (slen),
7119 slen,
7120 fold_convert (TREE_TYPE (slen),
7121 TYPE_SIZE_UNIT (chartype)));
7122 dlen = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (dlen),
7123 dlen,
7124 fold_convert (TREE_TYPE (dlen),
7125 TYPE_SIZE_UNIT (chartype)));
7127 if (dlength && POINTER_TYPE_P (TREE_TYPE (dest)))
7128 dest = fold_convert (pvoid_type_node, dest);
7129 else
7130 dest = gfc_build_addr_expr (pvoid_type_node, dest);
7132 if (slength && POINTER_TYPE_P (TREE_TYPE (src)))
7133 src = fold_convert (pvoid_type_node, src);
7134 else
7135 src = gfc_build_addr_expr (pvoid_type_node, src);
7137 /* Truncate string if source is too long. */
7138 cond2 = fold_build2_loc (input_location, LT_EXPR, logical_type_node, slen,
7139 dlen);
7141 /* Copy and pad with spaces. */
7142 tmp3 = build_call_expr_loc (input_location,
7143 builtin_decl_explicit (BUILT_IN_MEMMOVE),
7144 3, dest, src,
7145 fold_convert (size_type_node, slen));
7147 /* Wstringop-overflow appears at -O3 even though this warning is not
7148 explicitly available in fortran nor can it be switched off. If the
7149 source length is a constant, its negative appears as a very large
7150 postive number and triggers the warning in BUILTIN_MEMSET. Fixing
7151 the result of the MINUS_EXPR suppresses this spurious warning. */
7152 tmp = fold_build2_loc (input_location, MINUS_EXPR,
7153 TREE_TYPE(dlen), dlen, slen);
7154 if (slength && TREE_CONSTANT (slength))
7155 tmp = gfc_evaluate_now (tmp, block);
7157 tmp4 = fold_build_pointer_plus_loc (input_location, dest, slen);
7158 tmp4 = fill_with_spaces (tmp4, chartype, tmp);
7160 gfc_init_block (&tempblock);
7161 gfc_add_expr_to_block (&tempblock, tmp3);
7162 gfc_add_expr_to_block (&tempblock, tmp4);
7163 tmp3 = gfc_finish_block (&tempblock);
7165 /* The truncated memmove if the slen >= dlen. */
7166 tmp2 = build_call_expr_loc (input_location,
7167 builtin_decl_explicit (BUILT_IN_MEMMOVE),
7168 3, dest, src,
7169 fold_convert (size_type_node, dlen));
7171 /* The whole copy_string function is there. */
7172 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond2,
7173 tmp3, tmp2);
7174 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond, tmp,
7175 build_empty_stmt (input_location));
7176 gfc_add_expr_to_block (block, tmp);
7180 /* Translate a statement function.
7181 The value of a statement function reference is obtained by evaluating the
7182 expression using the values of the actual arguments for the values of the
7183 corresponding dummy arguments. */
7185 static void
7186 gfc_conv_statement_function (gfc_se * se, gfc_expr * expr)
7188 gfc_symbol *sym;
7189 gfc_symbol *fsym;
7190 gfc_formal_arglist *fargs;
7191 gfc_actual_arglist *args;
7192 gfc_se lse;
7193 gfc_se rse;
7194 gfc_saved_var *saved_vars;
7195 tree *temp_vars;
7196 tree type;
7197 tree tmp;
7198 int n;
7200 sym = expr->symtree->n.sym;
7201 args = expr->value.function.actual;
7202 gfc_init_se (&lse, NULL);
7203 gfc_init_se (&rse, NULL);
7205 n = 0;
7206 for (fargs = gfc_sym_get_dummy_args (sym); fargs; fargs = fargs->next)
7207 n++;
7208 saved_vars = XCNEWVEC (gfc_saved_var, n);
7209 temp_vars = XCNEWVEC (tree, n);
7211 for (fargs = gfc_sym_get_dummy_args (sym), n = 0; fargs;
7212 fargs = fargs->next, n++)
7214 /* Each dummy shall be specified, explicitly or implicitly, to be
7215 scalar. */
7216 gcc_assert (fargs->sym->attr.dimension == 0);
7217 fsym = fargs->sym;
7219 if (fsym->ts.type == BT_CHARACTER)
7221 /* Copy string arguments. */
7222 tree arglen;
7224 gcc_assert (fsym->ts.u.cl && fsym->ts.u.cl->length
7225 && fsym->ts.u.cl->length->expr_type == EXPR_CONSTANT);
7227 /* Create a temporary to hold the value. */
7228 if (fsym->ts.u.cl->backend_decl == NULL_TREE)
7229 fsym->ts.u.cl->backend_decl
7230 = gfc_conv_constant_to_tree (fsym->ts.u.cl->length);
7232 type = gfc_get_character_type (fsym->ts.kind, fsym->ts.u.cl);
7233 temp_vars[n] = gfc_create_var (type, fsym->name);
7235 arglen = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
7237 gfc_conv_expr (&rse, args->expr);
7238 gfc_conv_string_parameter (&rse);
7239 gfc_add_block_to_block (&se->pre, &lse.pre);
7240 gfc_add_block_to_block (&se->pre, &rse.pre);
7242 gfc_trans_string_copy (&se->pre, arglen, temp_vars[n], fsym->ts.kind,
7243 rse.string_length, rse.expr, fsym->ts.kind);
7244 gfc_add_block_to_block (&se->pre, &lse.post);
7245 gfc_add_block_to_block (&se->pre, &rse.post);
7247 else
7249 /* For everything else, just evaluate the expression. */
7251 /* Create a temporary to hold the value. */
7252 type = gfc_typenode_for_spec (&fsym->ts);
7253 temp_vars[n] = gfc_create_var (type, fsym->name);
7255 gfc_conv_expr (&lse, args->expr);
7257 gfc_add_block_to_block (&se->pre, &lse.pre);
7258 gfc_add_modify (&se->pre, temp_vars[n], lse.expr);
7259 gfc_add_block_to_block (&se->pre, &lse.post);
7262 args = args->next;
7265 /* Use the temporary variables in place of the real ones. */
7266 for (fargs = gfc_sym_get_dummy_args (sym), n = 0; fargs;
7267 fargs = fargs->next, n++)
7268 gfc_shadow_sym (fargs->sym, temp_vars[n], &saved_vars[n]);
7270 gfc_conv_expr (se, sym->value);
7272 if (sym->ts.type == BT_CHARACTER)
7274 gfc_conv_const_charlen (sym->ts.u.cl);
7276 /* Force the expression to the correct length. */
7277 if (!INTEGER_CST_P (se->string_length)
7278 || tree_int_cst_lt (se->string_length,
7279 sym->ts.u.cl->backend_decl))
7281 type = gfc_get_character_type (sym->ts.kind, sym->ts.u.cl);
7282 tmp = gfc_create_var (type, sym->name);
7283 tmp = gfc_build_addr_expr (build_pointer_type (type), tmp);
7284 gfc_trans_string_copy (&se->pre, sym->ts.u.cl->backend_decl, tmp,
7285 sym->ts.kind, se->string_length, se->expr,
7286 sym->ts.kind);
7287 se->expr = tmp;
7289 se->string_length = sym->ts.u.cl->backend_decl;
7292 /* Restore the original variables. */
7293 for (fargs = gfc_sym_get_dummy_args (sym), n = 0; fargs;
7294 fargs = fargs->next, n++)
7295 gfc_restore_sym (fargs->sym, &saved_vars[n]);
7296 free (temp_vars);
7297 free (saved_vars);
7301 /* Translate a function expression. */
7303 static void
7304 gfc_conv_function_expr (gfc_se * se, gfc_expr * expr)
7306 gfc_symbol *sym;
7308 if (expr->value.function.isym)
7310 gfc_conv_intrinsic_function (se, expr);
7311 return;
7314 /* expr.value.function.esym is the resolved (specific) function symbol for
7315 most functions. However this isn't set for dummy procedures. */
7316 sym = expr->value.function.esym;
7317 if (!sym)
7318 sym = expr->symtree->n.sym;
7320 /* The IEEE_ARITHMETIC functions are caught here. */
7321 if (sym->from_intmod == INTMOD_IEEE_ARITHMETIC)
7322 if (gfc_conv_ieee_arithmetic_function (se, expr))
7323 return;
7325 /* We distinguish statement functions from general functions to improve
7326 runtime performance. */
7327 if (sym->attr.proc == PROC_ST_FUNCTION)
7329 gfc_conv_statement_function (se, expr);
7330 return;
7333 gfc_conv_procedure_call (se, sym, expr->value.function.actual, expr,
7334 NULL);
7338 /* Determine whether the given EXPR_CONSTANT is a zero initializer. */
7340 static bool
7341 is_zero_initializer_p (gfc_expr * expr)
7343 if (expr->expr_type != EXPR_CONSTANT)
7344 return false;
7346 /* We ignore constants with prescribed memory representations for now. */
7347 if (expr->representation.string)
7348 return false;
7350 switch (expr->ts.type)
7352 case BT_INTEGER:
7353 return mpz_cmp_si (expr->value.integer, 0) == 0;
7355 case BT_REAL:
7356 return mpfr_zero_p (expr->value.real)
7357 && MPFR_SIGN (expr->value.real) >= 0;
7359 case BT_LOGICAL:
7360 return expr->value.logical == 0;
7362 case BT_COMPLEX:
7363 return mpfr_zero_p (mpc_realref (expr->value.complex))
7364 && MPFR_SIGN (mpc_realref (expr->value.complex)) >= 0
7365 && mpfr_zero_p (mpc_imagref (expr->value.complex))
7366 && MPFR_SIGN (mpc_imagref (expr->value.complex)) >= 0;
7368 default:
7369 break;
7371 return false;
7375 static void
7376 gfc_conv_array_constructor_expr (gfc_se * se, gfc_expr * expr)
7378 gfc_ss *ss;
7380 ss = se->ss;
7381 gcc_assert (ss != NULL && ss != gfc_ss_terminator);
7382 gcc_assert (ss->info->expr == expr && ss->info->type == GFC_SS_CONSTRUCTOR);
7384 gfc_conv_tmp_array_ref (se);
7388 /* Build a static initializer. EXPR is the expression for the initial value.
7389 The other parameters describe the variable of the component being
7390 initialized. EXPR may be null. */
7392 tree
7393 gfc_conv_initializer (gfc_expr * expr, gfc_typespec * ts, tree type,
7394 bool array, bool pointer, bool procptr)
7396 gfc_se se;
7398 if (flag_coarray != GFC_FCOARRAY_LIB && ts->type == BT_DERIVED
7399 && ts->u.derived->from_intmod == INTMOD_ISO_FORTRAN_ENV
7400 && ts->u.derived->intmod_sym_id == ISOFORTRAN_EVENT_TYPE)
7401 return build_constructor (type, NULL);
7403 if (!(expr || pointer || procptr))
7404 return NULL_TREE;
7406 /* Check if we have ISOCBINDING_NULL_PTR or ISOCBINDING_NULL_FUNPTR
7407 (these are the only two iso_c_binding derived types that can be
7408 used as initialization expressions). If so, we need to modify
7409 the 'expr' to be that for a (void *). */
7410 if (expr != NULL && expr->ts.type == BT_DERIVED
7411 && expr->ts.is_iso_c && expr->ts.u.derived)
7413 if (TREE_CODE (type) == ARRAY_TYPE)
7414 return build_constructor (type, NULL);
7415 else if (POINTER_TYPE_P (type))
7416 return build_int_cst (type, 0);
7417 else
7418 gcc_unreachable ();
7421 if (array && !procptr)
7423 tree ctor;
7424 /* Arrays need special handling. */
7425 if (pointer)
7426 ctor = gfc_build_null_descriptor (type);
7427 /* Special case assigning an array to zero. */
7428 else if (is_zero_initializer_p (expr))
7429 ctor = build_constructor (type, NULL);
7430 else
7431 ctor = gfc_conv_array_initializer (type, expr);
7432 TREE_STATIC (ctor) = 1;
7433 return ctor;
7435 else if (pointer || procptr)
7437 if (ts->type == BT_CLASS && !procptr)
7439 gfc_init_se (&se, NULL);
7440 gfc_conv_structure (&se, gfc_class_initializer (ts, expr), 1);
7441 gcc_assert (TREE_CODE (se.expr) == CONSTRUCTOR);
7442 TREE_STATIC (se.expr) = 1;
7443 return se.expr;
7445 else if (!expr || expr->expr_type == EXPR_NULL)
7446 return fold_convert (type, null_pointer_node);
7447 else
7449 gfc_init_se (&se, NULL);
7450 se.want_pointer = 1;
7451 gfc_conv_expr (&se, expr);
7452 gcc_assert (TREE_CODE (se.expr) != CONSTRUCTOR);
7453 return se.expr;
7456 else
7458 switch (ts->type)
7460 case_bt_struct:
7461 case BT_CLASS:
7462 gfc_init_se (&se, NULL);
7463 if (ts->type == BT_CLASS && expr->expr_type == EXPR_NULL)
7464 gfc_conv_structure (&se, gfc_class_initializer (ts, expr), 1);
7465 else
7466 gfc_conv_structure (&se, expr, 1);
7467 gcc_assert (TREE_CODE (se.expr) == CONSTRUCTOR);
7468 TREE_STATIC (se.expr) = 1;
7469 return se.expr;
7471 case BT_CHARACTER:
7473 tree ctor = gfc_conv_string_init (ts->u.cl->backend_decl,expr);
7474 TREE_STATIC (ctor) = 1;
7475 return ctor;
7478 default:
7479 gfc_init_se (&se, NULL);
7480 gfc_conv_constant (&se, expr);
7481 gcc_assert (TREE_CODE (se.expr) != CONSTRUCTOR);
7482 return se.expr;
7487 static tree
7488 gfc_trans_subarray_assign (tree dest, gfc_component * cm, gfc_expr * expr)
7490 gfc_se rse;
7491 gfc_se lse;
7492 gfc_ss *rss;
7493 gfc_ss *lss;
7494 gfc_array_info *lss_array;
7495 stmtblock_t body;
7496 stmtblock_t block;
7497 gfc_loopinfo loop;
7498 int n;
7499 tree tmp;
7501 gfc_start_block (&block);
7503 /* Initialize the scalarizer. */
7504 gfc_init_loopinfo (&loop);
7506 gfc_init_se (&lse, NULL);
7507 gfc_init_se (&rse, NULL);
7509 /* Walk the rhs. */
7510 rss = gfc_walk_expr (expr);
7511 if (rss == gfc_ss_terminator)
7512 /* The rhs is scalar. Add a ss for the expression. */
7513 rss = gfc_get_scalar_ss (gfc_ss_terminator, expr);
7515 /* Create a SS for the destination. */
7516 lss = gfc_get_array_ss (gfc_ss_terminator, NULL, cm->as->rank,
7517 GFC_SS_COMPONENT);
7518 lss_array = &lss->info->data.array;
7519 lss_array->shape = gfc_get_shape (cm->as->rank);
7520 lss_array->descriptor = dest;
7521 lss_array->data = gfc_conv_array_data (dest);
7522 lss_array->offset = gfc_conv_array_offset (dest);
7523 for (n = 0; n < cm->as->rank; n++)
7525 lss_array->start[n] = gfc_conv_array_lbound (dest, n);
7526 lss_array->stride[n] = gfc_index_one_node;
7528 mpz_init (lss_array->shape[n]);
7529 mpz_sub (lss_array->shape[n], cm->as->upper[n]->value.integer,
7530 cm->as->lower[n]->value.integer);
7531 mpz_add_ui (lss_array->shape[n], lss_array->shape[n], 1);
7534 /* Associate the SS with the loop. */
7535 gfc_add_ss_to_loop (&loop, lss);
7536 gfc_add_ss_to_loop (&loop, rss);
7538 /* Calculate the bounds of the scalarization. */
7539 gfc_conv_ss_startstride (&loop);
7541 /* Setup the scalarizing loops. */
7542 gfc_conv_loop_setup (&loop, &expr->where);
7544 /* Setup the gfc_se structures. */
7545 gfc_copy_loopinfo_to_se (&lse, &loop);
7546 gfc_copy_loopinfo_to_se (&rse, &loop);
7548 rse.ss = rss;
7549 gfc_mark_ss_chain_used (rss, 1);
7550 lse.ss = lss;
7551 gfc_mark_ss_chain_used (lss, 1);
7553 /* Start the scalarized loop body. */
7554 gfc_start_scalarized_body (&loop, &body);
7556 gfc_conv_tmp_array_ref (&lse);
7557 if (cm->ts.type == BT_CHARACTER)
7558 lse.string_length = cm->ts.u.cl->backend_decl;
7560 gfc_conv_expr (&rse, expr);
7562 tmp = gfc_trans_scalar_assign (&lse, &rse, cm->ts, true, false);
7563 gfc_add_expr_to_block (&body, tmp);
7565 gcc_assert (rse.ss == gfc_ss_terminator);
7567 /* Generate the copying loops. */
7568 gfc_trans_scalarizing_loops (&loop, &body);
7570 /* Wrap the whole thing up. */
7571 gfc_add_block_to_block (&block, &loop.pre);
7572 gfc_add_block_to_block (&block, &loop.post);
7574 gcc_assert (lss_array->shape != NULL);
7575 gfc_free_shape (&lss_array->shape, cm->as->rank);
7576 gfc_cleanup_loop (&loop);
7578 return gfc_finish_block (&block);
7582 static tree
7583 gfc_trans_alloc_subarray_assign (tree dest, gfc_component * cm,
7584 gfc_expr * expr)
7586 gfc_se se;
7587 stmtblock_t block;
7588 tree offset;
7589 int n;
7590 tree tmp;
7591 tree tmp2;
7592 gfc_array_spec *as;
7593 gfc_expr *arg = NULL;
7595 gfc_start_block (&block);
7596 gfc_init_se (&se, NULL);
7598 /* Get the descriptor for the expressions. */
7599 se.want_pointer = 0;
7600 gfc_conv_expr_descriptor (&se, expr);
7601 gfc_add_block_to_block (&block, &se.pre);
7602 gfc_add_modify (&block, dest, se.expr);
7604 /* Deal with arrays of derived types with allocatable components. */
7605 if (gfc_bt_struct (cm->ts.type)
7606 && cm->ts.u.derived->attr.alloc_comp)
7607 // TODO: Fix caf_mode
7608 tmp = gfc_copy_alloc_comp (cm->ts.u.derived,
7609 se.expr, dest,
7610 cm->as->rank, 0);
7611 else if (cm->ts.type == BT_CLASS && expr->ts.type == BT_DERIVED
7612 && CLASS_DATA(cm)->attr.allocatable)
7614 if (cm->ts.u.derived->attr.alloc_comp)
7615 // TODO: Fix caf_mode
7616 tmp = gfc_copy_alloc_comp (expr->ts.u.derived,
7617 se.expr, dest,
7618 expr->rank, 0);
7619 else
7621 tmp = TREE_TYPE (dest);
7622 tmp = gfc_duplicate_allocatable (dest, se.expr,
7623 tmp, expr->rank, NULL_TREE);
7626 else
7627 tmp = gfc_duplicate_allocatable (dest, se.expr,
7628 TREE_TYPE(cm->backend_decl),
7629 cm->as->rank, NULL_TREE);
7631 gfc_add_expr_to_block (&block, tmp);
7632 gfc_add_block_to_block (&block, &se.post);
7634 if (expr->expr_type != EXPR_VARIABLE)
7635 gfc_conv_descriptor_data_set (&block, se.expr,
7636 null_pointer_node);
7638 /* We need to know if the argument of a conversion function is a
7639 variable, so that the correct lower bound can be used. */
7640 if (expr->expr_type == EXPR_FUNCTION
7641 && expr->value.function.isym
7642 && expr->value.function.isym->conversion
7643 && expr->value.function.actual->expr
7644 && expr->value.function.actual->expr->expr_type == EXPR_VARIABLE)
7645 arg = expr->value.function.actual->expr;
7647 /* Obtain the array spec of full array references. */
7648 if (arg)
7649 as = gfc_get_full_arrayspec_from_expr (arg);
7650 else
7651 as = gfc_get_full_arrayspec_from_expr (expr);
7653 /* Shift the lbound and ubound of temporaries to being unity,
7654 rather than zero, based. Always calculate the offset. */
7655 offset = gfc_conv_descriptor_offset_get (dest);
7656 gfc_add_modify (&block, offset, gfc_index_zero_node);
7657 tmp2 =gfc_create_var (gfc_array_index_type, NULL);
7659 for (n = 0; n < expr->rank; n++)
7661 tree span;
7662 tree lbound;
7664 /* Obtain the correct lbound - ISO/IEC TR 15581:2001 page 9.
7665 TODO It looks as if gfc_conv_expr_descriptor should return
7666 the correct bounds and that the following should not be
7667 necessary. This would simplify gfc_conv_intrinsic_bound
7668 as well. */
7669 if (as && as->lower[n])
7671 gfc_se lbse;
7672 gfc_init_se (&lbse, NULL);
7673 gfc_conv_expr (&lbse, as->lower[n]);
7674 gfc_add_block_to_block (&block, &lbse.pre);
7675 lbound = gfc_evaluate_now (lbse.expr, &block);
7677 else if (as && arg)
7679 tmp = gfc_get_symbol_decl (arg->symtree->n.sym);
7680 lbound = gfc_conv_descriptor_lbound_get (tmp,
7681 gfc_rank_cst[n]);
7683 else if (as)
7684 lbound = gfc_conv_descriptor_lbound_get (dest,
7685 gfc_rank_cst[n]);
7686 else
7687 lbound = gfc_index_one_node;
7689 lbound = fold_convert (gfc_array_index_type, lbound);
7691 /* Shift the bounds and set the offset accordingly. */
7692 tmp = gfc_conv_descriptor_ubound_get (dest, gfc_rank_cst[n]);
7693 span = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
7694 tmp, gfc_conv_descriptor_lbound_get (dest, gfc_rank_cst[n]));
7695 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
7696 span, lbound);
7697 gfc_conv_descriptor_ubound_set (&block, dest,
7698 gfc_rank_cst[n], tmp);
7699 gfc_conv_descriptor_lbound_set (&block, dest,
7700 gfc_rank_cst[n], lbound);
7702 tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
7703 gfc_conv_descriptor_lbound_get (dest,
7704 gfc_rank_cst[n]),
7705 gfc_conv_descriptor_stride_get (dest,
7706 gfc_rank_cst[n]));
7707 gfc_add_modify (&block, tmp2, tmp);
7708 tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
7709 offset, tmp2);
7710 gfc_conv_descriptor_offset_set (&block, dest, tmp);
7713 if (arg)
7715 /* If a conversion expression has a null data pointer
7716 argument, nullify the allocatable component. */
7717 tree non_null_expr;
7718 tree null_expr;
7720 if (arg->symtree->n.sym->attr.allocatable
7721 || arg->symtree->n.sym->attr.pointer)
7723 non_null_expr = gfc_finish_block (&block);
7724 gfc_start_block (&block);
7725 gfc_conv_descriptor_data_set (&block, dest,
7726 null_pointer_node);
7727 null_expr = gfc_finish_block (&block);
7728 tmp = gfc_conv_descriptor_data_get (arg->symtree->n.sym->backend_decl);
7729 tmp = build2_loc (input_location, EQ_EXPR, logical_type_node, tmp,
7730 fold_convert (TREE_TYPE (tmp), null_pointer_node));
7731 return build3_v (COND_EXPR, tmp,
7732 null_expr, non_null_expr);
7736 return gfc_finish_block (&block);
7740 /* Allocate or reallocate scalar component, as necessary. */
7742 static void
7743 alloc_scalar_allocatable_for_subcomponent_assignment (stmtblock_t *block,
7744 tree comp,
7745 gfc_component *cm,
7746 gfc_expr *expr2,
7747 gfc_symbol *sym)
7749 tree tmp;
7750 tree ptr;
7751 tree size;
7752 tree size_in_bytes;
7753 tree lhs_cl_size = NULL_TREE;
7755 if (!comp)
7756 return;
7758 if (!expr2 || expr2->rank)
7759 return;
7761 realloc_lhs_warning (expr2->ts.type, false, &expr2->where);
7763 if (cm->ts.type == BT_CHARACTER && cm->ts.deferred)
7765 char name[GFC_MAX_SYMBOL_LEN+9];
7766 gfc_component *strlen;
7767 /* Use the rhs string length and the lhs element size. */
7768 gcc_assert (expr2->ts.type == BT_CHARACTER);
7769 if (!expr2->ts.u.cl->backend_decl)
7771 gfc_conv_string_length (expr2->ts.u.cl, expr2, block);
7772 gcc_assert (expr2->ts.u.cl->backend_decl);
7775 size = expr2->ts.u.cl->backend_decl;
7777 /* Ensure that cm->ts.u.cl->backend_decl is a componentref to _%s_length
7778 component. */
7779 sprintf (name, "_%s_length", cm->name);
7780 strlen = gfc_find_component (sym, name, true, true, NULL);
7781 lhs_cl_size = fold_build3_loc (input_location, COMPONENT_REF,
7782 gfc_charlen_type_node,
7783 TREE_OPERAND (comp, 0),
7784 strlen->backend_decl, NULL_TREE);
7786 tmp = TREE_TYPE (gfc_typenode_for_spec (&cm->ts));
7787 tmp = TYPE_SIZE_UNIT (tmp);
7788 size_in_bytes = fold_build2_loc (input_location, MULT_EXPR,
7789 TREE_TYPE (tmp), tmp,
7790 fold_convert (TREE_TYPE (tmp), size));
7792 else if (cm->ts.type == BT_CLASS)
7794 gcc_assert (expr2->ts.type == BT_CLASS || expr2->ts.type == BT_DERIVED);
7795 if (expr2->ts.type == BT_DERIVED)
7797 tmp = gfc_get_symbol_decl (expr2->ts.u.derived);
7798 size = TYPE_SIZE_UNIT (tmp);
7800 else
7802 gfc_expr *e2vtab;
7803 gfc_se se;
7804 e2vtab = gfc_find_and_cut_at_last_class_ref (expr2);
7805 gfc_add_vptr_component (e2vtab);
7806 gfc_add_size_component (e2vtab);
7807 gfc_init_se (&se, NULL);
7808 gfc_conv_expr (&se, e2vtab);
7809 gfc_add_block_to_block (block, &se.pre);
7810 size = fold_convert (size_type_node, se.expr);
7811 gfc_free_expr (e2vtab);
7813 size_in_bytes = size;
7815 else
7817 /* Otherwise use the length in bytes of the rhs. */
7818 size = TYPE_SIZE_UNIT (gfc_typenode_for_spec (&cm->ts));
7819 size_in_bytes = size;
7822 size_in_bytes = fold_build2_loc (input_location, MAX_EXPR, size_type_node,
7823 size_in_bytes, size_one_node);
7825 if (cm->ts.type == BT_DERIVED && cm->ts.u.derived->attr.alloc_comp)
7827 tmp = build_call_expr_loc (input_location,
7828 builtin_decl_explicit (BUILT_IN_CALLOC),
7829 2, build_one_cst (size_type_node),
7830 size_in_bytes);
7831 tmp = fold_convert (TREE_TYPE (comp), tmp);
7832 gfc_add_modify (block, comp, tmp);
7834 else
7836 tmp = build_call_expr_loc (input_location,
7837 builtin_decl_explicit (BUILT_IN_MALLOC),
7838 1, size_in_bytes);
7839 if (GFC_CLASS_TYPE_P (TREE_TYPE (comp)))
7840 ptr = gfc_class_data_get (comp);
7841 else
7842 ptr = comp;
7843 tmp = fold_convert (TREE_TYPE (ptr), tmp);
7844 gfc_add_modify (block, ptr, tmp);
7847 if (cm->ts.type == BT_CHARACTER && cm->ts.deferred)
7848 /* Update the lhs character length. */
7849 gfc_add_modify (block, lhs_cl_size,
7850 fold_convert (TREE_TYPE (lhs_cl_size), size));
7854 /* Assign a single component of a derived type constructor. */
7856 static tree
7857 gfc_trans_subcomponent_assign (tree dest, gfc_component * cm, gfc_expr * expr,
7858 gfc_symbol *sym, bool init)
7860 gfc_se se;
7861 gfc_se lse;
7862 stmtblock_t block;
7863 tree tmp;
7864 tree vtab;
7866 gfc_start_block (&block);
7868 if (cm->attr.pointer || cm->attr.proc_pointer)
7870 /* Only care about pointers here, not about allocatables. */
7871 gfc_init_se (&se, NULL);
7872 /* Pointer component. */
7873 if ((cm->attr.dimension || cm->attr.codimension)
7874 && !cm->attr.proc_pointer)
7876 /* Array pointer. */
7877 if (expr->expr_type == EXPR_NULL)
7878 gfc_conv_descriptor_data_set (&block, dest, null_pointer_node);
7879 else
7881 se.direct_byref = 1;
7882 se.expr = dest;
7883 gfc_conv_expr_descriptor (&se, expr);
7884 gfc_add_block_to_block (&block, &se.pre);
7885 gfc_add_block_to_block (&block, &se.post);
7888 else
7890 /* Scalar pointers. */
7891 se.want_pointer = 1;
7892 gfc_conv_expr (&se, expr);
7893 gfc_add_block_to_block (&block, &se.pre);
7895 if (expr->symtree && expr->symtree->n.sym->attr.proc_pointer
7896 && expr->symtree->n.sym->attr.dummy)
7897 se.expr = build_fold_indirect_ref_loc (input_location, se.expr);
7899 gfc_add_modify (&block, dest,
7900 fold_convert (TREE_TYPE (dest), se.expr));
7901 gfc_add_block_to_block (&block, &se.post);
7904 else if (cm->ts.type == BT_CLASS && expr->expr_type == EXPR_NULL)
7906 /* NULL initialization for CLASS components. */
7907 tmp = gfc_trans_structure_assign (dest,
7908 gfc_class_initializer (&cm->ts, expr),
7909 false);
7910 gfc_add_expr_to_block (&block, tmp);
7912 else if ((cm->attr.dimension || cm->attr.codimension)
7913 && !cm->attr.proc_pointer)
7915 if (cm->attr.allocatable && expr->expr_type == EXPR_NULL)
7916 gfc_conv_descriptor_data_set (&block, dest, null_pointer_node);
7917 else if (cm->attr.allocatable || cm->attr.pdt_array)
7919 tmp = gfc_trans_alloc_subarray_assign (dest, cm, expr);
7920 gfc_add_expr_to_block (&block, tmp);
7922 else
7924 tmp = gfc_trans_subarray_assign (dest, cm, expr);
7925 gfc_add_expr_to_block (&block, tmp);
7928 else if (cm->ts.type == BT_CLASS
7929 && CLASS_DATA (cm)->attr.dimension
7930 && CLASS_DATA (cm)->attr.allocatable
7931 && expr->ts.type == BT_DERIVED)
7933 vtab = gfc_get_symbol_decl (gfc_find_vtab (&expr->ts));
7934 vtab = gfc_build_addr_expr (NULL_TREE, vtab);
7935 tmp = gfc_class_vptr_get (dest);
7936 gfc_add_modify (&block, tmp,
7937 fold_convert (TREE_TYPE (tmp), vtab));
7938 tmp = gfc_class_data_get (dest);
7939 tmp = gfc_trans_alloc_subarray_assign (tmp, cm, expr);
7940 gfc_add_expr_to_block (&block, tmp);
7942 else if (init && cm->attr.allocatable && expr->expr_type == EXPR_NULL)
7944 /* NULL initialization for allocatable components. */
7945 gfc_add_modify (&block, dest, fold_convert (TREE_TYPE (dest),
7946 null_pointer_node));
7948 else if (init && (cm->attr.allocatable
7949 || (cm->ts.type == BT_CLASS && CLASS_DATA (cm)->attr.allocatable
7950 && expr->ts.type != BT_CLASS)))
7952 /* Take care about non-array allocatable components here. The alloc_*
7953 routine below is motivated by the alloc_scalar_allocatable_for_
7954 assignment() routine, but with the realloc portions removed and
7955 different input. */
7956 alloc_scalar_allocatable_for_subcomponent_assignment (&block,
7957 dest,
7959 expr,
7960 sym);
7961 /* The remainder of these instructions follow the if (cm->attr.pointer)
7962 if (!cm->attr.dimension) part above. */
7963 gfc_init_se (&se, NULL);
7964 gfc_conv_expr (&se, expr);
7965 gfc_add_block_to_block (&block, &se.pre);
7967 if (expr->symtree && expr->symtree->n.sym->attr.proc_pointer
7968 && expr->symtree->n.sym->attr.dummy)
7969 se.expr = build_fold_indirect_ref_loc (input_location, se.expr);
7971 if (cm->ts.type == BT_CLASS && expr->ts.type == BT_DERIVED)
7973 tmp = gfc_class_data_get (dest);
7974 tmp = build_fold_indirect_ref_loc (input_location, tmp);
7975 vtab = gfc_get_symbol_decl (gfc_find_vtab (&expr->ts));
7976 vtab = gfc_build_addr_expr (NULL_TREE, vtab);
7977 gfc_add_modify (&block, gfc_class_vptr_get (dest),
7978 fold_convert (TREE_TYPE (gfc_class_vptr_get (dest)), vtab));
7980 else
7981 tmp = build_fold_indirect_ref_loc (input_location, dest);
7983 /* For deferred strings insert a memcpy. */
7984 if (cm->ts.type == BT_CHARACTER && cm->ts.deferred)
7986 tree size;
7987 gcc_assert (se.string_length || expr->ts.u.cl->backend_decl);
7988 size = size_of_string_in_bytes (cm->ts.kind, se.string_length
7989 ? se.string_length
7990 : expr->ts.u.cl->backend_decl);
7991 tmp = gfc_build_memcpy_call (tmp, se.expr, size);
7992 gfc_add_expr_to_block (&block, tmp);
7994 else
7995 gfc_add_modify (&block, tmp,
7996 fold_convert (TREE_TYPE (tmp), se.expr));
7997 gfc_add_block_to_block (&block, &se.post);
7999 else if (expr->ts.type == BT_UNION)
8001 tree tmp;
8002 gfc_constructor *c = gfc_constructor_first (expr->value.constructor);
8003 /* We mark that the entire union should be initialized with a contrived
8004 EXPR_NULL expression at the beginning. */
8005 if (c != NULL && c->n.component == NULL
8006 && c->expr != NULL && c->expr->expr_type == EXPR_NULL)
8008 tmp = build2_loc (input_location, MODIFY_EXPR, void_type_node,
8009 dest, build_constructor (TREE_TYPE (dest), NULL));
8010 gfc_add_expr_to_block (&block, tmp);
8011 c = gfc_constructor_next (c);
8013 /* The following constructor expression, if any, represents a specific
8014 map intializer, as given by the user. */
8015 if (c != NULL && c->expr != NULL)
8017 gcc_assert (expr->expr_type == EXPR_STRUCTURE);
8018 tmp = gfc_trans_structure_assign (dest, expr, expr->symtree != NULL);
8019 gfc_add_expr_to_block (&block, tmp);
8022 else if (expr->ts.type == BT_DERIVED && expr->ts.f90_type != BT_VOID)
8024 if (expr->expr_type != EXPR_STRUCTURE)
8026 tree dealloc = NULL_TREE;
8027 gfc_init_se (&se, NULL);
8028 gfc_conv_expr (&se, expr);
8029 gfc_add_block_to_block (&block, &se.pre);
8030 /* Prevent repeat evaluations in gfc_copy_alloc_comp by fixing the
8031 expression in a temporary variable and deallocate the allocatable
8032 components. Then we can the copy the expression to the result. */
8033 if (cm->ts.u.derived->attr.alloc_comp
8034 && expr->expr_type != EXPR_VARIABLE)
8036 se.expr = gfc_evaluate_now (se.expr, &block);
8037 dealloc = gfc_deallocate_alloc_comp (cm->ts.u.derived, se.expr,
8038 expr->rank);
8040 gfc_add_modify (&block, dest,
8041 fold_convert (TREE_TYPE (dest), se.expr));
8042 if (cm->ts.u.derived->attr.alloc_comp
8043 && expr->expr_type != EXPR_NULL)
8045 // TODO: Fix caf_mode
8046 tmp = gfc_copy_alloc_comp (cm->ts.u.derived, se.expr,
8047 dest, expr->rank, 0);
8048 gfc_add_expr_to_block (&block, tmp);
8049 if (dealloc != NULL_TREE)
8050 gfc_add_expr_to_block (&block, dealloc);
8052 gfc_add_block_to_block (&block, &se.post);
8054 else
8056 /* Nested constructors. */
8057 tmp = gfc_trans_structure_assign (dest, expr, expr->symtree != NULL);
8058 gfc_add_expr_to_block (&block, tmp);
8061 else if (gfc_deferred_strlen (cm, &tmp))
8063 tree strlen;
8064 strlen = tmp;
8065 gcc_assert (strlen);
8066 strlen = fold_build3_loc (input_location, COMPONENT_REF,
8067 TREE_TYPE (strlen),
8068 TREE_OPERAND (dest, 0),
8069 strlen, NULL_TREE);
8071 if (expr->expr_type == EXPR_NULL)
8073 tmp = build_int_cst (TREE_TYPE (cm->backend_decl), 0);
8074 gfc_add_modify (&block, dest, tmp);
8075 tmp = build_int_cst (TREE_TYPE (strlen), 0);
8076 gfc_add_modify (&block, strlen, tmp);
8078 else
8080 tree size;
8081 gfc_init_se (&se, NULL);
8082 gfc_conv_expr (&se, expr);
8083 size = size_of_string_in_bytes (cm->ts.kind, se.string_length);
8084 tmp = build_call_expr_loc (input_location,
8085 builtin_decl_explicit (BUILT_IN_MALLOC),
8086 1, size);
8087 gfc_add_modify (&block, dest,
8088 fold_convert (TREE_TYPE (dest), tmp));
8089 gfc_add_modify (&block, strlen,
8090 fold_convert (TREE_TYPE (strlen), se.string_length));
8091 tmp = gfc_build_memcpy_call (dest, se.expr, size);
8092 gfc_add_expr_to_block (&block, tmp);
8095 else if (!cm->attr.artificial)
8097 /* Scalar component (excluding deferred parameters). */
8098 gfc_init_se (&se, NULL);
8099 gfc_init_se (&lse, NULL);
8101 gfc_conv_expr (&se, expr);
8102 if (cm->ts.type == BT_CHARACTER)
8103 lse.string_length = cm->ts.u.cl->backend_decl;
8104 lse.expr = dest;
8105 tmp = gfc_trans_scalar_assign (&lse, &se, cm->ts, false, false);
8106 gfc_add_expr_to_block (&block, tmp);
8108 return gfc_finish_block (&block);
8111 /* Assign a derived type constructor to a variable. */
8113 tree
8114 gfc_trans_structure_assign (tree dest, gfc_expr * expr, bool init, bool coarray)
8116 gfc_constructor *c;
8117 gfc_component *cm;
8118 stmtblock_t block;
8119 tree field;
8120 tree tmp;
8121 gfc_se se;
8123 gfc_start_block (&block);
8124 cm = expr->ts.u.derived->components;
8126 if (expr->ts.u.derived->from_intmod == INTMOD_ISO_C_BINDING
8127 && (expr->ts.u.derived->intmod_sym_id == ISOCBINDING_PTR
8128 || expr->ts.u.derived->intmod_sym_id == ISOCBINDING_FUNPTR))
8130 gfc_se lse;
8132 gfc_init_se (&se, NULL);
8133 gfc_init_se (&lse, NULL);
8134 gfc_conv_expr (&se, gfc_constructor_first (expr->value.constructor)->expr);
8135 lse.expr = dest;
8136 gfc_add_modify (&block, lse.expr,
8137 fold_convert (TREE_TYPE (lse.expr), se.expr));
8139 return gfc_finish_block (&block);
8142 if (coarray)
8143 gfc_init_se (&se, NULL);
8145 for (c = gfc_constructor_first (expr->value.constructor);
8146 c; c = gfc_constructor_next (c), cm = cm->next)
8148 /* Skip absent members in default initializers. */
8149 if (!c->expr && !cm->attr.allocatable)
8150 continue;
8152 /* Register the component with the caf-lib before it is initialized.
8153 Register only allocatable components, that are not coarray'ed
8154 components (%comp[*]). Only register when the constructor is not the
8155 null-expression. */
8156 if (coarray && !cm->attr.codimension
8157 && (cm->attr.allocatable || cm->attr.pointer)
8158 && (!c->expr || c->expr->expr_type == EXPR_NULL))
8160 tree token, desc, size;
8161 bool is_array = cm->ts.type == BT_CLASS
8162 ? CLASS_DATA (cm)->attr.dimension : cm->attr.dimension;
8164 field = cm->backend_decl;
8165 field = fold_build3_loc (input_location, COMPONENT_REF,
8166 TREE_TYPE (field), dest, field, NULL_TREE);
8167 if (cm->ts.type == BT_CLASS)
8168 field = gfc_class_data_get (field);
8170 token = is_array ? gfc_conv_descriptor_token (field)
8171 : fold_build3_loc (input_location, COMPONENT_REF,
8172 TREE_TYPE (cm->caf_token), dest,
8173 cm->caf_token, NULL_TREE);
8175 if (is_array)
8177 /* The _caf_register routine looks at the rank of the array
8178 descriptor to decide whether the data registered is an array
8179 or not. */
8180 int rank = cm->ts.type == BT_CLASS ? CLASS_DATA (cm)->as->rank
8181 : cm->as->rank;
8182 /* When the rank is not known just set a positive rank, which
8183 suffices to recognize the data as array. */
8184 if (rank < 0)
8185 rank = 1;
8186 size = build_zero_cst (size_type_node);
8187 desc = field;
8188 gfc_add_modify (&block, gfc_conv_descriptor_rank (desc),
8189 build_int_cst (signed_char_type_node, rank));
8191 else
8193 desc = gfc_conv_scalar_to_descriptor (&se, field,
8194 cm->ts.type == BT_CLASS
8195 ? CLASS_DATA (cm)->attr
8196 : cm->attr);
8197 size = TYPE_SIZE_UNIT (TREE_TYPE (field));
8199 gfc_add_block_to_block (&block, &se.pre);
8200 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_register,
8201 7, size, build_int_cst (
8202 integer_type_node,
8203 GFC_CAF_COARRAY_ALLOC_REGISTER_ONLY),
8204 gfc_build_addr_expr (pvoid_type_node,
8205 token),
8206 gfc_build_addr_expr (NULL_TREE, desc),
8207 null_pointer_node, null_pointer_node,
8208 integer_zero_node);
8209 gfc_add_expr_to_block (&block, tmp);
8211 field = cm->backend_decl;
8212 tmp = fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field),
8213 dest, field, NULL_TREE);
8214 if (!c->expr)
8216 gfc_expr *e = gfc_get_null_expr (NULL);
8217 tmp = gfc_trans_subcomponent_assign (tmp, cm, e, expr->ts.u.derived,
8218 init);
8219 gfc_free_expr (e);
8221 else
8222 tmp = gfc_trans_subcomponent_assign (tmp, cm, c->expr,
8223 expr->ts.u.derived, init);
8224 gfc_add_expr_to_block (&block, tmp);
8226 return gfc_finish_block (&block);
8229 void
8230 gfc_conv_union_initializer (vec<constructor_elt, va_gc> *v,
8231 gfc_component *un, gfc_expr *init)
8233 gfc_constructor *ctor;
8235 if (un->ts.type != BT_UNION || un == NULL || init == NULL)
8236 return;
8238 ctor = gfc_constructor_first (init->value.constructor);
8240 if (ctor == NULL || ctor->expr == NULL)
8241 return;
8243 gcc_assert (init->expr_type == EXPR_STRUCTURE);
8245 /* If we have an 'initialize all' constructor, do it first. */
8246 if (ctor->expr->expr_type == EXPR_NULL)
8248 tree union_type = TREE_TYPE (un->backend_decl);
8249 tree val = build_constructor (union_type, NULL);
8250 CONSTRUCTOR_APPEND_ELT (v, un->backend_decl, val);
8251 ctor = gfc_constructor_next (ctor);
8254 /* Add the map initializer on top. */
8255 if (ctor != NULL && ctor->expr != NULL)
8257 gcc_assert (ctor->expr->expr_type == EXPR_STRUCTURE);
8258 tree val = gfc_conv_initializer (ctor->expr, &un->ts,
8259 TREE_TYPE (un->backend_decl),
8260 un->attr.dimension, un->attr.pointer,
8261 un->attr.proc_pointer);
8262 CONSTRUCTOR_APPEND_ELT (v, un->backend_decl, val);
8266 /* Build an expression for a constructor. If init is nonzero then
8267 this is part of a static variable initializer. */
8269 void
8270 gfc_conv_structure (gfc_se * se, gfc_expr * expr, int init)
8272 gfc_constructor *c;
8273 gfc_component *cm;
8274 tree val;
8275 tree type;
8276 tree tmp;
8277 vec<constructor_elt, va_gc> *v = NULL;
8279 gcc_assert (se->ss == NULL);
8280 gcc_assert (expr->expr_type == EXPR_STRUCTURE);
8281 type = gfc_typenode_for_spec (&expr->ts);
8283 if (!init)
8285 /* Create a temporary variable and fill it in. */
8286 se->expr = gfc_create_var (type, expr->ts.u.derived->name);
8287 /* The symtree in expr is NULL, if the code to generate is for
8288 initializing the static members only. */
8289 tmp = gfc_trans_structure_assign (se->expr, expr, expr->symtree != NULL,
8290 se->want_coarray);
8291 gfc_add_expr_to_block (&se->pre, tmp);
8292 return;
8295 cm = expr->ts.u.derived->components;
8297 for (c = gfc_constructor_first (expr->value.constructor);
8298 c; c = gfc_constructor_next (c), cm = cm->next)
8300 /* Skip absent members in default initializers and allocatable
8301 components. Although the latter have a default initializer
8302 of EXPR_NULL,... by default, the static nullify is not needed
8303 since this is done every time we come into scope. */
8304 if (!c->expr || (cm->attr.allocatable && cm->attr.flavor != FL_PROCEDURE))
8305 continue;
8307 if (cm->initializer && cm->initializer->expr_type != EXPR_NULL
8308 && strcmp (cm->name, "_extends") == 0
8309 && cm->initializer->symtree)
8311 tree vtab;
8312 gfc_symbol *vtabs;
8313 vtabs = cm->initializer->symtree->n.sym;
8314 vtab = gfc_build_addr_expr (NULL_TREE, gfc_get_symbol_decl (vtabs));
8315 vtab = unshare_expr_without_location (vtab);
8316 CONSTRUCTOR_APPEND_ELT (v, cm->backend_decl, vtab);
8318 else if (cm->ts.u.derived && strcmp (cm->name, "_size") == 0)
8320 val = TYPE_SIZE_UNIT (gfc_get_derived_type (cm->ts.u.derived));
8321 CONSTRUCTOR_APPEND_ELT (v, cm->backend_decl,
8322 fold_convert (TREE_TYPE (cm->backend_decl),
8323 val));
8325 else if (cm->ts.type == BT_INTEGER && strcmp (cm->name, "_len") == 0)
8326 CONSTRUCTOR_APPEND_ELT (v, cm->backend_decl,
8327 fold_convert (TREE_TYPE (cm->backend_decl),
8328 integer_zero_node));
8329 else if (cm->ts.type == BT_UNION)
8330 gfc_conv_union_initializer (v, cm, c->expr);
8331 else
8333 val = gfc_conv_initializer (c->expr, &cm->ts,
8334 TREE_TYPE (cm->backend_decl),
8335 cm->attr.dimension, cm->attr.pointer,
8336 cm->attr.proc_pointer);
8337 val = unshare_expr_without_location (val);
8339 /* Append it to the constructor list. */
8340 CONSTRUCTOR_APPEND_ELT (v, cm->backend_decl, val);
8344 se->expr = build_constructor (type, v);
8345 if (init)
8346 TREE_CONSTANT (se->expr) = 1;
8350 /* Translate a substring expression. */
8352 static void
8353 gfc_conv_substring_expr (gfc_se * se, gfc_expr * expr)
8355 gfc_ref *ref;
8357 ref = expr->ref;
8359 gcc_assert (ref == NULL || ref->type == REF_SUBSTRING);
8361 se->expr = gfc_build_wide_string_const (expr->ts.kind,
8362 expr->value.character.length,
8363 expr->value.character.string);
8365 se->string_length = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (se->expr)));
8366 TYPE_STRING_FLAG (TREE_TYPE (se->expr)) = 1;
8368 if (ref)
8369 gfc_conv_substring (se, ref, expr->ts.kind, NULL, &expr->where);
8373 /* Entry point for expression translation. Evaluates a scalar quantity.
8374 EXPR is the expression to be translated, and SE is the state structure if
8375 called from within the scalarized. */
8377 void
8378 gfc_conv_expr (gfc_se * se, gfc_expr * expr)
8380 gfc_ss *ss;
8382 ss = se->ss;
8383 if (ss && ss->info->expr == expr
8384 && (ss->info->type == GFC_SS_SCALAR
8385 || ss->info->type == GFC_SS_REFERENCE))
8387 gfc_ss_info *ss_info;
8389 ss_info = ss->info;
8390 /* Substitute a scalar expression evaluated outside the scalarization
8391 loop. */
8392 se->expr = ss_info->data.scalar.value;
8393 if (gfc_scalar_elemental_arg_saved_as_reference (ss_info))
8394 se->expr = build_fold_indirect_ref_loc (input_location, se->expr);
8396 se->string_length = ss_info->string_length;
8397 gfc_advance_se_ss_chain (se);
8398 return;
8401 /* We need to convert the expressions for the iso_c_binding derived types.
8402 C_NULL_PTR and C_NULL_FUNPTR will be made EXPR_NULL, which evaluates to
8403 null_pointer_node. C_PTR and C_FUNPTR are converted to match the
8404 typespec for the C_PTR and C_FUNPTR symbols, which has already been
8405 updated to be an integer with a kind equal to the size of a (void *). */
8406 if (expr->ts.type == BT_DERIVED && expr->ts.u.derived->ts.f90_type == BT_VOID
8407 && expr->ts.u.derived->attr.is_bind_c)
8409 if (expr->expr_type == EXPR_VARIABLE
8410 && (expr->symtree->n.sym->intmod_sym_id == ISOCBINDING_NULL_PTR
8411 || expr->symtree->n.sym->intmod_sym_id
8412 == ISOCBINDING_NULL_FUNPTR))
8414 /* Set expr_type to EXPR_NULL, which will result in
8415 null_pointer_node being used below. */
8416 expr->expr_type = EXPR_NULL;
8418 else
8420 /* Update the type/kind of the expression to be what the new
8421 type/kind are for the updated symbols of C_PTR/C_FUNPTR. */
8422 expr->ts.type = BT_INTEGER;
8423 expr->ts.f90_type = BT_VOID;
8424 expr->ts.kind = gfc_index_integer_kind;
8428 gfc_fix_class_refs (expr);
8430 switch (expr->expr_type)
8432 case EXPR_OP:
8433 gfc_conv_expr_op (se, expr);
8434 break;
8436 case EXPR_FUNCTION:
8437 gfc_conv_function_expr (se, expr);
8438 break;
8440 case EXPR_CONSTANT:
8441 gfc_conv_constant (se, expr);
8442 break;
8444 case EXPR_VARIABLE:
8445 gfc_conv_variable (se, expr);
8446 break;
8448 case EXPR_NULL:
8449 se->expr = null_pointer_node;
8450 break;
8452 case EXPR_SUBSTRING:
8453 gfc_conv_substring_expr (se, expr);
8454 break;
8456 case EXPR_STRUCTURE:
8457 gfc_conv_structure (se, expr, 0);
8458 break;
8460 case EXPR_ARRAY:
8461 gfc_conv_array_constructor_expr (se, expr);
8462 break;
8464 default:
8465 gcc_unreachable ();
8466 break;
8470 /* Like gfc_conv_expr_val, but the value is also suitable for use in the lhs
8471 of an assignment. */
8472 void
8473 gfc_conv_expr_lhs (gfc_se * se, gfc_expr * expr)
8475 gfc_conv_expr (se, expr);
8476 /* All numeric lvalues should have empty post chains. If not we need to
8477 figure out a way of rewriting an lvalue so that it has no post chain. */
8478 gcc_assert (expr->ts.type == BT_CHARACTER || !se->post.head);
8481 /* Like gfc_conv_expr, but the POST block is guaranteed to be empty for
8482 numeric expressions. Used for scalar values where inserting cleanup code
8483 is inconvenient. */
8484 void
8485 gfc_conv_expr_val (gfc_se * se, gfc_expr * expr)
8487 tree val;
8489 gcc_assert (expr->ts.type != BT_CHARACTER);
8490 gfc_conv_expr (se, expr);
8491 if (se->post.head)
8493 val = gfc_create_var (TREE_TYPE (se->expr), NULL);
8494 gfc_add_modify (&se->pre, val, se->expr);
8495 se->expr = val;
8496 gfc_add_block_to_block (&se->pre, &se->post);
8500 /* Helper to translate an expression and convert it to a particular type. */
8501 void
8502 gfc_conv_expr_type (gfc_se * se, gfc_expr * expr, tree type)
8504 gfc_conv_expr_val (se, expr);
8505 se->expr = convert (type, se->expr);
8509 /* Converts an expression so that it can be passed by reference. Scalar
8510 values only. */
8512 void
8513 gfc_conv_expr_reference (gfc_se * se, gfc_expr * expr, bool add_clobber)
8515 gfc_ss *ss;
8516 tree var;
8518 ss = se->ss;
8519 if (ss && ss->info->expr == expr
8520 && ss->info->type == GFC_SS_REFERENCE)
8522 /* Returns a reference to the scalar evaluated outside the loop
8523 for this case. */
8524 gfc_conv_expr (se, expr);
8526 if (expr->ts.type == BT_CHARACTER
8527 && expr->expr_type != EXPR_FUNCTION)
8528 gfc_conv_string_parameter (se);
8529 else
8530 se->expr = gfc_build_addr_expr (NULL_TREE, se->expr);
8532 return;
8535 if (expr->ts.type == BT_CHARACTER)
8537 gfc_conv_expr (se, expr);
8538 gfc_conv_string_parameter (se);
8539 return;
8542 if (expr->expr_type == EXPR_VARIABLE)
8544 se->want_pointer = 1;
8545 gfc_conv_expr (se, expr);
8546 if (se->post.head)
8548 var = gfc_create_var (TREE_TYPE (se->expr), NULL);
8549 gfc_add_modify (&se->pre, var, se->expr);
8550 gfc_add_block_to_block (&se->pre, &se->post);
8551 se->expr = var;
8553 else if (add_clobber && expr->ref == NULL)
8555 tree clobber;
8556 tree var;
8557 /* FIXME: This fails if var is passed by reference, see PR
8558 41453. */
8559 var = expr->symtree->n.sym->backend_decl;
8560 clobber = build_clobber (TREE_TYPE (var));
8561 gfc_add_modify (&se->pre, var, clobber);
8563 return;
8566 if (expr->expr_type == EXPR_FUNCTION
8567 && ((expr->value.function.esym
8568 && expr->value.function.esym->result->attr.pointer
8569 && !expr->value.function.esym->result->attr.dimension)
8570 || (!expr->value.function.esym && !expr->ref
8571 && expr->symtree->n.sym->attr.pointer
8572 && !expr->symtree->n.sym->attr.dimension)))
8574 se->want_pointer = 1;
8575 gfc_conv_expr (se, expr);
8576 var = gfc_create_var (TREE_TYPE (se->expr), NULL);
8577 gfc_add_modify (&se->pre, var, se->expr);
8578 se->expr = var;
8579 return;
8582 gfc_conv_expr (se, expr);
8584 /* Create a temporary var to hold the value. */
8585 if (TREE_CONSTANT (se->expr))
8587 tree tmp = se->expr;
8588 STRIP_TYPE_NOPS (tmp);
8589 var = build_decl (input_location,
8590 CONST_DECL, NULL, TREE_TYPE (tmp));
8591 DECL_INITIAL (var) = tmp;
8592 TREE_STATIC (var) = 1;
8593 pushdecl (var);
8595 else
8597 var = gfc_create_var (TREE_TYPE (se->expr), NULL);
8598 gfc_add_modify (&se->pre, var, se->expr);
8601 if (!expr->must_finalize)
8602 gfc_add_block_to_block (&se->pre, &se->post);
8604 /* Take the address of that value. */
8605 se->expr = gfc_build_addr_expr (NULL_TREE, var);
8609 /* Get the _len component for an unlimited polymorphic expression. */
8611 static tree
8612 trans_get_upoly_len (stmtblock_t *block, gfc_expr *expr)
8614 gfc_se se;
8615 gfc_ref *ref = expr->ref;
8617 gfc_init_se (&se, NULL);
8618 while (ref && ref->next)
8619 ref = ref->next;
8620 gfc_add_len_component (expr);
8621 gfc_conv_expr (&se, expr);
8622 gfc_add_block_to_block (block, &se.pre);
8623 gcc_assert (se.post.head == NULL_TREE);
8624 if (ref)
8626 gfc_free_ref_list (ref->next);
8627 ref->next = NULL;
8629 else
8631 gfc_free_ref_list (expr->ref);
8632 expr->ref = NULL;
8634 return se.expr;
8638 /* Assign _vptr and _len components as appropriate. BLOCK should be a
8639 statement-list outside of the scalarizer-loop. When code is generated, that
8640 depends on the scalarized expression, it is added to RSE.PRE.
8641 Returns le's _vptr tree and when set the len expressions in to_lenp and
8642 from_lenp to form a le%_vptr%_copy (re, le, [from_lenp, to_lenp])
8643 expression. */
8645 static tree
8646 trans_class_vptr_len_assignment (stmtblock_t *block, gfc_expr * le,
8647 gfc_expr * re, gfc_se *rse,
8648 tree * to_lenp, tree * from_lenp)
8650 gfc_se se;
8651 gfc_expr * vptr_expr;
8652 tree tmp, to_len = NULL_TREE, from_len = NULL_TREE, lhs_vptr;
8653 bool set_vptr = false, temp_rhs = false;
8654 stmtblock_t *pre = block;
8656 /* Create a temporary for complicated expressions. */
8657 if (re->expr_type != EXPR_VARIABLE && re->expr_type != EXPR_NULL
8658 && rse->expr != NULL_TREE && !DECL_P (rse->expr))
8660 tmp = gfc_create_var (TREE_TYPE (rse->expr), "rhs");
8661 pre = &rse->pre;
8662 gfc_add_modify (&rse->pre, tmp, rse->expr);
8663 rse->expr = tmp;
8664 temp_rhs = true;
8667 /* Get the _vptr for the left-hand side expression. */
8668 gfc_init_se (&se, NULL);
8669 vptr_expr = gfc_find_and_cut_at_last_class_ref (le);
8670 if (vptr_expr != NULL && gfc_expr_attr (vptr_expr).class_ok)
8672 /* Care about _len for unlimited polymorphic entities. */
8673 if (UNLIMITED_POLY (vptr_expr)
8674 || (vptr_expr->ts.type == BT_DERIVED
8675 && vptr_expr->ts.u.derived->attr.unlimited_polymorphic))
8676 to_len = trans_get_upoly_len (block, vptr_expr);
8677 gfc_add_vptr_component (vptr_expr);
8678 set_vptr = true;
8680 else
8681 vptr_expr = gfc_lval_expr_from_sym (gfc_find_vtab (&le->ts));
8682 se.want_pointer = 1;
8683 gfc_conv_expr (&se, vptr_expr);
8684 gfc_free_expr (vptr_expr);
8685 gfc_add_block_to_block (block, &se.pre);
8686 gcc_assert (se.post.head == NULL_TREE);
8687 lhs_vptr = se.expr;
8688 STRIP_NOPS (lhs_vptr);
8690 /* Set the _vptr only when the left-hand side of the assignment is a
8691 class-object. */
8692 if (set_vptr)
8694 /* Get the vptr from the rhs expression only, when it is variable.
8695 Functions are expected to be assigned to a temporary beforehand. */
8696 vptr_expr = (re->expr_type == EXPR_VARIABLE && re->ts.type == BT_CLASS)
8697 ? gfc_find_and_cut_at_last_class_ref (re)
8698 : NULL;
8699 if (vptr_expr != NULL && vptr_expr->ts.type == BT_CLASS)
8701 if (to_len != NULL_TREE)
8703 /* Get the _len information from the rhs. */
8704 if (UNLIMITED_POLY (vptr_expr)
8705 || (vptr_expr->ts.type == BT_DERIVED
8706 && vptr_expr->ts.u.derived->attr.unlimited_polymorphic))
8707 from_len = trans_get_upoly_len (block, vptr_expr);
8709 gfc_add_vptr_component (vptr_expr);
8711 else
8713 if (re->expr_type == EXPR_VARIABLE
8714 && DECL_P (re->symtree->n.sym->backend_decl)
8715 && DECL_LANG_SPECIFIC (re->symtree->n.sym->backend_decl)
8716 && GFC_DECL_SAVED_DESCRIPTOR (re->symtree->n.sym->backend_decl)
8717 && GFC_CLASS_TYPE_P (TREE_TYPE (GFC_DECL_SAVED_DESCRIPTOR (
8718 re->symtree->n.sym->backend_decl))))
8720 vptr_expr = NULL;
8721 se.expr = gfc_class_vptr_get (GFC_DECL_SAVED_DESCRIPTOR (
8722 re->symtree->n.sym->backend_decl));
8723 if (to_len)
8724 from_len = gfc_class_len_get (GFC_DECL_SAVED_DESCRIPTOR (
8725 re->symtree->n.sym->backend_decl));
8727 else if (temp_rhs && re->ts.type == BT_CLASS)
8729 vptr_expr = NULL;
8730 se.expr = gfc_class_vptr_get (rse->expr);
8731 if (UNLIMITED_POLY (re))
8732 from_len = gfc_class_len_get (rse->expr);
8734 else if (re->expr_type != EXPR_NULL)
8735 /* Only when rhs is non-NULL use its declared type for vptr
8736 initialisation. */
8737 vptr_expr = gfc_lval_expr_from_sym (gfc_find_vtab (&re->ts));
8738 else
8739 /* When the rhs is NULL use the vtab of lhs' declared type. */
8740 vptr_expr = gfc_lval_expr_from_sym (gfc_find_vtab (&le->ts));
8743 if (vptr_expr)
8745 gfc_init_se (&se, NULL);
8746 se.want_pointer = 1;
8747 gfc_conv_expr (&se, vptr_expr);
8748 gfc_free_expr (vptr_expr);
8749 gfc_add_block_to_block (block, &se.pre);
8750 gcc_assert (se.post.head == NULL_TREE);
8752 gfc_add_modify (pre, lhs_vptr, fold_convert (TREE_TYPE (lhs_vptr),
8753 se.expr));
8755 if (to_len != NULL_TREE)
8757 /* The _len component needs to be set. Figure how to get the
8758 value of the right-hand side. */
8759 if (from_len == NULL_TREE)
8761 if (rse->string_length != NULL_TREE)
8762 from_len = rse->string_length;
8763 else if (re->ts.type == BT_CHARACTER && re->ts.u.cl->length)
8765 from_len = gfc_get_expr_charlen (re);
8766 gfc_init_se (&se, NULL);
8767 gfc_conv_expr (&se, re->ts.u.cl->length);
8768 gfc_add_block_to_block (block, &se.pre);
8769 gcc_assert (se.post.head == NULL_TREE);
8770 from_len = gfc_evaluate_now (se.expr, block);
8772 else
8773 from_len = build_zero_cst (gfc_charlen_type_node);
8775 gfc_add_modify (pre, to_len, fold_convert (TREE_TYPE (to_len),
8776 from_len));
8780 /* Return the _len trees only, when requested. */
8781 if (to_lenp)
8782 *to_lenp = to_len;
8783 if (from_lenp)
8784 *from_lenp = from_len;
8785 return lhs_vptr;
8789 /* Assign tokens for pointer components. */
8791 static void
8792 trans_caf_token_assign (gfc_se *lse, gfc_se *rse, gfc_expr *expr1,
8793 gfc_expr *expr2)
8795 symbol_attribute lhs_attr, rhs_attr;
8796 tree tmp, lhs_tok, rhs_tok;
8797 /* Flag to indicated component refs on the rhs. */
8798 bool rhs_cr;
8800 lhs_attr = gfc_caf_attr (expr1);
8801 if (expr2->expr_type != EXPR_NULL)
8803 rhs_attr = gfc_caf_attr (expr2, false, &rhs_cr);
8804 if (lhs_attr.codimension && rhs_attr.codimension)
8806 lhs_tok = gfc_get_ultimate_alloc_ptr_comps_caf_token (lse, expr1);
8807 lhs_tok = build_fold_indirect_ref (lhs_tok);
8809 if (rhs_cr)
8810 rhs_tok = gfc_get_ultimate_alloc_ptr_comps_caf_token (rse, expr2);
8811 else
8813 tree caf_decl;
8814 caf_decl = gfc_get_tree_for_caf_expr (expr2);
8815 gfc_get_caf_token_offset (rse, &rhs_tok, NULL, caf_decl,
8816 NULL_TREE, NULL);
8818 tmp = build2_loc (input_location, MODIFY_EXPR, void_type_node,
8819 lhs_tok,
8820 fold_convert (TREE_TYPE (lhs_tok), rhs_tok));
8821 gfc_prepend_expr_to_block (&lse->post, tmp);
8824 else if (lhs_attr.codimension)
8826 lhs_tok = gfc_get_ultimate_alloc_ptr_comps_caf_token (lse, expr1);
8827 lhs_tok = build_fold_indirect_ref (lhs_tok);
8828 tmp = build2_loc (input_location, MODIFY_EXPR, void_type_node,
8829 lhs_tok, null_pointer_node);
8830 gfc_prepend_expr_to_block (&lse->post, tmp);
8834 /* Indentify class valued proc_pointer assignments. */
8836 static bool
8837 pointer_assignment_is_proc_pointer (gfc_expr * expr1, gfc_expr * expr2)
8839 gfc_ref * ref;
8841 ref = expr1->ref;
8842 while (ref && ref->next)
8843 ref = ref->next;
8845 return ref && ref->type == REF_COMPONENT
8846 && ref->u.c.component->attr.proc_pointer
8847 && expr2->expr_type == EXPR_VARIABLE
8848 && expr2->symtree->n.sym->attr.flavor == FL_PROCEDURE;
8852 /* Do everything that is needed for a CLASS function expr2. */
8854 static tree
8855 trans_class_pointer_fcn (stmtblock_t *block, gfc_se *lse, gfc_se *rse,
8856 gfc_expr *expr1, gfc_expr *expr2)
8858 tree expr1_vptr = NULL_TREE;
8859 tree tmp;
8861 gfc_conv_function_expr (rse, expr2);
8862 rse->expr = gfc_evaluate_now (rse->expr, &rse->pre);
8864 if (expr1->ts.type != BT_CLASS)
8865 rse->expr = gfc_class_data_get (rse->expr);
8866 else
8868 expr1_vptr = trans_class_vptr_len_assignment (block, expr1,
8869 expr2, rse,
8870 NULL, NULL);
8871 gfc_add_block_to_block (block, &rse->pre);
8872 tmp = gfc_create_var (TREE_TYPE (rse->expr), "ptrtemp");
8873 gfc_add_modify (&lse->pre, tmp, rse->expr);
8875 gfc_add_modify (&lse->pre, expr1_vptr,
8876 fold_convert (TREE_TYPE (expr1_vptr),
8877 gfc_class_vptr_get (tmp)));
8878 rse->expr = gfc_class_data_get (tmp);
8881 return expr1_vptr;
8885 tree
8886 gfc_trans_pointer_assign (gfc_code * code)
8888 return gfc_trans_pointer_assignment (code->expr1, code->expr2);
8892 /* Generate code for a pointer assignment. */
8894 tree
8895 gfc_trans_pointer_assignment (gfc_expr * expr1, gfc_expr * expr2)
8897 gfc_se lse;
8898 gfc_se rse;
8899 stmtblock_t block;
8900 tree desc;
8901 tree tmp;
8902 tree expr1_vptr = NULL_TREE;
8903 bool scalar, non_proc_pointer_assign;
8904 gfc_ss *ss;
8906 gfc_start_block (&block);
8908 gfc_init_se (&lse, NULL);
8910 /* Usually testing whether this is not a proc pointer assignment. */
8911 non_proc_pointer_assign = !pointer_assignment_is_proc_pointer (expr1, expr2);
8913 /* Check whether the expression is a scalar or not; we cannot use
8914 expr1->rank as it can be nonzero for proc pointers. */
8915 ss = gfc_walk_expr (expr1);
8916 scalar = ss == gfc_ss_terminator;
8917 if (!scalar)
8918 gfc_free_ss_chain (ss);
8920 if (expr1->ts.type == BT_DERIVED && expr2->ts.type == BT_CLASS
8921 && expr2->expr_type != EXPR_FUNCTION && non_proc_pointer_assign)
8923 gfc_add_data_component (expr2);
8924 /* The following is required as gfc_add_data_component doesn't
8925 update ts.type if there is a tailing REF_ARRAY. */
8926 expr2->ts.type = BT_DERIVED;
8929 if (scalar)
8931 /* Scalar pointers. */
8932 lse.want_pointer = 1;
8933 gfc_conv_expr (&lse, expr1);
8934 gfc_init_se (&rse, NULL);
8935 rse.want_pointer = 1;
8936 if (expr2->expr_type == EXPR_FUNCTION && expr2->ts.type == BT_CLASS)
8937 trans_class_pointer_fcn (&block, &lse, &rse, expr1, expr2);
8938 else
8939 gfc_conv_expr (&rse, expr2);
8941 if (non_proc_pointer_assign && expr1->ts.type == BT_CLASS)
8943 trans_class_vptr_len_assignment (&block, expr1, expr2, &rse, NULL,
8944 NULL);
8945 lse.expr = gfc_class_data_get (lse.expr);
8948 if (expr1->symtree->n.sym->attr.proc_pointer
8949 && expr1->symtree->n.sym->attr.dummy)
8950 lse.expr = build_fold_indirect_ref_loc (input_location,
8951 lse.expr);
8953 if (expr2->symtree && expr2->symtree->n.sym->attr.proc_pointer
8954 && expr2->symtree->n.sym->attr.dummy)
8955 rse.expr = build_fold_indirect_ref_loc (input_location,
8956 rse.expr);
8958 gfc_add_block_to_block (&block, &lse.pre);
8959 gfc_add_block_to_block (&block, &rse.pre);
8961 /* Check character lengths if character expression. The test is only
8962 really added if -fbounds-check is enabled. Exclude deferred
8963 character length lefthand sides. */
8964 if (expr1->ts.type == BT_CHARACTER && expr2->expr_type != EXPR_NULL
8965 && !expr1->ts.deferred
8966 && !expr1->symtree->n.sym->attr.proc_pointer
8967 && !gfc_is_proc_ptr_comp (expr1))
8969 gcc_assert (expr2->ts.type == BT_CHARACTER);
8970 gcc_assert (lse.string_length && rse.string_length);
8971 gfc_trans_same_strlen_check ("pointer assignment", &expr1->where,
8972 lse.string_length, rse.string_length,
8973 &block);
8976 /* The assignment to an deferred character length sets the string
8977 length to that of the rhs. */
8978 if (expr1->ts.deferred)
8980 if (expr2->expr_type != EXPR_NULL && lse.string_length != NULL)
8981 gfc_add_modify (&block, lse.string_length,
8982 fold_convert (TREE_TYPE (lse.string_length),
8983 rse.string_length));
8984 else if (lse.string_length != NULL)
8985 gfc_add_modify (&block, lse.string_length,
8986 build_zero_cst (TREE_TYPE (lse.string_length)));
8989 gfc_add_modify (&block, lse.expr,
8990 fold_convert (TREE_TYPE (lse.expr), rse.expr));
8992 /* Also set the tokens for pointer components in derived typed
8993 coarrays. */
8994 if (flag_coarray == GFC_FCOARRAY_LIB)
8995 trans_caf_token_assign (&lse, &rse, expr1, expr2);
8997 gfc_add_block_to_block (&block, &rse.post);
8998 gfc_add_block_to_block (&block, &lse.post);
9000 else
9002 gfc_ref* remap;
9003 bool rank_remap;
9004 tree strlen_lhs;
9005 tree strlen_rhs = NULL_TREE;
9007 /* Array pointer. Find the last reference on the LHS and if it is an
9008 array section ref, we're dealing with bounds remapping. In this case,
9009 set it to AR_FULL so that gfc_conv_expr_descriptor does
9010 not see it and process the bounds remapping afterwards explicitly. */
9011 for (remap = expr1->ref; remap; remap = remap->next)
9012 if (!remap->next && remap->type == REF_ARRAY
9013 && remap->u.ar.type == AR_SECTION)
9014 break;
9015 rank_remap = (remap && remap->u.ar.end[0]);
9017 gfc_init_se (&lse, NULL);
9018 if (remap)
9019 lse.descriptor_only = 1;
9020 gfc_conv_expr_descriptor (&lse, expr1);
9021 strlen_lhs = lse.string_length;
9022 desc = lse.expr;
9024 if (expr2->expr_type == EXPR_NULL)
9026 /* Just set the data pointer to null. */
9027 gfc_conv_descriptor_data_set (&lse.pre, lse.expr, null_pointer_node);
9029 else if (rank_remap)
9031 /* If we are rank-remapping, just get the RHS's descriptor and
9032 process this later on. */
9033 gfc_init_se (&rse, NULL);
9034 rse.direct_byref = 1;
9035 rse.byref_noassign = 1;
9037 if (expr2->expr_type == EXPR_FUNCTION && expr2->ts.type == BT_CLASS)
9038 expr1_vptr = trans_class_pointer_fcn (&block, &lse, &rse,
9039 expr1, expr2);
9040 else if (expr2->expr_type == EXPR_FUNCTION)
9042 tree bound[GFC_MAX_DIMENSIONS];
9043 int i;
9045 for (i = 0; i < expr2->rank; i++)
9046 bound[i] = NULL_TREE;
9047 tmp = gfc_typenode_for_spec (&expr2->ts);
9048 tmp = gfc_get_array_type_bounds (tmp, expr2->rank, 0,
9049 bound, bound, 0,
9050 GFC_ARRAY_POINTER_CONT, false);
9051 tmp = gfc_create_var (tmp, "ptrtemp");
9052 rse.descriptor_only = 0;
9053 rse.expr = tmp;
9054 rse.direct_byref = 1;
9055 gfc_conv_expr_descriptor (&rse, expr2);
9056 strlen_rhs = rse.string_length;
9057 rse.expr = tmp;
9059 else
9061 gfc_conv_expr_descriptor (&rse, expr2);
9062 strlen_rhs = rse.string_length;
9063 if (expr1->ts.type == BT_CLASS)
9064 expr1_vptr = trans_class_vptr_len_assignment (&block, expr1,
9065 expr2, &rse,
9066 NULL, NULL);
9069 else if (expr2->expr_type == EXPR_VARIABLE)
9071 /* Assign directly to the LHS's descriptor. */
9072 lse.descriptor_only = 0;
9073 lse.direct_byref = 1;
9074 gfc_conv_expr_descriptor (&lse, expr2);
9075 strlen_rhs = lse.string_length;
9077 if (expr1->ts.type == BT_CLASS)
9079 rse.expr = NULL_TREE;
9080 rse.string_length = NULL_TREE;
9081 trans_class_vptr_len_assignment (&block, expr1, expr2, &rse,
9082 NULL, NULL);
9085 if (remap == NULL)
9087 /* If the target is not a whole array, use the target array
9088 reference for remap. */
9089 for (remap = expr2->ref; remap; remap = remap->next)
9090 if (remap->type == REF_ARRAY
9091 && remap->u.ar.type == AR_FULL
9092 && remap->next)
9093 break;
9096 else if (expr2->expr_type == EXPR_FUNCTION && expr2->ts.type == BT_CLASS)
9098 gfc_init_se (&rse, NULL);
9099 rse.want_pointer = 1;
9100 gfc_conv_function_expr (&rse, expr2);
9101 if (expr1->ts.type != BT_CLASS)
9103 rse.expr = gfc_class_data_get (rse.expr);
9104 gfc_add_modify (&lse.pre, desc, rse.expr);
9105 /* Set the lhs span. */
9106 tmp = TREE_TYPE (rse.expr);
9107 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (tmp));
9108 tmp = fold_convert (gfc_array_index_type, tmp);
9109 gfc_conv_descriptor_span_set (&lse.pre, desc, tmp);
9111 else
9113 expr1_vptr = trans_class_vptr_len_assignment (&block, expr1,
9114 expr2, &rse, NULL,
9115 NULL);
9116 gfc_add_block_to_block (&block, &rse.pre);
9117 tmp = gfc_create_var (TREE_TYPE (rse.expr), "ptrtemp");
9118 gfc_add_modify (&lse.pre, tmp, rse.expr);
9120 gfc_add_modify (&lse.pre, expr1_vptr,
9121 fold_convert (TREE_TYPE (expr1_vptr),
9122 gfc_class_vptr_get (tmp)));
9123 rse.expr = gfc_class_data_get (tmp);
9124 gfc_add_modify (&lse.pre, desc, rse.expr);
9127 else
9129 /* Assign to a temporary descriptor and then copy that
9130 temporary to the pointer. */
9131 tmp = gfc_create_var (TREE_TYPE (desc), "ptrtemp");
9132 lse.descriptor_only = 0;
9133 lse.expr = tmp;
9134 lse.direct_byref = 1;
9135 gfc_conv_expr_descriptor (&lse, expr2);
9136 strlen_rhs = lse.string_length;
9137 gfc_add_modify (&lse.pre, desc, tmp);
9140 gfc_add_block_to_block (&block, &lse.pre);
9141 if (rank_remap)
9142 gfc_add_block_to_block (&block, &rse.pre);
9144 /* If we do bounds remapping, update LHS descriptor accordingly. */
9145 if (remap)
9147 int dim;
9148 gcc_assert (remap->u.ar.dimen == expr1->rank);
9150 if (rank_remap)
9152 /* Do rank remapping. We already have the RHS's descriptor
9153 converted in rse and now have to build the correct LHS
9154 descriptor for it. */
9156 tree dtype, data, span;
9157 tree offs, stride;
9158 tree lbound, ubound;
9160 /* Set dtype. */
9161 dtype = gfc_conv_descriptor_dtype (desc);
9162 tmp = gfc_get_dtype (TREE_TYPE (desc));
9163 gfc_add_modify (&block, dtype, tmp);
9165 /* Copy data pointer. */
9166 data = gfc_conv_descriptor_data_get (rse.expr);
9167 gfc_conv_descriptor_data_set (&block, desc, data);
9169 /* Copy the span. */
9170 if (TREE_CODE (rse.expr) == VAR_DECL
9171 && GFC_DECL_PTR_ARRAY_P (rse.expr))
9172 span = gfc_conv_descriptor_span_get (rse.expr);
9173 else
9175 tmp = TREE_TYPE (rse.expr);
9176 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (tmp));
9177 span = fold_convert (gfc_array_index_type, tmp);
9179 gfc_conv_descriptor_span_set (&block, desc, span);
9181 /* Copy offset but adjust it such that it would correspond
9182 to a lbound of zero. */
9183 offs = gfc_conv_descriptor_offset_get (rse.expr);
9184 for (dim = 0; dim < expr2->rank; ++dim)
9186 stride = gfc_conv_descriptor_stride_get (rse.expr,
9187 gfc_rank_cst[dim]);
9188 lbound = gfc_conv_descriptor_lbound_get (rse.expr,
9189 gfc_rank_cst[dim]);
9190 tmp = fold_build2_loc (input_location, MULT_EXPR,
9191 gfc_array_index_type, stride, lbound);
9192 offs = fold_build2_loc (input_location, PLUS_EXPR,
9193 gfc_array_index_type, offs, tmp);
9195 gfc_conv_descriptor_offset_set (&block, desc, offs);
9197 /* Set the bounds as declared for the LHS and calculate strides as
9198 well as another offset update accordingly. */
9199 stride = gfc_conv_descriptor_stride_get (rse.expr,
9200 gfc_rank_cst[0]);
9201 for (dim = 0; dim < expr1->rank; ++dim)
9203 gfc_se lower_se;
9204 gfc_se upper_se;
9206 gcc_assert (remap->u.ar.start[dim] && remap->u.ar.end[dim]);
9208 /* Convert declared bounds. */
9209 gfc_init_se (&lower_se, NULL);
9210 gfc_init_se (&upper_se, NULL);
9211 gfc_conv_expr (&lower_se, remap->u.ar.start[dim]);
9212 gfc_conv_expr (&upper_se, remap->u.ar.end[dim]);
9214 gfc_add_block_to_block (&block, &lower_se.pre);
9215 gfc_add_block_to_block (&block, &upper_se.pre);
9217 lbound = fold_convert (gfc_array_index_type, lower_se.expr);
9218 ubound = fold_convert (gfc_array_index_type, upper_se.expr);
9220 lbound = gfc_evaluate_now (lbound, &block);
9221 ubound = gfc_evaluate_now (ubound, &block);
9223 gfc_add_block_to_block (&block, &lower_se.post);
9224 gfc_add_block_to_block (&block, &upper_se.post);
9226 /* Set bounds in descriptor. */
9227 gfc_conv_descriptor_lbound_set (&block, desc,
9228 gfc_rank_cst[dim], lbound);
9229 gfc_conv_descriptor_ubound_set (&block, desc,
9230 gfc_rank_cst[dim], ubound);
9232 /* Set stride. */
9233 stride = gfc_evaluate_now (stride, &block);
9234 gfc_conv_descriptor_stride_set (&block, desc,
9235 gfc_rank_cst[dim], stride);
9237 /* Update offset. */
9238 offs = gfc_conv_descriptor_offset_get (desc);
9239 tmp = fold_build2_loc (input_location, MULT_EXPR,
9240 gfc_array_index_type, lbound, stride);
9241 offs = fold_build2_loc (input_location, MINUS_EXPR,
9242 gfc_array_index_type, offs, tmp);
9243 offs = gfc_evaluate_now (offs, &block);
9244 gfc_conv_descriptor_offset_set (&block, desc, offs);
9246 /* Update stride. */
9247 tmp = gfc_conv_array_extent_dim (lbound, ubound, NULL);
9248 stride = fold_build2_loc (input_location, MULT_EXPR,
9249 gfc_array_index_type, stride, tmp);
9252 else
9254 /* Bounds remapping. Just shift the lower bounds. */
9256 gcc_assert (expr1->rank == expr2->rank);
9258 for (dim = 0; dim < remap->u.ar.dimen; ++dim)
9260 gfc_se lbound_se;
9262 gcc_assert (!remap->u.ar.end[dim]);
9263 gfc_init_se (&lbound_se, NULL);
9264 if (remap->u.ar.start[dim])
9266 gfc_conv_expr (&lbound_se, remap->u.ar.start[dim]);
9267 gfc_add_block_to_block (&block, &lbound_se.pre);
9269 else
9270 /* This remap arises from a target that is not a whole
9271 array. The start expressions will be NULL but we need
9272 the lbounds to be one. */
9273 lbound_se.expr = gfc_index_one_node;
9274 gfc_conv_shift_descriptor_lbound (&block, desc,
9275 dim, lbound_se.expr);
9276 gfc_add_block_to_block (&block, &lbound_se.post);
9281 /* If rank remapping was done, check with -fcheck=bounds that
9282 the target is at least as large as the pointer. */
9283 if (rank_remap && (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS))
9285 tree lsize, rsize;
9286 tree fault;
9287 const char* msg;
9289 lsize = gfc_conv_descriptor_size (lse.expr, expr1->rank);
9290 rsize = gfc_conv_descriptor_size (rse.expr, expr2->rank);
9292 lsize = gfc_evaluate_now (lsize, &block);
9293 rsize = gfc_evaluate_now (rsize, &block);
9294 fault = fold_build2_loc (input_location, LT_EXPR, logical_type_node,
9295 rsize, lsize);
9297 msg = _("Target of rank remapping is too small (%ld < %ld)");
9298 gfc_trans_runtime_check (true, false, fault, &block, &expr2->where,
9299 msg, rsize, lsize);
9302 if (expr1->ts.type == BT_CHARACTER
9303 && expr1->symtree->n.sym->ts.deferred
9304 && expr1->symtree->n.sym->ts.u.cl->backend_decl
9305 && VAR_P (expr1->symtree->n.sym->ts.u.cl->backend_decl))
9307 tmp = expr1->symtree->n.sym->ts.u.cl->backend_decl;
9308 if (expr2->expr_type != EXPR_NULL)
9309 gfc_add_modify (&block, tmp,
9310 fold_convert (TREE_TYPE (tmp), strlen_rhs));
9311 else
9312 gfc_add_modify (&block, tmp, build_zero_cst (TREE_TYPE (tmp)));
9315 /* Check string lengths if applicable. The check is only really added
9316 to the output code if -fbounds-check is enabled. */
9317 if (expr1->ts.type == BT_CHARACTER && expr2->expr_type != EXPR_NULL)
9319 gcc_assert (expr2->ts.type == BT_CHARACTER);
9320 gcc_assert (strlen_lhs && strlen_rhs);
9321 gfc_trans_same_strlen_check ("pointer assignment", &expr1->where,
9322 strlen_lhs, strlen_rhs, &block);
9325 gfc_add_block_to_block (&block, &lse.post);
9326 if (rank_remap)
9327 gfc_add_block_to_block (&block, &rse.post);
9330 return gfc_finish_block (&block);
9334 /* Makes sure se is suitable for passing as a function string parameter. */
9335 /* TODO: Need to check all callers of this function. It may be abused. */
9337 void
9338 gfc_conv_string_parameter (gfc_se * se)
9340 tree type;
9342 if (TREE_CODE (se->expr) == STRING_CST)
9344 type = TREE_TYPE (TREE_TYPE (se->expr));
9345 se->expr = gfc_build_addr_expr (build_pointer_type (type), se->expr);
9346 return;
9349 if (TYPE_STRING_FLAG (TREE_TYPE (se->expr)))
9351 if (TREE_CODE (se->expr) != INDIRECT_REF)
9353 type = TREE_TYPE (se->expr);
9354 se->expr = gfc_build_addr_expr (build_pointer_type (type), se->expr);
9356 else
9358 type = gfc_get_character_type_len (gfc_default_character_kind,
9359 se->string_length);
9360 type = build_pointer_type (type);
9361 se->expr = gfc_build_addr_expr (type, se->expr);
9365 gcc_assert (POINTER_TYPE_P (TREE_TYPE (se->expr)));
9369 /* Generate code for assignment of scalar variables. Includes character
9370 strings and derived types with allocatable components.
9371 If you know that the LHS has no allocations, set dealloc to false.
9373 DEEP_COPY has no effect if the typespec TS is not a derived type with
9374 allocatable components. Otherwise, if it is set, an explicit copy of each
9375 allocatable component is made. This is necessary as a simple copy of the
9376 whole object would copy array descriptors as is, so that the lhs's
9377 allocatable components would point to the rhs's after the assignment.
9378 Typically, setting DEEP_COPY is necessary if the rhs is a variable, and not
9379 necessary if the rhs is a non-pointer function, as the allocatable components
9380 are not accessible by other means than the function's result after the
9381 function has returned. It is even more subtle when temporaries are involved,
9382 as the two following examples show:
9383 1. When we evaluate an array constructor, a temporary is created. Thus
9384 there is theoretically no alias possible. However, no deep copy is
9385 made for this temporary, so that if the constructor is made of one or
9386 more variable with allocatable components, those components still point
9387 to the variable's: DEEP_COPY should be set for the assignment from the
9388 temporary to the lhs in that case.
9389 2. When assigning a scalar to an array, we evaluate the scalar value out
9390 of the loop, store it into a temporary variable, and assign from that.
9391 In that case, deep copying when assigning to the temporary would be a
9392 waste of resources; however deep copies should happen when assigning from
9393 the temporary to each array element: again DEEP_COPY should be set for
9394 the assignment from the temporary to the lhs. */
9396 tree
9397 gfc_trans_scalar_assign (gfc_se * lse, gfc_se * rse, gfc_typespec ts,
9398 bool deep_copy, bool dealloc, bool in_coarray)
9400 stmtblock_t block;
9401 tree tmp;
9402 tree cond;
9404 gfc_init_block (&block);
9406 if (ts.type == BT_CHARACTER)
9408 tree rlen = NULL;
9409 tree llen = NULL;
9411 if (lse->string_length != NULL_TREE)
9413 gfc_conv_string_parameter (lse);
9414 gfc_add_block_to_block (&block, &lse->pre);
9415 llen = lse->string_length;
9418 if (rse->string_length != NULL_TREE)
9420 gfc_conv_string_parameter (rse);
9421 gfc_add_block_to_block (&block, &rse->pre);
9422 rlen = rse->string_length;
9425 gfc_trans_string_copy (&block, llen, lse->expr, ts.kind, rlen,
9426 rse->expr, ts.kind);
9428 else if (gfc_bt_struct (ts.type)
9429 && (ts.u.derived->attr.alloc_comp
9430 || (deep_copy && ts.u.derived->attr.pdt_type)))
9432 tree tmp_var = NULL_TREE;
9433 cond = NULL_TREE;
9435 /* Are the rhs and the lhs the same? */
9436 if (deep_copy)
9438 cond = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
9439 gfc_build_addr_expr (NULL_TREE, lse->expr),
9440 gfc_build_addr_expr (NULL_TREE, rse->expr));
9441 cond = gfc_evaluate_now (cond, &lse->pre);
9444 /* Deallocate the lhs allocated components as long as it is not
9445 the same as the rhs. This must be done following the assignment
9446 to prevent deallocating data that could be used in the rhs
9447 expression. */
9448 if (dealloc)
9450 tmp_var = gfc_evaluate_now (lse->expr, &lse->pre);
9451 tmp = gfc_deallocate_alloc_comp_no_caf (ts.u.derived, tmp_var, 0);
9452 if (deep_copy)
9453 tmp = build3_v (COND_EXPR, cond, build_empty_stmt (input_location),
9454 tmp);
9455 gfc_add_expr_to_block (&lse->post, tmp);
9458 gfc_add_block_to_block (&block, &rse->pre);
9459 gfc_add_block_to_block (&block, &lse->pre);
9461 gfc_add_modify (&block, lse->expr,
9462 fold_convert (TREE_TYPE (lse->expr), rse->expr));
9464 /* Restore pointer address of coarray components. */
9465 if (ts.u.derived->attr.coarray_comp && deep_copy && tmp_var != NULL_TREE)
9467 tmp = gfc_reassign_alloc_comp_caf (ts.u.derived, tmp_var, lse->expr);
9468 tmp = build3_v (COND_EXPR, cond, build_empty_stmt (input_location),
9469 tmp);
9470 gfc_add_expr_to_block (&block, tmp);
9473 /* Do a deep copy if the rhs is a variable, if it is not the
9474 same as the lhs. */
9475 if (deep_copy)
9477 int caf_mode = in_coarray ? (GFC_STRUCTURE_CAF_MODE_ENABLE_COARRAY
9478 | GFC_STRUCTURE_CAF_MODE_IN_COARRAY) : 0;
9479 tmp = gfc_copy_alloc_comp (ts.u.derived, rse->expr, lse->expr, 0,
9480 caf_mode);
9481 tmp = build3_v (COND_EXPR, cond, build_empty_stmt (input_location),
9482 tmp);
9483 gfc_add_expr_to_block (&block, tmp);
9486 else if (gfc_bt_struct (ts.type) || ts.type == BT_CLASS)
9488 gfc_add_block_to_block (&block, &lse->pre);
9489 gfc_add_block_to_block (&block, &rse->pre);
9490 tmp = fold_build1_loc (input_location, VIEW_CONVERT_EXPR,
9491 TREE_TYPE (lse->expr), rse->expr);
9492 gfc_add_modify (&block, lse->expr, tmp);
9494 else
9496 gfc_add_block_to_block (&block, &lse->pre);
9497 gfc_add_block_to_block (&block, &rse->pre);
9499 gfc_add_modify (&block, lse->expr,
9500 fold_convert (TREE_TYPE (lse->expr), rse->expr));
9503 gfc_add_block_to_block (&block, &lse->post);
9504 gfc_add_block_to_block (&block, &rse->post);
9506 return gfc_finish_block (&block);
9510 /* There are quite a lot of restrictions on the optimisation in using an
9511 array function assign without a temporary. */
9513 static bool
9514 arrayfunc_assign_needs_temporary (gfc_expr * expr1, gfc_expr * expr2)
9516 gfc_ref * ref;
9517 bool seen_array_ref;
9518 bool c = false;
9519 gfc_symbol *sym = expr1->symtree->n.sym;
9521 /* Play it safe with class functions assigned to a derived type. */
9522 if (gfc_is_class_array_function (expr2)
9523 && expr1->ts.type == BT_DERIVED)
9524 return true;
9526 /* The caller has already checked rank>0 and expr_type == EXPR_FUNCTION. */
9527 if (expr2->value.function.isym && !gfc_is_intrinsic_libcall (expr2))
9528 return true;
9530 /* Elemental functions are scalarized so that they don't need a
9531 temporary in gfc_trans_assignment_1, so return a true. Otherwise,
9532 they would need special treatment in gfc_trans_arrayfunc_assign. */
9533 if (expr2->value.function.esym != NULL
9534 && expr2->value.function.esym->attr.elemental)
9535 return true;
9537 /* Need a temporary if rhs is not FULL or a contiguous section. */
9538 if (expr1->ref && !(gfc_full_array_ref_p (expr1->ref, &c) || c))
9539 return true;
9541 /* Need a temporary if EXPR1 can't be expressed as a descriptor. */
9542 if (gfc_ref_needs_temporary_p (expr1->ref))
9543 return true;
9545 /* Functions returning pointers or allocatables need temporaries. */
9546 c = expr2->value.function.esym
9547 ? (expr2->value.function.esym->attr.pointer
9548 || expr2->value.function.esym->attr.allocatable)
9549 : (expr2->symtree->n.sym->attr.pointer
9550 || expr2->symtree->n.sym->attr.allocatable);
9551 if (c)
9552 return true;
9554 /* Character array functions need temporaries unless the
9555 character lengths are the same. */
9556 if (expr2->ts.type == BT_CHARACTER && expr2->rank > 0)
9558 if (expr1->ts.u.cl->length == NULL
9559 || expr1->ts.u.cl->length->expr_type != EXPR_CONSTANT)
9560 return true;
9562 if (expr2->ts.u.cl->length == NULL
9563 || expr2->ts.u.cl->length->expr_type != EXPR_CONSTANT)
9564 return true;
9566 if (mpz_cmp (expr1->ts.u.cl->length->value.integer,
9567 expr2->ts.u.cl->length->value.integer) != 0)
9568 return true;
9571 /* Check that no LHS component references appear during an array
9572 reference. This is needed because we do not have the means to
9573 span any arbitrary stride with an array descriptor. This check
9574 is not needed for the rhs because the function result has to be
9575 a complete type. */
9576 seen_array_ref = false;
9577 for (ref = expr1->ref; ref; ref = ref->next)
9579 if (ref->type == REF_ARRAY)
9580 seen_array_ref= true;
9581 else if (ref->type == REF_COMPONENT && seen_array_ref)
9582 return true;
9585 /* Check for a dependency. */
9586 if (gfc_check_fncall_dependency (expr1, INTENT_OUT,
9587 expr2->value.function.esym,
9588 expr2->value.function.actual,
9589 NOT_ELEMENTAL))
9590 return true;
9592 /* If we have reached here with an intrinsic function, we do not
9593 need a temporary except in the particular case that reallocation
9594 on assignment is active and the lhs is allocatable and a target. */
9595 if (expr2->value.function.isym)
9596 return (flag_realloc_lhs && sym->attr.allocatable && sym->attr.target);
9598 /* If the LHS is a dummy, we need a temporary if it is not
9599 INTENT(OUT). */
9600 if (sym->attr.dummy && sym->attr.intent != INTENT_OUT)
9601 return true;
9603 /* If the lhs has been host_associated, is in common, a pointer or is
9604 a target and the function is not using a RESULT variable, aliasing
9605 can occur and a temporary is needed. */
9606 if ((sym->attr.host_assoc
9607 || sym->attr.in_common
9608 || sym->attr.pointer
9609 || sym->attr.cray_pointee
9610 || sym->attr.target)
9611 && expr2->symtree != NULL
9612 && expr2->symtree->n.sym == expr2->symtree->n.sym->result)
9613 return true;
9615 /* A PURE function can unconditionally be called without a temporary. */
9616 if (expr2->value.function.esym != NULL
9617 && expr2->value.function.esym->attr.pure)
9618 return false;
9620 /* Implicit_pure functions are those which could legally be declared
9621 to be PURE. */
9622 if (expr2->value.function.esym != NULL
9623 && expr2->value.function.esym->attr.implicit_pure)
9624 return false;
9626 if (!sym->attr.use_assoc
9627 && !sym->attr.in_common
9628 && !sym->attr.pointer
9629 && !sym->attr.target
9630 && !sym->attr.cray_pointee
9631 && expr2->value.function.esym)
9633 /* A temporary is not needed if the function is not contained and
9634 the variable is local or host associated and not a pointer or
9635 a target. */
9636 if (!expr2->value.function.esym->attr.contained)
9637 return false;
9639 /* A temporary is not needed if the lhs has never been host
9640 associated and the procedure is contained. */
9641 else if (!sym->attr.host_assoc)
9642 return false;
9644 /* A temporary is not needed if the variable is local and not
9645 a pointer, a target or a result. */
9646 if (sym->ns->parent
9647 && expr2->value.function.esym->ns == sym->ns->parent)
9648 return false;
9651 /* Default to temporary use. */
9652 return true;
9656 /* Provide the loop info so that the lhs descriptor can be built for
9657 reallocatable assignments from extrinsic function calls. */
9659 static void
9660 realloc_lhs_loop_for_fcn_call (gfc_se *se, locus *where, gfc_ss **ss,
9661 gfc_loopinfo *loop)
9663 /* Signal that the function call should not be made by
9664 gfc_conv_loop_setup. */
9665 se->ss->is_alloc_lhs = 1;
9666 gfc_init_loopinfo (loop);
9667 gfc_add_ss_to_loop (loop, *ss);
9668 gfc_add_ss_to_loop (loop, se->ss);
9669 gfc_conv_ss_startstride (loop);
9670 gfc_conv_loop_setup (loop, where);
9671 gfc_copy_loopinfo_to_se (se, loop);
9672 gfc_add_block_to_block (&se->pre, &loop->pre);
9673 gfc_add_block_to_block (&se->pre, &loop->post);
9674 se->ss->is_alloc_lhs = 0;
9678 /* For assignment to a reallocatable lhs from intrinsic functions,
9679 replace the se.expr (ie. the result) with a temporary descriptor.
9680 Null the data field so that the library allocates space for the
9681 result. Free the data of the original descriptor after the function,
9682 in case it appears in an argument expression and transfer the
9683 result to the original descriptor. */
9685 static void
9686 fcncall_realloc_result (gfc_se *se, int rank)
9688 tree desc;
9689 tree res_desc;
9690 tree tmp;
9691 tree offset;
9692 tree zero_cond;
9693 int n;
9695 /* Use the allocation done by the library. Substitute the lhs
9696 descriptor with a copy, whose data field is nulled.*/
9697 desc = build_fold_indirect_ref_loc (input_location, se->expr);
9698 if (POINTER_TYPE_P (TREE_TYPE (desc)))
9699 desc = build_fold_indirect_ref_loc (input_location, desc);
9701 /* Unallocated, the descriptor does not have a dtype. */
9702 tmp = gfc_conv_descriptor_dtype (desc);
9703 gfc_add_modify (&se->pre, tmp, gfc_get_dtype (TREE_TYPE (desc)));
9705 res_desc = gfc_evaluate_now (desc, &se->pre);
9706 gfc_conv_descriptor_data_set (&se->pre, res_desc, null_pointer_node);
9707 se->expr = gfc_build_addr_expr (NULL_TREE, res_desc);
9709 /* Free the lhs after the function call and copy the result data to
9710 the lhs descriptor. */
9711 tmp = gfc_conv_descriptor_data_get (desc);
9712 zero_cond = fold_build2_loc (input_location, EQ_EXPR,
9713 logical_type_node, tmp,
9714 build_int_cst (TREE_TYPE (tmp), 0));
9715 zero_cond = gfc_evaluate_now (zero_cond, &se->post);
9716 tmp = gfc_call_free (tmp);
9717 gfc_add_expr_to_block (&se->post, tmp);
9719 tmp = gfc_conv_descriptor_data_get (res_desc);
9720 gfc_conv_descriptor_data_set (&se->post, desc, tmp);
9722 /* Check that the shapes are the same between lhs and expression. */
9723 for (n = 0 ; n < rank; n++)
9725 tree tmp1;
9726 tmp = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[n]);
9727 tmp1 = gfc_conv_descriptor_lbound_get (res_desc, gfc_rank_cst[n]);
9728 tmp = fold_build2_loc (input_location, MINUS_EXPR,
9729 gfc_array_index_type, tmp, tmp1);
9730 tmp1 = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[n]);
9731 tmp = fold_build2_loc (input_location, MINUS_EXPR,
9732 gfc_array_index_type, tmp, tmp1);
9733 tmp1 = gfc_conv_descriptor_ubound_get (res_desc, gfc_rank_cst[n]);
9734 tmp = fold_build2_loc (input_location, PLUS_EXPR,
9735 gfc_array_index_type, tmp, tmp1);
9736 tmp = fold_build2_loc (input_location, NE_EXPR,
9737 logical_type_node, tmp,
9738 gfc_index_zero_node);
9739 tmp = gfc_evaluate_now (tmp, &se->post);
9740 zero_cond = fold_build2_loc (input_location, TRUTH_OR_EXPR,
9741 logical_type_node, tmp,
9742 zero_cond);
9745 /* 'zero_cond' being true is equal to lhs not being allocated or the
9746 shapes being different. */
9747 zero_cond = gfc_evaluate_now (zero_cond, &se->post);
9749 /* Now reset the bounds returned from the function call to bounds based
9750 on the lhs lbounds, except where the lhs is not allocated or the shapes
9751 of 'variable and 'expr' are different. Set the offset accordingly. */
9752 offset = gfc_index_zero_node;
9753 for (n = 0 ; n < rank; n++)
9755 tree lbound;
9757 lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[n]);
9758 lbound = fold_build3_loc (input_location, COND_EXPR,
9759 gfc_array_index_type, zero_cond,
9760 gfc_index_one_node, lbound);
9761 lbound = gfc_evaluate_now (lbound, &se->post);
9763 tmp = gfc_conv_descriptor_ubound_get (res_desc, gfc_rank_cst[n]);
9764 tmp = fold_build2_loc (input_location, PLUS_EXPR,
9765 gfc_array_index_type, tmp, lbound);
9766 gfc_conv_descriptor_lbound_set (&se->post, desc,
9767 gfc_rank_cst[n], lbound);
9768 gfc_conv_descriptor_ubound_set (&se->post, desc,
9769 gfc_rank_cst[n], tmp);
9771 /* Set stride and accumulate the offset. */
9772 tmp = gfc_conv_descriptor_stride_get (res_desc, gfc_rank_cst[n]);
9773 gfc_conv_descriptor_stride_set (&se->post, desc,
9774 gfc_rank_cst[n], tmp);
9775 tmp = fold_build2_loc (input_location, MULT_EXPR,
9776 gfc_array_index_type, lbound, tmp);
9777 offset = fold_build2_loc (input_location, MINUS_EXPR,
9778 gfc_array_index_type, offset, tmp);
9779 offset = gfc_evaluate_now (offset, &se->post);
9782 gfc_conv_descriptor_offset_set (&se->post, desc, offset);
9787 /* Try to translate array(:) = func (...), where func is a transformational
9788 array function, without using a temporary. Returns NULL if this isn't the
9789 case. */
9791 static tree
9792 gfc_trans_arrayfunc_assign (gfc_expr * expr1, gfc_expr * expr2)
9794 gfc_se se;
9795 gfc_ss *ss = NULL;
9796 gfc_component *comp = NULL;
9797 gfc_loopinfo loop;
9799 if (arrayfunc_assign_needs_temporary (expr1, expr2))
9800 return NULL;
9802 /* The frontend doesn't seem to bother filling in expr->symtree for intrinsic
9803 functions. */
9804 comp = gfc_get_proc_ptr_comp (expr2);
9806 if (!(expr2->value.function.isym
9807 || (comp && comp->attr.dimension)
9808 || (!comp && gfc_return_by_reference (expr2->value.function.esym)
9809 && expr2->value.function.esym->result->attr.dimension)))
9810 return NULL;
9812 gfc_init_se (&se, NULL);
9813 gfc_start_block (&se.pre);
9814 se.want_pointer = 1;
9816 gfc_conv_array_parameter (&se, expr1, false, NULL, NULL, NULL);
9818 if (expr1->ts.type == BT_DERIVED
9819 && expr1->ts.u.derived->attr.alloc_comp)
9821 tree tmp;
9822 tmp = gfc_deallocate_alloc_comp_no_caf (expr1->ts.u.derived, se.expr,
9823 expr1->rank);
9824 gfc_add_expr_to_block (&se.pre, tmp);
9827 se.direct_byref = 1;
9828 se.ss = gfc_walk_expr (expr2);
9829 gcc_assert (se.ss != gfc_ss_terminator);
9831 /* Reallocate on assignment needs the loopinfo for extrinsic functions.
9832 This is signalled to gfc_conv_procedure_call by setting is_alloc_lhs.
9833 Clearly, this cannot be done for an allocatable function result, since
9834 the shape of the result is unknown and, in any case, the function must
9835 correctly take care of the reallocation internally. For intrinsic
9836 calls, the array data is freed and the library takes care of allocation.
9837 TODO: Add logic of trans-array.c: gfc_alloc_allocatable_for_assignment
9838 to the library. */
9839 if (flag_realloc_lhs
9840 && gfc_is_reallocatable_lhs (expr1)
9841 && !gfc_expr_attr (expr1).codimension
9842 && !gfc_is_coindexed (expr1)
9843 && !(expr2->value.function.esym
9844 && expr2->value.function.esym->result->attr.allocatable))
9846 realloc_lhs_warning (expr1->ts.type, true, &expr1->where);
9848 if (!expr2->value.function.isym)
9850 ss = gfc_walk_expr (expr1);
9851 gcc_assert (ss != gfc_ss_terminator);
9853 realloc_lhs_loop_for_fcn_call (&se, &expr1->where, &ss, &loop);
9854 ss->is_alloc_lhs = 1;
9856 else
9857 fcncall_realloc_result (&se, expr1->rank);
9860 gfc_conv_function_expr (&se, expr2);
9861 gfc_add_block_to_block (&se.pre, &se.post);
9863 if (ss)
9864 gfc_cleanup_loop (&loop);
9865 else
9866 gfc_free_ss_chain (se.ss);
9868 return gfc_finish_block (&se.pre);
9872 /* Try to efficiently translate array(:) = 0. Return NULL if this
9873 can't be done. */
9875 static tree
9876 gfc_trans_zero_assign (gfc_expr * expr)
9878 tree dest, len, type;
9879 tree tmp;
9880 gfc_symbol *sym;
9882 sym = expr->symtree->n.sym;
9883 dest = gfc_get_symbol_decl (sym);
9885 type = TREE_TYPE (dest);
9886 if (POINTER_TYPE_P (type))
9887 type = TREE_TYPE (type);
9888 if (!GFC_ARRAY_TYPE_P (type))
9889 return NULL_TREE;
9891 /* Determine the length of the array. */
9892 len = GFC_TYPE_ARRAY_SIZE (type);
9893 if (!len || TREE_CODE (len) != INTEGER_CST)
9894 return NULL_TREE;
9896 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type));
9897 len = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type, len,
9898 fold_convert (gfc_array_index_type, tmp));
9900 /* If we are zeroing a local array avoid taking its address by emitting
9901 a = {} instead. */
9902 if (!POINTER_TYPE_P (TREE_TYPE (dest)))
9903 return build2_loc (input_location, MODIFY_EXPR, void_type_node,
9904 dest, build_constructor (TREE_TYPE (dest),
9905 NULL));
9907 /* Convert arguments to the correct types. */
9908 dest = fold_convert (pvoid_type_node, dest);
9909 len = fold_convert (size_type_node, len);
9911 /* Construct call to __builtin_memset. */
9912 tmp = build_call_expr_loc (input_location,
9913 builtin_decl_explicit (BUILT_IN_MEMSET),
9914 3, dest, integer_zero_node, len);
9915 return fold_convert (void_type_node, tmp);
9919 /* Helper for gfc_trans_array_copy and gfc_trans_array_constructor_copy
9920 that constructs the call to __builtin_memcpy. */
9922 tree
9923 gfc_build_memcpy_call (tree dst, tree src, tree len)
9925 tree tmp;
9927 /* Convert arguments to the correct types. */
9928 if (!POINTER_TYPE_P (TREE_TYPE (dst)))
9929 dst = gfc_build_addr_expr (pvoid_type_node, dst);
9930 else
9931 dst = fold_convert (pvoid_type_node, dst);
9933 if (!POINTER_TYPE_P (TREE_TYPE (src)))
9934 src = gfc_build_addr_expr (pvoid_type_node, src);
9935 else
9936 src = fold_convert (pvoid_type_node, src);
9938 len = fold_convert (size_type_node, len);
9940 /* Construct call to __builtin_memcpy. */
9941 tmp = build_call_expr_loc (input_location,
9942 builtin_decl_explicit (BUILT_IN_MEMCPY),
9943 3, dst, src, len);
9944 return fold_convert (void_type_node, tmp);
9948 /* Try to efficiently translate dst(:) = src(:). Return NULL if this
9949 can't be done. EXPR1 is the destination/lhs and EXPR2 is the
9950 source/rhs, both are gfc_full_array_ref_p which have been checked for
9951 dependencies. */
9953 static tree
9954 gfc_trans_array_copy (gfc_expr * expr1, gfc_expr * expr2)
9956 tree dst, dlen, dtype;
9957 tree src, slen, stype;
9958 tree tmp;
9960 dst = gfc_get_symbol_decl (expr1->symtree->n.sym);
9961 src = gfc_get_symbol_decl (expr2->symtree->n.sym);
9963 dtype = TREE_TYPE (dst);
9964 if (POINTER_TYPE_P (dtype))
9965 dtype = TREE_TYPE (dtype);
9966 stype = TREE_TYPE (src);
9967 if (POINTER_TYPE_P (stype))
9968 stype = TREE_TYPE (stype);
9970 if (!GFC_ARRAY_TYPE_P (dtype) || !GFC_ARRAY_TYPE_P (stype))
9971 return NULL_TREE;
9973 /* Determine the lengths of the arrays. */
9974 dlen = GFC_TYPE_ARRAY_SIZE (dtype);
9975 if (!dlen || TREE_CODE (dlen) != INTEGER_CST)
9976 return NULL_TREE;
9977 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (dtype));
9978 dlen = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
9979 dlen, fold_convert (gfc_array_index_type, tmp));
9981 slen = GFC_TYPE_ARRAY_SIZE (stype);
9982 if (!slen || TREE_CODE (slen) != INTEGER_CST)
9983 return NULL_TREE;
9984 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (stype));
9985 slen = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
9986 slen, fold_convert (gfc_array_index_type, tmp));
9988 /* Sanity check that they are the same. This should always be
9989 the case, as we should already have checked for conformance. */
9990 if (!tree_int_cst_equal (slen, dlen))
9991 return NULL_TREE;
9993 return gfc_build_memcpy_call (dst, src, dlen);
9997 /* Try to efficiently translate array(:) = (/ ... /). Return NULL if
9998 this can't be done. EXPR1 is the destination/lhs for which
9999 gfc_full_array_ref_p is true, and EXPR2 is the source/rhs. */
10001 static tree
10002 gfc_trans_array_constructor_copy (gfc_expr * expr1, gfc_expr * expr2)
10004 unsigned HOST_WIDE_INT nelem;
10005 tree dst, dtype;
10006 tree src, stype;
10007 tree len;
10008 tree tmp;
10010 nelem = gfc_constant_array_constructor_p (expr2->value.constructor);
10011 if (nelem == 0)
10012 return NULL_TREE;
10014 dst = gfc_get_symbol_decl (expr1->symtree->n.sym);
10015 dtype = TREE_TYPE (dst);
10016 if (POINTER_TYPE_P (dtype))
10017 dtype = TREE_TYPE (dtype);
10018 if (!GFC_ARRAY_TYPE_P (dtype))
10019 return NULL_TREE;
10021 /* Determine the lengths of the array. */
10022 len = GFC_TYPE_ARRAY_SIZE (dtype);
10023 if (!len || TREE_CODE (len) != INTEGER_CST)
10024 return NULL_TREE;
10026 /* Confirm that the constructor is the same size. */
10027 if (compare_tree_int (len, nelem) != 0)
10028 return NULL_TREE;
10030 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (dtype));
10031 len = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type, len,
10032 fold_convert (gfc_array_index_type, tmp));
10034 stype = gfc_typenode_for_spec (&expr2->ts);
10035 src = gfc_build_constant_array_constructor (expr2, stype);
10037 stype = TREE_TYPE (src);
10038 if (POINTER_TYPE_P (stype))
10039 stype = TREE_TYPE (stype);
10041 return gfc_build_memcpy_call (dst, src, len);
10045 /* Tells whether the expression is to be treated as a variable reference. */
10047 bool
10048 gfc_expr_is_variable (gfc_expr *expr)
10050 gfc_expr *arg;
10051 gfc_component *comp;
10052 gfc_symbol *func_ifc;
10054 if (expr->expr_type == EXPR_VARIABLE)
10055 return true;
10057 arg = gfc_get_noncopying_intrinsic_argument (expr);
10058 if (arg)
10060 gcc_assert (expr->value.function.isym->id == GFC_ISYM_TRANSPOSE);
10061 return gfc_expr_is_variable (arg);
10064 /* A data-pointer-returning function should be considered as a variable
10065 too. */
10066 if (expr->expr_type == EXPR_FUNCTION
10067 && expr->ref == NULL)
10069 if (expr->value.function.isym != NULL)
10070 return false;
10072 if (expr->value.function.esym != NULL)
10074 func_ifc = expr->value.function.esym;
10075 goto found_ifc;
10077 else
10079 gcc_assert (expr->symtree);
10080 func_ifc = expr->symtree->n.sym;
10081 goto found_ifc;
10084 gcc_unreachable ();
10087 comp = gfc_get_proc_ptr_comp (expr);
10088 if ((expr->expr_type == EXPR_PPC || expr->expr_type == EXPR_FUNCTION)
10089 && comp)
10091 func_ifc = comp->ts.interface;
10092 goto found_ifc;
10095 if (expr->expr_type == EXPR_COMPCALL)
10097 gcc_assert (!expr->value.compcall.tbp->is_generic);
10098 func_ifc = expr->value.compcall.tbp->u.specific->n.sym;
10099 goto found_ifc;
10102 return false;
10104 found_ifc:
10105 gcc_assert (func_ifc->attr.function
10106 && func_ifc->result != NULL);
10107 return func_ifc->result->attr.pointer;
10111 /* Is the lhs OK for automatic reallocation? */
10113 static bool
10114 is_scalar_reallocatable_lhs (gfc_expr *expr)
10116 gfc_ref * ref;
10118 /* An allocatable variable with no reference. */
10119 if (expr->symtree->n.sym->attr.allocatable
10120 && !expr->ref)
10121 return true;
10123 /* All that can be left are allocatable components. However, we do
10124 not check for allocatable components here because the expression
10125 could be an allocatable component of a pointer component. */
10126 if (expr->symtree->n.sym->ts.type != BT_DERIVED
10127 && expr->symtree->n.sym->ts.type != BT_CLASS)
10128 return false;
10130 /* Find an allocatable component ref last. */
10131 for (ref = expr->ref; ref; ref = ref->next)
10132 if (ref->type == REF_COMPONENT
10133 && !ref->next
10134 && ref->u.c.component->attr.allocatable)
10135 return true;
10137 return false;
10141 /* Allocate or reallocate scalar lhs, as necessary. */
10143 static void
10144 alloc_scalar_allocatable_for_assignment (stmtblock_t *block,
10145 tree string_length,
10146 gfc_expr *expr1,
10147 gfc_expr *expr2)
10150 tree cond;
10151 tree tmp;
10152 tree size;
10153 tree size_in_bytes;
10154 tree jump_label1;
10155 tree jump_label2;
10156 gfc_se lse;
10157 gfc_ref *ref;
10159 if (!expr1 || expr1->rank)
10160 return;
10162 if (!expr2 || expr2->rank)
10163 return;
10165 for (ref = expr1->ref; ref; ref = ref->next)
10166 if (ref->type == REF_SUBSTRING)
10167 return;
10169 realloc_lhs_warning (expr2->ts.type, false, &expr2->where);
10171 /* Since this is a scalar lhs, we can afford to do this. That is,
10172 there is no risk of side effects being repeated. */
10173 gfc_init_se (&lse, NULL);
10174 lse.want_pointer = 1;
10175 gfc_conv_expr (&lse, expr1);
10177 jump_label1 = gfc_build_label_decl (NULL_TREE);
10178 jump_label2 = gfc_build_label_decl (NULL_TREE);
10180 /* Do the allocation if the lhs is NULL. Otherwise go to label 1. */
10181 tmp = build_int_cst (TREE_TYPE (lse.expr), 0);
10182 cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
10183 lse.expr, tmp);
10184 tmp = build3_v (COND_EXPR, cond,
10185 build1_v (GOTO_EXPR, jump_label1),
10186 build_empty_stmt (input_location));
10187 gfc_add_expr_to_block (block, tmp);
10189 if (expr1->ts.type == BT_CHARACTER && expr1->ts.deferred)
10191 /* Use the rhs string length and the lhs element size. */
10192 size = string_length;
10193 tmp = TREE_TYPE (gfc_typenode_for_spec (&expr1->ts));
10194 tmp = TYPE_SIZE_UNIT (tmp);
10195 size_in_bytes = fold_build2_loc (input_location, MULT_EXPR,
10196 TREE_TYPE (tmp), tmp,
10197 fold_convert (TREE_TYPE (tmp), size));
10199 else
10201 /* Otherwise use the length in bytes of the rhs. */
10202 size = TYPE_SIZE_UNIT (gfc_typenode_for_spec (&expr1->ts));
10203 size_in_bytes = size;
10206 size_in_bytes = fold_build2_loc (input_location, MAX_EXPR, size_type_node,
10207 size_in_bytes, size_one_node);
10209 if (gfc_caf_attr (expr1).codimension && flag_coarray == GFC_FCOARRAY_LIB)
10211 tree caf_decl, token;
10212 gfc_se caf_se;
10213 symbol_attribute attr;
10215 gfc_clear_attr (&attr);
10216 gfc_init_se (&caf_se, NULL);
10218 caf_decl = gfc_get_tree_for_caf_expr (expr1);
10219 gfc_get_caf_token_offset (&caf_se, &token, NULL, caf_decl, NULL_TREE,
10220 NULL);
10221 gfc_add_block_to_block (block, &caf_se.pre);
10222 gfc_allocate_allocatable (block, lse.expr, size_in_bytes,
10223 gfc_build_addr_expr (NULL_TREE, token),
10224 NULL_TREE, NULL_TREE, NULL_TREE, jump_label1,
10225 expr1, 1);
10227 else if (expr1->ts.type == BT_DERIVED && expr1->ts.u.derived->attr.alloc_comp)
10229 tmp = build_call_expr_loc (input_location,
10230 builtin_decl_explicit (BUILT_IN_CALLOC),
10231 2, build_one_cst (size_type_node),
10232 size_in_bytes);
10233 tmp = fold_convert (TREE_TYPE (lse.expr), tmp);
10234 gfc_add_modify (block, lse.expr, tmp);
10236 else
10238 tmp = build_call_expr_loc (input_location,
10239 builtin_decl_explicit (BUILT_IN_MALLOC),
10240 1, size_in_bytes);
10241 tmp = fold_convert (TREE_TYPE (lse.expr), tmp);
10242 gfc_add_modify (block, lse.expr, tmp);
10245 if (expr1->ts.type == BT_CHARACTER && expr1->ts.deferred)
10247 /* Deferred characters need checking for lhs and rhs string
10248 length. Other deferred parameter variables will have to
10249 come here too. */
10250 tmp = build1_v (GOTO_EXPR, jump_label2);
10251 gfc_add_expr_to_block (block, tmp);
10253 tmp = build1_v (LABEL_EXPR, jump_label1);
10254 gfc_add_expr_to_block (block, tmp);
10256 /* For a deferred length character, reallocate if lengths of lhs and
10257 rhs are different. */
10258 if (expr1->ts.type == BT_CHARACTER && expr1->ts.deferred)
10260 cond = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
10261 lse.string_length,
10262 fold_convert (TREE_TYPE (lse.string_length),
10263 size));
10264 /* Jump past the realloc if the lengths are the same. */
10265 tmp = build3_v (COND_EXPR, cond,
10266 build1_v (GOTO_EXPR, jump_label2),
10267 build_empty_stmt (input_location));
10268 gfc_add_expr_to_block (block, tmp);
10269 tmp = build_call_expr_loc (input_location,
10270 builtin_decl_explicit (BUILT_IN_REALLOC),
10271 2, fold_convert (pvoid_type_node, lse.expr),
10272 size_in_bytes);
10273 tmp = fold_convert (TREE_TYPE (lse.expr), tmp);
10274 gfc_add_modify (block, lse.expr, tmp);
10275 tmp = build1_v (LABEL_EXPR, jump_label2);
10276 gfc_add_expr_to_block (block, tmp);
10278 /* Update the lhs character length. */
10279 size = string_length;
10280 gfc_add_modify (block, lse.string_length,
10281 fold_convert (TREE_TYPE (lse.string_length), size));
10285 /* Check for assignments of the type
10287 a = a + 4
10289 to make sure we do not check for reallocation unneccessarily. */
10292 static bool
10293 is_runtime_conformable (gfc_expr *expr1, gfc_expr *expr2)
10295 gfc_actual_arglist *a;
10296 gfc_expr *e1, *e2;
10298 switch (expr2->expr_type)
10300 case EXPR_VARIABLE:
10301 return gfc_dep_compare_expr (expr1, expr2) == 0;
10303 case EXPR_FUNCTION:
10304 if (expr2->value.function.esym
10305 && expr2->value.function.esym->attr.elemental)
10307 for (a = expr2->value.function.actual; a != NULL; a = a->next)
10309 e1 = a->expr;
10310 if (e1 && e1->rank > 0 && !is_runtime_conformable (expr1, e1))
10311 return false;
10313 return true;
10315 else if (expr2->value.function.isym
10316 && expr2->value.function.isym->elemental)
10318 for (a = expr2->value.function.actual; a != NULL; a = a->next)
10320 e1 = a->expr;
10321 if (e1 && e1->rank > 0 && !is_runtime_conformable (expr1, e1))
10322 return false;
10324 return true;
10327 break;
10329 case EXPR_OP:
10330 switch (expr2->value.op.op)
10332 case INTRINSIC_NOT:
10333 case INTRINSIC_UPLUS:
10334 case INTRINSIC_UMINUS:
10335 case INTRINSIC_PARENTHESES:
10336 return is_runtime_conformable (expr1, expr2->value.op.op1);
10338 case INTRINSIC_PLUS:
10339 case INTRINSIC_MINUS:
10340 case INTRINSIC_TIMES:
10341 case INTRINSIC_DIVIDE:
10342 case INTRINSIC_POWER:
10343 case INTRINSIC_AND:
10344 case INTRINSIC_OR:
10345 case INTRINSIC_EQV:
10346 case INTRINSIC_NEQV:
10347 case INTRINSIC_EQ:
10348 case INTRINSIC_NE:
10349 case INTRINSIC_GT:
10350 case INTRINSIC_GE:
10351 case INTRINSIC_LT:
10352 case INTRINSIC_LE:
10353 case INTRINSIC_EQ_OS:
10354 case INTRINSIC_NE_OS:
10355 case INTRINSIC_GT_OS:
10356 case INTRINSIC_GE_OS:
10357 case INTRINSIC_LT_OS:
10358 case INTRINSIC_LE_OS:
10360 e1 = expr2->value.op.op1;
10361 e2 = expr2->value.op.op2;
10363 if (e1->rank == 0 && e2->rank > 0)
10364 return is_runtime_conformable (expr1, e2);
10365 else if (e1->rank > 0 && e2->rank == 0)
10366 return is_runtime_conformable (expr1, e1);
10367 else if (e1->rank > 0 && e2->rank > 0)
10368 return is_runtime_conformable (expr1, e1)
10369 && is_runtime_conformable (expr1, e2);
10370 break;
10372 default:
10373 break;
10377 break;
10379 default:
10380 break;
10382 return false;
10386 static tree
10387 trans_class_assignment (stmtblock_t *block, gfc_expr *lhs, gfc_expr *rhs,
10388 gfc_se *lse, gfc_se *rse, bool use_vptr_copy,
10389 bool class_realloc)
10391 tree tmp, fcn, stdcopy, to_len, from_len, vptr;
10392 vec<tree, va_gc> *args = NULL;
10394 vptr = trans_class_vptr_len_assignment (block, lhs, rhs, rse, &to_len,
10395 &from_len);
10397 /* Generate allocation of the lhs. */
10398 if (class_realloc)
10400 stmtblock_t alloc;
10401 tree class_han;
10403 tmp = gfc_vptr_size_get (vptr);
10404 class_han = GFC_CLASS_TYPE_P (TREE_TYPE (lse->expr))
10405 ? gfc_class_data_get (lse->expr) : lse->expr;
10406 gfc_init_block (&alloc);
10407 gfc_allocate_using_malloc (&alloc, class_han, tmp, NULL_TREE);
10408 tmp = fold_build2_loc (input_location, EQ_EXPR,
10409 logical_type_node, class_han,
10410 build_int_cst (prvoid_type_node, 0));
10411 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
10412 gfc_unlikely (tmp,
10413 PRED_FORTRAN_FAIL_ALLOC),
10414 gfc_finish_block (&alloc),
10415 build_empty_stmt (input_location));
10416 gfc_add_expr_to_block (&lse->pre, tmp);
10419 fcn = gfc_vptr_copy_get (vptr);
10421 tmp = GFC_CLASS_TYPE_P (TREE_TYPE (rse->expr))
10422 ? gfc_class_data_get (rse->expr) : rse->expr;
10423 if (use_vptr_copy)
10425 if (!POINTER_TYPE_P (TREE_TYPE (tmp))
10426 || INDIRECT_REF_P (tmp)
10427 || (rhs->ts.type == BT_DERIVED
10428 && rhs->ts.u.derived->attr.unlimited_polymorphic
10429 && !rhs->ts.u.derived->attr.pointer
10430 && !rhs->ts.u.derived->attr.allocatable)
10431 || (UNLIMITED_POLY (rhs)
10432 && !CLASS_DATA (rhs)->attr.pointer
10433 && !CLASS_DATA (rhs)->attr.allocatable))
10434 vec_safe_push (args, gfc_build_addr_expr (NULL_TREE, tmp));
10435 else
10436 vec_safe_push (args, tmp);
10437 tmp = GFC_CLASS_TYPE_P (TREE_TYPE (lse->expr))
10438 ? gfc_class_data_get (lse->expr) : lse->expr;
10439 if (!POINTER_TYPE_P (TREE_TYPE (tmp))
10440 || INDIRECT_REF_P (tmp)
10441 || (lhs->ts.type == BT_DERIVED
10442 && lhs->ts.u.derived->attr.unlimited_polymorphic
10443 && !lhs->ts.u.derived->attr.pointer
10444 && !lhs->ts.u.derived->attr.allocatable)
10445 || (UNLIMITED_POLY (lhs)
10446 && !CLASS_DATA (lhs)->attr.pointer
10447 && !CLASS_DATA (lhs)->attr.allocatable))
10448 vec_safe_push (args, gfc_build_addr_expr (NULL_TREE, tmp));
10449 else
10450 vec_safe_push (args, tmp);
10452 stdcopy = build_call_vec (TREE_TYPE (TREE_TYPE (fcn)), fcn, args);
10454 if (to_len != NULL_TREE && !integer_zerop (from_len))
10456 tree extcopy;
10457 vec_safe_push (args, from_len);
10458 vec_safe_push (args, to_len);
10459 extcopy = build_call_vec (TREE_TYPE (TREE_TYPE (fcn)), fcn, args);
10461 tmp = fold_build2_loc (input_location, GT_EXPR,
10462 logical_type_node, from_len,
10463 build_zero_cst (TREE_TYPE (from_len)));
10464 return fold_build3_loc (input_location, COND_EXPR,
10465 void_type_node, tmp,
10466 extcopy, stdcopy);
10468 else
10469 return stdcopy;
10471 else
10473 tree rhst = GFC_CLASS_TYPE_P (TREE_TYPE (lse->expr))
10474 ? gfc_class_data_get (lse->expr) : lse->expr;
10475 stmtblock_t tblock;
10476 gfc_init_block (&tblock);
10477 if (!POINTER_TYPE_P (TREE_TYPE (tmp)))
10478 tmp = gfc_build_addr_expr (NULL_TREE, tmp);
10479 if (!POINTER_TYPE_P (TREE_TYPE (rhst)))
10480 rhst = gfc_build_addr_expr (NULL_TREE, rhst);
10481 /* When coming from a ptr_copy lhs and rhs are swapped. */
10482 gfc_add_modify_loc (input_location, &tblock, rhst,
10483 fold_convert (TREE_TYPE (rhst), tmp));
10484 return gfc_finish_block (&tblock);
10488 /* Subroutine of gfc_trans_assignment that actually scalarizes the
10489 assignment. EXPR1 is the destination/LHS and EXPR2 is the source/RHS.
10490 init_flag indicates initialization expressions and dealloc that no
10491 deallocate prior assignment is needed (if in doubt, set true).
10492 When PTR_COPY is set and expr1 is a class type, then use the _vptr-copy
10493 routine instead of a pointer assignment. Alias resolution is only done,
10494 when MAY_ALIAS is set (the default). This flag is used by ALLOCATE()
10495 where it is known, that newly allocated memory on the lhs can never be
10496 an alias of the rhs. */
10498 static tree
10499 gfc_trans_assignment_1 (gfc_expr * expr1, gfc_expr * expr2, bool init_flag,
10500 bool dealloc, bool use_vptr_copy, bool may_alias)
10502 gfc_se lse;
10503 gfc_se rse;
10504 gfc_ss *lss;
10505 gfc_ss *lss_section;
10506 gfc_ss *rss;
10507 gfc_loopinfo loop;
10508 tree tmp;
10509 stmtblock_t block;
10510 stmtblock_t body;
10511 bool l_is_temp;
10512 bool scalar_to_array;
10513 tree string_length;
10514 int n;
10515 bool maybe_workshare = false, lhs_refs_comp = false, rhs_refs_comp = false;
10516 symbol_attribute lhs_caf_attr, rhs_caf_attr, lhs_attr;
10517 bool is_poly_assign;
10519 /* Assignment of the form lhs = rhs. */
10520 gfc_start_block (&block);
10522 gfc_init_se (&lse, NULL);
10523 gfc_init_se (&rse, NULL);
10525 /* Walk the lhs. */
10526 lss = gfc_walk_expr (expr1);
10527 if (gfc_is_reallocatable_lhs (expr1))
10529 lss->no_bounds_check = 1;
10530 if (!(expr2->expr_type == EXPR_FUNCTION
10531 && expr2->value.function.isym != NULL
10532 && !(expr2->value.function.isym->elemental
10533 || expr2->value.function.isym->conversion)))
10534 lss->is_alloc_lhs = 1;
10536 else
10537 lss->no_bounds_check = expr1->no_bounds_check;
10539 rss = NULL;
10541 if ((expr1->ts.type == BT_DERIVED)
10542 && (gfc_is_class_array_function (expr2)
10543 || gfc_is_alloc_class_scalar_function (expr2)))
10544 expr2->must_finalize = 1;
10546 /* Checking whether a class assignment is desired is quite complicated and
10547 needed at two locations, so do it once only before the information is
10548 needed. */
10549 lhs_attr = gfc_expr_attr (expr1);
10550 is_poly_assign = (use_vptr_copy || lhs_attr.pointer
10551 || (lhs_attr.allocatable && !lhs_attr.dimension))
10552 && (expr1->ts.type == BT_CLASS
10553 || gfc_is_class_array_ref (expr1, NULL)
10554 || gfc_is_class_scalar_expr (expr1)
10555 || gfc_is_class_array_ref (expr2, NULL)
10556 || gfc_is_class_scalar_expr (expr2));
10559 /* Only analyze the expressions for coarray properties, when in coarray-lib
10560 mode. */
10561 if (flag_coarray == GFC_FCOARRAY_LIB)
10563 lhs_caf_attr = gfc_caf_attr (expr1, false, &lhs_refs_comp);
10564 rhs_caf_attr = gfc_caf_attr (expr2, false, &rhs_refs_comp);
10567 if (lss != gfc_ss_terminator)
10569 /* The assignment needs scalarization. */
10570 lss_section = lss;
10572 /* Find a non-scalar SS from the lhs. */
10573 while (lss_section != gfc_ss_terminator
10574 && lss_section->info->type != GFC_SS_SECTION)
10575 lss_section = lss_section->next;
10577 gcc_assert (lss_section != gfc_ss_terminator);
10579 /* Initialize the scalarizer. */
10580 gfc_init_loopinfo (&loop);
10582 /* Walk the rhs. */
10583 rss = gfc_walk_expr (expr2);
10584 if (rss == gfc_ss_terminator)
10585 /* The rhs is scalar. Add a ss for the expression. */
10586 rss = gfc_get_scalar_ss (gfc_ss_terminator, expr2);
10587 /* When doing a class assign, then the handle to the rhs needs to be a
10588 pointer to allow for polymorphism. */
10589 if (is_poly_assign && expr2->rank == 0 && !UNLIMITED_POLY (expr2))
10590 rss->info->type = GFC_SS_REFERENCE;
10592 rss->no_bounds_check = expr2->no_bounds_check;
10593 /* Associate the SS with the loop. */
10594 gfc_add_ss_to_loop (&loop, lss);
10595 gfc_add_ss_to_loop (&loop, rss);
10597 /* Calculate the bounds of the scalarization. */
10598 gfc_conv_ss_startstride (&loop);
10599 /* Enable loop reversal. */
10600 for (n = 0; n < GFC_MAX_DIMENSIONS; n++)
10601 loop.reverse[n] = GFC_ENABLE_REVERSE;
10602 /* Resolve any data dependencies in the statement. */
10603 if (may_alias)
10604 gfc_conv_resolve_dependencies (&loop, lss, rss);
10605 /* Setup the scalarizing loops. */
10606 gfc_conv_loop_setup (&loop, &expr2->where);
10608 /* Setup the gfc_se structures. */
10609 gfc_copy_loopinfo_to_se (&lse, &loop);
10610 gfc_copy_loopinfo_to_se (&rse, &loop);
10612 rse.ss = rss;
10613 gfc_mark_ss_chain_used (rss, 1);
10614 if (loop.temp_ss == NULL)
10616 lse.ss = lss;
10617 gfc_mark_ss_chain_used (lss, 1);
10619 else
10621 lse.ss = loop.temp_ss;
10622 gfc_mark_ss_chain_used (lss, 3);
10623 gfc_mark_ss_chain_used (loop.temp_ss, 3);
10626 /* Allow the scalarizer to workshare array assignments. */
10627 if ((ompws_flags & (OMPWS_WORKSHARE_FLAG | OMPWS_SCALARIZER_BODY))
10628 == OMPWS_WORKSHARE_FLAG
10629 && loop.temp_ss == NULL)
10631 maybe_workshare = true;
10632 ompws_flags |= OMPWS_SCALARIZER_WS | OMPWS_SCALARIZER_BODY;
10635 /* Start the scalarized loop body. */
10636 gfc_start_scalarized_body (&loop, &body);
10638 else
10639 gfc_init_block (&body);
10641 l_is_temp = (lss != gfc_ss_terminator && loop.temp_ss != NULL);
10643 /* Translate the expression. */
10644 rse.want_coarray = flag_coarray == GFC_FCOARRAY_LIB && init_flag
10645 && lhs_caf_attr.codimension;
10646 gfc_conv_expr (&rse, expr2);
10648 /* Deal with the case of a scalar class function assigned to a derived type. */
10649 if (gfc_is_alloc_class_scalar_function (expr2)
10650 && expr1->ts.type == BT_DERIVED)
10652 rse.expr = gfc_class_data_get (rse.expr);
10653 rse.expr = build_fold_indirect_ref_loc (input_location, rse.expr);
10656 /* Stabilize a string length for temporaries. */
10657 if (expr2->ts.type == BT_CHARACTER && !expr1->ts.deferred
10658 && !(VAR_P (rse.string_length)
10659 || TREE_CODE (rse.string_length) == PARM_DECL
10660 || TREE_CODE (rse.string_length) == INDIRECT_REF))
10661 string_length = gfc_evaluate_now (rse.string_length, &rse.pre);
10662 else if (expr2->ts.type == BT_CHARACTER)
10664 if (expr1->ts.deferred
10665 && gfc_expr_attr (expr1).allocatable
10666 && gfc_check_dependency (expr1, expr2, true))
10667 rse.string_length = gfc_evaluate_now (rse.string_length, &rse.pre);
10668 string_length = rse.string_length;
10670 else
10671 string_length = NULL_TREE;
10673 if (l_is_temp)
10675 gfc_conv_tmp_array_ref (&lse);
10676 if (expr2->ts.type == BT_CHARACTER)
10677 lse.string_length = string_length;
10679 else
10681 gfc_conv_expr (&lse, expr1);
10682 if (gfc_option.rtcheck & GFC_RTCHECK_MEM
10683 && !init_flag
10684 && gfc_expr_attr (expr1).allocatable
10685 && expr1->rank
10686 && !expr2->rank)
10688 tree cond;
10689 const char* msg;
10691 tmp = INDIRECT_REF_P (lse.expr)
10692 ? gfc_build_addr_expr (NULL_TREE, lse.expr) : lse.expr;
10694 /* We should only get array references here. */
10695 gcc_assert (TREE_CODE (tmp) == POINTER_PLUS_EXPR
10696 || TREE_CODE (tmp) == ARRAY_REF);
10698 /* 'tmp' is either the pointer to the array(POINTER_PLUS_EXPR)
10699 or the array itself(ARRAY_REF). */
10700 tmp = TREE_OPERAND (tmp, 0);
10702 /* Provide the address of the array. */
10703 if (TREE_CODE (lse.expr) == ARRAY_REF)
10704 tmp = gfc_build_addr_expr (NULL_TREE, tmp);
10706 cond = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
10707 tmp, build_int_cst (TREE_TYPE (tmp), 0));
10708 msg = _("Assignment of scalar to unallocated array");
10709 gfc_trans_runtime_check (true, false, cond, &loop.pre,
10710 &expr1->where, msg);
10713 /* Deallocate the lhs parameterized components if required. */
10714 if (dealloc && expr2->expr_type == EXPR_FUNCTION
10715 && !expr1->symtree->n.sym->attr.associate_var)
10717 if (expr1->ts.type == BT_DERIVED
10718 && expr1->ts.u.derived
10719 && expr1->ts.u.derived->attr.pdt_type)
10721 tmp = gfc_deallocate_pdt_comp (expr1->ts.u.derived, lse.expr,
10722 expr1->rank);
10723 gfc_add_expr_to_block (&lse.pre, tmp);
10725 else if (expr1->ts.type == BT_CLASS
10726 && CLASS_DATA (expr1)->ts.u.derived
10727 && CLASS_DATA (expr1)->ts.u.derived->attr.pdt_type)
10729 tmp = gfc_class_data_get (lse.expr);
10730 tmp = gfc_deallocate_pdt_comp (CLASS_DATA (expr1)->ts.u.derived,
10731 tmp, expr1->rank);
10732 gfc_add_expr_to_block (&lse.pre, tmp);
10737 /* Assignments of scalar derived types with allocatable components
10738 to arrays must be done with a deep copy and the rhs temporary
10739 must have its components deallocated afterwards. */
10740 scalar_to_array = (expr2->ts.type == BT_DERIVED
10741 && expr2->ts.u.derived->attr.alloc_comp
10742 && !gfc_expr_is_variable (expr2)
10743 && expr1->rank && !expr2->rank);
10744 scalar_to_array |= (expr1->ts.type == BT_DERIVED
10745 && expr1->rank
10746 && expr1->ts.u.derived->attr.alloc_comp
10747 && gfc_is_alloc_class_scalar_function (expr2));
10748 if (scalar_to_array && dealloc)
10750 tmp = gfc_deallocate_alloc_comp_no_caf (expr2->ts.u.derived, rse.expr, 0);
10751 gfc_prepend_expr_to_block (&loop.post, tmp);
10754 /* When assigning a character function result to a deferred-length variable,
10755 the function call must happen before the (re)allocation of the lhs -
10756 otherwise the character length of the result is not known.
10757 NOTE 1: This relies on having the exact dependence of the length type
10758 parameter available to the caller; gfortran saves it in the .mod files.
10759 NOTE 2: Vector array references generate an index temporary that must
10760 not go outside the loop. Otherwise, variables should not generate
10761 a pre block.
10762 NOTE 3: The concatenation operation generates a temporary pointer,
10763 whose allocation must go to the innermost loop.
10764 NOTE 4: Elemental functions may generate a temporary, too. */
10765 if (flag_realloc_lhs
10766 && expr2->ts.type == BT_CHARACTER && expr1->ts.deferred
10767 && !(lss != gfc_ss_terminator
10768 && rss != gfc_ss_terminator
10769 && ((expr2->expr_type == EXPR_VARIABLE && expr2->rank)
10770 || (expr2->expr_type == EXPR_FUNCTION
10771 && expr2->value.function.esym != NULL
10772 && expr2->value.function.esym->attr.elemental)
10773 || (expr2->expr_type == EXPR_FUNCTION
10774 && expr2->value.function.isym != NULL
10775 && expr2->value.function.isym->elemental)
10776 || (expr2->expr_type == EXPR_OP
10777 && expr2->value.op.op == INTRINSIC_CONCAT))))
10778 gfc_add_block_to_block (&block, &rse.pre);
10780 /* Nullify the allocatable components corresponding to those of the lhs
10781 derived type, so that the finalization of the function result does not
10782 affect the lhs of the assignment. Prepend is used to ensure that the
10783 nullification occurs before the call to the finalizer. In the case of
10784 a scalar to array assignment, this is done in gfc_trans_scalar_assign
10785 as part of the deep copy. */
10786 if (!scalar_to_array && expr1->ts.type == BT_DERIVED
10787 && (gfc_is_class_array_function (expr2)
10788 || gfc_is_alloc_class_scalar_function (expr2)))
10790 tmp = rse.expr;
10791 tmp = gfc_nullify_alloc_comp (expr1->ts.u.derived, rse.expr, 0);
10792 gfc_prepend_expr_to_block (&rse.post, tmp);
10793 if (lss != gfc_ss_terminator && rss == gfc_ss_terminator)
10794 gfc_add_block_to_block (&loop.post, &rse.post);
10797 tmp = NULL_TREE;
10799 if (is_poly_assign)
10800 tmp = trans_class_assignment (&body, expr1, expr2, &lse, &rse,
10801 use_vptr_copy || (lhs_attr.allocatable
10802 && !lhs_attr.dimension),
10803 flag_realloc_lhs && !lhs_attr.pointer);
10804 else if (flag_coarray == GFC_FCOARRAY_LIB
10805 && lhs_caf_attr.codimension && rhs_caf_attr.codimension
10806 && ((lhs_caf_attr.allocatable && lhs_refs_comp)
10807 || (rhs_caf_attr.allocatable && rhs_refs_comp)))
10809 /* Only detour to caf_send[get][_by_ref] () when the lhs or rhs is an
10810 allocatable component, because those need to be accessed via the
10811 caf-runtime. No need to check for coindexes here, because resolve
10812 has rewritten those already. */
10813 gfc_code code;
10814 gfc_actual_arglist a1, a2;
10815 /* Clear the structures to prevent accessing garbage. */
10816 memset (&code, '\0', sizeof (gfc_code));
10817 memset (&a1, '\0', sizeof (gfc_actual_arglist));
10818 memset (&a2, '\0', sizeof (gfc_actual_arglist));
10819 a1.expr = expr1;
10820 a1.next = &a2;
10821 a2.expr = expr2;
10822 a2.next = NULL;
10823 code.ext.actual = &a1;
10824 code.resolved_isym = gfc_intrinsic_subroutine_by_id (GFC_ISYM_CAF_SEND);
10825 tmp = gfc_conv_intrinsic_subroutine (&code);
10827 else if (!is_poly_assign && expr2->must_finalize
10828 && expr1->ts.type == BT_CLASS
10829 && expr2->ts.type == BT_CLASS)
10831 /* This case comes about when the scalarizer provides array element
10832 references. Use the vptr copy function, since this does a deep
10833 copy of allocatable components, without which the finalizer call */
10834 tmp = gfc_get_vptr_from_expr (rse.expr);
10835 if (tmp != NULL_TREE)
10837 tree fcn = gfc_vptr_copy_get (tmp);
10838 if (POINTER_TYPE_P (TREE_TYPE (fcn)))
10839 fcn = build_fold_indirect_ref_loc (input_location, fcn);
10840 tmp = build_call_expr_loc (input_location,
10841 fcn, 2,
10842 gfc_build_addr_expr (NULL, rse.expr),
10843 gfc_build_addr_expr (NULL, lse.expr));
10847 /* If nothing else works, do it the old fashioned way! */
10848 if (tmp == NULL_TREE)
10849 tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts,
10850 gfc_expr_is_variable (expr2)
10851 || scalar_to_array
10852 || expr2->expr_type == EXPR_ARRAY,
10853 !(l_is_temp || init_flag) && dealloc,
10854 expr1->symtree->n.sym->attr.codimension);
10856 /* Add the pre blocks to the body. */
10857 gfc_add_block_to_block (&body, &rse.pre);
10858 gfc_add_block_to_block (&body, &lse.pre);
10859 gfc_add_expr_to_block (&body, tmp);
10860 /* Add the post blocks to the body. */
10861 gfc_add_block_to_block (&body, &rse.post);
10862 gfc_add_block_to_block (&body, &lse.post);
10864 if (lss == gfc_ss_terminator)
10866 /* F2003: Add the code for reallocation on assignment. */
10867 if (flag_realloc_lhs && is_scalar_reallocatable_lhs (expr1)
10868 && !is_poly_assign)
10869 alloc_scalar_allocatable_for_assignment (&block, string_length,
10870 expr1, expr2);
10872 /* Use the scalar assignment as is. */
10873 gfc_add_block_to_block (&block, &body);
10875 else
10877 gcc_assert (lse.ss == gfc_ss_terminator
10878 && rse.ss == gfc_ss_terminator);
10880 if (l_is_temp)
10882 gfc_trans_scalarized_loop_boundary (&loop, &body);
10884 /* We need to copy the temporary to the actual lhs. */
10885 gfc_init_se (&lse, NULL);
10886 gfc_init_se (&rse, NULL);
10887 gfc_copy_loopinfo_to_se (&lse, &loop);
10888 gfc_copy_loopinfo_to_se (&rse, &loop);
10890 rse.ss = loop.temp_ss;
10891 lse.ss = lss;
10893 gfc_conv_tmp_array_ref (&rse);
10894 gfc_conv_expr (&lse, expr1);
10896 gcc_assert (lse.ss == gfc_ss_terminator
10897 && rse.ss == gfc_ss_terminator);
10899 if (expr2->ts.type == BT_CHARACTER)
10900 rse.string_length = string_length;
10902 tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts,
10903 false, dealloc);
10904 gfc_add_expr_to_block (&body, tmp);
10907 /* F2003: Allocate or reallocate lhs of allocatable array. */
10908 if (flag_realloc_lhs
10909 && gfc_is_reallocatable_lhs (expr1)
10910 && expr2->rank
10911 && !is_runtime_conformable (expr1, expr2))
10913 realloc_lhs_warning (expr1->ts.type, true, &expr1->where);
10914 ompws_flags &= ~OMPWS_SCALARIZER_WS;
10915 tmp = gfc_alloc_allocatable_for_assignment (&loop, expr1, expr2);
10916 if (tmp != NULL_TREE)
10917 gfc_add_expr_to_block (&loop.code[expr1->rank - 1], tmp);
10920 if (maybe_workshare)
10921 ompws_flags &= ~OMPWS_SCALARIZER_BODY;
10923 /* Generate the copying loops. */
10924 gfc_trans_scalarizing_loops (&loop, &body);
10926 /* Wrap the whole thing up. */
10927 gfc_add_block_to_block (&block, &loop.pre);
10928 gfc_add_block_to_block (&block, &loop.post);
10930 gfc_cleanup_loop (&loop);
10933 return gfc_finish_block (&block);
10937 /* Check whether EXPR is a copyable array. */
10939 static bool
10940 copyable_array_p (gfc_expr * expr)
10942 if (expr->expr_type != EXPR_VARIABLE)
10943 return false;
10945 /* First check it's an array. */
10946 if (expr->rank < 1 || !expr->ref || expr->ref->next)
10947 return false;
10949 if (!gfc_full_array_ref_p (expr->ref, NULL))
10950 return false;
10952 /* Next check that it's of a simple enough type. */
10953 switch (expr->ts.type)
10955 case BT_INTEGER:
10956 case BT_REAL:
10957 case BT_COMPLEX:
10958 case BT_LOGICAL:
10959 return true;
10961 case BT_CHARACTER:
10962 return false;
10964 case_bt_struct:
10965 return !expr->ts.u.derived->attr.alloc_comp;
10967 default:
10968 break;
10971 return false;
10974 /* Translate an assignment. */
10976 tree
10977 gfc_trans_assignment (gfc_expr * expr1, gfc_expr * expr2, bool init_flag,
10978 bool dealloc, bool use_vptr_copy, bool may_alias)
10980 tree tmp;
10982 /* Special case a single function returning an array. */
10983 if (expr2->expr_type == EXPR_FUNCTION && expr2->rank > 0)
10985 tmp = gfc_trans_arrayfunc_assign (expr1, expr2);
10986 if (tmp)
10987 return tmp;
10990 /* Special case assigning an array to zero. */
10991 if (copyable_array_p (expr1)
10992 && is_zero_initializer_p (expr2))
10994 tmp = gfc_trans_zero_assign (expr1);
10995 if (tmp)
10996 return tmp;
10999 /* Special case copying one array to another. */
11000 if (copyable_array_p (expr1)
11001 && copyable_array_p (expr2)
11002 && gfc_compare_types (&expr1->ts, &expr2->ts)
11003 && !gfc_check_dependency (expr1, expr2, 0))
11005 tmp = gfc_trans_array_copy (expr1, expr2);
11006 if (tmp)
11007 return tmp;
11010 /* Special case initializing an array from a constant array constructor. */
11011 if (copyable_array_p (expr1)
11012 && expr2->expr_type == EXPR_ARRAY
11013 && gfc_compare_types (&expr1->ts, &expr2->ts))
11015 tmp = gfc_trans_array_constructor_copy (expr1, expr2);
11016 if (tmp)
11017 return tmp;
11020 if (UNLIMITED_POLY (expr1) && expr1->rank
11021 && expr2->ts.type != BT_CLASS)
11022 use_vptr_copy = true;
11024 /* Fallback to the scalarizer to generate explicit loops. */
11025 return gfc_trans_assignment_1 (expr1, expr2, init_flag, dealloc,
11026 use_vptr_copy, may_alias);
11029 tree
11030 gfc_trans_init_assign (gfc_code * code)
11032 return gfc_trans_assignment (code->expr1, code->expr2, true, false, true);
11035 tree
11036 gfc_trans_assign (gfc_code * code)
11038 return gfc_trans_assignment (code->expr1, code->expr2, false, true);