Don't warn when alignment of global common data exceeds maximum alignment.
[official-gcc.git] / gcc / fortran / trans-expr.c
blobc4291cce0790c0dd790a377341f5128c45eba524
1 /* Expression translation
2 Copyright (C) 2002-2021 Free Software Foundation, Inc.
3 Contributed by Paul Brook <paul@nowt.org>
4 and Steven Bosscher <s.bosscher@student.tudelft.nl>
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"
46 /* Calculate the number of characters in a string. */
48 tree
49 gfc_get_character_len (tree type)
51 tree len;
53 gcc_assert (type && TREE_CODE (type) == ARRAY_TYPE
54 && TYPE_STRING_FLAG (type));
56 len = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
57 len = (len) ? (len) : (integer_zero_node);
58 return fold_convert (gfc_charlen_type_node, len);
63 /* Calculate the number of bytes in a string. */
65 tree
66 gfc_get_character_len_in_bytes (tree type)
68 tree tmp, len;
70 gcc_assert (type && TREE_CODE (type) == ARRAY_TYPE
71 && TYPE_STRING_FLAG (type));
73 tmp = TYPE_SIZE_UNIT (TREE_TYPE (type));
74 tmp = (tmp && !integer_zerop (tmp))
75 ? (fold_convert (gfc_charlen_type_node, tmp)) : (NULL_TREE);
76 len = gfc_get_character_len (type);
77 if (tmp && len && !integer_zerop (len))
78 len = fold_build2_loc (input_location, MULT_EXPR,
79 gfc_charlen_type_node, len, tmp);
80 return len;
84 /* Convert a scalar to an array descriptor. To be used for assumed-rank
85 arrays. */
87 static tree
88 get_scalar_to_descriptor_type (tree scalar, symbol_attribute attr)
90 enum gfc_array_kind akind;
92 if (attr.pointer)
93 akind = GFC_ARRAY_POINTER_CONT;
94 else if (attr.allocatable)
95 akind = GFC_ARRAY_ALLOCATABLE;
96 else
97 akind = GFC_ARRAY_ASSUMED_SHAPE_CONT;
99 if (POINTER_TYPE_P (TREE_TYPE (scalar)))
100 scalar = TREE_TYPE (scalar);
101 return gfc_get_array_type_bounds (TREE_TYPE (scalar), 0, 0, NULL, NULL, 1,
102 akind, !(attr.pointer || attr.target));
105 tree
106 gfc_conv_scalar_to_descriptor (gfc_se *se, tree scalar, symbol_attribute attr)
108 tree desc, type, etype;
110 type = get_scalar_to_descriptor_type (scalar, attr);
111 etype = TREE_TYPE (scalar);
112 desc = gfc_create_var (type, "desc");
113 DECL_ARTIFICIAL (desc) = 1;
115 if (CONSTANT_CLASS_P (scalar))
117 tree tmp;
118 tmp = gfc_create_var (TREE_TYPE (scalar), "scalar");
119 gfc_add_modify (&se->pre, tmp, scalar);
120 scalar = tmp;
122 if (!POINTER_TYPE_P (TREE_TYPE (scalar)))
123 scalar = gfc_build_addr_expr (NULL_TREE, scalar);
124 else if (TREE_TYPE (etype) && TREE_CODE (TREE_TYPE (etype)) == ARRAY_TYPE)
125 etype = TREE_TYPE (etype);
126 gfc_add_modify (&se->pre, gfc_conv_descriptor_dtype (desc),
127 gfc_get_dtype_rank_type (0, etype));
128 gfc_conv_descriptor_data_set (&se->pre, desc, scalar);
129 gfc_conv_descriptor_span_set (&se->pre, desc,
130 gfc_conv_descriptor_elem_len (desc));
132 /* Copy pointer address back - but only if it could have changed and
133 if the actual argument is a pointer and not, e.g., NULL(). */
134 if ((attr.pointer || attr.allocatable) && attr.intent != INTENT_IN)
135 gfc_add_modify (&se->post, scalar,
136 fold_convert (TREE_TYPE (scalar),
137 gfc_conv_descriptor_data_get (desc)));
138 return desc;
142 /* Get the coarray token from the ultimate array or component ref.
143 Returns a NULL_TREE, when the ref object is not allocatable or pointer. */
145 tree
146 gfc_get_ultimate_alloc_ptr_comps_caf_token (gfc_se *outerse, gfc_expr *expr)
148 gfc_symbol *sym = expr->symtree->n.sym;
149 bool is_coarray = sym->attr.codimension;
150 gfc_expr *caf_expr = gfc_copy_expr (expr);
151 gfc_ref *ref = caf_expr->ref, *last_caf_ref = NULL;
153 while (ref)
155 if (ref->type == REF_COMPONENT
156 && (ref->u.c.component->attr.allocatable
157 || ref->u.c.component->attr.pointer)
158 && (is_coarray || ref->u.c.component->attr.codimension))
159 last_caf_ref = ref;
160 ref = ref->next;
163 if (last_caf_ref == NULL)
164 return NULL_TREE;
166 tree comp = last_caf_ref->u.c.component->caf_token, caf;
167 gfc_se se;
168 bool comp_ref = !last_caf_ref->u.c.component->attr.dimension;
169 if (comp == NULL_TREE && comp_ref)
170 return NULL_TREE;
171 gfc_init_se (&se, outerse);
172 gfc_free_ref_list (last_caf_ref->next);
173 last_caf_ref->next = NULL;
174 caf_expr->rank = comp_ref ? 0 : last_caf_ref->u.c.component->as->rank;
175 se.want_pointer = comp_ref;
176 gfc_conv_expr (&se, caf_expr);
177 gfc_add_block_to_block (&outerse->pre, &se.pre);
179 if (TREE_CODE (se.expr) == COMPONENT_REF && comp_ref)
180 se.expr = TREE_OPERAND (se.expr, 0);
181 gfc_free_expr (caf_expr);
183 if (comp_ref)
184 caf = fold_build3_loc (input_location, COMPONENT_REF,
185 TREE_TYPE (comp), se.expr, comp, NULL_TREE);
186 else
187 caf = gfc_conv_descriptor_token (se.expr);
188 return gfc_build_addr_expr (NULL_TREE, caf);
192 /* This is the seed for an eventual trans-class.c
194 The following parameters should not be used directly since they might
195 in future implementations. Use the corresponding APIs. */
196 #define CLASS_DATA_FIELD 0
197 #define CLASS_VPTR_FIELD 1
198 #define CLASS_LEN_FIELD 2
199 #define VTABLE_HASH_FIELD 0
200 #define VTABLE_SIZE_FIELD 1
201 #define VTABLE_EXTENDS_FIELD 2
202 #define VTABLE_DEF_INIT_FIELD 3
203 #define VTABLE_COPY_FIELD 4
204 #define VTABLE_FINAL_FIELD 5
205 #define VTABLE_DEALLOCATE_FIELD 6
208 tree
209 gfc_class_set_static_fields (tree decl, tree vptr, tree data)
211 tree tmp;
212 tree field;
213 vec<constructor_elt, va_gc> *init = NULL;
215 field = TYPE_FIELDS (TREE_TYPE (decl));
216 tmp = gfc_advance_chain (field, CLASS_DATA_FIELD);
217 CONSTRUCTOR_APPEND_ELT (init, tmp, data);
219 tmp = gfc_advance_chain (field, CLASS_VPTR_FIELD);
220 CONSTRUCTOR_APPEND_ELT (init, tmp, vptr);
222 return build_constructor (TREE_TYPE (decl), init);
226 tree
227 gfc_class_data_get (tree decl)
229 tree data;
230 if (POINTER_TYPE_P (TREE_TYPE (decl)))
231 decl = build_fold_indirect_ref_loc (input_location, decl);
232 data = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (decl)),
233 CLASS_DATA_FIELD);
234 return fold_build3_loc (input_location, COMPONENT_REF,
235 TREE_TYPE (data), decl, data,
236 NULL_TREE);
240 tree
241 gfc_class_vptr_get (tree decl)
243 tree vptr;
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 vptr = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (decl)),
252 CLASS_VPTR_FIELD);
253 return fold_build3_loc (input_location, COMPONENT_REF,
254 TREE_TYPE (vptr), decl, vptr,
255 NULL_TREE);
259 tree
260 gfc_class_len_get (tree decl)
262 tree len;
263 /* For class arrays decl may be a temporary descriptor handle, the len is
264 then available through the saved descriptor. */
265 if (VAR_P (decl) && DECL_LANG_SPECIFIC (decl)
266 && GFC_DECL_SAVED_DESCRIPTOR (decl))
267 decl = GFC_DECL_SAVED_DESCRIPTOR (decl);
268 if (POINTER_TYPE_P (TREE_TYPE (decl)))
269 decl = build_fold_indirect_ref_loc (input_location, decl);
270 len = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (decl)),
271 CLASS_LEN_FIELD);
272 return fold_build3_loc (input_location, COMPONENT_REF,
273 TREE_TYPE (len), decl, len,
274 NULL_TREE);
278 /* Try to get the _len component of a class. When the class is not unlimited
279 poly, i.e. no _len field exists, then return a zero node. */
281 tree
282 gfc_class_len_or_zero_get (tree decl)
284 tree len;
285 /* For class arrays decl may be a temporary descriptor handle, the vptr is
286 then available through the saved descriptor. */
287 if (VAR_P (decl) && DECL_LANG_SPECIFIC (decl)
288 && GFC_DECL_SAVED_DESCRIPTOR (decl))
289 decl = GFC_DECL_SAVED_DESCRIPTOR (decl);
290 if (POINTER_TYPE_P (TREE_TYPE (decl)))
291 decl = build_fold_indirect_ref_loc (input_location, decl);
292 len = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (decl)),
293 CLASS_LEN_FIELD);
294 return len != NULL_TREE ? fold_build3_loc (input_location, COMPONENT_REF,
295 TREE_TYPE (len), decl, len,
296 NULL_TREE)
297 : build_zero_cst (gfc_charlen_type_node);
301 tree
302 gfc_resize_class_size_with_len (stmtblock_t * block, tree class_expr, tree size)
304 tree tmp;
305 tree tmp2;
306 tree type;
308 tmp = gfc_class_len_or_zero_get (class_expr);
310 /* Include the len value in the element size if present. */
311 if (!integer_zerop (tmp))
313 type = TREE_TYPE (size);
314 if (block)
316 size = gfc_evaluate_now (size, block);
317 tmp = gfc_evaluate_now (fold_convert (type , tmp), block);
319 tmp2 = fold_build2_loc (input_location, MULT_EXPR,
320 type, size, tmp);
321 tmp = fold_build2_loc (input_location, GT_EXPR,
322 logical_type_node, tmp,
323 build_zero_cst (type));
324 size = fold_build3_loc (input_location, COND_EXPR,
325 type, tmp, tmp2, size);
327 else
328 return size;
330 if (block)
331 size = gfc_evaluate_now (size, block);
333 return size;
337 /* Get the specified FIELD from the VPTR. */
339 static tree
340 vptr_field_get (tree vptr, int fieldno)
342 tree field;
343 vptr = build_fold_indirect_ref_loc (input_location, vptr);
344 field = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (vptr)),
345 fieldno);
346 field = fold_build3_loc (input_location, COMPONENT_REF,
347 TREE_TYPE (field), vptr, field,
348 NULL_TREE);
349 gcc_assert (field);
350 return field;
354 /* Get the field from the class' vptr. */
356 static tree
357 class_vtab_field_get (tree decl, int fieldno)
359 tree vptr;
360 vptr = gfc_class_vptr_get (decl);
361 return vptr_field_get (vptr, fieldno);
365 /* Define a macro for creating the class_vtab_* and vptr_* accessors in
366 unison. */
367 #define VTAB_GET_FIELD_GEN(name, field) tree \
368 gfc_class_vtab_## name ##_get (tree cl) \
370 return class_vtab_field_get (cl, field); \
373 tree \
374 gfc_vptr_## name ##_get (tree vptr) \
376 return vptr_field_get (vptr, field); \
379 VTAB_GET_FIELD_GEN (hash, VTABLE_HASH_FIELD)
380 VTAB_GET_FIELD_GEN (extends, VTABLE_EXTENDS_FIELD)
381 VTAB_GET_FIELD_GEN (def_init, VTABLE_DEF_INIT_FIELD)
382 VTAB_GET_FIELD_GEN (copy, VTABLE_COPY_FIELD)
383 VTAB_GET_FIELD_GEN (final, VTABLE_FINAL_FIELD)
384 VTAB_GET_FIELD_GEN (deallocate, VTABLE_DEALLOCATE_FIELD)
387 /* The size field is returned as an array index type. Therefore treat
388 it and only it specially. */
390 tree
391 gfc_class_vtab_size_get (tree cl)
393 tree size;
394 size = class_vtab_field_get (cl, VTABLE_SIZE_FIELD);
395 /* Always return size as an array index type. */
396 size = fold_convert (gfc_array_index_type, size);
397 gcc_assert (size);
398 return size;
401 tree
402 gfc_vptr_size_get (tree vptr)
404 tree size;
405 size = vptr_field_get (vptr, VTABLE_SIZE_FIELD);
406 /* Always return size as an array index type. */
407 size = fold_convert (gfc_array_index_type, size);
408 gcc_assert (size);
409 return size;
413 #undef CLASS_DATA_FIELD
414 #undef CLASS_VPTR_FIELD
415 #undef CLASS_LEN_FIELD
416 #undef VTABLE_HASH_FIELD
417 #undef VTABLE_SIZE_FIELD
418 #undef VTABLE_EXTENDS_FIELD
419 #undef VTABLE_DEF_INIT_FIELD
420 #undef VTABLE_COPY_FIELD
421 #undef VTABLE_FINAL_FIELD
424 /* IF ts is null (default), search for the last _class ref in the chain
425 of references of the expression and cut the chain there. Although
426 this routine is similiar to class.c:gfc_add_component_ref (), there
427 is a significant difference: gfc_add_component_ref () concentrates
428 on an array ref that is the last ref in the chain and is oblivious
429 to the kind of refs following.
430 ELSE IF ts is non-null the cut is at the class entity or component
431 that is followed by an array reference, which is not an element.
432 These calls come from trans-array.c:build_class_array_ref, which
433 handles scalarized class array references.*/
435 gfc_expr *
436 gfc_find_and_cut_at_last_class_ref (gfc_expr *e, bool is_mold,
437 gfc_typespec **ts)
439 gfc_expr *base_expr;
440 gfc_ref *ref, *class_ref, *tail = NULL, *array_ref;
442 /* Find the last class reference. */
443 class_ref = NULL;
444 array_ref = NULL;
446 if (ts)
448 if (e->symtree
449 && e->symtree->n.sym->ts.type == BT_CLASS)
450 *ts = &e->symtree->n.sym->ts;
451 else
452 *ts = NULL;
455 for (ref = e->ref; ref; ref = ref->next)
457 if (ts)
459 if (ref->type == REF_COMPONENT
460 && ref->u.c.component->ts.type == BT_CLASS
461 && ref->next && ref->next->type == REF_COMPONENT
462 && !strcmp (ref->next->u.c.component->name, "_data")
463 && ref->next->next
464 && ref->next->next->type == REF_ARRAY
465 && ref->next->next->u.ar.type != AR_ELEMENT)
467 *ts = &ref->u.c.component->ts;
468 class_ref = ref;
469 break;
472 if (ref->next == NULL)
473 break;
475 else
477 if (ref->type == REF_ARRAY && ref->u.ar.type != AR_ELEMENT)
478 array_ref = ref;
480 if (ref->type == REF_COMPONENT
481 && ref->u.c.component->ts.type == BT_CLASS)
483 /* Component to the right of a part reference with nonzero
484 rank must not have the ALLOCATABLE attribute. If attempts
485 are made to reference such a component reference, an error
486 results followed by an ICE. */
487 if (array_ref
488 && CLASS_DATA (ref->u.c.component)->attr.allocatable)
489 return NULL;
490 class_ref = ref;
495 if (ts && *ts == NULL)
496 return NULL;
498 /* Remove and store all subsequent references after the
499 CLASS reference. */
500 if (class_ref)
502 tail = class_ref->next;
503 class_ref->next = NULL;
505 else if (e->symtree && e->symtree->n.sym->ts.type == BT_CLASS)
507 tail = e->ref;
508 e->ref = NULL;
511 if (is_mold)
512 base_expr = gfc_expr_to_initialize (e);
513 else
514 base_expr = gfc_copy_expr (e);
516 /* Restore the original tail expression. */
517 if (class_ref)
519 gfc_free_ref_list (class_ref->next);
520 class_ref->next = tail;
522 else if (e->symtree && e->symtree->n.sym->ts.type == BT_CLASS)
524 gfc_free_ref_list (e->ref);
525 e->ref = tail;
527 return base_expr;
531 /* Reset the vptr to the declared type, e.g. after deallocation. */
533 void
534 gfc_reset_vptr (stmtblock_t *block, gfc_expr *e)
536 gfc_symbol *vtab;
537 tree vptr;
538 tree vtable;
539 gfc_se se;
541 /* Evaluate the expression and obtain the vptr from it. */
542 gfc_init_se (&se, NULL);
543 if (e->rank)
544 gfc_conv_expr_descriptor (&se, e);
545 else
546 gfc_conv_expr (&se, e);
547 gfc_add_block_to_block (block, &se.pre);
548 vptr = gfc_get_vptr_from_expr (se.expr);
550 /* If a vptr is not found, we can do nothing more. */
551 if (vptr == NULL_TREE)
552 return;
554 if (UNLIMITED_POLY (e))
555 gfc_add_modify (block, vptr, build_int_cst (TREE_TYPE (vptr), 0));
556 else
558 /* Return the vptr to the address of the declared type. */
559 vtab = gfc_find_derived_vtab (e->ts.u.derived);
560 vtable = vtab->backend_decl;
561 if (vtable == NULL_TREE)
562 vtable = gfc_get_symbol_decl (vtab);
563 vtable = gfc_build_addr_expr (NULL, vtable);
564 vtable = fold_convert (TREE_TYPE (vptr), vtable);
565 gfc_add_modify (block, vptr, vtable);
570 /* Reset the len for unlimited polymorphic objects. */
572 void
573 gfc_reset_len (stmtblock_t *block, gfc_expr *expr)
575 gfc_expr *e;
576 gfc_se se_len;
577 e = gfc_find_and_cut_at_last_class_ref (expr);
578 if (e == NULL)
579 return;
580 gfc_add_len_component (e);
581 gfc_init_se (&se_len, NULL);
582 gfc_conv_expr (&se_len, e);
583 gfc_add_modify (block, se_len.expr,
584 fold_convert (TREE_TYPE (se_len.expr), integer_zero_node));
585 gfc_free_expr (e);
589 /* Obtain the last class reference in a gfc_expr. Return NULL_TREE if no class
590 reference is found. Note that it is up to the caller to avoid using this
591 for expressions other than variables. */
593 tree
594 gfc_get_class_from_gfc_expr (gfc_expr *e)
596 gfc_expr *class_expr;
597 gfc_se cse;
598 class_expr = gfc_find_and_cut_at_last_class_ref (e);
599 if (class_expr == NULL)
600 return NULL_TREE;
601 gfc_init_se (&cse, NULL);
602 gfc_conv_expr (&cse, class_expr);
603 gfc_free_expr (class_expr);
604 return cse.expr;
608 /* Obtain the last class reference in an expression.
609 Return NULL_TREE if no class reference is found. */
611 tree
612 gfc_get_class_from_expr (tree expr)
614 tree tmp;
615 tree type;
617 for (tmp = expr; tmp; tmp = TREE_OPERAND (tmp, 0))
619 if (CONSTANT_CLASS_P (tmp))
620 return NULL_TREE;
622 type = TREE_TYPE (tmp);
623 while (type)
625 if (GFC_CLASS_TYPE_P (type))
626 return tmp;
627 if (type != TYPE_CANONICAL (type))
628 type = TYPE_CANONICAL (type);
629 else
630 type = NULL_TREE;
632 if (VAR_P (tmp) || TREE_CODE (tmp) == PARM_DECL)
633 break;
636 if (POINTER_TYPE_P (TREE_TYPE (tmp)))
637 tmp = build_fold_indirect_ref_loc (input_location, tmp);
639 if (GFC_CLASS_TYPE_P (TREE_TYPE (tmp)))
640 return tmp;
642 return NULL_TREE;
646 /* Obtain the vptr of the last class reference in an expression.
647 Return NULL_TREE if no class reference is found. */
649 tree
650 gfc_get_vptr_from_expr (tree expr)
652 tree tmp;
654 tmp = gfc_get_class_from_expr (expr);
656 if (tmp != NULL_TREE)
657 return gfc_class_vptr_get (tmp);
659 return NULL_TREE;
663 static void
664 class_array_data_assign (stmtblock_t *block, tree lhs_desc, tree rhs_desc,
665 bool lhs_type)
667 tree tmp, tmp2, type;
669 gfc_conv_descriptor_data_set (block, lhs_desc,
670 gfc_conv_descriptor_data_get (rhs_desc));
671 gfc_conv_descriptor_offset_set (block, lhs_desc,
672 gfc_conv_descriptor_offset_get (rhs_desc));
674 gfc_add_modify (block, gfc_conv_descriptor_dtype (lhs_desc),
675 gfc_conv_descriptor_dtype (rhs_desc));
677 /* Assign the dimension as range-ref. */
678 tmp = gfc_get_descriptor_dimension (lhs_desc);
679 tmp2 = gfc_get_descriptor_dimension (rhs_desc);
681 type = lhs_type ? TREE_TYPE (tmp) : TREE_TYPE (tmp2);
682 tmp = build4_loc (input_location, ARRAY_RANGE_REF, type, tmp,
683 gfc_index_zero_node, NULL_TREE, NULL_TREE);
684 tmp2 = build4_loc (input_location, ARRAY_RANGE_REF, type, tmp2,
685 gfc_index_zero_node, NULL_TREE, NULL_TREE);
686 gfc_add_modify (block, tmp, tmp2);
690 /* Takes a derived type expression and returns the address of a temporary
691 class object of the 'declared' type. If vptr is not NULL, this is
692 used for the temporary class object.
693 optional_alloc_ptr is false when the dummy is neither allocatable
694 nor a pointer; that's only relevant for the optional handling.
695 The optional argument 'derived_array' is used to preserve the parmse
696 expression for deallocation of allocatable components. Assumed rank
697 formal arguments made this necessary. */
698 void
699 gfc_conv_derived_to_class (gfc_se *parmse, gfc_expr *e,
700 gfc_typespec class_ts, tree vptr, bool optional,
701 bool optional_alloc_ptr,
702 tree *derived_array)
704 gfc_symbol *vtab;
705 tree cond_optional = NULL_TREE;
706 gfc_ss *ss;
707 tree ctree;
708 tree var;
709 tree tmp;
710 int dim;
712 /* The derived type needs to be converted to a temporary
713 CLASS object. */
714 tmp = gfc_typenode_for_spec (&class_ts);
715 var = gfc_create_var (tmp, "class");
717 /* Set the vptr. */
718 ctree = gfc_class_vptr_get (var);
720 if (vptr != NULL_TREE)
722 /* Use the dynamic vptr. */
723 tmp = vptr;
725 else
727 /* In this case the vtab corresponds to the derived type and the
728 vptr must point to it. */
729 vtab = gfc_find_derived_vtab (e->ts.u.derived);
730 gcc_assert (vtab);
731 tmp = gfc_build_addr_expr (NULL_TREE, gfc_get_symbol_decl (vtab));
733 gfc_add_modify (&parmse->pre, ctree,
734 fold_convert (TREE_TYPE (ctree), tmp));
736 /* Now set the data field. */
737 ctree = gfc_class_data_get (var);
739 if (optional)
740 cond_optional = gfc_conv_expr_present (e->symtree->n.sym);
742 if (parmse->expr && POINTER_TYPE_P (TREE_TYPE (parmse->expr)))
744 /* If there is a ready made pointer to a derived type, use it
745 rather than evaluating the expression again. */
746 tmp = fold_convert (TREE_TYPE (ctree), parmse->expr);
747 gfc_add_modify (&parmse->pre, ctree, tmp);
749 else if (parmse->ss && parmse->ss->info && parmse->ss->info->useflags)
751 /* For an array reference in an elemental procedure call we need
752 to retain the ss to provide the scalarized array reference. */
753 gfc_conv_expr_reference (parmse, e);
754 tmp = fold_convert (TREE_TYPE (ctree), parmse->expr);
755 if (optional)
756 tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp),
757 cond_optional, tmp,
758 fold_convert (TREE_TYPE (tmp), null_pointer_node));
759 gfc_add_modify (&parmse->pre, ctree, tmp);
761 else
763 ss = gfc_walk_expr (e);
764 if (ss == gfc_ss_terminator)
766 parmse->ss = NULL;
767 gfc_conv_expr_reference (parmse, e);
769 /* Scalar to an assumed-rank array. */
770 if (class_ts.u.derived->components->as)
772 tree type;
773 type = get_scalar_to_descriptor_type (parmse->expr,
774 gfc_expr_attr (e));
775 gfc_add_modify (&parmse->pre, gfc_conv_descriptor_dtype (ctree),
776 gfc_get_dtype (type));
777 if (optional)
778 parmse->expr = build3_loc (input_location, COND_EXPR,
779 TREE_TYPE (parmse->expr),
780 cond_optional, parmse->expr,
781 fold_convert (TREE_TYPE (parmse->expr),
782 null_pointer_node));
783 gfc_conv_descriptor_data_set (&parmse->pre, ctree, parmse->expr);
785 else
787 tmp = fold_convert (TREE_TYPE (ctree), parmse->expr);
788 if (optional)
789 tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp),
790 cond_optional, tmp,
791 fold_convert (TREE_TYPE (tmp),
792 null_pointer_node));
793 gfc_add_modify (&parmse->pre, ctree, tmp);
796 else
798 stmtblock_t block;
799 gfc_init_block (&block);
800 gfc_ref *ref;
802 parmse->ss = ss;
803 parmse->use_offset = 1;
804 gfc_conv_expr_descriptor (parmse, e);
806 /* Detect any array references with vector subscripts. */
807 for (ref = e->ref; ref; ref = ref->next)
808 if (ref->type == REF_ARRAY
809 && ref->u.ar.type != AR_ELEMENT
810 && ref->u.ar.type != AR_FULL)
812 for (dim = 0; dim < ref->u.ar.dimen; dim++)
813 if (ref->u.ar.dimen_type[dim] == DIMEN_VECTOR)
814 break;
815 if (dim < ref->u.ar.dimen)
816 break;
819 /* Array references with vector subscripts and non-variable expressions
820 need be converted to a one-based descriptor. */
821 if (ref || e->expr_type != EXPR_VARIABLE)
823 for (dim = 0; dim < e->rank; ++dim)
824 gfc_conv_shift_descriptor_lbound (&block, parmse->expr, dim,
825 gfc_index_one_node);
828 if (e->rank != class_ts.u.derived->components->as->rank)
830 gcc_assert (class_ts.u.derived->components->as->type
831 == AS_ASSUMED_RANK);
832 if (derived_array
833 && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (parmse->expr)))
835 *derived_array = gfc_create_var (TREE_TYPE (parmse->expr),
836 "array");
837 gfc_add_modify (&block, *derived_array , parmse->expr);
839 class_array_data_assign (&block, ctree, parmse->expr, false);
841 else
843 if (gfc_expr_attr (e).codimension)
844 parmse->expr = fold_build1_loc (input_location,
845 VIEW_CONVERT_EXPR,
846 TREE_TYPE (ctree),
847 parmse->expr);
848 gfc_add_modify (&block, ctree, parmse->expr);
851 if (optional)
853 tmp = gfc_finish_block (&block);
855 gfc_init_block (&block);
856 gfc_conv_descriptor_data_set (&block, ctree, null_pointer_node);
857 if (derived_array && *derived_array != NULL_TREE)
858 gfc_conv_descriptor_data_set (&block, *derived_array,
859 null_pointer_node);
861 tmp = build3_v (COND_EXPR, cond_optional, tmp,
862 gfc_finish_block (&block));
863 gfc_add_expr_to_block (&parmse->pre, tmp);
865 else
866 gfc_add_block_to_block (&parmse->pre, &block);
870 if (class_ts.u.derived->components->ts.type == BT_DERIVED
871 && class_ts.u.derived->components->ts.u.derived
872 ->attr.unlimited_polymorphic)
874 /* Take care about initializing the _len component correctly. */
875 ctree = gfc_class_len_get (var);
876 if (UNLIMITED_POLY (e))
878 gfc_expr *len;
879 gfc_se se;
881 len = gfc_find_and_cut_at_last_class_ref (e);
882 gfc_add_len_component (len);
883 gfc_init_se (&se, NULL);
884 gfc_conv_expr (&se, len);
885 if (optional)
886 tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (se.expr),
887 cond_optional, se.expr,
888 fold_convert (TREE_TYPE (se.expr),
889 integer_zero_node));
890 else
891 tmp = se.expr;
892 gfc_free_expr (len);
894 else
895 tmp = integer_zero_node;
896 gfc_add_modify (&parmse->pre, ctree, fold_convert (TREE_TYPE (ctree),
897 tmp));
899 /* Pass the address of the class object. */
900 parmse->expr = gfc_build_addr_expr (NULL_TREE, var);
902 if (optional && optional_alloc_ptr)
903 parmse->expr = build3_loc (input_location, COND_EXPR,
904 TREE_TYPE (parmse->expr),
905 cond_optional, parmse->expr,
906 fold_convert (TREE_TYPE (parmse->expr),
907 null_pointer_node));
911 /* Create a new class container, which is required as scalar coarrays
912 have an array descriptor while normal scalars haven't. Optionally,
913 NULL pointer checks are added if the argument is OPTIONAL. */
915 static void
916 class_scalar_coarray_to_class (gfc_se *parmse, gfc_expr *e,
917 gfc_typespec class_ts, bool optional)
919 tree var, ctree, tmp;
920 stmtblock_t block;
921 gfc_ref *ref;
922 gfc_ref *class_ref;
924 gfc_init_block (&block);
926 class_ref = NULL;
927 for (ref = e->ref; ref; ref = ref->next)
929 if (ref->type == REF_COMPONENT
930 && ref->u.c.component->ts.type == BT_CLASS)
931 class_ref = ref;
934 if (class_ref == NULL
935 && e->symtree && e->symtree->n.sym->ts.type == BT_CLASS)
936 tmp = e->symtree->n.sym->backend_decl;
937 else
939 /* Remove everything after the last class reference, convert the
940 expression and then recover its tailend once more. */
941 gfc_se tmpse;
942 ref = class_ref->next;
943 class_ref->next = NULL;
944 gfc_init_se (&tmpse, NULL);
945 gfc_conv_expr (&tmpse, e);
946 class_ref->next = ref;
947 tmp = tmpse.expr;
950 var = gfc_typenode_for_spec (&class_ts);
951 var = gfc_create_var (var, "class");
953 ctree = gfc_class_vptr_get (var);
954 gfc_add_modify (&block, ctree,
955 fold_convert (TREE_TYPE (ctree), gfc_class_vptr_get (tmp)));
957 ctree = gfc_class_data_get (var);
958 tmp = gfc_conv_descriptor_data_get (gfc_class_data_get (tmp));
959 gfc_add_modify (&block, ctree, fold_convert (TREE_TYPE (ctree), tmp));
961 /* Pass the address of the class object. */
962 parmse->expr = gfc_build_addr_expr (NULL_TREE, var);
964 if (optional)
966 tree cond = gfc_conv_expr_present (e->symtree->n.sym);
967 tree tmp2;
969 tmp = gfc_finish_block (&block);
971 gfc_init_block (&block);
972 tmp2 = gfc_class_data_get (var);
973 gfc_add_modify (&block, tmp2, fold_convert (TREE_TYPE (tmp2),
974 null_pointer_node));
975 tmp2 = gfc_finish_block (&block);
977 tmp = build3_loc (input_location, COND_EXPR, void_type_node,
978 cond, tmp, tmp2);
979 gfc_add_expr_to_block (&parmse->pre, tmp);
981 else
982 gfc_add_block_to_block (&parmse->pre, &block);
986 /* Takes an intrinsic type expression and returns the address of a temporary
987 class object of the 'declared' type. */
988 void
989 gfc_conv_intrinsic_to_class (gfc_se *parmse, gfc_expr *e,
990 gfc_typespec class_ts)
992 gfc_symbol *vtab;
993 gfc_ss *ss;
994 tree ctree;
995 tree var;
996 tree tmp;
997 int dim;
999 /* The intrinsic type needs to be converted to a temporary
1000 CLASS object. */
1001 tmp = gfc_typenode_for_spec (&class_ts);
1002 var = gfc_create_var (tmp, "class");
1004 /* Set the vptr. */
1005 ctree = gfc_class_vptr_get (var);
1007 vtab = gfc_find_vtab (&e->ts);
1008 gcc_assert (vtab);
1009 tmp = gfc_build_addr_expr (NULL_TREE, gfc_get_symbol_decl (vtab));
1010 gfc_add_modify (&parmse->pre, ctree,
1011 fold_convert (TREE_TYPE (ctree), tmp));
1013 /* Now set the data field. */
1014 ctree = gfc_class_data_get (var);
1015 if (parmse->ss && parmse->ss->info->useflags)
1017 /* For an array reference in an elemental procedure call we need
1018 to retain the ss to provide the scalarized array reference. */
1019 gfc_conv_expr_reference (parmse, e);
1020 tmp = fold_convert (TREE_TYPE (ctree), parmse->expr);
1021 gfc_add_modify (&parmse->pre, ctree, tmp);
1023 else
1025 ss = gfc_walk_expr (e);
1026 if (ss == gfc_ss_terminator)
1028 parmse->ss = NULL;
1029 gfc_conv_expr_reference (parmse, e);
1030 if (class_ts.u.derived->components->as
1031 && class_ts.u.derived->components->as->type == AS_ASSUMED_RANK)
1033 tmp = gfc_conv_scalar_to_descriptor (parmse, parmse->expr,
1034 gfc_expr_attr (e));
1035 tmp = fold_build1_loc (input_location, VIEW_CONVERT_EXPR,
1036 TREE_TYPE (ctree), tmp);
1038 else
1039 tmp = fold_convert (TREE_TYPE (ctree), parmse->expr);
1040 gfc_add_modify (&parmse->pre, ctree, tmp);
1042 else
1044 parmse->ss = ss;
1045 parmse->use_offset = 1;
1046 gfc_conv_expr_descriptor (parmse, e);
1048 /* Array references with vector subscripts and non-variable expressions
1049 need be converted to a one-based descriptor. */
1050 if (e->expr_type != EXPR_VARIABLE)
1052 for (dim = 0; dim < e->rank; ++dim)
1053 gfc_conv_shift_descriptor_lbound (&parmse->pre, parmse->expr,
1054 dim, gfc_index_one_node);
1057 if (class_ts.u.derived->components->as->rank != e->rank)
1059 tmp = fold_build1_loc (input_location, VIEW_CONVERT_EXPR,
1060 TREE_TYPE (ctree), parmse->expr);
1061 gfc_add_modify (&parmse->pre, ctree, tmp);
1063 else
1064 gfc_add_modify (&parmse->pre, ctree, parmse->expr);
1068 gcc_assert (class_ts.type == BT_CLASS);
1069 if (class_ts.u.derived->components->ts.type == BT_DERIVED
1070 && class_ts.u.derived->components->ts.u.derived
1071 ->attr.unlimited_polymorphic)
1073 ctree = gfc_class_len_get (var);
1074 /* When the actual arg is a char array, then set the _len component of the
1075 unlimited polymorphic entity to the length of the string. */
1076 if (e->ts.type == BT_CHARACTER)
1078 /* Start with parmse->string_length because this seems to be set to a
1079 correct value more often. */
1080 if (parmse->string_length)
1081 tmp = parmse->string_length;
1082 /* When the string_length is not yet set, then try the backend_decl of
1083 the cl. */
1084 else if (e->ts.u.cl->backend_decl)
1085 tmp = e->ts.u.cl->backend_decl;
1086 /* If both of the above approaches fail, then try to generate an
1087 expression from the input, which is only feasible currently, when the
1088 expression can be evaluated to a constant one. */
1089 else
1091 /* Try to simplify the expression. */
1092 gfc_simplify_expr (e, 0);
1093 if (e->expr_type == EXPR_CONSTANT && !e->ts.u.cl->resolved)
1095 /* Amazingly all data is present to compute the length of a
1096 constant string, but the expression is not yet there. */
1097 e->ts.u.cl->length = gfc_get_constant_expr (BT_INTEGER,
1098 gfc_charlen_int_kind,
1099 &e->where);
1100 mpz_set_ui (e->ts.u.cl->length->value.integer,
1101 e->value.character.length);
1102 gfc_conv_const_charlen (e->ts.u.cl);
1103 e->ts.u.cl->resolved = 1;
1104 tmp = e->ts.u.cl->backend_decl;
1106 else
1108 gfc_error ("Cannot compute the length of the char array "
1109 "at %L.", &e->where);
1113 else
1114 tmp = integer_zero_node;
1116 gfc_add_modify (&parmse->pre, ctree, fold_convert (TREE_TYPE (ctree), tmp));
1118 else if (class_ts.type == BT_CLASS
1119 && class_ts.u.derived->components
1120 && class_ts.u.derived->components->ts.u
1121 .derived->attr.unlimited_polymorphic)
1123 ctree = gfc_class_len_get (var);
1124 gfc_add_modify (&parmse->pre, ctree,
1125 fold_convert (TREE_TYPE (ctree),
1126 integer_zero_node));
1128 /* Pass the address of the class object. */
1129 parmse->expr = gfc_build_addr_expr (NULL_TREE, var);
1133 /* Takes a scalarized class array expression and returns the
1134 address of a temporary scalar class object of the 'declared'
1135 type.
1136 OOP-TODO: This could be improved by adding code that branched on
1137 the dynamic type being the same as the declared type. In this case
1138 the original class expression can be passed directly.
1139 optional_alloc_ptr is false when the dummy is neither allocatable
1140 nor a pointer; that's relevant for the optional handling.
1141 Set copyback to true if class container's _data and _vtab pointers
1142 might get modified. */
1144 void
1145 gfc_conv_class_to_class (gfc_se *parmse, gfc_expr *e, gfc_typespec class_ts,
1146 bool elemental, bool copyback, bool optional,
1147 bool optional_alloc_ptr)
1149 tree ctree;
1150 tree var;
1151 tree tmp;
1152 tree vptr;
1153 tree cond = NULL_TREE;
1154 tree slen = NULL_TREE;
1155 gfc_ref *ref;
1156 gfc_ref *class_ref;
1157 stmtblock_t block;
1158 bool full_array = false;
1160 gfc_init_block (&block);
1162 class_ref = NULL;
1163 for (ref = e->ref; ref; ref = ref->next)
1165 if (ref->type == REF_COMPONENT
1166 && ref->u.c.component->ts.type == BT_CLASS)
1167 class_ref = ref;
1169 if (ref->next == NULL)
1170 break;
1173 if ((ref == NULL || class_ref == ref)
1174 && !(gfc_is_class_array_function (e) && parmse->class_vptr != NULL_TREE)
1175 && (!class_ts.u.derived->components->as
1176 || class_ts.u.derived->components->as->rank != -1))
1177 return;
1179 /* Test for FULL_ARRAY. */
1180 if (e->rank == 0 && gfc_expr_attr (e).codimension
1181 && gfc_expr_attr (e).dimension)
1182 full_array = true;
1183 else
1184 gfc_is_class_array_ref (e, &full_array);
1186 /* The derived type needs to be converted to a temporary
1187 CLASS object. */
1188 tmp = gfc_typenode_for_spec (&class_ts);
1189 var = gfc_create_var (tmp, "class");
1191 /* Set the data. */
1192 ctree = gfc_class_data_get (var);
1193 if (class_ts.u.derived->components->as
1194 && e->rank != class_ts.u.derived->components->as->rank)
1196 if (e->rank == 0)
1198 tree type = get_scalar_to_descriptor_type (parmse->expr,
1199 gfc_expr_attr (e));
1200 gfc_add_modify (&block, gfc_conv_descriptor_dtype (ctree),
1201 gfc_get_dtype (type));
1203 tmp = gfc_class_data_get (parmse->expr);
1204 if (!POINTER_TYPE_P (TREE_TYPE (tmp)))
1205 tmp = gfc_build_addr_expr (NULL_TREE, tmp);
1207 gfc_conv_descriptor_data_set (&block, ctree, tmp);
1209 else
1210 class_array_data_assign (&block, ctree, parmse->expr, false);
1212 else
1214 if (TREE_TYPE (parmse->expr) != TREE_TYPE (ctree))
1215 parmse->expr = fold_build1_loc (input_location, VIEW_CONVERT_EXPR,
1216 TREE_TYPE (ctree), parmse->expr);
1217 gfc_add_modify (&block, ctree, parmse->expr);
1220 /* Return the data component, except in the case of scalarized array
1221 references, where nullification of the cannot occur and so there
1222 is no need. */
1223 if (!elemental && full_array && copyback)
1225 if (class_ts.u.derived->components->as
1226 && e->rank != class_ts.u.derived->components->as->rank)
1228 if (e->rank == 0)
1229 gfc_add_modify (&parmse->post, gfc_class_data_get (parmse->expr),
1230 gfc_conv_descriptor_data_get (ctree));
1231 else
1232 class_array_data_assign (&parmse->post, parmse->expr, ctree, true);
1234 else
1235 gfc_add_modify (&parmse->post, parmse->expr, ctree);
1238 /* Set the vptr. */
1239 ctree = gfc_class_vptr_get (var);
1241 /* The vptr is the second field of the actual argument.
1242 First we have to find the corresponding class reference. */
1244 tmp = NULL_TREE;
1245 if (gfc_is_class_array_function (e)
1246 && parmse->class_vptr != NULL_TREE)
1247 tmp = parmse->class_vptr;
1248 else if (class_ref == NULL
1249 && e->symtree && e->symtree->n.sym->ts.type == BT_CLASS)
1251 tmp = e->symtree->n.sym->backend_decl;
1253 if (TREE_CODE (tmp) == FUNCTION_DECL)
1254 tmp = gfc_get_fake_result_decl (e->symtree->n.sym, 0);
1256 if (DECL_LANG_SPECIFIC (tmp) && GFC_DECL_SAVED_DESCRIPTOR (tmp))
1257 tmp = GFC_DECL_SAVED_DESCRIPTOR (tmp);
1259 slen = build_zero_cst (size_type_node);
1261 else
1263 /* Remove everything after the last class reference, convert the
1264 expression and then recover its tailend once more. */
1265 gfc_se tmpse;
1266 ref = class_ref->next;
1267 class_ref->next = NULL;
1268 gfc_init_se (&tmpse, NULL);
1269 gfc_conv_expr (&tmpse, e);
1270 class_ref->next = ref;
1271 tmp = tmpse.expr;
1272 slen = tmpse.string_length;
1275 gcc_assert (tmp != NULL_TREE);
1277 /* Dereference if needs be. */
1278 if (TREE_CODE (TREE_TYPE (tmp)) == REFERENCE_TYPE)
1279 tmp = build_fold_indirect_ref_loc (input_location, tmp);
1281 if (!(gfc_is_class_array_function (e) && parmse->class_vptr))
1282 vptr = gfc_class_vptr_get (tmp);
1283 else
1284 vptr = tmp;
1286 gfc_add_modify (&block, ctree,
1287 fold_convert (TREE_TYPE (ctree), vptr));
1289 /* Return the vptr component, except in the case of scalarized array
1290 references, where the dynamic type cannot change. */
1291 if (!elemental && full_array && copyback)
1292 gfc_add_modify (&parmse->post, vptr,
1293 fold_convert (TREE_TYPE (vptr), ctree));
1295 /* For unlimited polymorphic objects also set the _len component. */
1296 if (class_ts.type == BT_CLASS
1297 && class_ts.u.derived->components
1298 && class_ts.u.derived->components->ts.u
1299 .derived->attr.unlimited_polymorphic)
1301 ctree = gfc_class_len_get (var);
1302 if (UNLIMITED_POLY (e))
1303 tmp = gfc_class_len_get (tmp);
1304 else if (e->ts.type == BT_CHARACTER)
1306 gcc_assert (slen != NULL_TREE);
1307 tmp = slen;
1309 else
1310 tmp = build_zero_cst (size_type_node);
1311 gfc_add_modify (&parmse->pre, ctree,
1312 fold_convert (TREE_TYPE (ctree), tmp));
1314 /* Return the len component, except in the case of scalarized array
1315 references, where the dynamic type cannot change. */
1316 if (!elemental && full_array && copyback
1317 && (UNLIMITED_POLY (e) || VAR_P (tmp)))
1318 gfc_add_modify (&parmse->post, tmp,
1319 fold_convert (TREE_TYPE (tmp), ctree));
1322 if (optional)
1324 tree tmp2;
1326 cond = gfc_conv_expr_present (e->symtree->n.sym);
1327 /* parmse->pre may contain some preparatory instructions for the
1328 temporary array descriptor. Those may only be executed when the
1329 optional argument is set, therefore add parmse->pre's instructions
1330 to block, which is later guarded by an if (optional_arg_given). */
1331 gfc_add_block_to_block (&parmse->pre, &block);
1332 block.head = parmse->pre.head;
1333 parmse->pre.head = NULL_TREE;
1334 tmp = gfc_finish_block (&block);
1336 if (optional_alloc_ptr)
1337 tmp2 = build_empty_stmt (input_location);
1338 else
1340 gfc_init_block (&block);
1342 tmp2 = gfc_conv_descriptor_data_get (gfc_class_data_get (var));
1343 gfc_add_modify (&block, tmp2, fold_convert (TREE_TYPE (tmp2),
1344 null_pointer_node));
1345 tmp2 = gfc_finish_block (&block);
1348 tmp = build3_loc (input_location, COND_EXPR, void_type_node,
1349 cond, tmp, tmp2);
1350 gfc_add_expr_to_block (&parmse->pre, tmp);
1352 else
1353 gfc_add_block_to_block (&parmse->pre, &block);
1355 /* Pass the address of the class object. */
1356 parmse->expr = gfc_build_addr_expr (NULL_TREE, var);
1358 if (optional && optional_alloc_ptr)
1359 parmse->expr = build3_loc (input_location, COND_EXPR,
1360 TREE_TYPE (parmse->expr),
1361 cond, parmse->expr,
1362 fold_convert (TREE_TYPE (parmse->expr),
1363 null_pointer_node));
1367 /* Given a class array declaration and an index, returns the address
1368 of the referenced element. */
1370 tree
1371 gfc_get_class_array_ref (tree index, tree class_decl, tree data_comp,
1372 bool unlimited)
1374 tree data, size, tmp, ctmp, offset, ptr;
1376 data = data_comp != NULL_TREE ? data_comp :
1377 gfc_class_data_get (class_decl);
1378 size = gfc_class_vtab_size_get (class_decl);
1380 if (unlimited)
1382 tmp = fold_convert (gfc_array_index_type,
1383 gfc_class_len_get (class_decl));
1384 ctmp = fold_build2_loc (input_location, MULT_EXPR,
1385 gfc_array_index_type, size, tmp);
1386 tmp = fold_build2_loc (input_location, GT_EXPR,
1387 logical_type_node, tmp,
1388 build_zero_cst (TREE_TYPE (tmp)));
1389 size = fold_build3_loc (input_location, COND_EXPR,
1390 gfc_array_index_type, tmp, ctmp, size);
1393 offset = fold_build2_loc (input_location, MULT_EXPR,
1394 gfc_array_index_type,
1395 index, size);
1397 data = gfc_conv_descriptor_data_get (data);
1398 ptr = fold_convert (pvoid_type_node, data);
1399 ptr = fold_build_pointer_plus_loc (input_location, ptr, offset);
1400 return fold_convert (TREE_TYPE (data), ptr);
1404 /* Copies one class expression to another, assuming that if either
1405 'to' or 'from' are arrays they are packed. Should 'from' be
1406 NULL_TREE, the initialization expression for 'to' is used, assuming
1407 that the _vptr is set. */
1409 tree
1410 gfc_copy_class_to_class (tree from, tree to, tree nelems, bool unlimited)
1412 tree fcn;
1413 tree fcn_type;
1414 tree from_data;
1415 tree from_len;
1416 tree to_data;
1417 tree to_len;
1418 tree to_ref;
1419 tree from_ref;
1420 vec<tree, va_gc> *args;
1421 tree tmp;
1422 tree stdcopy;
1423 tree extcopy;
1424 tree index;
1425 bool is_from_desc = false, is_to_class = false;
1427 args = NULL;
1428 /* To prevent warnings on uninitialized variables. */
1429 from_len = to_len = NULL_TREE;
1431 if (from != NULL_TREE)
1432 fcn = gfc_class_vtab_copy_get (from);
1433 else
1434 fcn = gfc_class_vtab_copy_get (to);
1436 fcn_type = TREE_TYPE (TREE_TYPE (fcn));
1438 if (from != NULL_TREE)
1440 is_from_desc = GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (from));
1441 if (is_from_desc)
1443 from_data = from;
1444 from = GFC_DECL_SAVED_DESCRIPTOR (from);
1446 else
1448 /* Check that from is a class. When the class is part of a coarray,
1449 then from is a common pointer and is to be used as is. */
1450 tmp = POINTER_TYPE_P (TREE_TYPE (from))
1451 ? build_fold_indirect_ref (from) : from;
1452 from_data =
1453 (GFC_CLASS_TYPE_P (TREE_TYPE (tmp))
1454 || (DECL_P (tmp) && GFC_DECL_CLASS (tmp)))
1455 ? gfc_class_data_get (from) : from;
1456 is_from_desc = GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (from_data));
1459 else
1460 from_data = gfc_class_vtab_def_init_get (to);
1462 if (unlimited)
1464 if (from != NULL_TREE && unlimited)
1465 from_len = gfc_class_len_or_zero_get (from);
1466 else
1467 from_len = build_zero_cst (size_type_node);
1470 if (GFC_CLASS_TYPE_P (TREE_TYPE (to)))
1472 is_to_class = true;
1473 to_data = gfc_class_data_get (to);
1474 if (unlimited)
1475 to_len = gfc_class_len_get (to);
1477 else
1478 /* When to is a BT_DERIVED and not a BT_CLASS, then to_data == to. */
1479 to_data = to;
1481 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (to_data)))
1483 stmtblock_t loopbody;
1484 stmtblock_t body;
1485 stmtblock_t ifbody;
1486 gfc_loopinfo loop;
1487 tree orig_nelems = nelems; /* Needed for bounds check. */
1489 gfc_init_block (&body);
1490 tmp = fold_build2_loc (input_location, MINUS_EXPR,
1491 gfc_array_index_type, nelems,
1492 gfc_index_one_node);
1493 nelems = gfc_evaluate_now (tmp, &body);
1494 index = gfc_create_var (gfc_array_index_type, "S");
1496 if (is_from_desc)
1498 from_ref = gfc_get_class_array_ref (index, from, from_data,
1499 unlimited);
1500 vec_safe_push (args, from_ref);
1502 else
1503 vec_safe_push (args, from_data);
1505 if (is_to_class)
1506 to_ref = gfc_get_class_array_ref (index, to, to_data, unlimited);
1507 else
1509 tmp = gfc_conv_array_data (to);
1510 tmp = build_fold_indirect_ref_loc (input_location, tmp);
1511 to_ref = gfc_build_addr_expr (NULL_TREE,
1512 gfc_build_array_ref (tmp, index, to));
1514 vec_safe_push (args, to_ref);
1516 /* Add bounds check. */
1517 if ((gfc_option.rtcheck & GFC_RTCHECK_BOUNDS) > 0 && is_from_desc)
1519 char *msg;
1520 const char *name = "<<unknown>>";
1521 tree from_len;
1523 if (DECL_P (to))
1524 name = (const char *)(DECL_NAME (to)->identifier.id.str);
1526 from_len = gfc_conv_descriptor_size (from_data, 1);
1527 tmp = fold_build2_loc (input_location, NE_EXPR,
1528 logical_type_node, from_len, orig_nelems);
1529 msg = xasprintf ("Array bound mismatch for dimension %d "
1530 "of array '%s' (%%ld/%%ld)",
1531 1, name);
1533 gfc_trans_runtime_check (true, false, tmp, &body,
1534 &gfc_current_locus, msg,
1535 fold_convert (long_integer_type_node, orig_nelems),
1536 fold_convert (long_integer_type_node, from_len));
1538 free (msg);
1541 tmp = build_call_vec (fcn_type, fcn, args);
1543 /* Build the body of the loop. */
1544 gfc_init_block (&loopbody);
1545 gfc_add_expr_to_block (&loopbody, tmp);
1547 /* Build the loop and return. */
1548 gfc_init_loopinfo (&loop);
1549 loop.dimen = 1;
1550 loop.from[0] = gfc_index_zero_node;
1551 loop.loopvar[0] = index;
1552 loop.to[0] = nelems;
1553 gfc_trans_scalarizing_loops (&loop, &loopbody);
1554 gfc_init_block (&ifbody);
1555 gfc_add_block_to_block (&ifbody, &loop.pre);
1556 stdcopy = gfc_finish_block (&ifbody);
1557 /* In initialization mode from_len is a constant zero. */
1558 if (unlimited && !integer_zerop (from_len))
1560 vec_safe_push (args, from_len);
1561 vec_safe_push (args, to_len);
1562 tmp = build_call_vec (fcn_type, fcn, args);
1563 /* Build the body of the loop. */
1564 gfc_init_block (&loopbody);
1565 gfc_add_expr_to_block (&loopbody, tmp);
1567 /* Build the loop and return. */
1568 gfc_init_loopinfo (&loop);
1569 loop.dimen = 1;
1570 loop.from[0] = gfc_index_zero_node;
1571 loop.loopvar[0] = index;
1572 loop.to[0] = nelems;
1573 gfc_trans_scalarizing_loops (&loop, &loopbody);
1574 gfc_init_block (&ifbody);
1575 gfc_add_block_to_block (&ifbody, &loop.pre);
1576 extcopy = gfc_finish_block (&ifbody);
1578 tmp = fold_build2_loc (input_location, GT_EXPR,
1579 logical_type_node, from_len,
1580 build_zero_cst (TREE_TYPE (from_len)));
1581 tmp = fold_build3_loc (input_location, COND_EXPR,
1582 void_type_node, tmp, extcopy, stdcopy);
1583 gfc_add_expr_to_block (&body, tmp);
1584 tmp = gfc_finish_block (&body);
1586 else
1588 gfc_add_expr_to_block (&body, stdcopy);
1589 tmp = gfc_finish_block (&body);
1591 gfc_cleanup_loop (&loop);
1593 else
1595 gcc_assert (!is_from_desc);
1596 vec_safe_push (args, from_data);
1597 vec_safe_push (args, to_data);
1598 stdcopy = build_call_vec (fcn_type, fcn, args);
1600 /* In initialization mode from_len is a constant zero. */
1601 if (unlimited && !integer_zerop (from_len))
1603 vec_safe_push (args, from_len);
1604 vec_safe_push (args, to_len);
1605 extcopy = build_call_vec (fcn_type, unshare_expr (fcn), args);
1606 tmp = fold_build2_loc (input_location, GT_EXPR,
1607 logical_type_node, from_len,
1608 build_zero_cst (TREE_TYPE (from_len)));
1609 tmp = fold_build3_loc (input_location, COND_EXPR,
1610 void_type_node, tmp, extcopy, stdcopy);
1612 else
1613 tmp = stdcopy;
1616 /* Only copy _def_init to to_data, when it is not a NULL-pointer. */
1617 if (from == NULL_TREE)
1619 tree cond;
1620 cond = fold_build2_loc (input_location, NE_EXPR,
1621 logical_type_node,
1622 from_data, null_pointer_node);
1623 tmp = fold_build3_loc (input_location, COND_EXPR,
1624 void_type_node, cond,
1625 tmp, build_empty_stmt (input_location));
1628 return tmp;
1632 static tree
1633 gfc_trans_class_array_init_assign (gfc_expr *rhs, gfc_expr *lhs, gfc_expr *obj)
1635 gfc_actual_arglist *actual;
1636 gfc_expr *ppc;
1637 gfc_code *ppc_code;
1638 tree res;
1640 actual = gfc_get_actual_arglist ();
1641 actual->expr = gfc_copy_expr (rhs);
1642 actual->next = gfc_get_actual_arglist ();
1643 actual->next->expr = gfc_copy_expr (lhs);
1644 ppc = gfc_copy_expr (obj);
1645 gfc_add_vptr_component (ppc);
1646 gfc_add_component_ref (ppc, "_copy");
1647 ppc_code = gfc_get_code (EXEC_CALL);
1648 ppc_code->resolved_sym = ppc->symtree->n.sym;
1649 /* Although '_copy' is set to be elemental in class.c, it is
1650 not staying that way. Find out why, sometime.... */
1651 ppc_code->resolved_sym->attr.elemental = 1;
1652 ppc_code->ext.actual = actual;
1653 ppc_code->expr1 = ppc;
1654 /* Since '_copy' is elemental, the scalarizer will take care
1655 of arrays in gfc_trans_call. */
1656 res = gfc_trans_call (ppc_code, false, NULL, NULL, false);
1657 gfc_free_statements (ppc_code);
1659 if (UNLIMITED_POLY(obj))
1661 /* Check if rhs is non-NULL. */
1662 gfc_se src;
1663 gfc_init_se (&src, NULL);
1664 gfc_conv_expr (&src, rhs);
1665 src.expr = gfc_build_addr_expr (NULL_TREE, src.expr);
1666 tree cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
1667 src.expr, fold_convert (TREE_TYPE (src.expr),
1668 null_pointer_node));
1669 res = build3_loc (input_location, COND_EXPR, TREE_TYPE (res), cond, res,
1670 build_empty_stmt (input_location));
1673 return res;
1676 /* Special case for initializing a polymorphic dummy with INTENT(OUT).
1677 A MEMCPY is needed to copy the full data from the default initializer
1678 of the dynamic type. */
1680 tree
1681 gfc_trans_class_init_assign (gfc_code *code)
1683 stmtblock_t block;
1684 tree tmp;
1685 gfc_se dst,src,memsz;
1686 gfc_expr *lhs, *rhs, *sz;
1688 gfc_start_block (&block);
1690 lhs = gfc_copy_expr (code->expr1);
1692 rhs = gfc_copy_expr (code->expr1);
1693 gfc_add_vptr_component (rhs);
1695 /* Make sure that the component backend_decls have been built, which
1696 will not have happened if the derived types concerned have not
1697 been referenced. */
1698 gfc_get_derived_type (rhs->ts.u.derived);
1699 gfc_add_def_init_component (rhs);
1700 /* The _def_init is always scalar. */
1701 rhs->rank = 0;
1703 if (code->expr1->ts.type == BT_CLASS
1704 && CLASS_DATA (code->expr1)->attr.dimension)
1706 gfc_array_spec *tmparr = gfc_get_array_spec ();
1707 *tmparr = *CLASS_DATA (code->expr1)->as;
1708 /* Adding the array ref to the class expression results in correct
1709 indexing to the dynamic type. */
1710 gfc_add_full_array_ref (lhs, tmparr);
1711 tmp = gfc_trans_class_array_init_assign (rhs, lhs, code->expr1);
1713 else
1715 /* Scalar initialization needs the _data component. */
1716 gfc_add_data_component (lhs);
1717 sz = gfc_copy_expr (code->expr1);
1718 gfc_add_vptr_component (sz);
1719 gfc_add_size_component (sz);
1721 gfc_init_se (&dst, NULL);
1722 gfc_init_se (&src, NULL);
1723 gfc_init_se (&memsz, NULL);
1724 gfc_conv_expr (&dst, lhs);
1725 gfc_conv_expr (&src, rhs);
1726 gfc_conv_expr (&memsz, sz);
1727 gfc_add_block_to_block (&block, &src.pre);
1728 src.expr = gfc_build_addr_expr (NULL_TREE, src.expr);
1730 tmp = gfc_build_memcpy_call (dst.expr, src.expr, memsz.expr);
1732 if (UNLIMITED_POLY(code->expr1))
1734 /* Check if _def_init is non-NULL. */
1735 tree cond = fold_build2_loc (input_location, NE_EXPR,
1736 logical_type_node, src.expr,
1737 fold_convert (TREE_TYPE (src.expr),
1738 null_pointer_node));
1739 tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp), cond,
1740 tmp, build_empty_stmt (input_location));
1744 if (code->expr1->symtree->n.sym->attr.dummy
1745 && (code->expr1->symtree->n.sym->attr.optional
1746 || code->expr1->symtree->n.sym->ns->proc_name->attr.entry_master))
1748 tree present = gfc_conv_expr_present (code->expr1->symtree->n.sym);
1749 tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp),
1750 present, tmp,
1751 build_empty_stmt (input_location));
1754 gfc_add_expr_to_block (&block, tmp);
1756 return gfc_finish_block (&block);
1760 /* Class valued elemental function calls or class array elements arriving
1761 in gfc_trans_scalar_assign come here. Wherever possible the vptr copy
1762 is used to ensure that the rhs dynamic type is assigned to the lhs. */
1764 static bool
1765 trans_scalar_class_assign (stmtblock_t *block, gfc_se *lse, gfc_se *rse)
1767 tree fcn;
1768 tree rse_expr;
1769 tree class_data;
1770 tree tmp;
1771 tree zero;
1772 tree cond;
1773 tree final_cond;
1774 stmtblock_t inner_block;
1775 bool is_descriptor;
1776 bool not_call_expr = TREE_CODE (rse->expr) != CALL_EXPR;
1777 bool not_lhs_array_type;
1779 /* Temporaries arising from depencies in assignment get cast as a
1780 character type of the dynamic size of the rhs. Use the vptr copy
1781 for this case. */
1782 tmp = TREE_TYPE (lse->expr);
1783 not_lhs_array_type = !(tmp && TREE_CODE (tmp) == ARRAY_TYPE
1784 && TYPE_MAX_VALUE (TYPE_DOMAIN (tmp)) != NULL_TREE);
1786 /* Use ordinary assignment if the rhs is not a call expression or
1787 the lhs is not a class entity or an array(ie. character) type. */
1788 if ((not_call_expr && gfc_get_class_from_expr (lse->expr) == NULL_TREE)
1789 && not_lhs_array_type)
1790 return false;
1792 /* Ordinary assignment can be used if both sides are class expressions
1793 since the dynamic type is preserved by copying the vptr. This
1794 should only occur, where temporaries are involved. */
1795 if (GFC_CLASS_TYPE_P (TREE_TYPE (lse->expr))
1796 && GFC_CLASS_TYPE_P (TREE_TYPE (rse->expr)))
1797 return false;
1799 /* Fix the class expression and the class data of the rhs. */
1800 if (!GFC_CLASS_TYPE_P (TREE_TYPE (rse->expr))
1801 || not_call_expr)
1803 tmp = gfc_get_class_from_expr (rse->expr);
1804 if (tmp == NULL_TREE)
1805 return false;
1806 rse_expr = gfc_evaluate_now (tmp, block);
1808 else
1809 rse_expr = gfc_evaluate_now (rse->expr, block);
1811 class_data = gfc_class_data_get (rse_expr);
1813 /* Check that the rhs data is not null. */
1814 is_descriptor = GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (class_data));
1815 if (is_descriptor)
1816 class_data = gfc_conv_descriptor_data_get (class_data);
1817 class_data = gfc_evaluate_now (class_data, block);
1819 zero = build_int_cst (TREE_TYPE (class_data), 0);
1820 cond = fold_build2_loc (input_location, NE_EXPR,
1821 logical_type_node,
1822 class_data, zero);
1824 /* Copy the rhs to the lhs. */
1825 fcn = gfc_vptr_copy_get (gfc_class_vptr_get (rse_expr));
1826 fcn = build_fold_indirect_ref_loc (input_location, fcn);
1827 tmp = gfc_evaluate_now (gfc_build_addr_expr (NULL, rse->expr), block);
1828 tmp = is_descriptor ? tmp : class_data;
1829 tmp = build_call_expr_loc (input_location, fcn, 2, tmp,
1830 gfc_build_addr_expr (NULL, lse->expr));
1831 gfc_add_expr_to_block (block, tmp);
1833 /* Only elemental function results need to be finalised and freed. */
1834 if (not_call_expr)
1835 return true;
1837 /* Finalize the class data if needed. */
1838 gfc_init_block (&inner_block);
1839 fcn = gfc_vptr_final_get (gfc_class_vptr_get (rse_expr));
1840 zero = build_int_cst (TREE_TYPE (fcn), 0);
1841 final_cond = fold_build2_loc (input_location, NE_EXPR,
1842 logical_type_node, fcn, zero);
1843 fcn = build_fold_indirect_ref_loc (input_location, fcn);
1844 tmp = build_call_expr_loc (input_location, fcn, 1, class_data);
1845 tmp = build3_v (COND_EXPR, final_cond,
1846 tmp, build_empty_stmt (input_location));
1847 gfc_add_expr_to_block (&inner_block, tmp);
1849 /* Free the class data. */
1850 tmp = gfc_call_free (class_data);
1851 tmp = build3_v (COND_EXPR, cond, tmp,
1852 build_empty_stmt (input_location));
1853 gfc_add_expr_to_block (&inner_block, tmp);
1855 /* Finish the inner block and subject it to the condition on the
1856 class data being non-zero. */
1857 tmp = gfc_finish_block (&inner_block);
1858 tmp = build3_v (COND_EXPR, cond, tmp,
1859 build_empty_stmt (input_location));
1860 gfc_add_expr_to_block (block, tmp);
1862 return true;
1865 /* End of prototype trans-class.c */
1868 static void
1869 realloc_lhs_warning (bt type, bool array, locus *where)
1871 if (array && type != BT_CLASS && type != BT_DERIVED && warn_realloc_lhs)
1872 gfc_warning (OPT_Wrealloc_lhs,
1873 "Code for reallocating the allocatable array at %L will "
1874 "be added", where);
1875 else if (warn_realloc_lhs_all)
1876 gfc_warning (OPT_Wrealloc_lhs_all,
1877 "Code for reallocating the allocatable variable at %L "
1878 "will be added", where);
1882 static void gfc_apply_interface_mapping_to_expr (gfc_interface_mapping *,
1883 gfc_expr *);
1885 /* Copy the scalarization loop variables. */
1887 static void
1888 gfc_copy_se_loopvars (gfc_se * dest, gfc_se * src)
1890 dest->ss = src->ss;
1891 dest->loop = src->loop;
1895 /* Initialize a simple expression holder.
1897 Care must be taken when multiple se are created with the same parent.
1898 The child se must be kept in sync. The easiest way is to delay creation
1899 of a child se until after the previous se has been translated. */
1901 void
1902 gfc_init_se (gfc_se * se, gfc_se * parent)
1904 memset (se, 0, sizeof (gfc_se));
1905 gfc_init_block (&se->pre);
1906 gfc_init_block (&se->post);
1908 se->parent = parent;
1910 if (parent)
1911 gfc_copy_se_loopvars (se, parent);
1915 /* Advances to the next SS in the chain. Use this rather than setting
1916 se->ss = se->ss->next because all the parents needs to be kept in sync.
1917 See gfc_init_se. */
1919 void
1920 gfc_advance_se_ss_chain (gfc_se * se)
1922 gfc_se *p;
1923 gfc_ss *ss;
1925 gcc_assert (se != NULL && se->ss != NULL && se->ss != gfc_ss_terminator);
1927 p = se;
1928 /* Walk down the parent chain. */
1929 while (p != NULL)
1931 /* Simple consistency check. */
1932 gcc_assert (p->parent == NULL || p->parent->ss == p->ss
1933 || p->parent->ss->nested_ss == p->ss);
1935 /* If we were in a nested loop, the next scalarized expression can be
1936 on the parent ss' next pointer. Thus we should not take the next
1937 pointer blindly, but rather go up one nest level as long as next
1938 is the end of chain. */
1939 ss = p->ss;
1940 while (ss->next == gfc_ss_terminator && ss->parent != NULL)
1941 ss = ss->parent;
1943 p->ss = ss->next;
1945 p = p->parent;
1950 /* Ensures the result of the expression as either a temporary variable
1951 or a constant so that it can be used repeatedly. */
1953 void
1954 gfc_make_safe_expr (gfc_se * se)
1956 tree var;
1958 if (CONSTANT_CLASS_P (se->expr))
1959 return;
1961 /* We need a temporary for this result. */
1962 var = gfc_create_var (TREE_TYPE (se->expr), NULL);
1963 gfc_add_modify (&se->pre, var, se->expr);
1964 se->expr = var;
1968 /* Return an expression which determines if a dummy parameter is present.
1969 Also used for arguments to procedures with multiple entry points. */
1971 tree
1972 gfc_conv_expr_present (gfc_symbol * sym, bool use_saved_desc)
1974 tree decl, orig_decl, cond;
1976 gcc_assert (sym->attr.dummy);
1977 orig_decl = decl = gfc_get_symbol_decl (sym);
1979 /* Intrinsic scalars with VALUE attribute which are passed by value
1980 use a hidden argument to denote the present status. */
1981 if (sym->attr.value && sym->ts.type != BT_CHARACTER
1982 && sym->ts.type != BT_CLASS && sym->ts.type != BT_DERIVED
1983 && !sym->attr.dimension)
1985 char name[GFC_MAX_SYMBOL_LEN + 2];
1986 tree tree_name;
1988 gcc_assert (TREE_CODE (decl) == PARM_DECL);
1989 name[0] = '_';
1990 strcpy (&name[1], sym->name);
1991 tree_name = get_identifier (name);
1993 /* Walk function argument list to find hidden arg. */
1994 cond = DECL_ARGUMENTS (DECL_CONTEXT (decl));
1995 for ( ; cond != NULL_TREE; cond = TREE_CHAIN (cond))
1996 if (DECL_NAME (cond) == tree_name
1997 && DECL_ARTIFICIAL (cond))
1998 break;
2000 gcc_assert (cond);
2001 return cond;
2004 /* Assumed-shape arrays use a local variable for the array data;
2005 the actual PARAM_DECL is in a saved decl. As the local variable
2006 is NULL, it can be checked instead, unless use_saved_desc is
2007 requested. */
2009 if (use_saved_desc && TREE_CODE (decl) != PARM_DECL)
2011 gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl))
2012 || GFC_ARRAY_TYPE_P (TREE_TYPE (decl)));
2013 decl = GFC_DECL_SAVED_DESCRIPTOR (decl);
2016 cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node, decl,
2017 fold_convert (TREE_TYPE (decl), null_pointer_node));
2019 /* Fortran 2008 allows to pass null pointers and non-associated pointers
2020 as actual argument to denote absent dummies. For array descriptors,
2021 we thus also need to check the array descriptor. For BT_CLASS, it
2022 can also occur for scalars and F2003 due to type->class wrapping and
2023 class->class wrapping. Note further that BT_CLASS always uses an
2024 array descriptor for arrays, also for explicit-shape/assumed-size.
2025 For assumed-rank arrays, no local variable is generated, hence,
2026 the following also applies with !use_saved_desc. */
2028 if ((use_saved_desc || TREE_CODE (orig_decl) == PARM_DECL)
2029 && !sym->attr.allocatable
2030 && ((sym->ts.type != BT_CLASS && !sym->attr.pointer)
2031 || (sym->ts.type == BT_CLASS
2032 && !CLASS_DATA (sym)->attr.allocatable
2033 && !CLASS_DATA (sym)->attr.class_pointer))
2034 && ((gfc_option.allow_std & GFC_STD_F2008) != 0
2035 || sym->ts.type == BT_CLASS))
2037 tree tmp;
2039 if ((sym->as && (sym->as->type == AS_ASSUMED_SHAPE
2040 || sym->as->type == AS_ASSUMED_RANK
2041 || sym->attr.codimension))
2042 || (sym->ts.type == BT_CLASS && CLASS_DATA (sym)->as))
2044 tmp = build_fold_indirect_ref_loc (input_location, decl);
2045 if (sym->ts.type == BT_CLASS)
2046 tmp = gfc_class_data_get (tmp);
2047 tmp = gfc_conv_array_data (tmp);
2049 else if (sym->ts.type == BT_CLASS)
2050 tmp = gfc_class_data_get (decl);
2051 else
2052 tmp = NULL_TREE;
2054 if (tmp != NULL_TREE)
2056 tmp = fold_build2_loc (input_location, NE_EXPR, logical_type_node, tmp,
2057 fold_convert (TREE_TYPE (tmp), null_pointer_node));
2058 cond = fold_build2_loc (input_location, TRUTH_ANDIF_EXPR,
2059 logical_type_node, cond, tmp);
2063 return cond;
2067 /* Converts a missing, dummy argument into a null or zero. */
2069 void
2070 gfc_conv_missing_dummy (gfc_se * se, gfc_expr * arg, gfc_typespec ts, int kind)
2072 tree present;
2073 tree tmp;
2075 present = gfc_conv_expr_present (arg->symtree->n.sym);
2077 if (kind > 0)
2079 /* Create a temporary and convert it to the correct type. */
2080 tmp = gfc_get_int_type (kind);
2081 tmp = fold_convert (tmp, build_fold_indirect_ref_loc (input_location,
2082 se->expr));
2084 /* Test for a NULL value. */
2085 tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp), present,
2086 tmp, fold_convert (TREE_TYPE (tmp), integer_one_node));
2087 tmp = gfc_evaluate_now (tmp, &se->pre);
2088 se->expr = gfc_build_addr_expr (NULL_TREE, tmp);
2090 else
2092 tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (se->expr),
2093 present, se->expr,
2094 build_zero_cst (TREE_TYPE (se->expr)));
2095 tmp = gfc_evaluate_now (tmp, &se->pre);
2096 se->expr = tmp;
2099 if (ts.type == BT_CHARACTER)
2101 tmp = build_int_cst (gfc_charlen_type_node, 0);
2102 tmp = fold_build3_loc (input_location, COND_EXPR, gfc_charlen_type_node,
2103 present, se->string_length, tmp);
2104 tmp = gfc_evaluate_now (tmp, &se->pre);
2105 se->string_length = tmp;
2107 return;
2111 /* Get the character length of an expression, looking through gfc_refs
2112 if necessary. */
2114 tree
2115 gfc_get_expr_charlen (gfc_expr *e)
2117 gfc_ref *r;
2118 tree length;
2119 gfc_se se;
2121 gcc_assert (e->expr_type == EXPR_VARIABLE
2122 && e->ts.type == BT_CHARACTER);
2124 length = NULL; /* To silence compiler warning. */
2126 if (is_subref_array (e) && e->ts.u.cl->length)
2128 gfc_se tmpse;
2129 gfc_init_se (&tmpse, NULL);
2130 gfc_conv_expr_type (&tmpse, e->ts.u.cl->length, gfc_charlen_type_node);
2131 e->ts.u.cl->backend_decl = tmpse.expr;
2132 return tmpse.expr;
2135 /* First candidate: if the variable is of type CHARACTER, the
2136 expression's length could be the length of the character
2137 variable. */
2138 if (e->symtree->n.sym->ts.type == BT_CHARACTER)
2139 length = e->symtree->n.sym->ts.u.cl->backend_decl;
2141 /* Look through the reference chain for component references. */
2142 for (r = e->ref; r; r = r->next)
2144 switch (r->type)
2146 case REF_COMPONENT:
2147 if (r->u.c.component->ts.type == BT_CHARACTER)
2148 length = r->u.c.component->ts.u.cl->backend_decl;
2149 break;
2151 case REF_ARRAY:
2152 /* Do nothing. */
2153 break;
2155 case REF_SUBSTRING:
2156 gfc_init_se (&se, NULL);
2157 gfc_conv_expr_type (&se, r->u.ss.start, gfc_charlen_type_node);
2158 length = se.expr;
2159 gfc_conv_expr_type (&se, r->u.ss.end, gfc_charlen_type_node);
2160 length = fold_build2_loc (input_location, MINUS_EXPR,
2161 gfc_charlen_type_node,
2162 se.expr, length);
2163 length = fold_build2_loc (input_location, PLUS_EXPR,
2164 gfc_charlen_type_node, length,
2165 gfc_index_one_node);
2166 break;
2168 default:
2169 gcc_unreachable ();
2170 break;
2174 gcc_assert (length != NULL);
2175 return length;
2179 /* Return for an expression the backend decl of the coarray. */
2181 tree
2182 gfc_get_tree_for_caf_expr (gfc_expr *expr)
2184 tree caf_decl;
2185 bool found = false;
2186 gfc_ref *ref;
2188 gcc_assert (expr && expr->expr_type == EXPR_VARIABLE);
2190 /* Not-implemented diagnostic. */
2191 if (expr->symtree->n.sym->ts.type == BT_CLASS
2192 && UNLIMITED_POLY (expr->symtree->n.sym)
2193 && CLASS_DATA (expr->symtree->n.sym)->attr.codimension)
2194 gfc_error ("Sorry, coindexed access to an unlimited polymorphic object at "
2195 "%L is not supported", &expr->where);
2197 for (ref = expr->ref; ref; ref = ref->next)
2198 if (ref->type == REF_COMPONENT)
2200 if (ref->u.c.component->ts.type == BT_CLASS
2201 && UNLIMITED_POLY (ref->u.c.component)
2202 && CLASS_DATA (ref->u.c.component)->attr.codimension)
2203 gfc_error ("Sorry, coindexed access to an unlimited polymorphic "
2204 "component at %L is not supported", &expr->where);
2207 /* Make sure the backend_decl is present before accessing it. */
2208 caf_decl = expr->symtree->n.sym->backend_decl == NULL_TREE
2209 ? gfc_get_symbol_decl (expr->symtree->n.sym)
2210 : expr->symtree->n.sym->backend_decl;
2212 if (expr->symtree->n.sym->ts.type == BT_CLASS)
2214 if (expr->ref && expr->ref->type == REF_ARRAY)
2216 caf_decl = gfc_class_data_get (caf_decl);
2217 if (CLASS_DATA (expr->symtree->n.sym)->attr.codimension)
2218 return caf_decl;
2220 for (ref = expr->ref; ref; ref = ref->next)
2222 if (ref->type == REF_COMPONENT
2223 && strcmp (ref->u.c.component->name, "_data") != 0)
2225 caf_decl = gfc_class_data_get (caf_decl);
2226 if (CLASS_DATA (expr->symtree->n.sym)->attr.codimension)
2227 return caf_decl;
2228 break;
2230 else if (ref->type == REF_ARRAY && ref->u.ar.dimen)
2231 break;
2234 if (expr->symtree->n.sym->attr.codimension)
2235 return caf_decl;
2237 /* The following code assumes that the coarray is a component reachable via
2238 only scalar components/variables; the Fortran standard guarantees this. */
2240 for (ref = expr->ref; ref; ref = ref->next)
2241 if (ref->type == REF_COMPONENT)
2243 gfc_component *comp = ref->u.c.component;
2245 if (POINTER_TYPE_P (TREE_TYPE (caf_decl)))
2246 caf_decl = build_fold_indirect_ref_loc (input_location, caf_decl);
2247 caf_decl = fold_build3_loc (input_location, COMPONENT_REF,
2248 TREE_TYPE (comp->backend_decl), caf_decl,
2249 comp->backend_decl, NULL_TREE);
2250 if (comp->ts.type == BT_CLASS)
2252 caf_decl = gfc_class_data_get (caf_decl);
2253 if (CLASS_DATA (comp)->attr.codimension)
2255 found = true;
2256 break;
2259 if (comp->attr.codimension)
2261 found = true;
2262 break;
2265 gcc_assert (found && caf_decl);
2266 return caf_decl;
2270 /* Obtain the Coarray token - and optionally also the offset. */
2272 void
2273 gfc_get_caf_token_offset (gfc_se *se, tree *token, tree *offset, tree caf_decl,
2274 tree se_expr, gfc_expr *expr)
2276 tree tmp;
2278 /* Coarray token. */
2279 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (caf_decl)))
2281 gcc_assert (GFC_TYPE_ARRAY_AKIND (TREE_TYPE (caf_decl))
2282 == GFC_ARRAY_ALLOCATABLE
2283 || expr->symtree->n.sym->attr.select_type_temporary);
2284 *token = gfc_conv_descriptor_token (caf_decl);
2286 else if (DECL_LANG_SPECIFIC (caf_decl)
2287 && GFC_DECL_TOKEN (caf_decl) != NULL_TREE)
2288 *token = GFC_DECL_TOKEN (caf_decl);
2289 else
2291 gcc_assert (GFC_ARRAY_TYPE_P (TREE_TYPE (caf_decl))
2292 && GFC_TYPE_ARRAY_CAF_TOKEN (TREE_TYPE (caf_decl)) != NULL_TREE);
2293 *token = GFC_TYPE_ARRAY_CAF_TOKEN (TREE_TYPE (caf_decl));
2296 if (offset == NULL)
2297 return;
2299 /* Offset between the coarray base address and the address wanted. */
2300 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (caf_decl))
2301 && (GFC_TYPE_ARRAY_AKIND (TREE_TYPE (caf_decl)) == GFC_ARRAY_ALLOCATABLE
2302 || GFC_TYPE_ARRAY_AKIND (TREE_TYPE (caf_decl)) == GFC_ARRAY_POINTER))
2303 *offset = build_int_cst (gfc_array_index_type, 0);
2304 else if (DECL_LANG_SPECIFIC (caf_decl)
2305 && GFC_DECL_CAF_OFFSET (caf_decl) != NULL_TREE)
2306 *offset = GFC_DECL_CAF_OFFSET (caf_decl);
2307 else if (GFC_TYPE_ARRAY_CAF_OFFSET (TREE_TYPE (caf_decl)) != NULL_TREE)
2308 *offset = GFC_TYPE_ARRAY_CAF_OFFSET (TREE_TYPE (caf_decl));
2309 else
2310 *offset = build_int_cst (gfc_array_index_type, 0);
2312 if (POINTER_TYPE_P (TREE_TYPE (se_expr))
2313 && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (TREE_TYPE (se_expr))))
2315 tmp = build_fold_indirect_ref_loc (input_location, se_expr);
2316 tmp = gfc_conv_descriptor_data_get (tmp);
2318 else if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se_expr)))
2319 tmp = gfc_conv_descriptor_data_get (se_expr);
2320 else
2322 gcc_assert (POINTER_TYPE_P (TREE_TYPE (se_expr)));
2323 tmp = se_expr;
2326 *offset = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
2327 *offset, fold_convert (gfc_array_index_type, tmp));
2329 if (expr->symtree->n.sym->ts.type == BT_DERIVED
2330 && expr->symtree->n.sym->attr.codimension
2331 && expr->symtree->n.sym->ts.u.derived->attr.alloc_comp)
2333 gfc_expr *base_expr = gfc_copy_expr (expr);
2334 gfc_ref *ref = base_expr->ref;
2335 gfc_se base_se;
2337 // Iterate through the refs until the last one.
2338 while (ref->next)
2339 ref = ref->next;
2341 if (ref->type == REF_ARRAY
2342 && ref->u.ar.type != AR_FULL)
2344 const int ranksum = ref->u.ar.dimen + ref->u.ar.codimen;
2345 int i;
2346 for (i = 0; i < ranksum; ++i)
2348 ref->u.ar.start[i] = NULL;
2349 ref->u.ar.end[i] = NULL;
2351 ref->u.ar.type = AR_FULL;
2353 gfc_init_se (&base_se, NULL);
2354 if (gfc_caf_attr (base_expr).dimension)
2356 gfc_conv_expr_descriptor (&base_se, base_expr);
2357 tmp = gfc_conv_descriptor_data_get (base_se.expr);
2359 else
2361 gfc_conv_expr (&base_se, base_expr);
2362 tmp = base_se.expr;
2365 gfc_free_expr (base_expr);
2366 gfc_add_block_to_block (&se->pre, &base_se.pre);
2367 gfc_add_block_to_block (&se->post, &base_se.post);
2369 else if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (caf_decl)))
2370 tmp = gfc_conv_descriptor_data_get (caf_decl);
2371 else
2373 gcc_assert (POINTER_TYPE_P (TREE_TYPE (caf_decl)));
2374 tmp = caf_decl;
2377 *offset = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
2378 fold_convert (gfc_array_index_type, *offset),
2379 fold_convert (gfc_array_index_type, tmp));
2383 /* Convert the coindex of a coarray into an image index; the result is
2384 image_num = (idx(1)-lcobound(1)+1) + (idx(2)-lcobound(2))*extent(1)
2385 + (idx(3)-lcobound(3))*extend(1)*extent(2) + ... */
2387 tree
2388 gfc_caf_get_image_index (stmtblock_t *block, gfc_expr *e, tree desc)
2390 gfc_ref *ref;
2391 tree lbound, ubound, extent, tmp, img_idx;
2392 gfc_se se;
2393 int i;
2395 for (ref = e->ref; ref; ref = ref->next)
2396 if (ref->type == REF_ARRAY && ref->u.ar.codimen > 0)
2397 break;
2398 gcc_assert (ref != NULL);
2400 if (ref->u.ar.dimen_type[ref->u.ar.dimen] == DIMEN_THIS_IMAGE)
2402 return build_call_expr_loc (input_location, gfor_fndecl_caf_this_image, 1,
2403 integer_zero_node);
2406 img_idx = build_zero_cst (gfc_array_index_type);
2407 extent = build_one_cst (gfc_array_index_type);
2408 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (desc)))
2409 for (i = ref->u.ar.dimen; i < ref->u.ar.dimen + ref->u.ar.codimen; i++)
2411 gfc_init_se (&se, NULL);
2412 gfc_conv_expr_type (&se, ref->u.ar.start[i], gfc_array_index_type);
2413 gfc_add_block_to_block (block, &se.pre);
2414 lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[i]);
2415 tmp = fold_build2_loc (input_location, MINUS_EXPR,
2416 TREE_TYPE (lbound), se.expr, lbound);
2417 tmp = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (tmp),
2418 extent, tmp);
2419 img_idx = fold_build2_loc (input_location, PLUS_EXPR,
2420 TREE_TYPE (tmp), img_idx, tmp);
2421 if (i < ref->u.ar.dimen + ref->u.ar.codimen - 1)
2423 ubound = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[i]);
2424 tmp = gfc_conv_array_extent_dim (lbound, ubound, NULL);
2425 extent = fold_build2_loc (input_location, MULT_EXPR,
2426 TREE_TYPE (tmp), extent, tmp);
2429 else
2430 for (i = ref->u.ar.dimen; i < ref->u.ar.dimen + ref->u.ar.codimen; i++)
2432 gfc_init_se (&se, NULL);
2433 gfc_conv_expr_type (&se, ref->u.ar.start[i], gfc_array_index_type);
2434 gfc_add_block_to_block (block, &se.pre);
2435 lbound = GFC_TYPE_ARRAY_LBOUND (TREE_TYPE (desc), i);
2436 tmp = fold_build2_loc (input_location, MINUS_EXPR,
2437 TREE_TYPE (lbound), se.expr, lbound);
2438 tmp = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (tmp),
2439 extent, tmp);
2440 img_idx = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (tmp),
2441 img_idx, tmp);
2442 if (i < ref->u.ar.dimen + ref->u.ar.codimen - 1)
2444 ubound = GFC_TYPE_ARRAY_UBOUND (TREE_TYPE (desc), i);
2445 tmp = fold_build2_loc (input_location, MINUS_EXPR,
2446 TREE_TYPE (ubound), ubound, lbound);
2447 tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (tmp),
2448 tmp, build_one_cst (TREE_TYPE (tmp)));
2449 extent = fold_build2_loc (input_location, MULT_EXPR,
2450 TREE_TYPE (tmp), extent, tmp);
2453 img_idx = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (img_idx),
2454 img_idx, build_one_cst (TREE_TYPE (img_idx)));
2455 return fold_convert (integer_type_node, img_idx);
2459 /* For each character array constructor subexpression without a ts.u.cl->length,
2460 replace it by its first element (if there aren't any elements, the length
2461 should already be set to zero). */
2463 static void
2464 flatten_array_ctors_without_strlen (gfc_expr* e)
2466 gfc_actual_arglist* arg;
2467 gfc_constructor* c;
2469 if (!e)
2470 return;
2472 switch (e->expr_type)
2475 case EXPR_OP:
2476 flatten_array_ctors_without_strlen (e->value.op.op1);
2477 flatten_array_ctors_without_strlen (e->value.op.op2);
2478 break;
2480 case EXPR_COMPCALL:
2481 /* TODO: Implement as with EXPR_FUNCTION when needed. */
2482 gcc_unreachable ();
2484 case EXPR_FUNCTION:
2485 for (arg = e->value.function.actual; arg; arg = arg->next)
2486 flatten_array_ctors_without_strlen (arg->expr);
2487 break;
2489 case EXPR_ARRAY:
2491 /* We've found what we're looking for. */
2492 if (e->ts.type == BT_CHARACTER && !e->ts.u.cl->length)
2494 gfc_constructor *c;
2495 gfc_expr* new_expr;
2497 gcc_assert (e->value.constructor);
2499 c = gfc_constructor_first (e->value.constructor);
2500 new_expr = c->expr;
2501 c->expr = NULL;
2503 flatten_array_ctors_without_strlen (new_expr);
2504 gfc_replace_expr (e, new_expr);
2505 break;
2508 /* Otherwise, fall through to handle constructor elements. */
2509 gcc_fallthrough ();
2510 case EXPR_STRUCTURE:
2511 for (c = gfc_constructor_first (e->value.constructor);
2512 c; c = gfc_constructor_next (c))
2513 flatten_array_ctors_without_strlen (c->expr);
2514 break;
2516 default:
2517 break;
2523 /* Generate code to initialize a string length variable. Returns the
2524 value. For array constructors, cl->length might be NULL and in this case,
2525 the first element of the constructor is needed. expr is the original
2526 expression so we can access it but can be NULL if this is not needed. */
2528 void
2529 gfc_conv_string_length (gfc_charlen * cl, gfc_expr * expr, stmtblock_t * pblock)
2531 gfc_se se;
2533 gfc_init_se (&se, NULL);
2535 if (!cl->length && cl->backend_decl && VAR_P (cl->backend_decl))
2536 return;
2538 /* If cl->length is NULL, use gfc_conv_expr to obtain the string length but
2539 "flatten" array constructors by taking their first element; all elements
2540 should be the same length or a cl->length should be present. */
2541 if (!cl->length)
2543 gfc_expr* expr_flat;
2544 if (!expr)
2545 return;
2546 expr_flat = gfc_copy_expr (expr);
2547 flatten_array_ctors_without_strlen (expr_flat);
2548 gfc_resolve_expr (expr_flat);
2550 gfc_conv_expr (&se, expr_flat);
2551 gfc_add_block_to_block (pblock, &se.pre);
2552 cl->backend_decl = convert (gfc_charlen_type_node, se.string_length);
2554 gfc_free_expr (expr_flat);
2555 return;
2558 /* Convert cl->length. */
2560 gcc_assert (cl->length);
2562 gfc_conv_expr_type (&se, cl->length, gfc_charlen_type_node);
2563 se.expr = fold_build2_loc (input_location, MAX_EXPR, gfc_charlen_type_node,
2564 se.expr, build_zero_cst (TREE_TYPE (se.expr)));
2565 gfc_add_block_to_block (pblock, &se.pre);
2567 if (cl->backend_decl && VAR_P (cl->backend_decl))
2568 gfc_add_modify (pblock, cl->backend_decl, se.expr);
2569 else
2570 cl->backend_decl = gfc_evaluate_now (se.expr, pblock);
2574 static void
2575 gfc_conv_substring (gfc_se * se, gfc_ref * ref, int kind,
2576 const char *name, locus *where)
2578 tree tmp;
2579 tree type;
2580 tree fault;
2581 gfc_se start;
2582 gfc_se end;
2583 char *msg;
2584 mpz_t length;
2586 type = gfc_get_character_type (kind, ref->u.ss.length);
2587 type = build_pointer_type (type);
2589 gfc_init_se (&start, se);
2590 gfc_conv_expr_type (&start, ref->u.ss.start, gfc_charlen_type_node);
2591 gfc_add_block_to_block (&se->pre, &start.pre);
2593 if (integer_onep (start.expr))
2594 gfc_conv_string_parameter (se);
2595 else
2597 tmp = start.expr;
2598 STRIP_NOPS (tmp);
2599 /* Avoid multiple evaluation of substring start. */
2600 if (!CONSTANT_CLASS_P (tmp) && !DECL_P (tmp))
2601 start.expr = gfc_evaluate_now (start.expr, &se->pre);
2603 /* Change the start of the string. */
2604 if ((TREE_CODE (TREE_TYPE (se->expr)) == ARRAY_TYPE
2605 || TREE_CODE (TREE_TYPE (se->expr)) == INTEGER_TYPE)
2606 && TYPE_STRING_FLAG (TREE_TYPE (se->expr)))
2607 tmp = se->expr;
2608 else
2609 tmp = build_fold_indirect_ref_loc (input_location,
2610 se->expr);
2611 /* For BIND(C), a BT_CHARACTER is not an ARRAY_TYPE. */
2612 if (TREE_CODE (TREE_TYPE (tmp)) == ARRAY_TYPE)
2614 tmp = gfc_build_array_ref (tmp, start.expr, NULL);
2615 se->expr = gfc_build_addr_expr (type, tmp);
2619 /* Length = end + 1 - start. */
2620 gfc_init_se (&end, se);
2621 if (ref->u.ss.end == NULL)
2622 end.expr = se->string_length;
2623 else
2625 gfc_conv_expr_type (&end, ref->u.ss.end, gfc_charlen_type_node);
2626 gfc_add_block_to_block (&se->pre, &end.pre);
2628 tmp = end.expr;
2629 STRIP_NOPS (tmp);
2630 if (!CONSTANT_CLASS_P (tmp) && !DECL_P (tmp))
2631 end.expr = gfc_evaluate_now (end.expr, &se->pre);
2633 if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
2635 tree nonempty = fold_build2_loc (input_location, LE_EXPR,
2636 logical_type_node, start.expr,
2637 end.expr);
2639 /* Check lower bound. */
2640 fault = fold_build2_loc (input_location, LT_EXPR, logical_type_node,
2641 start.expr,
2642 build_one_cst (TREE_TYPE (start.expr)));
2643 fault = fold_build2_loc (input_location, TRUTH_ANDIF_EXPR,
2644 logical_type_node, nonempty, fault);
2645 if (name)
2646 msg = xasprintf ("Substring out of bounds: lower bound (%%ld) of '%s' "
2647 "is less than one", name);
2648 else
2649 msg = xasprintf ("Substring out of bounds: lower bound (%%ld) "
2650 "is less than one");
2651 gfc_trans_runtime_check (true, false, fault, &se->pre, where, msg,
2652 fold_convert (long_integer_type_node,
2653 start.expr));
2654 free (msg);
2656 /* Check upper bound. */
2657 fault = fold_build2_loc (input_location, GT_EXPR, logical_type_node,
2658 end.expr, se->string_length);
2659 fault = fold_build2_loc (input_location, TRUTH_ANDIF_EXPR,
2660 logical_type_node, nonempty, fault);
2661 if (name)
2662 msg = xasprintf ("Substring out of bounds: upper bound (%%ld) of '%s' "
2663 "exceeds string length (%%ld)", name);
2664 else
2665 msg = xasprintf ("Substring out of bounds: upper bound (%%ld) "
2666 "exceeds string length (%%ld)");
2667 gfc_trans_runtime_check (true, false, fault, &se->pre, where, msg,
2668 fold_convert (long_integer_type_node, end.expr),
2669 fold_convert (long_integer_type_node,
2670 se->string_length));
2671 free (msg);
2674 /* Try to calculate the length from the start and end expressions. */
2675 if (ref->u.ss.end
2676 && gfc_dep_difference (ref->u.ss.end, ref->u.ss.start, &length))
2678 HOST_WIDE_INT i_len;
2680 i_len = gfc_mpz_get_hwi (length) + 1;
2681 if (i_len < 0)
2682 i_len = 0;
2684 tmp = build_int_cst (gfc_charlen_type_node, i_len);
2685 mpz_clear (length); /* Was initialized by gfc_dep_difference. */
2687 else
2689 tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_charlen_type_node,
2690 fold_convert (gfc_charlen_type_node, end.expr),
2691 fold_convert (gfc_charlen_type_node, start.expr));
2692 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_charlen_type_node,
2693 build_int_cst (gfc_charlen_type_node, 1), tmp);
2694 tmp = fold_build2_loc (input_location, MAX_EXPR, gfc_charlen_type_node,
2695 tmp, build_int_cst (gfc_charlen_type_node, 0));
2698 se->string_length = tmp;
2702 /* Convert a derived type component reference. */
2704 void
2705 gfc_conv_component_ref (gfc_se * se, gfc_ref * ref)
2707 gfc_component *c;
2708 tree tmp;
2709 tree decl;
2710 tree field;
2711 tree context;
2713 c = ref->u.c.component;
2715 if (c->backend_decl == NULL_TREE
2716 && ref->u.c.sym != NULL)
2717 gfc_get_derived_type (ref->u.c.sym);
2719 field = c->backend_decl;
2720 gcc_assert (field && TREE_CODE (field) == FIELD_DECL);
2721 decl = se->expr;
2722 context = DECL_FIELD_CONTEXT (field);
2724 /* Components can correspond to fields of different containing
2725 types, as components are created without context, whereas
2726 a concrete use of a component has the type of decl as context.
2727 So, if the type doesn't match, we search the corresponding
2728 FIELD_DECL in the parent type. To not waste too much time
2729 we cache this result in norestrict_decl.
2730 On the other hand, if the context is a UNION or a MAP (a
2731 RECORD_TYPE within a UNION_TYPE) always use the given FIELD_DECL. */
2733 if (context != TREE_TYPE (decl)
2734 && !( TREE_CODE (TREE_TYPE (field)) == UNION_TYPE /* Field is union */
2735 || TREE_CODE (context) == UNION_TYPE)) /* Field is map */
2737 tree f2 = c->norestrict_decl;
2738 if (!f2 || DECL_FIELD_CONTEXT (f2) != TREE_TYPE (decl))
2739 for (f2 = TYPE_FIELDS (TREE_TYPE (decl)); f2; f2 = DECL_CHAIN (f2))
2740 if (TREE_CODE (f2) == FIELD_DECL
2741 && DECL_NAME (f2) == DECL_NAME (field))
2742 break;
2743 gcc_assert (f2);
2744 c->norestrict_decl = f2;
2745 field = f2;
2748 if (ref->u.c.sym && ref->u.c.sym->ts.type == BT_CLASS
2749 && strcmp ("_data", c->name) == 0)
2751 /* Found a ref to the _data component. Store the associated ref to
2752 the vptr in se->class_vptr. */
2753 se->class_vptr = gfc_class_vptr_get (decl);
2755 else
2756 se->class_vptr = NULL_TREE;
2758 tmp = fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field),
2759 decl, field, NULL_TREE);
2761 se->expr = tmp;
2763 /* Allocatable deferred char arrays are to be handled by the gfc_deferred_
2764 strlen () conditional below. */
2765 if (c->ts.type == BT_CHARACTER && !c->attr.proc_pointer
2766 && !c->ts.deferred
2767 && !c->attr.pdt_string)
2769 tmp = c->ts.u.cl->backend_decl;
2770 /* Components must always be constant length. */
2771 gcc_assert (tmp && INTEGER_CST_P (tmp));
2772 se->string_length = tmp;
2775 if (gfc_deferred_strlen (c, &field))
2777 tmp = fold_build3_loc (input_location, COMPONENT_REF,
2778 TREE_TYPE (field),
2779 decl, field, NULL_TREE);
2780 se->string_length = tmp;
2783 if (((c->attr.pointer || c->attr.allocatable)
2784 && (!c->attr.dimension && !c->attr.codimension)
2785 && c->ts.type != BT_CHARACTER)
2786 || c->attr.proc_pointer)
2787 se->expr = build_fold_indirect_ref_loc (input_location,
2788 se->expr);
2792 /* This function deals with component references to components of the
2793 parent type for derived type extensions. */
2794 void
2795 conv_parent_component_references (gfc_se * se, gfc_ref * ref)
2797 gfc_component *c;
2798 gfc_component *cmp;
2799 gfc_symbol *dt;
2800 gfc_ref parent;
2802 dt = ref->u.c.sym;
2803 c = ref->u.c.component;
2805 /* Return if the component is in the parent type. */
2806 for (cmp = dt->components; cmp; cmp = cmp->next)
2807 if (strcmp (c->name, cmp->name) == 0)
2808 return;
2810 /* Build a gfc_ref to recursively call gfc_conv_component_ref. */
2811 parent.type = REF_COMPONENT;
2812 parent.next = NULL;
2813 parent.u.c.sym = dt;
2814 parent.u.c.component = dt->components;
2816 if (dt->backend_decl == NULL)
2817 gfc_get_derived_type (dt);
2819 /* Build the reference and call self. */
2820 gfc_conv_component_ref (se, &parent);
2821 parent.u.c.sym = dt->components->ts.u.derived;
2822 parent.u.c.component = c;
2823 conv_parent_component_references (se, &parent);
2827 static void
2828 conv_inquiry (gfc_se * se, gfc_ref * ref, gfc_expr *expr, gfc_typespec *ts)
2830 tree res = se->expr;
2832 switch (ref->u.i)
2834 case INQUIRY_RE:
2835 res = fold_build1_loc (input_location, REALPART_EXPR,
2836 TREE_TYPE (TREE_TYPE (res)), res);
2837 break;
2839 case INQUIRY_IM:
2840 res = fold_build1_loc (input_location, IMAGPART_EXPR,
2841 TREE_TYPE (TREE_TYPE (res)), res);
2842 break;
2844 case INQUIRY_KIND:
2845 res = build_int_cst (gfc_typenode_for_spec (&expr->ts),
2846 ts->kind);
2847 break;
2849 case INQUIRY_LEN:
2850 res = fold_convert (gfc_typenode_for_spec (&expr->ts),
2851 se->string_length);
2852 break;
2854 default:
2855 gcc_unreachable ();
2857 se->expr = res;
2860 /* Dereference VAR where needed if it is a pointer, reference, etc.
2861 according to Fortran semantics. */
2863 tree
2864 gfc_maybe_dereference_var (gfc_symbol *sym, tree var, bool descriptor_only_p,
2865 bool is_classarray)
2867 /* Characters are entirely different from other types, they are treated
2868 separately. */
2869 if (sym->ts.type == BT_CHARACTER)
2871 /* Dereference character pointer dummy arguments
2872 or results. */
2873 if ((sym->attr.pointer || sym->attr.allocatable
2874 || (sym->as && sym->as->type == AS_ASSUMED_RANK))
2875 && (sym->attr.dummy
2876 || sym->attr.function
2877 || sym->attr.result))
2878 var = build_fold_indirect_ref_loc (input_location, var);
2880 else if (!sym->attr.value)
2882 /* Dereference temporaries for class array dummy arguments. */
2883 if (sym->attr.dummy && is_classarray
2884 && GFC_ARRAY_TYPE_P (TREE_TYPE (var)))
2886 if (!descriptor_only_p)
2887 var = GFC_DECL_SAVED_DESCRIPTOR (var);
2889 var = build_fold_indirect_ref_loc (input_location, var);
2892 /* Dereference non-character scalar dummy arguments. */
2893 if (sym->attr.dummy && !sym->attr.dimension
2894 && !(sym->attr.codimension && sym->attr.allocatable)
2895 && (sym->ts.type != BT_CLASS
2896 || (!CLASS_DATA (sym)->attr.dimension
2897 && !(CLASS_DATA (sym)->attr.codimension
2898 && CLASS_DATA (sym)->attr.allocatable))))
2899 var = build_fold_indirect_ref_loc (input_location, var);
2901 /* Dereference scalar hidden result. */
2902 if (flag_f2c && sym->ts.type == BT_COMPLEX
2903 && (sym->attr.function || sym->attr.result)
2904 && !sym->attr.dimension && !sym->attr.pointer
2905 && !sym->attr.always_explicit)
2906 var = build_fold_indirect_ref_loc (input_location, var);
2908 /* Dereference non-character, non-class pointer variables.
2909 These must be dummies, results, or scalars. */
2910 if (!is_classarray
2911 && (sym->attr.pointer || sym->attr.allocatable
2912 || gfc_is_associate_pointer (sym)
2913 || (sym->as && sym->as->type == AS_ASSUMED_RANK))
2914 && (sym->attr.dummy
2915 || sym->attr.function
2916 || sym->attr.result
2917 || (!sym->attr.dimension
2918 && (!sym->attr.codimension || !sym->attr.allocatable))))
2919 var = build_fold_indirect_ref_loc (input_location, var);
2920 /* Now treat the class array pointer variables accordingly. */
2921 else if (sym->ts.type == BT_CLASS
2922 && sym->attr.dummy
2923 && (CLASS_DATA (sym)->attr.dimension
2924 || CLASS_DATA (sym)->attr.codimension)
2925 && ((CLASS_DATA (sym)->as
2926 && CLASS_DATA (sym)->as->type == AS_ASSUMED_RANK)
2927 || CLASS_DATA (sym)->attr.allocatable
2928 || CLASS_DATA (sym)->attr.class_pointer))
2929 var = build_fold_indirect_ref_loc (input_location, var);
2930 /* And the case where a non-dummy, non-result, non-function,
2931 non-allotable and non-pointer classarray is present. This case was
2932 previously covered by the first if, but with introducing the
2933 condition !is_classarray there, that case has to be covered
2934 explicitly. */
2935 else if (sym->ts.type == BT_CLASS
2936 && !sym->attr.dummy
2937 && !sym->attr.function
2938 && !sym->attr.result
2939 && (CLASS_DATA (sym)->attr.dimension
2940 || CLASS_DATA (sym)->attr.codimension)
2941 && (sym->assoc
2942 || !CLASS_DATA (sym)->attr.allocatable)
2943 && !CLASS_DATA (sym)->attr.class_pointer)
2944 var = build_fold_indirect_ref_loc (input_location, var);
2947 return var;
2950 /* Return the contents of a variable. Also handles reference/pointer
2951 variables (all Fortran pointer references are implicit). */
2953 static void
2954 gfc_conv_variable (gfc_se * se, gfc_expr * expr)
2956 gfc_ss *ss;
2957 gfc_ref *ref;
2958 gfc_symbol *sym;
2959 tree parent_decl = NULL_TREE;
2960 int parent_flag;
2961 bool return_value;
2962 bool alternate_entry;
2963 bool entry_master;
2964 bool is_classarray;
2965 bool first_time = true;
2967 sym = expr->symtree->n.sym;
2968 is_classarray = IS_CLASS_ARRAY (sym);
2969 ss = se->ss;
2970 if (ss != NULL)
2972 gfc_ss_info *ss_info = ss->info;
2974 /* Check that something hasn't gone horribly wrong. */
2975 gcc_assert (ss != gfc_ss_terminator);
2976 gcc_assert (ss_info->expr == expr);
2978 /* A scalarized term. We already know the descriptor. */
2979 se->expr = ss_info->data.array.descriptor;
2980 se->string_length = ss_info->string_length;
2981 ref = ss_info->data.array.ref;
2982 if (ref)
2983 gcc_assert (ref->type == REF_ARRAY
2984 && ref->u.ar.type != AR_ELEMENT);
2985 else
2986 gfc_conv_tmp_array_ref (se);
2988 else
2990 tree se_expr = NULL_TREE;
2992 se->expr = gfc_get_symbol_decl (sym);
2994 /* Deal with references to a parent results or entries by storing
2995 the current_function_decl and moving to the parent_decl. */
2996 return_value = sym->attr.function && sym->result == sym;
2997 alternate_entry = sym->attr.function && sym->attr.entry
2998 && sym->result == sym;
2999 entry_master = sym->attr.result
3000 && sym->ns->proc_name->attr.entry_master
3001 && !gfc_return_by_reference (sym->ns->proc_name);
3002 if (current_function_decl)
3003 parent_decl = DECL_CONTEXT (current_function_decl);
3005 if ((se->expr == parent_decl && return_value)
3006 || (sym->ns && sym->ns->proc_name
3007 && parent_decl
3008 && sym->ns->proc_name->backend_decl == parent_decl
3009 && (alternate_entry || entry_master)))
3010 parent_flag = 1;
3011 else
3012 parent_flag = 0;
3014 /* Special case for assigning the return value of a function.
3015 Self recursive functions must have an explicit return value. */
3016 if (return_value && (se->expr == current_function_decl || parent_flag))
3017 se_expr = gfc_get_fake_result_decl (sym, parent_flag);
3019 /* Similarly for alternate entry points. */
3020 else if (alternate_entry
3021 && (sym->ns->proc_name->backend_decl == current_function_decl
3022 || parent_flag))
3024 gfc_entry_list *el = NULL;
3026 for (el = sym->ns->entries; el; el = el->next)
3027 if (sym == el->sym)
3029 se_expr = gfc_get_fake_result_decl (sym, parent_flag);
3030 break;
3034 else if (entry_master
3035 && (sym->ns->proc_name->backend_decl == current_function_decl
3036 || parent_flag))
3037 se_expr = gfc_get_fake_result_decl (sym, parent_flag);
3039 if (se_expr)
3040 se->expr = se_expr;
3042 /* Procedure actual arguments. Look out for temporary variables
3043 with the same attributes as function values. */
3044 else if (!sym->attr.temporary
3045 && sym->attr.flavor == FL_PROCEDURE
3046 && se->expr != current_function_decl)
3048 if (!sym->attr.dummy && !sym->attr.proc_pointer)
3050 gcc_assert (TREE_CODE (se->expr) == FUNCTION_DECL);
3051 se->expr = gfc_build_addr_expr (NULL_TREE, se->expr);
3053 return;
3056 /* Dereference the expression, where needed. */
3057 se->expr = gfc_maybe_dereference_var (sym, se->expr, se->descriptor_only,
3058 is_classarray);
3060 ref = expr->ref;
3063 /* For character variables, also get the length. */
3064 if (sym->ts.type == BT_CHARACTER)
3066 /* If the character length of an entry isn't set, get the length from
3067 the master function instead. */
3068 if (sym->attr.entry && !sym->ts.u.cl->backend_decl)
3069 se->string_length = sym->ns->proc_name->ts.u.cl->backend_decl;
3070 else
3071 se->string_length = sym->ts.u.cl->backend_decl;
3072 gcc_assert (se->string_length);
3075 gfc_typespec *ts = &sym->ts;
3076 while (ref)
3078 switch (ref->type)
3080 case REF_ARRAY:
3081 /* Return the descriptor if that's what we want and this is an array
3082 section reference. */
3083 if (se->descriptor_only && ref->u.ar.type != AR_ELEMENT)
3084 return;
3085 /* TODO: Pointers to single elements of array sections, eg elemental subs. */
3086 /* Return the descriptor for array pointers and allocations. */
3087 if (se->want_pointer
3088 && ref->next == NULL && (se->descriptor_only))
3089 return;
3091 gfc_conv_array_ref (se, &ref->u.ar, expr, &expr->where);
3092 /* Return a pointer to an element. */
3093 break;
3095 case REF_COMPONENT:
3096 ts = &ref->u.c.component->ts;
3097 if (first_time && is_classarray && sym->attr.dummy
3098 && se->descriptor_only
3099 && !CLASS_DATA (sym)->attr.allocatable
3100 && !CLASS_DATA (sym)->attr.class_pointer
3101 && CLASS_DATA (sym)->as
3102 && CLASS_DATA (sym)->as->type != AS_ASSUMED_RANK
3103 && strcmp ("_data", ref->u.c.component->name) == 0)
3104 /* Skip the first ref of a _data component, because for class
3105 arrays that one is already done by introducing a temporary
3106 array descriptor. */
3107 break;
3109 if (ref->u.c.sym->attr.extension)
3110 conv_parent_component_references (se, ref);
3112 gfc_conv_component_ref (se, ref);
3113 if (!ref->next && ref->u.c.sym->attr.codimension
3114 && se->want_pointer && se->descriptor_only)
3115 return;
3117 break;
3119 case REF_SUBSTRING:
3120 gfc_conv_substring (se, ref, expr->ts.kind,
3121 expr->symtree->name, &expr->where);
3122 break;
3124 case REF_INQUIRY:
3125 conv_inquiry (se, ref, expr, ts);
3126 break;
3128 default:
3129 gcc_unreachable ();
3130 break;
3132 first_time = false;
3133 ref = ref->next;
3135 /* Pointer assignment, allocation or pass by reference. Arrays are handled
3136 separately. */
3137 if (se->want_pointer)
3139 if (expr->ts.type == BT_CHARACTER && !gfc_is_proc_ptr_comp (expr))
3140 gfc_conv_string_parameter (se);
3141 else
3142 se->expr = gfc_build_addr_expr (NULL_TREE, se->expr);
3147 /* Unary ops are easy... Or they would be if ! was a valid op. */
3149 static void
3150 gfc_conv_unary_op (enum tree_code code, gfc_se * se, gfc_expr * expr)
3152 gfc_se operand;
3153 tree type;
3155 gcc_assert (expr->ts.type != BT_CHARACTER);
3156 /* Initialize the operand. */
3157 gfc_init_se (&operand, se);
3158 gfc_conv_expr_val (&operand, expr->value.op.op1);
3159 gfc_add_block_to_block (&se->pre, &operand.pre);
3161 type = gfc_typenode_for_spec (&expr->ts);
3163 /* TRUTH_NOT_EXPR is not a "true" unary operator in GCC.
3164 We must convert it to a compare to 0 (e.g. EQ_EXPR (op1, 0)).
3165 All other unary operators have an equivalent GIMPLE unary operator. */
3166 if (code == TRUTH_NOT_EXPR)
3167 se->expr = fold_build2_loc (input_location, EQ_EXPR, type, operand.expr,
3168 build_int_cst (type, 0));
3169 else
3170 se->expr = fold_build1_loc (input_location, code, type, operand.expr);
3174 /* Expand power operator to optimal multiplications when a value is raised
3175 to a constant integer n. See section 4.6.3, "Evaluation of Powers" of
3176 Donald E. Knuth, "Seminumerical Algorithms", Vol. 2, "The Art of Computer
3177 Programming", 3rd Edition, 1998. */
3179 /* This code is mostly duplicated from expand_powi in the backend.
3180 We establish the "optimal power tree" lookup table with the defined size.
3181 The items in the table are the exponents used to calculate the index
3182 exponents. Any integer n less than the value can get an "addition chain",
3183 with the first node being one. */
3184 #define POWI_TABLE_SIZE 256
3186 /* The table is from builtins.c. */
3187 static const unsigned char powi_table[POWI_TABLE_SIZE] =
3189 0, 1, 1, 2, 2, 3, 3, 4, /* 0 - 7 */
3190 4, 6, 5, 6, 6, 10, 7, 9, /* 8 - 15 */
3191 8, 16, 9, 16, 10, 12, 11, 13, /* 16 - 23 */
3192 12, 17, 13, 18, 14, 24, 15, 26, /* 24 - 31 */
3193 16, 17, 17, 19, 18, 33, 19, 26, /* 32 - 39 */
3194 20, 25, 21, 40, 22, 27, 23, 44, /* 40 - 47 */
3195 24, 32, 25, 34, 26, 29, 27, 44, /* 48 - 55 */
3196 28, 31, 29, 34, 30, 60, 31, 36, /* 56 - 63 */
3197 32, 64, 33, 34, 34, 46, 35, 37, /* 64 - 71 */
3198 36, 65, 37, 50, 38, 48, 39, 69, /* 72 - 79 */
3199 40, 49, 41, 43, 42, 51, 43, 58, /* 80 - 87 */
3200 44, 64, 45, 47, 46, 59, 47, 76, /* 88 - 95 */
3201 48, 65, 49, 66, 50, 67, 51, 66, /* 96 - 103 */
3202 52, 70, 53, 74, 54, 104, 55, 74, /* 104 - 111 */
3203 56, 64, 57, 69, 58, 78, 59, 68, /* 112 - 119 */
3204 60, 61, 61, 80, 62, 75, 63, 68, /* 120 - 127 */
3205 64, 65, 65, 128, 66, 129, 67, 90, /* 128 - 135 */
3206 68, 73, 69, 131, 70, 94, 71, 88, /* 136 - 143 */
3207 72, 128, 73, 98, 74, 132, 75, 121, /* 144 - 151 */
3208 76, 102, 77, 124, 78, 132, 79, 106, /* 152 - 159 */
3209 80, 97, 81, 160, 82, 99, 83, 134, /* 160 - 167 */
3210 84, 86, 85, 95, 86, 160, 87, 100, /* 168 - 175 */
3211 88, 113, 89, 98, 90, 107, 91, 122, /* 176 - 183 */
3212 92, 111, 93, 102, 94, 126, 95, 150, /* 184 - 191 */
3213 96, 128, 97, 130, 98, 133, 99, 195, /* 192 - 199 */
3214 100, 128, 101, 123, 102, 164, 103, 138, /* 200 - 207 */
3215 104, 145, 105, 146, 106, 109, 107, 149, /* 208 - 215 */
3216 108, 200, 109, 146, 110, 170, 111, 157, /* 216 - 223 */
3217 112, 128, 113, 130, 114, 182, 115, 132, /* 224 - 231 */
3218 116, 200, 117, 132, 118, 158, 119, 206, /* 232 - 239 */
3219 120, 240, 121, 162, 122, 147, 123, 152, /* 240 - 247 */
3220 124, 166, 125, 214, 126, 138, 127, 153, /* 248 - 255 */
3223 /* If n is larger than lookup table's max index, we use the "window
3224 method". */
3225 #define POWI_WINDOW_SIZE 3
3227 /* Recursive function to expand the power operator. The temporary
3228 values are put in tmpvar. The function returns tmpvar[1] ** n. */
3229 static tree
3230 gfc_conv_powi (gfc_se * se, unsigned HOST_WIDE_INT n, tree * tmpvar)
3232 tree op0;
3233 tree op1;
3234 tree tmp;
3235 int digit;
3237 if (n < POWI_TABLE_SIZE)
3239 if (tmpvar[n])
3240 return tmpvar[n];
3242 op0 = gfc_conv_powi (se, n - powi_table[n], tmpvar);
3243 op1 = gfc_conv_powi (se, powi_table[n], tmpvar);
3245 else if (n & 1)
3247 digit = n & ((1 << POWI_WINDOW_SIZE) - 1);
3248 op0 = gfc_conv_powi (se, n - digit, tmpvar);
3249 op1 = gfc_conv_powi (se, digit, tmpvar);
3251 else
3253 op0 = gfc_conv_powi (se, n >> 1, tmpvar);
3254 op1 = op0;
3257 tmp = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (op0), op0, op1);
3258 tmp = gfc_evaluate_now (tmp, &se->pre);
3260 if (n < POWI_TABLE_SIZE)
3261 tmpvar[n] = tmp;
3263 return tmp;
3267 /* Expand lhs ** rhs. rhs is a constant integer. If it expands successfully,
3268 return 1. Else return 0 and a call to runtime library functions
3269 will have to be built. */
3270 static int
3271 gfc_conv_cst_int_power (gfc_se * se, tree lhs, tree rhs)
3273 tree cond;
3274 tree tmp;
3275 tree type;
3276 tree vartmp[POWI_TABLE_SIZE];
3277 HOST_WIDE_INT m;
3278 unsigned HOST_WIDE_INT n;
3279 int sgn;
3280 wi::tree_to_wide_ref wrhs = wi::to_wide (rhs);
3282 /* If exponent is too large, we won't expand it anyway, so don't bother
3283 with large integer values. */
3284 if (!wi::fits_shwi_p (wrhs))
3285 return 0;
3287 m = wrhs.to_shwi ();
3288 /* Use the wide_int's routine to reliably get the absolute value on all
3289 platforms. Then convert it to a HOST_WIDE_INT like above. */
3290 n = wi::abs (wrhs).to_shwi ();
3292 type = TREE_TYPE (lhs);
3293 sgn = tree_int_cst_sgn (rhs);
3295 if (((FLOAT_TYPE_P (type) && !flag_unsafe_math_optimizations)
3296 || optimize_size) && (m > 2 || m < -1))
3297 return 0;
3299 /* rhs == 0 */
3300 if (sgn == 0)
3302 se->expr = gfc_build_const (type, integer_one_node);
3303 return 1;
3306 /* If rhs < 0 and lhs is an integer, the result is -1, 0 or 1. */
3307 if ((sgn == -1) && (TREE_CODE (type) == INTEGER_TYPE))
3309 tmp = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
3310 lhs, build_int_cst (TREE_TYPE (lhs), -1));
3311 cond = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
3312 lhs, build_int_cst (TREE_TYPE (lhs), 1));
3314 /* If rhs is even,
3315 result = (lhs == 1 || lhs == -1) ? 1 : 0. */
3316 if ((n & 1) == 0)
3318 tmp = fold_build2_loc (input_location, TRUTH_OR_EXPR,
3319 logical_type_node, tmp, cond);
3320 se->expr = fold_build3_loc (input_location, COND_EXPR, type,
3321 tmp, build_int_cst (type, 1),
3322 build_int_cst (type, 0));
3323 return 1;
3325 /* If rhs is odd,
3326 result = (lhs == 1) ? 1 : (lhs == -1) ? -1 : 0. */
3327 tmp = fold_build3_loc (input_location, COND_EXPR, type, tmp,
3328 build_int_cst (type, -1),
3329 build_int_cst (type, 0));
3330 se->expr = fold_build3_loc (input_location, COND_EXPR, type,
3331 cond, build_int_cst (type, 1), tmp);
3332 return 1;
3335 memset (vartmp, 0, sizeof (vartmp));
3336 vartmp[1] = lhs;
3337 if (sgn == -1)
3339 tmp = gfc_build_const (type, integer_one_node);
3340 vartmp[1] = fold_build2_loc (input_location, RDIV_EXPR, type, tmp,
3341 vartmp[1]);
3344 se->expr = gfc_conv_powi (se, n, vartmp);
3346 return 1;
3350 /* Power op (**). Constant integer exponent has special handling. */
3352 static void
3353 gfc_conv_power_op (gfc_se * se, gfc_expr * expr)
3355 tree gfc_int4_type_node;
3356 int kind;
3357 int ikind;
3358 int res_ikind_1, res_ikind_2;
3359 gfc_se lse;
3360 gfc_se rse;
3361 tree fndecl = NULL;
3363 gfc_init_se (&lse, se);
3364 gfc_conv_expr_val (&lse, expr->value.op.op1);
3365 lse.expr = gfc_evaluate_now (lse.expr, &lse.pre);
3366 gfc_add_block_to_block (&se->pre, &lse.pre);
3368 gfc_init_se (&rse, se);
3369 gfc_conv_expr_val (&rse, expr->value.op.op2);
3370 gfc_add_block_to_block (&se->pre, &rse.pre);
3372 if (expr->value.op.op2->ts.type == BT_INTEGER
3373 && expr->value.op.op2->expr_type == EXPR_CONSTANT)
3374 if (gfc_conv_cst_int_power (se, lse.expr, rse.expr))
3375 return;
3377 if (INTEGER_CST_P (lse.expr)
3378 && TREE_CODE (TREE_TYPE (rse.expr)) == INTEGER_TYPE)
3380 wi::tree_to_wide_ref wlhs = wi::to_wide (lse.expr);
3381 HOST_WIDE_INT v, w;
3382 int kind, ikind, bit_size;
3384 v = wlhs.to_shwi ();
3385 w = abs (v);
3387 kind = expr->value.op.op1->ts.kind;
3388 ikind = gfc_validate_kind (BT_INTEGER, kind, false);
3389 bit_size = gfc_integer_kinds[ikind].bit_size;
3391 if (v == 1)
3393 /* 1**something is always 1. */
3394 se->expr = build_int_cst (TREE_TYPE (lse.expr), 1);
3395 return;
3397 else if (v == -1)
3399 /* (-1)**n is 1 - ((n & 1) << 1) */
3400 tree type;
3401 tree tmp;
3403 type = TREE_TYPE (lse.expr);
3404 tmp = fold_build2_loc (input_location, BIT_AND_EXPR, type,
3405 rse.expr, build_int_cst (type, 1));
3406 tmp = fold_build2_loc (input_location, LSHIFT_EXPR, type,
3407 tmp, build_int_cst (type, 1));
3408 tmp = fold_build2_loc (input_location, MINUS_EXPR, type,
3409 build_int_cst (type, 1), tmp);
3410 se->expr = tmp;
3411 return;
3413 else if (w > 0 && ((w & (w-1)) == 0) && ((w >> (bit_size-1)) == 0))
3415 /* Here v is +/- 2**e. The further simplification uses
3416 2**n = 1<<n, 4**n = 1<<(n+n), 8**n = 1 <<(3*n), 16**n =
3417 1<<(4*n), etc., but we have to make sure to return zero
3418 if the number of bits is too large. */
3419 tree lshift;
3420 tree type;
3421 tree shift;
3422 tree ge;
3423 tree cond;
3424 tree num_bits;
3425 tree cond2;
3426 tree tmp1;
3428 type = TREE_TYPE (lse.expr);
3430 if (w == 2)
3431 shift = rse.expr;
3432 else if (w == 4)
3433 shift = fold_build2_loc (input_location, PLUS_EXPR,
3434 TREE_TYPE (rse.expr),
3435 rse.expr, rse.expr);
3436 else
3438 /* use popcount for fast log2(w) */
3439 int e = wi::popcount (w-1);
3440 shift = fold_build2_loc (input_location, MULT_EXPR,
3441 TREE_TYPE (rse.expr),
3442 build_int_cst (TREE_TYPE (rse.expr), e),
3443 rse.expr);
3446 lshift = fold_build2_loc (input_location, LSHIFT_EXPR, type,
3447 build_int_cst (type, 1), shift);
3448 ge = fold_build2_loc (input_location, GE_EXPR, logical_type_node,
3449 rse.expr, build_int_cst (type, 0));
3450 cond = fold_build3_loc (input_location, COND_EXPR, type, ge, lshift,
3451 build_int_cst (type, 0));
3452 num_bits = build_int_cst (TREE_TYPE (rse.expr), TYPE_PRECISION (type));
3453 cond2 = fold_build2_loc (input_location, GE_EXPR, logical_type_node,
3454 rse.expr, num_bits);
3455 tmp1 = fold_build3_loc (input_location, COND_EXPR, type, cond2,
3456 build_int_cst (type, 0), cond);
3457 if (v > 0)
3459 se->expr = tmp1;
3461 else
3463 /* for v < 0, calculate v**n = |v|**n * (-1)**n */
3464 tree tmp2;
3465 tmp2 = fold_build2_loc (input_location, BIT_AND_EXPR, type,
3466 rse.expr, build_int_cst (type, 1));
3467 tmp2 = fold_build2_loc (input_location, LSHIFT_EXPR, type,
3468 tmp2, build_int_cst (type, 1));
3469 tmp2 = fold_build2_loc (input_location, MINUS_EXPR, type,
3470 build_int_cst (type, 1), tmp2);
3471 se->expr = fold_build2_loc (input_location, MULT_EXPR, type,
3472 tmp1, tmp2);
3474 return;
3478 gfc_int4_type_node = gfc_get_int_type (4);
3480 /* In case of integer operands with kinds 1 or 2, we call the integer kind 4
3481 library routine. But in the end, we have to convert the result back
3482 if this case applies -- with res_ikind_K, we keep track whether operand K
3483 falls into this case. */
3484 res_ikind_1 = -1;
3485 res_ikind_2 = -1;
3487 kind = expr->value.op.op1->ts.kind;
3488 switch (expr->value.op.op2->ts.type)
3490 case BT_INTEGER:
3491 ikind = expr->value.op.op2->ts.kind;
3492 switch (ikind)
3494 case 1:
3495 case 2:
3496 rse.expr = convert (gfc_int4_type_node, rse.expr);
3497 res_ikind_2 = ikind;
3498 /* Fall through. */
3500 case 4:
3501 ikind = 0;
3502 break;
3504 case 8:
3505 ikind = 1;
3506 break;
3508 case 16:
3509 ikind = 2;
3510 break;
3512 default:
3513 gcc_unreachable ();
3515 switch (kind)
3517 case 1:
3518 case 2:
3519 if (expr->value.op.op1->ts.type == BT_INTEGER)
3521 lse.expr = convert (gfc_int4_type_node, lse.expr);
3522 res_ikind_1 = kind;
3524 else
3525 gcc_unreachable ();
3526 /* Fall through. */
3528 case 4:
3529 kind = 0;
3530 break;
3532 case 8:
3533 kind = 1;
3534 break;
3536 case 10:
3537 kind = 2;
3538 break;
3540 case 16:
3541 kind = 3;
3542 break;
3544 default:
3545 gcc_unreachable ();
3548 switch (expr->value.op.op1->ts.type)
3550 case BT_INTEGER:
3551 if (kind == 3) /* Case 16 was not handled properly above. */
3552 kind = 2;
3553 fndecl = gfor_fndecl_math_powi[kind][ikind].integer;
3554 break;
3556 case BT_REAL:
3557 /* Use builtins for real ** int4. */
3558 if (ikind == 0)
3560 switch (kind)
3562 case 0:
3563 fndecl = builtin_decl_explicit (BUILT_IN_POWIF);
3564 break;
3566 case 1:
3567 fndecl = builtin_decl_explicit (BUILT_IN_POWI);
3568 break;
3570 case 2:
3571 fndecl = builtin_decl_explicit (BUILT_IN_POWIL);
3572 break;
3574 case 3:
3575 /* Use the __builtin_powil() only if real(kind=16) is
3576 actually the C long double type. */
3577 if (!gfc_real16_is_float128)
3578 fndecl = builtin_decl_explicit (BUILT_IN_POWIL);
3579 break;
3581 default:
3582 gcc_unreachable ();
3586 /* If we don't have a good builtin for this, go for the
3587 library function. */
3588 if (!fndecl)
3589 fndecl = gfor_fndecl_math_powi[kind][ikind].real;
3590 break;
3592 case BT_COMPLEX:
3593 fndecl = gfor_fndecl_math_powi[kind][ikind].cmplx;
3594 break;
3596 default:
3597 gcc_unreachable ();
3599 break;
3601 case BT_REAL:
3602 fndecl = gfc_builtin_decl_for_float_kind (BUILT_IN_POW, kind);
3603 break;
3605 case BT_COMPLEX:
3606 fndecl = gfc_builtin_decl_for_float_kind (BUILT_IN_CPOW, kind);
3607 break;
3609 default:
3610 gcc_unreachable ();
3611 break;
3614 se->expr = build_call_expr_loc (input_location,
3615 fndecl, 2, lse.expr, rse.expr);
3617 /* Convert the result back if it is of wrong integer kind. */
3618 if (res_ikind_1 != -1 && res_ikind_2 != -1)
3620 /* We want the maximum of both operand kinds as result. */
3621 if (res_ikind_1 < res_ikind_2)
3622 res_ikind_1 = res_ikind_2;
3623 se->expr = convert (gfc_get_int_type (res_ikind_1), se->expr);
3628 /* Generate code to allocate a string temporary. */
3630 tree
3631 gfc_conv_string_tmp (gfc_se * se, tree type, tree len)
3633 tree var;
3634 tree tmp;
3636 if (gfc_can_put_var_on_stack (len))
3638 /* Create a temporary variable to hold the result. */
3639 tmp = fold_build2_loc (input_location, MINUS_EXPR,
3640 TREE_TYPE (len), len,
3641 build_int_cst (TREE_TYPE (len), 1));
3642 tmp = build_range_type (gfc_charlen_type_node, size_zero_node, tmp);
3644 if (TREE_CODE (TREE_TYPE (type)) == ARRAY_TYPE)
3645 tmp = build_array_type (TREE_TYPE (TREE_TYPE (type)), tmp);
3646 else
3647 tmp = build_array_type (TREE_TYPE (type), tmp);
3649 var = gfc_create_var (tmp, "str");
3650 var = gfc_build_addr_expr (type, var);
3652 else
3654 /* Allocate a temporary to hold the result. */
3655 var = gfc_create_var (type, "pstr");
3656 gcc_assert (POINTER_TYPE_P (type));
3657 tmp = TREE_TYPE (type);
3658 if (TREE_CODE (tmp) == ARRAY_TYPE)
3659 tmp = TREE_TYPE (tmp);
3660 tmp = TYPE_SIZE_UNIT (tmp);
3661 tmp = fold_build2_loc (input_location, MULT_EXPR, size_type_node,
3662 fold_convert (size_type_node, len),
3663 fold_convert (size_type_node, tmp));
3664 tmp = gfc_call_malloc (&se->pre, type, tmp);
3665 gfc_add_modify (&se->pre, var, tmp);
3667 /* Free the temporary afterwards. */
3668 tmp = gfc_call_free (var);
3669 gfc_add_expr_to_block (&se->post, tmp);
3672 return var;
3676 /* Handle a string concatenation operation. A temporary will be allocated to
3677 hold the result. */
3679 static void
3680 gfc_conv_concat_op (gfc_se * se, gfc_expr * expr)
3682 gfc_se lse, rse;
3683 tree len, type, var, tmp, fndecl;
3685 gcc_assert (expr->value.op.op1->ts.type == BT_CHARACTER
3686 && expr->value.op.op2->ts.type == BT_CHARACTER);
3687 gcc_assert (expr->value.op.op1->ts.kind == expr->value.op.op2->ts.kind);
3689 gfc_init_se (&lse, se);
3690 gfc_conv_expr (&lse, expr->value.op.op1);
3691 gfc_conv_string_parameter (&lse);
3692 gfc_init_se (&rse, se);
3693 gfc_conv_expr (&rse, expr->value.op.op2);
3694 gfc_conv_string_parameter (&rse);
3696 gfc_add_block_to_block (&se->pre, &lse.pre);
3697 gfc_add_block_to_block (&se->pre, &rse.pre);
3699 type = gfc_get_character_type (expr->ts.kind, expr->ts.u.cl);
3700 len = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
3701 if (len == NULL_TREE)
3703 len = fold_build2_loc (input_location, PLUS_EXPR,
3704 gfc_charlen_type_node,
3705 fold_convert (gfc_charlen_type_node,
3706 lse.string_length),
3707 fold_convert (gfc_charlen_type_node,
3708 rse.string_length));
3711 type = build_pointer_type (type);
3713 var = gfc_conv_string_tmp (se, type, len);
3715 /* Do the actual concatenation. */
3716 if (expr->ts.kind == 1)
3717 fndecl = gfor_fndecl_concat_string;
3718 else if (expr->ts.kind == 4)
3719 fndecl = gfor_fndecl_concat_string_char4;
3720 else
3721 gcc_unreachable ();
3723 tmp = build_call_expr_loc (input_location,
3724 fndecl, 6, len, var, lse.string_length, lse.expr,
3725 rse.string_length, rse.expr);
3726 gfc_add_expr_to_block (&se->pre, tmp);
3728 /* Add the cleanup for the operands. */
3729 gfc_add_block_to_block (&se->pre, &rse.post);
3730 gfc_add_block_to_block (&se->pre, &lse.post);
3732 se->expr = var;
3733 se->string_length = len;
3736 /* Translates an op expression. Common (binary) cases are handled by this
3737 function, others are passed on. Recursion is used in either case.
3738 We use the fact that (op1.ts == op2.ts) (except for the power
3739 operator **).
3740 Operators need no special handling for scalarized expressions as long as
3741 they call gfc_conv_simple_val to get their operands.
3742 Character strings get special handling. */
3744 static void
3745 gfc_conv_expr_op (gfc_se * se, gfc_expr * expr)
3747 enum tree_code code;
3748 gfc_se lse;
3749 gfc_se rse;
3750 tree tmp, type;
3751 int lop;
3752 int checkstring;
3754 checkstring = 0;
3755 lop = 0;
3756 switch (expr->value.op.op)
3758 case INTRINSIC_PARENTHESES:
3759 if ((expr->ts.type == BT_REAL || expr->ts.type == BT_COMPLEX)
3760 && flag_protect_parens)
3762 gfc_conv_unary_op (PAREN_EXPR, se, expr);
3763 gcc_assert (FLOAT_TYPE_P (TREE_TYPE (se->expr)));
3764 return;
3767 /* Fallthrough. */
3768 case INTRINSIC_UPLUS:
3769 gfc_conv_expr (se, expr->value.op.op1);
3770 return;
3772 case INTRINSIC_UMINUS:
3773 gfc_conv_unary_op (NEGATE_EXPR, se, expr);
3774 return;
3776 case INTRINSIC_NOT:
3777 gfc_conv_unary_op (TRUTH_NOT_EXPR, se, expr);
3778 return;
3780 case INTRINSIC_PLUS:
3781 code = PLUS_EXPR;
3782 break;
3784 case INTRINSIC_MINUS:
3785 code = MINUS_EXPR;
3786 break;
3788 case INTRINSIC_TIMES:
3789 code = MULT_EXPR;
3790 break;
3792 case INTRINSIC_DIVIDE:
3793 /* If expr is a real or complex expr, use an RDIV_EXPR. If op1 is
3794 an integer, we must round towards zero, so we use a
3795 TRUNC_DIV_EXPR. */
3796 if (expr->ts.type == BT_INTEGER)
3797 code = TRUNC_DIV_EXPR;
3798 else
3799 code = RDIV_EXPR;
3800 break;
3802 case INTRINSIC_POWER:
3803 gfc_conv_power_op (se, expr);
3804 return;
3806 case INTRINSIC_CONCAT:
3807 gfc_conv_concat_op (se, expr);
3808 return;
3810 case INTRINSIC_AND:
3811 code = flag_frontend_optimize ? TRUTH_ANDIF_EXPR : TRUTH_AND_EXPR;
3812 lop = 1;
3813 break;
3815 case INTRINSIC_OR:
3816 code = flag_frontend_optimize ? TRUTH_ORIF_EXPR : TRUTH_OR_EXPR;
3817 lop = 1;
3818 break;
3820 /* EQV and NEQV only work on logicals, but since we represent them
3821 as integers, we can use EQ_EXPR and NE_EXPR for them in GIMPLE. */
3822 case INTRINSIC_EQ:
3823 case INTRINSIC_EQ_OS:
3824 case INTRINSIC_EQV:
3825 code = EQ_EXPR;
3826 checkstring = 1;
3827 lop = 1;
3828 break;
3830 case INTRINSIC_NE:
3831 case INTRINSIC_NE_OS:
3832 case INTRINSIC_NEQV:
3833 code = NE_EXPR;
3834 checkstring = 1;
3835 lop = 1;
3836 break;
3838 case INTRINSIC_GT:
3839 case INTRINSIC_GT_OS:
3840 code = GT_EXPR;
3841 checkstring = 1;
3842 lop = 1;
3843 break;
3845 case INTRINSIC_GE:
3846 case INTRINSIC_GE_OS:
3847 code = GE_EXPR;
3848 checkstring = 1;
3849 lop = 1;
3850 break;
3852 case INTRINSIC_LT:
3853 case INTRINSIC_LT_OS:
3854 code = LT_EXPR;
3855 checkstring = 1;
3856 lop = 1;
3857 break;
3859 case INTRINSIC_LE:
3860 case INTRINSIC_LE_OS:
3861 code = LE_EXPR;
3862 checkstring = 1;
3863 lop = 1;
3864 break;
3866 case INTRINSIC_USER:
3867 case INTRINSIC_ASSIGN:
3868 /* These should be converted into function calls by the frontend. */
3869 gcc_unreachable ();
3871 default:
3872 fatal_error (input_location, "Unknown intrinsic op");
3873 return;
3876 /* The only exception to this is **, which is handled separately anyway. */
3877 gcc_assert (expr->value.op.op1->ts.type == expr->value.op.op2->ts.type);
3879 if (checkstring && expr->value.op.op1->ts.type != BT_CHARACTER)
3880 checkstring = 0;
3882 /* lhs */
3883 gfc_init_se (&lse, se);
3884 gfc_conv_expr (&lse, expr->value.op.op1);
3885 gfc_add_block_to_block (&se->pre, &lse.pre);
3887 /* rhs */
3888 gfc_init_se (&rse, se);
3889 gfc_conv_expr (&rse, expr->value.op.op2);
3890 gfc_add_block_to_block (&se->pre, &rse.pre);
3892 if (checkstring)
3894 gfc_conv_string_parameter (&lse);
3895 gfc_conv_string_parameter (&rse);
3897 lse.expr = gfc_build_compare_string (lse.string_length, lse.expr,
3898 rse.string_length, rse.expr,
3899 expr->value.op.op1->ts.kind,
3900 code);
3901 rse.expr = build_int_cst (TREE_TYPE (lse.expr), 0);
3902 gfc_add_block_to_block (&lse.post, &rse.post);
3905 type = gfc_typenode_for_spec (&expr->ts);
3907 if (lop)
3909 /* The result of logical ops is always logical_type_node. */
3910 tmp = fold_build2_loc (input_location, code, logical_type_node,
3911 lse.expr, rse.expr);
3912 se->expr = convert (type, tmp);
3914 else
3915 se->expr = fold_build2_loc (input_location, code, type, lse.expr, rse.expr);
3917 /* Add the post blocks. */
3918 gfc_add_block_to_block (&se->post, &rse.post);
3919 gfc_add_block_to_block (&se->post, &lse.post);
3922 /* If a string's length is one, we convert it to a single character. */
3924 tree
3925 gfc_string_to_single_character (tree len, tree str, int kind)
3928 if (len == NULL
3929 || !tree_fits_uhwi_p (len)
3930 || !POINTER_TYPE_P (TREE_TYPE (str)))
3931 return NULL_TREE;
3933 if (TREE_INT_CST_LOW (len) == 1)
3935 str = fold_convert (gfc_get_pchar_type (kind), str);
3936 return build_fold_indirect_ref_loc (input_location, str);
3939 if (kind == 1
3940 && TREE_CODE (str) == ADDR_EXPR
3941 && TREE_CODE (TREE_OPERAND (str, 0)) == ARRAY_REF
3942 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (str, 0), 0)) == STRING_CST
3943 && array_ref_low_bound (TREE_OPERAND (str, 0))
3944 == TREE_OPERAND (TREE_OPERAND (str, 0), 1)
3945 && TREE_INT_CST_LOW (len) > 1
3946 && TREE_INT_CST_LOW (len)
3947 == (unsigned HOST_WIDE_INT)
3948 TREE_STRING_LENGTH (TREE_OPERAND (TREE_OPERAND (str, 0), 0)))
3950 tree ret = fold_convert (gfc_get_pchar_type (kind), str);
3951 ret = build_fold_indirect_ref_loc (input_location, ret);
3952 if (TREE_CODE (ret) == INTEGER_CST)
3954 tree string_cst = TREE_OPERAND (TREE_OPERAND (str, 0), 0);
3955 int i, length = TREE_STRING_LENGTH (string_cst);
3956 const char *ptr = TREE_STRING_POINTER (string_cst);
3958 for (i = 1; i < length; i++)
3959 if (ptr[i] != ' ')
3960 return NULL_TREE;
3962 return ret;
3966 return NULL_TREE;
3970 void
3971 gfc_conv_scalar_char_value (gfc_symbol *sym, gfc_se *se, gfc_expr **expr)
3974 if (sym->backend_decl)
3976 /* This becomes the nominal_type in
3977 function.c:assign_parm_find_data_types. */
3978 TREE_TYPE (sym->backend_decl) = unsigned_char_type_node;
3979 /* This becomes the passed_type in
3980 function.c:assign_parm_find_data_types. C promotes char to
3981 integer for argument passing. */
3982 DECL_ARG_TYPE (sym->backend_decl) = unsigned_type_node;
3984 DECL_BY_REFERENCE (sym->backend_decl) = 0;
3987 if (expr != NULL)
3989 /* If we have a constant character expression, make it into an
3990 integer. */
3991 if ((*expr)->expr_type == EXPR_CONSTANT)
3993 gfc_typespec ts;
3994 gfc_clear_ts (&ts);
3996 *expr = gfc_get_int_expr (gfc_default_integer_kind, NULL,
3997 (int)(*expr)->value.character.string[0]);
3998 if ((*expr)->ts.kind != gfc_c_int_kind)
4000 /* The expr needs to be compatible with a C int. If the
4001 conversion fails, then the 2 causes an ICE. */
4002 ts.type = BT_INTEGER;
4003 ts.kind = gfc_c_int_kind;
4004 gfc_convert_type (*expr, &ts, 2);
4007 else if (se != NULL && (*expr)->expr_type == EXPR_VARIABLE)
4009 if ((*expr)->ref == NULL)
4011 se->expr = gfc_string_to_single_character
4012 (build_int_cst (integer_type_node, 1),
4013 gfc_build_addr_expr (gfc_get_pchar_type ((*expr)->ts.kind),
4014 gfc_get_symbol_decl
4015 ((*expr)->symtree->n.sym)),
4016 (*expr)->ts.kind);
4018 else
4020 gfc_conv_variable (se, *expr);
4021 se->expr = gfc_string_to_single_character
4022 (build_int_cst (integer_type_node, 1),
4023 gfc_build_addr_expr (gfc_get_pchar_type ((*expr)->ts.kind),
4024 se->expr),
4025 (*expr)->ts.kind);
4031 /* Helper function for gfc_build_compare_string. Return LEN_TRIM value
4032 if STR is a string literal, otherwise return -1. */
4034 static int
4035 gfc_optimize_len_trim (tree len, tree str, int kind)
4037 if (kind == 1
4038 && TREE_CODE (str) == ADDR_EXPR
4039 && TREE_CODE (TREE_OPERAND (str, 0)) == ARRAY_REF
4040 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (str, 0), 0)) == STRING_CST
4041 && array_ref_low_bound (TREE_OPERAND (str, 0))
4042 == TREE_OPERAND (TREE_OPERAND (str, 0), 1)
4043 && tree_fits_uhwi_p (len)
4044 && tree_to_uhwi (len) >= 1
4045 && tree_to_uhwi (len)
4046 == (unsigned HOST_WIDE_INT)
4047 TREE_STRING_LENGTH (TREE_OPERAND (TREE_OPERAND (str, 0), 0)))
4049 tree folded = fold_convert (gfc_get_pchar_type (kind), str);
4050 folded = build_fold_indirect_ref_loc (input_location, folded);
4051 if (TREE_CODE (folded) == INTEGER_CST)
4053 tree string_cst = TREE_OPERAND (TREE_OPERAND (str, 0), 0);
4054 int length = TREE_STRING_LENGTH (string_cst);
4055 const char *ptr = TREE_STRING_POINTER (string_cst);
4057 for (; length > 0; length--)
4058 if (ptr[length - 1] != ' ')
4059 break;
4061 return length;
4064 return -1;
4067 /* Helper to build a call to memcmp. */
4069 static tree
4070 build_memcmp_call (tree s1, tree s2, tree n)
4072 tree tmp;
4074 if (!POINTER_TYPE_P (TREE_TYPE (s1)))
4075 s1 = gfc_build_addr_expr (pvoid_type_node, s1);
4076 else
4077 s1 = fold_convert (pvoid_type_node, s1);
4079 if (!POINTER_TYPE_P (TREE_TYPE (s2)))
4080 s2 = gfc_build_addr_expr (pvoid_type_node, s2);
4081 else
4082 s2 = fold_convert (pvoid_type_node, s2);
4084 n = fold_convert (size_type_node, n);
4086 tmp = build_call_expr_loc (input_location,
4087 builtin_decl_explicit (BUILT_IN_MEMCMP),
4088 3, s1, s2, n);
4090 return fold_convert (integer_type_node, tmp);
4093 /* Compare two strings. If they are all single characters, the result is the
4094 subtraction of them. Otherwise, we build a library call. */
4096 tree
4097 gfc_build_compare_string (tree len1, tree str1, tree len2, tree str2, int kind,
4098 enum tree_code code)
4100 tree sc1;
4101 tree sc2;
4102 tree fndecl;
4104 gcc_assert (POINTER_TYPE_P (TREE_TYPE (str1)));
4105 gcc_assert (POINTER_TYPE_P (TREE_TYPE (str2)));
4107 sc1 = gfc_string_to_single_character (len1, str1, kind);
4108 sc2 = gfc_string_to_single_character (len2, str2, kind);
4110 if (sc1 != NULL_TREE && sc2 != NULL_TREE)
4112 /* Deal with single character specially. */
4113 sc1 = fold_convert (integer_type_node, sc1);
4114 sc2 = fold_convert (integer_type_node, sc2);
4115 return fold_build2_loc (input_location, MINUS_EXPR, integer_type_node,
4116 sc1, sc2);
4119 if ((code == EQ_EXPR || code == NE_EXPR)
4120 && optimize
4121 && INTEGER_CST_P (len1) && INTEGER_CST_P (len2))
4123 /* If one string is a string literal with LEN_TRIM longer
4124 than the length of the second string, the strings
4125 compare unequal. */
4126 int len = gfc_optimize_len_trim (len1, str1, kind);
4127 if (len > 0 && compare_tree_int (len2, len) < 0)
4128 return integer_one_node;
4129 len = gfc_optimize_len_trim (len2, str2, kind);
4130 if (len > 0 && compare_tree_int (len1, len) < 0)
4131 return integer_one_node;
4134 /* We can compare via memcpy if the strings are known to be equal
4135 in length and they are
4136 - kind=1
4137 - kind=4 and the comparison is for (in)equality. */
4139 if (INTEGER_CST_P (len1) && INTEGER_CST_P (len2)
4140 && tree_int_cst_equal (len1, len2)
4141 && (kind == 1 || code == EQ_EXPR || code == NE_EXPR))
4143 tree tmp;
4144 tree chartype;
4146 chartype = gfc_get_char_type (kind);
4147 tmp = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE(len1),
4148 fold_convert (TREE_TYPE(len1),
4149 TYPE_SIZE_UNIT(chartype)),
4150 len1);
4151 return build_memcmp_call (str1, str2, tmp);
4154 /* Build a call for the comparison. */
4155 if (kind == 1)
4156 fndecl = gfor_fndecl_compare_string;
4157 else if (kind == 4)
4158 fndecl = gfor_fndecl_compare_string_char4;
4159 else
4160 gcc_unreachable ();
4162 return build_call_expr_loc (input_location, fndecl, 4,
4163 len1, str1, len2, str2);
4167 /* Return the backend_decl for a procedure pointer component. */
4169 static tree
4170 get_proc_ptr_comp (gfc_expr *e)
4172 gfc_se comp_se;
4173 gfc_expr *e2;
4174 expr_t old_type;
4176 gfc_init_se (&comp_se, NULL);
4177 e2 = gfc_copy_expr (e);
4178 /* We have to restore the expr type later so that gfc_free_expr frees
4179 the exact same thing that was allocated.
4180 TODO: This is ugly. */
4181 old_type = e2->expr_type;
4182 e2->expr_type = EXPR_VARIABLE;
4183 gfc_conv_expr (&comp_se, e2);
4184 e2->expr_type = old_type;
4185 gfc_free_expr (e2);
4186 return build_fold_addr_expr_loc (input_location, comp_se.expr);
4190 /* Convert a typebound function reference from a class object. */
4191 static void
4192 conv_base_obj_fcn_val (gfc_se * se, tree base_object, gfc_expr * expr)
4194 gfc_ref *ref;
4195 tree var;
4197 if (!VAR_P (base_object))
4199 var = gfc_create_var (TREE_TYPE (base_object), NULL);
4200 gfc_add_modify (&se->pre, var, base_object);
4202 se->expr = gfc_class_vptr_get (base_object);
4203 se->expr = build_fold_indirect_ref_loc (input_location, se->expr);
4204 ref = expr->ref;
4205 while (ref && ref->next)
4206 ref = ref->next;
4207 gcc_assert (ref && ref->type == REF_COMPONENT);
4208 if (ref->u.c.sym->attr.extension)
4209 conv_parent_component_references (se, ref);
4210 gfc_conv_component_ref (se, ref);
4211 se->expr = build_fold_addr_expr_loc (input_location, se->expr);
4215 static void
4216 conv_function_val (gfc_se * se, gfc_symbol * sym, gfc_expr * expr,
4217 gfc_actual_arglist *actual_args)
4219 tree tmp;
4221 if (gfc_is_proc_ptr_comp (expr))
4222 tmp = get_proc_ptr_comp (expr);
4223 else if (sym->attr.dummy)
4225 tmp = gfc_get_symbol_decl (sym);
4226 if (sym->attr.proc_pointer)
4227 tmp = build_fold_indirect_ref_loc (input_location,
4228 tmp);
4229 gcc_assert (TREE_CODE (TREE_TYPE (tmp)) == POINTER_TYPE
4230 && TREE_CODE (TREE_TYPE (TREE_TYPE (tmp))) == FUNCTION_TYPE);
4232 else
4234 if (!sym->backend_decl)
4235 sym->backend_decl = gfc_get_extern_function_decl (sym, actual_args);
4237 TREE_USED (sym->backend_decl) = 1;
4239 tmp = sym->backend_decl;
4241 if (sym->attr.cray_pointee)
4243 /* TODO - make the cray pointee a pointer to a procedure,
4244 assign the pointer to it and use it for the call. This
4245 will do for now! */
4246 tmp = convert (build_pointer_type (TREE_TYPE (tmp)),
4247 gfc_get_symbol_decl (sym->cp_pointer));
4248 tmp = gfc_evaluate_now (tmp, &se->pre);
4251 if (!POINTER_TYPE_P (TREE_TYPE (tmp)))
4253 gcc_assert (TREE_CODE (tmp) == FUNCTION_DECL);
4254 tmp = gfc_build_addr_expr (NULL_TREE, tmp);
4257 se->expr = tmp;
4261 /* Initialize MAPPING. */
4263 void
4264 gfc_init_interface_mapping (gfc_interface_mapping * mapping)
4266 mapping->syms = NULL;
4267 mapping->charlens = NULL;
4271 /* Free all memory held by MAPPING (but not MAPPING itself). */
4273 void
4274 gfc_free_interface_mapping (gfc_interface_mapping * mapping)
4276 gfc_interface_sym_mapping *sym;
4277 gfc_interface_sym_mapping *nextsym;
4278 gfc_charlen *cl;
4279 gfc_charlen *nextcl;
4281 for (sym = mapping->syms; sym; sym = nextsym)
4283 nextsym = sym->next;
4284 sym->new_sym->n.sym->formal = NULL;
4285 gfc_free_symbol (sym->new_sym->n.sym);
4286 gfc_free_expr (sym->expr);
4287 free (sym->new_sym);
4288 free (sym);
4290 for (cl = mapping->charlens; cl; cl = nextcl)
4292 nextcl = cl->next;
4293 gfc_free_expr (cl->length);
4294 free (cl);
4299 /* Return a copy of gfc_charlen CL. Add the returned structure to
4300 MAPPING so that it will be freed by gfc_free_interface_mapping. */
4302 static gfc_charlen *
4303 gfc_get_interface_mapping_charlen (gfc_interface_mapping * mapping,
4304 gfc_charlen * cl)
4306 gfc_charlen *new_charlen;
4308 new_charlen = gfc_get_charlen ();
4309 new_charlen->next = mapping->charlens;
4310 new_charlen->length = gfc_copy_expr (cl->length);
4312 mapping->charlens = new_charlen;
4313 return new_charlen;
4317 /* A subroutine of gfc_add_interface_mapping. Return a descriptorless
4318 array variable that can be used as the actual argument for dummy
4319 argument SYM. Add any initialization code to BLOCK. PACKED is as
4320 for gfc_get_nodesc_array_type and DATA points to the first element
4321 in the passed array. */
4323 static tree
4324 gfc_get_interface_mapping_array (stmtblock_t * block, gfc_symbol * sym,
4325 gfc_packed packed, tree data)
4327 tree type;
4328 tree var;
4330 type = gfc_typenode_for_spec (&sym->ts);
4331 type = gfc_get_nodesc_array_type (type, sym->as, packed,
4332 !sym->attr.target && !sym->attr.pointer
4333 && !sym->attr.proc_pointer);
4335 var = gfc_create_var (type, "ifm");
4336 gfc_add_modify (block, var, fold_convert (type, data));
4338 return var;
4342 /* A subroutine of gfc_add_interface_mapping. Set the stride, upper bounds
4343 and offset of descriptorless array type TYPE given that it has the same
4344 size as DESC. Add any set-up code to BLOCK. */
4346 static void
4347 gfc_set_interface_mapping_bounds (stmtblock_t * block, tree type, tree desc)
4349 int n;
4350 tree dim;
4351 tree offset;
4352 tree tmp;
4354 offset = gfc_index_zero_node;
4355 for (n = 0; n < GFC_TYPE_ARRAY_RANK (type); n++)
4357 dim = gfc_rank_cst[n];
4358 GFC_TYPE_ARRAY_STRIDE (type, n) = gfc_conv_array_stride (desc, n);
4359 if (GFC_TYPE_ARRAY_LBOUND (type, n) == NULL_TREE)
4361 GFC_TYPE_ARRAY_LBOUND (type, n)
4362 = gfc_conv_descriptor_lbound_get (desc, dim);
4363 GFC_TYPE_ARRAY_UBOUND (type, n)
4364 = gfc_conv_descriptor_ubound_get (desc, dim);
4366 else if (GFC_TYPE_ARRAY_UBOUND (type, n) == NULL_TREE)
4368 tmp = fold_build2_loc (input_location, MINUS_EXPR,
4369 gfc_array_index_type,
4370 gfc_conv_descriptor_ubound_get (desc, dim),
4371 gfc_conv_descriptor_lbound_get (desc, dim));
4372 tmp = fold_build2_loc (input_location, PLUS_EXPR,
4373 gfc_array_index_type,
4374 GFC_TYPE_ARRAY_LBOUND (type, n), tmp);
4375 tmp = gfc_evaluate_now (tmp, block);
4376 GFC_TYPE_ARRAY_UBOUND (type, n) = tmp;
4378 tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
4379 GFC_TYPE_ARRAY_LBOUND (type, n),
4380 GFC_TYPE_ARRAY_STRIDE (type, n));
4381 offset = fold_build2_loc (input_location, MINUS_EXPR,
4382 gfc_array_index_type, offset, tmp);
4384 offset = gfc_evaluate_now (offset, block);
4385 GFC_TYPE_ARRAY_OFFSET (type) = offset;
4389 /* Extend MAPPING so that it maps dummy argument SYM to the value stored
4390 in SE. The caller may still use se->expr and se->string_length after
4391 calling this function. */
4393 void
4394 gfc_add_interface_mapping (gfc_interface_mapping * mapping,
4395 gfc_symbol * sym, gfc_se * se,
4396 gfc_expr *expr)
4398 gfc_interface_sym_mapping *sm;
4399 tree desc;
4400 tree tmp;
4401 tree value;
4402 gfc_symbol *new_sym;
4403 gfc_symtree *root;
4404 gfc_symtree *new_symtree;
4406 /* Create a new symbol to represent the actual argument. */
4407 new_sym = gfc_new_symbol (sym->name, NULL);
4408 new_sym->ts = sym->ts;
4409 new_sym->as = gfc_copy_array_spec (sym->as);
4410 new_sym->attr.referenced = 1;
4411 new_sym->attr.dimension = sym->attr.dimension;
4412 new_sym->attr.contiguous = sym->attr.contiguous;
4413 new_sym->attr.codimension = sym->attr.codimension;
4414 new_sym->attr.pointer = sym->attr.pointer;
4415 new_sym->attr.allocatable = sym->attr.allocatable;
4416 new_sym->attr.flavor = sym->attr.flavor;
4417 new_sym->attr.function = sym->attr.function;
4419 /* Ensure that the interface is available and that
4420 descriptors are passed for array actual arguments. */
4421 if (sym->attr.flavor == FL_PROCEDURE)
4423 new_sym->formal = expr->symtree->n.sym->formal;
4424 new_sym->attr.always_explicit
4425 = expr->symtree->n.sym->attr.always_explicit;
4428 /* Create a fake symtree for it. */
4429 root = NULL;
4430 new_symtree = gfc_new_symtree (&root, sym->name);
4431 new_symtree->n.sym = new_sym;
4432 gcc_assert (new_symtree == root);
4434 /* Create a dummy->actual mapping. */
4435 sm = XCNEW (gfc_interface_sym_mapping);
4436 sm->next = mapping->syms;
4437 sm->old = sym;
4438 sm->new_sym = new_symtree;
4439 sm->expr = gfc_copy_expr (expr);
4440 mapping->syms = sm;
4442 /* Stabilize the argument's value. */
4443 if (!sym->attr.function && se)
4444 se->expr = gfc_evaluate_now (se->expr, &se->pre);
4446 if (sym->ts.type == BT_CHARACTER)
4448 /* Create a copy of the dummy argument's length. */
4449 new_sym->ts.u.cl = gfc_get_interface_mapping_charlen (mapping, sym->ts.u.cl);
4450 sm->expr->ts.u.cl = new_sym->ts.u.cl;
4452 /* If the length is specified as "*", record the length that
4453 the caller is passing. We should use the callee's length
4454 in all other cases. */
4455 if (!new_sym->ts.u.cl->length && se)
4457 se->string_length = gfc_evaluate_now (se->string_length, &se->pre);
4458 new_sym->ts.u.cl->backend_decl = se->string_length;
4462 if (!se)
4463 return;
4465 /* Use the passed value as-is if the argument is a function. */
4466 if (sym->attr.flavor == FL_PROCEDURE)
4467 value = se->expr;
4469 /* If the argument is a pass-by-value scalar, use the value as is. */
4470 else if (!sym->attr.dimension && sym->attr.value)
4471 value = se->expr;
4473 /* If the argument is either a string or a pointer to a string,
4474 convert it to a boundless character type. */
4475 else if (!sym->attr.dimension && sym->ts.type == BT_CHARACTER)
4477 tmp = gfc_get_character_type_len (sym->ts.kind, NULL);
4478 tmp = build_pointer_type (tmp);
4479 if (sym->attr.pointer)
4480 value = build_fold_indirect_ref_loc (input_location,
4481 se->expr);
4482 else
4483 value = se->expr;
4484 value = fold_convert (tmp, value);
4487 /* If the argument is a scalar, a pointer to an array or an allocatable,
4488 dereference it. */
4489 else if (!sym->attr.dimension || sym->attr.pointer || sym->attr.allocatable)
4490 value = build_fold_indirect_ref_loc (input_location,
4491 se->expr);
4493 /* For character(*), use the actual argument's descriptor. */
4494 else if (sym->ts.type == BT_CHARACTER && !new_sym->ts.u.cl->length)
4495 value = build_fold_indirect_ref_loc (input_location,
4496 se->expr);
4498 /* If the argument is an array descriptor, use it to determine
4499 information about the actual argument's shape. */
4500 else if (POINTER_TYPE_P (TREE_TYPE (se->expr))
4501 && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (TREE_TYPE (se->expr))))
4503 /* Get the actual argument's descriptor. */
4504 desc = build_fold_indirect_ref_loc (input_location,
4505 se->expr);
4507 /* Create the replacement variable. */
4508 tmp = gfc_conv_descriptor_data_get (desc);
4509 value = gfc_get_interface_mapping_array (&se->pre, sym,
4510 PACKED_NO, tmp);
4512 /* Use DESC to work out the upper bounds, strides and offset. */
4513 gfc_set_interface_mapping_bounds (&se->pre, TREE_TYPE (value), desc);
4515 else
4516 /* Otherwise we have a packed array. */
4517 value = gfc_get_interface_mapping_array (&se->pre, sym,
4518 PACKED_FULL, se->expr);
4520 new_sym->backend_decl = value;
4524 /* Called once all dummy argument mappings have been added to MAPPING,
4525 but before the mapping is used to evaluate expressions. Pre-evaluate
4526 the length of each argument, adding any initialization code to PRE and
4527 any finalization code to POST. */
4529 void
4530 gfc_finish_interface_mapping (gfc_interface_mapping * mapping,
4531 stmtblock_t * pre, stmtblock_t * post)
4533 gfc_interface_sym_mapping *sym;
4534 gfc_expr *expr;
4535 gfc_se se;
4537 for (sym = mapping->syms; sym; sym = sym->next)
4538 if (sym->new_sym->n.sym->ts.type == BT_CHARACTER
4539 && !sym->new_sym->n.sym->ts.u.cl->backend_decl)
4541 expr = sym->new_sym->n.sym->ts.u.cl->length;
4542 gfc_apply_interface_mapping_to_expr (mapping, expr);
4543 gfc_init_se (&se, NULL);
4544 gfc_conv_expr (&se, expr);
4545 se.expr = fold_convert (gfc_charlen_type_node, se.expr);
4546 se.expr = gfc_evaluate_now (se.expr, &se.pre);
4547 gfc_add_block_to_block (pre, &se.pre);
4548 gfc_add_block_to_block (post, &se.post);
4550 sym->new_sym->n.sym->ts.u.cl->backend_decl = se.expr;
4555 /* Like gfc_apply_interface_mapping_to_expr, but applied to
4556 constructor C. */
4558 static void
4559 gfc_apply_interface_mapping_to_cons (gfc_interface_mapping * mapping,
4560 gfc_constructor_base base)
4562 gfc_constructor *c;
4563 for (c = gfc_constructor_first (base); c; c = gfc_constructor_next (c))
4565 gfc_apply_interface_mapping_to_expr (mapping, c->expr);
4566 if (c->iterator)
4568 gfc_apply_interface_mapping_to_expr (mapping, c->iterator->start);
4569 gfc_apply_interface_mapping_to_expr (mapping, c->iterator->end);
4570 gfc_apply_interface_mapping_to_expr (mapping, c->iterator->step);
4576 /* Like gfc_apply_interface_mapping_to_expr, but applied to
4577 reference REF. */
4579 static void
4580 gfc_apply_interface_mapping_to_ref (gfc_interface_mapping * mapping,
4581 gfc_ref * ref)
4583 int n;
4585 for (; ref; ref = ref->next)
4586 switch (ref->type)
4588 case REF_ARRAY:
4589 for (n = 0; n < ref->u.ar.dimen; n++)
4591 gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.start[n]);
4592 gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.end[n]);
4593 gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.stride[n]);
4595 break;
4597 case REF_COMPONENT:
4598 case REF_INQUIRY:
4599 break;
4601 case REF_SUBSTRING:
4602 gfc_apply_interface_mapping_to_expr (mapping, ref->u.ss.start);
4603 gfc_apply_interface_mapping_to_expr (mapping, ref->u.ss.end);
4604 break;
4609 /* Convert intrinsic function calls into result expressions. */
4611 static bool
4612 gfc_map_intrinsic_function (gfc_expr *expr, gfc_interface_mapping *mapping)
4614 gfc_symbol *sym;
4615 gfc_expr *new_expr;
4616 gfc_expr *arg1;
4617 gfc_expr *arg2;
4618 int d, dup;
4620 arg1 = expr->value.function.actual->expr;
4621 if (expr->value.function.actual->next)
4622 arg2 = expr->value.function.actual->next->expr;
4623 else
4624 arg2 = NULL;
4626 sym = arg1->symtree->n.sym;
4628 if (sym->attr.dummy)
4629 return false;
4631 new_expr = NULL;
4633 switch (expr->value.function.isym->id)
4635 case GFC_ISYM_LEN:
4636 /* TODO figure out why this condition is necessary. */
4637 if (sym->attr.function
4638 && (arg1->ts.u.cl->length == NULL
4639 || (arg1->ts.u.cl->length->expr_type != EXPR_CONSTANT
4640 && arg1->ts.u.cl->length->expr_type != EXPR_VARIABLE)))
4641 return false;
4643 new_expr = gfc_copy_expr (arg1->ts.u.cl->length);
4644 break;
4646 case GFC_ISYM_LEN_TRIM:
4647 new_expr = gfc_copy_expr (arg1);
4648 gfc_apply_interface_mapping_to_expr (mapping, new_expr);
4650 if (!new_expr)
4651 return false;
4653 gfc_replace_expr (arg1, new_expr);
4654 return true;
4656 case GFC_ISYM_SIZE:
4657 if (!sym->as || sym->as->rank == 0)
4658 return false;
4660 if (arg2 && arg2->expr_type == EXPR_CONSTANT)
4662 dup = mpz_get_si (arg2->value.integer);
4663 d = dup - 1;
4665 else
4667 dup = sym->as->rank;
4668 d = 0;
4671 for (; d < dup; d++)
4673 gfc_expr *tmp;
4675 if (!sym->as->upper[d] || !sym->as->lower[d])
4677 gfc_free_expr (new_expr);
4678 return false;
4681 tmp = gfc_add (gfc_copy_expr (sym->as->upper[d]),
4682 gfc_get_int_expr (gfc_default_integer_kind,
4683 NULL, 1));
4684 tmp = gfc_subtract (tmp, gfc_copy_expr (sym->as->lower[d]));
4685 if (new_expr)
4686 new_expr = gfc_multiply (new_expr, tmp);
4687 else
4688 new_expr = tmp;
4690 break;
4692 case GFC_ISYM_LBOUND:
4693 case GFC_ISYM_UBOUND:
4694 /* TODO These implementations of lbound and ubound do not limit if
4695 the size < 0, according to F95's 13.14.53 and 13.14.113. */
4697 if (!sym->as || sym->as->rank == 0)
4698 return false;
4700 if (arg2 && arg2->expr_type == EXPR_CONSTANT)
4701 d = mpz_get_si (arg2->value.integer) - 1;
4702 else
4703 return false;
4705 if (expr->value.function.isym->id == GFC_ISYM_LBOUND)
4707 if (sym->as->lower[d])
4708 new_expr = gfc_copy_expr (sym->as->lower[d]);
4710 else
4712 if (sym->as->upper[d])
4713 new_expr = gfc_copy_expr (sym->as->upper[d]);
4715 break;
4717 default:
4718 break;
4721 gfc_apply_interface_mapping_to_expr (mapping, new_expr);
4722 if (!new_expr)
4723 return false;
4725 gfc_replace_expr (expr, new_expr);
4726 return true;
4730 static void
4731 gfc_map_fcn_formal_to_actual (gfc_expr *expr, gfc_expr *map_expr,
4732 gfc_interface_mapping * mapping)
4734 gfc_formal_arglist *f;
4735 gfc_actual_arglist *actual;
4737 actual = expr->value.function.actual;
4738 f = gfc_sym_get_dummy_args (map_expr->symtree->n.sym);
4740 for (; f && actual; f = f->next, actual = actual->next)
4742 if (!actual->expr)
4743 continue;
4745 gfc_add_interface_mapping (mapping, f->sym, NULL, actual->expr);
4748 if (map_expr->symtree->n.sym->attr.dimension)
4750 int d;
4751 gfc_array_spec *as;
4753 as = gfc_copy_array_spec (map_expr->symtree->n.sym->as);
4755 for (d = 0; d < as->rank; d++)
4757 gfc_apply_interface_mapping_to_expr (mapping, as->lower[d]);
4758 gfc_apply_interface_mapping_to_expr (mapping, as->upper[d]);
4761 expr->value.function.esym->as = as;
4764 if (map_expr->symtree->n.sym->ts.type == BT_CHARACTER)
4766 expr->value.function.esym->ts.u.cl->length
4767 = gfc_copy_expr (map_expr->symtree->n.sym->ts.u.cl->length);
4769 gfc_apply_interface_mapping_to_expr (mapping,
4770 expr->value.function.esym->ts.u.cl->length);
4775 /* EXPR is a copy of an expression that appeared in the interface
4776 associated with MAPPING. Walk it recursively looking for references to
4777 dummy arguments that MAPPING maps to actual arguments. Replace each such
4778 reference with a reference to the associated actual argument. */
4780 static void
4781 gfc_apply_interface_mapping_to_expr (gfc_interface_mapping * mapping,
4782 gfc_expr * expr)
4784 gfc_interface_sym_mapping *sym;
4785 gfc_actual_arglist *actual;
4787 if (!expr)
4788 return;
4790 /* Copying an expression does not copy its length, so do that here. */
4791 if (expr->ts.type == BT_CHARACTER && expr->ts.u.cl)
4793 expr->ts.u.cl = gfc_get_interface_mapping_charlen (mapping, expr->ts.u.cl);
4794 gfc_apply_interface_mapping_to_expr (mapping, expr->ts.u.cl->length);
4797 /* Apply the mapping to any references. */
4798 gfc_apply_interface_mapping_to_ref (mapping, expr->ref);
4800 /* ...and to the expression's symbol, if it has one. */
4801 /* TODO Find out why the condition on expr->symtree had to be moved into
4802 the loop rather than being outside it, as originally. */
4803 for (sym = mapping->syms; sym; sym = sym->next)
4804 if (expr->symtree && sym->old == expr->symtree->n.sym)
4806 if (sym->new_sym->n.sym->backend_decl)
4807 expr->symtree = sym->new_sym;
4808 else if (sym->expr)
4809 gfc_replace_expr (expr, gfc_copy_expr (sym->expr));
4812 /* ...and to subexpressions in expr->value. */
4813 switch (expr->expr_type)
4815 case EXPR_VARIABLE:
4816 case EXPR_CONSTANT:
4817 case EXPR_NULL:
4818 case EXPR_SUBSTRING:
4819 break;
4821 case EXPR_OP:
4822 gfc_apply_interface_mapping_to_expr (mapping, expr->value.op.op1);
4823 gfc_apply_interface_mapping_to_expr (mapping, expr->value.op.op2);
4824 break;
4826 case EXPR_FUNCTION:
4827 for (actual = expr->value.function.actual; actual; actual = actual->next)
4828 gfc_apply_interface_mapping_to_expr (mapping, actual->expr);
4830 if (expr->value.function.esym == NULL
4831 && expr->value.function.isym != NULL
4832 && expr->value.function.actual
4833 && expr->value.function.actual->expr
4834 && expr->value.function.actual->expr->symtree
4835 && gfc_map_intrinsic_function (expr, mapping))
4836 break;
4838 for (sym = mapping->syms; sym; sym = sym->next)
4839 if (sym->old == expr->value.function.esym)
4841 expr->value.function.esym = sym->new_sym->n.sym;
4842 gfc_map_fcn_formal_to_actual (expr, sym->expr, mapping);
4843 expr->value.function.esym->result = sym->new_sym->n.sym;
4845 break;
4847 case EXPR_ARRAY:
4848 case EXPR_STRUCTURE:
4849 gfc_apply_interface_mapping_to_cons (mapping, expr->value.constructor);
4850 break;
4852 case EXPR_COMPCALL:
4853 case EXPR_PPC:
4854 case EXPR_UNKNOWN:
4855 gcc_unreachable ();
4856 break;
4859 return;
4863 /* Evaluate interface expression EXPR using MAPPING. Store the result
4864 in SE. */
4866 void
4867 gfc_apply_interface_mapping (gfc_interface_mapping * mapping,
4868 gfc_se * se, gfc_expr * expr)
4870 expr = gfc_copy_expr (expr);
4871 gfc_apply_interface_mapping_to_expr (mapping, expr);
4872 gfc_conv_expr (se, expr);
4873 se->expr = gfc_evaluate_now (se->expr, &se->pre);
4874 gfc_free_expr (expr);
4878 /* Returns a reference to a temporary array into which a component of
4879 an actual argument derived type array is copied and then returned
4880 after the function call. */
4881 void
4882 gfc_conv_subref_array_arg (gfc_se *se, gfc_expr * expr, int g77,
4883 sym_intent intent, bool formal_ptr,
4884 const gfc_symbol *fsym, const char *proc_name,
4885 gfc_symbol *sym, bool check_contiguous)
4887 gfc_se lse;
4888 gfc_se rse;
4889 gfc_ss *lss;
4890 gfc_ss *rss;
4891 gfc_loopinfo loop;
4892 gfc_loopinfo loop2;
4893 gfc_array_info *info;
4894 tree offset;
4895 tree tmp_index;
4896 tree tmp;
4897 tree base_type;
4898 tree size;
4899 stmtblock_t body;
4900 int n;
4901 int dimen;
4902 gfc_se work_se;
4903 gfc_se *parmse;
4904 bool pass_optional;
4906 pass_optional = fsym && fsym->attr.optional && sym && sym->attr.optional;
4908 if (pass_optional || check_contiguous)
4910 gfc_init_se (&work_se, NULL);
4911 parmse = &work_se;
4913 else
4914 parmse = se;
4916 if (gfc_option.rtcheck & GFC_RTCHECK_ARRAY_TEMPS)
4918 /* We will create a temporary array, so let us warn. */
4919 char * msg;
4921 if (fsym && proc_name)
4922 msg = xasprintf ("An array temporary was created for argument "
4923 "'%s' of procedure '%s'", fsym->name, proc_name);
4924 else
4925 msg = xasprintf ("An array temporary was created");
4927 tmp = build_int_cst (logical_type_node, 1);
4928 gfc_trans_runtime_check (false, true, tmp, &parmse->pre,
4929 &expr->where, msg);
4930 free (msg);
4933 gfc_init_se (&lse, NULL);
4934 gfc_init_se (&rse, NULL);
4936 /* Walk the argument expression. */
4937 rss = gfc_walk_expr (expr);
4939 gcc_assert (rss != gfc_ss_terminator);
4941 /* Initialize the scalarizer. */
4942 gfc_init_loopinfo (&loop);
4943 gfc_add_ss_to_loop (&loop, rss);
4945 /* Calculate the bounds of the scalarization. */
4946 gfc_conv_ss_startstride (&loop);
4948 /* Build an ss for the temporary. */
4949 if (expr->ts.type == BT_CHARACTER && !expr->ts.u.cl->backend_decl)
4950 gfc_conv_string_length (expr->ts.u.cl, expr, &parmse->pre);
4952 base_type = gfc_typenode_for_spec (&expr->ts);
4953 if (GFC_ARRAY_TYPE_P (base_type)
4954 || GFC_DESCRIPTOR_TYPE_P (base_type))
4955 base_type = gfc_get_element_type (base_type);
4957 if (expr->ts.type == BT_CLASS)
4958 base_type = gfc_typenode_for_spec (&CLASS_DATA (expr)->ts);
4960 loop.temp_ss = gfc_get_temp_ss (base_type, ((expr->ts.type == BT_CHARACTER)
4961 ? expr->ts.u.cl->backend_decl
4962 : NULL),
4963 loop.dimen);
4965 parmse->string_length = loop.temp_ss->info->string_length;
4967 /* Associate the SS with the loop. */
4968 gfc_add_ss_to_loop (&loop, loop.temp_ss);
4970 /* Setup the scalarizing loops. */
4971 gfc_conv_loop_setup (&loop, &expr->where);
4973 /* Pass the temporary descriptor back to the caller. */
4974 info = &loop.temp_ss->info->data.array;
4975 parmse->expr = info->descriptor;
4977 /* Setup the gfc_se structures. */
4978 gfc_copy_loopinfo_to_se (&lse, &loop);
4979 gfc_copy_loopinfo_to_se (&rse, &loop);
4981 rse.ss = rss;
4982 lse.ss = loop.temp_ss;
4983 gfc_mark_ss_chain_used (rss, 1);
4984 gfc_mark_ss_chain_used (loop.temp_ss, 1);
4986 /* Start the scalarized loop body. */
4987 gfc_start_scalarized_body (&loop, &body);
4989 /* Translate the expression. */
4990 gfc_conv_expr (&rse, expr);
4992 /* Reset the offset for the function call since the loop
4993 is zero based on the data pointer. Note that the temp
4994 comes first in the loop chain since it is added second. */
4995 if (gfc_is_class_array_function (expr))
4997 tmp = loop.ss->loop_chain->info->data.array.descriptor;
4998 gfc_conv_descriptor_offset_set (&loop.pre, tmp,
4999 gfc_index_zero_node);
5002 gfc_conv_tmp_array_ref (&lse);
5004 if (intent != INTENT_OUT)
5006 tmp = gfc_trans_scalar_assign (&lse, &rse, expr->ts, false, false);
5007 gfc_add_expr_to_block (&body, tmp);
5008 gcc_assert (rse.ss == gfc_ss_terminator);
5009 gfc_trans_scalarizing_loops (&loop, &body);
5011 else
5013 /* Make sure that the temporary declaration survives by merging
5014 all the loop declarations into the current context. */
5015 for (n = 0; n < loop.dimen; n++)
5017 gfc_merge_block_scope (&body);
5018 body = loop.code[loop.order[n]];
5020 gfc_merge_block_scope (&body);
5023 /* Add the post block after the second loop, so that any
5024 freeing of allocated memory is done at the right time. */
5025 gfc_add_block_to_block (&parmse->pre, &loop.pre);
5027 /**********Copy the temporary back again.*********/
5029 gfc_init_se (&lse, NULL);
5030 gfc_init_se (&rse, NULL);
5032 /* Walk the argument expression. */
5033 lss = gfc_walk_expr (expr);
5034 rse.ss = loop.temp_ss;
5035 lse.ss = lss;
5037 /* Initialize the scalarizer. */
5038 gfc_init_loopinfo (&loop2);
5039 gfc_add_ss_to_loop (&loop2, lss);
5041 dimen = rse.ss->dimen;
5043 /* Skip the write-out loop for this case. */
5044 if (gfc_is_class_array_function (expr))
5045 goto class_array_fcn;
5047 /* Calculate the bounds of the scalarization. */
5048 gfc_conv_ss_startstride (&loop2);
5050 /* Setup the scalarizing loops. */
5051 gfc_conv_loop_setup (&loop2, &expr->where);
5053 gfc_copy_loopinfo_to_se (&lse, &loop2);
5054 gfc_copy_loopinfo_to_se (&rse, &loop2);
5056 gfc_mark_ss_chain_used (lss, 1);
5057 gfc_mark_ss_chain_used (loop.temp_ss, 1);
5059 /* Declare the variable to hold the temporary offset and start the
5060 scalarized loop body. */
5061 offset = gfc_create_var (gfc_array_index_type, NULL);
5062 gfc_start_scalarized_body (&loop2, &body);
5064 /* Build the offsets for the temporary from the loop variables. The
5065 temporary array has lbounds of zero and strides of one in all
5066 dimensions, so this is very simple. The offset is only computed
5067 outside the innermost loop, so the overall transfer could be
5068 optimized further. */
5069 info = &rse.ss->info->data.array;
5071 tmp_index = gfc_index_zero_node;
5072 for (n = dimen - 1; n > 0; n--)
5074 tree tmp_str;
5075 tmp = rse.loop->loopvar[n];
5076 tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
5077 tmp, rse.loop->from[n]);
5078 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
5079 tmp, tmp_index);
5081 tmp_str = fold_build2_loc (input_location, MINUS_EXPR,
5082 gfc_array_index_type,
5083 rse.loop->to[n-1], rse.loop->from[n-1]);
5084 tmp_str = fold_build2_loc (input_location, PLUS_EXPR,
5085 gfc_array_index_type,
5086 tmp_str, gfc_index_one_node);
5088 tmp_index = fold_build2_loc (input_location, MULT_EXPR,
5089 gfc_array_index_type, tmp, tmp_str);
5092 tmp_index = fold_build2_loc (input_location, MINUS_EXPR,
5093 gfc_array_index_type,
5094 tmp_index, rse.loop->from[0]);
5095 gfc_add_modify (&rse.loop->code[0], offset, tmp_index);
5097 tmp_index = fold_build2_loc (input_location, PLUS_EXPR,
5098 gfc_array_index_type,
5099 rse.loop->loopvar[0], offset);
5101 /* Now use the offset for the reference. */
5102 tmp = build_fold_indirect_ref_loc (input_location,
5103 info->data);
5104 rse.expr = gfc_build_array_ref (tmp, tmp_index, NULL);
5106 if (expr->ts.type == BT_CHARACTER)
5107 rse.string_length = expr->ts.u.cl->backend_decl;
5109 gfc_conv_expr (&lse, expr);
5111 gcc_assert (lse.ss == gfc_ss_terminator);
5113 tmp = gfc_trans_scalar_assign (&lse, &rse, expr->ts, false, true);
5114 gfc_add_expr_to_block (&body, tmp);
5116 /* Generate the copying loops. */
5117 gfc_trans_scalarizing_loops (&loop2, &body);
5119 /* Wrap the whole thing up by adding the second loop to the post-block
5120 and following it by the post-block of the first loop. In this way,
5121 if the temporary needs freeing, it is done after use! */
5122 if (intent != INTENT_IN)
5124 gfc_add_block_to_block (&parmse->post, &loop2.pre);
5125 gfc_add_block_to_block (&parmse->post, &loop2.post);
5128 class_array_fcn:
5130 gfc_add_block_to_block (&parmse->post, &loop.post);
5132 gfc_cleanup_loop (&loop);
5133 gfc_cleanup_loop (&loop2);
5135 /* Pass the string length to the argument expression. */
5136 if (expr->ts.type == BT_CHARACTER)
5137 parmse->string_length = expr->ts.u.cl->backend_decl;
5139 /* Determine the offset for pointer formal arguments and set the
5140 lbounds to one. */
5141 if (formal_ptr)
5143 size = gfc_index_one_node;
5144 offset = gfc_index_zero_node;
5145 for (n = 0; n < dimen; n++)
5147 tmp = gfc_conv_descriptor_ubound_get (parmse->expr,
5148 gfc_rank_cst[n]);
5149 tmp = fold_build2_loc (input_location, PLUS_EXPR,
5150 gfc_array_index_type, tmp,
5151 gfc_index_one_node);
5152 gfc_conv_descriptor_ubound_set (&parmse->pre,
5153 parmse->expr,
5154 gfc_rank_cst[n],
5155 tmp);
5156 gfc_conv_descriptor_lbound_set (&parmse->pre,
5157 parmse->expr,
5158 gfc_rank_cst[n],
5159 gfc_index_one_node);
5160 size = gfc_evaluate_now (size, &parmse->pre);
5161 offset = fold_build2_loc (input_location, MINUS_EXPR,
5162 gfc_array_index_type,
5163 offset, size);
5164 offset = gfc_evaluate_now (offset, &parmse->pre);
5165 tmp = fold_build2_loc (input_location, MINUS_EXPR,
5166 gfc_array_index_type,
5167 rse.loop->to[n], rse.loop->from[n]);
5168 tmp = fold_build2_loc (input_location, PLUS_EXPR,
5169 gfc_array_index_type,
5170 tmp, gfc_index_one_node);
5171 size = fold_build2_loc (input_location, MULT_EXPR,
5172 gfc_array_index_type, size, tmp);
5175 gfc_conv_descriptor_offset_set (&parmse->pre, parmse->expr,
5176 offset);
5179 /* We want either the address for the data or the address of the descriptor,
5180 depending on the mode of passing array arguments. */
5181 if (g77)
5182 parmse->expr = gfc_conv_descriptor_data_get (parmse->expr);
5183 else
5184 parmse->expr = gfc_build_addr_expr (NULL_TREE, parmse->expr);
5186 /* Basically make this into
5188 if (present)
5190 if (contiguous)
5192 pointer = a;
5194 else
5196 parmse->pre();
5197 pointer = parmse->expr;
5200 else
5201 pointer = NULL;
5203 foo (pointer);
5204 if (present && !contiguous)
5205 se->post();
5209 if (pass_optional || check_contiguous)
5211 tree type;
5212 stmtblock_t else_block;
5213 tree pre_stmts, post_stmts;
5214 tree pointer;
5215 tree else_stmt;
5216 tree present_var = NULL_TREE;
5217 tree cont_var = NULL_TREE;
5218 tree post_cond;
5220 type = TREE_TYPE (parmse->expr);
5221 pointer = gfc_create_var (type, "arg_ptr");
5223 if (check_contiguous)
5225 gfc_se cont_se, array_se;
5226 stmtblock_t if_block, else_block;
5227 tree if_stmt, else_stmt;
5228 mpz_t size;
5229 bool size_set;
5231 cont_var = gfc_create_var (boolean_type_node, "contiguous");
5233 /* If the size is known to be one at compile-time, set
5234 cont_var to true unconditionally. This may look
5235 inelegant, but we're only doing this during
5236 optimization, so the statements will be optimized away,
5237 and this saves complexity here. */
5239 size_set = gfc_array_size (expr, &size);
5240 if (size_set && mpz_cmp_ui (size, 1) == 0)
5242 gfc_add_modify (&se->pre, cont_var,
5243 build_one_cst (boolean_type_node));
5245 else
5247 /* cont_var = is_contiguous (expr); . */
5248 gfc_init_se (&cont_se, parmse);
5249 gfc_conv_is_contiguous_expr (&cont_se, expr);
5250 gfc_add_block_to_block (&se->pre, &(&cont_se)->pre);
5251 gfc_add_modify (&se->pre, cont_var, cont_se.expr);
5252 gfc_add_block_to_block (&se->pre, &(&cont_se)->post);
5255 if (size_set)
5256 mpz_clear (size);
5258 /* arrayse->expr = descriptor of a. */
5259 gfc_init_se (&array_se, se);
5260 gfc_conv_expr_descriptor (&array_se, expr);
5261 gfc_add_block_to_block (&se->pre, &(&array_se)->pre);
5262 gfc_add_block_to_block (&se->pre, &(&array_se)->post);
5264 /* if_stmt = { pointer = &a[0]; } . */
5265 gfc_init_block (&if_block);
5266 tmp = gfc_conv_array_data (array_se.expr);
5267 tmp = fold_convert (type, tmp);
5268 gfc_add_modify (&if_block, pointer, tmp);
5269 if_stmt = gfc_finish_block (&if_block);
5271 /* else_stmt = { parmse->pre(); pointer = parmse->expr; } . */
5272 gfc_init_block (&else_block);
5273 gfc_add_block_to_block (&else_block, &parmse->pre);
5274 gfc_add_modify (&else_block, pointer, parmse->expr);
5275 else_stmt = gfc_finish_block (&else_block);
5277 /* And put the above into an if statement. */
5278 pre_stmts = fold_build3_loc (input_location, COND_EXPR, void_type_node,
5279 gfc_likely (cont_var,
5280 PRED_FORTRAN_CONTIGUOUS),
5281 if_stmt, else_stmt);
5283 else
5285 /* pointer = pramse->expr; . */
5286 gfc_add_modify (&parmse->pre, pointer, parmse->expr);
5287 pre_stmts = gfc_finish_block (&parmse->pre);
5290 if (pass_optional)
5292 present_var = gfc_create_var (boolean_type_node, "present");
5294 /* present_var = present(sym); . */
5295 tmp = gfc_conv_expr_present (sym);
5296 tmp = fold_convert (boolean_type_node, tmp);
5297 gfc_add_modify (&se->pre, present_var, tmp);
5299 /* else_stmt = { pointer = NULL; } . */
5300 gfc_init_block (&else_block);
5301 gfc_add_modify (&else_block, pointer, build_int_cst (type, 0));
5302 else_stmt = gfc_finish_block (&else_block);
5304 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
5305 gfc_likely (present_var,
5306 PRED_FORTRAN_ABSENT_DUMMY),
5307 pre_stmts, else_stmt);
5308 gfc_add_expr_to_block (&se->pre, tmp);
5310 else
5311 gfc_add_expr_to_block (&se->pre, pre_stmts);
5313 post_stmts = gfc_finish_block (&parmse->post);
5315 /* Put together the post stuff, plus the optional
5316 deallocation. */
5317 if (check_contiguous)
5319 /* !cont_var. */
5320 tmp = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
5321 cont_var,
5322 build_zero_cst (boolean_type_node));
5323 tmp = gfc_unlikely (tmp, PRED_FORTRAN_CONTIGUOUS);
5325 if (pass_optional)
5327 tree present_likely = gfc_likely (present_var,
5328 PRED_FORTRAN_ABSENT_DUMMY);
5329 post_cond = fold_build2_loc (input_location, TRUTH_ANDIF_EXPR,
5330 boolean_type_node, present_likely,
5331 tmp);
5333 else
5334 post_cond = tmp;
5336 else
5338 gcc_assert (pass_optional);
5339 post_cond = present_var;
5342 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, post_cond,
5343 post_stmts, build_empty_stmt (input_location));
5344 gfc_add_expr_to_block (&se->post, tmp);
5345 se->expr = pointer;
5348 return;
5352 /* Generate the code for argument list functions. */
5354 static void
5355 conv_arglist_function (gfc_se *se, gfc_expr *expr, const char *name)
5357 /* Pass by value for g77 %VAL(arg), pass the address
5358 indirectly for %LOC, else by reference. Thus %REF
5359 is a "do-nothing" and %LOC is the same as an F95
5360 pointer. */
5361 if (strcmp (name, "%VAL") == 0)
5362 gfc_conv_expr (se, expr);
5363 else if (strcmp (name, "%LOC") == 0)
5365 gfc_conv_expr_reference (se, expr);
5366 se->expr = gfc_build_addr_expr (NULL, se->expr);
5368 else if (strcmp (name, "%REF") == 0)
5369 gfc_conv_expr_reference (se, expr);
5370 else
5371 gfc_error ("Unknown argument list function at %L", &expr->where);
5375 /* This function tells whether the middle-end representation of the expression
5376 E given as input may point to data otherwise accessible through a variable
5377 (sub-)reference.
5378 It is assumed that the only expressions that may alias are variables,
5379 and array constructors if ARRAY_MAY_ALIAS is true and some of its elements
5380 may alias.
5381 This function is used to decide whether freeing an expression's allocatable
5382 components is safe or should be avoided.
5384 If ARRAY_MAY_ALIAS is true, an array constructor may alias if some of
5385 its elements are copied from a variable. This ARRAY_MAY_ALIAS trick
5386 is necessary because for array constructors, aliasing depends on how
5387 the array is used:
5388 - If E is an array constructor used as argument to an elemental procedure,
5389 the array, which is generated through shallow copy by the scalarizer,
5390 is used directly and can alias the expressions it was copied from.
5391 - If E is an array constructor used as argument to a non-elemental
5392 procedure,the scalarizer is used in gfc_conv_expr_descriptor to generate
5393 the array as in the previous case, but then that array is used
5394 to initialize a new descriptor through deep copy. There is no alias
5395 possible in that case.
5396 Thus, the ARRAY_MAY_ALIAS flag is necessary to distinguish the two cases
5397 above. */
5399 static bool
5400 expr_may_alias_variables (gfc_expr *e, bool array_may_alias)
5402 gfc_constructor *c;
5404 if (e->expr_type == EXPR_VARIABLE)
5405 return true;
5406 else if (e->expr_type == EXPR_FUNCTION)
5408 gfc_symbol *proc_ifc = gfc_get_proc_ifc_for_expr (e);
5410 if (proc_ifc->result != NULL
5411 && ((proc_ifc->result->ts.type == BT_CLASS
5412 && proc_ifc->result->ts.u.derived->attr.is_class
5413 && CLASS_DATA (proc_ifc->result)->attr.class_pointer)
5414 || proc_ifc->result->attr.pointer))
5415 return true;
5416 else
5417 return false;
5419 else if (e->expr_type != EXPR_ARRAY || !array_may_alias)
5420 return false;
5422 for (c = gfc_constructor_first (e->value.constructor);
5423 c; c = gfc_constructor_next (c))
5424 if (c->expr
5425 && expr_may_alias_variables (c->expr, array_may_alias))
5426 return true;
5428 return false;
5432 /* A helper function to set the dtype for unallocated or unassociated
5433 entities. */
5435 static void
5436 set_dtype_for_unallocated (gfc_se *parmse, gfc_expr *e)
5438 tree tmp;
5439 tree desc;
5440 tree cond;
5441 tree type;
5442 stmtblock_t block;
5444 /* TODO Figure out how to handle optional dummies. */
5445 if (e && e->expr_type == EXPR_VARIABLE
5446 && e->symtree->n.sym->attr.optional)
5447 return;
5449 desc = parmse->expr;
5450 if (desc == NULL_TREE)
5451 return;
5453 if (POINTER_TYPE_P (TREE_TYPE (desc)))
5454 desc = build_fold_indirect_ref_loc (input_location, desc);
5456 if (!GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (desc)))
5457 return;
5459 gfc_init_block (&block);
5460 tmp = gfc_conv_descriptor_data_get (desc);
5461 cond = fold_build2_loc (input_location, EQ_EXPR,
5462 logical_type_node, tmp,
5463 build_int_cst (TREE_TYPE (tmp), 0));
5464 tmp = gfc_conv_descriptor_dtype (desc);
5465 type = gfc_get_element_type (TREE_TYPE (desc));
5466 tmp = fold_build2_loc (input_location, MODIFY_EXPR,
5467 TREE_TYPE (tmp), tmp,
5468 gfc_get_dtype_rank_type (e->rank, type));
5469 gfc_add_expr_to_block (&block, tmp);
5470 cond = build3_v (COND_EXPR, cond,
5471 gfc_finish_block (&block),
5472 build_empty_stmt (input_location));
5473 gfc_add_expr_to_block (&parmse->pre, cond);
5478 /* Provide an interface between gfortran array descriptors and the F2018:18.4
5479 ISO_Fortran_binding array descriptors. */
5481 static void
5482 gfc_conv_gfc_desc_to_cfi_desc (gfc_se *parmse, gfc_expr *e, gfc_symbol *fsym)
5484 tree tmp;
5485 tree cfi_desc_ptr;
5486 tree gfc_desc_ptr;
5487 tree type;
5488 tree cond;
5489 tree desc_attr;
5490 int attribute;
5491 int cfi_attribute;
5492 symbol_attribute attr = gfc_expr_attr (e);
5494 /* If this is a full array or a scalar, the allocatable and pointer
5495 attributes can be passed. Otherwise it is 'CFI_attribute_other'*/
5496 attribute = 2;
5497 if (!e->rank || gfc_get_full_arrayspec_from_expr (e))
5499 if (attr.pointer)
5500 attribute = 0;
5501 else if (attr.allocatable)
5502 attribute = 1;
5505 if (fsym->attr.pointer)
5506 cfi_attribute = 0;
5507 else if (fsym->attr.allocatable)
5508 cfi_attribute = 1;
5509 else
5510 cfi_attribute = 2;
5512 if (e->rank != 0)
5514 parmse->force_no_tmp = 1;
5515 if (fsym->attr.contiguous
5516 && !gfc_is_simply_contiguous (e, false, true))
5517 gfc_conv_subref_array_arg (parmse, e, false, fsym->attr.intent,
5518 fsym->attr.pointer);
5519 else
5520 gfc_conv_expr_descriptor (parmse, e);
5522 if (POINTER_TYPE_P (TREE_TYPE (parmse->expr)))
5523 parmse->expr = build_fold_indirect_ref_loc (input_location,
5524 parmse->expr);
5525 bool is_artificial = (INDIRECT_REF_P (parmse->expr)
5526 ? DECL_ARTIFICIAL (TREE_OPERAND (parmse->expr, 0))
5527 : DECL_ARTIFICIAL (parmse->expr));
5529 /* Unallocated allocatable arrays and unassociated pointer arrays
5530 need their dtype setting if they are argument associated with
5531 assumed rank dummies. */
5532 if (fsym && fsym->as
5533 && (gfc_expr_attr (e).pointer
5534 || gfc_expr_attr (e).allocatable))
5535 set_dtype_for_unallocated (parmse, e);
5537 /* All the temporary descriptors are marked as DECL_ARTIFICIAL. If
5538 the expression type is different from the descriptor type, then
5539 the offset must be found (eg. to a component ref or substring)
5540 and the dtype updated. Assumed type entities are only allowed
5541 to be dummies in Fortran. They therefore lack the decl specific
5542 appendiges and so must be treated differently from other fortran
5543 entities passed to CFI descriptors in the interface decl. */
5544 type = e->ts.type != BT_ASSUMED ? gfc_typenode_for_spec (&e->ts) :
5545 NULL_TREE;
5547 if (type && is_artificial
5548 && type != gfc_get_element_type (TREE_TYPE (parmse->expr)))
5550 /* Obtain the offset to the data. */
5551 gfc_get_dataptr_offset (&parmse->pre, parmse->expr, parmse->expr,
5552 gfc_index_zero_node, true, e);
5554 /* Update the dtype. */
5555 gfc_add_modify (&parmse->pre,
5556 gfc_conv_descriptor_dtype (parmse->expr),
5557 gfc_get_dtype_rank_type (e->rank, type));
5559 else if (type == NULL_TREE
5560 || (!is_subref_array (e) && !is_artificial))
5562 /* Make sure that the span is set for expressions where it
5563 might not have been done already. */
5564 tmp = gfc_conv_descriptor_elem_len (parmse->expr);
5565 tmp = fold_convert (gfc_array_index_type, tmp);
5566 gfc_conv_descriptor_span_set (&parmse->pre, parmse->expr, tmp);
5569 else
5571 gfc_conv_expr (parmse, e);
5573 if (POINTER_TYPE_P (TREE_TYPE (parmse->expr)))
5574 parmse->expr = build_fold_indirect_ref_loc (input_location,
5575 parmse->expr);
5577 parmse->expr = gfc_conv_scalar_to_descriptor (parmse,
5578 parmse->expr, attr);
5581 /* Set the CFI attribute field through a temporary value for the
5582 gfc attribute. */
5583 desc_attr = gfc_conv_descriptor_attribute (parmse->expr);
5584 tmp = fold_build2_loc (input_location, MODIFY_EXPR,
5585 void_type_node, desc_attr,
5586 build_int_cst (TREE_TYPE (desc_attr), cfi_attribute));
5587 gfc_add_expr_to_block (&parmse->pre, tmp);
5589 /* Now pass the gfc_descriptor by reference. */
5590 parmse->expr = gfc_build_addr_expr (NULL_TREE, parmse->expr);
5592 /* Variables to point to the gfc and CFI descriptors; cfi = NULL implies
5593 that the CFI descriptor is allocated by the gfor_fndecl_gfc_to_cfi call. */
5594 gfc_desc_ptr = parmse->expr;
5595 cfi_desc_ptr = gfc_create_var (pvoid_type_node, "cfi");
5596 gfc_add_modify (&parmse->pre, cfi_desc_ptr, null_pointer_node);
5598 /* Allocate the CFI descriptor itself and fill the fields. */
5599 tmp = gfc_build_addr_expr (NULL_TREE, cfi_desc_ptr);
5600 tmp = build_call_expr_loc (input_location,
5601 gfor_fndecl_gfc_to_cfi, 2, tmp, gfc_desc_ptr);
5602 gfc_add_expr_to_block (&parmse->pre, tmp);
5604 /* Now set the gfc descriptor attribute. */
5605 tmp = fold_build2_loc (input_location, MODIFY_EXPR,
5606 void_type_node, desc_attr,
5607 build_int_cst (TREE_TYPE (desc_attr), attribute));
5608 gfc_add_expr_to_block (&parmse->pre, tmp);
5610 /* The CFI descriptor is passed to the bind_C procedure. */
5611 parmse->expr = cfi_desc_ptr;
5613 /* Free the CFI descriptor. */
5614 tmp = gfc_call_free (cfi_desc_ptr);
5615 gfc_prepend_expr_to_block (&parmse->post, tmp);
5617 /* Transfer values back to gfc descriptor. */
5618 if (cfi_attribute != 2 /* CFI_attribute_other. */
5619 && !fsym->attr.value
5620 && fsym->attr.intent != INTENT_IN)
5622 tmp = gfc_build_addr_expr (NULL_TREE, parmse->expr);
5623 tmp = build_call_expr_loc (input_location,
5624 gfor_fndecl_cfi_to_gfc, 2, gfc_desc_ptr, tmp);
5625 gfc_prepend_expr_to_block (&parmse->post, tmp);
5628 /* Deal with an optional dummy being passed to an optional formal arg
5629 by finishing the pre and post blocks and making their execution
5630 conditional on the dummy being present. */
5631 if (fsym->attr.optional && e->expr_type == EXPR_VARIABLE
5632 && e->symtree->n.sym->attr.optional)
5634 cond = gfc_conv_expr_present (e->symtree->n.sym);
5635 tmp = fold_build2 (MODIFY_EXPR, void_type_node,
5636 cfi_desc_ptr,
5637 build_int_cst (pvoid_type_node, 0));
5638 tmp = build3_v (COND_EXPR, cond,
5639 gfc_finish_block (&parmse->pre), tmp);
5640 gfc_add_expr_to_block (&parmse->pre, tmp);
5641 tmp = build3_v (COND_EXPR, cond,
5642 gfc_finish_block (&parmse->post),
5643 build_empty_stmt (input_location));
5644 gfc_add_expr_to_block (&parmse->post, tmp);
5649 /* Generate code for a procedure call. Note can return se->post != NULL.
5650 If se->direct_byref is set then se->expr contains the return parameter.
5651 Return nonzero, if the call has alternate specifiers.
5652 'expr' is only needed for procedure pointer components. */
5655 gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
5656 gfc_actual_arglist * args, gfc_expr * expr,
5657 vec<tree, va_gc> *append_args)
5659 gfc_interface_mapping mapping;
5660 vec<tree, va_gc> *arglist;
5661 vec<tree, va_gc> *retargs;
5662 tree tmp;
5663 tree fntype;
5664 gfc_se parmse;
5665 gfc_array_info *info;
5666 int byref;
5667 int parm_kind;
5668 tree type;
5669 tree var;
5670 tree len;
5671 tree base_object;
5672 vec<tree, va_gc> *stringargs;
5673 vec<tree, va_gc> *optionalargs;
5674 tree result = NULL;
5675 gfc_formal_arglist *formal;
5676 gfc_actual_arglist *arg;
5677 int has_alternate_specifier = 0;
5678 bool need_interface_mapping;
5679 bool callee_alloc;
5680 bool ulim_copy;
5681 gfc_typespec ts;
5682 gfc_charlen cl;
5683 gfc_expr *e;
5684 gfc_symbol *fsym;
5685 stmtblock_t post;
5686 enum {MISSING = 0, ELEMENTAL, SCALAR, SCALAR_POINTER, ARRAY};
5687 gfc_component *comp = NULL;
5688 int arglen;
5689 unsigned int argc;
5691 arglist = NULL;
5692 retargs = NULL;
5693 stringargs = NULL;
5694 optionalargs = NULL;
5695 var = NULL_TREE;
5696 len = NULL_TREE;
5697 gfc_clear_ts (&ts);
5699 comp = gfc_get_proc_ptr_comp (expr);
5701 bool elemental_proc = (comp
5702 && comp->ts.interface
5703 && comp->ts.interface->attr.elemental)
5704 || (comp && comp->attr.elemental)
5705 || sym->attr.elemental;
5707 if (se->ss != NULL)
5709 if (!elemental_proc)
5711 gcc_assert (se->ss->info->type == GFC_SS_FUNCTION);
5712 if (se->ss->info->useflags)
5714 gcc_assert ((!comp && gfc_return_by_reference (sym)
5715 && sym->result->attr.dimension)
5716 || (comp && comp->attr.dimension)
5717 || gfc_is_class_array_function (expr));
5718 gcc_assert (se->loop != NULL);
5719 /* Access the previously obtained result. */
5720 gfc_conv_tmp_array_ref (se);
5721 return 0;
5724 info = &se->ss->info->data.array;
5726 else
5727 info = NULL;
5729 gfc_init_block (&post);
5730 gfc_init_interface_mapping (&mapping);
5731 if (!comp)
5733 formal = gfc_sym_get_dummy_args (sym);
5734 need_interface_mapping = sym->attr.dimension ||
5735 (sym->ts.type == BT_CHARACTER
5736 && sym->ts.u.cl->length
5737 && sym->ts.u.cl->length->expr_type
5738 != EXPR_CONSTANT);
5740 else
5742 formal = comp->ts.interface ? comp->ts.interface->formal : NULL;
5743 need_interface_mapping = comp->attr.dimension ||
5744 (comp->ts.type == BT_CHARACTER
5745 && comp->ts.u.cl->length
5746 && comp->ts.u.cl->length->expr_type
5747 != EXPR_CONSTANT);
5750 base_object = NULL_TREE;
5751 /* For _vprt->_copy () routines no formal symbol is present. Nevertheless
5752 is the third and fourth argument to such a function call a value
5753 denoting the number of elements to copy (i.e., most of the time the
5754 length of a deferred length string). */
5755 ulim_copy = (formal == NULL)
5756 && UNLIMITED_POLY (sym)
5757 && comp && (strcmp ("_copy", comp->name) == 0);
5759 /* Evaluate the arguments. */
5760 for (arg = args, argc = 0; arg != NULL;
5761 arg = arg->next, formal = formal ? formal->next : NULL, ++argc)
5763 bool finalized = false;
5764 bool assumed_length_string = false;
5765 tree derived_array = NULL_TREE;
5767 e = arg->expr;
5768 fsym = formal ? formal->sym : NULL;
5769 parm_kind = MISSING;
5771 if (fsym && fsym->ts.type == BT_CHARACTER
5772 && (!fsym->ts.u.cl || !fsym->ts.u.cl->length))
5773 assumed_length_string = true;
5775 /* If the procedure requires an explicit interface, the actual
5776 argument is passed according to the corresponding formal
5777 argument. If the corresponding formal argument is a POINTER,
5778 ALLOCATABLE or assumed shape, we do not use g77's calling
5779 convention, and pass the address of the array descriptor
5780 instead. Otherwise we use g77's calling convention, in other words
5781 pass the array data pointer without descriptor. */
5782 bool nodesc_arg = fsym != NULL
5783 && !(fsym->attr.pointer || fsym->attr.allocatable)
5784 && fsym->as
5785 && fsym->as->type != AS_ASSUMED_SHAPE
5786 && fsym->as->type != AS_ASSUMED_RANK;
5787 if (comp)
5788 nodesc_arg = nodesc_arg || !comp->attr.always_explicit;
5789 else
5790 nodesc_arg = nodesc_arg || !sym->attr.always_explicit;
5792 /* Class array expressions are sometimes coming completely unadorned
5793 with either arrayspec or _data component. Correct that here.
5794 OOP-TODO: Move this to the frontend. */
5795 if (e && e->expr_type == EXPR_VARIABLE
5796 && !e->ref
5797 && e->ts.type == BT_CLASS
5798 && (CLASS_DATA (e)->attr.codimension
5799 || CLASS_DATA (e)->attr.dimension))
5801 gfc_typespec temp_ts = e->ts;
5802 gfc_add_class_array_ref (e);
5803 e->ts = temp_ts;
5806 if (e == NULL)
5808 if (se->ignore_optional)
5810 /* Some intrinsics have already been resolved to the correct
5811 parameters. */
5812 continue;
5814 else if (arg->label)
5816 has_alternate_specifier = 1;
5817 continue;
5819 else
5821 gfc_init_se (&parmse, NULL);
5823 /* For scalar arguments with VALUE attribute which are passed by
5824 value, pass "0" and a hidden argument gives the optional
5825 status. */
5826 if (fsym && fsym->attr.optional && fsym->attr.value
5827 && !fsym->attr.dimension && fsym->ts.type != BT_CHARACTER
5828 && fsym->ts.type != BT_CLASS && fsym->ts.type != BT_DERIVED)
5830 parmse.expr = fold_convert (gfc_sym_type (fsym),
5831 integer_zero_node);
5832 vec_safe_push (optionalargs, boolean_false_node);
5834 else
5836 /* Pass a NULL pointer for an absent arg. */
5837 parmse.expr = null_pointer_node;
5838 if (arg->missing_arg_type == BT_CHARACTER)
5839 parmse.string_length = build_int_cst (gfc_charlen_type_node,
5844 else if (arg->expr->expr_type == EXPR_NULL
5845 && fsym && !fsym->attr.pointer
5846 && (fsym->ts.type != BT_CLASS
5847 || !CLASS_DATA (fsym)->attr.class_pointer))
5849 /* Pass a NULL pointer to denote an absent arg. */
5850 gcc_assert (fsym->attr.optional && !fsym->attr.allocatable
5851 && (fsym->ts.type != BT_CLASS
5852 || !CLASS_DATA (fsym)->attr.allocatable));
5853 gfc_init_se (&parmse, NULL);
5854 parmse.expr = null_pointer_node;
5855 if (arg->missing_arg_type == BT_CHARACTER)
5856 parmse.string_length = build_int_cst (gfc_charlen_type_node, 0);
5858 else if (fsym && fsym->ts.type == BT_CLASS
5859 && e->ts.type == BT_DERIVED)
5861 /* The derived type needs to be converted to a temporary
5862 CLASS object. */
5863 gfc_init_se (&parmse, se);
5864 gfc_conv_derived_to_class (&parmse, e, fsym->ts, NULL,
5865 fsym->attr.optional
5866 && e->expr_type == EXPR_VARIABLE
5867 && e->symtree->n.sym->attr.optional,
5868 CLASS_DATA (fsym)->attr.class_pointer
5869 || CLASS_DATA (fsym)->attr.allocatable,
5870 &derived_array);
5872 else if (UNLIMITED_POLY (fsym) && e->ts.type != BT_CLASS
5873 && e->ts.type != BT_PROCEDURE
5874 && (gfc_expr_attr (e).flavor != FL_PROCEDURE
5875 || gfc_expr_attr (e).proc != PROC_UNKNOWN))
5877 /* The intrinsic type needs to be converted to a temporary
5878 CLASS object for the unlimited polymorphic formal. */
5879 gfc_find_vtab (&e->ts);
5880 gfc_init_se (&parmse, se);
5881 gfc_conv_intrinsic_to_class (&parmse, e, fsym->ts);
5884 else if (se->ss && se->ss->info->useflags)
5886 gfc_ss *ss;
5888 ss = se->ss;
5890 /* An elemental function inside a scalarized loop. */
5891 gfc_init_se (&parmse, se);
5892 parm_kind = ELEMENTAL;
5894 /* When no fsym is present, ulim_copy is set and this is a third or
5895 fourth argument, use call-by-value instead of by reference to
5896 hand the length properties to the copy routine (i.e., most of the
5897 time this will be a call to a __copy_character_* routine where the
5898 third and fourth arguments are the lengths of a deferred length
5899 char array). */
5900 if ((fsym && fsym->attr.value)
5901 || (ulim_copy && (argc == 2 || argc == 3)))
5902 gfc_conv_expr (&parmse, e);
5903 else
5904 gfc_conv_expr_reference (&parmse, e);
5906 if (e->ts.type == BT_CHARACTER && !e->rank
5907 && e->expr_type == EXPR_FUNCTION)
5908 parmse.expr = build_fold_indirect_ref_loc (input_location,
5909 parmse.expr);
5911 if (fsym && fsym->ts.type == BT_DERIVED
5912 && gfc_is_class_container_ref (e))
5914 parmse.expr = gfc_class_data_get (parmse.expr);
5916 if (fsym->attr.optional && e->expr_type == EXPR_VARIABLE
5917 && e->symtree->n.sym->attr.optional)
5919 tree cond = gfc_conv_expr_present (e->symtree->n.sym);
5920 parmse.expr = build3_loc (input_location, COND_EXPR,
5921 TREE_TYPE (parmse.expr),
5922 cond, parmse.expr,
5923 fold_convert (TREE_TYPE (parmse.expr),
5924 null_pointer_node));
5928 /* If we are passing an absent array as optional dummy to an
5929 elemental procedure, make sure that we pass NULL when the data
5930 pointer is NULL. We need this extra conditional because of
5931 scalarization which passes arrays elements to the procedure,
5932 ignoring the fact that the array can be absent/unallocated/... */
5933 if (ss->info->can_be_null_ref && ss->info->type != GFC_SS_REFERENCE)
5935 tree descriptor_data;
5937 descriptor_data = ss->info->data.array.data;
5938 tmp = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
5939 descriptor_data,
5940 fold_convert (TREE_TYPE (descriptor_data),
5941 null_pointer_node));
5942 parmse.expr
5943 = fold_build3_loc (input_location, COND_EXPR,
5944 TREE_TYPE (parmse.expr),
5945 gfc_unlikely (tmp, PRED_FORTRAN_ABSENT_DUMMY),
5946 fold_convert (TREE_TYPE (parmse.expr),
5947 null_pointer_node),
5948 parmse.expr);
5951 /* The scalarizer does not repackage the reference to a class
5952 array - instead it returns a pointer to the data element. */
5953 if (fsym && fsym->ts.type == BT_CLASS && e->ts.type == BT_CLASS)
5954 gfc_conv_class_to_class (&parmse, e, fsym->ts, true,
5955 fsym->attr.intent != INTENT_IN
5956 && (CLASS_DATA (fsym)->attr.class_pointer
5957 || CLASS_DATA (fsym)->attr.allocatable),
5958 fsym->attr.optional
5959 && e->expr_type == EXPR_VARIABLE
5960 && e->symtree->n.sym->attr.optional,
5961 CLASS_DATA (fsym)->attr.class_pointer
5962 || CLASS_DATA (fsym)->attr.allocatable);
5964 else
5966 bool scalar;
5967 gfc_ss *argss;
5969 gfc_init_se (&parmse, NULL);
5971 /* Check whether the expression is a scalar or not; we cannot use
5972 e->rank as it can be nonzero for functions arguments. */
5973 argss = gfc_walk_expr (e);
5974 scalar = argss == gfc_ss_terminator;
5975 if (!scalar)
5976 gfc_free_ss_chain (argss);
5978 /* Special handling for passing scalar polymorphic coarrays;
5979 otherwise one passes "class->_data.data" instead of "&class". */
5980 if (e->rank == 0 && e->ts.type == BT_CLASS
5981 && fsym && fsym->ts.type == BT_CLASS
5982 && CLASS_DATA (fsym)->attr.codimension
5983 && !CLASS_DATA (fsym)->attr.dimension)
5985 gfc_add_class_array_ref (e);
5986 parmse.want_coarray = 1;
5987 scalar = false;
5990 /* A scalar or transformational function. */
5991 if (scalar)
5993 if (e->expr_type == EXPR_VARIABLE
5994 && e->symtree->n.sym->attr.cray_pointee
5995 && fsym && fsym->attr.flavor == FL_PROCEDURE)
5997 /* The Cray pointer needs to be converted to a pointer to
5998 a type given by the expression. */
5999 gfc_conv_expr (&parmse, e);
6000 type = build_pointer_type (TREE_TYPE (parmse.expr));
6001 tmp = gfc_get_symbol_decl (e->symtree->n.sym->cp_pointer);
6002 parmse.expr = convert (type, tmp);
6005 else if (sym->attr.is_bind_c && e
6006 && (is_CFI_desc (fsym, NULL)
6007 || assumed_length_string))
6008 /* Implement F2018, 18.3.6, list item (5), bullet point 2. */
6009 gfc_conv_gfc_desc_to_cfi_desc (&parmse, e, fsym);
6011 else if (fsym && fsym->attr.value)
6013 if (fsym->ts.type == BT_CHARACTER
6014 && fsym->ts.is_c_interop
6015 && fsym->ns->proc_name != NULL
6016 && fsym->ns->proc_name->attr.is_bind_c)
6018 parmse.expr = NULL;
6019 gfc_conv_scalar_char_value (fsym, &parmse, &e);
6020 if (parmse.expr == NULL)
6021 gfc_conv_expr (&parmse, e);
6023 else
6025 gfc_conv_expr (&parmse, e);
6026 if (fsym->attr.optional
6027 && fsym->ts.type != BT_CLASS
6028 && fsym->ts.type != BT_DERIVED)
6030 if (e->expr_type != EXPR_VARIABLE
6031 || !e->symtree->n.sym->attr.optional
6032 || e->ref != NULL)
6033 vec_safe_push (optionalargs, boolean_true_node);
6034 else
6036 tmp = gfc_conv_expr_present (e->symtree->n.sym);
6037 if (!e->symtree->n.sym->attr.value)
6038 parmse.expr
6039 = fold_build3_loc (input_location, COND_EXPR,
6040 TREE_TYPE (parmse.expr),
6041 tmp, parmse.expr,
6042 fold_convert (TREE_TYPE (parmse.expr),
6043 integer_zero_node));
6045 vec_safe_push (optionalargs,
6046 fold_convert (boolean_type_node,
6047 tmp));
6053 else if (arg->name && arg->name[0] == '%')
6054 /* Argument list functions %VAL, %LOC and %REF are signalled
6055 through arg->name. */
6056 conv_arglist_function (&parmse, arg->expr, arg->name);
6057 else if ((e->expr_type == EXPR_FUNCTION)
6058 && ((e->value.function.esym
6059 && e->value.function.esym->result->attr.pointer)
6060 || (!e->value.function.esym
6061 && e->symtree->n.sym->attr.pointer))
6062 && fsym && fsym->attr.target)
6063 /* Make sure the function only gets called once. */
6064 gfc_conv_expr_reference (&parmse, e, false);
6065 else if (e->expr_type == EXPR_FUNCTION
6066 && e->symtree->n.sym->result
6067 && e->symtree->n.sym->result != e->symtree->n.sym
6068 && e->symtree->n.sym->result->attr.proc_pointer)
6070 /* Functions returning procedure pointers. */
6071 gfc_conv_expr (&parmse, e);
6072 if (fsym && fsym->attr.proc_pointer)
6073 parmse.expr = gfc_build_addr_expr (NULL_TREE, parmse.expr);
6076 else
6078 if (e->ts.type == BT_CLASS && fsym
6079 && fsym->ts.type == BT_CLASS
6080 && (!CLASS_DATA (fsym)->as
6081 || CLASS_DATA (fsym)->as->type != AS_ASSUMED_RANK)
6082 && CLASS_DATA (e)->attr.codimension)
6084 gcc_assert (!CLASS_DATA (fsym)->attr.codimension);
6085 gcc_assert (!CLASS_DATA (fsym)->as);
6086 gfc_add_class_array_ref (e);
6087 parmse.want_coarray = 1;
6088 gfc_conv_expr_reference (&parmse, e);
6089 class_scalar_coarray_to_class (&parmse, e, fsym->ts,
6090 fsym->attr.optional
6091 && e->expr_type == EXPR_VARIABLE);
6093 else if (e->ts.type == BT_CLASS && fsym
6094 && fsym->ts.type == BT_CLASS
6095 && !CLASS_DATA (fsym)->as
6096 && !CLASS_DATA (e)->as
6097 && strcmp (fsym->ts.u.derived->name,
6098 e->ts.u.derived->name))
6100 type = gfc_typenode_for_spec (&fsym->ts);
6101 var = gfc_create_var (type, fsym->name);
6102 gfc_conv_expr (&parmse, e);
6103 if (fsym->attr.optional
6104 && e->expr_type == EXPR_VARIABLE
6105 && e->symtree->n.sym->attr.optional)
6107 stmtblock_t block;
6108 tree cond;
6109 tmp = gfc_build_addr_expr (NULL_TREE, parmse.expr);
6110 cond = fold_build2_loc (input_location, NE_EXPR,
6111 logical_type_node, tmp,
6112 fold_convert (TREE_TYPE (tmp),
6113 null_pointer_node));
6114 gfc_start_block (&block);
6115 gfc_add_modify (&block, var,
6116 fold_build1_loc (input_location,
6117 VIEW_CONVERT_EXPR,
6118 type, parmse.expr));
6119 gfc_add_expr_to_block (&parmse.pre,
6120 fold_build3_loc (input_location,
6121 COND_EXPR, void_type_node,
6122 cond, gfc_finish_block (&block),
6123 build_empty_stmt (input_location)));
6124 parmse.expr = gfc_build_addr_expr (NULL_TREE, var);
6125 parmse.expr = build3_loc (input_location, COND_EXPR,
6126 TREE_TYPE (parmse.expr),
6127 cond, parmse.expr,
6128 fold_convert (TREE_TYPE (parmse.expr),
6129 null_pointer_node));
6131 else
6133 /* Since the internal representation of unlimited
6134 polymorphic expressions includes an extra field
6135 that other class objects do not, a cast to the
6136 formal type does not work. */
6137 if (!UNLIMITED_POLY (e) && UNLIMITED_POLY (fsym))
6139 tree efield;
6141 /* Set the _data field. */
6142 tmp = gfc_class_data_get (var);
6143 efield = fold_convert (TREE_TYPE (tmp),
6144 gfc_class_data_get (parmse.expr));
6145 gfc_add_modify (&parmse.pre, tmp, efield);
6147 /* Set the _vptr field. */
6148 tmp = gfc_class_vptr_get (var);
6149 efield = fold_convert (TREE_TYPE (tmp),
6150 gfc_class_vptr_get (parmse.expr));
6151 gfc_add_modify (&parmse.pre, tmp, efield);
6153 /* Set the _len field. */
6154 tmp = gfc_class_len_get (var);
6155 gfc_add_modify (&parmse.pre, tmp,
6156 build_int_cst (TREE_TYPE (tmp), 0));
6158 else
6160 tmp = fold_build1_loc (input_location,
6161 VIEW_CONVERT_EXPR,
6162 type, parmse.expr);
6163 gfc_add_modify (&parmse.pre, var, tmp);
6166 parmse.expr = gfc_build_addr_expr (NULL_TREE, var);
6169 else
6171 bool add_clobber;
6172 add_clobber = fsym && fsym->attr.intent == INTENT_OUT
6173 && !fsym->attr.allocatable && !fsym->attr.pointer
6174 && e->symtree && e->symtree->n.sym
6175 && !e->symtree->n.sym->attr.dimension
6176 && !e->symtree->n.sym->attr.pointer
6177 && !e->symtree->n.sym->attr.allocatable
6178 /* See PR 41453. */
6179 && !e->symtree->n.sym->attr.dummy
6180 /* FIXME - PR 87395 and PR 41453 */
6181 && e->symtree->n.sym->attr.save == SAVE_NONE
6182 && !e->symtree->n.sym->attr.associate_var
6183 && e->ts.type != BT_CHARACTER && e->ts.type != BT_DERIVED
6184 && e->ts.type != BT_CLASS && !sym->attr.elemental;
6186 gfc_conv_expr_reference (&parmse, e, add_clobber);
6188 /* Catch base objects that are not variables. */
6189 if (e->ts.type == BT_CLASS
6190 && e->expr_type != EXPR_VARIABLE
6191 && expr && e == expr->base_expr)
6192 base_object = build_fold_indirect_ref_loc (input_location,
6193 parmse.expr);
6195 /* A class array element needs converting back to be a
6196 class object, if the formal argument is a class object. */
6197 if (fsym && fsym->ts.type == BT_CLASS
6198 && e->ts.type == BT_CLASS
6199 && ((CLASS_DATA (fsym)->as
6200 && CLASS_DATA (fsym)->as->type == AS_ASSUMED_RANK)
6201 || CLASS_DATA (e)->attr.dimension))
6202 gfc_conv_class_to_class (&parmse, e, fsym->ts, false,
6203 fsym->attr.intent != INTENT_IN
6204 && (CLASS_DATA (fsym)->attr.class_pointer
6205 || CLASS_DATA (fsym)->attr.allocatable),
6206 fsym->attr.optional
6207 && e->expr_type == EXPR_VARIABLE
6208 && e->symtree->n.sym->attr.optional,
6209 CLASS_DATA (fsym)->attr.class_pointer
6210 || CLASS_DATA (fsym)->attr.allocatable);
6212 /* If an ALLOCATABLE dummy argument has INTENT(OUT) and is
6213 allocated on entry, it must be deallocated. */
6214 if (fsym && fsym->attr.intent == INTENT_OUT
6215 && (fsym->attr.allocatable
6216 || (fsym->ts.type == BT_CLASS
6217 && CLASS_DATA (fsym)->attr.allocatable)))
6219 stmtblock_t block;
6220 tree ptr;
6222 gfc_init_block (&block);
6223 ptr = parmse.expr;
6224 if (e->ts.type == BT_CLASS)
6225 ptr = gfc_class_data_get (ptr);
6227 tmp = gfc_deallocate_scalar_with_status (ptr, NULL_TREE,
6228 NULL_TREE, true,
6229 e, e->ts);
6230 gfc_add_expr_to_block (&block, tmp);
6231 tmp = fold_build2_loc (input_location, MODIFY_EXPR,
6232 void_type_node, ptr,
6233 null_pointer_node);
6234 gfc_add_expr_to_block (&block, tmp);
6236 if (fsym->ts.type == BT_CLASS && UNLIMITED_POLY (fsym))
6238 gfc_add_modify (&block, ptr,
6239 fold_convert (TREE_TYPE (ptr),
6240 null_pointer_node));
6241 gfc_add_expr_to_block (&block, tmp);
6243 else if (fsym->ts.type == BT_CLASS)
6245 gfc_symbol *vtab;
6246 vtab = gfc_find_derived_vtab (fsym->ts.u.derived);
6247 tmp = gfc_get_symbol_decl (vtab);
6248 tmp = gfc_build_addr_expr (NULL_TREE, tmp);
6249 ptr = gfc_class_vptr_get (parmse.expr);
6250 gfc_add_modify (&block, ptr,
6251 fold_convert (TREE_TYPE (ptr), tmp));
6252 gfc_add_expr_to_block (&block, tmp);
6255 if (fsym->attr.optional
6256 && e->expr_type == EXPR_VARIABLE
6257 && e->symtree->n.sym->attr.optional)
6259 tmp = fold_build3_loc (input_location, COND_EXPR,
6260 void_type_node,
6261 gfc_conv_expr_present (e->symtree->n.sym),
6262 gfc_finish_block (&block),
6263 build_empty_stmt (input_location));
6265 else
6266 tmp = gfc_finish_block (&block);
6268 gfc_add_expr_to_block (&se->pre, tmp);
6271 if (fsym && (fsym->ts.type == BT_DERIVED
6272 || fsym->ts.type == BT_ASSUMED)
6273 && e->ts.type == BT_CLASS
6274 && !CLASS_DATA (e)->attr.dimension
6275 && !CLASS_DATA (e)->attr.codimension)
6277 parmse.expr = gfc_class_data_get (parmse.expr);
6278 /* The result is a class temporary, whose _data component
6279 must be freed to avoid a memory leak. */
6280 if (e->expr_type == EXPR_FUNCTION
6281 && CLASS_DATA (e)->attr.allocatable)
6283 tree zero;
6285 gfc_expr *var;
6287 /* Borrow the function symbol to make a call to
6288 gfc_add_finalizer_call and then restore it. */
6289 tmp = e->symtree->n.sym->backend_decl;
6290 e->symtree->n.sym->backend_decl
6291 = TREE_OPERAND (parmse.expr, 0);
6292 e->symtree->n.sym->attr.flavor = FL_VARIABLE;
6293 var = gfc_lval_expr_from_sym (e->symtree->n.sym);
6294 finalized = gfc_add_finalizer_call (&parmse.post,
6295 var);
6296 gfc_free_expr (var);
6297 e->symtree->n.sym->backend_decl = tmp;
6298 e->symtree->n.sym->attr.flavor = FL_PROCEDURE;
6300 /* Then free the class _data. */
6301 zero = build_int_cst (TREE_TYPE (parmse.expr), 0);
6302 tmp = fold_build2_loc (input_location, NE_EXPR,
6303 logical_type_node,
6304 parmse.expr, zero);
6305 tmp = build3_v (COND_EXPR, tmp,
6306 gfc_call_free (parmse.expr),
6307 build_empty_stmt (input_location));
6308 gfc_add_expr_to_block (&parmse.post, tmp);
6309 gfc_add_modify (&parmse.post, parmse.expr, zero);
6313 /* Wrap scalar variable in a descriptor. We need to convert
6314 the address of a pointer back to the pointer itself before,
6315 we can assign it to the data field. */
6317 if (fsym && fsym->as && fsym->as->type == AS_ASSUMED_RANK
6318 && fsym->ts.type != BT_CLASS && e->expr_type != EXPR_NULL)
6320 tmp = parmse.expr;
6321 if (TREE_CODE (tmp) == ADDR_EXPR)
6322 tmp = build_fold_indirect_ref_loc (input_location, tmp);
6323 parmse.expr = gfc_conv_scalar_to_descriptor (&parmse, tmp,
6324 fsym->attr);
6325 parmse.expr = gfc_build_addr_expr (NULL_TREE,
6326 parmse.expr);
6328 else if (fsym && e->expr_type != EXPR_NULL
6329 && ((fsym->attr.pointer
6330 && fsym->attr.flavor != FL_PROCEDURE)
6331 || (fsym->attr.proc_pointer
6332 && !(e->expr_type == EXPR_VARIABLE
6333 && e->symtree->n.sym->attr.dummy))
6334 || (fsym->attr.proc_pointer
6335 && e->expr_type == EXPR_VARIABLE
6336 && gfc_is_proc_ptr_comp (e))
6337 || (fsym->attr.allocatable
6338 && fsym->attr.flavor != FL_PROCEDURE)))
6340 /* Scalar pointer dummy args require an extra level of
6341 indirection. The null pointer already contains
6342 this level of indirection. */
6343 parm_kind = SCALAR_POINTER;
6344 parmse.expr = gfc_build_addr_expr (NULL_TREE, parmse.expr);
6348 else if (e->ts.type == BT_CLASS
6349 && fsym && fsym->ts.type == BT_CLASS
6350 && (CLASS_DATA (fsym)->attr.dimension
6351 || CLASS_DATA (fsym)->attr.codimension))
6353 /* Pass a class array. */
6354 parmse.use_offset = 1;
6355 gfc_conv_expr_descriptor (&parmse, e);
6357 /* If an ALLOCATABLE dummy argument has INTENT(OUT) and is
6358 allocated on entry, it must be deallocated. */
6359 if (fsym->attr.intent == INTENT_OUT
6360 && CLASS_DATA (fsym)->attr.allocatable)
6362 stmtblock_t block;
6363 tree ptr;
6365 gfc_init_block (&block);
6366 ptr = parmse.expr;
6367 ptr = gfc_class_data_get (ptr);
6369 tmp = gfc_deallocate_with_status (ptr, NULL_TREE,
6370 NULL_TREE, NULL_TREE,
6371 NULL_TREE, true, e,
6372 GFC_CAF_COARRAY_NOCOARRAY);
6373 gfc_add_expr_to_block (&block, tmp);
6374 tmp = fold_build2_loc (input_location, MODIFY_EXPR,
6375 void_type_node, ptr,
6376 null_pointer_node);
6377 gfc_add_expr_to_block (&block, tmp);
6378 gfc_reset_vptr (&block, e);
6380 if (fsym->attr.optional
6381 && e->expr_type == EXPR_VARIABLE
6382 && (!e->ref
6383 || (e->ref->type == REF_ARRAY
6384 && e->ref->u.ar.type != AR_FULL))
6385 && e->symtree->n.sym->attr.optional)
6387 tmp = fold_build3_loc (input_location, COND_EXPR,
6388 void_type_node,
6389 gfc_conv_expr_present (e->symtree->n.sym),
6390 gfc_finish_block (&block),
6391 build_empty_stmt (input_location));
6393 else
6394 tmp = gfc_finish_block (&block);
6396 gfc_add_expr_to_block (&se->pre, tmp);
6399 /* The conversion does not repackage the reference to a class
6400 array - _data descriptor. */
6401 gfc_conv_class_to_class (&parmse, e, fsym->ts, false,
6402 fsym->attr.intent != INTENT_IN
6403 && (CLASS_DATA (fsym)->attr.class_pointer
6404 || CLASS_DATA (fsym)->attr.allocatable),
6405 fsym->attr.optional
6406 && e->expr_type == EXPR_VARIABLE
6407 && e->symtree->n.sym->attr.optional,
6408 CLASS_DATA (fsym)->attr.class_pointer
6409 || CLASS_DATA (fsym)->attr.allocatable);
6411 else
6413 /* If the argument is a function call that may not create
6414 a temporary for the result, we have to check that we
6415 can do it, i.e. that there is no alias between this
6416 argument and another one. */
6417 if (gfc_get_noncopying_intrinsic_argument (e) != NULL)
6419 gfc_expr *iarg;
6420 sym_intent intent;
6422 if (fsym != NULL)
6423 intent = fsym->attr.intent;
6424 else
6425 intent = INTENT_UNKNOWN;
6427 if (gfc_check_fncall_dependency (e, intent, sym, args,
6428 NOT_ELEMENTAL))
6429 parmse.force_tmp = 1;
6431 iarg = e->value.function.actual->expr;
6433 /* Temporary needed if aliasing due to host association. */
6434 if (sym->attr.contained
6435 && !sym->attr.pure
6436 && !sym->attr.implicit_pure
6437 && !sym->attr.use_assoc
6438 && iarg->expr_type == EXPR_VARIABLE
6439 && sym->ns == iarg->symtree->n.sym->ns)
6440 parmse.force_tmp = 1;
6442 /* Ditto within module. */
6443 if (sym->attr.use_assoc
6444 && !sym->attr.pure
6445 && !sym->attr.implicit_pure
6446 && iarg->expr_type == EXPR_VARIABLE
6447 && sym->module == iarg->symtree->n.sym->module)
6448 parmse.force_tmp = 1;
6451 if (sym->attr.is_bind_c && e
6452 && (is_CFI_desc (fsym, NULL) || assumed_length_string))
6453 /* Implement F2018, 18.3.6, list item (5), bullet point 2. */
6454 gfc_conv_gfc_desc_to_cfi_desc (&parmse, e, fsym);
6456 else if (e->expr_type == EXPR_VARIABLE
6457 && is_subref_array (e)
6458 && !(fsym && fsym->attr.pointer))
6459 /* The actual argument is a component reference to an
6460 array of derived types. In this case, the argument
6461 is converted to a temporary, which is passed and then
6462 written back after the procedure call. */
6463 gfc_conv_subref_array_arg (&parmse, e, nodesc_arg,
6464 fsym ? fsym->attr.intent : INTENT_INOUT,
6465 fsym && fsym->attr.pointer);
6467 else if (e->ts.type == BT_CLASS && CLASS_DATA (e)->as
6468 && CLASS_DATA (e)->as->type == AS_ASSUMED_SIZE
6469 && nodesc_arg && fsym->ts.type == BT_DERIVED)
6470 /* An assumed size class actual argument being passed to
6471 a 'no descriptor' formal argument just requires the
6472 data pointer to be passed. For class dummy arguments
6473 this is stored in the symbol backend decl.. */
6474 parmse.expr = e->symtree->n.sym->backend_decl;
6476 else if (gfc_is_class_array_ref (e, NULL)
6477 && fsym && fsym->ts.type == BT_DERIVED)
6478 /* The actual argument is a component reference to an
6479 array of derived types. In this case, the argument
6480 is converted to a temporary, which is passed and then
6481 written back after the procedure call.
6482 OOP-TODO: Insert code so that if the dynamic type is
6483 the same as the declared type, copy-in/copy-out does
6484 not occur. */
6485 gfc_conv_subref_array_arg (&parmse, e, nodesc_arg,
6486 fsym->attr.intent,
6487 fsym->attr.pointer);
6489 else if (gfc_is_class_array_function (e)
6490 && fsym && fsym->ts.type == BT_DERIVED)
6491 /* See previous comment. For function actual argument,
6492 the write out is not needed so the intent is set as
6493 intent in. */
6495 e->must_finalize = 1;
6496 gfc_conv_subref_array_arg (&parmse, e, nodesc_arg,
6497 INTENT_IN, fsym->attr.pointer);
6499 else if (fsym && fsym->attr.contiguous
6500 && !gfc_is_simply_contiguous (e, false, true)
6501 && gfc_expr_is_variable (e))
6503 gfc_conv_subref_array_arg (&parmse, e, nodesc_arg,
6504 fsym->attr.intent,
6505 fsym->attr.pointer);
6507 else
6508 gfc_conv_array_parameter (&parmse, e, nodesc_arg, fsym,
6509 sym->name, NULL);
6511 /* Unallocated allocatable arrays and unassociated pointer arrays
6512 need their dtype setting if they are argument associated with
6513 assumed rank dummies, unless already assumed rank. */
6514 if (!sym->attr.is_bind_c && e && fsym && fsym->as
6515 && fsym->as->type == AS_ASSUMED_RANK
6516 && e->rank != -1)
6518 if (gfc_expr_attr (e).pointer
6519 || gfc_expr_attr (e).allocatable)
6520 set_dtype_for_unallocated (&parmse, e);
6521 else if (e->expr_type == EXPR_VARIABLE
6522 && e->ref
6523 && e->ref->u.ar.type == AR_FULL
6524 && e->symtree->n.sym->attr.dummy
6525 && e->symtree->n.sym->as
6526 && e->symtree->n.sym->as->type == AS_ASSUMED_SIZE)
6528 tree minus_one;
6529 tmp = build_fold_indirect_ref_loc (input_location,
6530 parmse.expr);
6531 minus_one = build_int_cst (gfc_array_index_type, -1);
6532 gfc_conv_descriptor_ubound_set (&parmse.pre, tmp,
6533 gfc_rank_cst[e->rank - 1],
6534 minus_one);
6538 /* If an ALLOCATABLE dummy argument has INTENT(OUT) and is
6539 allocated on entry, it must be deallocated. */
6540 if (fsym && fsym->attr.allocatable
6541 && fsym->attr.intent == INTENT_OUT)
6543 if (fsym->ts.type == BT_DERIVED
6544 && fsym->ts.u.derived->attr.alloc_comp)
6546 // deallocate the components first
6547 tmp = gfc_deallocate_alloc_comp (fsym->ts.u.derived,
6548 parmse.expr, e->rank);
6549 if (tmp != NULL_TREE)
6550 gfc_add_expr_to_block (&se->pre, tmp);
6553 tmp = parmse.expr;
6554 /* With bind(C), the actual argument is replaced by a bind-C
6555 descriptor; in this case, the data component arrives here,
6556 which shall not be dereferenced, but still freed and
6557 nullified. */
6558 if (TREE_TYPE(tmp) != pvoid_type_node)
6559 tmp = build_fold_indirect_ref_loc (input_location,
6560 parmse.expr);
6561 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp)))
6562 tmp = gfc_conv_descriptor_data_get (tmp);
6563 tmp = gfc_deallocate_with_status (tmp, NULL_TREE, NULL_TREE,
6564 NULL_TREE, NULL_TREE, true,
6566 GFC_CAF_COARRAY_NOCOARRAY);
6567 if (fsym->attr.optional
6568 && e->expr_type == EXPR_VARIABLE
6569 && e->symtree->n.sym->attr.optional)
6570 tmp = fold_build3_loc (input_location, COND_EXPR,
6571 void_type_node,
6572 gfc_conv_expr_present (e->symtree->n.sym),
6573 tmp, build_empty_stmt (input_location));
6574 gfc_add_expr_to_block (&se->pre, tmp);
6579 /* The case with fsym->attr.optional is that of a user subroutine
6580 with an interface indicating an optional argument. When we call
6581 an intrinsic subroutine, however, fsym is NULL, but we might still
6582 have an optional argument, so we proceed to the substitution
6583 just in case. */
6584 if (e && (fsym == NULL || fsym->attr.optional))
6586 /* If an optional argument is itself an optional dummy argument,
6587 check its presence and substitute a null if absent. This is
6588 only needed when passing an array to an elemental procedure
6589 as then array elements are accessed - or no NULL pointer is
6590 allowed and a "1" or "0" should be passed if not present.
6591 When passing a non-array-descriptor full array to a
6592 non-array-descriptor dummy, no check is needed. For
6593 array-descriptor actual to array-descriptor dummy, see
6594 PR 41911 for why a check has to be inserted.
6595 fsym == NULL is checked as intrinsics required the descriptor
6596 but do not always set fsym.
6597 Also, it is necessary to pass a NULL pointer to library routines
6598 which usually ignore optional arguments, so they can handle
6599 these themselves. */
6600 if (e->expr_type == EXPR_VARIABLE
6601 && e->symtree->n.sym->attr.optional
6602 && (((e->rank != 0 && elemental_proc)
6603 || e->representation.length || e->ts.type == BT_CHARACTER
6604 || (e->rank != 0
6605 && (fsym == NULL
6606 || (fsym->as
6607 && (fsym->as->type == AS_ASSUMED_SHAPE
6608 || fsym->as->type == AS_ASSUMED_RANK
6609 || fsym->as->type == AS_DEFERRED)))))
6610 || se->ignore_optional))
6611 gfc_conv_missing_dummy (&parmse, e, fsym ? fsym->ts : e->ts,
6612 e->representation.length);
6615 if (fsym && e)
6617 /* Obtain the character length of an assumed character length
6618 length procedure from the typespec. */
6619 if (fsym->ts.type == BT_CHARACTER
6620 && parmse.string_length == NULL_TREE
6621 && e->ts.type == BT_PROCEDURE
6622 && e->symtree->n.sym->ts.type == BT_CHARACTER
6623 && e->symtree->n.sym->ts.u.cl->length != NULL
6624 && e->symtree->n.sym->ts.u.cl->length->expr_type == EXPR_CONSTANT)
6626 gfc_conv_const_charlen (e->symtree->n.sym->ts.u.cl);
6627 parmse.string_length = e->symtree->n.sym->ts.u.cl->backend_decl;
6631 if (fsym && need_interface_mapping && e)
6632 gfc_add_interface_mapping (&mapping, fsym, &parmse, e);
6634 gfc_add_block_to_block (&se->pre, &parmse.pre);
6635 gfc_add_block_to_block (&post, &parmse.post);
6637 /* Allocated allocatable components of derived types must be
6638 deallocated for non-variable scalars, array arguments to elemental
6639 procedures, and array arguments with descriptor to non-elemental
6640 procedures. As bounds information for descriptorless arrays is no
6641 longer available here, they are dealt with in trans-array.c
6642 (gfc_conv_array_parameter). */
6643 if (e && (e->ts.type == BT_DERIVED || e->ts.type == BT_CLASS)
6644 && e->ts.u.derived->attr.alloc_comp
6645 && (e->rank == 0 || elemental_proc || !nodesc_arg)
6646 && !expr_may_alias_variables (e, elemental_proc))
6648 int parm_rank;
6649 /* It is known the e returns a structure type with at least one
6650 allocatable component. When e is a function, ensure that the
6651 function is called once only by using a temporary variable. */
6652 if (!DECL_P (parmse.expr))
6653 parmse.expr = gfc_evaluate_now_loc (input_location,
6654 parmse.expr, &se->pre);
6656 if (fsym && fsym->attr.value)
6657 tmp = parmse.expr;
6658 else
6659 tmp = build_fold_indirect_ref_loc (input_location,
6660 parmse.expr);
6662 parm_rank = e->rank;
6663 switch (parm_kind)
6665 case (ELEMENTAL):
6666 case (SCALAR):
6667 parm_rank = 0;
6668 break;
6670 case (SCALAR_POINTER):
6671 tmp = build_fold_indirect_ref_loc (input_location,
6672 tmp);
6673 break;
6676 if (e->ts.type == BT_DERIVED && fsym && fsym->ts.type == BT_CLASS)
6678 /* The derived type is passed to gfc_deallocate_alloc_comp.
6679 Therefore, class actuals can be handled correctly but derived
6680 types passed to class formals need the _data component. */
6681 tmp = gfc_class_data_get (tmp);
6682 if (!CLASS_DATA (fsym)->attr.dimension)
6683 tmp = build_fold_indirect_ref_loc (input_location, tmp);
6686 if (e->expr_type == EXPR_OP
6687 && e->value.op.op == INTRINSIC_PARENTHESES
6688 && e->value.op.op1->expr_type == EXPR_VARIABLE)
6690 tree local_tmp;
6691 local_tmp = gfc_evaluate_now (tmp, &se->pre);
6692 local_tmp = gfc_copy_alloc_comp (e->ts.u.derived, local_tmp, tmp,
6693 parm_rank, 0);
6694 gfc_add_expr_to_block (&se->post, local_tmp);
6697 if (!finalized && !e->must_finalize)
6699 bool scalar_res_outside_loop;
6700 scalar_res_outside_loop = e->expr_type == EXPR_FUNCTION
6701 && parm_rank == 0
6702 && parmse.loop;
6704 /* Scalars passed to an assumed rank argument are converted to
6705 a descriptor. Obtain the data field before deallocating any
6706 allocatable components. */
6707 if (parm_rank == 0 && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp)))
6708 tmp = gfc_conv_descriptor_data_get (tmp);
6710 if (scalar_res_outside_loop)
6712 /* Go through the ss chain to find the argument and use
6713 the stored value. */
6714 gfc_ss *tmp_ss = parmse.loop->ss;
6715 for (; tmp_ss; tmp_ss = tmp_ss->next)
6716 if (tmp_ss->info
6717 && tmp_ss->info->expr == e
6718 && tmp_ss->info->data.scalar.value != NULL_TREE)
6720 tmp = tmp_ss->info->data.scalar.value;
6721 break;
6725 STRIP_NOPS (tmp);
6727 if (derived_array != NULL_TREE)
6728 tmp = gfc_deallocate_alloc_comp (e->ts.u.derived,
6729 derived_array,
6730 parm_rank);
6731 else if ((e->ts.type == BT_CLASS
6732 && GFC_CLASS_TYPE_P (TREE_TYPE (tmp)))
6733 || e->ts.type == BT_DERIVED)
6734 tmp = gfc_deallocate_alloc_comp (e->ts.u.derived, tmp,
6735 parm_rank);
6736 else if (e->ts.type == BT_CLASS)
6737 tmp = gfc_deallocate_alloc_comp (CLASS_DATA (e)->ts.u.derived,
6738 tmp, parm_rank);
6740 if (scalar_res_outside_loop)
6741 gfc_add_expr_to_block (&parmse.loop->post, tmp);
6742 else
6743 gfc_prepend_expr_to_block (&post, tmp);
6747 /* Add argument checking of passing an unallocated/NULL actual to
6748 a nonallocatable/nonpointer dummy. */
6750 if (gfc_option.rtcheck & GFC_RTCHECK_POINTER && e != NULL)
6752 symbol_attribute attr;
6753 char *msg;
6754 tree cond;
6755 tree tmp;
6756 symbol_attribute fsym_attr;
6758 if (fsym)
6760 if (fsym->ts.type == BT_CLASS)
6762 fsym_attr = CLASS_DATA (fsym)->attr;
6763 fsym_attr.pointer = fsym_attr.class_pointer;
6765 else
6766 fsym_attr = fsym->attr;
6769 if (e->expr_type == EXPR_VARIABLE || e->expr_type == EXPR_FUNCTION)
6770 attr = gfc_expr_attr (e);
6771 else
6772 goto end_pointer_check;
6774 /* In Fortran 2008 it's allowed to pass a NULL pointer/nonallocated
6775 allocatable to an optional dummy, cf. 12.5.2.12. */
6776 if (fsym != NULL && fsym->attr.optional && !attr.proc_pointer
6777 && (gfc_option.allow_std & GFC_STD_F2008) != 0)
6778 goto end_pointer_check;
6780 if (attr.optional)
6782 /* If the actual argument is an optional pointer/allocatable and
6783 the formal argument takes an nonpointer optional value,
6784 it is invalid to pass a non-present argument on, even
6785 though there is no technical reason for this in gfortran.
6786 See Fortran 2003, Section 12.4.1.6 item (7)+(8). */
6787 tree present, null_ptr, type;
6789 if (attr.allocatable
6790 && (fsym == NULL || !fsym_attr.allocatable))
6791 msg = xasprintf ("Allocatable actual argument '%s' is not "
6792 "allocated or not present",
6793 e->symtree->n.sym->name);
6794 else if (attr.pointer
6795 && (fsym == NULL || !fsym_attr.pointer))
6796 msg = xasprintf ("Pointer actual argument '%s' is not "
6797 "associated or not present",
6798 e->symtree->n.sym->name);
6799 else if (attr.proc_pointer && !e->value.function.actual
6800 && (fsym == NULL || !fsym_attr.proc_pointer))
6801 msg = xasprintf ("Proc-pointer actual argument '%s' is not "
6802 "associated or not present",
6803 e->symtree->n.sym->name);
6804 else
6805 goto end_pointer_check;
6807 present = gfc_conv_expr_present (e->symtree->n.sym);
6808 type = TREE_TYPE (present);
6809 present = fold_build2_loc (input_location, EQ_EXPR,
6810 logical_type_node, present,
6811 fold_convert (type,
6812 null_pointer_node));
6813 type = TREE_TYPE (parmse.expr);
6814 null_ptr = fold_build2_loc (input_location, EQ_EXPR,
6815 logical_type_node, parmse.expr,
6816 fold_convert (type,
6817 null_pointer_node));
6818 cond = fold_build2_loc (input_location, TRUTH_ORIF_EXPR,
6819 logical_type_node, present, null_ptr);
6821 else
6823 if (attr.allocatable
6824 && (fsym == NULL || !fsym_attr.allocatable))
6825 msg = xasprintf ("Allocatable actual argument '%s' is not "
6826 "allocated", e->symtree->n.sym->name);
6827 else if (attr.pointer
6828 && (fsym == NULL || !fsym_attr.pointer))
6829 msg = xasprintf ("Pointer actual argument '%s' is not "
6830 "associated", e->symtree->n.sym->name);
6831 else if (attr.proc_pointer && !e->value.function.actual
6832 && (fsym == NULL || !fsym_attr.proc_pointer))
6833 msg = xasprintf ("Proc-pointer actual argument '%s' is not "
6834 "associated", e->symtree->n.sym->name);
6835 else
6836 goto end_pointer_check;
6838 if (fsym && fsym->ts.type == BT_CLASS)
6840 tmp = build_fold_indirect_ref_loc (input_location,
6841 parmse.expr);
6842 tmp = gfc_class_data_get (tmp);
6843 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp)))
6844 tmp = gfc_conv_descriptor_data_get (tmp);
6846 else
6847 tmp = parmse.expr;
6849 /* If the argument is passed by value, we need to strip the
6850 INDIRECT_REF. */
6851 if (!POINTER_TYPE_P (TREE_TYPE (tmp)))
6852 tmp = gfc_build_addr_expr (NULL_TREE, tmp);
6854 cond = fold_build2_loc (input_location, EQ_EXPR,
6855 logical_type_node, tmp,
6856 fold_convert (TREE_TYPE (tmp),
6857 null_pointer_node));
6860 gfc_trans_runtime_check (true, false, cond, &se->pre, &e->where,
6861 msg);
6862 free (msg);
6864 end_pointer_check:
6866 /* Deferred length dummies pass the character length by reference
6867 so that the value can be returned. */
6868 if (parmse.string_length && fsym && fsym->ts.deferred)
6870 if (INDIRECT_REF_P (parmse.string_length))
6871 /* In chains of functions/procedure calls the string_length already
6872 is a pointer to the variable holding the length. Therefore
6873 remove the deref on call. */
6874 parmse.string_length = TREE_OPERAND (parmse.string_length, 0);
6875 else
6877 tmp = parmse.string_length;
6878 if (!VAR_P (tmp) && TREE_CODE (tmp) != COMPONENT_REF)
6879 tmp = gfc_evaluate_now (parmse.string_length, &se->pre);
6880 parmse.string_length = gfc_build_addr_expr (NULL_TREE, tmp);
6884 /* Character strings are passed as two parameters, a length and a
6885 pointer - except for Bind(c) which only passes the pointer.
6886 An unlimited polymorphic formal argument likewise does not
6887 need the length. */
6888 if (parmse.string_length != NULL_TREE
6889 && !sym->attr.is_bind_c
6890 && !(fsym && UNLIMITED_POLY (fsym)))
6891 vec_safe_push (stringargs, parmse.string_length);
6893 /* When calling __copy for character expressions to unlimited
6894 polymorphic entities, the dst argument needs a string length. */
6895 if (sym->name[0] == '_' && e && e->ts.type == BT_CHARACTER
6896 && startswith (sym->name, "__vtab_CHARACTER")
6897 && arg->next && arg->next->expr
6898 && (arg->next->expr->ts.type == BT_DERIVED
6899 || arg->next->expr->ts.type == BT_CLASS)
6900 && arg->next->expr->ts.u.derived->attr.unlimited_polymorphic)
6901 vec_safe_push (stringargs, parmse.string_length);
6903 /* For descriptorless coarrays and assumed-shape coarray dummies, we
6904 pass the token and the offset as additional arguments. */
6905 if (fsym && e == NULL && flag_coarray == GFC_FCOARRAY_LIB
6906 && ((fsym->ts.type != BT_CLASS && fsym->attr.codimension
6907 && !fsym->attr.allocatable)
6908 || (fsym->ts.type == BT_CLASS
6909 && CLASS_DATA (fsym)->attr.codimension
6910 && !CLASS_DATA (fsym)->attr.allocatable)))
6912 /* Token and offset. */
6913 vec_safe_push (stringargs, null_pointer_node);
6914 vec_safe_push (stringargs, build_int_cst (gfc_array_index_type, 0));
6915 gcc_assert (fsym->attr.optional);
6917 else if (fsym && flag_coarray == GFC_FCOARRAY_LIB
6918 && ((fsym->ts.type != BT_CLASS && fsym->attr.codimension
6919 && !fsym->attr.allocatable)
6920 || (fsym->ts.type == BT_CLASS
6921 && CLASS_DATA (fsym)->attr.codimension
6922 && !CLASS_DATA (fsym)->attr.allocatable)))
6924 tree caf_decl, caf_type;
6925 tree offset, tmp2;
6927 caf_decl = gfc_get_tree_for_caf_expr (e);
6928 caf_type = TREE_TYPE (caf_decl);
6930 if (GFC_DESCRIPTOR_TYPE_P (caf_type)
6931 && (GFC_TYPE_ARRAY_AKIND (caf_type) == GFC_ARRAY_ALLOCATABLE
6932 || GFC_TYPE_ARRAY_AKIND (caf_type) == GFC_ARRAY_POINTER))
6933 tmp = gfc_conv_descriptor_token (caf_decl);
6934 else if (DECL_LANG_SPECIFIC (caf_decl)
6935 && GFC_DECL_TOKEN (caf_decl) != NULL_TREE)
6936 tmp = GFC_DECL_TOKEN (caf_decl);
6937 else
6939 gcc_assert (GFC_ARRAY_TYPE_P (caf_type)
6940 && GFC_TYPE_ARRAY_CAF_TOKEN (caf_type) != NULL_TREE);
6941 tmp = GFC_TYPE_ARRAY_CAF_TOKEN (caf_type);
6944 vec_safe_push (stringargs, tmp);
6946 if (GFC_DESCRIPTOR_TYPE_P (caf_type)
6947 && GFC_TYPE_ARRAY_AKIND (caf_type) == GFC_ARRAY_ALLOCATABLE)
6948 offset = build_int_cst (gfc_array_index_type, 0);
6949 else if (DECL_LANG_SPECIFIC (caf_decl)
6950 && GFC_DECL_CAF_OFFSET (caf_decl) != NULL_TREE)
6951 offset = GFC_DECL_CAF_OFFSET (caf_decl);
6952 else if (GFC_TYPE_ARRAY_CAF_OFFSET (caf_type) != NULL_TREE)
6953 offset = GFC_TYPE_ARRAY_CAF_OFFSET (caf_type);
6954 else
6955 offset = build_int_cst (gfc_array_index_type, 0);
6957 if (GFC_DESCRIPTOR_TYPE_P (caf_type))
6958 tmp = gfc_conv_descriptor_data_get (caf_decl);
6959 else
6961 gcc_assert (POINTER_TYPE_P (caf_type));
6962 tmp = caf_decl;
6965 tmp2 = fsym->ts.type == BT_CLASS
6966 ? gfc_class_data_get (parmse.expr) : parmse.expr;
6967 if ((fsym->ts.type != BT_CLASS
6968 && (fsym->as->type == AS_ASSUMED_SHAPE
6969 || fsym->as->type == AS_ASSUMED_RANK))
6970 || (fsym->ts.type == BT_CLASS
6971 && (CLASS_DATA (fsym)->as->type == AS_ASSUMED_SHAPE
6972 || CLASS_DATA (fsym)->as->type == AS_ASSUMED_RANK)))
6974 if (fsym->ts.type == BT_CLASS)
6975 gcc_assert (!POINTER_TYPE_P (TREE_TYPE (tmp2)));
6976 else
6978 gcc_assert (POINTER_TYPE_P (TREE_TYPE (tmp2)));
6979 tmp2 = build_fold_indirect_ref_loc (input_location, tmp2);
6981 gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp2)));
6982 tmp2 = gfc_conv_descriptor_data_get (tmp2);
6984 else if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp2)))
6985 tmp2 = gfc_conv_descriptor_data_get (tmp2);
6986 else
6988 gcc_assert (POINTER_TYPE_P (TREE_TYPE (tmp2)));
6991 tmp = fold_build2_loc (input_location, MINUS_EXPR,
6992 gfc_array_index_type,
6993 fold_convert (gfc_array_index_type, tmp2),
6994 fold_convert (gfc_array_index_type, tmp));
6995 offset = fold_build2_loc (input_location, PLUS_EXPR,
6996 gfc_array_index_type, offset, tmp);
6998 vec_safe_push (stringargs, offset);
7001 vec_safe_push (arglist, parmse.expr);
7003 gfc_finish_interface_mapping (&mapping, &se->pre, &se->post);
7005 if (comp)
7006 ts = comp->ts;
7007 else if (sym->ts.type == BT_CLASS)
7008 ts = CLASS_DATA (sym)->ts;
7009 else
7010 ts = sym->ts;
7012 if (ts.type == BT_CHARACTER && sym->attr.is_bind_c)
7013 se->string_length = build_int_cst (gfc_charlen_type_node, 1);
7014 else if (ts.type == BT_CHARACTER)
7016 if (ts.u.cl->length == NULL)
7018 /* Assumed character length results are not allowed by C418 of the 2003
7019 standard and are trapped in resolve.c; except in the case of SPREAD
7020 (and other intrinsics?) and dummy functions. In the case of SPREAD,
7021 we take the character length of the first argument for the result.
7022 For dummies, we have to look through the formal argument list for
7023 this function and use the character length found there.*/
7024 if (ts.deferred)
7025 cl.backend_decl = gfc_create_var (gfc_charlen_type_node, "slen");
7026 else if (!sym->attr.dummy)
7027 cl.backend_decl = (*stringargs)[0];
7028 else
7030 formal = gfc_sym_get_dummy_args (sym->ns->proc_name);
7031 for (; formal; formal = formal->next)
7032 if (strcmp (formal->sym->name, sym->name) == 0)
7033 cl.backend_decl = formal->sym->ts.u.cl->backend_decl;
7035 len = cl.backend_decl;
7037 else
7039 tree tmp;
7041 /* Calculate the length of the returned string. */
7042 gfc_init_se (&parmse, NULL);
7043 if (need_interface_mapping)
7044 gfc_apply_interface_mapping (&mapping, &parmse, ts.u.cl->length);
7045 else
7046 gfc_conv_expr (&parmse, ts.u.cl->length);
7047 gfc_add_block_to_block (&se->pre, &parmse.pre);
7048 gfc_add_block_to_block (&se->post, &parmse.post);
7049 tmp = parmse.expr;
7050 /* TODO: It would be better to have the charlens as
7051 gfc_charlen_type_node already when the interface is
7052 created instead of converting it here (see PR 84615). */
7053 tmp = fold_build2_loc (input_location, MAX_EXPR,
7054 gfc_charlen_type_node,
7055 fold_convert (gfc_charlen_type_node, tmp),
7056 build_zero_cst (gfc_charlen_type_node));
7057 cl.backend_decl = tmp;
7060 /* Set up a charlen structure for it. */
7061 cl.next = NULL;
7062 cl.length = NULL;
7063 ts.u.cl = &cl;
7065 len = cl.backend_decl;
7068 byref = (comp && (comp->attr.dimension
7069 || (comp->ts.type == BT_CHARACTER && !sym->attr.is_bind_c)))
7070 || (!comp && gfc_return_by_reference (sym));
7071 if (byref)
7073 if (se->direct_byref)
7075 /* Sometimes, too much indirection can be applied; e.g. for
7076 function_result = array_valued_recursive_function. */
7077 if (TREE_TYPE (TREE_TYPE (se->expr))
7078 && TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr)))
7079 && GFC_DESCRIPTOR_TYPE_P
7080 (TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr)))))
7081 se->expr = build_fold_indirect_ref_loc (input_location,
7082 se->expr);
7084 /* If the lhs of an assignment x = f(..) is allocatable and
7085 f2003 is allowed, we must do the automatic reallocation.
7086 TODO - deal with intrinsics, without using a temporary. */
7087 if (flag_realloc_lhs
7088 && se->ss && se->ss->loop_chain
7089 && se->ss->loop_chain->is_alloc_lhs
7090 && !expr->value.function.isym
7091 && sym->result->as != NULL)
7093 /* Evaluate the bounds of the result, if known. */
7094 gfc_set_loop_bounds_from_array_spec (&mapping, se,
7095 sym->result->as);
7097 /* Perform the automatic reallocation. */
7098 tmp = gfc_alloc_allocatable_for_assignment (se->loop,
7099 expr, NULL);
7100 gfc_add_expr_to_block (&se->pre, tmp);
7102 /* Pass the temporary as the first argument. */
7103 result = info->descriptor;
7105 else
7106 result = build_fold_indirect_ref_loc (input_location,
7107 se->expr);
7108 vec_safe_push (retargs, se->expr);
7110 else if (comp && comp->attr.dimension)
7112 gcc_assert (se->loop && info);
7114 /* Set the type of the array. */
7115 tmp = gfc_typenode_for_spec (&comp->ts);
7116 gcc_assert (se->ss->dimen == se->loop->dimen);
7118 /* Evaluate the bounds of the result, if known. */
7119 gfc_set_loop_bounds_from_array_spec (&mapping, se, comp->as);
7121 /* If the lhs of an assignment x = f(..) is allocatable and
7122 f2003 is allowed, we must not generate the function call
7123 here but should just send back the results of the mapping.
7124 This is signalled by the function ss being flagged. */
7125 if (flag_realloc_lhs && se->ss && se->ss->is_alloc_lhs)
7127 gfc_free_interface_mapping (&mapping);
7128 return has_alternate_specifier;
7131 /* Create a temporary to store the result. In case the function
7132 returns a pointer, the temporary will be a shallow copy and
7133 mustn't be deallocated. */
7134 callee_alloc = comp->attr.allocatable || comp->attr.pointer;
7135 gfc_trans_create_temp_array (&se->pre, &se->post, se->ss,
7136 tmp, NULL_TREE, false,
7137 !comp->attr.pointer, callee_alloc,
7138 &se->ss->info->expr->where);
7140 /* Pass the temporary as the first argument. */
7141 result = info->descriptor;
7142 tmp = gfc_build_addr_expr (NULL_TREE, result);
7143 vec_safe_push (retargs, tmp);
7145 else if (!comp && sym->result->attr.dimension)
7147 gcc_assert (se->loop && info);
7149 /* Set the type of the array. */
7150 tmp = gfc_typenode_for_spec (&ts);
7151 gcc_assert (se->ss->dimen == se->loop->dimen);
7153 /* Evaluate the bounds of the result, if known. */
7154 gfc_set_loop_bounds_from_array_spec (&mapping, se, sym->result->as);
7156 /* If the lhs of an assignment x = f(..) is allocatable and
7157 f2003 is allowed, we must not generate the function call
7158 here but should just send back the results of the mapping.
7159 This is signalled by the function ss being flagged. */
7160 if (flag_realloc_lhs && se->ss && se->ss->is_alloc_lhs)
7162 gfc_free_interface_mapping (&mapping);
7163 return has_alternate_specifier;
7166 /* Create a temporary to store the result. In case the function
7167 returns a pointer, the temporary will be a shallow copy and
7168 mustn't be deallocated. */
7169 callee_alloc = sym->attr.allocatable || sym->attr.pointer;
7170 gfc_trans_create_temp_array (&se->pre, &se->post, se->ss,
7171 tmp, NULL_TREE, false,
7172 !sym->attr.pointer, callee_alloc,
7173 &se->ss->info->expr->where);
7175 /* Pass the temporary as the first argument. */
7176 result = info->descriptor;
7177 tmp = gfc_build_addr_expr (NULL_TREE, result);
7178 vec_safe_push (retargs, tmp);
7180 else if (ts.type == BT_CHARACTER)
7182 /* Pass the string length. */
7183 type = gfc_get_character_type (ts.kind, ts.u.cl);
7184 type = build_pointer_type (type);
7186 /* Emit a DECL_EXPR for the VLA type. */
7187 tmp = TREE_TYPE (type);
7188 if (TYPE_SIZE (tmp)
7189 && TREE_CODE (TYPE_SIZE (tmp)) != INTEGER_CST)
7191 tmp = build_decl (input_location, TYPE_DECL, NULL_TREE, tmp);
7192 DECL_ARTIFICIAL (tmp) = 1;
7193 DECL_IGNORED_P (tmp) = 1;
7194 tmp = fold_build1_loc (input_location, DECL_EXPR,
7195 TREE_TYPE (tmp), tmp);
7196 gfc_add_expr_to_block (&se->pre, tmp);
7199 /* Return an address to a char[0:len-1]* temporary for
7200 character pointers. */
7201 if ((!comp && (sym->attr.pointer || sym->attr.allocatable))
7202 || (comp && (comp->attr.pointer || comp->attr.allocatable)))
7204 var = gfc_create_var (type, "pstr");
7206 if ((!comp && sym->attr.allocatable)
7207 || (comp && comp->attr.allocatable))
7209 gfc_add_modify (&se->pre, var,
7210 fold_convert (TREE_TYPE (var),
7211 null_pointer_node));
7212 tmp = gfc_call_free (var);
7213 gfc_add_expr_to_block (&se->post, tmp);
7216 /* Provide an address expression for the function arguments. */
7217 var = gfc_build_addr_expr (NULL_TREE, var);
7219 else
7220 var = gfc_conv_string_tmp (se, type, len);
7222 vec_safe_push (retargs, var);
7224 else
7226 gcc_assert (flag_f2c && ts.type == BT_COMPLEX);
7228 type = gfc_get_complex_type (ts.kind);
7229 var = gfc_build_addr_expr (NULL_TREE, gfc_create_var (type, "cmplx"));
7230 vec_safe_push (retargs, var);
7233 /* Add the string length to the argument list. */
7234 if (ts.type == BT_CHARACTER && ts.deferred)
7236 tmp = len;
7237 if (!VAR_P (tmp))
7238 tmp = gfc_evaluate_now (len, &se->pre);
7239 TREE_STATIC (tmp) = 1;
7240 gfc_add_modify (&se->pre, tmp,
7241 build_int_cst (TREE_TYPE (tmp), 0));
7242 tmp = gfc_build_addr_expr (NULL_TREE, tmp);
7243 vec_safe_push (retargs, tmp);
7245 else if (ts.type == BT_CHARACTER)
7246 vec_safe_push (retargs, len);
7248 gfc_free_interface_mapping (&mapping);
7250 /* We need to glom RETARGS + ARGLIST + STRINGARGS + APPEND_ARGS. */
7251 arglen = (vec_safe_length (arglist) + vec_safe_length (optionalargs)
7252 + vec_safe_length (stringargs) + vec_safe_length (append_args));
7253 vec_safe_reserve (retargs, arglen);
7255 /* Add the return arguments. */
7256 vec_safe_splice (retargs, arglist);
7258 /* Add the hidden present status for optional+value to the arguments. */
7259 vec_safe_splice (retargs, optionalargs);
7261 /* Add the hidden string length parameters to the arguments. */
7262 vec_safe_splice (retargs, stringargs);
7264 /* We may want to append extra arguments here. This is used e.g. for
7265 calls to libgfortran_matmul_??, which need extra information. */
7266 vec_safe_splice (retargs, append_args);
7268 arglist = retargs;
7270 /* Generate the actual call. */
7271 if (base_object == NULL_TREE)
7272 conv_function_val (se, sym, expr, args);
7273 else
7274 conv_base_obj_fcn_val (se, base_object, expr);
7276 /* If there are alternate return labels, function type should be
7277 integer. Can't modify the type in place though, since it can be shared
7278 with other functions. For dummy arguments, the typing is done to
7279 this result, even if it has to be repeated for each call. */
7280 if (has_alternate_specifier
7281 && TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr))) != integer_type_node)
7283 if (!sym->attr.dummy)
7285 TREE_TYPE (sym->backend_decl)
7286 = build_function_type (integer_type_node,
7287 TYPE_ARG_TYPES (TREE_TYPE (sym->backend_decl)));
7288 se->expr = gfc_build_addr_expr (NULL_TREE, sym->backend_decl);
7290 else
7291 TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr))) = integer_type_node;
7294 fntype = TREE_TYPE (TREE_TYPE (se->expr));
7295 se->expr = build_call_vec (TREE_TYPE (fntype), se->expr, arglist);
7297 /* Allocatable scalar function results must be freed and nullified
7298 after use. This necessitates the creation of a temporary to
7299 hold the result to prevent duplicate calls. */
7300 if (!byref && sym->ts.type != BT_CHARACTER
7301 && ((sym->attr.allocatable && !sym->attr.dimension && !comp)
7302 || (comp && comp->attr.allocatable && !comp->attr.dimension)))
7304 tmp = gfc_create_var (TREE_TYPE (se->expr), NULL);
7305 gfc_add_modify (&se->pre, tmp, se->expr);
7306 se->expr = tmp;
7307 tmp = gfc_call_free (tmp);
7308 gfc_add_expr_to_block (&post, tmp);
7309 gfc_add_modify (&post, se->expr, build_int_cst (TREE_TYPE (se->expr), 0));
7312 /* If we have a pointer function, but we don't want a pointer, e.g.
7313 something like
7314 x = f()
7315 where f is pointer valued, we have to dereference the result. */
7316 if (!se->want_pointer && !byref
7317 && ((!comp && (sym->attr.pointer || sym->attr.allocatable))
7318 || (comp && (comp->attr.pointer || comp->attr.allocatable))))
7319 se->expr = build_fold_indirect_ref_loc (input_location, se->expr);
7321 /* f2c calling conventions require a scalar default real function to
7322 return a double precision result. Convert this back to default
7323 real. We only care about the cases that can happen in Fortran 77.
7325 if (flag_f2c && sym->ts.type == BT_REAL
7326 && sym->ts.kind == gfc_default_real_kind
7327 && !sym->attr.always_explicit)
7328 se->expr = fold_convert (gfc_get_real_type (sym->ts.kind), se->expr);
7330 /* A pure function may still have side-effects - it may modify its
7331 parameters. */
7332 TREE_SIDE_EFFECTS (se->expr) = 1;
7333 #if 0
7334 if (!sym->attr.pure)
7335 TREE_SIDE_EFFECTS (se->expr) = 1;
7336 #endif
7338 if (byref)
7340 /* Add the function call to the pre chain. There is no expression. */
7341 gfc_add_expr_to_block (&se->pre, se->expr);
7342 se->expr = NULL_TREE;
7344 if (!se->direct_byref)
7346 if ((sym->attr.dimension && !comp) || (comp && comp->attr.dimension))
7348 if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
7350 /* Check the data pointer hasn't been modified. This would
7351 happen in a function returning a pointer. */
7352 tmp = gfc_conv_descriptor_data_get (info->descriptor);
7353 tmp = fold_build2_loc (input_location, NE_EXPR,
7354 logical_type_node,
7355 tmp, info->data);
7356 gfc_trans_runtime_check (true, false, tmp, &se->pre, NULL,
7357 gfc_msg_fault);
7359 se->expr = info->descriptor;
7360 /* Bundle in the string length. */
7361 se->string_length = len;
7363 else if (ts.type == BT_CHARACTER)
7365 /* Dereference for character pointer results. */
7366 if ((!comp && (sym->attr.pointer || sym->attr.allocatable))
7367 || (comp && (comp->attr.pointer || comp->attr.allocatable)))
7368 se->expr = build_fold_indirect_ref_loc (input_location, var);
7369 else
7370 se->expr = var;
7372 se->string_length = len;
7374 else
7376 gcc_assert (ts.type == BT_COMPLEX && flag_f2c);
7377 se->expr = build_fold_indirect_ref_loc (input_location, var);
7382 /* Associate the rhs class object's meta-data with the result, when the
7383 result is a temporary. */
7384 if (args && args->expr && args->expr->ts.type == BT_CLASS
7385 && sym->ts.type == BT_CLASS && result != NULL_TREE && DECL_P (result)
7386 && !GFC_CLASS_TYPE_P (TREE_TYPE (result)))
7388 gfc_se parmse;
7389 gfc_expr *class_expr = gfc_find_and_cut_at_last_class_ref (args->expr);
7391 gfc_init_se (&parmse, NULL);
7392 parmse.data_not_needed = 1;
7393 gfc_conv_expr (&parmse, class_expr);
7394 if (!DECL_LANG_SPECIFIC (result))
7395 gfc_allocate_lang_decl (result);
7396 GFC_DECL_SAVED_DESCRIPTOR (result) = parmse.expr;
7397 gfc_free_expr (class_expr);
7398 /* -fcheck= can add diagnostic code, which has to be placed before
7399 the call. */
7400 if (parmse.pre.head != NULL)
7401 gfc_add_expr_to_block (&se->pre, parmse.pre.head);
7402 gcc_assert (parmse.post.head == NULL_TREE);
7405 /* Follow the function call with the argument post block. */
7406 if (byref)
7408 gfc_add_block_to_block (&se->pre, &post);
7410 /* Transformational functions of derived types with allocatable
7411 components must have the result allocatable components copied when the
7412 argument is actually given. */
7413 arg = expr->value.function.actual;
7414 if (result && arg && expr->rank
7415 && expr->value.function.isym
7416 && expr->value.function.isym->transformational
7417 && arg->expr
7418 && arg->expr->ts.type == BT_DERIVED
7419 && arg->expr->ts.u.derived->attr.alloc_comp)
7421 tree tmp2;
7422 /* Copy the allocatable components. We have to use a
7423 temporary here to prevent source allocatable components
7424 from being corrupted. */
7425 tmp2 = gfc_evaluate_now (result, &se->pre);
7426 tmp = gfc_copy_alloc_comp (arg->expr->ts.u.derived,
7427 result, tmp2, expr->rank, 0);
7428 gfc_add_expr_to_block (&se->pre, tmp);
7429 tmp = gfc_copy_allocatable_data (result, tmp2, TREE_TYPE(tmp2),
7430 expr->rank);
7431 gfc_add_expr_to_block (&se->pre, tmp);
7433 /* Finally free the temporary's data field. */
7434 tmp = gfc_conv_descriptor_data_get (tmp2);
7435 tmp = gfc_deallocate_with_status (tmp, NULL_TREE, NULL_TREE,
7436 NULL_TREE, NULL_TREE, true,
7437 NULL, GFC_CAF_COARRAY_NOCOARRAY);
7438 gfc_add_expr_to_block (&se->pre, tmp);
7441 else
7443 /* For a function with a class array result, save the result as
7444 a temporary, set the info fields needed by the scalarizer and
7445 call the finalization function of the temporary. Note that the
7446 nullification of allocatable components needed by the result
7447 is done in gfc_trans_assignment_1. */
7448 if (expr && ((gfc_is_class_array_function (expr)
7449 && se->ss && se->ss->loop)
7450 || gfc_is_alloc_class_scalar_function (expr))
7451 && se->expr && GFC_CLASS_TYPE_P (TREE_TYPE (se->expr))
7452 && expr->must_finalize)
7454 tree final_fndecl;
7455 tree is_final;
7456 int n;
7457 if (se->ss && se->ss->loop)
7459 gfc_add_block_to_block (&se->ss->loop->pre, &se->pre);
7460 se->expr = gfc_evaluate_now (se->expr, &se->ss->loop->pre);
7461 tmp = gfc_class_data_get (se->expr);
7462 info->descriptor = tmp;
7463 info->data = gfc_conv_descriptor_data_get (tmp);
7464 info->offset = gfc_conv_descriptor_offset_get (tmp);
7465 for (n = 0; n < se->ss->loop->dimen; n++)
7467 tree dim = gfc_rank_cst[n];
7468 se->ss->loop->to[n] = gfc_conv_descriptor_ubound_get (tmp, dim);
7469 se->ss->loop->from[n] = gfc_conv_descriptor_lbound_get (tmp, dim);
7472 else
7474 /* TODO Eliminate the doubling of temporaries. This
7475 one is necessary to ensure no memory leakage. */
7476 se->expr = gfc_evaluate_now (se->expr, &se->pre);
7477 tmp = gfc_class_data_get (se->expr);
7478 tmp = gfc_conv_scalar_to_descriptor (se, tmp,
7479 CLASS_DATA (expr->value.function.esym->result)->attr);
7482 if ((gfc_is_class_array_function (expr)
7483 || gfc_is_alloc_class_scalar_function (expr))
7484 && CLASS_DATA (expr->value.function.esym->result)->attr.pointer)
7485 goto no_finalization;
7487 final_fndecl = gfc_class_vtab_final_get (se->expr);
7488 is_final = fold_build2_loc (input_location, NE_EXPR,
7489 logical_type_node,
7490 final_fndecl,
7491 fold_convert (TREE_TYPE (final_fndecl),
7492 null_pointer_node));
7493 final_fndecl = build_fold_indirect_ref_loc (input_location,
7494 final_fndecl);
7495 tmp = build_call_expr_loc (input_location,
7496 final_fndecl, 3,
7497 gfc_build_addr_expr (NULL, tmp),
7498 gfc_class_vtab_size_get (se->expr),
7499 boolean_false_node);
7500 tmp = fold_build3_loc (input_location, COND_EXPR,
7501 void_type_node, is_final, tmp,
7502 build_empty_stmt (input_location));
7504 if (se->ss && se->ss->loop)
7506 gfc_prepend_expr_to_block (&se->ss->loop->post, tmp);
7507 tmp = fold_build2_loc (input_location, NE_EXPR,
7508 logical_type_node,
7509 info->data,
7510 fold_convert (TREE_TYPE (info->data),
7511 null_pointer_node));
7512 tmp = fold_build3_loc (input_location, COND_EXPR,
7513 void_type_node, tmp,
7514 gfc_call_free (info->data),
7515 build_empty_stmt (input_location));
7516 gfc_add_expr_to_block (&se->ss->loop->post, tmp);
7518 else
7520 tree classdata;
7521 gfc_prepend_expr_to_block (&se->post, tmp);
7522 classdata = gfc_class_data_get (se->expr);
7523 tmp = fold_build2_loc (input_location, NE_EXPR,
7524 logical_type_node,
7525 classdata,
7526 fold_convert (TREE_TYPE (classdata),
7527 null_pointer_node));
7528 tmp = fold_build3_loc (input_location, COND_EXPR,
7529 void_type_node, tmp,
7530 gfc_call_free (classdata),
7531 build_empty_stmt (input_location));
7532 gfc_add_expr_to_block (&se->post, tmp);
7536 no_finalization:
7537 gfc_add_block_to_block (&se->post, &post);
7540 return has_alternate_specifier;
7544 /* Fill a character string with spaces. */
7546 static tree
7547 fill_with_spaces (tree start, tree type, tree size)
7549 stmtblock_t block, loop;
7550 tree i, el, exit_label, cond, tmp;
7552 /* For a simple char type, we can call memset(). */
7553 if (compare_tree_int (TYPE_SIZE_UNIT (type), 1) == 0)
7554 return build_call_expr_loc (input_location,
7555 builtin_decl_explicit (BUILT_IN_MEMSET),
7556 3, start,
7557 build_int_cst (gfc_get_int_type (gfc_c_int_kind),
7558 lang_hooks.to_target_charset (' ')),
7559 fold_convert (size_type_node, size));
7561 /* Otherwise, we use a loop:
7562 for (el = start, i = size; i > 0; el--, i+= TYPE_SIZE_UNIT (type))
7563 *el = (type) ' ';
7566 /* Initialize variables. */
7567 gfc_init_block (&block);
7568 i = gfc_create_var (sizetype, "i");
7569 gfc_add_modify (&block, i, fold_convert (sizetype, size));
7570 el = gfc_create_var (build_pointer_type (type), "el");
7571 gfc_add_modify (&block, el, fold_convert (TREE_TYPE (el), start));
7572 exit_label = gfc_build_label_decl (NULL_TREE);
7573 TREE_USED (exit_label) = 1;
7576 /* Loop body. */
7577 gfc_init_block (&loop);
7579 /* Exit condition. */
7580 cond = fold_build2_loc (input_location, LE_EXPR, logical_type_node, i,
7581 build_zero_cst (sizetype));
7582 tmp = build1_v (GOTO_EXPR, exit_label);
7583 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond, tmp,
7584 build_empty_stmt (input_location));
7585 gfc_add_expr_to_block (&loop, tmp);
7587 /* Assignment. */
7588 gfc_add_modify (&loop,
7589 fold_build1_loc (input_location, INDIRECT_REF, type, el),
7590 build_int_cst (type, lang_hooks.to_target_charset (' ')));
7592 /* Increment loop variables. */
7593 gfc_add_modify (&loop, i,
7594 fold_build2_loc (input_location, MINUS_EXPR, sizetype, i,
7595 TYPE_SIZE_UNIT (type)));
7596 gfc_add_modify (&loop, el,
7597 fold_build_pointer_plus_loc (input_location,
7598 el, TYPE_SIZE_UNIT (type)));
7600 /* Making the loop... actually loop! */
7601 tmp = gfc_finish_block (&loop);
7602 tmp = build1_v (LOOP_EXPR, tmp);
7603 gfc_add_expr_to_block (&block, tmp);
7605 /* The exit label. */
7606 tmp = build1_v (LABEL_EXPR, exit_label);
7607 gfc_add_expr_to_block (&block, tmp);
7610 return gfc_finish_block (&block);
7614 /* Generate code to copy a string. */
7616 void
7617 gfc_trans_string_copy (stmtblock_t * block, tree dlength, tree dest,
7618 int dkind, tree slength, tree src, int skind)
7620 tree tmp, dlen, slen;
7621 tree dsc;
7622 tree ssc;
7623 tree cond;
7624 tree cond2;
7625 tree tmp2;
7626 tree tmp3;
7627 tree tmp4;
7628 tree chartype;
7629 stmtblock_t tempblock;
7631 gcc_assert (dkind == skind);
7633 if (slength != NULL_TREE)
7635 slen = gfc_evaluate_now (fold_convert (gfc_charlen_type_node, slength), block);
7636 ssc = gfc_string_to_single_character (slen, src, skind);
7638 else
7640 slen = build_one_cst (gfc_charlen_type_node);
7641 ssc = src;
7644 if (dlength != NULL_TREE)
7646 dlen = gfc_evaluate_now (fold_convert (gfc_charlen_type_node, dlength), block);
7647 dsc = gfc_string_to_single_character (dlen, dest, dkind);
7649 else
7651 dlen = build_one_cst (gfc_charlen_type_node);
7652 dsc = dest;
7655 /* Assign directly if the types are compatible. */
7656 if (dsc != NULL_TREE && ssc != NULL_TREE
7657 && TREE_TYPE (dsc) == TREE_TYPE (ssc))
7659 gfc_add_modify (block, dsc, ssc);
7660 return;
7663 /* The string copy algorithm below generates code like
7665 if (destlen > 0)
7667 if (srclen < destlen)
7669 memmove (dest, src, srclen);
7670 // Pad with spaces.
7671 memset (&dest[srclen], ' ', destlen - srclen);
7673 else
7675 // Truncate if too long.
7676 memmove (dest, src, destlen);
7681 /* Do nothing if the destination length is zero. */
7682 cond = fold_build2_loc (input_location, GT_EXPR, logical_type_node, dlen,
7683 build_zero_cst (TREE_TYPE (dlen)));
7685 /* For non-default character kinds, we have to multiply the string
7686 length by the base type size. */
7687 chartype = gfc_get_char_type (dkind);
7688 slen = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (slen),
7689 slen,
7690 fold_convert (TREE_TYPE (slen),
7691 TYPE_SIZE_UNIT (chartype)));
7692 dlen = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (dlen),
7693 dlen,
7694 fold_convert (TREE_TYPE (dlen),
7695 TYPE_SIZE_UNIT (chartype)));
7697 if (dlength && POINTER_TYPE_P (TREE_TYPE (dest)))
7698 dest = fold_convert (pvoid_type_node, dest);
7699 else
7700 dest = gfc_build_addr_expr (pvoid_type_node, dest);
7702 if (slength && POINTER_TYPE_P (TREE_TYPE (src)))
7703 src = fold_convert (pvoid_type_node, src);
7704 else
7705 src = gfc_build_addr_expr (pvoid_type_node, src);
7707 /* Truncate string if source is too long. */
7708 cond2 = fold_build2_loc (input_location, LT_EXPR, logical_type_node, slen,
7709 dlen);
7711 /* Copy and pad with spaces. */
7712 tmp3 = build_call_expr_loc (input_location,
7713 builtin_decl_explicit (BUILT_IN_MEMMOVE),
7714 3, dest, src,
7715 fold_convert (size_type_node, slen));
7717 /* Wstringop-overflow appears at -O3 even though this warning is not
7718 explicitly available in fortran nor can it be switched off. If the
7719 source length is a constant, its negative appears as a very large
7720 postive number and triggers the warning in BUILTIN_MEMSET. Fixing
7721 the result of the MINUS_EXPR suppresses this spurious warning. */
7722 tmp = fold_build2_loc (input_location, MINUS_EXPR,
7723 TREE_TYPE(dlen), dlen, slen);
7724 if (slength && TREE_CONSTANT (slength))
7725 tmp = gfc_evaluate_now (tmp, block);
7727 tmp4 = fold_build_pointer_plus_loc (input_location, dest, slen);
7728 tmp4 = fill_with_spaces (tmp4, chartype, tmp);
7730 gfc_init_block (&tempblock);
7731 gfc_add_expr_to_block (&tempblock, tmp3);
7732 gfc_add_expr_to_block (&tempblock, tmp4);
7733 tmp3 = gfc_finish_block (&tempblock);
7735 /* The truncated memmove if the slen >= dlen. */
7736 tmp2 = build_call_expr_loc (input_location,
7737 builtin_decl_explicit (BUILT_IN_MEMMOVE),
7738 3, dest, src,
7739 fold_convert (size_type_node, dlen));
7741 /* The whole copy_string function is there. */
7742 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond2,
7743 tmp3, tmp2);
7744 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond, tmp,
7745 build_empty_stmt (input_location));
7746 gfc_add_expr_to_block (block, tmp);
7750 /* Translate a statement function.
7751 The value of a statement function reference is obtained by evaluating the
7752 expression using the values of the actual arguments for the values of the
7753 corresponding dummy arguments. */
7755 static void
7756 gfc_conv_statement_function (gfc_se * se, gfc_expr * expr)
7758 gfc_symbol *sym;
7759 gfc_symbol *fsym;
7760 gfc_formal_arglist *fargs;
7761 gfc_actual_arglist *args;
7762 gfc_se lse;
7763 gfc_se rse;
7764 gfc_saved_var *saved_vars;
7765 tree *temp_vars;
7766 tree type;
7767 tree tmp;
7768 int n;
7770 sym = expr->symtree->n.sym;
7771 args = expr->value.function.actual;
7772 gfc_init_se (&lse, NULL);
7773 gfc_init_se (&rse, NULL);
7775 n = 0;
7776 for (fargs = gfc_sym_get_dummy_args (sym); fargs; fargs = fargs->next)
7777 n++;
7778 saved_vars = XCNEWVEC (gfc_saved_var, n);
7779 temp_vars = XCNEWVEC (tree, n);
7781 for (fargs = gfc_sym_get_dummy_args (sym), n = 0; fargs;
7782 fargs = fargs->next, n++)
7784 /* Each dummy shall be specified, explicitly or implicitly, to be
7785 scalar. */
7786 gcc_assert (fargs->sym->attr.dimension == 0);
7787 fsym = fargs->sym;
7789 if (fsym->ts.type == BT_CHARACTER)
7791 /* Copy string arguments. */
7792 tree arglen;
7794 gcc_assert (fsym->ts.u.cl && fsym->ts.u.cl->length
7795 && fsym->ts.u.cl->length->expr_type == EXPR_CONSTANT);
7797 /* Create a temporary to hold the value. */
7798 if (fsym->ts.u.cl->backend_decl == NULL_TREE)
7799 fsym->ts.u.cl->backend_decl
7800 = gfc_conv_constant_to_tree (fsym->ts.u.cl->length);
7802 type = gfc_get_character_type (fsym->ts.kind, fsym->ts.u.cl);
7803 temp_vars[n] = gfc_create_var (type, fsym->name);
7805 arglen = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
7807 gfc_conv_expr (&rse, args->expr);
7808 gfc_conv_string_parameter (&rse);
7809 gfc_add_block_to_block (&se->pre, &lse.pre);
7810 gfc_add_block_to_block (&se->pre, &rse.pre);
7812 gfc_trans_string_copy (&se->pre, arglen, temp_vars[n], fsym->ts.kind,
7813 rse.string_length, rse.expr, fsym->ts.kind);
7814 gfc_add_block_to_block (&se->pre, &lse.post);
7815 gfc_add_block_to_block (&se->pre, &rse.post);
7817 else
7819 /* For everything else, just evaluate the expression. */
7821 /* Create a temporary to hold the value. */
7822 type = gfc_typenode_for_spec (&fsym->ts);
7823 temp_vars[n] = gfc_create_var (type, fsym->name);
7825 gfc_conv_expr (&lse, args->expr);
7827 gfc_add_block_to_block (&se->pre, &lse.pre);
7828 gfc_add_modify (&se->pre, temp_vars[n], lse.expr);
7829 gfc_add_block_to_block (&se->pre, &lse.post);
7832 args = args->next;
7835 /* Use the temporary variables in place of the real ones. */
7836 for (fargs = gfc_sym_get_dummy_args (sym), n = 0; fargs;
7837 fargs = fargs->next, n++)
7838 gfc_shadow_sym (fargs->sym, temp_vars[n], &saved_vars[n]);
7840 gfc_conv_expr (se, sym->value);
7842 if (sym->ts.type == BT_CHARACTER)
7844 gfc_conv_const_charlen (sym->ts.u.cl);
7846 /* Force the expression to the correct length. */
7847 if (!INTEGER_CST_P (se->string_length)
7848 || tree_int_cst_lt (se->string_length,
7849 sym->ts.u.cl->backend_decl))
7851 type = gfc_get_character_type (sym->ts.kind, sym->ts.u.cl);
7852 tmp = gfc_create_var (type, sym->name);
7853 tmp = gfc_build_addr_expr (build_pointer_type (type), tmp);
7854 gfc_trans_string_copy (&se->pre, sym->ts.u.cl->backend_decl, tmp,
7855 sym->ts.kind, se->string_length, se->expr,
7856 sym->ts.kind);
7857 se->expr = tmp;
7859 se->string_length = sym->ts.u.cl->backend_decl;
7862 /* Restore the original variables. */
7863 for (fargs = gfc_sym_get_dummy_args (sym), n = 0; fargs;
7864 fargs = fargs->next, n++)
7865 gfc_restore_sym (fargs->sym, &saved_vars[n]);
7866 free (temp_vars);
7867 free (saved_vars);
7871 /* Translate a function expression. */
7873 static void
7874 gfc_conv_function_expr (gfc_se * se, gfc_expr * expr)
7876 gfc_symbol *sym;
7878 if (expr->value.function.isym)
7880 gfc_conv_intrinsic_function (se, expr);
7881 return;
7884 /* expr.value.function.esym is the resolved (specific) function symbol for
7885 most functions. However this isn't set for dummy procedures. */
7886 sym = expr->value.function.esym;
7887 if (!sym)
7888 sym = expr->symtree->n.sym;
7890 /* The IEEE_ARITHMETIC functions are caught here. */
7891 if (sym->from_intmod == INTMOD_IEEE_ARITHMETIC)
7892 if (gfc_conv_ieee_arithmetic_function (se, expr))
7893 return;
7895 /* We distinguish statement functions from general functions to improve
7896 runtime performance. */
7897 if (sym->attr.proc == PROC_ST_FUNCTION)
7899 gfc_conv_statement_function (se, expr);
7900 return;
7903 gfc_conv_procedure_call (se, sym, expr->value.function.actual, expr,
7904 NULL);
7908 /* Determine whether the given EXPR_CONSTANT is a zero initializer. */
7910 static bool
7911 is_zero_initializer_p (gfc_expr * expr)
7913 if (expr->expr_type != EXPR_CONSTANT)
7914 return false;
7916 /* We ignore constants with prescribed memory representations for now. */
7917 if (expr->representation.string)
7918 return false;
7920 switch (expr->ts.type)
7922 case BT_INTEGER:
7923 return mpz_cmp_si (expr->value.integer, 0) == 0;
7925 case BT_REAL:
7926 return mpfr_zero_p (expr->value.real)
7927 && MPFR_SIGN (expr->value.real) >= 0;
7929 case BT_LOGICAL:
7930 return expr->value.logical == 0;
7932 case BT_COMPLEX:
7933 return mpfr_zero_p (mpc_realref (expr->value.complex))
7934 && MPFR_SIGN (mpc_realref (expr->value.complex)) >= 0
7935 && mpfr_zero_p (mpc_imagref (expr->value.complex))
7936 && MPFR_SIGN (mpc_imagref (expr->value.complex)) >= 0;
7938 default:
7939 break;
7941 return false;
7945 static void
7946 gfc_conv_array_constructor_expr (gfc_se * se, gfc_expr * expr)
7948 gfc_ss *ss;
7950 ss = se->ss;
7951 gcc_assert (ss != NULL && ss != gfc_ss_terminator);
7952 gcc_assert (ss->info->expr == expr && ss->info->type == GFC_SS_CONSTRUCTOR);
7954 gfc_conv_tmp_array_ref (se);
7958 /* Build a static initializer. EXPR is the expression for the initial value.
7959 The other parameters describe the variable of the component being
7960 initialized. EXPR may be null. */
7962 tree
7963 gfc_conv_initializer (gfc_expr * expr, gfc_typespec * ts, tree type,
7964 bool array, bool pointer, bool procptr)
7966 gfc_se se;
7968 if (flag_coarray != GFC_FCOARRAY_LIB && ts->type == BT_DERIVED
7969 && ts->u.derived->from_intmod == INTMOD_ISO_FORTRAN_ENV
7970 && ts->u.derived->intmod_sym_id == ISOFORTRAN_EVENT_TYPE)
7971 return build_constructor (type, NULL);
7973 if (!(expr || pointer || procptr))
7974 return NULL_TREE;
7976 /* Check if we have ISOCBINDING_NULL_PTR or ISOCBINDING_NULL_FUNPTR
7977 (these are the only two iso_c_binding derived types that can be
7978 used as initialization expressions). If so, we need to modify
7979 the 'expr' to be that for a (void *). */
7980 if (expr != NULL && expr->ts.type == BT_DERIVED
7981 && expr->ts.is_iso_c && expr->ts.u.derived)
7983 if (TREE_CODE (type) == ARRAY_TYPE)
7984 return build_constructor (type, NULL);
7985 else if (POINTER_TYPE_P (type))
7986 return build_int_cst (type, 0);
7987 else
7988 gcc_unreachable ();
7991 if (array && !procptr)
7993 tree ctor;
7994 /* Arrays need special handling. */
7995 if (pointer)
7996 ctor = gfc_build_null_descriptor (type);
7997 /* Special case assigning an array to zero. */
7998 else if (is_zero_initializer_p (expr))
7999 ctor = build_constructor (type, NULL);
8000 else
8001 ctor = gfc_conv_array_initializer (type, expr);
8002 TREE_STATIC (ctor) = 1;
8003 return ctor;
8005 else if (pointer || procptr)
8007 if (ts->type == BT_CLASS && !procptr)
8009 gfc_init_se (&se, NULL);
8010 gfc_conv_structure (&se, gfc_class_initializer (ts, expr), 1);
8011 gcc_assert (TREE_CODE (se.expr) == CONSTRUCTOR);
8012 TREE_STATIC (se.expr) = 1;
8013 return se.expr;
8015 else if (!expr || expr->expr_type == EXPR_NULL)
8016 return fold_convert (type, null_pointer_node);
8017 else
8019 gfc_init_se (&se, NULL);
8020 se.want_pointer = 1;
8021 gfc_conv_expr (&se, expr);
8022 gcc_assert (TREE_CODE (se.expr) != CONSTRUCTOR);
8023 return se.expr;
8026 else
8028 switch (ts->type)
8030 case_bt_struct:
8031 case BT_CLASS:
8032 gfc_init_se (&se, NULL);
8033 if (ts->type == BT_CLASS && expr->expr_type == EXPR_NULL)
8034 gfc_conv_structure (&se, gfc_class_initializer (ts, expr), 1);
8035 else
8036 gfc_conv_structure (&se, expr, 1);
8037 gcc_assert (TREE_CODE (se.expr) == CONSTRUCTOR);
8038 TREE_STATIC (se.expr) = 1;
8039 return se.expr;
8041 case BT_CHARACTER:
8042 if (expr->expr_type == EXPR_CONSTANT)
8044 tree ctor = gfc_conv_string_init (ts->u.cl->backend_decl, expr);
8045 TREE_STATIC (ctor) = 1;
8046 return ctor;
8049 /* Fallthrough. */
8050 default:
8051 gfc_init_se (&se, NULL);
8052 gfc_conv_constant (&se, expr);
8053 gcc_assert (TREE_CODE (se.expr) != CONSTRUCTOR);
8054 return se.expr;
8059 static tree
8060 gfc_trans_subarray_assign (tree dest, gfc_component * cm, gfc_expr * expr)
8062 gfc_se rse;
8063 gfc_se lse;
8064 gfc_ss *rss;
8065 gfc_ss *lss;
8066 gfc_array_info *lss_array;
8067 stmtblock_t body;
8068 stmtblock_t block;
8069 gfc_loopinfo loop;
8070 int n;
8071 tree tmp;
8073 gfc_start_block (&block);
8075 /* Initialize the scalarizer. */
8076 gfc_init_loopinfo (&loop);
8078 gfc_init_se (&lse, NULL);
8079 gfc_init_se (&rse, NULL);
8081 /* Walk the rhs. */
8082 rss = gfc_walk_expr (expr);
8083 if (rss == gfc_ss_terminator)
8084 /* The rhs is scalar. Add a ss for the expression. */
8085 rss = gfc_get_scalar_ss (gfc_ss_terminator, expr);
8087 /* Create a SS for the destination. */
8088 lss = gfc_get_array_ss (gfc_ss_terminator, NULL, cm->as->rank,
8089 GFC_SS_COMPONENT);
8090 lss_array = &lss->info->data.array;
8091 lss_array->shape = gfc_get_shape (cm->as->rank);
8092 lss_array->descriptor = dest;
8093 lss_array->data = gfc_conv_array_data (dest);
8094 lss_array->offset = gfc_conv_array_offset (dest);
8095 for (n = 0; n < cm->as->rank; n++)
8097 lss_array->start[n] = gfc_conv_array_lbound (dest, n);
8098 lss_array->stride[n] = gfc_index_one_node;
8100 mpz_init (lss_array->shape[n]);
8101 mpz_sub (lss_array->shape[n], cm->as->upper[n]->value.integer,
8102 cm->as->lower[n]->value.integer);
8103 mpz_add_ui (lss_array->shape[n], lss_array->shape[n], 1);
8106 /* Associate the SS with the loop. */
8107 gfc_add_ss_to_loop (&loop, lss);
8108 gfc_add_ss_to_loop (&loop, rss);
8110 /* Calculate the bounds of the scalarization. */
8111 gfc_conv_ss_startstride (&loop);
8113 /* Setup the scalarizing loops. */
8114 gfc_conv_loop_setup (&loop, &expr->where);
8116 /* Setup the gfc_se structures. */
8117 gfc_copy_loopinfo_to_se (&lse, &loop);
8118 gfc_copy_loopinfo_to_se (&rse, &loop);
8120 rse.ss = rss;
8121 gfc_mark_ss_chain_used (rss, 1);
8122 lse.ss = lss;
8123 gfc_mark_ss_chain_used (lss, 1);
8125 /* Start the scalarized loop body. */
8126 gfc_start_scalarized_body (&loop, &body);
8128 gfc_conv_tmp_array_ref (&lse);
8129 if (cm->ts.type == BT_CHARACTER)
8130 lse.string_length = cm->ts.u.cl->backend_decl;
8132 gfc_conv_expr (&rse, expr);
8134 tmp = gfc_trans_scalar_assign (&lse, &rse, cm->ts, true, false);
8135 gfc_add_expr_to_block (&body, tmp);
8137 gcc_assert (rse.ss == gfc_ss_terminator);
8139 /* Generate the copying loops. */
8140 gfc_trans_scalarizing_loops (&loop, &body);
8142 /* Wrap the whole thing up. */
8143 gfc_add_block_to_block (&block, &loop.pre);
8144 gfc_add_block_to_block (&block, &loop.post);
8146 gcc_assert (lss_array->shape != NULL);
8147 gfc_free_shape (&lss_array->shape, cm->as->rank);
8148 gfc_cleanup_loop (&loop);
8150 return gfc_finish_block (&block);
8154 static tree
8155 gfc_trans_alloc_subarray_assign (tree dest, gfc_component * cm,
8156 gfc_expr * expr)
8158 gfc_se se;
8159 stmtblock_t block;
8160 tree offset;
8161 int n;
8162 tree tmp;
8163 tree tmp2;
8164 gfc_array_spec *as;
8165 gfc_expr *arg = NULL;
8167 gfc_start_block (&block);
8168 gfc_init_se (&se, NULL);
8170 /* Get the descriptor for the expressions. */
8171 se.want_pointer = 0;
8172 gfc_conv_expr_descriptor (&se, expr);
8173 gfc_add_block_to_block (&block, &se.pre);
8174 gfc_add_modify (&block, dest, se.expr);
8176 /* Deal with arrays of derived types with allocatable components. */
8177 if (gfc_bt_struct (cm->ts.type)
8178 && cm->ts.u.derived->attr.alloc_comp)
8179 // TODO: Fix caf_mode
8180 tmp = gfc_copy_alloc_comp (cm->ts.u.derived,
8181 se.expr, dest,
8182 cm->as->rank, 0);
8183 else if (cm->ts.type == BT_CLASS && expr->ts.type == BT_DERIVED
8184 && CLASS_DATA(cm)->attr.allocatable)
8186 if (cm->ts.u.derived->attr.alloc_comp)
8187 // TODO: Fix caf_mode
8188 tmp = gfc_copy_alloc_comp (expr->ts.u.derived,
8189 se.expr, dest,
8190 expr->rank, 0);
8191 else
8193 tmp = TREE_TYPE (dest);
8194 tmp = gfc_duplicate_allocatable (dest, se.expr,
8195 tmp, expr->rank, NULL_TREE);
8198 else
8199 tmp = gfc_duplicate_allocatable (dest, se.expr,
8200 TREE_TYPE(cm->backend_decl),
8201 cm->as->rank, NULL_TREE);
8203 gfc_add_expr_to_block (&block, tmp);
8204 gfc_add_block_to_block (&block, &se.post);
8206 if (expr->expr_type != EXPR_VARIABLE)
8207 gfc_conv_descriptor_data_set (&block, se.expr,
8208 null_pointer_node);
8210 /* We need to know if the argument of a conversion function is a
8211 variable, so that the correct lower bound can be used. */
8212 if (expr->expr_type == EXPR_FUNCTION
8213 && expr->value.function.isym
8214 && expr->value.function.isym->conversion
8215 && expr->value.function.actual->expr
8216 && expr->value.function.actual->expr->expr_type == EXPR_VARIABLE)
8217 arg = expr->value.function.actual->expr;
8219 /* Obtain the array spec of full array references. */
8220 if (arg)
8221 as = gfc_get_full_arrayspec_from_expr (arg);
8222 else
8223 as = gfc_get_full_arrayspec_from_expr (expr);
8225 /* Shift the lbound and ubound of temporaries to being unity,
8226 rather than zero, based. Always calculate the offset. */
8227 offset = gfc_conv_descriptor_offset_get (dest);
8228 gfc_add_modify (&block, offset, gfc_index_zero_node);
8229 tmp2 =gfc_create_var (gfc_array_index_type, NULL);
8231 for (n = 0; n < expr->rank; n++)
8233 tree span;
8234 tree lbound;
8236 /* Obtain the correct lbound - ISO/IEC TR 15581:2001 page 9.
8237 TODO It looks as if gfc_conv_expr_descriptor should return
8238 the correct bounds and that the following should not be
8239 necessary. This would simplify gfc_conv_intrinsic_bound
8240 as well. */
8241 if (as && as->lower[n])
8243 gfc_se lbse;
8244 gfc_init_se (&lbse, NULL);
8245 gfc_conv_expr (&lbse, as->lower[n]);
8246 gfc_add_block_to_block (&block, &lbse.pre);
8247 lbound = gfc_evaluate_now (lbse.expr, &block);
8249 else if (as && arg)
8251 tmp = gfc_get_symbol_decl (arg->symtree->n.sym);
8252 lbound = gfc_conv_descriptor_lbound_get (tmp,
8253 gfc_rank_cst[n]);
8255 else if (as)
8256 lbound = gfc_conv_descriptor_lbound_get (dest,
8257 gfc_rank_cst[n]);
8258 else
8259 lbound = gfc_index_one_node;
8261 lbound = fold_convert (gfc_array_index_type, lbound);
8263 /* Shift the bounds and set the offset accordingly. */
8264 tmp = gfc_conv_descriptor_ubound_get (dest, gfc_rank_cst[n]);
8265 span = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
8266 tmp, gfc_conv_descriptor_lbound_get (dest, gfc_rank_cst[n]));
8267 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
8268 span, lbound);
8269 gfc_conv_descriptor_ubound_set (&block, dest,
8270 gfc_rank_cst[n], tmp);
8271 gfc_conv_descriptor_lbound_set (&block, dest,
8272 gfc_rank_cst[n], lbound);
8274 tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
8275 gfc_conv_descriptor_lbound_get (dest,
8276 gfc_rank_cst[n]),
8277 gfc_conv_descriptor_stride_get (dest,
8278 gfc_rank_cst[n]));
8279 gfc_add_modify (&block, tmp2, tmp);
8280 tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
8281 offset, tmp2);
8282 gfc_conv_descriptor_offset_set (&block, dest, tmp);
8285 if (arg)
8287 /* If a conversion expression has a null data pointer
8288 argument, nullify the allocatable component. */
8289 tree non_null_expr;
8290 tree null_expr;
8292 if (arg->symtree->n.sym->attr.allocatable
8293 || arg->symtree->n.sym->attr.pointer)
8295 non_null_expr = gfc_finish_block (&block);
8296 gfc_start_block (&block);
8297 gfc_conv_descriptor_data_set (&block, dest,
8298 null_pointer_node);
8299 null_expr = gfc_finish_block (&block);
8300 tmp = gfc_conv_descriptor_data_get (arg->symtree->n.sym->backend_decl);
8301 tmp = build2_loc (input_location, EQ_EXPR, logical_type_node, tmp,
8302 fold_convert (TREE_TYPE (tmp), null_pointer_node));
8303 return build3_v (COND_EXPR, tmp,
8304 null_expr, non_null_expr);
8308 return gfc_finish_block (&block);
8312 /* Allocate or reallocate scalar component, as necessary. */
8314 static void
8315 alloc_scalar_allocatable_for_subcomponent_assignment (stmtblock_t *block,
8316 tree comp,
8317 gfc_component *cm,
8318 gfc_expr *expr2,
8319 gfc_symbol *sym)
8321 tree tmp;
8322 tree ptr;
8323 tree size;
8324 tree size_in_bytes;
8325 tree lhs_cl_size = NULL_TREE;
8327 if (!comp)
8328 return;
8330 if (!expr2 || expr2->rank)
8331 return;
8333 realloc_lhs_warning (expr2->ts.type, false, &expr2->where);
8335 if (cm->ts.type == BT_CHARACTER && cm->ts.deferred)
8337 char name[GFC_MAX_SYMBOL_LEN+9];
8338 gfc_component *strlen;
8339 /* Use the rhs string length and the lhs element size. */
8340 gcc_assert (expr2->ts.type == BT_CHARACTER);
8341 if (!expr2->ts.u.cl->backend_decl)
8343 gfc_conv_string_length (expr2->ts.u.cl, expr2, block);
8344 gcc_assert (expr2->ts.u.cl->backend_decl);
8347 size = expr2->ts.u.cl->backend_decl;
8349 /* Ensure that cm->ts.u.cl->backend_decl is a componentref to _%s_length
8350 component. */
8351 sprintf (name, "_%s_length", cm->name);
8352 strlen = gfc_find_component (sym, name, true, true, NULL);
8353 lhs_cl_size = fold_build3_loc (input_location, COMPONENT_REF,
8354 gfc_charlen_type_node,
8355 TREE_OPERAND (comp, 0),
8356 strlen->backend_decl, NULL_TREE);
8358 tmp = TREE_TYPE (gfc_typenode_for_spec (&cm->ts));
8359 tmp = TYPE_SIZE_UNIT (tmp);
8360 size_in_bytes = fold_build2_loc (input_location, MULT_EXPR,
8361 TREE_TYPE (tmp), tmp,
8362 fold_convert (TREE_TYPE (tmp), size));
8364 else if (cm->ts.type == BT_CLASS)
8366 gcc_assert (expr2->ts.type == BT_CLASS || expr2->ts.type == BT_DERIVED);
8367 if (expr2->ts.type == BT_DERIVED)
8369 tmp = gfc_get_symbol_decl (expr2->ts.u.derived);
8370 size = TYPE_SIZE_UNIT (tmp);
8372 else
8374 gfc_expr *e2vtab;
8375 gfc_se se;
8376 e2vtab = gfc_find_and_cut_at_last_class_ref (expr2);
8377 gfc_add_vptr_component (e2vtab);
8378 gfc_add_size_component (e2vtab);
8379 gfc_init_se (&se, NULL);
8380 gfc_conv_expr (&se, e2vtab);
8381 gfc_add_block_to_block (block, &se.pre);
8382 size = fold_convert (size_type_node, se.expr);
8383 gfc_free_expr (e2vtab);
8385 size_in_bytes = size;
8387 else
8389 /* Otherwise use the length in bytes of the rhs. */
8390 size = TYPE_SIZE_UNIT (gfc_typenode_for_spec (&cm->ts));
8391 size_in_bytes = size;
8394 size_in_bytes = fold_build2_loc (input_location, MAX_EXPR, size_type_node,
8395 size_in_bytes, size_one_node);
8397 if (cm->ts.type == BT_DERIVED && cm->ts.u.derived->attr.alloc_comp)
8399 tmp = build_call_expr_loc (input_location,
8400 builtin_decl_explicit (BUILT_IN_CALLOC),
8401 2, build_one_cst (size_type_node),
8402 size_in_bytes);
8403 tmp = fold_convert (TREE_TYPE (comp), tmp);
8404 gfc_add_modify (block, comp, tmp);
8406 else
8408 tmp = build_call_expr_loc (input_location,
8409 builtin_decl_explicit (BUILT_IN_MALLOC),
8410 1, size_in_bytes);
8411 if (GFC_CLASS_TYPE_P (TREE_TYPE (comp)))
8412 ptr = gfc_class_data_get (comp);
8413 else
8414 ptr = comp;
8415 tmp = fold_convert (TREE_TYPE (ptr), tmp);
8416 gfc_add_modify (block, ptr, tmp);
8419 if (cm->ts.type == BT_CHARACTER && cm->ts.deferred)
8420 /* Update the lhs character length. */
8421 gfc_add_modify (block, lhs_cl_size,
8422 fold_convert (TREE_TYPE (lhs_cl_size), size));
8426 /* Assign a single component of a derived type constructor. */
8428 static tree
8429 gfc_trans_subcomponent_assign (tree dest, gfc_component * cm, gfc_expr * expr,
8430 gfc_symbol *sym, bool init)
8432 gfc_se se;
8433 gfc_se lse;
8434 stmtblock_t block;
8435 tree tmp;
8436 tree vtab;
8438 gfc_start_block (&block);
8440 if (cm->attr.pointer || cm->attr.proc_pointer)
8442 /* Only care about pointers here, not about allocatables. */
8443 gfc_init_se (&se, NULL);
8444 /* Pointer component. */
8445 if ((cm->attr.dimension || cm->attr.codimension)
8446 && !cm->attr.proc_pointer)
8448 /* Array pointer. */
8449 if (expr->expr_type == EXPR_NULL)
8450 gfc_conv_descriptor_data_set (&block, dest, null_pointer_node);
8451 else
8453 se.direct_byref = 1;
8454 se.expr = dest;
8455 gfc_conv_expr_descriptor (&se, expr);
8456 gfc_add_block_to_block (&block, &se.pre);
8457 gfc_add_block_to_block (&block, &se.post);
8460 else
8462 /* Scalar pointers. */
8463 se.want_pointer = 1;
8464 gfc_conv_expr (&se, expr);
8465 gfc_add_block_to_block (&block, &se.pre);
8467 if (expr->symtree && expr->symtree->n.sym->attr.proc_pointer
8468 && expr->symtree->n.sym->attr.dummy)
8469 se.expr = build_fold_indirect_ref_loc (input_location, se.expr);
8471 gfc_add_modify (&block, dest,
8472 fold_convert (TREE_TYPE (dest), se.expr));
8473 gfc_add_block_to_block (&block, &se.post);
8476 else if (cm->ts.type == BT_CLASS && expr->expr_type == EXPR_NULL)
8478 /* NULL initialization for CLASS components. */
8479 tmp = gfc_trans_structure_assign (dest,
8480 gfc_class_initializer (&cm->ts, expr),
8481 false);
8482 gfc_add_expr_to_block (&block, tmp);
8484 else if ((cm->attr.dimension || cm->attr.codimension)
8485 && !cm->attr.proc_pointer)
8487 if (cm->attr.allocatable && expr->expr_type == EXPR_NULL)
8488 gfc_conv_descriptor_data_set (&block, dest, null_pointer_node);
8489 else if (cm->attr.allocatable || cm->attr.pdt_array)
8491 tmp = gfc_trans_alloc_subarray_assign (dest, cm, expr);
8492 gfc_add_expr_to_block (&block, tmp);
8494 else
8496 tmp = gfc_trans_subarray_assign (dest, cm, expr);
8497 gfc_add_expr_to_block (&block, tmp);
8500 else if (cm->ts.type == BT_CLASS
8501 && CLASS_DATA (cm)->attr.dimension
8502 && CLASS_DATA (cm)->attr.allocatable
8503 && expr->ts.type == BT_DERIVED)
8505 vtab = gfc_get_symbol_decl (gfc_find_vtab (&expr->ts));
8506 vtab = gfc_build_addr_expr (NULL_TREE, vtab);
8507 tmp = gfc_class_vptr_get (dest);
8508 gfc_add_modify (&block, tmp,
8509 fold_convert (TREE_TYPE (tmp), vtab));
8510 tmp = gfc_class_data_get (dest);
8511 tmp = gfc_trans_alloc_subarray_assign (tmp, cm, expr);
8512 gfc_add_expr_to_block (&block, tmp);
8514 else if (init && cm->attr.allocatable && expr->expr_type == EXPR_NULL)
8516 /* NULL initialization for allocatable components. */
8517 gfc_add_modify (&block, dest, fold_convert (TREE_TYPE (dest),
8518 null_pointer_node));
8520 else if (init && (cm->attr.allocatable
8521 || (cm->ts.type == BT_CLASS && CLASS_DATA (cm)->attr.allocatable
8522 && expr->ts.type != BT_CLASS)))
8524 /* Take care about non-array allocatable components here. The alloc_*
8525 routine below is motivated by the alloc_scalar_allocatable_for_
8526 assignment() routine, but with the realloc portions removed and
8527 different input. */
8528 alloc_scalar_allocatable_for_subcomponent_assignment (&block,
8529 dest,
8531 expr,
8532 sym);
8533 /* The remainder of these instructions follow the if (cm->attr.pointer)
8534 if (!cm->attr.dimension) part above. */
8535 gfc_init_se (&se, NULL);
8536 gfc_conv_expr (&se, expr);
8537 gfc_add_block_to_block (&block, &se.pre);
8539 if (expr->symtree && expr->symtree->n.sym->attr.proc_pointer
8540 && expr->symtree->n.sym->attr.dummy)
8541 se.expr = build_fold_indirect_ref_loc (input_location, se.expr);
8543 if (cm->ts.type == BT_CLASS && expr->ts.type == BT_DERIVED)
8545 tmp = gfc_class_data_get (dest);
8546 tmp = build_fold_indirect_ref_loc (input_location, tmp);
8547 vtab = gfc_get_symbol_decl (gfc_find_vtab (&expr->ts));
8548 vtab = gfc_build_addr_expr (NULL_TREE, vtab);
8549 gfc_add_modify (&block, gfc_class_vptr_get (dest),
8550 fold_convert (TREE_TYPE (gfc_class_vptr_get (dest)), vtab));
8552 else
8553 tmp = build_fold_indirect_ref_loc (input_location, dest);
8555 /* For deferred strings insert a memcpy. */
8556 if (cm->ts.type == BT_CHARACTER && cm->ts.deferred)
8558 tree size;
8559 gcc_assert (se.string_length || expr->ts.u.cl->backend_decl);
8560 size = size_of_string_in_bytes (cm->ts.kind, se.string_length
8561 ? se.string_length
8562 : expr->ts.u.cl->backend_decl);
8563 tmp = gfc_build_memcpy_call (tmp, se.expr, size);
8564 gfc_add_expr_to_block (&block, tmp);
8566 else
8567 gfc_add_modify (&block, tmp,
8568 fold_convert (TREE_TYPE (tmp), se.expr));
8569 gfc_add_block_to_block (&block, &se.post);
8571 else if (expr->ts.type == BT_UNION)
8573 tree tmp;
8574 gfc_constructor *c = gfc_constructor_first (expr->value.constructor);
8575 /* We mark that the entire union should be initialized with a contrived
8576 EXPR_NULL expression at the beginning. */
8577 if (c != NULL && c->n.component == NULL
8578 && c->expr != NULL && c->expr->expr_type == EXPR_NULL)
8580 tmp = build2_loc (input_location, MODIFY_EXPR, void_type_node,
8581 dest, build_constructor (TREE_TYPE (dest), NULL));
8582 gfc_add_expr_to_block (&block, tmp);
8583 c = gfc_constructor_next (c);
8585 /* The following constructor expression, if any, represents a specific
8586 map intializer, as given by the user. */
8587 if (c != NULL && c->expr != NULL)
8589 gcc_assert (expr->expr_type == EXPR_STRUCTURE);
8590 tmp = gfc_trans_structure_assign (dest, expr, expr->symtree != NULL);
8591 gfc_add_expr_to_block (&block, tmp);
8594 else if (expr->ts.type == BT_DERIVED && expr->ts.f90_type != BT_VOID)
8596 if (expr->expr_type != EXPR_STRUCTURE)
8598 tree dealloc = NULL_TREE;
8599 gfc_init_se (&se, NULL);
8600 gfc_conv_expr (&se, expr);
8601 gfc_add_block_to_block (&block, &se.pre);
8602 /* Prevent repeat evaluations in gfc_copy_alloc_comp by fixing the
8603 expression in a temporary variable and deallocate the allocatable
8604 components. Then we can the copy the expression to the result. */
8605 if (cm->ts.u.derived->attr.alloc_comp
8606 && expr->expr_type != EXPR_VARIABLE)
8608 se.expr = gfc_evaluate_now (se.expr, &block);
8609 dealloc = gfc_deallocate_alloc_comp (cm->ts.u.derived, se.expr,
8610 expr->rank);
8612 gfc_add_modify (&block, dest,
8613 fold_convert (TREE_TYPE (dest), se.expr));
8614 if (cm->ts.u.derived->attr.alloc_comp
8615 && expr->expr_type != EXPR_NULL)
8617 // TODO: Fix caf_mode
8618 tmp = gfc_copy_alloc_comp (cm->ts.u.derived, se.expr,
8619 dest, expr->rank, 0);
8620 gfc_add_expr_to_block (&block, tmp);
8621 if (dealloc != NULL_TREE)
8622 gfc_add_expr_to_block (&block, dealloc);
8624 gfc_add_block_to_block (&block, &se.post);
8626 else
8628 /* Nested constructors. */
8629 tmp = gfc_trans_structure_assign (dest, expr, expr->symtree != NULL);
8630 gfc_add_expr_to_block (&block, tmp);
8633 else if (gfc_deferred_strlen (cm, &tmp))
8635 tree strlen;
8636 strlen = tmp;
8637 gcc_assert (strlen);
8638 strlen = fold_build3_loc (input_location, COMPONENT_REF,
8639 TREE_TYPE (strlen),
8640 TREE_OPERAND (dest, 0),
8641 strlen, NULL_TREE);
8643 if (expr->expr_type == EXPR_NULL)
8645 tmp = build_int_cst (TREE_TYPE (cm->backend_decl), 0);
8646 gfc_add_modify (&block, dest, tmp);
8647 tmp = build_int_cst (TREE_TYPE (strlen), 0);
8648 gfc_add_modify (&block, strlen, tmp);
8650 else
8652 tree size;
8653 gfc_init_se (&se, NULL);
8654 gfc_conv_expr (&se, expr);
8655 size = size_of_string_in_bytes (cm->ts.kind, se.string_length);
8656 tmp = build_call_expr_loc (input_location,
8657 builtin_decl_explicit (BUILT_IN_MALLOC),
8658 1, size);
8659 gfc_add_modify (&block, dest,
8660 fold_convert (TREE_TYPE (dest), tmp));
8661 gfc_add_modify (&block, strlen,
8662 fold_convert (TREE_TYPE (strlen), se.string_length));
8663 tmp = gfc_build_memcpy_call (dest, se.expr, size);
8664 gfc_add_expr_to_block (&block, tmp);
8667 else if (!cm->attr.artificial)
8669 /* Scalar component (excluding deferred parameters). */
8670 gfc_init_se (&se, NULL);
8671 gfc_init_se (&lse, NULL);
8673 gfc_conv_expr (&se, expr);
8674 if (cm->ts.type == BT_CHARACTER)
8675 lse.string_length = cm->ts.u.cl->backend_decl;
8676 lse.expr = dest;
8677 tmp = gfc_trans_scalar_assign (&lse, &se, cm->ts, false, false);
8678 gfc_add_expr_to_block (&block, tmp);
8680 return gfc_finish_block (&block);
8683 /* Assign a derived type constructor to a variable. */
8685 tree
8686 gfc_trans_structure_assign (tree dest, gfc_expr * expr, bool init, bool coarray)
8688 gfc_constructor *c;
8689 gfc_component *cm;
8690 stmtblock_t block;
8691 tree field;
8692 tree tmp;
8693 gfc_se se;
8695 gfc_start_block (&block);
8697 if (expr->ts.u.derived->from_intmod == INTMOD_ISO_C_BINDING
8698 && (expr->ts.u.derived->intmod_sym_id == ISOCBINDING_PTR
8699 || expr->ts.u.derived->intmod_sym_id == ISOCBINDING_FUNPTR))
8701 gfc_se lse;
8703 gfc_init_se (&se, NULL);
8704 gfc_init_se (&lse, NULL);
8705 gfc_conv_expr (&se, gfc_constructor_first (expr->value.constructor)->expr);
8706 lse.expr = dest;
8707 gfc_add_modify (&block, lse.expr,
8708 fold_convert (TREE_TYPE (lse.expr), se.expr));
8710 return gfc_finish_block (&block);
8713 /* Make sure that the derived type has been completely built. */
8714 if (!expr->ts.u.derived->backend_decl
8715 || !TYPE_FIELDS (expr->ts.u.derived->backend_decl))
8717 tmp = gfc_typenode_for_spec (&expr->ts);
8718 gcc_assert (tmp);
8721 cm = expr->ts.u.derived->components;
8724 if (coarray)
8725 gfc_init_se (&se, NULL);
8727 for (c = gfc_constructor_first (expr->value.constructor);
8728 c; c = gfc_constructor_next (c), cm = cm->next)
8730 /* Skip absent members in default initializers. */
8731 if (!c->expr && !cm->attr.allocatable)
8732 continue;
8734 /* Register the component with the caf-lib before it is initialized.
8735 Register only allocatable components, that are not coarray'ed
8736 components (%comp[*]). Only register when the constructor is not the
8737 null-expression. */
8738 if (coarray && !cm->attr.codimension
8739 && (cm->attr.allocatable || cm->attr.pointer)
8740 && (!c->expr || c->expr->expr_type == EXPR_NULL))
8742 tree token, desc, size;
8743 bool is_array = cm->ts.type == BT_CLASS
8744 ? CLASS_DATA (cm)->attr.dimension : cm->attr.dimension;
8746 field = cm->backend_decl;
8747 field = fold_build3_loc (input_location, COMPONENT_REF,
8748 TREE_TYPE (field), dest, field, NULL_TREE);
8749 if (cm->ts.type == BT_CLASS)
8750 field = gfc_class_data_get (field);
8752 token = is_array ? gfc_conv_descriptor_token (field)
8753 : fold_build3_loc (input_location, COMPONENT_REF,
8754 TREE_TYPE (cm->caf_token), dest,
8755 cm->caf_token, NULL_TREE);
8757 if (is_array)
8759 /* The _caf_register routine looks at the rank of the array
8760 descriptor to decide whether the data registered is an array
8761 or not. */
8762 int rank = cm->ts.type == BT_CLASS ? CLASS_DATA (cm)->as->rank
8763 : cm->as->rank;
8764 /* When the rank is not known just set a positive rank, which
8765 suffices to recognize the data as array. */
8766 if (rank < 0)
8767 rank = 1;
8768 size = build_zero_cst (size_type_node);
8769 desc = field;
8770 gfc_add_modify (&block, gfc_conv_descriptor_rank (desc),
8771 build_int_cst (signed_char_type_node, rank));
8773 else
8775 desc = gfc_conv_scalar_to_descriptor (&se, field,
8776 cm->ts.type == BT_CLASS
8777 ? CLASS_DATA (cm)->attr
8778 : cm->attr);
8779 size = TYPE_SIZE_UNIT (TREE_TYPE (field));
8781 gfc_add_block_to_block (&block, &se.pre);
8782 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_register,
8783 7, size, build_int_cst (
8784 integer_type_node,
8785 GFC_CAF_COARRAY_ALLOC_REGISTER_ONLY),
8786 gfc_build_addr_expr (pvoid_type_node,
8787 token),
8788 gfc_build_addr_expr (NULL_TREE, desc),
8789 null_pointer_node, null_pointer_node,
8790 integer_zero_node);
8791 gfc_add_expr_to_block (&block, tmp);
8793 field = cm->backend_decl;
8794 gcc_assert(field);
8795 tmp = fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field),
8796 dest, field, NULL_TREE);
8797 if (!c->expr)
8799 gfc_expr *e = gfc_get_null_expr (NULL);
8800 tmp = gfc_trans_subcomponent_assign (tmp, cm, e, expr->ts.u.derived,
8801 init);
8802 gfc_free_expr (e);
8804 else
8805 tmp = gfc_trans_subcomponent_assign (tmp, cm, c->expr,
8806 expr->ts.u.derived, init);
8807 gfc_add_expr_to_block (&block, tmp);
8809 return gfc_finish_block (&block);
8812 void
8813 gfc_conv_union_initializer (vec<constructor_elt, va_gc> *v,
8814 gfc_component *un, gfc_expr *init)
8816 gfc_constructor *ctor;
8818 if (un->ts.type != BT_UNION || un == NULL || init == NULL)
8819 return;
8821 ctor = gfc_constructor_first (init->value.constructor);
8823 if (ctor == NULL || ctor->expr == NULL)
8824 return;
8826 gcc_assert (init->expr_type == EXPR_STRUCTURE);
8828 /* If we have an 'initialize all' constructor, do it first. */
8829 if (ctor->expr->expr_type == EXPR_NULL)
8831 tree union_type = TREE_TYPE (un->backend_decl);
8832 tree val = build_constructor (union_type, NULL);
8833 CONSTRUCTOR_APPEND_ELT (v, un->backend_decl, val);
8834 ctor = gfc_constructor_next (ctor);
8837 /* Add the map initializer on top. */
8838 if (ctor != NULL && ctor->expr != NULL)
8840 gcc_assert (ctor->expr->expr_type == EXPR_STRUCTURE);
8841 tree val = gfc_conv_initializer (ctor->expr, &un->ts,
8842 TREE_TYPE (un->backend_decl),
8843 un->attr.dimension, un->attr.pointer,
8844 un->attr.proc_pointer);
8845 CONSTRUCTOR_APPEND_ELT (v, un->backend_decl, val);
8849 /* Build an expression for a constructor. If init is nonzero then
8850 this is part of a static variable initializer. */
8852 void
8853 gfc_conv_structure (gfc_se * se, gfc_expr * expr, int init)
8855 gfc_constructor *c;
8856 gfc_component *cm;
8857 tree val;
8858 tree type;
8859 tree tmp;
8860 vec<constructor_elt, va_gc> *v = NULL;
8862 gcc_assert (se->ss == NULL);
8863 gcc_assert (expr->expr_type == EXPR_STRUCTURE);
8864 type = gfc_typenode_for_spec (&expr->ts);
8866 if (!init)
8868 /* Create a temporary variable and fill it in. */
8869 se->expr = gfc_create_var (type, expr->ts.u.derived->name);
8870 /* The symtree in expr is NULL, if the code to generate is for
8871 initializing the static members only. */
8872 tmp = gfc_trans_structure_assign (se->expr, expr, expr->symtree != NULL,
8873 se->want_coarray);
8874 gfc_add_expr_to_block (&se->pre, tmp);
8875 return;
8878 cm = expr->ts.u.derived->components;
8880 for (c = gfc_constructor_first (expr->value.constructor);
8881 c; c = gfc_constructor_next (c), cm = cm->next)
8883 /* Skip absent members in default initializers and allocatable
8884 components. Although the latter have a default initializer
8885 of EXPR_NULL,... by default, the static nullify is not needed
8886 since this is done every time we come into scope. */
8887 if (!c->expr || (cm->attr.allocatable && cm->attr.flavor != FL_PROCEDURE))
8888 continue;
8890 if (cm->initializer && cm->initializer->expr_type != EXPR_NULL
8891 && strcmp (cm->name, "_extends") == 0
8892 && cm->initializer->symtree)
8894 tree vtab;
8895 gfc_symbol *vtabs;
8896 vtabs = cm->initializer->symtree->n.sym;
8897 vtab = gfc_build_addr_expr (NULL_TREE, gfc_get_symbol_decl (vtabs));
8898 vtab = unshare_expr_without_location (vtab);
8899 CONSTRUCTOR_APPEND_ELT (v, cm->backend_decl, vtab);
8901 else if (cm->ts.u.derived && strcmp (cm->name, "_size") == 0)
8903 val = TYPE_SIZE_UNIT (gfc_get_derived_type (cm->ts.u.derived));
8904 CONSTRUCTOR_APPEND_ELT (v, cm->backend_decl,
8905 fold_convert (TREE_TYPE (cm->backend_decl),
8906 val));
8908 else if (cm->ts.type == BT_INTEGER && strcmp (cm->name, "_len") == 0)
8909 CONSTRUCTOR_APPEND_ELT (v, cm->backend_decl,
8910 fold_convert (TREE_TYPE (cm->backend_decl),
8911 integer_zero_node));
8912 else if (cm->ts.type == BT_UNION)
8913 gfc_conv_union_initializer (v, cm, c->expr);
8914 else
8916 val = gfc_conv_initializer (c->expr, &cm->ts,
8917 TREE_TYPE (cm->backend_decl),
8918 cm->attr.dimension, cm->attr.pointer,
8919 cm->attr.proc_pointer);
8920 val = unshare_expr_without_location (val);
8922 /* Append it to the constructor list. */
8923 CONSTRUCTOR_APPEND_ELT (v, cm->backend_decl, val);
8927 se->expr = build_constructor (type, v);
8928 if (init)
8929 TREE_CONSTANT (se->expr) = 1;
8933 /* Translate a substring expression. */
8935 static void
8936 gfc_conv_substring_expr (gfc_se * se, gfc_expr * expr)
8938 gfc_ref *ref;
8940 ref = expr->ref;
8942 gcc_assert (ref == NULL || ref->type == REF_SUBSTRING);
8944 se->expr = gfc_build_wide_string_const (expr->ts.kind,
8945 expr->value.character.length,
8946 expr->value.character.string);
8948 se->string_length = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (se->expr)));
8949 TYPE_STRING_FLAG (TREE_TYPE (se->expr)) = 1;
8951 if (ref)
8952 gfc_conv_substring (se, ref, expr->ts.kind, NULL, &expr->where);
8956 /* Entry point for expression translation. Evaluates a scalar quantity.
8957 EXPR is the expression to be translated, and SE is the state structure if
8958 called from within the scalarized. */
8960 void
8961 gfc_conv_expr (gfc_se * se, gfc_expr * expr)
8963 gfc_ss *ss;
8965 ss = se->ss;
8966 if (ss && ss->info->expr == expr
8967 && (ss->info->type == GFC_SS_SCALAR
8968 || ss->info->type == GFC_SS_REFERENCE))
8970 gfc_ss_info *ss_info;
8972 ss_info = ss->info;
8973 /* Substitute a scalar expression evaluated outside the scalarization
8974 loop. */
8975 se->expr = ss_info->data.scalar.value;
8976 if (gfc_scalar_elemental_arg_saved_as_reference (ss_info))
8977 se->expr = build_fold_indirect_ref_loc (input_location, se->expr);
8979 se->string_length = ss_info->string_length;
8980 gfc_advance_se_ss_chain (se);
8981 return;
8984 /* We need to convert the expressions for the iso_c_binding derived types.
8985 C_NULL_PTR and C_NULL_FUNPTR will be made EXPR_NULL, which evaluates to
8986 null_pointer_node. C_PTR and C_FUNPTR are converted to match the
8987 typespec for the C_PTR and C_FUNPTR symbols, which has already been
8988 updated to be an integer with a kind equal to the size of a (void *). */
8989 if (expr->ts.type == BT_DERIVED && expr->ts.u.derived->ts.f90_type == BT_VOID
8990 && expr->ts.u.derived->attr.is_bind_c)
8992 if (expr->expr_type == EXPR_VARIABLE
8993 && (expr->symtree->n.sym->intmod_sym_id == ISOCBINDING_NULL_PTR
8994 || expr->symtree->n.sym->intmod_sym_id
8995 == ISOCBINDING_NULL_FUNPTR))
8997 /* Set expr_type to EXPR_NULL, which will result in
8998 null_pointer_node being used below. */
8999 expr->expr_type = EXPR_NULL;
9001 else
9003 /* Update the type/kind of the expression to be what the new
9004 type/kind are for the updated symbols of C_PTR/C_FUNPTR. */
9005 expr->ts.type = BT_INTEGER;
9006 expr->ts.f90_type = BT_VOID;
9007 expr->ts.kind = gfc_index_integer_kind;
9011 gfc_fix_class_refs (expr);
9013 switch (expr->expr_type)
9015 case EXPR_OP:
9016 gfc_conv_expr_op (se, expr);
9017 break;
9019 case EXPR_FUNCTION:
9020 gfc_conv_function_expr (se, expr);
9021 break;
9023 case EXPR_CONSTANT:
9024 gfc_conv_constant (se, expr);
9025 break;
9027 case EXPR_VARIABLE:
9028 gfc_conv_variable (se, expr);
9029 break;
9031 case EXPR_NULL:
9032 se->expr = null_pointer_node;
9033 break;
9035 case EXPR_SUBSTRING:
9036 gfc_conv_substring_expr (se, expr);
9037 break;
9039 case EXPR_STRUCTURE:
9040 gfc_conv_structure (se, expr, 0);
9041 break;
9043 case EXPR_ARRAY:
9044 gfc_conv_array_constructor_expr (se, expr);
9045 break;
9047 default:
9048 gcc_unreachable ();
9049 break;
9053 /* Like gfc_conv_expr_val, but the value is also suitable for use in the lhs
9054 of an assignment. */
9055 void
9056 gfc_conv_expr_lhs (gfc_se * se, gfc_expr * expr)
9058 gfc_conv_expr (se, expr);
9059 /* All numeric lvalues should have empty post chains. If not we need to
9060 figure out a way of rewriting an lvalue so that it has no post chain. */
9061 gcc_assert (expr->ts.type == BT_CHARACTER || !se->post.head);
9064 /* Like gfc_conv_expr, but the POST block is guaranteed to be empty for
9065 numeric expressions. Used for scalar values where inserting cleanup code
9066 is inconvenient. */
9067 void
9068 gfc_conv_expr_val (gfc_se * se, gfc_expr * expr)
9070 tree val;
9072 gcc_assert (expr->ts.type != BT_CHARACTER);
9073 gfc_conv_expr (se, expr);
9074 if (se->post.head)
9076 val = gfc_create_var (TREE_TYPE (se->expr), NULL);
9077 gfc_add_modify (&se->pre, val, se->expr);
9078 se->expr = val;
9079 gfc_add_block_to_block (&se->pre, &se->post);
9083 /* Helper to translate an expression and convert it to a particular type. */
9084 void
9085 gfc_conv_expr_type (gfc_se * se, gfc_expr * expr, tree type)
9087 gfc_conv_expr_val (se, expr);
9088 se->expr = convert (type, se->expr);
9092 /* Converts an expression so that it can be passed by reference. Scalar
9093 values only. */
9095 void
9096 gfc_conv_expr_reference (gfc_se * se, gfc_expr * expr, bool add_clobber)
9098 gfc_ss *ss;
9099 tree var;
9101 ss = se->ss;
9102 if (ss && ss->info->expr == expr
9103 && ss->info->type == GFC_SS_REFERENCE)
9105 /* Returns a reference to the scalar evaluated outside the loop
9106 for this case. */
9107 gfc_conv_expr (se, expr);
9109 if (expr->ts.type == BT_CHARACTER
9110 && expr->expr_type != EXPR_FUNCTION)
9111 gfc_conv_string_parameter (se);
9112 else
9113 se->expr = gfc_build_addr_expr (NULL_TREE, se->expr);
9115 return;
9118 if (expr->ts.type == BT_CHARACTER)
9120 gfc_conv_expr (se, expr);
9121 gfc_conv_string_parameter (se);
9122 return;
9125 if (expr->expr_type == EXPR_VARIABLE)
9127 se->want_pointer = 1;
9128 gfc_conv_expr (se, expr);
9129 if (se->post.head)
9131 var = gfc_create_var (TREE_TYPE (se->expr), NULL);
9132 gfc_add_modify (&se->pre, var, se->expr);
9133 gfc_add_block_to_block (&se->pre, &se->post);
9134 se->expr = var;
9136 else if (add_clobber && expr->ref == NULL)
9138 tree clobber;
9139 tree var;
9140 /* FIXME: This fails if var is passed by reference, see PR
9141 41453. */
9142 var = expr->symtree->n.sym->backend_decl;
9143 clobber = build_clobber (TREE_TYPE (var));
9144 gfc_add_modify (&se->pre, var, clobber);
9146 return;
9149 if (expr->expr_type == EXPR_FUNCTION
9150 && ((expr->value.function.esym
9151 && expr->value.function.esym->result
9152 && expr->value.function.esym->result->attr.pointer
9153 && !expr->value.function.esym->result->attr.dimension)
9154 || (!expr->value.function.esym && !expr->ref
9155 && expr->symtree->n.sym->attr.pointer
9156 && !expr->symtree->n.sym->attr.dimension)))
9158 se->want_pointer = 1;
9159 gfc_conv_expr (se, expr);
9160 var = gfc_create_var (TREE_TYPE (se->expr), NULL);
9161 gfc_add_modify (&se->pre, var, se->expr);
9162 se->expr = var;
9163 return;
9166 gfc_conv_expr (se, expr);
9168 /* Create a temporary var to hold the value. */
9169 if (TREE_CONSTANT (se->expr))
9171 tree tmp = se->expr;
9172 STRIP_TYPE_NOPS (tmp);
9173 var = build_decl (input_location,
9174 CONST_DECL, NULL, TREE_TYPE (tmp));
9175 DECL_INITIAL (var) = tmp;
9176 TREE_STATIC (var) = 1;
9177 pushdecl (var);
9179 else
9181 var = gfc_create_var (TREE_TYPE (se->expr), NULL);
9182 gfc_add_modify (&se->pre, var, se->expr);
9185 if (!expr->must_finalize)
9186 gfc_add_block_to_block (&se->pre, &se->post);
9188 /* Take the address of that value. */
9189 se->expr = gfc_build_addr_expr (NULL_TREE, var);
9193 /* Get the _len component for an unlimited polymorphic expression. */
9195 static tree
9196 trans_get_upoly_len (stmtblock_t *block, gfc_expr *expr)
9198 gfc_se se;
9199 gfc_ref *ref = expr->ref;
9201 gfc_init_se (&se, NULL);
9202 while (ref && ref->next)
9203 ref = ref->next;
9204 gfc_add_len_component (expr);
9205 gfc_conv_expr (&se, expr);
9206 gfc_add_block_to_block (block, &se.pre);
9207 gcc_assert (se.post.head == NULL_TREE);
9208 if (ref)
9210 gfc_free_ref_list (ref->next);
9211 ref->next = NULL;
9213 else
9215 gfc_free_ref_list (expr->ref);
9216 expr->ref = NULL;
9218 return se.expr;
9222 /* Assign _vptr and _len components as appropriate. BLOCK should be a
9223 statement-list outside of the scalarizer-loop. When code is generated, that
9224 depends on the scalarized expression, it is added to RSE.PRE.
9225 Returns le's _vptr tree and when set the len expressions in to_lenp and
9226 from_lenp to form a le%_vptr%_copy (re, le, [from_lenp, to_lenp])
9227 expression. */
9229 static tree
9230 trans_class_vptr_len_assignment (stmtblock_t *block, gfc_expr * le,
9231 gfc_expr * re, gfc_se *rse,
9232 tree * to_lenp, tree * from_lenp)
9234 gfc_se se;
9235 gfc_expr * vptr_expr;
9236 tree tmp, to_len = NULL_TREE, from_len = NULL_TREE, lhs_vptr;
9237 bool set_vptr = false, temp_rhs = false;
9238 stmtblock_t *pre = block;
9239 tree class_expr = NULL_TREE;
9241 /* Create a temporary for complicated expressions. */
9242 if (re->expr_type != EXPR_VARIABLE && re->expr_type != EXPR_NULL
9243 && rse->expr != NULL_TREE && !DECL_P (rse->expr))
9245 if (re->ts.type == BT_CLASS && !GFC_CLASS_TYPE_P (TREE_TYPE (rse->expr)))
9246 class_expr = gfc_get_class_from_expr (rse->expr);
9248 if (rse->loop)
9249 pre = &rse->loop->pre;
9250 else
9251 pre = &rse->pre;
9253 if (class_expr != NULL_TREE && UNLIMITED_POLY (re))
9255 tmp = TREE_OPERAND (rse->expr, 0);
9256 tmp = gfc_create_var (TREE_TYPE (tmp), "rhs");
9257 gfc_add_modify (&rse->pre, tmp, TREE_OPERAND (rse->expr, 0));
9259 else
9261 tmp = gfc_create_var (TREE_TYPE (rse->expr), "rhs");
9262 gfc_add_modify (&rse->pre, tmp, rse->expr);
9265 rse->expr = tmp;
9266 temp_rhs = true;
9269 /* Get the _vptr for the left-hand side expression. */
9270 gfc_init_se (&se, NULL);
9271 vptr_expr = gfc_find_and_cut_at_last_class_ref (le);
9272 if (vptr_expr != NULL && gfc_expr_attr (vptr_expr).class_ok)
9274 /* Care about _len for unlimited polymorphic entities. */
9275 if (UNLIMITED_POLY (vptr_expr)
9276 || (vptr_expr->ts.type == BT_DERIVED
9277 && vptr_expr->ts.u.derived->attr.unlimited_polymorphic))
9278 to_len = trans_get_upoly_len (block, vptr_expr);
9279 gfc_add_vptr_component (vptr_expr);
9280 set_vptr = true;
9282 else
9283 vptr_expr = gfc_lval_expr_from_sym (gfc_find_vtab (&le->ts));
9284 se.want_pointer = 1;
9285 gfc_conv_expr (&se, vptr_expr);
9286 gfc_free_expr (vptr_expr);
9287 gfc_add_block_to_block (block, &se.pre);
9288 gcc_assert (se.post.head == NULL_TREE);
9289 lhs_vptr = se.expr;
9290 STRIP_NOPS (lhs_vptr);
9292 /* Set the _vptr only when the left-hand side of the assignment is a
9293 class-object. */
9294 if (set_vptr)
9296 /* Get the vptr from the rhs expression only, when it is variable.
9297 Functions are expected to be assigned to a temporary beforehand. */
9298 vptr_expr = (re->expr_type == EXPR_VARIABLE && re->ts.type == BT_CLASS)
9299 ? gfc_find_and_cut_at_last_class_ref (re)
9300 : NULL;
9301 if (vptr_expr != NULL && vptr_expr->ts.type == BT_CLASS)
9303 if (to_len != NULL_TREE)
9305 /* Get the _len information from the rhs. */
9306 if (UNLIMITED_POLY (vptr_expr)
9307 || (vptr_expr->ts.type == BT_DERIVED
9308 && vptr_expr->ts.u.derived->attr.unlimited_polymorphic))
9309 from_len = trans_get_upoly_len (block, vptr_expr);
9311 gfc_add_vptr_component (vptr_expr);
9313 else
9315 if (re->expr_type == EXPR_VARIABLE
9316 && DECL_P (re->symtree->n.sym->backend_decl)
9317 && DECL_LANG_SPECIFIC (re->symtree->n.sym->backend_decl)
9318 && GFC_DECL_SAVED_DESCRIPTOR (re->symtree->n.sym->backend_decl)
9319 && GFC_CLASS_TYPE_P (TREE_TYPE (GFC_DECL_SAVED_DESCRIPTOR (
9320 re->symtree->n.sym->backend_decl))))
9322 vptr_expr = NULL;
9323 se.expr = gfc_class_vptr_get (GFC_DECL_SAVED_DESCRIPTOR (
9324 re->symtree->n.sym->backend_decl));
9325 if (to_len)
9326 from_len = gfc_class_len_get (GFC_DECL_SAVED_DESCRIPTOR (
9327 re->symtree->n.sym->backend_decl));
9329 else if (temp_rhs && re->ts.type == BT_CLASS)
9331 vptr_expr = NULL;
9332 if (class_expr)
9333 tmp = class_expr;
9334 else if (!GFC_CLASS_TYPE_P (TREE_TYPE (rse->expr)))
9335 tmp = gfc_get_class_from_expr (rse->expr);
9336 else
9337 tmp = rse->expr;
9339 se.expr = gfc_class_vptr_get (tmp);
9340 if (UNLIMITED_POLY (re))
9341 from_len = gfc_class_len_get (tmp);
9344 else if (re->expr_type != EXPR_NULL)
9345 /* Only when rhs is non-NULL use its declared type for vptr
9346 initialisation. */
9347 vptr_expr = gfc_lval_expr_from_sym (gfc_find_vtab (&re->ts));
9348 else
9349 /* When the rhs is NULL use the vtab of lhs' declared type. */
9350 vptr_expr = gfc_lval_expr_from_sym (gfc_find_vtab (&le->ts));
9353 if (vptr_expr)
9355 gfc_init_se (&se, NULL);
9356 se.want_pointer = 1;
9357 gfc_conv_expr (&se, vptr_expr);
9358 gfc_free_expr (vptr_expr);
9359 gfc_add_block_to_block (block, &se.pre);
9360 gcc_assert (se.post.head == NULL_TREE);
9362 gfc_add_modify (pre, lhs_vptr, fold_convert (TREE_TYPE (lhs_vptr),
9363 se.expr));
9365 if (to_len != NULL_TREE)
9367 /* The _len component needs to be set. Figure how to get the
9368 value of the right-hand side. */
9369 if (from_len == NULL_TREE)
9371 if (rse->string_length != NULL_TREE)
9372 from_len = rse->string_length;
9373 else if (re->ts.type == BT_CHARACTER && re->ts.u.cl->length)
9375 gfc_init_se (&se, NULL);
9376 gfc_conv_expr (&se, re->ts.u.cl->length);
9377 gfc_add_block_to_block (block, &se.pre);
9378 gcc_assert (se.post.head == NULL_TREE);
9379 from_len = gfc_evaluate_now (se.expr, block);
9381 else
9382 from_len = build_zero_cst (gfc_charlen_type_node);
9384 gfc_add_modify (pre, to_len, fold_convert (TREE_TYPE (to_len),
9385 from_len));
9389 /* Return the _len trees only, when requested. */
9390 if (to_lenp)
9391 *to_lenp = to_len;
9392 if (from_lenp)
9393 *from_lenp = from_len;
9394 return lhs_vptr;
9398 /* Assign tokens for pointer components. */
9400 static void
9401 trans_caf_token_assign (gfc_se *lse, gfc_se *rse, gfc_expr *expr1,
9402 gfc_expr *expr2)
9404 symbol_attribute lhs_attr, rhs_attr;
9405 tree tmp, lhs_tok, rhs_tok;
9406 /* Flag to indicated component refs on the rhs. */
9407 bool rhs_cr;
9409 lhs_attr = gfc_caf_attr (expr1);
9410 if (expr2->expr_type != EXPR_NULL)
9412 rhs_attr = gfc_caf_attr (expr2, false, &rhs_cr);
9413 if (lhs_attr.codimension && rhs_attr.codimension)
9415 lhs_tok = gfc_get_ultimate_alloc_ptr_comps_caf_token (lse, expr1);
9416 lhs_tok = build_fold_indirect_ref (lhs_tok);
9418 if (rhs_cr)
9419 rhs_tok = gfc_get_ultimate_alloc_ptr_comps_caf_token (rse, expr2);
9420 else
9422 tree caf_decl;
9423 caf_decl = gfc_get_tree_for_caf_expr (expr2);
9424 gfc_get_caf_token_offset (rse, &rhs_tok, NULL, caf_decl,
9425 NULL_TREE, NULL);
9427 tmp = build2_loc (input_location, MODIFY_EXPR, void_type_node,
9428 lhs_tok,
9429 fold_convert (TREE_TYPE (lhs_tok), rhs_tok));
9430 gfc_prepend_expr_to_block (&lse->post, tmp);
9433 else if (lhs_attr.codimension)
9435 lhs_tok = gfc_get_ultimate_alloc_ptr_comps_caf_token (lse, expr1);
9436 lhs_tok = build_fold_indirect_ref (lhs_tok);
9437 tmp = build2_loc (input_location, MODIFY_EXPR, void_type_node,
9438 lhs_tok, null_pointer_node);
9439 gfc_prepend_expr_to_block (&lse->post, tmp);
9444 /* Do everything that is needed for a CLASS function expr2. */
9446 static tree
9447 trans_class_pointer_fcn (stmtblock_t *block, gfc_se *lse, gfc_se *rse,
9448 gfc_expr *expr1, gfc_expr *expr2)
9450 tree expr1_vptr = NULL_TREE;
9451 tree tmp;
9453 gfc_conv_function_expr (rse, expr2);
9454 rse->expr = gfc_evaluate_now (rse->expr, &rse->pre);
9456 if (expr1->ts.type != BT_CLASS)
9457 rse->expr = gfc_class_data_get (rse->expr);
9458 else
9460 expr1_vptr = trans_class_vptr_len_assignment (block, expr1,
9461 expr2, rse,
9462 NULL, NULL);
9463 gfc_add_block_to_block (block, &rse->pre);
9464 tmp = gfc_create_var (TREE_TYPE (rse->expr), "ptrtemp");
9465 gfc_add_modify (&lse->pre, tmp, rse->expr);
9467 gfc_add_modify (&lse->pre, expr1_vptr,
9468 fold_convert (TREE_TYPE (expr1_vptr),
9469 gfc_class_vptr_get (tmp)));
9470 rse->expr = gfc_class_data_get (tmp);
9473 return expr1_vptr;
9477 tree
9478 gfc_trans_pointer_assign (gfc_code * code)
9480 return gfc_trans_pointer_assignment (code->expr1, code->expr2);
9484 /* Generate code for a pointer assignment. */
9486 tree
9487 gfc_trans_pointer_assignment (gfc_expr * expr1, gfc_expr * expr2)
9489 gfc_se lse;
9490 gfc_se rse;
9491 stmtblock_t block;
9492 tree desc;
9493 tree tmp;
9494 tree expr1_vptr = NULL_TREE;
9495 bool scalar, non_proc_ptr_assign;
9496 gfc_ss *ss;
9498 gfc_start_block (&block);
9500 gfc_init_se (&lse, NULL);
9502 /* Usually testing whether this is not a proc pointer assignment. */
9503 non_proc_ptr_assign = !(gfc_expr_attr (expr1).proc_pointer
9504 && expr2->expr_type == EXPR_VARIABLE
9505 && expr2->symtree->n.sym->attr.flavor == FL_PROCEDURE);
9507 /* Check whether the expression is a scalar or not; we cannot use
9508 expr1->rank as it can be nonzero for proc pointers. */
9509 ss = gfc_walk_expr (expr1);
9510 scalar = ss == gfc_ss_terminator;
9511 if (!scalar)
9512 gfc_free_ss_chain (ss);
9514 if (expr1->ts.type == BT_DERIVED && expr2->ts.type == BT_CLASS
9515 && expr2->expr_type != EXPR_FUNCTION && non_proc_ptr_assign)
9517 gfc_add_data_component (expr2);
9518 /* The following is required as gfc_add_data_component doesn't
9519 update ts.type if there is a trailing REF_ARRAY. */
9520 expr2->ts.type = BT_DERIVED;
9523 if (scalar)
9525 /* Scalar pointers. */
9526 lse.want_pointer = 1;
9527 gfc_conv_expr (&lse, expr1);
9528 gfc_init_se (&rse, NULL);
9529 rse.want_pointer = 1;
9530 if (expr2->expr_type == EXPR_FUNCTION && expr2->ts.type == BT_CLASS)
9531 trans_class_pointer_fcn (&block, &lse, &rse, expr1, expr2);
9532 else
9533 gfc_conv_expr (&rse, expr2);
9535 if (non_proc_ptr_assign && expr1->ts.type == BT_CLASS)
9537 trans_class_vptr_len_assignment (&block, expr1, expr2, &rse, NULL,
9538 NULL);
9539 lse.expr = gfc_class_data_get (lse.expr);
9542 if (expr1->symtree->n.sym->attr.proc_pointer
9543 && expr1->symtree->n.sym->attr.dummy)
9544 lse.expr = build_fold_indirect_ref_loc (input_location,
9545 lse.expr);
9547 if (expr2->symtree && expr2->symtree->n.sym->attr.proc_pointer
9548 && expr2->symtree->n.sym->attr.dummy)
9549 rse.expr = build_fold_indirect_ref_loc (input_location,
9550 rse.expr);
9552 gfc_add_block_to_block (&block, &lse.pre);
9553 gfc_add_block_to_block (&block, &rse.pre);
9555 /* Check character lengths if character expression. The test is only
9556 really added if -fbounds-check is enabled. Exclude deferred
9557 character length lefthand sides. */
9558 if (expr1->ts.type == BT_CHARACTER && expr2->expr_type != EXPR_NULL
9559 && !expr1->ts.deferred
9560 && !expr1->symtree->n.sym->attr.proc_pointer
9561 && !gfc_is_proc_ptr_comp (expr1))
9563 gcc_assert (expr2->ts.type == BT_CHARACTER);
9564 gcc_assert (lse.string_length && rse.string_length);
9565 gfc_trans_same_strlen_check ("pointer assignment", &expr1->where,
9566 lse.string_length, rse.string_length,
9567 &block);
9570 /* The assignment to an deferred character length sets the string
9571 length to that of the rhs. */
9572 if (expr1->ts.deferred)
9574 if (expr2->expr_type != EXPR_NULL && lse.string_length != NULL)
9575 gfc_add_modify (&block, lse.string_length,
9576 fold_convert (TREE_TYPE (lse.string_length),
9577 rse.string_length));
9578 else if (lse.string_length != NULL)
9579 gfc_add_modify (&block, lse.string_length,
9580 build_zero_cst (TREE_TYPE (lse.string_length)));
9583 gfc_add_modify (&block, lse.expr,
9584 fold_convert (TREE_TYPE (lse.expr), rse.expr));
9586 /* Also set the tokens for pointer components in derived typed
9587 coarrays. */
9588 if (flag_coarray == GFC_FCOARRAY_LIB)
9589 trans_caf_token_assign (&lse, &rse, expr1, expr2);
9591 gfc_add_block_to_block (&block, &rse.post);
9592 gfc_add_block_to_block (&block, &lse.post);
9594 else
9596 gfc_ref* remap;
9597 bool rank_remap;
9598 tree strlen_lhs;
9599 tree strlen_rhs = NULL_TREE;
9601 /* Array pointer. Find the last reference on the LHS and if it is an
9602 array section ref, we're dealing with bounds remapping. In this case,
9603 set it to AR_FULL so that gfc_conv_expr_descriptor does
9604 not see it and process the bounds remapping afterwards explicitly. */
9605 for (remap = expr1->ref; remap; remap = remap->next)
9606 if (!remap->next && remap->type == REF_ARRAY
9607 && remap->u.ar.type == AR_SECTION)
9608 break;
9609 rank_remap = (remap && remap->u.ar.end[0]);
9611 if (remap && expr2->expr_type == EXPR_NULL)
9613 gfc_error ("If bounds remapping is specified at %L, "
9614 "the pointer target shall not be NULL", &expr1->where);
9615 return NULL_TREE;
9618 gfc_init_se (&lse, NULL);
9619 if (remap)
9620 lse.descriptor_only = 1;
9621 gfc_conv_expr_descriptor (&lse, expr1);
9622 strlen_lhs = lse.string_length;
9623 desc = lse.expr;
9625 if (expr2->expr_type == EXPR_NULL)
9627 /* Just set the data pointer to null. */
9628 gfc_conv_descriptor_data_set (&lse.pre, lse.expr, null_pointer_node);
9630 else if (rank_remap)
9632 /* If we are rank-remapping, just get the RHS's descriptor and
9633 process this later on. */
9634 gfc_init_se (&rse, NULL);
9635 rse.direct_byref = 1;
9636 rse.byref_noassign = 1;
9638 if (expr2->expr_type == EXPR_FUNCTION && expr2->ts.type == BT_CLASS)
9639 expr1_vptr = trans_class_pointer_fcn (&block, &lse, &rse,
9640 expr1, expr2);
9641 else if (expr2->expr_type == EXPR_FUNCTION)
9643 tree bound[GFC_MAX_DIMENSIONS];
9644 int i;
9646 for (i = 0; i < expr2->rank; i++)
9647 bound[i] = NULL_TREE;
9648 tmp = gfc_typenode_for_spec (&expr2->ts);
9649 tmp = gfc_get_array_type_bounds (tmp, expr2->rank, 0,
9650 bound, bound, 0,
9651 GFC_ARRAY_POINTER_CONT, false);
9652 tmp = gfc_create_var (tmp, "ptrtemp");
9653 rse.descriptor_only = 0;
9654 rse.expr = tmp;
9655 rse.direct_byref = 1;
9656 gfc_conv_expr_descriptor (&rse, expr2);
9657 strlen_rhs = rse.string_length;
9658 rse.expr = tmp;
9660 else
9662 gfc_conv_expr_descriptor (&rse, expr2);
9663 strlen_rhs = rse.string_length;
9664 if (expr1->ts.type == BT_CLASS)
9665 expr1_vptr = trans_class_vptr_len_assignment (&block, expr1,
9666 expr2, &rse,
9667 NULL, NULL);
9670 else if (expr2->expr_type == EXPR_VARIABLE)
9672 /* Assign directly to the LHS's descriptor. */
9673 lse.descriptor_only = 0;
9674 lse.direct_byref = 1;
9675 gfc_conv_expr_descriptor (&lse, expr2);
9676 strlen_rhs = lse.string_length;
9677 gfc_init_se (&rse, NULL);
9679 if (expr1->ts.type == BT_CLASS)
9681 rse.expr = NULL_TREE;
9682 rse.string_length = strlen_rhs;
9683 trans_class_vptr_len_assignment (&block, expr1, expr2, &rse,
9684 NULL, NULL);
9687 if (remap == NULL)
9689 /* If the target is not a whole array, use the target array
9690 reference for remap. */
9691 for (remap = expr2->ref; remap; remap = remap->next)
9692 if (remap->type == REF_ARRAY
9693 && remap->u.ar.type == AR_FULL
9694 && remap->next)
9695 break;
9698 else if (expr2->expr_type == EXPR_FUNCTION && expr2->ts.type == BT_CLASS)
9700 gfc_init_se (&rse, NULL);
9701 rse.want_pointer = 1;
9702 gfc_conv_function_expr (&rse, expr2);
9703 if (expr1->ts.type != BT_CLASS)
9705 rse.expr = gfc_class_data_get (rse.expr);
9706 gfc_add_modify (&lse.pre, desc, rse.expr);
9707 /* Set the lhs span. */
9708 tmp = TREE_TYPE (rse.expr);
9709 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (tmp));
9710 tmp = fold_convert (gfc_array_index_type, tmp);
9711 gfc_conv_descriptor_span_set (&lse.pre, desc, tmp);
9713 else
9715 expr1_vptr = trans_class_vptr_len_assignment (&block, expr1,
9716 expr2, &rse, NULL,
9717 NULL);
9718 gfc_add_block_to_block (&block, &rse.pre);
9719 tmp = gfc_create_var (TREE_TYPE (rse.expr), "ptrtemp");
9720 gfc_add_modify (&lse.pre, tmp, rse.expr);
9722 gfc_add_modify (&lse.pre, expr1_vptr,
9723 fold_convert (TREE_TYPE (expr1_vptr),
9724 gfc_class_vptr_get (tmp)));
9725 rse.expr = gfc_class_data_get (tmp);
9726 gfc_add_modify (&lse.pre, desc, rse.expr);
9729 else
9731 /* Assign to a temporary descriptor and then copy that
9732 temporary to the pointer. */
9733 tmp = gfc_create_var (TREE_TYPE (desc), "ptrtemp");
9734 lse.descriptor_only = 0;
9735 lse.expr = tmp;
9736 lse.direct_byref = 1;
9737 gfc_conv_expr_descriptor (&lse, expr2);
9738 strlen_rhs = lse.string_length;
9739 gfc_add_modify (&lse.pre, desc, tmp);
9742 if (expr1->ts.type == BT_CHARACTER
9743 && expr1->symtree->n.sym->ts.deferred
9744 && expr1->symtree->n.sym->ts.u.cl->backend_decl
9745 && VAR_P (expr1->symtree->n.sym->ts.u.cl->backend_decl))
9747 tmp = expr1->symtree->n.sym->ts.u.cl->backend_decl;
9748 if (expr2->expr_type != EXPR_NULL)
9749 gfc_add_modify (&block, tmp,
9750 fold_convert (TREE_TYPE (tmp), strlen_rhs));
9751 else
9752 gfc_add_modify (&block, tmp, build_zero_cst (TREE_TYPE (tmp)));
9755 gfc_add_block_to_block (&block, &lse.pre);
9756 if (rank_remap)
9757 gfc_add_block_to_block (&block, &rse.pre);
9759 /* If we do bounds remapping, update LHS descriptor accordingly. */
9760 if (remap)
9762 int dim;
9763 gcc_assert (remap->u.ar.dimen == expr1->rank);
9765 if (rank_remap)
9767 /* Do rank remapping. We already have the RHS's descriptor
9768 converted in rse and now have to build the correct LHS
9769 descriptor for it. */
9771 tree dtype, data, span;
9772 tree offs, stride;
9773 tree lbound, ubound;
9775 /* Set dtype. */
9776 dtype = gfc_conv_descriptor_dtype (desc);
9777 tmp = gfc_get_dtype (TREE_TYPE (desc));
9778 gfc_add_modify (&block, dtype, tmp);
9780 /* Copy data pointer. */
9781 data = gfc_conv_descriptor_data_get (rse.expr);
9782 gfc_conv_descriptor_data_set (&block, desc, data);
9784 /* Copy the span. */
9785 if (TREE_CODE (rse.expr) == VAR_DECL
9786 && GFC_DECL_PTR_ARRAY_P (rse.expr))
9787 span = gfc_conv_descriptor_span_get (rse.expr);
9788 else
9790 tmp = TREE_TYPE (rse.expr);
9791 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (tmp));
9792 span = fold_convert (gfc_array_index_type, tmp);
9794 gfc_conv_descriptor_span_set (&block, desc, span);
9796 /* Copy offset but adjust it such that it would correspond
9797 to a lbound of zero. */
9798 offs = gfc_conv_descriptor_offset_get (rse.expr);
9799 for (dim = 0; dim < expr2->rank; ++dim)
9801 stride = gfc_conv_descriptor_stride_get (rse.expr,
9802 gfc_rank_cst[dim]);
9803 lbound = gfc_conv_descriptor_lbound_get (rse.expr,
9804 gfc_rank_cst[dim]);
9805 tmp = fold_build2_loc (input_location, MULT_EXPR,
9806 gfc_array_index_type, stride, lbound);
9807 offs = fold_build2_loc (input_location, PLUS_EXPR,
9808 gfc_array_index_type, offs, tmp);
9810 gfc_conv_descriptor_offset_set (&block, desc, offs);
9812 /* Set the bounds as declared for the LHS and calculate strides as
9813 well as another offset update accordingly. */
9814 stride = gfc_conv_descriptor_stride_get (rse.expr,
9815 gfc_rank_cst[0]);
9816 for (dim = 0; dim < expr1->rank; ++dim)
9818 gfc_se lower_se;
9819 gfc_se upper_se;
9821 gcc_assert (remap->u.ar.start[dim] && remap->u.ar.end[dim]);
9823 /* Convert declared bounds. */
9824 gfc_init_se (&lower_se, NULL);
9825 gfc_init_se (&upper_se, NULL);
9826 gfc_conv_expr (&lower_se, remap->u.ar.start[dim]);
9827 gfc_conv_expr (&upper_se, remap->u.ar.end[dim]);
9829 gfc_add_block_to_block (&block, &lower_se.pre);
9830 gfc_add_block_to_block (&block, &upper_se.pre);
9832 lbound = fold_convert (gfc_array_index_type, lower_se.expr);
9833 ubound = fold_convert (gfc_array_index_type, upper_se.expr);
9835 lbound = gfc_evaluate_now (lbound, &block);
9836 ubound = gfc_evaluate_now (ubound, &block);
9838 gfc_add_block_to_block (&block, &lower_se.post);
9839 gfc_add_block_to_block (&block, &upper_se.post);
9841 /* Set bounds in descriptor. */
9842 gfc_conv_descriptor_lbound_set (&block, desc,
9843 gfc_rank_cst[dim], lbound);
9844 gfc_conv_descriptor_ubound_set (&block, desc,
9845 gfc_rank_cst[dim], ubound);
9847 /* Set stride. */
9848 stride = gfc_evaluate_now (stride, &block);
9849 gfc_conv_descriptor_stride_set (&block, desc,
9850 gfc_rank_cst[dim], stride);
9852 /* Update offset. */
9853 offs = gfc_conv_descriptor_offset_get (desc);
9854 tmp = fold_build2_loc (input_location, MULT_EXPR,
9855 gfc_array_index_type, lbound, stride);
9856 offs = fold_build2_loc (input_location, MINUS_EXPR,
9857 gfc_array_index_type, offs, tmp);
9858 offs = gfc_evaluate_now (offs, &block);
9859 gfc_conv_descriptor_offset_set (&block, desc, offs);
9861 /* Update stride. */
9862 tmp = gfc_conv_array_extent_dim (lbound, ubound, NULL);
9863 stride = fold_build2_loc (input_location, MULT_EXPR,
9864 gfc_array_index_type, stride, tmp);
9867 else
9869 /* Bounds remapping. Just shift the lower bounds. */
9871 gcc_assert (expr1->rank == expr2->rank);
9873 for (dim = 0; dim < remap->u.ar.dimen; ++dim)
9875 gfc_se lbound_se;
9877 gcc_assert (!remap->u.ar.end[dim]);
9878 gfc_init_se (&lbound_se, NULL);
9879 if (remap->u.ar.start[dim])
9881 gfc_conv_expr (&lbound_se, remap->u.ar.start[dim]);
9882 gfc_add_block_to_block (&block, &lbound_se.pre);
9884 else
9885 /* This remap arises from a target that is not a whole
9886 array. The start expressions will be NULL but we need
9887 the lbounds to be one. */
9888 lbound_se.expr = gfc_index_one_node;
9889 gfc_conv_shift_descriptor_lbound (&block, desc,
9890 dim, lbound_se.expr);
9891 gfc_add_block_to_block (&block, &lbound_se.post);
9896 /* If rank remapping was done, check with -fcheck=bounds that
9897 the target is at least as large as the pointer. */
9898 if (rank_remap && (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS))
9900 tree lsize, rsize;
9901 tree fault;
9902 const char* msg;
9904 lsize = gfc_conv_descriptor_size (lse.expr, expr1->rank);
9905 rsize = gfc_conv_descriptor_size (rse.expr, expr2->rank);
9907 lsize = gfc_evaluate_now (lsize, &block);
9908 rsize = gfc_evaluate_now (rsize, &block);
9909 fault = fold_build2_loc (input_location, LT_EXPR, logical_type_node,
9910 rsize, lsize);
9912 msg = _("Target of rank remapping is too small (%ld < %ld)");
9913 gfc_trans_runtime_check (true, false, fault, &block, &expr2->where,
9914 msg, rsize, lsize);
9917 /* Check string lengths if applicable. The check is only really added
9918 to the output code if -fbounds-check is enabled. */
9919 if (expr1->ts.type == BT_CHARACTER && expr2->expr_type != EXPR_NULL)
9921 gcc_assert (expr2->ts.type == BT_CHARACTER);
9922 gcc_assert (strlen_lhs && strlen_rhs);
9923 gfc_trans_same_strlen_check ("pointer assignment", &expr1->where,
9924 strlen_lhs, strlen_rhs, &block);
9927 gfc_add_block_to_block (&block, &lse.post);
9928 if (rank_remap)
9929 gfc_add_block_to_block (&block, &rse.post);
9932 return gfc_finish_block (&block);
9936 /* Makes sure se is suitable for passing as a function string parameter. */
9937 /* TODO: Need to check all callers of this function. It may be abused. */
9939 void
9940 gfc_conv_string_parameter (gfc_se * se)
9942 tree type;
9944 if (TREE_CODE (se->expr) == STRING_CST)
9946 type = TREE_TYPE (TREE_TYPE (se->expr));
9947 se->expr = gfc_build_addr_expr (build_pointer_type (type), se->expr);
9948 return;
9951 if ((TREE_CODE (TREE_TYPE (se->expr)) == ARRAY_TYPE
9952 || TREE_CODE (TREE_TYPE (se->expr)) == INTEGER_TYPE)
9953 && TYPE_STRING_FLAG (TREE_TYPE (se->expr)))
9955 if (TREE_CODE (se->expr) != INDIRECT_REF)
9957 type = TREE_TYPE (se->expr);
9958 se->expr = gfc_build_addr_expr (build_pointer_type (type), se->expr);
9960 else
9962 type = gfc_get_character_type_len (gfc_default_character_kind,
9963 se->string_length);
9964 type = build_pointer_type (type);
9965 se->expr = gfc_build_addr_expr (type, se->expr);
9969 gcc_assert (POINTER_TYPE_P (TREE_TYPE (se->expr)));
9973 /* Generate code for assignment of scalar variables. Includes character
9974 strings and derived types with allocatable components.
9975 If you know that the LHS has no allocations, set dealloc to false.
9977 DEEP_COPY has no effect if the typespec TS is not a derived type with
9978 allocatable components. Otherwise, if it is set, an explicit copy of each
9979 allocatable component is made. This is necessary as a simple copy of the
9980 whole object would copy array descriptors as is, so that the lhs's
9981 allocatable components would point to the rhs's after the assignment.
9982 Typically, setting DEEP_COPY is necessary if the rhs is a variable, and not
9983 necessary if the rhs is a non-pointer function, as the allocatable components
9984 are not accessible by other means than the function's result after the
9985 function has returned. It is even more subtle when temporaries are involved,
9986 as the two following examples show:
9987 1. When we evaluate an array constructor, a temporary is created. Thus
9988 there is theoretically no alias possible. However, no deep copy is
9989 made for this temporary, so that if the constructor is made of one or
9990 more variable with allocatable components, those components still point
9991 to the variable's: DEEP_COPY should be set for the assignment from the
9992 temporary to the lhs in that case.
9993 2. When assigning a scalar to an array, we evaluate the scalar value out
9994 of the loop, store it into a temporary variable, and assign from that.
9995 In that case, deep copying when assigning to the temporary would be a
9996 waste of resources; however deep copies should happen when assigning from
9997 the temporary to each array element: again DEEP_COPY should be set for
9998 the assignment from the temporary to the lhs. */
10000 tree
10001 gfc_trans_scalar_assign (gfc_se * lse, gfc_se * rse, gfc_typespec ts,
10002 bool deep_copy, bool dealloc, bool in_coarray)
10004 stmtblock_t block;
10005 tree tmp;
10006 tree cond;
10008 gfc_init_block (&block);
10010 if (ts.type == BT_CHARACTER)
10012 tree rlen = NULL;
10013 tree llen = NULL;
10015 if (lse->string_length != NULL_TREE)
10017 gfc_conv_string_parameter (lse);
10018 gfc_add_block_to_block (&block, &lse->pre);
10019 llen = lse->string_length;
10022 if (rse->string_length != NULL_TREE)
10024 gfc_conv_string_parameter (rse);
10025 gfc_add_block_to_block (&block, &rse->pre);
10026 rlen = rse->string_length;
10029 gfc_trans_string_copy (&block, llen, lse->expr, ts.kind, rlen,
10030 rse->expr, ts.kind);
10032 else if (gfc_bt_struct (ts.type)
10033 && (ts.u.derived->attr.alloc_comp
10034 || (deep_copy && ts.u.derived->attr.pdt_type)))
10036 tree tmp_var = NULL_TREE;
10037 cond = NULL_TREE;
10039 /* Are the rhs and the lhs the same? */
10040 if (deep_copy)
10042 cond = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
10043 gfc_build_addr_expr (NULL_TREE, lse->expr),
10044 gfc_build_addr_expr (NULL_TREE, rse->expr));
10045 cond = gfc_evaluate_now (cond, &lse->pre);
10048 /* Deallocate the lhs allocated components as long as it is not
10049 the same as the rhs. This must be done following the assignment
10050 to prevent deallocating data that could be used in the rhs
10051 expression. */
10052 if (dealloc)
10054 tmp_var = gfc_evaluate_now (lse->expr, &lse->pre);
10055 tmp = gfc_deallocate_alloc_comp_no_caf (ts.u.derived, tmp_var, 0);
10056 if (deep_copy)
10057 tmp = build3_v (COND_EXPR, cond, build_empty_stmt (input_location),
10058 tmp);
10059 gfc_add_expr_to_block (&lse->post, tmp);
10062 gfc_add_block_to_block (&block, &rse->pre);
10063 gfc_add_block_to_block (&block, &lse->pre);
10065 gfc_add_modify (&block, lse->expr,
10066 fold_convert (TREE_TYPE (lse->expr), rse->expr));
10068 /* Restore pointer address of coarray components. */
10069 if (ts.u.derived->attr.coarray_comp && deep_copy && tmp_var != NULL_TREE)
10071 tmp = gfc_reassign_alloc_comp_caf (ts.u.derived, tmp_var, lse->expr);
10072 tmp = build3_v (COND_EXPR, cond, build_empty_stmt (input_location),
10073 tmp);
10074 gfc_add_expr_to_block (&block, tmp);
10077 /* Do a deep copy if the rhs is a variable, if it is not the
10078 same as the lhs. */
10079 if (deep_copy)
10081 int caf_mode = in_coarray ? (GFC_STRUCTURE_CAF_MODE_ENABLE_COARRAY
10082 | GFC_STRUCTURE_CAF_MODE_IN_COARRAY) : 0;
10083 tmp = gfc_copy_alloc_comp (ts.u.derived, rse->expr, lse->expr, 0,
10084 caf_mode);
10085 tmp = build3_v (COND_EXPR, cond, build_empty_stmt (input_location),
10086 tmp);
10087 gfc_add_expr_to_block (&block, tmp);
10090 else if (gfc_bt_struct (ts.type))
10092 gfc_add_block_to_block (&block, &lse->pre);
10093 gfc_add_block_to_block (&block, &rse->pre);
10094 tmp = fold_build1_loc (input_location, VIEW_CONVERT_EXPR,
10095 TREE_TYPE (lse->expr), rse->expr);
10096 gfc_add_modify (&block, lse->expr, tmp);
10098 /* If possible use the rhs vptr copy with trans_scalar_class_assign.... */
10099 else if (ts.type == BT_CLASS)
10101 gfc_add_block_to_block (&block, &lse->pre);
10102 gfc_add_block_to_block (&block, &rse->pre);
10104 if (!trans_scalar_class_assign (&block, lse, rse))
10106 /* ...otherwise assignment suffices. Note the use of VIEW_CONVERT_EXPR
10107 for the lhs which ensures that class data rhs cast as a string assigns
10108 correctly. */
10109 tmp = fold_build1_loc (input_location, VIEW_CONVERT_EXPR,
10110 TREE_TYPE (rse->expr), lse->expr);
10111 gfc_add_modify (&block, tmp, rse->expr);
10114 else if (ts.type != BT_CLASS)
10116 gfc_add_block_to_block (&block, &lse->pre);
10117 gfc_add_block_to_block (&block, &rse->pre);
10119 gfc_add_modify (&block, lse->expr,
10120 fold_convert (TREE_TYPE (lse->expr), rse->expr));
10123 gfc_add_block_to_block (&block, &lse->post);
10124 gfc_add_block_to_block (&block, &rse->post);
10126 return gfc_finish_block (&block);
10130 /* There are quite a lot of restrictions on the optimisation in using an
10131 array function assign without a temporary. */
10133 static bool
10134 arrayfunc_assign_needs_temporary (gfc_expr * expr1, gfc_expr * expr2)
10136 gfc_ref * ref;
10137 bool seen_array_ref;
10138 bool c = false;
10139 gfc_symbol *sym = expr1->symtree->n.sym;
10141 /* Play it safe with class functions assigned to a derived type. */
10142 if (gfc_is_class_array_function (expr2)
10143 && expr1->ts.type == BT_DERIVED)
10144 return true;
10146 /* The caller has already checked rank>0 and expr_type == EXPR_FUNCTION. */
10147 if (expr2->value.function.isym && !gfc_is_intrinsic_libcall (expr2))
10148 return true;
10150 /* Elemental functions are scalarized so that they don't need a
10151 temporary in gfc_trans_assignment_1, so return a true. Otherwise,
10152 they would need special treatment in gfc_trans_arrayfunc_assign. */
10153 if (expr2->value.function.esym != NULL
10154 && expr2->value.function.esym->attr.elemental)
10155 return true;
10157 /* Need a temporary if rhs is not FULL or a contiguous section. */
10158 if (expr1->ref && !(gfc_full_array_ref_p (expr1->ref, &c) || c))
10159 return true;
10161 /* Need a temporary if EXPR1 can't be expressed as a descriptor. */
10162 if (gfc_ref_needs_temporary_p (expr1->ref))
10163 return true;
10165 /* Functions returning pointers or allocatables need temporaries. */
10166 if (gfc_expr_attr (expr2).pointer
10167 || gfc_expr_attr (expr2).allocatable)
10168 return true;
10170 /* Character array functions need temporaries unless the
10171 character lengths are the same. */
10172 if (expr2->ts.type == BT_CHARACTER && expr2->rank > 0)
10174 if (expr1->ts.u.cl->length == NULL
10175 || expr1->ts.u.cl->length->expr_type != EXPR_CONSTANT)
10176 return true;
10178 if (expr2->ts.u.cl->length == NULL
10179 || expr2->ts.u.cl->length->expr_type != EXPR_CONSTANT)
10180 return true;
10182 if (mpz_cmp (expr1->ts.u.cl->length->value.integer,
10183 expr2->ts.u.cl->length->value.integer) != 0)
10184 return true;
10187 /* Check that no LHS component references appear during an array
10188 reference. This is needed because we do not have the means to
10189 span any arbitrary stride with an array descriptor. This check
10190 is not needed for the rhs because the function result has to be
10191 a complete type. */
10192 seen_array_ref = false;
10193 for (ref = expr1->ref; ref; ref = ref->next)
10195 if (ref->type == REF_ARRAY)
10196 seen_array_ref= true;
10197 else if (ref->type == REF_COMPONENT && seen_array_ref)
10198 return true;
10201 /* Check for a dependency. */
10202 if (gfc_check_fncall_dependency (expr1, INTENT_OUT,
10203 expr2->value.function.esym,
10204 expr2->value.function.actual,
10205 NOT_ELEMENTAL))
10206 return true;
10208 /* If we have reached here with an intrinsic function, we do not
10209 need a temporary except in the particular case that reallocation
10210 on assignment is active and the lhs is allocatable and a target,
10211 or a pointer which may be a subref pointer. FIXME: The last
10212 condition can go away when we use span in the intrinsics
10213 directly.*/
10214 if (expr2->value.function.isym)
10215 return (flag_realloc_lhs && sym->attr.allocatable && sym->attr.target)
10216 || (sym->attr.pointer && sym->attr.subref_array_pointer);
10218 /* If the LHS is a dummy, we need a temporary if it is not
10219 INTENT(OUT). */
10220 if (sym->attr.dummy && sym->attr.intent != INTENT_OUT)
10221 return true;
10223 /* If the lhs has been host_associated, is in common, a pointer or is
10224 a target and the function is not using a RESULT variable, aliasing
10225 can occur and a temporary is needed. */
10226 if ((sym->attr.host_assoc
10227 || sym->attr.in_common
10228 || sym->attr.pointer
10229 || sym->attr.cray_pointee
10230 || sym->attr.target)
10231 && expr2->symtree != NULL
10232 && expr2->symtree->n.sym == expr2->symtree->n.sym->result)
10233 return true;
10235 /* A PURE function can unconditionally be called without a temporary. */
10236 if (expr2->value.function.esym != NULL
10237 && expr2->value.function.esym->attr.pure)
10238 return false;
10240 /* Implicit_pure functions are those which could legally be declared
10241 to be PURE. */
10242 if (expr2->value.function.esym != NULL
10243 && expr2->value.function.esym->attr.implicit_pure)
10244 return false;
10246 if (!sym->attr.use_assoc
10247 && !sym->attr.in_common
10248 && !sym->attr.pointer
10249 && !sym->attr.target
10250 && !sym->attr.cray_pointee
10251 && expr2->value.function.esym)
10253 /* A temporary is not needed if the function is not contained and
10254 the variable is local or host associated and not a pointer or
10255 a target. */
10256 if (!expr2->value.function.esym->attr.contained)
10257 return false;
10259 /* A temporary is not needed if the lhs has never been host
10260 associated and the procedure is contained. */
10261 else if (!sym->attr.host_assoc)
10262 return false;
10264 /* A temporary is not needed if the variable is local and not
10265 a pointer, a target or a result. */
10266 if (sym->ns->parent
10267 && expr2->value.function.esym->ns == sym->ns->parent)
10268 return false;
10271 /* Default to temporary use. */
10272 return true;
10276 /* Provide the loop info so that the lhs descriptor can be built for
10277 reallocatable assignments from extrinsic function calls. */
10279 static void
10280 realloc_lhs_loop_for_fcn_call (gfc_se *se, locus *where, gfc_ss **ss,
10281 gfc_loopinfo *loop)
10283 /* Signal that the function call should not be made by
10284 gfc_conv_loop_setup. */
10285 se->ss->is_alloc_lhs = 1;
10286 gfc_init_loopinfo (loop);
10287 gfc_add_ss_to_loop (loop, *ss);
10288 gfc_add_ss_to_loop (loop, se->ss);
10289 gfc_conv_ss_startstride (loop);
10290 gfc_conv_loop_setup (loop, where);
10291 gfc_copy_loopinfo_to_se (se, loop);
10292 gfc_add_block_to_block (&se->pre, &loop->pre);
10293 gfc_add_block_to_block (&se->pre, &loop->post);
10294 se->ss->is_alloc_lhs = 0;
10298 /* For assignment to a reallocatable lhs from intrinsic functions,
10299 replace the se.expr (ie. the result) with a temporary descriptor.
10300 Null the data field so that the library allocates space for the
10301 result. Free the data of the original descriptor after the function,
10302 in case it appears in an argument expression and transfer the
10303 result to the original descriptor. */
10305 static void
10306 fcncall_realloc_result (gfc_se *se, int rank)
10308 tree desc;
10309 tree res_desc;
10310 tree tmp;
10311 tree offset;
10312 tree zero_cond;
10313 tree not_same_shape;
10314 stmtblock_t shape_block;
10315 int n;
10317 /* Use the allocation done by the library. Substitute the lhs
10318 descriptor with a copy, whose data field is nulled.*/
10319 desc = build_fold_indirect_ref_loc (input_location, se->expr);
10320 if (POINTER_TYPE_P (TREE_TYPE (desc)))
10321 desc = build_fold_indirect_ref_loc (input_location, desc);
10323 /* Unallocated, the descriptor does not have a dtype. */
10324 tmp = gfc_conv_descriptor_dtype (desc);
10325 gfc_add_modify (&se->pre, tmp, gfc_get_dtype (TREE_TYPE (desc)));
10327 res_desc = gfc_evaluate_now (desc, &se->pre);
10328 gfc_conv_descriptor_data_set (&se->pre, res_desc, null_pointer_node);
10329 se->expr = gfc_build_addr_expr (NULL_TREE, res_desc);
10331 /* Free the lhs after the function call and copy the result data to
10332 the lhs descriptor. */
10333 tmp = gfc_conv_descriptor_data_get (desc);
10334 zero_cond = fold_build2_loc (input_location, EQ_EXPR,
10335 logical_type_node, tmp,
10336 build_int_cst (TREE_TYPE (tmp), 0));
10337 zero_cond = gfc_evaluate_now (zero_cond, &se->post);
10338 tmp = gfc_call_free (tmp);
10339 gfc_add_expr_to_block (&se->post, tmp);
10341 tmp = gfc_conv_descriptor_data_get (res_desc);
10342 gfc_conv_descriptor_data_set (&se->post, desc, tmp);
10344 /* Check that the shapes are the same between lhs and expression.
10345 The evaluation of the shape is done in 'shape_block' to avoid
10346 unitialized warnings from the lhs bounds. */
10347 not_same_shape = boolean_false_node;
10348 gfc_start_block (&shape_block);
10349 for (n = 0 ; n < rank; n++)
10351 tree tmp1;
10352 tmp = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[n]);
10353 tmp1 = gfc_conv_descriptor_lbound_get (res_desc, gfc_rank_cst[n]);
10354 tmp = fold_build2_loc (input_location, MINUS_EXPR,
10355 gfc_array_index_type, tmp, tmp1);
10356 tmp1 = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[n]);
10357 tmp = fold_build2_loc (input_location, MINUS_EXPR,
10358 gfc_array_index_type, tmp, tmp1);
10359 tmp1 = gfc_conv_descriptor_ubound_get (res_desc, gfc_rank_cst[n]);
10360 tmp = fold_build2_loc (input_location, PLUS_EXPR,
10361 gfc_array_index_type, tmp, tmp1);
10362 tmp = fold_build2_loc (input_location, NE_EXPR,
10363 logical_type_node, tmp,
10364 gfc_index_zero_node);
10365 tmp = gfc_evaluate_now (tmp, &shape_block);
10366 if (n == 0)
10367 not_same_shape = tmp;
10368 else
10369 not_same_shape = fold_build2_loc (input_location, TRUTH_OR_EXPR,
10370 logical_type_node, tmp,
10371 not_same_shape);
10374 /* 'zero_cond' being true is equal to lhs not being allocated or the
10375 shapes being different. */
10376 tmp = fold_build2_loc (input_location, TRUTH_OR_EXPR, logical_type_node,
10377 zero_cond, not_same_shape);
10378 gfc_add_modify (&shape_block, zero_cond, tmp);
10379 tmp = gfc_finish_block (&shape_block);
10380 tmp = build3_v (COND_EXPR, zero_cond,
10381 build_empty_stmt (input_location), tmp);
10382 gfc_add_expr_to_block (&se->post, tmp);
10384 /* Now reset the bounds returned from the function call to bounds based
10385 on the lhs lbounds, except where the lhs is not allocated or the shapes
10386 of 'variable and 'expr' are different. Set the offset accordingly. */
10387 offset = gfc_index_zero_node;
10388 for (n = 0 ; n < rank; n++)
10390 tree lbound;
10392 lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[n]);
10393 lbound = fold_build3_loc (input_location, COND_EXPR,
10394 gfc_array_index_type, zero_cond,
10395 gfc_index_one_node, lbound);
10396 lbound = gfc_evaluate_now (lbound, &se->post);
10398 tmp = gfc_conv_descriptor_ubound_get (res_desc, gfc_rank_cst[n]);
10399 tmp = fold_build2_loc (input_location, PLUS_EXPR,
10400 gfc_array_index_type, tmp, lbound);
10401 gfc_conv_descriptor_lbound_set (&se->post, desc,
10402 gfc_rank_cst[n], lbound);
10403 gfc_conv_descriptor_ubound_set (&se->post, desc,
10404 gfc_rank_cst[n], tmp);
10406 /* Set stride and accumulate the offset. */
10407 tmp = gfc_conv_descriptor_stride_get (res_desc, gfc_rank_cst[n]);
10408 gfc_conv_descriptor_stride_set (&se->post, desc,
10409 gfc_rank_cst[n], tmp);
10410 tmp = fold_build2_loc (input_location, MULT_EXPR,
10411 gfc_array_index_type, lbound, tmp);
10412 offset = fold_build2_loc (input_location, MINUS_EXPR,
10413 gfc_array_index_type, offset, tmp);
10414 offset = gfc_evaluate_now (offset, &se->post);
10417 gfc_conv_descriptor_offset_set (&se->post, desc, offset);
10422 /* Try to translate array(:) = func (...), where func is a transformational
10423 array function, without using a temporary. Returns NULL if this isn't the
10424 case. */
10426 static tree
10427 gfc_trans_arrayfunc_assign (gfc_expr * expr1, gfc_expr * expr2)
10429 gfc_se se;
10430 gfc_ss *ss = NULL;
10431 gfc_component *comp = NULL;
10432 gfc_loopinfo loop;
10434 if (arrayfunc_assign_needs_temporary (expr1, expr2))
10435 return NULL;
10437 /* The frontend doesn't seem to bother filling in expr->symtree for intrinsic
10438 functions. */
10439 comp = gfc_get_proc_ptr_comp (expr2);
10441 if (!(expr2->value.function.isym
10442 || (comp && comp->attr.dimension)
10443 || (!comp && gfc_return_by_reference (expr2->value.function.esym)
10444 && expr2->value.function.esym->result->attr.dimension)))
10445 return NULL;
10447 gfc_init_se (&se, NULL);
10448 gfc_start_block (&se.pre);
10449 se.want_pointer = 1;
10451 gfc_conv_array_parameter (&se, expr1, false, NULL, NULL, NULL);
10453 if (expr1->ts.type == BT_DERIVED
10454 && expr1->ts.u.derived->attr.alloc_comp)
10456 tree tmp;
10457 tmp = gfc_deallocate_alloc_comp_no_caf (expr1->ts.u.derived, se.expr,
10458 expr1->rank);
10459 gfc_add_expr_to_block (&se.pre, tmp);
10462 se.direct_byref = 1;
10463 se.ss = gfc_walk_expr (expr2);
10464 gcc_assert (se.ss != gfc_ss_terminator);
10466 /* Reallocate on assignment needs the loopinfo for extrinsic functions.
10467 This is signalled to gfc_conv_procedure_call by setting is_alloc_lhs.
10468 Clearly, this cannot be done for an allocatable function result, since
10469 the shape of the result is unknown and, in any case, the function must
10470 correctly take care of the reallocation internally. For intrinsic
10471 calls, the array data is freed and the library takes care of allocation.
10472 TODO: Add logic of trans-array.c: gfc_alloc_allocatable_for_assignment
10473 to the library. */
10474 if (flag_realloc_lhs
10475 && gfc_is_reallocatable_lhs (expr1)
10476 && !gfc_expr_attr (expr1).codimension
10477 && !gfc_is_coindexed (expr1)
10478 && !(expr2->value.function.esym
10479 && expr2->value.function.esym->result->attr.allocatable))
10481 realloc_lhs_warning (expr1->ts.type, true, &expr1->where);
10483 if (!expr2->value.function.isym)
10485 ss = gfc_walk_expr (expr1);
10486 gcc_assert (ss != gfc_ss_terminator);
10488 realloc_lhs_loop_for_fcn_call (&se, &expr1->where, &ss, &loop);
10489 ss->is_alloc_lhs = 1;
10491 else
10492 fcncall_realloc_result (&se, expr1->rank);
10495 gfc_conv_function_expr (&se, expr2);
10496 gfc_add_block_to_block (&se.pre, &se.post);
10498 if (ss)
10499 gfc_cleanup_loop (&loop);
10500 else
10501 gfc_free_ss_chain (se.ss);
10503 return gfc_finish_block (&se.pre);
10507 /* Try to efficiently translate array(:) = 0. Return NULL if this
10508 can't be done. */
10510 static tree
10511 gfc_trans_zero_assign (gfc_expr * expr)
10513 tree dest, len, type;
10514 tree tmp;
10515 gfc_symbol *sym;
10517 sym = expr->symtree->n.sym;
10518 dest = gfc_get_symbol_decl (sym);
10520 type = TREE_TYPE (dest);
10521 if (POINTER_TYPE_P (type))
10522 type = TREE_TYPE (type);
10523 if (!GFC_ARRAY_TYPE_P (type))
10524 return NULL_TREE;
10526 /* Determine the length of the array. */
10527 len = GFC_TYPE_ARRAY_SIZE (type);
10528 if (!len || TREE_CODE (len) != INTEGER_CST)
10529 return NULL_TREE;
10531 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type));
10532 len = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type, len,
10533 fold_convert (gfc_array_index_type, tmp));
10535 /* If we are zeroing a local array avoid taking its address by emitting
10536 a = {} instead. */
10537 if (!POINTER_TYPE_P (TREE_TYPE (dest)))
10538 return build2_loc (input_location, MODIFY_EXPR, void_type_node,
10539 dest, build_constructor (TREE_TYPE (dest),
10540 NULL));
10542 /* Convert arguments to the correct types. */
10543 dest = fold_convert (pvoid_type_node, dest);
10544 len = fold_convert (size_type_node, len);
10546 /* Construct call to __builtin_memset. */
10547 tmp = build_call_expr_loc (input_location,
10548 builtin_decl_explicit (BUILT_IN_MEMSET),
10549 3, dest, integer_zero_node, len);
10550 return fold_convert (void_type_node, tmp);
10554 /* Helper for gfc_trans_array_copy and gfc_trans_array_constructor_copy
10555 that constructs the call to __builtin_memcpy. */
10557 tree
10558 gfc_build_memcpy_call (tree dst, tree src, tree len)
10560 tree tmp;
10562 /* Convert arguments to the correct types. */
10563 if (!POINTER_TYPE_P (TREE_TYPE (dst)))
10564 dst = gfc_build_addr_expr (pvoid_type_node, dst);
10565 else
10566 dst = fold_convert (pvoid_type_node, dst);
10568 if (!POINTER_TYPE_P (TREE_TYPE (src)))
10569 src = gfc_build_addr_expr (pvoid_type_node, src);
10570 else
10571 src = fold_convert (pvoid_type_node, src);
10573 len = fold_convert (size_type_node, len);
10575 /* Construct call to __builtin_memcpy. */
10576 tmp = build_call_expr_loc (input_location,
10577 builtin_decl_explicit (BUILT_IN_MEMCPY),
10578 3, dst, src, len);
10579 return fold_convert (void_type_node, tmp);
10583 /* Try to efficiently translate dst(:) = src(:). Return NULL if this
10584 can't be done. EXPR1 is the destination/lhs and EXPR2 is the
10585 source/rhs, both are gfc_full_array_ref_p which have been checked for
10586 dependencies. */
10588 static tree
10589 gfc_trans_array_copy (gfc_expr * expr1, gfc_expr * expr2)
10591 tree dst, dlen, dtype;
10592 tree src, slen, stype;
10593 tree tmp;
10595 dst = gfc_get_symbol_decl (expr1->symtree->n.sym);
10596 src = gfc_get_symbol_decl (expr2->symtree->n.sym);
10598 dtype = TREE_TYPE (dst);
10599 if (POINTER_TYPE_P (dtype))
10600 dtype = TREE_TYPE (dtype);
10601 stype = TREE_TYPE (src);
10602 if (POINTER_TYPE_P (stype))
10603 stype = TREE_TYPE (stype);
10605 if (!GFC_ARRAY_TYPE_P (dtype) || !GFC_ARRAY_TYPE_P (stype))
10606 return NULL_TREE;
10608 /* Determine the lengths of the arrays. */
10609 dlen = GFC_TYPE_ARRAY_SIZE (dtype);
10610 if (!dlen || TREE_CODE (dlen) != INTEGER_CST)
10611 return NULL_TREE;
10612 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (dtype));
10613 dlen = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
10614 dlen, fold_convert (gfc_array_index_type, tmp));
10616 slen = GFC_TYPE_ARRAY_SIZE (stype);
10617 if (!slen || TREE_CODE (slen) != INTEGER_CST)
10618 return NULL_TREE;
10619 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (stype));
10620 slen = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
10621 slen, fold_convert (gfc_array_index_type, tmp));
10623 /* Sanity check that they are the same. This should always be
10624 the case, as we should already have checked for conformance. */
10625 if (!tree_int_cst_equal (slen, dlen))
10626 return NULL_TREE;
10628 return gfc_build_memcpy_call (dst, src, dlen);
10632 /* Try to efficiently translate array(:) = (/ ... /). Return NULL if
10633 this can't be done. EXPR1 is the destination/lhs for which
10634 gfc_full_array_ref_p is true, and EXPR2 is the source/rhs. */
10636 static tree
10637 gfc_trans_array_constructor_copy (gfc_expr * expr1, gfc_expr * expr2)
10639 unsigned HOST_WIDE_INT nelem;
10640 tree dst, dtype;
10641 tree src, stype;
10642 tree len;
10643 tree tmp;
10645 nelem = gfc_constant_array_constructor_p (expr2->value.constructor);
10646 if (nelem == 0)
10647 return NULL_TREE;
10649 dst = gfc_get_symbol_decl (expr1->symtree->n.sym);
10650 dtype = TREE_TYPE (dst);
10651 if (POINTER_TYPE_P (dtype))
10652 dtype = TREE_TYPE (dtype);
10653 if (!GFC_ARRAY_TYPE_P (dtype))
10654 return NULL_TREE;
10656 /* Determine the lengths of the array. */
10657 len = GFC_TYPE_ARRAY_SIZE (dtype);
10658 if (!len || TREE_CODE (len) != INTEGER_CST)
10659 return NULL_TREE;
10661 /* Confirm that the constructor is the same size. */
10662 if (compare_tree_int (len, nelem) != 0)
10663 return NULL_TREE;
10665 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (dtype));
10666 len = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type, len,
10667 fold_convert (gfc_array_index_type, tmp));
10669 stype = gfc_typenode_for_spec (&expr2->ts);
10670 src = gfc_build_constant_array_constructor (expr2, stype);
10672 return gfc_build_memcpy_call (dst, src, len);
10676 /* Tells whether the expression is to be treated as a variable reference. */
10678 bool
10679 gfc_expr_is_variable (gfc_expr *expr)
10681 gfc_expr *arg;
10682 gfc_component *comp;
10683 gfc_symbol *func_ifc;
10685 if (expr->expr_type == EXPR_VARIABLE)
10686 return true;
10688 arg = gfc_get_noncopying_intrinsic_argument (expr);
10689 if (arg)
10691 gcc_assert (expr->value.function.isym->id == GFC_ISYM_TRANSPOSE);
10692 return gfc_expr_is_variable (arg);
10695 /* A data-pointer-returning function should be considered as a variable
10696 too. */
10697 if (expr->expr_type == EXPR_FUNCTION
10698 && expr->ref == NULL)
10700 if (expr->value.function.isym != NULL)
10701 return false;
10703 if (expr->value.function.esym != NULL)
10705 func_ifc = expr->value.function.esym;
10706 goto found_ifc;
10708 else
10710 gcc_assert (expr->symtree);
10711 func_ifc = expr->symtree->n.sym;
10712 goto found_ifc;
10715 gcc_unreachable ();
10718 comp = gfc_get_proc_ptr_comp (expr);
10719 if ((expr->expr_type == EXPR_PPC || expr->expr_type == EXPR_FUNCTION)
10720 && comp)
10722 func_ifc = comp->ts.interface;
10723 goto found_ifc;
10726 if (expr->expr_type == EXPR_COMPCALL)
10728 gcc_assert (!expr->value.compcall.tbp->is_generic);
10729 func_ifc = expr->value.compcall.tbp->u.specific->n.sym;
10730 goto found_ifc;
10733 return false;
10735 found_ifc:
10736 gcc_assert (func_ifc->attr.function
10737 && func_ifc->result != NULL);
10738 return func_ifc->result->attr.pointer;
10742 /* Is the lhs OK for automatic reallocation? */
10744 static bool
10745 is_scalar_reallocatable_lhs (gfc_expr *expr)
10747 gfc_ref * ref;
10749 /* An allocatable variable with no reference. */
10750 if (expr->symtree->n.sym->attr.allocatable
10751 && !expr->ref)
10752 return true;
10754 /* All that can be left are allocatable components. However, we do
10755 not check for allocatable components here because the expression
10756 could be an allocatable component of a pointer component. */
10757 if (expr->symtree->n.sym->ts.type != BT_DERIVED
10758 && expr->symtree->n.sym->ts.type != BT_CLASS)
10759 return false;
10761 /* Find an allocatable component ref last. */
10762 for (ref = expr->ref; ref; ref = ref->next)
10763 if (ref->type == REF_COMPONENT
10764 && !ref->next
10765 && ref->u.c.component->attr.allocatable)
10766 return true;
10768 return false;
10772 /* Allocate or reallocate scalar lhs, as necessary. */
10774 static void
10775 alloc_scalar_allocatable_for_assignment (stmtblock_t *block,
10776 tree string_length,
10777 gfc_expr *expr1,
10778 gfc_expr *expr2)
10781 tree cond;
10782 tree tmp;
10783 tree size;
10784 tree size_in_bytes;
10785 tree jump_label1;
10786 tree jump_label2;
10787 gfc_se lse;
10788 gfc_ref *ref;
10790 if (!expr1 || expr1->rank)
10791 return;
10793 if (!expr2 || expr2->rank)
10794 return;
10796 for (ref = expr1->ref; ref; ref = ref->next)
10797 if (ref->type == REF_SUBSTRING)
10798 return;
10800 realloc_lhs_warning (expr2->ts.type, false, &expr2->where);
10802 /* Since this is a scalar lhs, we can afford to do this. That is,
10803 there is no risk of side effects being repeated. */
10804 gfc_init_se (&lse, NULL);
10805 lse.want_pointer = 1;
10806 gfc_conv_expr (&lse, expr1);
10808 jump_label1 = gfc_build_label_decl (NULL_TREE);
10809 jump_label2 = gfc_build_label_decl (NULL_TREE);
10811 /* Do the allocation if the lhs is NULL. Otherwise go to label 1. */
10812 tmp = build_int_cst (TREE_TYPE (lse.expr), 0);
10813 cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
10814 lse.expr, tmp);
10815 tmp = build3_v (COND_EXPR, cond,
10816 build1_v (GOTO_EXPR, jump_label1),
10817 build_empty_stmt (input_location));
10818 gfc_add_expr_to_block (block, tmp);
10820 if (expr1->ts.type == BT_CHARACTER && expr1->ts.deferred)
10822 /* Use the rhs string length and the lhs element size. */
10823 size = string_length;
10824 tmp = TREE_TYPE (gfc_typenode_for_spec (&expr1->ts));
10825 tmp = TYPE_SIZE_UNIT (tmp);
10826 size_in_bytes = fold_build2_loc (input_location, MULT_EXPR,
10827 TREE_TYPE (tmp), tmp,
10828 fold_convert (TREE_TYPE (tmp), size));
10830 else
10832 /* Otherwise use the length in bytes of the rhs. */
10833 size = TYPE_SIZE_UNIT (gfc_typenode_for_spec (&expr1->ts));
10834 size_in_bytes = size;
10837 size_in_bytes = fold_build2_loc (input_location, MAX_EXPR, size_type_node,
10838 size_in_bytes, size_one_node);
10840 if (gfc_caf_attr (expr1).codimension && flag_coarray == GFC_FCOARRAY_LIB)
10842 tree caf_decl, token;
10843 gfc_se caf_se;
10844 symbol_attribute attr;
10846 gfc_clear_attr (&attr);
10847 gfc_init_se (&caf_se, NULL);
10849 caf_decl = gfc_get_tree_for_caf_expr (expr1);
10850 gfc_get_caf_token_offset (&caf_se, &token, NULL, caf_decl, NULL_TREE,
10851 NULL);
10852 gfc_add_block_to_block (block, &caf_se.pre);
10853 gfc_allocate_allocatable (block, lse.expr, size_in_bytes,
10854 gfc_build_addr_expr (NULL_TREE, token),
10855 NULL_TREE, NULL_TREE, NULL_TREE, jump_label1,
10856 expr1, 1);
10858 else if (expr1->ts.type == BT_DERIVED && expr1->ts.u.derived->attr.alloc_comp)
10860 tmp = build_call_expr_loc (input_location,
10861 builtin_decl_explicit (BUILT_IN_CALLOC),
10862 2, build_one_cst (size_type_node),
10863 size_in_bytes);
10864 tmp = fold_convert (TREE_TYPE (lse.expr), tmp);
10865 gfc_add_modify (block, lse.expr, tmp);
10867 else
10869 tmp = build_call_expr_loc (input_location,
10870 builtin_decl_explicit (BUILT_IN_MALLOC),
10871 1, size_in_bytes);
10872 tmp = fold_convert (TREE_TYPE (lse.expr), tmp);
10873 gfc_add_modify (block, lse.expr, tmp);
10876 if (expr1->ts.type == BT_CHARACTER && expr1->ts.deferred)
10878 /* Deferred characters need checking for lhs and rhs string
10879 length. Other deferred parameter variables will have to
10880 come here too. */
10881 tmp = build1_v (GOTO_EXPR, jump_label2);
10882 gfc_add_expr_to_block (block, tmp);
10884 tmp = build1_v (LABEL_EXPR, jump_label1);
10885 gfc_add_expr_to_block (block, tmp);
10887 /* For a deferred length character, reallocate if lengths of lhs and
10888 rhs are different. */
10889 if (expr1->ts.type == BT_CHARACTER && expr1->ts.deferred)
10891 cond = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
10892 lse.string_length,
10893 fold_convert (TREE_TYPE (lse.string_length),
10894 size));
10895 /* Jump past the realloc if the lengths are the same. */
10896 tmp = build3_v (COND_EXPR, cond,
10897 build1_v (GOTO_EXPR, jump_label2),
10898 build_empty_stmt (input_location));
10899 gfc_add_expr_to_block (block, tmp);
10900 tmp = build_call_expr_loc (input_location,
10901 builtin_decl_explicit (BUILT_IN_REALLOC),
10902 2, fold_convert (pvoid_type_node, lse.expr),
10903 size_in_bytes);
10904 tmp = fold_convert (TREE_TYPE (lse.expr), tmp);
10905 gfc_add_modify (block, lse.expr, tmp);
10906 tmp = build1_v (LABEL_EXPR, jump_label2);
10907 gfc_add_expr_to_block (block, tmp);
10909 /* Update the lhs character length. */
10910 size = string_length;
10911 gfc_add_modify (block, lse.string_length,
10912 fold_convert (TREE_TYPE (lse.string_length), size));
10916 /* Check for assignments of the type
10918 a = a + 4
10920 to make sure we do not check for reallocation unneccessarily. */
10923 static bool
10924 is_runtime_conformable (gfc_expr *expr1, gfc_expr *expr2)
10926 gfc_actual_arglist *a;
10927 gfc_expr *e1, *e2;
10929 switch (expr2->expr_type)
10931 case EXPR_VARIABLE:
10932 return gfc_dep_compare_expr (expr1, expr2) == 0;
10934 case EXPR_FUNCTION:
10935 if (expr2->value.function.esym
10936 && expr2->value.function.esym->attr.elemental)
10938 for (a = expr2->value.function.actual; a != NULL; a = a->next)
10940 e1 = a->expr;
10941 if (e1 && e1->rank > 0 && !is_runtime_conformable (expr1, e1))
10942 return false;
10944 return true;
10946 else if (expr2->value.function.isym
10947 && expr2->value.function.isym->elemental)
10949 for (a = expr2->value.function.actual; a != NULL; a = a->next)
10951 e1 = a->expr;
10952 if (e1 && e1->rank > 0 && !is_runtime_conformable (expr1, e1))
10953 return false;
10955 return true;
10958 break;
10960 case EXPR_OP:
10961 switch (expr2->value.op.op)
10963 case INTRINSIC_NOT:
10964 case INTRINSIC_UPLUS:
10965 case INTRINSIC_UMINUS:
10966 case INTRINSIC_PARENTHESES:
10967 return is_runtime_conformable (expr1, expr2->value.op.op1);
10969 case INTRINSIC_PLUS:
10970 case INTRINSIC_MINUS:
10971 case INTRINSIC_TIMES:
10972 case INTRINSIC_DIVIDE:
10973 case INTRINSIC_POWER:
10974 case INTRINSIC_AND:
10975 case INTRINSIC_OR:
10976 case INTRINSIC_EQV:
10977 case INTRINSIC_NEQV:
10978 case INTRINSIC_EQ:
10979 case INTRINSIC_NE:
10980 case INTRINSIC_GT:
10981 case INTRINSIC_GE:
10982 case INTRINSIC_LT:
10983 case INTRINSIC_LE:
10984 case INTRINSIC_EQ_OS:
10985 case INTRINSIC_NE_OS:
10986 case INTRINSIC_GT_OS:
10987 case INTRINSIC_GE_OS:
10988 case INTRINSIC_LT_OS:
10989 case INTRINSIC_LE_OS:
10991 e1 = expr2->value.op.op1;
10992 e2 = expr2->value.op.op2;
10994 if (e1->rank == 0 && e2->rank > 0)
10995 return is_runtime_conformable (expr1, e2);
10996 else if (e1->rank > 0 && e2->rank == 0)
10997 return is_runtime_conformable (expr1, e1);
10998 else if (e1->rank > 0 && e2->rank > 0)
10999 return is_runtime_conformable (expr1, e1)
11000 && is_runtime_conformable (expr1, e2);
11001 break;
11003 default:
11004 break;
11008 break;
11010 default:
11011 break;
11013 return false;
11017 static tree
11018 trans_class_assignment (stmtblock_t *block, gfc_expr *lhs, gfc_expr *rhs,
11019 gfc_se *lse, gfc_se *rse, bool use_vptr_copy,
11020 bool class_realloc)
11022 tree tmp, fcn, stdcopy, to_len, from_len, vptr, old_vptr;
11023 vec<tree, va_gc> *args = NULL;
11025 /* Store the old vptr so that dynamic types can be compared for
11026 reallocation to occur or not. */
11027 if (class_realloc)
11029 tmp = lse->expr;
11030 if (!GFC_CLASS_TYPE_P (TREE_TYPE (tmp)))
11031 tmp = gfc_get_class_from_expr (tmp);
11034 vptr = trans_class_vptr_len_assignment (block, lhs, rhs, rse, &to_len,
11035 &from_len);
11037 /* Generate (re)allocation of the lhs. */
11038 if (class_realloc)
11040 stmtblock_t alloc, re_alloc;
11041 tree class_han, re, size;
11043 if (tmp && GFC_CLASS_TYPE_P (TREE_TYPE (tmp)))
11044 old_vptr = gfc_evaluate_now (gfc_class_vptr_get (tmp), block);
11045 else
11046 old_vptr = build_int_cst (TREE_TYPE (vptr), 0);
11048 size = gfc_vptr_size_get (vptr);
11049 class_han = GFC_CLASS_TYPE_P (TREE_TYPE (lse->expr))
11050 ? gfc_class_data_get (lse->expr) : lse->expr;
11052 /* Allocate block. */
11053 gfc_init_block (&alloc);
11054 gfc_allocate_using_malloc (&alloc, class_han, size, NULL_TREE);
11056 /* Reallocate if dynamic types are different. */
11057 gfc_init_block (&re_alloc);
11058 re = build_call_expr_loc (input_location,
11059 builtin_decl_explicit (BUILT_IN_REALLOC), 2,
11060 fold_convert (pvoid_type_node, class_han),
11061 size);
11062 tmp = fold_build2_loc (input_location, NE_EXPR,
11063 logical_type_node, vptr, old_vptr);
11064 re = fold_build3_loc (input_location, COND_EXPR, void_type_node,
11065 tmp, re, build_empty_stmt (input_location));
11066 gfc_add_expr_to_block (&re_alloc, re);
11068 /* Allocate if _data is NULL, reallocate otherwise. */
11069 tmp = fold_build2_loc (input_location, EQ_EXPR,
11070 logical_type_node, class_han,
11071 build_int_cst (prvoid_type_node, 0));
11072 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
11073 gfc_unlikely (tmp,
11074 PRED_FORTRAN_FAIL_ALLOC),
11075 gfc_finish_block (&alloc),
11076 gfc_finish_block (&re_alloc));
11077 gfc_add_expr_to_block (&lse->pre, tmp);
11080 fcn = gfc_vptr_copy_get (vptr);
11082 tmp = GFC_CLASS_TYPE_P (TREE_TYPE (rse->expr))
11083 ? gfc_class_data_get (rse->expr) : rse->expr;
11084 if (use_vptr_copy)
11086 if (!POINTER_TYPE_P (TREE_TYPE (tmp))
11087 || INDIRECT_REF_P (tmp)
11088 || (rhs->ts.type == BT_DERIVED
11089 && rhs->ts.u.derived->attr.unlimited_polymorphic
11090 && !rhs->ts.u.derived->attr.pointer
11091 && !rhs->ts.u.derived->attr.allocatable)
11092 || (UNLIMITED_POLY (rhs)
11093 && !CLASS_DATA (rhs)->attr.pointer
11094 && !CLASS_DATA (rhs)->attr.allocatable))
11095 vec_safe_push (args, gfc_build_addr_expr (NULL_TREE, tmp));
11096 else
11097 vec_safe_push (args, tmp);
11098 tmp = GFC_CLASS_TYPE_P (TREE_TYPE (lse->expr))
11099 ? gfc_class_data_get (lse->expr) : lse->expr;
11100 if (!POINTER_TYPE_P (TREE_TYPE (tmp))
11101 || INDIRECT_REF_P (tmp)
11102 || (lhs->ts.type == BT_DERIVED
11103 && lhs->ts.u.derived->attr.unlimited_polymorphic
11104 && !lhs->ts.u.derived->attr.pointer
11105 && !lhs->ts.u.derived->attr.allocatable)
11106 || (UNLIMITED_POLY (lhs)
11107 && !CLASS_DATA (lhs)->attr.pointer
11108 && !CLASS_DATA (lhs)->attr.allocatable))
11109 vec_safe_push (args, gfc_build_addr_expr (NULL_TREE, tmp));
11110 else
11111 vec_safe_push (args, tmp);
11113 stdcopy = build_call_vec (TREE_TYPE (TREE_TYPE (fcn)), fcn, args);
11115 if (to_len != NULL_TREE && !integer_zerop (from_len))
11117 tree extcopy;
11118 vec_safe_push (args, from_len);
11119 vec_safe_push (args, to_len);
11120 extcopy = build_call_vec (TREE_TYPE (TREE_TYPE (fcn)), fcn, args);
11122 tmp = fold_build2_loc (input_location, GT_EXPR,
11123 logical_type_node, from_len,
11124 build_zero_cst (TREE_TYPE (from_len)));
11125 return fold_build3_loc (input_location, COND_EXPR,
11126 void_type_node, tmp,
11127 extcopy, stdcopy);
11129 else
11130 return stdcopy;
11132 else
11134 tree rhst = GFC_CLASS_TYPE_P (TREE_TYPE (lse->expr))
11135 ? gfc_class_data_get (lse->expr) : lse->expr;
11136 stmtblock_t tblock;
11137 gfc_init_block (&tblock);
11138 if (!POINTER_TYPE_P (TREE_TYPE (tmp)))
11139 tmp = gfc_build_addr_expr (NULL_TREE, tmp);
11140 if (!POINTER_TYPE_P (TREE_TYPE (rhst)))
11141 rhst = gfc_build_addr_expr (NULL_TREE, rhst);
11142 /* When coming from a ptr_copy lhs and rhs are swapped. */
11143 gfc_add_modify_loc (input_location, &tblock, rhst,
11144 fold_convert (TREE_TYPE (rhst), tmp));
11145 return gfc_finish_block (&tblock);
11149 /* Subroutine of gfc_trans_assignment that actually scalarizes the
11150 assignment. EXPR1 is the destination/LHS and EXPR2 is the source/RHS.
11151 init_flag indicates initialization expressions and dealloc that no
11152 deallocate prior assignment is needed (if in doubt, set true).
11153 When PTR_COPY is set and expr1 is a class type, then use the _vptr-copy
11154 routine instead of a pointer assignment. Alias resolution is only done,
11155 when MAY_ALIAS is set (the default). This flag is used by ALLOCATE()
11156 where it is known, that newly allocated memory on the lhs can never be
11157 an alias of the rhs. */
11159 static tree
11160 gfc_trans_assignment_1 (gfc_expr * expr1, gfc_expr * expr2, bool init_flag,
11161 bool dealloc, bool use_vptr_copy, bool may_alias)
11163 gfc_se lse;
11164 gfc_se rse;
11165 gfc_ss *lss;
11166 gfc_ss *lss_section;
11167 gfc_ss *rss;
11168 gfc_loopinfo loop;
11169 tree tmp;
11170 stmtblock_t block;
11171 stmtblock_t body;
11172 bool l_is_temp;
11173 bool scalar_to_array;
11174 tree string_length;
11175 int n;
11176 bool maybe_workshare = false, lhs_refs_comp = false, rhs_refs_comp = false;
11177 symbol_attribute lhs_caf_attr, rhs_caf_attr, lhs_attr;
11178 bool is_poly_assign;
11179 bool realloc_flag;
11181 /* Assignment of the form lhs = rhs. */
11182 gfc_start_block (&block);
11184 gfc_init_se (&lse, NULL);
11185 gfc_init_se (&rse, NULL);
11187 /* Walk the lhs. */
11188 lss = gfc_walk_expr (expr1);
11189 if (gfc_is_reallocatable_lhs (expr1))
11191 lss->no_bounds_check = 1;
11192 if (!(expr2->expr_type == EXPR_FUNCTION
11193 && expr2->value.function.isym != NULL
11194 && !(expr2->value.function.isym->elemental
11195 || expr2->value.function.isym->conversion)))
11196 lss->is_alloc_lhs = 1;
11198 else
11199 lss->no_bounds_check = expr1->no_bounds_check;
11201 rss = NULL;
11203 if ((expr1->ts.type == BT_DERIVED)
11204 && (gfc_is_class_array_function (expr2)
11205 || gfc_is_alloc_class_scalar_function (expr2)))
11206 expr2->must_finalize = 1;
11208 /* Checking whether a class assignment is desired is quite complicated and
11209 needed at two locations, so do it once only before the information is
11210 needed. */
11211 lhs_attr = gfc_expr_attr (expr1);
11212 is_poly_assign = (use_vptr_copy || lhs_attr.pointer
11213 || (lhs_attr.allocatable && !lhs_attr.dimension))
11214 && (expr1->ts.type == BT_CLASS
11215 || gfc_is_class_array_ref (expr1, NULL)
11216 || gfc_is_class_scalar_expr (expr1)
11217 || gfc_is_class_array_ref (expr2, NULL)
11218 || gfc_is_class_scalar_expr (expr2))
11219 && lhs_attr.flavor != FL_PROCEDURE;
11221 realloc_flag = flag_realloc_lhs
11222 && gfc_is_reallocatable_lhs (expr1)
11223 && expr2->rank
11224 && !is_runtime_conformable (expr1, expr2);
11226 /* Only analyze the expressions for coarray properties, when in coarray-lib
11227 mode. */
11228 if (flag_coarray == GFC_FCOARRAY_LIB)
11230 lhs_caf_attr = gfc_caf_attr (expr1, false, &lhs_refs_comp);
11231 rhs_caf_attr = gfc_caf_attr (expr2, false, &rhs_refs_comp);
11234 if (lss != gfc_ss_terminator)
11236 /* The assignment needs scalarization. */
11237 lss_section = lss;
11239 /* Find a non-scalar SS from the lhs. */
11240 while (lss_section != gfc_ss_terminator
11241 && lss_section->info->type != GFC_SS_SECTION)
11242 lss_section = lss_section->next;
11244 gcc_assert (lss_section != gfc_ss_terminator);
11246 /* Initialize the scalarizer. */
11247 gfc_init_loopinfo (&loop);
11249 /* Walk the rhs. */
11250 rss = gfc_walk_expr (expr2);
11251 if (rss == gfc_ss_terminator)
11252 /* The rhs is scalar. Add a ss for the expression. */
11253 rss = gfc_get_scalar_ss (gfc_ss_terminator, expr2);
11254 /* When doing a class assign, then the handle to the rhs needs to be a
11255 pointer to allow for polymorphism. */
11256 if (is_poly_assign && expr2->rank == 0 && !UNLIMITED_POLY (expr2))
11257 rss->info->type = GFC_SS_REFERENCE;
11259 rss->no_bounds_check = expr2->no_bounds_check;
11260 /* Associate the SS with the loop. */
11261 gfc_add_ss_to_loop (&loop, lss);
11262 gfc_add_ss_to_loop (&loop, rss);
11264 /* Calculate the bounds of the scalarization. */
11265 gfc_conv_ss_startstride (&loop);
11266 /* Enable loop reversal. */
11267 for (n = 0; n < GFC_MAX_DIMENSIONS; n++)
11268 loop.reverse[n] = GFC_ENABLE_REVERSE;
11269 /* Resolve any data dependencies in the statement. */
11270 if (may_alias)
11271 gfc_conv_resolve_dependencies (&loop, lss, rss);
11272 /* Setup the scalarizing loops. */
11273 gfc_conv_loop_setup (&loop, &expr2->where);
11275 /* Setup the gfc_se structures. */
11276 gfc_copy_loopinfo_to_se (&lse, &loop);
11277 gfc_copy_loopinfo_to_se (&rse, &loop);
11279 rse.ss = rss;
11280 gfc_mark_ss_chain_used (rss, 1);
11281 if (loop.temp_ss == NULL)
11283 lse.ss = lss;
11284 gfc_mark_ss_chain_used (lss, 1);
11286 else
11288 lse.ss = loop.temp_ss;
11289 gfc_mark_ss_chain_used (lss, 3);
11290 gfc_mark_ss_chain_used (loop.temp_ss, 3);
11293 /* Allow the scalarizer to workshare array assignments. */
11294 if ((ompws_flags & (OMPWS_WORKSHARE_FLAG | OMPWS_SCALARIZER_BODY))
11295 == OMPWS_WORKSHARE_FLAG
11296 && loop.temp_ss == NULL)
11298 maybe_workshare = true;
11299 ompws_flags |= OMPWS_SCALARIZER_WS | OMPWS_SCALARIZER_BODY;
11302 /* Start the scalarized loop body. */
11303 gfc_start_scalarized_body (&loop, &body);
11305 else
11306 gfc_init_block (&body);
11308 l_is_temp = (lss != gfc_ss_terminator && loop.temp_ss != NULL);
11310 /* Translate the expression. */
11311 rse.want_coarray = flag_coarray == GFC_FCOARRAY_LIB && init_flag
11312 && lhs_caf_attr.codimension;
11313 gfc_conv_expr (&rse, expr2);
11315 /* Deal with the case of a scalar class function assigned to a derived type. */
11316 if (gfc_is_alloc_class_scalar_function (expr2)
11317 && expr1->ts.type == BT_DERIVED)
11319 rse.expr = gfc_class_data_get (rse.expr);
11320 rse.expr = build_fold_indirect_ref_loc (input_location, rse.expr);
11323 /* Stabilize a string length for temporaries. */
11324 if (expr2->ts.type == BT_CHARACTER && !expr1->ts.deferred
11325 && !(VAR_P (rse.string_length)
11326 || TREE_CODE (rse.string_length) == PARM_DECL
11327 || TREE_CODE (rse.string_length) == INDIRECT_REF))
11328 string_length = gfc_evaluate_now (rse.string_length, &rse.pre);
11329 else if (expr2->ts.type == BT_CHARACTER)
11331 if (expr1->ts.deferred
11332 && gfc_expr_attr (expr1).allocatable
11333 && gfc_check_dependency (expr1, expr2, true))
11334 rse.string_length =
11335 gfc_evaluate_now_function_scope (rse.string_length, &rse.pre);
11336 string_length = rse.string_length;
11338 else
11339 string_length = NULL_TREE;
11341 if (l_is_temp)
11343 gfc_conv_tmp_array_ref (&lse);
11344 if (expr2->ts.type == BT_CHARACTER)
11345 lse.string_length = string_length;
11347 else
11349 gfc_conv_expr (&lse, expr1);
11350 if (gfc_option.rtcheck & GFC_RTCHECK_MEM
11351 && !init_flag
11352 && gfc_expr_attr (expr1).allocatable
11353 && expr1->rank
11354 && !expr2->rank)
11356 tree cond;
11357 const char* msg;
11359 tmp = INDIRECT_REF_P (lse.expr)
11360 ? gfc_build_addr_expr (NULL_TREE, lse.expr) : lse.expr;
11362 /* We should only get array references here. */
11363 gcc_assert (TREE_CODE (tmp) == POINTER_PLUS_EXPR
11364 || TREE_CODE (tmp) == ARRAY_REF);
11366 /* 'tmp' is either the pointer to the array(POINTER_PLUS_EXPR)
11367 or the array itself(ARRAY_REF). */
11368 tmp = TREE_OPERAND (tmp, 0);
11370 /* Provide the address of the array. */
11371 if (TREE_CODE (lse.expr) == ARRAY_REF)
11372 tmp = gfc_build_addr_expr (NULL_TREE, tmp);
11374 cond = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
11375 tmp, build_int_cst (TREE_TYPE (tmp), 0));
11376 msg = _("Assignment of scalar to unallocated array");
11377 gfc_trans_runtime_check (true, false, cond, &loop.pre,
11378 &expr1->where, msg);
11381 /* Deallocate the lhs parameterized components if required. */
11382 if (dealloc && expr2->expr_type == EXPR_FUNCTION
11383 && !expr1->symtree->n.sym->attr.associate_var)
11385 if (expr1->ts.type == BT_DERIVED
11386 && expr1->ts.u.derived
11387 && expr1->ts.u.derived->attr.pdt_type)
11389 tmp = gfc_deallocate_pdt_comp (expr1->ts.u.derived, lse.expr,
11390 expr1->rank);
11391 gfc_add_expr_to_block (&lse.pre, tmp);
11393 else if (expr1->ts.type == BT_CLASS
11394 && CLASS_DATA (expr1)->ts.u.derived
11395 && CLASS_DATA (expr1)->ts.u.derived->attr.pdt_type)
11397 tmp = gfc_class_data_get (lse.expr);
11398 tmp = gfc_deallocate_pdt_comp (CLASS_DATA (expr1)->ts.u.derived,
11399 tmp, expr1->rank);
11400 gfc_add_expr_to_block (&lse.pre, tmp);
11405 /* Assignments of scalar derived types with allocatable components
11406 to arrays must be done with a deep copy and the rhs temporary
11407 must have its components deallocated afterwards. */
11408 scalar_to_array = (expr2->ts.type == BT_DERIVED
11409 && expr2->ts.u.derived->attr.alloc_comp
11410 && !gfc_expr_is_variable (expr2)
11411 && expr1->rank && !expr2->rank);
11412 scalar_to_array |= (expr1->ts.type == BT_DERIVED
11413 && expr1->rank
11414 && expr1->ts.u.derived->attr.alloc_comp
11415 && gfc_is_alloc_class_scalar_function (expr2));
11416 if (scalar_to_array && dealloc)
11418 tmp = gfc_deallocate_alloc_comp_no_caf (expr2->ts.u.derived, rse.expr, 0);
11419 gfc_prepend_expr_to_block (&loop.post, tmp);
11422 /* When assigning a character function result to a deferred-length variable,
11423 the function call must happen before the (re)allocation of the lhs -
11424 otherwise the character length of the result is not known.
11425 NOTE 1: This relies on having the exact dependence of the length type
11426 parameter available to the caller; gfortran saves it in the .mod files.
11427 NOTE 2: Vector array references generate an index temporary that must
11428 not go outside the loop. Otherwise, variables should not generate
11429 a pre block.
11430 NOTE 3: The concatenation operation generates a temporary pointer,
11431 whose allocation must go to the innermost loop.
11432 NOTE 4: Elemental functions may generate a temporary, too. */
11433 if (flag_realloc_lhs
11434 && expr2->ts.type == BT_CHARACTER && expr1->ts.deferred
11435 && !(lss != gfc_ss_terminator
11436 && rss != gfc_ss_terminator
11437 && ((expr2->expr_type == EXPR_VARIABLE && expr2->rank)
11438 || (expr2->expr_type == EXPR_FUNCTION
11439 && expr2->value.function.esym != NULL
11440 && expr2->value.function.esym->attr.elemental)
11441 || (expr2->expr_type == EXPR_FUNCTION
11442 && expr2->value.function.isym != NULL
11443 && expr2->value.function.isym->elemental)
11444 || (expr2->expr_type == EXPR_OP
11445 && expr2->value.op.op == INTRINSIC_CONCAT))))
11446 gfc_add_block_to_block (&block, &rse.pre);
11448 /* Nullify the allocatable components corresponding to those of the lhs
11449 derived type, so that the finalization of the function result does not
11450 affect the lhs of the assignment. Prepend is used to ensure that the
11451 nullification occurs before the call to the finalizer. In the case of
11452 a scalar to array assignment, this is done in gfc_trans_scalar_assign
11453 as part of the deep copy. */
11454 if (!scalar_to_array && expr1->ts.type == BT_DERIVED
11455 && (gfc_is_class_array_function (expr2)
11456 || gfc_is_alloc_class_scalar_function (expr2)))
11458 tmp = gfc_nullify_alloc_comp (expr1->ts.u.derived, rse.expr, 0);
11459 gfc_prepend_expr_to_block (&rse.post, tmp);
11460 if (lss != gfc_ss_terminator && rss == gfc_ss_terminator)
11461 gfc_add_block_to_block (&loop.post, &rse.post);
11464 tmp = NULL_TREE;
11466 if (is_poly_assign)
11468 tmp = trans_class_assignment (&body, expr1, expr2, &lse, &rse,
11469 use_vptr_copy || (lhs_attr.allocatable
11470 && !lhs_attr.dimension),
11471 !realloc_flag && flag_realloc_lhs
11472 && !lhs_attr.pointer);
11473 if (expr2->expr_type == EXPR_FUNCTION
11474 && expr2->ts.type == BT_DERIVED
11475 && expr2->ts.u.derived->attr.alloc_comp)
11477 tree tmp2 = gfc_deallocate_alloc_comp (expr2->ts.u.derived,
11478 rse.expr, expr2->rank);
11479 if (lss == gfc_ss_terminator)
11480 gfc_add_expr_to_block (&rse.post, tmp2);
11481 else
11482 gfc_add_expr_to_block (&loop.post, tmp2);
11485 else if (flag_coarray == GFC_FCOARRAY_LIB
11486 && lhs_caf_attr.codimension && rhs_caf_attr.codimension
11487 && ((lhs_caf_attr.allocatable && lhs_refs_comp)
11488 || (rhs_caf_attr.allocatable && rhs_refs_comp)))
11490 /* Only detour to caf_send[get][_by_ref] () when the lhs or rhs is an
11491 allocatable component, because those need to be accessed via the
11492 caf-runtime. No need to check for coindexes here, because resolve
11493 has rewritten those already. */
11494 gfc_code code;
11495 gfc_actual_arglist a1, a2;
11496 /* Clear the structures to prevent accessing garbage. */
11497 memset (&code, '\0', sizeof (gfc_code));
11498 memset (&a1, '\0', sizeof (gfc_actual_arglist));
11499 memset (&a2, '\0', sizeof (gfc_actual_arglist));
11500 a1.expr = expr1;
11501 a1.next = &a2;
11502 a2.expr = expr2;
11503 a2.next = NULL;
11504 code.ext.actual = &a1;
11505 code.resolved_isym = gfc_intrinsic_subroutine_by_id (GFC_ISYM_CAF_SEND);
11506 tmp = gfc_conv_intrinsic_subroutine (&code);
11508 else if (!is_poly_assign && expr2->must_finalize
11509 && expr1->ts.type == BT_CLASS
11510 && expr2->ts.type == BT_CLASS)
11512 /* This case comes about when the scalarizer provides array element
11513 references. Use the vptr copy function, since this does a deep
11514 copy of allocatable components, without which the finalizer call
11515 will deallocate the components. */
11516 tmp = gfc_get_vptr_from_expr (rse.expr);
11517 if (tmp != NULL_TREE)
11519 tree fcn = gfc_vptr_copy_get (tmp);
11520 if (POINTER_TYPE_P (TREE_TYPE (fcn)))
11521 fcn = build_fold_indirect_ref_loc (input_location, fcn);
11522 tmp = build_call_expr_loc (input_location,
11523 fcn, 2,
11524 gfc_build_addr_expr (NULL, rse.expr),
11525 gfc_build_addr_expr (NULL, lse.expr));
11529 /* If nothing else works, do it the old fashioned way! */
11530 if (tmp == NULL_TREE)
11531 tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts,
11532 gfc_expr_is_variable (expr2)
11533 || scalar_to_array
11534 || expr2->expr_type == EXPR_ARRAY,
11535 !(l_is_temp || init_flag) && dealloc,
11536 expr1->symtree->n.sym->attr.codimension);
11538 /* Add the pre blocks to the body. */
11539 gfc_add_block_to_block (&body, &rse.pre);
11540 gfc_add_block_to_block (&body, &lse.pre);
11541 gfc_add_expr_to_block (&body, tmp);
11542 /* Add the post blocks to the body. */
11543 gfc_add_block_to_block (&body, &rse.post);
11544 gfc_add_block_to_block (&body, &lse.post);
11546 if (lss == gfc_ss_terminator)
11548 /* F2003: Add the code for reallocation on assignment. */
11549 if (flag_realloc_lhs && is_scalar_reallocatable_lhs (expr1)
11550 && !is_poly_assign)
11551 alloc_scalar_allocatable_for_assignment (&block, string_length,
11552 expr1, expr2);
11554 /* Use the scalar assignment as is. */
11555 gfc_add_block_to_block (&block, &body);
11557 else
11559 gcc_assert (lse.ss == gfc_ss_terminator
11560 && rse.ss == gfc_ss_terminator);
11562 if (l_is_temp)
11564 gfc_trans_scalarized_loop_boundary (&loop, &body);
11566 /* We need to copy the temporary to the actual lhs. */
11567 gfc_init_se (&lse, NULL);
11568 gfc_init_se (&rse, NULL);
11569 gfc_copy_loopinfo_to_se (&lse, &loop);
11570 gfc_copy_loopinfo_to_se (&rse, &loop);
11572 rse.ss = loop.temp_ss;
11573 lse.ss = lss;
11575 gfc_conv_tmp_array_ref (&rse);
11576 gfc_conv_expr (&lse, expr1);
11578 gcc_assert (lse.ss == gfc_ss_terminator
11579 && rse.ss == gfc_ss_terminator);
11581 if (expr2->ts.type == BT_CHARACTER)
11582 rse.string_length = string_length;
11584 tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts,
11585 false, dealloc);
11586 gfc_add_expr_to_block (&body, tmp);
11589 /* F2003: Allocate or reallocate lhs of allocatable array. */
11590 if (realloc_flag)
11592 realloc_lhs_warning (expr1->ts.type, true, &expr1->where);
11593 ompws_flags &= ~OMPWS_SCALARIZER_WS;
11594 tmp = gfc_alloc_allocatable_for_assignment (&loop, expr1, expr2);
11595 if (tmp != NULL_TREE)
11596 gfc_add_expr_to_block (&loop.code[expr1->rank - 1], tmp);
11599 if (maybe_workshare)
11600 ompws_flags &= ~OMPWS_SCALARIZER_BODY;
11602 /* Generate the copying loops. */
11603 gfc_trans_scalarizing_loops (&loop, &body);
11605 /* Wrap the whole thing up. */
11606 gfc_add_block_to_block (&block, &loop.pre);
11607 gfc_add_block_to_block (&block, &loop.post);
11609 gfc_cleanup_loop (&loop);
11612 return gfc_finish_block (&block);
11616 /* Check whether EXPR is a copyable array. */
11618 static bool
11619 copyable_array_p (gfc_expr * expr)
11621 if (expr->expr_type != EXPR_VARIABLE)
11622 return false;
11624 /* First check it's an array. */
11625 if (expr->rank < 1 || !expr->ref || expr->ref->next)
11626 return false;
11628 if (!gfc_full_array_ref_p (expr->ref, NULL))
11629 return false;
11631 /* Next check that it's of a simple enough type. */
11632 switch (expr->ts.type)
11634 case BT_INTEGER:
11635 case BT_REAL:
11636 case BT_COMPLEX:
11637 case BT_LOGICAL:
11638 return true;
11640 case BT_CHARACTER:
11641 return false;
11643 case_bt_struct:
11644 return !expr->ts.u.derived->attr.alloc_comp;
11646 default:
11647 break;
11650 return false;
11653 /* Translate an assignment. */
11655 tree
11656 gfc_trans_assignment (gfc_expr * expr1, gfc_expr * expr2, bool init_flag,
11657 bool dealloc, bool use_vptr_copy, bool may_alias)
11659 tree tmp;
11661 /* Special case a single function returning an array. */
11662 if (expr2->expr_type == EXPR_FUNCTION && expr2->rank > 0)
11664 tmp = gfc_trans_arrayfunc_assign (expr1, expr2);
11665 if (tmp)
11666 return tmp;
11669 /* Special case assigning an array to zero. */
11670 if (copyable_array_p (expr1)
11671 && is_zero_initializer_p (expr2))
11673 tmp = gfc_trans_zero_assign (expr1);
11674 if (tmp)
11675 return tmp;
11678 /* Special case copying one array to another. */
11679 if (copyable_array_p (expr1)
11680 && copyable_array_p (expr2)
11681 && gfc_compare_types (&expr1->ts, &expr2->ts)
11682 && !gfc_check_dependency (expr1, expr2, 0))
11684 tmp = gfc_trans_array_copy (expr1, expr2);
11685 if (tmp)
11686 return tmp;
11689 /* Special case initializing an array from a constant array constructor. */
11690 if (copyable_array_p (expr1)
11691 && expr2->expr_type == EXPR_ARRAY
11692 && gfc_compare_types (&expr1->ts, &expr2->ts))
11694 tmp = gfc_trans_array_constructor_copy (expr1, expr2);
11695 if (tmp)
11696 return tmp;
11699 if (UNLIMITED_POLY (expr1) && expr1->rank)
11700 use_vptr_copy = true;
11702 /* Fallback to the scalarizer to generate explicit loops. */
11703 return gfc_trans_assignment_1 (expr1, expr2, init_flag, dealloc,
11704 use_vptr_copy, may_alias);
11707 tree
11708 gfc_trans_init_assign (gfc_code * code)
11710 return gfc_trans_assignment (code->expr1, code->expr2, true, false, true);
11713 tree
11714 gfc_trans_assign (gfc_code * code)
11716 return gfc_trans_assignment (code->expr1, code->expr2, false, true);