MATCH: Remove redundant pattern for `(x | y) & ~x`
[official-gcc.git] / gcc / fortran / trans-expr.cc
blob244126cdd00191563a1629792a0c304daf4b37cc
1 /* Expression translation
2 Copyright (C) 2002-2023 Free Software Foundation, Inc.
3 Contributed by Paul Brook <paul@nowt.org>
4 and Steven Bosscher <s.bosscher@student.tudelft.nl>
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.cc-- 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"
44 #include "tm.h" /* For CHAR_TYPE_SIZE. */
47 /* Calculate the number of characters in a string. */
49 static tree
50 gfc_get_character_len (tree type)
52 tree len;
54 gcc_assert (type && TREE_CODE (type) == ARRAY_TYPE
55 && TYPE_STRING_FLAG (type));
57 len = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
58 len = (len) ? (len) : (integer_zero_node);
59 return fold_convert (gfc_charlen_type_node, len);
64 /* Calculate the number of bytes in a string. */
66 tree
67 gfc_get_character_len_in_bytes (tree type)
69 tree tmp, len;
71 gcc_assert (type && TREE_CODE (type) == ARRAY_TYPE
72 && TYPE_STRING_FLAG (type));
74 tmp = TYPE_SIZE_UNIT (TREE_TYPE (type));
75 tmp = (tmp && !integer_zerop (tmp))
76 ? (fold_convert (gfc_charlen_type_node, tmp)) : (NULL_TREE);
77 len = gfc_get_character_len (type);
78 if (tmp && len && !integer_zerop (len))
79 len = fold_build2_loc (input_location, MULT_EXPR,
80 gfc_charlen_type_node, len, tmp);
81 return len;
85 /* Convert a scalar to an array descriptor. To be used for assumed-rank
86 arrays. */
88 static tree
89 get_scalar_to_descriptor_type (tree scalar, symbol_attribute attr)
91 enum gfc_array_kind akind;
93 if (attr.pointer)
94 akind = GFC_ARRAY_POINTER_CONT;
95 else if (attr.allocatable)
96 akind = GFC_ARRAY_ALLOCATABLE;
97 else
98 akind = GFC_ARRAY_ASSUMED_SHAPE_CONT;
100 if (POINTER_TYPE_P (TREE_TYPE (scalar)))
101 scalar = TREE_TYPE (scalar);
102 return gfc_get_array_type_bounds (TREE_TYPE (scalar), 0, 0, NULL, NULL, 1,
103 akind, !(attr.pointer || attr.target));
106 tree
107 gfc_conv_scalar_to_descriptor (gfc_se *se, tree scalar, symbol_attribute attr)
109 tree desc, type, etype;
111 type = get_scalar_to_descriptor_type (scalar, attr);
112 etype = TREE_TYPE (scalar);
113 desc = gfc_create_var (type, "desc");
114 DECL_ARTIFICIAL (desc) = 1;
116 if (CONSTANT_CLASS_P (scalar))
118 tree tmp;
119 tmp = gfc_create_var (TREE_TYPE (scalar), "scalar");
120 gfc_add_modify (&se->pre, tmp, scalar);
121 scalar = tmp;
123 if (!POINTER_TYPE_P (TREE_TYPE (scalar)))
124 scalar = gfc_build_addr_expr (NULL_TREE, scalar);
125 else if (TREE_TYPE (etype) && TREE_CODE (TREE_TYPE (etype)) == ARRAY_TYPE)
126 etype = TREE_TYPE (etype);
127 gfc_add_modify (&se->pre, gfc_conv_descriptor_dtype (desc),
128 gfc_get_dtype_rank_type (0, etype));
129 gfc_conv_descriptor_data_set (&se->pre, desc, scalar);
130 gfc_conv_descriptor_span_set (&se->pre, desc,
131 gfc_conv_descriptor_elem_len (desc));
133 /* Copy pointer address back - but only if it could have changed and
134 if the actual argument is a pointer and not, e.g., NULL(). */
135 if ((attr.pointer || attr.allocatable) && attr.intent != INTENT_IN)
136 gfc_add_modify (&se->post, scalar,
137 fold_convert (TREE_TYPE (scalar),
138 gfc_conv_descriptor_data_get (desc)));
139 return desc;
143 /* Get the coarray token from the ultimate array or component ref.
144 Returns a NULL_TREE, when the ref object is not allocatable or pointer. */
146 tree
147 gfc_get_ultimate_alloc_ptr_comps_caf_token (gfc_se *outerse, gfc_expr *expr)
149 gfc_symbol *sym = expr->symtree->n.sym;
150 bool is_coarray = sym->attr.codimension;
151 gfc_expr *caf_expr = gfc_copy_expr (expr);
152 gfc_ref *ref = caf_expr->ref, *last_caf_ref = NULL;
154 while (ref)
156 if (ref->type == REF_COMPONENT
157 && (ref->u.c.component->attr.allocatable
158 || ref->u.c.component->attr.pointer)
159 && (is_coarray || ref->u.c.component->attr.codimension))
160 last_caf_ref = ref;
161 ref = ref->next;
164 if (last_caf_ref == NULL)
165 return NULL_TREE;
167 tree comp = last_caf_ref->u.c.component->caf_token, caf;
168 gfc_se se;
169 bool comp_ref = !last_caf_ref->u.c.component->attr.dimension;
170 if (comp == NULL_TREE && comp_ref)
171 return NULL_TREE;
172 gfc_init_se (&se, outerse);
173 gfc_free_ref_list (last_caf_ref->next);
174 last_caf_ref->next = NULL;
175 caf_expr->rank = comp_ref ? 0 : last_caf_ref->u.c.component->as->rank;
176 se.want_pointer = comp_ref;
177 gfc_conv_expr (&se, caf_expr);
178 gfc_add_block_to_block (&outerse->pre, &se.pre);
180 if (TREE_CODE (se.expr) == COMPONENT_REF && comp_ref)
181 se.expr = TREE_OPERAND (se.expr, 0);
182 gfc_free_expr (caf_expr);
184 if (comp_ref)
185 caf = fold_build3_loc (input_location, COMPONENT_REF,
186 TREE_TYPE (comp), se.expr, comp, NULL_TREE);
187 else
188 caf = gfc_conv_descriptor_token (se.expr);
189 return gfc_build_addr_expr (NULL_TREE, caf);
193 /* This is the seed for an eventual trans-class.c
195 The following parameters should not be used directly since they might
196 in future implementations. Use the corresponding APIs. */
197 #define CLASS_DATA_FIELD 0
198 #define CLASS_VPTR_FIELD 1
199 #define CLASS_LEN_FIELD 2
200 #define VTABLE_HASH_FIELD 0
201 #define VTABLE_SIZE_FIELD 1
202 #define VTABLE_EXTENDS_FIELD 2
203 #define VTABLE_DEF_INIT_FIELD 3
204 #define VTABLE_COPY_FIELD 4
205 #define VTABLE_FINAL_FIELD 5
206 #define VTABLE_DEALLOCATE_FIELD 6
209 tree
210 gfc_class_set_static_fields (tree decl, tree vptr, tree data)
212 tree tmp;
213 tree field;
214 vec<constructor_elt, va_gc> *init = NULL;
216 field = TYPE_FIELDS (TREE_TYPE (decl));
217 tmp = gfc_advance_chain (field, CLASS_DATA_FIELD);
218 CONSTRUCTOR_APPEND_ELT (init, tmp, data);
220 tmp = gfc_advance_chain (field, CLASS_VPTR_FIELD);
221 CONSTRUCTOR_APPEND_ELT (init, tmp, vptr);
223 return build_constructor (TREE_TYPE (decl), init);
227 tree
228 gfc_class_data_get (tree decl)
230 tree data;
231 if (POINTER_TYPE_P (TREE_TYPE (decl)))
232 decl = build_fold_indirect_ref_loc (input_location, decl);
233 data = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (decl)),
234 CLASS_DATA_FIELD);
235 return fold_build3_loc (input_location, COMPONENT_REF,
236 TREE_TYPE (data), decl, data,
237 NULL_TREE);
241 tree
242 gfc_class_vptr_get (tree decl)
244 tree vptr;
245 /* For class arrays decl may be a temporary descriptor handle, the vptr is
246 then available through the saved descriptor. */
247 if (VAR_P (decl) && DECL_LANG_SPECIFIC (decl)
248 && GFC_DECL_SAVED_DESCRIPTOR (decl))
249 decl = GFC_DECL_SAVED_DESCRIPTOR (decl);
250 if (POINTER_TYPE_P (TREE_TYPE (decl)))
251 decl = build_fold_indirect_ref_loc (input_location, decl);
252 vptr = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (decl)),
253 CLASS_VPTR_FIELD);
254 return fold_build3_loc (input_location, COMPONENT_REF,
255 TREE_TYPE (vptr), decl, vptr,
256 NULL_TREE);
260 tree
261 gfc_class_len_get (tree decl)
263 tree len;
264 /* For class arrays decl may be a temporary descriptor handle, the len is
265 then available through the saved descriptor. */
266 if (VAR_P (decl) && DECL_LANG_SPECIFIC (decl)
267 && GFC_DECL_SAVED_DESCRIPTOR (decl))
268 decl = GFC_DECL_SAVED_DESCRIPTOR (decl);
269 if (POINTER_TYPE_P (TREE_TYPE (decl)))
270 decl = build_fold_indirect_ref_loc (input_location, decl);
271 len = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (decl)),
272 CLASS_LEN_FIELD);
273 return fold_build3_loc (input_location, COMPONENT_REF,
274 TREE_TYPE (len), decl, len,
275 NULL_TREE);
279 /* Try to get the _len component of a class. When the class is not unlimited
280 poly, i.e. no _len field exists, then return a zero node. */
282 static tree
283 gfc_class_len_or_zero_get (tree decl)
285 tree len;
286 /* For class arrays decl may be a temporary descriptor handle, the vptr is
287 then available through the saved descriptor. */
288 if (VAR_P (decl) && DECL_LANG_SPECIFIC (decl)
289 && GFC_DECL_SAVED_DESCRIPTOR (decl))
290 decl = GFC_DECL_SAVED_DESCRIPTOR (decl);
291 if (POINTER_TYPE_P (TREE_TYPE (decl)))
292 decl = build_fold_indirect_ref_loc (input_location, decl);
293 len = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (decl)),
294 CLASS_LEN_FIELD);
295 return len != NULL_TREE ? fold_build3_loc (input_location, COMPONENT_REF,
296 TREE_TYPE (len), decl, len,
297 NULL_TREE)
298 : build_zero_cst (gfc_charlen_type_node);
302 tree
303 gfc_resize_class_size_with_len (stmtblock_t * block, tree class_expr, tree size)
305 tree tmp;
306 tree tmp2;
307 tree type;
309 tmp = gfc_class_len_or_zero_get (class_expr);
311 /* Include the len value in the element size if present. */
312 if (!integer_zerop (tmp))
314 type = TREE_TYPE (size);
315 if (block)
317 size = gfc_evaluate_now (size, block);
318 tmp = gfc_evaluate_now (fold_convert (type , tmp), block);
320 tmp2 = fold_build2_loc (input_location, MULT_EXPR,
321 type, size, tmp);
322 tmp = fold_build2_loc (input_location, GT_EXPR,
323 logical_type_node, tmp,
324 build_zero_cst (type));
325 size = fold_build3_loc (input_location, COND_EXPR,
326 type, tmp, tmp2, size);
328 else
329 return size;
331 if (block)
332 size = gfc_evaluate_now (size, block);
334 return size;
338 /* Get the specified FIELD from the VPTR. */
340 static tree
341 vptr_field_get (tree vptr, int fieldno)
343 tree field;
344 vptr = build_fold_indirect_ref_loc (input_location, vptr);
345 field = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (vptr)),
346 fieldno);
347 field = fold_build3_loc (input_location, COMPONENT_REF,
348 TREE_TYPE (field), vptr, field,
349 NULL_TREE);
350 gcc_assert (field);
351 return field;
355 /* Get the field from the class' vptr. */
357 static tree
358 class_vtab_field_get (tree decl, int fieldno)
360 tree vptr;
361 vptr = gfc_class_vptr_get (decl);
362 return vptr_field_get (vptr, fieldno);
366 /* Define a macro for creating the class_vtab_* and vptr_* accessors in
367 unison. */
368 #define VTAB_GET_FIELD_GEN(name, field) tree \
369 gfc_class_vtab_## name ##_get (tree cl) \
371 return class_vtab_field_get (cl, field); \
374 tree \
375 gfc_vptr_## name ##_get (tree vptr) \
377 return vptr_field_get (vptr, field); \
380 VTAB_GET_FIELD_GEN (hash, VTABLE_HASH_FIELD)
381 VTAB_GET_FIELD_GEN (extends, VTABLE_EXTENDS_FIELD)
382 VTAB_GET_FIELD_GEN (def_init, VTABLE_DEF_INIT_FIELD)
383 VTAB_GET_FIELD_GEN (copy, VTABLE_COPY_FIELD)
384 VTAB_GET_FIELD_GEN (final, VTABLE_FINAL_FIELD)
385 VTAB_GET_FIELD_GEN (deallocate, VTABLE_DEALLOCATE_FIELD)
386 #undef VTAB_GET_FIELD_GEN
388 /* The size field is returned as an array index type. Therefore treat
389 it and only it specially. */
391 tree
392 gfc_class_vtab_size_get (tree cl)
394 tree size;
395 size = class_vtab_field_get (cl, VTABLE_SIZE_FIELD);
396 /* Always return size as an array index type. */
397 size = fold_convert (gfc_array_index_type, size);
398 gcc_assert (size);
399 return size;
402 tree
403 gfc_vptr_size_get (tree vptr)
405 tree size;
406 size = vptr_field_get (vptr, VTABLE_SIZE_FIELD);
407 /* Always return size as an array index type. */
408 size = fold_convert (gfc_array_index_type, size);
409 gcc_assert (size);
410 return size;
414 #undef CLASS_DATA_FIELD
415 #undef CLASS_VPTR_FIELD
416 #undef CLASS_LEN_FIELD
417 #undef VTABLE_HASH_FIELD
418 #undef VTABLE_SIZE_FIELD
419 #undef VTABLE_EXTENDS_FIELD
420 #undef VTABLE_DEF_INIT_FIELD
421 #undef VTABLE_COPY_FIELD
422 #undef VTABLE_FINAL_FIELD
425 /* IF ts is null (default), search for the last _class ref in the chain
426 of references of the expression and cut the chain there. Although
427 this routine is similiar to class.cc:gfc_add_component_ref (), there
428 is a significant difference: gfc_add_component_ref () concentrates
429 on an array ref that is the last ref in the chain and is oblivious
430 to the kind of refs following.
431 ELSE IF ts is non-null the cut is at the class entity or component
432 that is followed by an array reference, which is not an element.
433 These calls come from trans-array.cc:build_class_array_ref, which
434 handles scalarized class array references.*/
436 gfc_expr *
437 gfc_find_and_cut_at_last_class_ref (gfc_expr *e, bool is_mold,
438 gfc_typespec **ts)
440 gfc_expr *base_expr;
441 gfc_ref *ref, *class_ref, *tail = NULL, *array_ref;
443 /* Find the last class reference. */
444 class_ref = NULL;
445 array_ref = NULL;
447 if (ts)
449 if (e->symtree
450 && e->symtree->n.sym->ts.type == BT_CLASS)
451 *ts = &e->symtree->n.sym->ts;
452 else
453 *ts = NULL;
456 for (ref = e->ref; ref; ref = ref->next)
458 if (ts)
460 if (ref->type == REF_COMPONENT
461 && ref->u.c.component->ts.type == BT_CLASS
462 && ref->next && ref->next->type == REF_COMPONENT
463 && !strcmp (ref->next->u.c.component->name, "_data")
464 && ref->next->next
465 && ref->next->next->type == REF_ARRAY
466 && ref->next->next->u.ar.type != AR_ELEMENT)
468 *ts = &ref->u.c.component->ts;
469 class_ref = ref;
470 break;
473 if (ref->next == NULL)
474 break;
476 else
478 if (ref->type == REF_ARRAY && ref->u.ar.type != AR_ELEMENT)
479 array_ref = ref;
481 if (ref->type == REF_COMPONENT
482 && ref->u.c.component->ts.type == BT_CLASS)
484 /* Component to the right of a part reference with nonzero
485 rank must not have the ALLOCATABLE attribute. If attempts
486 are made to reference such a component reference, an error
487 results followed by an ICE. */
488 if (array_ref
489 && CLASS_DATA (ref->u.c.component)->attr.allocatable)
490 return NULL;
491 class_ref = ref;
496 if (ts && *ts == NULL)
497 return NULL;
499 /* Remove and store all subsequent references after the
500 CLASS reference. */
501 if (class_ref)
503 tail = class_ref->next;
504 class_ref->next = NULL;
506 else if (e->symtree && e->symtree->n.sym->ts.type == BT_CLASS)
508 tail = e->ref;
509 e->ref = NULL;
512 if (is_mold)
513 base_expr = gfc_expr_to_initialize (e);
514 else
515 base_expr = gfc_copy_expr (e);
517 /* Restore the original tail expression. */
518 if (class_ref)
520 gfc_free_ref_list (class_ref->next);
521 class_ref->next = tail;
523 else if (e->symtree && e->symtree->n.sym->ts.type == BT_CLASS)
525 gfc_free_ref_list (e->ref);
526 e->ref = tail;
528 return base_expr;
532 /* Reset the vptr to the declared type, e.g. after deallocation.
533 Use the variable in CLASS_CONTAINER if available. Otherwise, recreate
534 one with E. The generated assignment code is added at the end of BLOCK. */
536 void
537 gfc_reset_vptr (stmtblock_t *block, gfc_expr *e, tree class_container)
539 tree vptr = NULL_TREE;
541 if (class_container != NULL_TREE)
542 vptr = gfc_get_vptr_from_expr (class_container);
544 if (vptr == NULL_TREE)
546 gfc_se se;
548 /* Evaluate the expression and obtain the vptr from it. */
549 gfc_init_se (&se, NULL);
550 if (e->rank)
551 gfc_conv_expr_descriptor (&se, e);
552 else
553 gfc_conv_expr (&se, e);
554 gfc_add_block_to_block (block, &se.pre);
556 vptr = gfc_get_vptr_from_expr (se.expr);
559 /* If a vptr is not found, we can do nothing more. */
560 if (vptr == NULL_TREE)
561 return;
563 if (UNLIMITED_POLY (e))
564 gfc_add_modify (block, vptr, build_int_cst (TREE_TYPE (vptr), 0));
565 else
567 gfc_symbol *vtab;
568 tree vtable;
570 /* Return the vptr to the address of the declared type. */
571 vtab = gfc_find_derived_vtab (e->ts.u.derived);
572 vtable = vtab->backend_decl;
573 if (vtable == NULL_TREE)
574 vtable = gfc_get_symbol_decl (vtab);
575 vtable = gfc_build_addr_expr (NULL, vtable);
576 vtable = fold_convert (TREE_TYPE (vptr), vtable);
577 gfc_add_modify (block, vptr, vtable);
582 /* Reset the len for unlimited polymorphic objects. */
584 void
585 gfc_reset_len (stmtblock_t *block, gfc_expr *expr)
587 gfc_expr *e;
588 gfc_se se_len;
589 e = gfc_find_and_cut_at_last_class_ref (expr);
590 if (e == NULL)
591 return;
592 gfc_add_len_component (e);
593 gfc_init_se (&se_len, NULL);
594 gfc_conv_expr (&se_len, e);
595 gfc_add_modify (block, se_len.expr,
596 fold_convert (TREE_TYPE (se_len.expr), integer_zero_node));
597 gfc_free_expr (e);
601 /* Obtain the last class reference in a gfc_expr. Return NULL_TREE if no class
602 reference is found. Note that it is up to the caller to avoid using this
603 for expressions other than variables. */
605 tree
606 gfc_get_class_from_gfc_expr (gfc_expr *e)
608 gfc_expr *class_expr;
609 gfc_se cse;
610 class_expr = gfc_find_and_cut_at_last_class_ref (e);
611 if (class_expr == NULL)
612 return NULL_TREE;
613 gfc_init_se (&cse, NULL);
614 gfc_conv_expr (&cse, class_expr);
615 gfc_free_expr (class_expr);
616 return cse.expr;
620 /* Obtain the last class reference in an expression.
621 Return NULL_TREE if no class reference is found. */
623 tree
624 gfc_get_class_from_expr (tree expr)
626 tree tmp;
627 tree type;
629 for (tmp = expr; tmp; tmp = TREE_OPERAND (tmp, 0))
631 if (CONSTANT_CLASS_P (tmp))
632 return NULL_TREE;
634 type = TREE_TYPE (tmp);
635 while (type)
637 if (GFC_CLASS_TYPE_P (type))
638 return tmp;
639 if (type != TYPE_CANONICAL (type))
640 type = TYPE_CANONICAL (type);
641 else
642 type = NULL_TREE;
644 if (VAR_P (tmp) || TREE_CODE (tmp) == PARM_DECL)
645 break;
648 if (POINTER_TYPE_P (TREE_TYPE (tmp)))
649 tmp = build_fold_indirect_ref_loc (input_location, tmp);
651 if (GFC_CLASS_TYPE_P (TREE_TYPE (tmp)))
652 return tmp;
654 return NULL_TREE;
658 /* Obtain the vptr of the last class reference in an expression.
659 Return NULL_TREE if no class reference is found. */
661 tree
662 gfc_get_vptr_from_expr (tree expr)
664 tree tmp;
666 tmp = gfc_get_class_from_expr (expr);
668 if (tmp != NULL_TREE)
669 return gfc_class_vptr_get (tmp);
671 return NULL_TREE;
675 static void
676 class_array_data_assign (stmtblock_t *block, tree lhs_desc, tree rhs_desc,
677 bool lhs_type)
679 tree tmp, tmp2, type;
681 gfc_conv_descriptor_data_set (block, lhs_desc,
682 gfc_conv_descriptor_data_get (rhs_desc));
683 gfc_conv_descriptor_offset_set (block, lhs_desc,
684 gfc_conv_descriptor_offset_get (rhs_desc));
686 gfc_add_modify (block, gfc_conv_descriptor_dtype (lhs_desc),
687 gfc_conv_descriptor_dtype (rhs_desc));
689 /* Assign the dimension as range-ref. */
690 tmp = gfc_get_descriptor_dimension (lhs_desc);
691 tmp2 = gfc_get_descriptor_dimension (rhs_desc);
693 type = lhs_type ? TREE_TYPE (tmp) : TREE_TYPE (tmp2);
694 tmp = build4_loc (input_location, ARRAY_RANGE_REF, type, tmp,
695 gfc_index_zero_node, NULL_TREE, NULL_TREE);
696 tmp2 = build4_loc (input_location, ARRAY_RANGE_REF, type, tmp2,
697 gfc_index_zero_node, NULL_TREE, NULL_TREE);
698 gfc_add_modify (block, tmp, tmp2);
702 /* Takes a derived type expression and returns the address of a temporary
703 class object of the 'declared' type. If vptr is not NULL, this is
704 used for the temporary class object.
705 optional_alloc_ptr is false when the dummy is neither allocatable
706 nor a pointer; that's only relevant for the optional handling.
707 The optional argument 'derived_array' is used to preserve the parmse
708 expression for deallocation of allocatable components. Assumed rank
709 formal arguments made this necessary. */
710 void
711 gfc_conv_derived_to_class (gfc_se *parmse, gfc_expr *e,
712 gfc_typespec class_ts, tree vptr, bool optional,
713 bool optional_alloc_ptr,
714 tree *derived_array)
716 gfc_symbol *vtab;
717 tree cond_optional = NULL_TREE;
718 gfc_ss *ss;
719 tree ctree;
720 tree var;
721 tree tmp;
722 int dim;
724 /* The derived type needs to be converted to a temporary
725 CLASS object. */
726 tmp = gfc_typenode_for_spec (&class_ts);
727 var = gfc_create_var (tmp, "class");
729 /* Set the vptr. */
730 ctree = gfc_class_vptr_get (var);
732 if (vptr != NULL_TREE)
734 /* Use the dynamic vptr. */
735 tmp = vptr;
737 else
739 /* In this case the vtab corresponds to the derived type and the
740 vptr must point to it. */
741 vtab = gfc_find_derived_vtab (e->ts.u.derived);
742 gcc_assert (vtab);
743 tmp = gfc_build_addr_expr (NULL_TREE, gfc_get_symbol_decl (vtab));
745 gfc_add_modify (&parmse->pre, ctree,
746 fold_convert (TREE_TYPE (ctree), tmp));
748 /* Now set the data field. */
749 ctree = gfc_class_data_get (var);
751 if (optional)
752 cond_optional = gfc_conv_expr_present (e->symtree->n.sym);
754 if (parmse->expr && POINTER_TYPE_P (TREE_TYPE (parmse->expr)))
756 /* If there is a ready made pointer to a derived type, use it
757 rather than evaluating the expression again. */
758 tmp = fold_convert (TREE_TYPE (ctree), parmse->expr);
759 gfc_add_modify (&parmse->pre, ctree, tmp);
761 else if (parmse->ss && parmse->ss->info && parmse->ss->info->useflags)
763 /* For an array reference in an elemental procedure call we need
764 to retain the ss to provide the scalarized array reference. */
765 gfc_conv_expr_reference (parmse, e);
766 tmp = fold_convert (TREE_TYPE (ctree), parmse->expr);
767 if (optional)
768 tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp),
769 cond_optional, tmp,
770 fold_convert (TREE_TYPE (tmp), null_pointer_node));
771 gfc_add_modify (&parmse->pre, ctree, tmp);
773 else
775 ss = gfc_walk_expr (e);
776 if (ss == gfc_ss_terminator)
778 parmse->ss = NULL;
779 gfc_conv_expr_reference (parmse, e);
781 /* Scalar to an assumed-rank array. */
782 if (class_ts.u.derived->components->as)
784 tree type;
785 type = get_scalar_to_descriptor_type (parmse->expr,
786 gfc_expr_attr (e));
787 gfc_add_modify (&parmse->pre, gfc_conv_descriptor_dtype (ctree),
788 gfc_get_dtype (type));
789 if (optional)
790 parmse->expr = build3_loc (input_location, COND_EXPR,
791 TREE_TYPE (parmse->expr),
792 cond_optional, parmse->expr,
793 fold_convert (TREE_TYPE (parmse->expr),
794 null_pointer_node));
795 gfc_conv_descriptor_data_set (&parmse->pre, ctree, parmse->expr);
797 else
799 tmp = fold_convert (TREE_TYPE (ctree), parmse->expr);
800 if (optional)
801 tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp),
802 cond_optional, tmp,
803 fold_convert (TREE_TYPE (tmp),
804 null_pointer_node));
805 gfc_add_modify (&parmse->pre, ctree, tmp);
808 else
810 stmtblock_t block;
811 gfc_init_block (&block);
812 gfc_ref *ref;
814 parmse->ss = ss;
815 parmse->use_offset = 1;
816 gfc_conv_expr_descriptor (parmse, e);
818 /* Detect any array references with vector subscripts. */
819 for (ref = e->ref; ref; ref = ref->next)
820 if (ref->type == REF_ARRAY
821 && ref->u.ar.type != AR_ELEMENT
822 && ref->u.ar.type != AR_FULL)
824 for (dim = 0; dim < ref->u.ar.dimen; dim++)
825 if (ref->u.ar.dimen_type[dim] == DIMEN_VECTOR)
826 break;
827 if (dim < ref->u.ar.dimen)
828 break;
831 /* Array references with vector subscripts and non-variable expressions
832 need be converted to a one-based descriptor. */
833 if (ref || e->expr_type != EXPR_VARIABLE)
835 for (dim = 0; dim < e->rank; ++dim)
836 gfc_conv_shift_descriptor_lbound (&block, parmse->expr, dim,
837 gfc_index_one_node);
840 if (e->rank != class_ts.u.derived->components->as->rank)
842 gcc_assert (class_ts.u.derived->components->as->type
843 == AS_ASSUMED_RANK);
844 if (derived_array
845 && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (parmse->expr)))
847 *derived_array = gfc_create_var (TREE_TYPE (parmse->expr),
848 "array");
849 gfc_add_modify (&block, *derived_array , parmse->expr);
851 class_array_data_assign (&block, ctree, parmse->expr, false);
853 else
855 if (gfc_expr_attr (e).codimension)
856 parmse->expr = fold_build1_loc (input_location,
857 VIEW_CONVERT_EXPR,
858 TREE_TYPE (ctree),
859 parmse->expr);
860 gfc_add_modify (&block, ctree, parmse->expr);
863 if (optional)
865 tmp = gfc_finish_block (&block);
867 gfc_init_block (&block);
868 gfc_conv_descriptor_data_set (&block, ctree, null_pointer_node);
869 if (derived_array && *derived_array != NULL_TREE)
870 gfc_conv_descriptor_data_set (&block, *derived_array,
871 null_pointer_node);
873 tmp = build3_v (COND_EXPR, cond_optional, tmp,
874 gfc_finish_block (&block));
875 gfc_add_expr_to_block (&parmse->pre, tmp);
877 else
878 gfc_add_block_to_block (&parmse->pre, &block);
882 if (class_ts.u.derived->components->ts.type == BT_DERIVED
883 && class_ts.u.derived->components->ts.u.derived
884 ->attr.unlimited_polymorphic)
886 /* Take care about initializing the _len component correctly. */
887 ctree = gfc_class_len_get (var);
888 if (UNLIMITED_POLY (e))
890 gfc_expr *len;
891 gfc_se se;
893 len = gfc_find_and_cut_at_last_class_ref (e);
894 gfc_add_len_component (len);
895 gfc_init_se (&se, NULL);
896 gfc_conv_expr (&se, len);
897 if (optional)
898 tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (se.expr),
899 cond_optional, se.expr,
900 fold_convert (TREE_TYPE (se.expr),
901 integer_zero_node));
902 else
903 tmp = se.expr;
904 gfc_free_expr (len);
906 else
907 tmp = integer_zero_node;
908 gfc_add_modify (&parmse->pre, ctree, fold_convert (TREE_TYPE (ctree),
909 tmp));
911 /* Pass the address of the class object. */
912 parmse->expr = gfc_build_addr_expr (NULL_TREE, var);
914 if (optional && optional_alloc_ptr)
915 parmse->expr = build3_loc (input_location, COND_EXPR,
916 TREE_TYPE (parmse->expr),
917 cond_optional, parmse->expr,
918 fold_convert (TREE_TYPE (parmse->expr),
919 null_pointer_node));
923 /* Create a new class container, which is required as scalar coarrays
924 have an array descriptor while normal scalars haven't. Optionally,
925 NULL pointer checks are added if the argument is OPTIONAL. */
927 static void
928 class_scalar_coarray_to_class (gfc_se *parmse, gfc_expr *e,
929 gfc_typespec class_ts, bool optional)
931 tree var, ctree, tmp;
932 stmtblock_t block;
933 gfc_ref *ref;
934 gfc_ref *class_ref;
936 gfc_init_block (&block);
938 class_ref = NULL;
939 for (ref = e->ref; ref; ref = ref->next)
941 if (ref->type == REF_COMPONENT
942 && ref->u.c.component->ts.type == BT_CLASS)
943 class_ref = ref;
946 if (class_ref == NULL
947 && e->symtree && e->symtree->n.sym->ts.type == BT_CLASS)
948 tmp = e->symtree->n.sym->backend_decl;
949 else
951 /* Remove everything after the last class reference, convert the
952 expression and then recover its tailend once more. */
953 gfc_se tmpse;
954 ref = class_ref->next;
955 class_ref->next = NULL;
956 gfc_init_se (&tmpse, NULL);
957 gfc_conv_expr (&tmpse, e);
958 class_ref->next = ref;
959 tmp = tmpse.expr;
962 var = gfc_typenode_for_spec (&class_ts);
963 var = gfc_create_var (var, "class");
965 ctree = gfc_class_vptr_get (var);
966 gfc_add_modify (&block, ctree,
967 fold_convert (TREE_TYPE (ctree), gfc_class_vptr_get (tmp)));
969 ctree = gfc_class_data_get (var);
970 tmp = gfc_conv_descriptor_data_get (gfc_class_data_get (tmp));
971 gfc_add_modify (&block, ctree, fold_convert (TREE_TYPE (ctree), tmp));
973 /* Pass the address of the class object. */
974 parmse->expr = gfc_build_addr_expr (NULL_TREE, var);
976 if (optional)
978 tree cond = gfc_conv_expr_present (e->symtree->n.sym);
979 tree tmp2;
981 tmp = gfc_finish_block (&block);
983 gfc_init_block (&block);
984 tmp2 = gfc_class_data_get (var);
985 gfc_add_modify (&block, tmp2, fold_convert (TREE_TYPE (tmp2),
986 null_pointer_node));
987 tmp2 = gfc_finish_block (&block);
989 tmp = build3_loc (input_location, COND_EXPR, void_type_node,
990 cond, tmp, tmp2);
991 gfc_add_expr_to_block (&parmse->pre, tmp);
993 else
994 gfc_add_block_to_block (&parmse->pre, &block);
998 /* Takes an intrinsic type expression and returns the address of a temporary
999 class object of the 'declared' type. */
1000 void
1001 gfc_conv_intrinsic_to_class (gfc_se *parmse, gfc_expr *e,
1002 gfc_typespec class_ts)
1004 gfc_symbol *vtab;
1005 gfc_ss *ss;
1006 tree ctree;
1007 tree var;
1008 tree tmp;
1009 int dim;
1010 bool unlimited_poly;
1012 unlimited_poly = class_ts.type == BT_CLASS
1013 && class_ts.u.derived->components->ts.type == BT_DERIVED
1014 && class_ts.u.derived->components->ts.u.derived
1015 ->attr.unlimited_polymorphic;
1017 /* The intrinsic type needs to be converted to a temporary
1018 CLASS object. */
1019 tmp = gfc_typenode_for_spec (&class_ts);
1020 var = gfc_create_var (tmp, "class");
1022 /* Set the vptr. */
1023 ctree = gfc_class_vptr_get (var);
1025 vtab = gfc_find_vtab (&e->ts);
1026 gcc_assert (vtab);
1027 tmp = gfc_build_addr_expr (NULL_TREE, gfc_get_symbol_decl (vtab));
1028 gfc_add_modify (&parmse->pre, ctree,
1029 fold_convert (TREE_TYPE (ctree), tmp));
1031 /* Now set the data field. */
1032 ctree = gfc_class_data_get (var);
1033 if (parmse->ss && parmse->ss->info->useflags)
1035 /* For an array reference in an elemental procedure call we need
1036 to retain the ss to provide the scalarized array reference. */
1037 gfc_conv_expr_reference (parmse, e);
1038 tmp = fold_convert (TREE_TYPE (ctree), parmse->expr);
1039 gfc_add_modify (&parmse->pre, ctree, tmp);
1041 else
1043 ss = gfc_walk_expr (e);
1044 if (ss == gfc_ss_terminator)
1046 parmse->ss = NULL;
1047 gfc_conv_expr_reference (parmse, e);
1048 if (class_ts.u.derived->components->as
1049 && class_ts.u.derived->components->as->type == AS_ASSUMED_RANK)
1051 tmp = gfc_conv_scalar_to_descriptor (parmse, parmse->expr,
1052 gfc_expr_attr (e));
1053 tmp = fold_build1_loc (input_location, VIEW_CONVERT_EXPR,
1054 TREE_TYPE (ctree), tmp);
1056 else
1057 tmp = fold_convert (TREE_TYPE (ctree), parmse->expr);
1058 gfc_add_modify (&parmse->pre, ctree, tmp);
1060 else
1062 parmse->ss = ss;
1063 parmse->use_offset = 1;
1064 gfc_conv_expr_descriptor (parmse, e);
1066 /* Array references with vector subscripts and non-variable expressions
1067 need be converted to a one-based descriptor. */
1068 if (e->expr_type != EXPR_VARIABLE)
1070 for (dim = 0; dim < e->rank; ++dim)
1071 gfc_conv_shift_descriptor_lbound (&parmse->pre, parmse->expr,
1072 dim, gfc_index_one_node);
1075 if (class_ts.u.derived->components->as->rank != e->rank)
1077 tmp = fold_build1_loc (input_location, VIEW_CONVERT_EXPR,
1078 TREE_TYPE (ctree), parmse->expr);
1079 gfc_add_modify (&parmse->pre, ctree, tmp);
1081 else
1082 gfc_add_modify (&parmse->pre, ctree, parmse->expr);
1086 gcc_assert (class_ts.type == BT_CLASS);
1087 if (unlimited_poly)
1089 ctree = gfc_class_len_get (var);
1090 /* When the actual arg is a char array, then set the _len component of the
1091 unlimited polymorphic entity to the length of the string. */
1092 if (e->ts.type == BT_CHARACTER)
1094 /* Start with parmse->string_length because this seems to be set to a
1095 correct value more often. */
1096 if (parmse->string_length)
1097 tmp = parmse->string_length;
1098 /* When the string_length is not yet set, then try the backend_decl of
1099 the cl. */
1100 else if (e->ts.u.cl->backend_decl)
1101 tmp = e->ts.u.cl->backend_decl;
1102 /* If both of the above approaches fail, then try to generate an
1103 expression from the input, which is only feasible currently, when the
1104 expression can be evaluated to a constant one. */
1105 else
1107 /* Try to simplify the expression. */
1108 gfc_simplify_expr (e, 0);
1109 if (e->expr_type == EXPR_CONSTANT && !e->ts.u.cl->resolved)
1111 /* Amazingly all data is present to compute the length of a
1112 constant string, but the expression is not yet there. */
1113 e->ts.u.cl->length = gfc_get_constant_expr (BT_INTEGER,
1114 gfc_charlen_int_kind,
1115 &e->where);
1116 mpz_set_ui (e->ts.u.cl->length->value.integer,
1117 e->value.character.length);
1118 gfc_conv_const_charlen (e->ts.u.cl);
1119 e->ts.u.cl->resolved = 1;
1120 tmp = e->ts.u.cl->backend_decl;
1122 else
1124 gfc_error ("Cannot compute the length of the char array "
1125 "at %L.", &e->where);
1129 else
1130 tmp = integer_zero_node;
1132 gfc_add_modify (&parmse->pre, ctree, fold_convert (TREE_TYPE (ctree), tmp));
1134 else if (unlimited_poly)
1136 ctree = gfc_class_len_get (var);
1137 gfc_add_modify (&parmse->pre, ctree,
1138 fold_convert (TREE_TYPE (ctree),
1139 integer_zero_node));
1141 /* Pass the address of the class object. */
1142 parmse->expr = gfc_build_addr_expr (NULL_TREE, var);
1146 /* Takes a scalarized class array expression and returns the
1147 address of a temporary scalar class object of the 'declared'
1148 type.
1149 OOP-TODO: This could be improved by adding code that branched on
1150 the dynamic type being the same as the declared type. In this case
1151 the original class expression can be passed directly.
1152 optional_alloc_ptr is false when the dummy is neither allocatable
1153 nor a pointer; that's relevant for the optional handling.
1154 Set copyback to true if class container's _data and _vtab pointers
1155 might get modified. */
1157 void
1158 gfc_conv_class_to_class (gfc_se *parmse, gfc_expr *e, gfc_typespec class_ts,
1159 bool elemental, bool copyback, bool optional,
1160 bool optional_alloc_ptr)
1162 tree ctree;
1163 tree var;
1164 tree tmp;
1165 tree vptr;
1166 tree cond = NULL_TREE;
1167 tree slen = NULL_TREE;
1168 gfc_ref *ref;
1169 gfc_ref *class_ref;
1170 stmtblock_t block;
1171 bool full_array = false;
1173 gfc_init_block (&block);
1175 class_ref = NULL;
1176 for (ref = e->ref; ref; ref = ref->next)
1178 if (ref->type == REF_COMPONENT
1179 && ref->u.c.component->ts.type == BT_CLASS)
1180 class_ref = ref;
1182 if (ref->next == NULL)
1183 break;
1186 if ((ref == NULL || class_ref == ref)
1187 && !(gfc_is_class_array_function (e) && parmse->class_vptr != NULL_TREE)
1188 && (!class_ts.u.derived->components->as
1189 || class_ts.u.derived->components->as->rank != -1))
1190 return;
1192 /* Test for FULL_ARRAY. */
1193 if (e->rank == 0
1194 && ((gfc_expr_attr (e).codimension && gfc_expr_attr (e).dimension)
1195 || (class_ts.u.derived->components->as
1196 && class_ts.u.derived->components->as->type == AS_ASSUMED_RANK)))
1197 full_array = true;
1198 else
1199 gfc_is_class_array_ref (e, &full_array);
1201 /* The derived type needs to be converted to a temporary
1202 CLASS object. */
1203 tmp = gfc_typenode_for_spec (&class_ts);
1204 var = gfc_create_var (tmp, "class");
1206 /* Set the data. */
1207 ctree = gfc_class_data_get (var);
1208 if (class_ts.u.derived->components->as
1209 && e->rank != class_ts.u.derived->components->as->rank)
1211 if (e->rank == 0)
1213 tree type = get_scalar_to_descriptor_type (parmse->expr,
1214 gfc_expr_attr (e));
1215 gfc_add_modify (&block, gfc_conv_descriptor_dtype (ctree),
1216 gfc_get_dtype (type));
1218 tmp = gfc_class_data_get (parmse->expr);
1219 if (!POINTER_TYPE_P (TREE_TYPE (tmp)))
1220 tmp = gfc_build_addr_expr (NULL_TREE, tmp);
1222 gfc_conv_descriptor_data_set (&block, ctree, tmp);
1224 else
1225 class_array_data_assign (&block, ctree, parmse->expr, false);
1227 else
1229 if (TREE_TYPE (parmse->expr) != TREE_TYPE (ctree))
1230 parmse->expr = fold_build1_loc (input_location, VIEW_CONVERT_EXPR,
1231 TREE_TYPE (ctree), parmse->expr);
1232 gfc_add_modify (&block, ctree, parmse->expr);
1235 /* Return the data component, except in the case of scalarized array
1236 references, where nullification of the cannot occur and so there
1237 is no need. */
1238 if (!elemental && full_array && copyback)
1240 if (class_ts.u.derived->components->as
1241 && e->rank != class_ts.u.derived->components->as->rank)
1243 if (e->rank == 0)
1245 tmp = gfc_class_data_get (parmse->expr);
1246 gfc_add_modify (&parmse->post, tmp,
1247 fold_convert (TREE_TYPE (tmp),
1248 gfc_conv_descriptor_data_get (ctree)));
1250 else
1251 class_array_data_assign (&parmse->post, parmse->expr, ctree, true);
1253 else
1254 gfc_add_modify (&parmse->post, parmse->expr, ctree);
1257 /* Set the vptr. */
1258 ctree = gfc_class_vptr_get (var);
1260 /* The vptr is the second field of the actual argument.
1261 First we have to find the corresponding class reference. */
1263 tmp = NULL_TREE;
1264 if (gfc_is_class_array_function (e)
1265 && parmse->class_vptr != NULL_TREE)
1266 tmp = parmse->class_vptr;
1267 else if (class_ref == NULL
1268 && e->symtree && e->symtree->n.sym->ts.type == BT_CLASS)
1270 tmp = e->symtree->n.sym->backend_decl;
1272 if (TREE_CODE (tmp) == FUNCTION_DECL)
1273 tmp = gfc_get_fake_result_decl (e->symtree->n.sym, 0);
1275 if (DECL_LANG_SPECIFIC (tmp) && GFC_DECL_SAVED_DESCRIPTOR (tmp))
1276 tmp = GFC_DECL_SAVED_DESCRIPTOR (tmp);
1278 slen = build_zero_cst (size_type_node);
1280 else if (parmse->class_container != NULL_TREE)
1281 /* Don't redundantly evaluate the expression if the required information
1282 is already available. */
1283 tmp = parmse->class_container;
1284 else
1286 /* Remove everything after the last class reference, convert the
1287 expression and then recover its tailend once more. */
1288 gfc_se tmpse;
1289 ref = class_ref->next;
1290 class_ref->next = NULL;
1291 gfc_init_se (&tmpse, NULL);
1292 gfc_conv_expr (&tmpse, e);
1293 class_ref->next = ref;
1294 tmp = tmpse.expr;
1295 slen = tmpse.string_length;
1298 gcc_assert (tmp != NULL_TREE);
1300 /* Dereference if needs be. */
1301 if (TREE_CODE (TREE_TYPE (tmp)) == REFERENCE_TYPE)
1302 tmp = build_fold_indirect_ref_loc (input_location, tmp);
1304 if (!(gfc_is_class_array_function (e) && parmse->class_vptr))
1305 vptr = gfc_class_vptr_get (tmp);
1306 else
1307 vptr = tmp;
1309 gfc_add_modify (&block, ctree,
1310 fold_convert (TREE_TYPE (ctree), vptr));
1312 /* Return the vptr component, except in the case of scalarized array
1313 references, where the dynamic type cannot change. */
1314 if (!elemental && full_array && copyback)
1315 gfc_add_modify (&parmse->post, vptr,
1316 fold_convert (TREE_TYPE (vptr), ctree));
1318 /* For unlimited polymorphic objects also set the _len component. */
1319 if (class_ts.type == BT_CLASS
1320 && class_ts.u.derived->components
1321 && class_ts.u.derived->components->ts.u
1322 .derived->attr.unlimited_polymorphic)
1324 ctree = gfc_class_len_get (var);
1325 if (UNLIMITED_POLY (e))
1326 tmp = gfc_class_len_get (tmp);
1327 else if (e->ts.type == BT_CHARACTER)
1329 gcc_assert (slen != NULL_TREE);
1330 tmp = slen;
1332 else
1333 tmp = build_zero_cst (size_type_node);
1334 gfc_add_modify (&parmse->pre, ctree,
1335 fold_convert (TREE_TYPE (ctree), tmp));
1337 /* Return the len component, except in the case of scalarized array
1338 references, where the dynamic type cannot change. */
1339 if (!elemental && full_array && copyback
1340 && (UNLIMITED_POLY (e) || VAR_P (tmp)))
1341 gfc_add_modify (&parmse->post, tmp,
1342 fold_convert (TREE_TYPE (tmp), ctree));
1345 if (optional)
1347 tree tmp2;
1349 cond = gfc_conv_expr_present (e->symtree->n.sym);
1350 /* parmse->pre may contain some preparatory instructions for the
1351 temporary array descriptor. Those may only be executed when the
1352 optional argument is set, therefore add parmse->pre's instructions
1353 to block, which is later guarded by an if (optional_arg_given). */
1354 gfc_add_block_to_block (&parmse->pre, &block);
1355 block.head = parmse->pre.head;
1356 parmse->pre.head = NULL_TREE;
1357 tmp = gfc_finish_block (&block);
1359 if (optional_alloc_ptr)
1360 tmp2 = build_empty_stmt (input_location);
1361 else
1363 gfc_init_block (&block);
1365 tmp2 = gfc_conv_descriptor_data_get (gfc_class_data_get (var));
1366 gfc_add_modify (&block, tmp2, fold_convert (TREE_TYPE (tmp2),
1367 null_pointer_node));
1368 tmp2 = gfc_finish_block (&block);
1371 tmp = build3_loc (input_location, COND_EXPR, void_type_node,
1372 cond, tmp, tmp2);
1373 gfc_add_expr_to_block (&parmse->pre, tmp);
1375 else
1376 gfc_add_block_to_block (&parmse->pre, &block);
1378 /* Pass the address of the class object. */
1379 parmse->expr = gfc_build_addr_expr (NULL_TREE, var);
1381 if (optional && optional_alloc_ptr)
1382 parmse->expr = build3_loc (input_location, COND_EXPR,
1383 TREE_TYPE (parmse->expr),
1384 cond, parmse->expr,
1385 fold_convert (TREE_TYPE (parmse->expr),
1386 null_pointer_node));
1390 /* Given a class array declaration and an index, returns the address
1391 of the referenced element. */
1393 static tree
1394 gfc_get_class_array_ref (tree index, tree class_decl, tree data_comp,
1395 bool unlimited)
1397 tree data, size, tmp, ctmp, offset, ptr;
1399 data = data_comp != NULL_TREE ? data_comp :
1400 gfc_class_data_get (class_decl);
1401 size = gfc_class_vtab_size_get (class_decl);
1403 if (unlimited)
1405 tmp = fold_convert (gfc_array_index_type,
1406 gfc_class_len_get (class_decl));
1407 ctmp = fold_build2_loc (input_location, MULT_EXPR,
1408 gfc_array_index_type, size, tmp);
1409 tmp = fold_build2_loc (input_location, GT_EXPR,
1410 logical_type_node, tmp,
1411 build_zero_cst (TREE_TYPE (tmp)));
1412 size = fold_build3_loc (input_location, COND_EXPR,
1413 gfc_array_index_type, tmp, ctmp, size);
1416 offset = fold_build2_loc (input_location, MULT_EXPR,
1417 gfc_array_index_type,
1418 index, size);
1420 data = gfc_conv_descriptor_data_get (data);
1421 ptr = fold_convert (pvoid_type_node, data);
1422 ptr = fold_build_pointer_plus_loc (input_location, ptr, offset);
1423 return fold_convert (TREE_TYPE (data), ptr);
1427 /* Copies one class expression to another, assuming that if either
1428 'to' or 'from' are arrays they are packed. Should 'from' be
1429 NULL_TREE, the initialization expression for 'to' is used, assuming
1430 that the _vptr is set. */
1432 tree
1433 gfc_copy_class_to_class (tree from, tree to, tree nelems, bool unlimited)
1435 tree fcn;
1436 tree fcn_type;
1437 tree from_data;
1438 tree from_len;
1439 tree to_data;
1440 tree to_len;
1441 tree to_ref;
1442 tree from_ref;
1443 vec<tree, va_gc> *args;
1444 tree tmp;
1445 tree stdcopy;
1446 tree extcopy;
1447 tree index;
1448 bool is_from_desc = false, is_to_class = false;
1450 args = NULL;
1451 /* To prevent warnings on uninitialized variables. */
1452 from_len = to_len = NULL_TREE;
1454 if (from != NULL_TREE)
1455 fcn = gfc_class_vtab_copy_get (from);
1456 else
1457 fcn = gfc_class_vtab_copy_get (to);
1459 fcn_type = TREE_TYPE (TREE_TYPE (fcn));
1461 if (from != NULL_TREE)
1463 is_from_desc = GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (from));
1464 if (is_from_desc)
1466 from_data = from;
1467 from = GFC_DECL_SAVED_DESCRIPTOR (from);
1469 else
1471 /* Check that from is a class. When the class is part of a coarray,
1472 then from is a common pointer and is to be used as is. */
1473 tmp = POINTER_TYPE_P (TREE_TYPE (from))
1474 ? build_fold_indirect_ref (from) : from;
1475 from_data =
1476 (GFC_CLASS_TYPE_P (TREE_TYPE (tmp))
1477 || (DECL_P (tmp) && GFC_DECL_CLASS (tmp)))
1478 ? gfc_class_data_get (from) : from;
1479 is_from_desc = GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (from_data));
1482 else
1483 from_data = gfc_class_vtab_def_init_get (to);
1485 if (unlimited)
1487 if (from != NULL_TREE && unlimited)
1488 from_len = gfc_class_len_or_zero_get (from);
1489 else
1490 from_len = build_zero_cst (size_type_node);
1493 if (GFC_CLASS_TYPE_P (TREE_TYPE (to)))
1495 is_to_class = true;
1496 to_data = gfc_class_data_get (to);
1497 if (unlimited)
1498 to_len = gfc_class_len_get (to);
1500 else
1501 /* When to is a BT_DERIVED and not a BT_CLASS, then to_data == to. */
1502 to_data = to;
1504 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (to_data)))
1506 stmtblock_t loopbody;
1507 stmtblock_t body;
1508 stmtblock_t ifbody;
1509 gfc_loopinfo loop;
1510 tree orig_nelems = nelems; /* Needed for bounds check. */
1512 gfc_init_block (&body);
1513 tmp = fold_build2_loc (input_location, MINUS_EXPR,
1514 gfc_array_index_type, nelems,
1515 gfc_index_one_node);
1516 nelems = gfc_evaluate_now (tmp, &body);
1517 index = gfc_create_var (gfc_array_index_type, "S");
1519 if (is_from_desc)
1521 from_ref = gfc_get_class_array_ref (index, from, from_data,
1522 unlimited);
1523 vec_safe_push (args, from_ref);
1525 else
1526 vec_safe_push (args, from_data);
1528 if (is_to_class)
1529 to_ref = gfc_get_class_array_ref (index, to, to_data, unlimited);
1530 else
1532 tmp = gfc_conv_array_data (to);
1533 tmp = build_fold_indirect_ref_loc (input_location, tmp);
1534 to_ref = gfc_build_addr_expr (NULL_TREE,
1535 gfc_build_array_ref (tmp, index, to));
1537 vec_safe_push (args, to_ref);
1539 /* Add bounds check. */
1540 if ((gfc_option.rtcheck & GFC_RTCHECK_BOUNDS) > 0 && is_from_desc)
1542 char *msg;
1543 const char *name = "<<unknown>>";
1544 tree from_len;
1546 if (DECL_P (to))
1547 name = (const char *)(DECL_NAME (to)->identifier.id.str);
1549 from_len = gfc_conv_descriptor_size (from_data, 1);
1550 from_len = fold_convert (TREE_TYPE (orig_nelems), from_len);
1551 tmp = fold_build2_loc (input_location, NE_EXPR,
1552 logical_type_node, from_len, orig_nelems);
1553 msg = xasprintf ("Array bound mismatch for dimension %d "
1554 "of array '%s' (%%ld/%%ld)",
1555 1, name);
1557 gfc_trans_runtime_check (true, false, tmp, &body,
1558 &gfc_current_locus, msg,
1559 fold_convert (long_integer_type_node, orig_nelems),
1560 fold_convert (long_integer_type_node, from_len));
1562 free (msg);
1565 tmp = build_call_vec (fcn_type, fcn, args);
1567 /* Build the body of the loop. */
1568 gfc_init_block (&loopbody);
1569 gfc_add_expr_to_block (&loopbody, tmp);
1571 /* Build the loop and return. */
1572 gfc_init_loopinfo (&loop);
1573 loop.dimen = 1;
1574 loop.from[0] = gfc_index_zero_node;
1575 loop.loopvar[0] = index;
1576 loop.to[0] = nelems;
1577 gfc_trans_scalarizing_loops (&loop, &loopbody);
1578 gfc_init_block (&ifbody);
1579 gfc_add_block_to_block (&ifbody, &loop.pre);
1580 stdcopy = gfc_finish_block (&ifbody);
1581 /* In initialization mode from_len is a constant zero. */
1582 if (unlimited && !integer_zerop (from_len))
1584 vec_safe_push (args, from_len);
1585 vec_safe_push (args, to_len);
1586 tmp = build_call_vec (fcn_type, fcn, args);
1587 /* Build the body of the loop. */
1588 gfc_init_block (&loopbody);
1589 gfc_add_expr_to_block (&loopbody, tmp);
1591 /* Build the loop and return. */
1592 gfc_init_loopinfo (&loop);
1593 loop.dimen = 1;
1594 loop.from[0] = gfc_index_zero_node;
1595 loop.loopvar[0] = index;
1596 loop.to[0] = nelems;
1597 gfc_trans_scalarizing_loops (&loop, &loopbody);
1598 gfc_init_block (&ifbody);
1599 gfc_add_block_to_block (&ifbody, &loop.pre);
1600 extcopy = gfc_finish_block (&ifbody);
1602 tmp = fold_build2_loc (input_location, GT_EXPR,
1603 logical_type_node, from_len,
1604 build_zero_cst (TREE_TYPE (from_len)));
1605 tmp = fold_build3_loc (input_location, COND_EXPR,
1606 void_type_node, tmp, extcopy, stdcopy);
1607 gfc_add_expr_to_block (&body, tmp);
1608 tmp = gfc_finish_block (&body);
1610 else
1612 gfc_add_expr_to_block (&body, stdcopy);
1613 tmp = gfc_finish_block (&body);
1615 gfc_cleanup_loop (&loop);
1617 else
1619 gcc_assert (!is_from_desc);
1620 vec_safe_push (args, from_data);
1621 vec_safe_push (args, to_data);
1622 stdcopy = build_call_vec (fcn_type, fcn, args);
1624 /* In initialization mode from_len is a constant zero. */
1625 if (unlimited && !integer_zerop (from_len))
1627 vec_safe_push (args, from_len);
1628 vec_safe_push (args, to_len);
1629 extcopy = build_call_vec (fcn_type, unshare_expr (fcn), args);
1630 tmp = fold_build2_loc (input_location, GT_EXPR,
1631 logical_type_node, from_len,
1632 build_zero_cst (TREE_TYPE (from_len)));
1633 tmp = fold_build3_loc (input_location, COND_EXPR,
1634 void_type_node, tmp, extcopy, stdcopy);
1636 else
1637 tmp = stdcopy;
1640 /* Only copy _def_init to to_data, when it is not a NULL-pointer. */
1641 if (from == NULL_TREE)
1643 tree cond;
1644 cond = fold_build2_loc (input_location, NE_EXPR,
1645 logical_type_node,
1646 from_data, null_pointer_node);
1647 tmp = fold_build3_loc (input_location, COND_EXPR,
1648 void_type_node, cond,
1649 tmp, build_empty_stmt (input_location));
1652 return tmp;
1656 static tree
1657 gfc_trans_class_array_init_assign (gfc_expr *rhs, gfc_expr *lhs, gfc_expr *obj)
1659 gfc_actual_arglist *actual;
1660 gfc_expr *ppc;
1661 gfc_code *ppc_code;
1662 tree res;
1664 actual = gfc_get_actual_arglist ();
1665 actual->expr = gfc_copy_expr (rhs);
1666 actual->next = gfc_get_actual_arglist ();
1667 actual->next->expr = gfc_copy_expr (lhs);
1668 ppc = gfc_copy_expr (obj);
1669 gfc_add_vptr_component (ppc);
1670 gfc_add_component_ref (ppc, "_copy");
1671 ppc_code = gfc_get_code (EXEC_CALL);
1672 ppc_code->resolved_sym = ppc->symtree->n.sym;
1673 /* Although '_copy' is set to be elemental in class.cc, it is
1674 not staying that way. Find out why, sometime.... */
1675 ppc_code->resolved_sym->attr.elemental = 1;
1676 ppc_code->ext.actual = actual;
1677 ppc_code->expr1 = ppc;
1678 /* Since '_copy' is elemental, the scalarizer will take care
1679 of arrays in gfc_trans_call. */
1680 res = gfc_trans_call (ppc_code, false, NULL, NULL, false);
1681 gfc_free_statements (ppc_code);
1683 if (UNLIMITED_POLY(obj))
1685 /* Check if rhs is non-NULL. */
1686 gfc_se src;
1687 gfc_init_se (&src, NULL);
1688 gfc_conv_expr (&src, rhs);
1689 src.expr = gfc_build_addr_expr (NULL_TREE, src.expr);
1690 tree cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
1691 src.expr, fold_convert (TREE_TYPE (src.expr),
1692 null_pointer_node));
1693 res = build3_loc (input_location, COND_EXPR, TREE_TYPE (res), cond, res,
1694 build_empty_stmt (input_location));
1697 return res;
1700 /* Special case for initializing a polymorphic dummy with INTENT(OUT).
1701 A MEMCPY is needed to copy the full data from the default initializer
1702 of the dynamic type. */
1704 tree
1705 gfc_trans_class_init_assign (gfc_code *code)
1707 stmtblock_t block;
1708 tree tmp;
1709 gfc_se dst,src,memsz;
1710 gfc_expr *lhs, *rhs, *sz;
1712 gfc_start_block (&block);
1714 lhs = gfc_copy_expr (code->expr1);
1716 rhs = gfc_copy_expr (code->expr1);
1717 gfc_add_vptr_component (rhs);
1719 /* Make sure that the component backend_decls have been built, which
1720 will not have happened if the derived types concerned have not
1721 been referenced. */
1722 gfc_get_derived_type (rhs->ts.u.derived);
1723 gfc_add_def_init_component (rhs);
1724 /* The _def_init is always scalar. */
1725 rhs->rank = 0;
1727 if (code->expr1->ts.type == BT_CLASS
1728 && CLASS_DATA (code->expr1)->attr.dimension)
1730 gfc_array_spec *tmparr = gfc_get_array_spec ();
1731 *tmparr = *CLASS_DATA (code->expr1)->as;
1732 /* Adding the array ref to the class expression results in correct
1733 indexing to the dynamic type. */
1734 gfc_add_full_array_ref (lhs, tmparr);
1735 tmp = gfc_trans_class_array_init_assign (rhs, lhs, code->expr1);
1737 else
1739 /* Scalar initialization needs the _data component. */
1740 gfc_add_data_component (lhs);
1741 sz = gfc_copy_expr (code->expr1);
1742 gfc_add_vptr_component (sz);
1743 gfc_add_size_component (sz);
1745 gfc_init_se (&dst, NULL);
1746 gfc_init_se (&src, NULL);
1747 gfc_init_se (&memsz, NULL);
1748 gfc_conv_expr (&dst, lhs);
1749 gfc_conv_expr (&src, rhs);
1750 gfc_conv_expr (&memsz, sz);
1751 gfc_add_block_to_block (&block, &src.pre);
1752 src.expr = gfc_build_addr_expr (NULL_TREE, src.expr);
1754 tmp = gfc_build_memcpy_call (dst.expr, src.expr, memsz.expr);
1756 if (UNLIMITED_POLY(code->expr1))
1758 /* Check if _def_init is non-NULL. */
1759 tree cond = fold_build2_loc (input_location, NE_EXPR,
1760 logical_type_node, src.expr,
1761 fold_convert (TREE_TYPE (src.expr),
1762 null_pointer_node));
1763 tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp), cond,
1764 tmp, build_empty_stmt (input_location));
1768 if (code->expr1->symtree->n.sym->attr.dummy
1769 && (code->expr1->symtree->n.sym->attr.optional
1770 || code->expr1->symtree->n.sym->ns->proc_name->attr.entry_master))
1772 tree present = gfc_conv_expr_present (code->expr1->symtree->n.sym);
1773 tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp),
1774 present, tmp,
1775 build_empty_stmt (input_location));
1778 gfc_add_expr_to_block (&block, tmp);
1780 return gfc_finish_block (&block);
1784 /* Class valued elemental function calls or class array elements arriving
1785 in gfc_trans_scalar_assign come here. Wherever possible the vptr copy
1786 is used to ensure that the rhs dynamic type is assigned to the lhs. */
1788 static bool
1789 trans_scalar_class_assign (stmtblock_t *block, gfc_se *lse, gfc_se *rse)
1791 tree fcn;
1792 tree rse_expr;
1793 tree class_data;
1794 tree tmp;
1795 tree zero;
1796 tree cond;
1797 tree final_cond;
1798 stmtblock_t inner_block;
1799 bool is_descriptor;
1800 bool not_call_expr = TREE_CODE (rse->expr) != CALL_EXPR;
1801 bool not_lhs_array_type;
1803 /* Temporaries arising from dependencies in assignment get cast as a
1804 character type of the dynamic size of the rhs. Use the vptr copy
1805 for this case. */
1806 tmp = TREE_TYPE (lse->expr);
1807 not_lhs_array_type = !(tmp && TREE_CODE (tmp) == ARRAY_TYPE
1808 && TYPE_MAX_VALUE (TYPE_DOMAIN (tmp)) != NULL_TREE);
1810 /* Use ordinary assignment if the rhs is not a call expression or
1811 the lhs is not a class entity or an array(ie. character) type. */
1812 if ((not_call_expr && gfc_get_class_from_expr (lse->expr) == NULL_TREE)
1813 && not_lhs_array_type)
1814 return false;
1816 /* Ordinary assignment can be used if both sides are class expressions
1817 since the dynamic type is preserved by copying the vptr. This
1818 should only occur, where temporaries are involved. */
1819 if (GFC_CLASS_TYPE_P (TREE_TYPE (lse->expr))
1820 && GFC_CLASS_TYPE_P (TREE_TYPE (rse->expr)))
1821 return false;
1823 /* Fix the class expression and the class data of the rhs. */
1824 if (!GFC_CLASS_TYPE_P (TREE_TYPE (rse->expr))
1825 || not_call_expr)
1827 tmp = gfc_get_class_from_expr (rse->expr);
1828 if (tmp == NULL_TREE)
1829 return false;
1830 rse_expr = gfc_evaluate_now (tmp, block);
1832 else
1833 rse_expr = gfc_evaluate_now (rse->expr, block);
1835 class_data = gfc_class_data_get (rse_expr);
1837 /* Check that the rhs data is not null. */
1838 is_descriptor = GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (class_data));
1839 if (is_descriptor)
1840 class_data = gfc_conv_descriptor_data_get (class_data);
1841 class_data = gfc_evaluate_now (class_data, block);
1843 zero = build_int_cst (TREE_TYPE (class_data), 0);
1844 cond = fold_build2_loc (input_location, NE_EXPR,
1845 logical_type_node,
1846 class_data, zero);
1848 /* Copy the rhs to the lhs. */
1849 fcn = gfc_vptr_copy_get (gfc_class_vptr_get (rse_expr));
1850 fcn = build_fold_indirect_ref_loc (input_location, fcn);
1851 tmp = gfc_evaluate_now (gfc_build_addr_expr (NULL, rse->expr), block);
1852 tmp = is_descriptor ? tmp : class_data;
1853 tmp = build_call_expr_loc (input_location, fcn, 2, tmp,
1854 gfc_build_addr_expr (NULL, lse->expr));
1855 gfc_add_expr_to_block (block, tmp);
1857 /* Only elemental function results need to be finalised and freed. */
1858 if (not_call_expr)
1859 return true;
1861 /* Finalize the class data if needed. */
1862 gfc_init_block (&inner_block);
1863 fcn = gfc_vptr_final_get (gfc_class_vptr_get (rse_expr));
1864 zero = build_int_cst (TREE_TYPE (fcn), 0);
1865 final_cond = fold_build2_loc (input_location, NE_EXPR,
1866 logical_type_node, fcn, zero);
1867 fcn = build_fold_indirect_ref_loc (input_location, fcn);
1868 tmp = build_call_expr_loc (input_location, fcn, 1, class_data);
1869 tmp = build3_v (COND_EXPR, final_cond,
1870 tmp, build_empty_stmt (input_location));
1871 gfc_add_expr_to_block (&inner_block, tmp);
1873 /* Free the class data. */
1874 tmp = gfc_call_free (class_data);
1875 tmp = build3_v (COND_EXPR, cond, tmp,
1876 build_empty_stmt (input_location));
1877 gfc_add_expr_to_block (&inner_block, tmp);
1879 /* Finish the inner block and subject it to the condition on the
1880 class data being non-zero. */
1881 tmp = gfc_finish_block (&inner_block);
1882 tmp = build3_v (COND_EXPR, cond, tmp,
1883 build_empty_stmt (input_location));
1884 gfc_add_expr_to_block (block, tmp);
1886 return true;
1889 /* End of prototype trans-class.c */
1892 static void
1893 realloc_lhs_warning (bt type, bool array, locus *where)
1895 if (array && type != BT_CLASS && type != BT_DERIVED && warn_realloc_lhs)
1896 gfc_warning (OPT_Wrealloc_lhs,
1897 "Code for reallocating the allocatable array at %L will "
1898 "be added", where);
1899 else if (warn_realloc_lhs_all)
1900 gfc_warning (OPT_Wrealloc_lhs_all,
1901 "Code for reallocating the allocatable variable at %L "
1902 "will be added", where);
1906 static void gfc_apply_interface_mapping_to_expr (gfc_interface_mapping *,
1907 gfc_expr *);
1909 /* Copy the scalarization loop variables. */
1911 static void
1912 gfc_copy_se_loopvars (gfc_se * dest, gfc_se * src)
1914 dest->ss = src->ss;
1915 dest->loop = src->loop;
1919 /* Initialize a simple expression holder.
1921 Care must be taken when multiple se are created with the same parent.
1922 The child se must be kept in sync. The easiest way is to delay creation
1923 of a child se until after the previous se has been translated. */
1925 void
1926 gfc_init_se (gfc_se * se, gfc_se * parent)
1928 memset (se, 0, sizeof (gfc_se));
1929 gfc_init_block (&se->pre);
1930 gfc_init_block (&se->finalblock);
1931 gfc_init_block (&se->post);
1933 se->parent = parent;
1935 if (parent)
1936 gfc_copy_se_loopvars (se, parent);
1940 /* Advances to the next SS in the chain. Use this rather than setting
1941 se->ss = se->ss->next because all the parents needs to be kept in sync.
1942 See gfc_init_se. */
1944 void
1945 gfc_advance_se_ss_chain (gfc_se * se)
1947 gfc_se *p;
1948 gfc_ss *ss;
1950 gcc_assert (se != NULL && se->ss != NULL && se->ss != gfc_ss_terminator);
1952 p = se;
1953 /* Walk down the parent chain. */
1954 while (p != NULL)
1956 /* Simple consistency check. */
1957 gcc_assert (p->parent == NULL || p->parent->ss == p->ss
1958 || p->parent->ss->nested_ss == p->ss);
1960 /* If we were in a nested loop, the next scalarized expression can be
1961 on the parent ss' next pointer. Thus we should not take the next
1962 pointer blindly, but rather go up one nest level as long as next
1963 is the end of chain. */
1964 ss = p->ss;
1965 while (ss->next == gfc_ss_terminator && ss->parent != NULL)
1966 ss = ss->parent;
1968 p->ss = ss->next;
1970 p = p->parent;
1975 /* Ensures the result of the expression as either a temporary variable
1976 or a constant so that it can be used repeatedly. */
1978 void
1979 gfc_make_safe_expr (gfc_se * se)
1981 tree var;
1983 if (CONSTANT_CLASS_P (se->expr))
1984 return;
1986 /* We need a temporary for this result. */
1987 var = gfc_create_var (TREE_TYPE (se->expr), NULL);
1988 gfc_add_modify (&se->pre, var, se->expr);
1989 se->expr = var;
1993 /* Return an expression which determines if a dummy parameter is present.
1994 Also used for arguments to procedures with multiple entry points. */
1996 tree
1997 gfc_conv_expr_present (gfc_symbol * sym, bool use_saved_desc)
1999 tree decl, orig_decl, cond;
2001 gcc_assert (sym->attr.dummy);
2002 orig_decl = decl = gfc_get_symbol_decl (sym);
2004 /* Intrinsic scalars with VALUE attribute which are passed by value
2005 use a hidden argument to denote the present status. */
2006 if (sym->attr.value && !sym->attr.dimension
2007 && sym->ts.type != BT_CLASS && !gfc_bt_struct (sym->ts.type))
2009 char name[GFC_MAX_SYMBOL_LEN + 2];
2010 tree tree_name;
2012 gcc_assert (TREE_CODE (decl) == PARM_DECL);
2013 name[0] = '.';
2014 strcpy (&name[1], sym->name);
2015 tree_name = get_identifier (name);
2017 /* Walk function argument list to find hidden arg. */
2018 cond = DECL_ARGUMENTS (DECL_CONTEXT (decl));
2019 for ( ; cond != NULL_TREE; cond = TREE_CHAIN (cond))
2020 if (DECL_NAME (cond) == tree_name
2021 && DECL_ARTIFICIAL (cond))
2022 break;
2024 gcc_assert (cond);
2025 return cond;
2028 /* Assumed-shape arrays use a local variable for the array data;
2029 the actual PARAM_DECL is in a saved decl. As the local variable
2030 is NULL, it can be checked instead, unless use_saved_desc is
2031 requested. */
2033 if (use_saved_desc && TREE_CODE (decl) != PARM_DECL)
2035 gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl))
2036 || GFC_ARRAY_TYPE_P (TREE_TYPE (decl)));
2037 decl = GFC_DECL_SAVED_DESCRIPTOR (decl);
2040 cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node, decl,
2041 fold_convert (TREE_TYPE (decl), null_pointer_node));
2043 /* Fortran 2008 allows to pass null pointers and non-associated pointers
2044 as actual argument to denote absent dummies. For array descriptors,
2045 we thus also need to check the array descriptor. For BT_CLASS, it
2046 can also occur for scalars and F2003 due to type->class wrapping and
2047 class->class wrapping. Note further that BT_CLASS always uses an
2048 array descriptor for arrays, also for explicit-shape/assumed-size.
2049 For assumed-rank arrays, no local variable is generated, hence,
2050 the following also applies with !use_saved_desc. */
2052 if ((use_saved_desc || TREE_CODE (orig_decl) == PARM_DECL)
2053 && !sym->attr.allocatable
2054 && ((sym->ts.type != BT_CLASS && !sym->attr.pointer)
2055 || (sym->ts.type == BT_CLASS
2056 && !CLASS_DATA (sym)->attr.allocatable
2057 && !CLASS_DATA (sym)->attr.class_pointer))
2058 && ((gfc_option.allow_std & GFC_STD_F2008) != 0
2059 || sym->ts.type == BT_CLASS))
2061 tree tmp;
2063 if ((sym->as && (sym->as->type == AS_ASSUMED_SHAPE
2064 || sym->as->type == AS_ASSUMED_RANK
2065 || sym->attr.codimension))
2066 || (sym->ts.type == BT_CLASS && CLASS_DATA (sym)->as))
2068 tmp = build_fold_indirect_ref_loc (input_location, decl);
2069 if (sym->ts.type == BT_CLASS)
2070 tmp = gfc_class_data_get (tmp);
2071 tmp = gfc_conv_array_data (tmp);
2073 else if (sym->ts.type == BT_CLASS)
2074 tmp = gfc_class_data_get (decl);
2075 else
2076 tmp = NULL_TREE;
2078 if (tmp != NULL_TREE)
2080 tmp = fold_build2_loc (input_location, NE_EXPR, logical_type_node, tmp,
2081 fold_convert (TREE_TYPE (tmp), null_pointer_node));
2082 cond = fold_build2_loc (input_location, TRUTH_ANDIF_EXPR,
2083 logical_type_node, cond, tmp);
2087 return cond;
2091 /* Converts a missing, dummy argument into a null or zero. */
2093 void
2094 gfc_conv_missing_dummy (gfc_se * se, gfc_expr * arg, gfc_typespec ts, int kind)
2096 tree present;
2097 tree tmp;
2099 present = gfc_conv_expr_present (arg->symtree->n.sym);
2101 if (kind > 0)
2103 /* Create a temporary and convert it to the correct type. */
2104 tmp = gfc_get_int_type (kind);
2105 tmp = fold_convert (tmp, build_fold_indirect_ref_loc (input_location,
2106 se->expr));
2108 /* Test for a NULL value. */
2109 tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp), present,
2110 tmp, fold_convert (TREE_TYPE (tmp), integer_one_node));
2111 tmp = gfc_evaluate_now (tmp, &se->pre);
2112 se->expr = gfc_build_addr_expr (NULL_TREE, tmp);
2114 else
2116 tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (se->expr),
2117 present, se->expr,
2118 build_zero_cst (TREE_TYPE (se->expr)));
2119 tmp = gfc_evaluate_now (tmp, &se->pre);
2120 se->expr = tmp;
2123 if (ts.type == BT_CHARACTER)
2125 tmp = build_int_cst (gfc_charlen_type_node, 0);
2126 tmp = fold_build3_loc (input_location, COND_EXPR, gfc_charlen_type_node,
2127 present, se->string_length, tmp);
2128 tmp = gfc_evaluate_now (tmp, &se->pre);
2129 se->string_length = tmp;
2131 return;
2135 /* Get the character length of an expression, looking through gfc_refs
2136 if necessary. */
2138 tree
2139 gfc_get_expr_charlen (gfc_expr *e)
2141 gfc_ref *r;
2142 tree length;
2143 tree previous = NULL_TREE;
2144 gfc_se se;
2146 gcc_assert (e->expr_type == EXPR_VARIABLE
2147 && e->ts.type == BT_CHARACTER);
2149 length = NULL; /* To silence compiler warning. */
2151 if (is_subref_array (e) && e->ts.u.cl->length)
2153 gfc_se tmpse;
2154 gfc_init_se (&tmpse, NULL);
2155 gfc_conv_expr_type (&tmpse, e->ts.u.cl->length, gfc_charlen_type_node);
2156 e->ts.u.cl->backend_decl = tmpse.expr;
2157 return tmpse.expr;
2160 /* First candidate: if the variable is of type CHARACTER, the
2161 expression's length could be the length of the character
2162 variable. */
2163 if (e->symtree->n.sym->ts.type == BT_CHARACTER)
2164 length = e->symtree->n.sym->ts.u.cl->backend_decl;
2166 /* Look through the reference chain for component references. */
2167 for (r = e->ref; r; r = r->next)
2169 previous = length;
2170 switch (r->type)
2172 case REF_COMPONENT:
2173 if (r->u.c.component->ts.type == BT_CHARACTER)
2174 length = r->u.c.component->ts.u.cl->backend_decl;
2175 break;
2177 case REF_ARRAY:
2178 /* Do nothing. */
2179 break;
2181 case REF_SUBSTRING:
2182 gfc_init_se (&se, NULL);
2183 gfc_conv_expr_type (&se, r->u.ss.start, gfc_charlen_type_node);
2184 length = se.expr;
2185 if (r->u.ss.end)
2186 gfc_conv_expr_type (&se, r->u.ss.end, gfc_charlen_type_node);
2187 else
2188 se.expr = previous;
2189 length = fold_build2_loc (input_location, MINUS_EXPR,
2190 gfc_charlen_type_node,
2191 se.expr, length);
2192 length = fold_build2_loc (input_location, PLUS_EXPR,
2193 gfc_charlen_type_node, length,
2194 gfc_index_one_node);
2195 break;
2197 default:
2198 gcc_unreachable ();
2199 break;
2203 gcc_assert (length != NULL);
2204 return length;
2208 /* Return for an expression the backend decl of the coarray. */
2210 tree
2211 gfc_get_tree_for_caf_expr (gfc_expr *expr)
2213 tree caf_decl;
2214 bool found = false;
2215 gfc_ref *ref;
2217 gcc_assert (expr && expr->expr_type == EXPR_VARIABLE);
2219 /* Not-implemented diagnostic. */
2220 if (expr->symtree->n.sym->ts.type == BT_CLASS
2221 && UNLIMITED_POLY (expr->symtree->n.sym)
2222 && CLASS_DATA (expr->symtree->n.sym)->attr.codimension)
2223 gfc_error ("Sorry, coindexed access to an unlimited polymorphic object at "
2224 "%L is not supported", &expr->where);
2226 for (ref = expr->ref; ref; ref = ref->next)
2227 if (ref->type == REF_COMPONENT)
2229 if (ref->u.c.component->ts.type == BT_CLASS
2230 && UNLIMITED_POLY (ref->u.c.component)
2231 && CLASS_DATA (ref->u.c.component)->attr.codimension)
2232 gfc_error ("Sorry, coindexed access to an unlimited polymorphic "
2233 "component at %L is not supported", &expr->where);
2236 /* Make sure the backend_decl is present before accessing it. */
2237 caf_decl = expr->symtree->n.sym->backend_decl == NULL_TREE
2238 ? gfc_get_symbol_decl (expr->symtree->n.sym)
2239 : expr->symtree->n.sym->backend_decl;
2241 if (expr->symtree->n.sym->ts.type == BT_CLASS)
2243 if (expr->ref && expr->ref->type == REF_ARRAY)
2245 caf_decl = gfc_class_data_get (caf_decl);
2246 if (CLASS_DATA (expr->symtree->n.sym)->attr.codimension)
2247 return caf_decl;
2249 for (ref = expr->ref; ref; ref = ref->next)
2251 if (ref->type == REF_COMPONENT
2252 && strcmp (ref->u.c.component->name, "_data") != 0)
2254 caf_decl = gfc_class_data_get (caf_decl);
2255 if (CLASS_DATA (expr->symtree->n.sym)->attr.codimension)
2256 return caf_decl;
2257 break;
2259 else if (ref->type == REF_ARRAY && ref->u.ar.dimen)
2260 break;
2263 if (expr->symtree->n.sym->attr.codimension)
2264 return caf_decl;
2266 /* The following code assumes that the coarray is a component reachable via
2267 only scalar components/variables; the Fortran standard guarantees this. */
2269 for (ref = expr->ref; ref; ref = ref->next)
2270 if (ref->type == REF_COMPONENT)
2272 gfc_component *comp = ref->u.c.component;
2274 if (POINTER_TYPE_P (TREE_TYPE (caf_decl)))
2275 caf_decl = build_fold_indirect_ref_loc (input_location, caf_decl);
2276 caf_decl = fold_build3_loc (input_location, COMPONENT_REF,
2277 TREE_TYPE (comp->backend_decl), caf_decl,
2278 comp->backend_decl, NULL_TREE);
2279 if (comp->ts.type == BT_CLASS)
2281 caf_decl = gfc_class_data_get (caf_decl);
2282 if (CLASS_DATA (comp)->attr.codimension)
2284 found = true;
2285 break;
2288 if (comp->attr.codimension)
2290 found = true;
2291 break;
2294 gcc_assert (found && caf_decl);
2295 return caf_decl;
2299 /* Obtain the Coarray token - and optionally also the offset. */
2301 void
2302 gfc_get_caf_token_offset (gfc_se *se, tree *token, tree *offset, tree caf_decl,
2303 tree se_expr, gfc_expr *expr)
2305 tree tmp;
2307 /* Coarray token. */
2308 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (caf_decl)))
2310 gcc_assert (GFC_TYPE_ARRAY_AKIND (TREE_TYPE (caf_decl))
2311 == GFC_ARRAY_ALLOCATABLE
2312 || expr->symtree->n.sym->attr.select_type_temporary);
2313 *token = gfc_conv_descriptor_token (caf_decl);
2315 else if (DECL_LANG_SPECIFIC (caf_decl)
2316 && GFC_DECL_TOKEN (caf_decl) != NULL_TREE)
2317 *token = GFC_DECL_TOKEN (caf_decl);
2318 else
2320 gcc_assert (GFC_ARRAY_TYPE_P (TREE_TYPE (caf_decl))
2321 && GFC_TYPE_ARRAY_CAF_TOKEN (TREE_TYPE (caf_decl)) != NULL_TREE);
2322 *token = GFC_TYPE_ARRAY_CAF_TOKEN (TREE_TYPE (caf_decl));
2325 if (offset == NULL)
2326 return;
2328 /* Offset between the coarray base address and the address wanted. */
2329 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (caf_decl))
2330 && (GFC_TYPE_ARRAY_AKIND (TREE_TYPE (caf_decl)) == GFC_ARRAY_ALLOCATABLE
2331 || GFC_TYPE_ARRAY_AKIND (TREE_TYPE (caf_decl)) == GFC_ARRAY_POINTER))
2332 *offset = build_int_cst (gfc_array_index_type, 0);
2333 else if (DECL_LANG_SPECIFIC (caf_decl)
2334 && GFC_DECL_CAF_OFFSET (caf_decl) != NULL_TREE)
2335 *offset = GFC_DECL_CAF_OFFSET (caf_decl);
2336 else if (GFC_TYPE_ARRAY_CAF_OFFSET (TREE_TYPE (caf_decl)) != NULL_TREE)
2337 *offset = GFC_TYPE_ARRAY_CAF_OFFSET (TREE_TYPE (caf_decl));
2338 else
2339 *offset = build_int_cst (gfc_array_index_type, 0);
2341 if (POINTER_TYPE_P (TREE_TYPE (se_expr))
2342 && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (TREE_TYPE (se_expr))))
2344 tmp = build_fold_indirect_ref_loc (input_location, se_expr);
2345 tmp = gfc_conv_descriptor_data_get (tmp);
2347 else if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se_expr)))
2348 tmp = gfc_conv_descriptor_data_get (se_expr);
2349 else
2351 gcc_assert (POINTER_TYPE_P (TREE_TYPE (se_expr)));
2352 tmp = se_expr;
2355 *offset = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
2356 *offset, fold_convert (gfc_array_index_type, tmp));
2358 if (expr->symtree->n.sym->ts.type == BT_DERIVED
2359 && expr->symtree->n.sym->attr.codimension
2360 && expr->symtree->n.sym->ts.u.derived->attr.alloc_comp)
2362 gfc_expr *base_expr = gfc_copy_expr (expr);
2363 gfc_ref *ref = base_expr->ref;
2364 gfc_se base_se;
2366 // Iterate through the refs until the last one.
2367 while (ref->next)
2368 ref = ref->next;
2370 if (ref->type == REF_ARRAY
2371 && ref->u.ar.type != AR_FULL)
2373 const int ranksum = ref->u.ar.dimen + ref->u.ar.codimen;
2374 int i;
2375 for (i = 0; i < ranksum; ++i)
2377 ref->u.ar.start[i] = NULL;
2378 ref->u.ar.end[i] = NULL;
2380 ref->u.ar.type = AR_FULL;
2382 gfc_init_se (&base_se, NULL);
2383 if (gfc_caf_attr (base_expr).dimension)
2385 gfc_conv_expr_descriptor (&base_se, base_expr);
2386 tmp = gfc_conv_descriptor_data_get (base_se.expr);
2388 else
2390 gfc_conv_expr (&base_se, base_expr);
2391 tmp = base_se.expr;
2394 gfc_free_expr (base_expr);
2395 gfc_add_block_to_block (&se->pre, &base_se.pre);
2396 gfc_add_block_to_block (&se->post, &base_se.post);
2398 else if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (caf_decl)))
2399 tmp = gfc_conv_descriptor_data_get (caf_decl);
2400 else
2402 gcc_assert (POINTER_TYPE_P (TREE_TYPE (caf_decl)));
2403 tmp = caf_decl;
2406 *offset = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
2407 fold_convert (gfc_array_index_type, *offset),
2408 fold_convert (gfc_array_index_type, tmp));
2412 /* Convert the coindex of a coarray into an image index; the result is
2413 image_num = (idx(1)-lcobound(1)+1) + (idx(2)-lcobound(2))*extent(1)
2414 + (idx(3)-lcobound(3))*extend(1)*extent(2) + ... */
2416 tree
2417 gfc_caf_get_image_index (stmtblock_t *block, gfc_expr *e, tree desc)
2419 gfc_ref *ref;
2420 tree lbound, ubound, extent, tmp, img_idx;
2421 gfc_se se;
2422 int i;
2424 for (ref = e->ref; ref; ref = ref->next)
2425 if (ref->type == REF_ARRAY && ref->u.ar.codimen > 0)
2426 break;
2427 gcc_assert (ref != NULL);
2429 if (ref->u.ar.dimen_type[ref->u.ar.dimen] == DIMEN_THIS_IMAGE)
2431 return build_call_expr_loc (input_location, gfor_fndecl_caf_this_image, 1,
2432 integer_zero_node);
2435 img_idx = build_zero_cst (gfc_array_index_type);
2436 extent = build_one_cst (gfc_array_index_type);
2437 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (desc)))
2438 for (i = ref->u.ar.dimen; i < ref->u.ar.dimen + ref->u.ar.codimen; i++)
2440 gfc_init_se (&se, NULL);
2441 gfc_conv_expr_type (&se, ref->u.ar.start[i], gfc_array_index_type);
2442 gfc_add_block_to_block (block, &se.pre);
2443 lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[i]);
2444 tmp = fold_build2_loc (input_location, MINUS_EXPR,
2445 TREE_TYPE (lbound), se.expr, lbound);
2446 tmp = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (tmp),
2447 extent, tmp);
2448 img_idx = fold_build2_loc (input_location, PLUS_EXPR,
2449 TREE_TYPE (tmp), img_idx, tmp);
2450 if (i < ref->u.ar.dimen + ref->u.ar.codimen - 1)
2452 ubound = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[i]);
2453 tmp = gfc_conv_array_extent_dim (lbound, ubound, NULL);
2454 extent = fold_build2_loc (input_location, MULT_EXPR,
2455 TREE_TYPE (tmp), extent, tmp);
2458 else
2459 for (i = ref->u.ar.dimen; i < ref->u.ar.dimen + ref->u.ar.codimen; i++)
2461 gfc_init_se (&se, NULL);
2462 gfc_conv_expr_type (&se, ref->u.ar.start[i], gfc_array_index_type);
2463 gfc_add_block_to_block (block, &se.pre);
2464 lbound = GFC_TYPE_ARRAY_LBOUND (TREE_TYPE (desc), i);
2465 tmp = fold_build2_loc (input_location, MINUS_EXPR,
2466 TREE_TYPE (lbound), se.expr, lbound);
2467 tmp = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (tmp),
2468 extent, tmp);
2469 img_idx = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (tmp),
2470 img_idx, tmp);
2471 if (i < ref->u.ar.dimen + ref->u.ar.codimen - 1)
2473 ubound = GFC_TYPE_ARRAY_UBOUND (TREE_TYPE (desc), i);
2474 tmp = fold_build2_loc (input_location, MINUS_EXPR,
2475 TREE_TYPE (ubound), ubound, lbound);
2476 tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (tmp),
2477 tmp, build_one_cst (TREE_TYPE (tmp)));
2478 extent = fold_build2_loc (input_location, MULT_EXPR,
2479 TREE_TYPE (tmp), extent, tmp);
2482 img_idx = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (img_idx),
2483 img_idx, build_one_cst (TREE_TYPE (img_idx)));
2484 return fold_convert (integer_type_node, img_idx);
2488 /* For each character array constructor subexpression without a ts.u.cl->length,
2489 replace it by its first element (if there aren't any elements, the length
2490 should already be set to zero). */
2492 static void
2493 flatten_array_ctors_without_strlen (gfc_expr* e)
2495 gfc_actual_arglist* arg;
2496 gfc_constructor* c;
2498 if (!e)
2499 return;
2501 switch (e->expr_type)
2504 case EXPR_OP:
2505 flatten_array_ctors_without_strlen (e->value.op.op1);
2506 flatten_array_ctors_without_strlen (e->value.op.op2);
2507 break;
2509 case EXPR_COMPCALL:
2510 /* TODO: Implement as with EXPR_FUNCTION when needed. */
2511 gcc_unreachable ();
2513 case EXPR_FUNCTION:
2514 for (arg = e->value.function.actual; arg; arg = arg->next)
2515 flatten_array_ctors_without_strlen (arg->expr);
2516 break;
2518 case EXPR_ARRAY:
2520 /* We've found what we're looking for. */
2521 if (e->ts.type == BT_CHARACTER && !e->ts.u.cl->length)
2523 gfc_constructor *c;
2524 gfc_expr* new_expr;
2526 gcc_assert (e->value.constructor);
2528 c = gfc_constructor_first (e->value.constructor);
2529 new_expr = c->expr;
2530 c->expr = NULL;
2532 flatten_array_ctors_without_strlen (new_expr);
2533 gfc_replace_expr (e, new_expr);
2534 break;
2537 /* Otherwise, fall through to handle constructor elements. */
2538 gcc_fallthrough ();
2539 case EXPR_STRUCTURE:
2540 for (c = gfc_constructor_first (e->value.constructor);
2541 c; c = gfc_constructor_next (c))
2542 flatten_array_ctors_without_strlen (c->expr);
2543 break;
2545 default:
2546 break;
2552 /* Generate code to initialize a string length variable. Returns the
2553 value. For array constructors, cl->length might be NULL and in this case,
2554 the first element of the constructor is needed. expr is the original
2555 expression so we can access it but can be NULL if this is not needed. */
2557 void
2558 gfc_conv_string_length (gfc_charlen * cl, gfc_expr * expr, stmtblock_t * pblock)
2560 gfc_se se;
2562 gfc_init_se (&se, NULL);
2564 if (!cl->length && cl->backend_decl && VAR_P (cl->backend_decl))
2565 return;
2567 /* If cl->length is NULL, use gfc_conv_expr to obtain the string length but
2568 "flatten" array constructors by taking their first element; all elements
2569 should be the same length or a cl->length should be present. */
2570 if (!cl->length)
2572 gfc_expr* expr_flat;
2573 if (!expr)
2574 return;
2575 expr_flat = gfc_copy_expr (expr);
2576 flatten_array_ctors_without_strlen (expr_flat);
2577 gfc_resolve_expr (expr_flat);
2578 if (expr_flat->rank)
2579 gfc_conv_expr_descriptor (&se, expr_flat);
2580 else
2581 gfc_conv_expr (&se, expr_flat);
2582 if (expr_flat->expr_type != EXPR_VARIABLE)
2583 gfc_add_block_to_block (pblock, &se.pre);
2584 se.expr = convert (gfc_charlen_type_node, se.string_length);
2585 gfc_add_block_to_block (pblock, &se.post);
2586 gfc_free_expr (expr_flat);
2588 else
2590 /* Convert cl->length. */
2591 gfc_conv_expr_type (&se, cl->length, gfc_charlen_type_node);
2592 se.expr = fold_build2_loc (input_location, MAX_EXPR,
2593 gfc_charlen_type_node, se.expr,
2594 build_zero_cst (TREE_TYPE (se.expr)));
2595 gfc_add_block_to_block (pblock, &se.pre);
2598 if (cl->backend_decl && VAR_P (cl->backend_decl))
2599 gfc_add_modify (pblock, cl->backend_decl, se.expr);
2600 else
2601 cl->backend_decl = gfc_evaluate_now (se.expr, pblock);
2605 static void
2606 gfc_conv_substring (gfc_se * se, gfc_ref * ref, int kind,
2607 const char *name, locus *where)
2609 tree tmp;
2610 tree type;
2611 tree fault;
2612 gfc_se start;
2613 gfc_se end;
2614 char *msg;
2615 mpz_t length;
2617 type = gfc_get_character_type (kind, ref->u.ss.length);
2618 type = build_pointer_type (type);
2620 gfc_init_se (&start, se);
2621 gfc_conv_expr_type (&start, ref->u.ss.start, gfc_charlen_type_node);
2622 gfc_add_block_to_block (&se->pre, &start.pre);
2624 if (integer_onep (start.expr))
2625 gfc_conv_string_parameter (se);
2626 else
2628 tmp = start.expr;
2629 STRIP_NOPS (tmp);
2630 /* Avoid multiple evaluation of substring start. */
2631 if (!CONSTANT_CLASS_P (tmp) && !DECL_P (tmp))
2632 start.expr = gfc_evaluate_now (start.expr, &se->pre);
2634 /* Change the start of the string. */
2635 if ((TREE_CODE (TREE_TYPE (se->expr)) == ARRAY_TYPE
2636 || TREE_CODE (TREE_TYPE (se->expr)) == INTEGER_TYPE)
2637 && TYPE_STRING_FLAG (TREE_TYPE (se->expr)))
2638 tmp = se->expr;
2639 else
2640 tmp = build_fold_indirect_ref_loc (input_location,
2641 se->expr);
2642 /* For BIND(C), a BT_CHARACTER is not an ARRAY_TYPE. */
2643 if (TREE_CODE (TREE_TYPE (tmp)) == ARRAY_TYPE)
2645 tmp = gfc_build_array_ref (tmp, start.expr, NULL_TREE, true);
2646 se->expr = gfc_build_addr_expr (type, tmp);
2650 /* Length = end + 1 - start. */
2651 gfc_init_se (&end, se);
2652 if (ref->u.ss.end == NULL)
2653 end.expr = se->string_length;
2654 else
2656 gfc_conv_expr_type (&end, ref->u.ss.end, gfc_charlen_type_node);
2657 gfc_add_block_to_block (&se->pre, &end.pre);
2659 tmp = end.expr;
2660 STRIP_NOPS (tmp);
2661 if (!CONSTANT_CLASS_P (tmp) && !DECL_P (tmp))
2662 end.expr = gfc_evaluate_now (end.expr, &se->pre);
2664 if ((gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
2665 && (ref->u.ss.start->symtree
2666 && !ref->u.ss.start->symtree->n.sym->attr.implied_index))
2668 tree nonempty = fold_build2_loc (input_location, LE_EXPR,
2669 logical_type_node, start.expr,
2670 end.expr);
2672 /* Check lower bound. */
2673 fault = fold_build2_loc (input_location, LT_EXPR, logical_type_node,
2674 start.expr,
2675 build_one_cst (TREE_TYPE (start.expr)));
2676 fault = fold_build2_loc (input_location, TRUTH_ANDIF_EXPR,
2677 logical_type_node, nonempty, fault);
2678 if (name)
2679 msg = xasprintf ("Substring out of bounds: lower bound (%%ld) of '%s' "
2680 "is less than one", name);
2681 else
2682 msg = xasprintf ("Substring out of bounds: lower bound (%%ld) "
2683 "is less than one");
2684 gfc_trans_runtime_check (true, false, fault, &se->pre, where, msg,
2685 fold_convert (long_integer_type_node,
2686 start.expr));
2687 free (msg);
2689 /* Check upper bound. */
2690 fault = fold_build2_loc (input_location, GT_EXPR, logical_type_node,
2691 end.expr, se->string_length);
2692 fault = fold_build2_loc (input_location, TRUTH_ANDIF_EXPR,
2693 logical_type_node, nonempty, fault);
2694 if (name)
2695 msg = xasprintf ("Substring out of bounds: upper bound (%%ld) of '%s' "
2696 "exceeds string length (%%ld)", name);
2697 else
2698 msg = xasprintf ("Substring out of bounds: upper bound (%%ld) "
2699 "exceeds string length (%%ld)");
2700 gfc_trans_runtime_check (true, false, fault, &se->pre, where, msg,
2701 fold_convert (long_integer_type_node, end.expr),
2702 fold_convert (long_integer_type_node,
2703 se->string_length));
2704 free (msg);
2707 /* Try to calculate the length from the start and end expressions. */
2708 if (ref->u.ss.end
2709 && gfc_dep_difference (ref->u.ss.end, ref->u.ss.start, &length))
2711 HOST_WIDE_INT i_len;
2713 i_len = gfc_mpz_get_hwi (length) + 1;
2714 if (i_len < 0)
2715 i_len = 0;
2717 tmp = build_int_cst (gfc_charlen_type_node, i_len);
2718 mpz_clear (length); /* Was initialized by gfc_dep_difference. */
2720 else
2722 tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_charlen_type_node,
2723 fold_convert (gfc_charlen_type_node, end.expr),
2724 fold_convert (gfc_charlen_type_node, start.expr));
2725 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_charlen_type_node,
2726 build_int_cst (gfc_charlen_type_node, 1), tmp);
2727 tmp = fold_build2_loc (input_location, MAX_EXPR, gfc_charlen_type_node,
2728 tmp, build_int_cst (gfc_charlen_type_node, 0));
2731 se->string_length = tmp;
2735 /* Convert a derived type component reference. */
2737 void
2738 gfc_conv_component_ref (gfc_se * se, gfc_ref * ref)
2740 gfc_component *c;
2741 tree tmp;
2742 tree decl;
2743 tree field;
2744 tree context;
2746 c = ref->u.c.component;
2748 if (c->backend_decl == NULL_TREE
2749 && ref->u.c.sym != NULL)
2750 gfc_get_derived_type (ref->u.c.sym);
2752 field = c->backend_decl;
2753 gcc_assert (field && TREE_CODE (field) == FIELD_DECL);
2754 decl = se->expr;
2755 context = DECL_FIELD_CONTEXT (field);
2757 /* Components can correspond to fields of different containing
2758 types, as components are created without context, whereas
2759 a concrete use of a component has the type of decl as context.
2760 So, if the type doesn't match, we search the corresponding
2761 FIELD_DECL in the parent type. To not waste too much time
2762 we cache this result in norestrict_decl.
2763 On the other hand, if the context is a UNION or a MAP (a
2764 RECORD_TYPE within a UNION_TYPE) always use the given FIELD_DECL. */
2766 if (context != TREE_TYPE (decl)
2767 && !( TREE_CODE (TREE_TYPE (field)) == UNION_TYPE /* Field is union */
2768 || TREE_CODE (context) == UNION_TYPE)) /* Field is map */
2770 tree f2 = c->norestrict_decl;
2771 if (!f2 || DECL_FIELD_CONTEXT (f2) != TREE_TYPE (decl))
2772 for (f2 = TYPE_FIELDS (TREE_TYPE (decl)); f2; f2 = DECL_CHAIN (f2))
2773 if (TREE_CODE (f2) == FIELD_DECL
2774 && DECL_NAME (f2) == DECL_NAME (field))
2775 break;
2776 gcc_assert (f2);
2777 c->norestrict_decl = f2;
2778 field = f2;
2781 if (ref->u.c.sym && ref->u.c.sym->ts.type == BT_CLASS
2782 && strcmp ("_data", c->name) == 0)
2784 /* Found a ref to the _data component. Store the associated ref to
2785 the vptr in se->class_vptr. */
2786 se->class_vptr = gfc_class_vptr_get (decl);
2788 else
2789 se->class_vptr = NULL_TREE;
2791 tmp = fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field),
2792 decl, field, NULL_TREE);
2794 se->expr = tmp;
2796 /* Allocatable deferred char arrays are to be handled by the gfc_deferred_
2797 strlen () conditional below. */
2798 if (c->ts.type == BT_CHARACTER && !c->attr.proc_pointer
2799 && !c->ts.deferred
2800 && !c->attr.pdt_string)
2802 tmp = c->ts.u.cl->backend_decl;
2803 /* Components must always be constant length. */
2804 gcc_assert (tmp && INTEGER_CST_P (tmp));
2805 se->string_length = tmp;
2808 if (gfc_deferred_strlen (c, &field))
2810 tmp = fold_build3_loc (input_location, COMPONENT_REF,
2811 TREE_TYPE (field),
2812 decl, field, NULL_TREE);
2813 se->string_length = tmp;
2816 if (((c->attr.pointer || c->attr.allocatable)
2817 && (!c->attr.dimension && !c->attr.codimension)
2818 && c->ts.type != BT_CHARACTER)
2819 || c->attr.proc_pointer)
2820 se->expr = build_fold_indirect_ref_loc (input_location,
2821 se->expr);
2825 /* This function deals with component references to components of the
2826 parent type for derived type extensions. */
2827 void
2828 conv_parent_component_references (gfc_se * se, gfc_ref * ref)
2830 gfc_component *c;
2831 gfc_component *cmp;
2832 gfc_symbol *dt;
2833 gfc_ref parent;
2835 dt = ref->u.c.sym;
2836 c = ref->u.c.component;
2838 /* Return if the component is in this type, i.e. not in the parent type. */
2839 for (cmp = dt->components; cmp; cmp = cmp->next)
2840 if (c == cmp)
2841 return;
2843 /* Build a gfc_ref to recursively call gfc_conv_component_ref. */
2844 parent.type = REF_COMPONENT;
2845 parent.next = NULL;
2846 parent.u.c.sym = dt;
2847 parent.u.c.component = dt->components;
2849 if (dt->backend_decl == NULL)
2850 gfc_get_derived_type (dt);
2852 /* Build the reference and call self. */
2853 gfc_conv_component_ref (se, &parent);
2854 parent.u.c.sym = dt->components->ts.u.derived;
2855 parent.u.c.component = c;
2856 conv_parent_component_references (se, &parent);
2860 static void
2861 conv_inquiry (gfc_se * se, gfc_ref * ref, gfc_expr *expr, gfc_typespec *ts)
2863 tree res = se->expr;
2865 switch (ref->u.i)
2867 case INQUIRY_RE:
2868 res = fold_build1_loc (input_location, REALPART_EXPR,
2869 TREE_TYPE (TREE_TYPE (res)), res);
2870 break;
2872 case INQUIRY_IM:
2873 res = fold_build1_loc (input_location, IMAGPART_EXPR,
2874 TREE_TYPE (TREE_TYPE (res)), res);
2875 break;
2877 case INQUIRY_KIND:
2878 res = build_int_cst (gfc_typenode_for_spec (&expr->ts),
2879 ts->kind);
2880 se->string_length = NULL_TREE;
2881 break;
2883 case INQUIRY_LEN:
2884 res = fold_convert (gfc_typenode_for_spec (&expr->ts),
2885 se->string_length);
2886 se->string_length = NULL_TREE;
2887 break;
2889 default:
2890 gcc_unreachable ();
2892 se->expr = res;
2895 /* Dereference VAR where needed if it is a pointer, reference, etc.
2896 according to Fortran semantics. */
2898 tree
2899 gfc_maybe_dereference_var (gfc_symbol *sym, tree var, bool descriptor_only_p,
2900 bool is_classarray)
2902 if (!POINTER_TYPE_P (TREE_TYPE (var)))
2903 return var;
2904 if (is_CFI_desc (sym, NULL))
2905 return build_fold_indirect_ref_loc (input_location, var);
2907 /* Characters are entirely different from other types, they are treated
2908 separately. */
2909 if (sym->ts.type == BT_CHARACTER)
2911 /* Dereference character pointer dummy arguments
2912 or results. */
2913 if ((sym->attr.pointer || sym->attr.allocatable
2914 || (sym->as && sym->as->type == AS_ASSUMED_RANK))
2915 && (sym->attr.dummy
2916 || sym->attr.function
2917 || sym->attr.result))
2918 var = build_fold_indirect_ref_loc (input_location, var);
2920 else if (!sym->attr.value)
2922 /* Dereference temporaries for class array dummy arguments. */
2923 if (sym->attr.dummy && is_classarray
2924 && GFC_ARRAY_TYPE_P (TREE_TYPE (var)))
2926 if (!descriptor_only_p)
2927 var = GFC_DECL_SAVED_DESCRIPTOR (var);
2929 var = build_fold_indirect_ref_loc (input_location, var);
2932 /* Dereference non-character scalar dummy arguments. */
2933 if (sym->attr.dummy && !sym->attr.dimension
2934 && !(sym->attr.codimension && sym->attr.allocatable)
2935 && (sym->ts.type != BT_CLASS
2936 || (!CLASS_DATA (sym)->attr.dimension
2937 && !(CLASS_DATA (sym)->attr.codimension
2938 && CLASS_DATA (sym)->attr.allocatable))))
2939 var = build_fold_indirect_ref_loc (input_location, var);
2941 /* Dereference scalar hidden result. */
2942 if (flag_f2c && sym->ts.type == BT_COMPLEX
2943 && (sym->attr.function || sym->attr.result)
2944 && !sym->attr.dimension && !sym->attr.pointer
2945 && !sym->attr.always_explicit)
2946 var = build_fold_indirect_ref_loc (input_location, var);
2948 /* Dereference non-character, non-class pointer variables.
2949 These must be dummies, results, or scalars. */
2950 if (!is_classarray
2951 && (sym->attr.pointer || sym->attr.allocatable
2952 || gfc_is_associate_pointer (sym)
2953 || (sym->as && sym->as->type == AS_ASSUMED_RANK))
2954 && (sym->attr.dummy
2955 || sym->attr.function
2956 || sym->attr.result
2957 || (!sym->attr.dimension
2958 && (!sym->attr.codimension || !sym->attr.allocatable))))
2959 var = build_fold_indirect_ref_loc (input_location, var);
2960 /* Now treat the class array pointer variables accordingly. */
2961 else if (sym->ts.type == BT_CLASS
2962 && sym->attr.dummy
2963 && (CLASS_DATA (sym)->attr.dimension
2964 || CLASS_DATA (sym)->attr.codimension)
2965 && ((CLASS_DATA (sym)->as
2966 && CLASS_DATA (sym)->as->type == AS_ASSUMED_RANK)
2967 || CLASS_DATA (sym)->attr.allocatable
2968 || CLASS_DATA (sym)->attr.class_pointer))
2969 var = build_fold_indirect_ref_loc (input_location, var);
2970 /* And the case where a non-dummy, non-result, non-function,
2971 non-allocable and non-pointer classarray is present. This case was
2972 previously covered by the first if, but with introducing the
2973 condition !is_classarray there, that case has to be covered
2974 explicitly. */
2975 else if (sym->ts.type == BT_CLASS
2976 && !sym->attr.dummy
2977 && !sym->attr.function
2978 && !sym->attr.result
2979 && (CLASS_DATA (sym)->attr.dimension
2980 || CLASS_DATA (sym)->attr.codimension)
2981 && (sym->assoc
2982 || !CLASS_DATA (sym)->attr.allocatable)
2983 && !CLASS_DATA (sym)->attr.class_pointer)
2984 var = build_fold_indirect_ref_loc (input_location, var);
2987 return var;
2990 /* Return the contents of a variable. Also handles reference/pointer
2991 variables (all Fortran pointer references are implicit). */
2993 static void
2994 gfc_conv_variable (gfc_se * se, gfc_expr * expr)
2996 gfc_ss *ss;
2997 gfc_ref *ref;
2998 gfc_symbol *sym;
2999 tree parent_decl = NULL_TREE;
3000 int parent_flag;
3001 bool return_value;
3002 bool alternate_entry;
3003 bool entry_master;
3004 bool is_classarray;
3005 bool first_time = true;
3007 sym = expr->symtree->n.sym;
3008 is_classarray = IS_CLASS_ARRAY (sym);
3009 ss = se->ss;
3010 if (ss != NULL)
3012 gfc_ss_info *ss_info = ss->info;
3014 /* Check that something hasn't gone horribly wrong. */
3015 gcc_assert (ss != gfc_ss_terminator);
3016 gcc_assert (ss_info->expr == expr);
3018 /* A scalarized term. We already know the descriptor. */
3019 se->expr = ss_info->data.array.descriptor;
3020 se->string_length = ss_info->string_length;
3021 ref = ss_info->data.array.ref;
3022 if (ref)
3023 gcc_assert (ref->type == REF_ARRAY
3024 && ref->u.ar.type != AR_ELEMENT);
3025 else
3026 gfc_conv_tmp_array_ref (se);
3028 else
3030 tree se_expr = NULL_TREE;
3032 se->expr = gfc_get_symbol_decl (sym);
3034 /* Deal with references to a parent results or entries by storing
3035 the current_function_decl and moving to the parent_decl. */
3036 return_value = sym->attr.function && sym->result == sym;
3037 alternate_entry = sym->attr.function && sym->attr.entry
3038 && sym->result == sym;
3039 entry_master = sym->attr.result
3040 && sym->ns->proc_name->attr.entry_master
3041 && !gfc_return_by_reference (sym->ns->proc_name);
3042 if (current_function_decl)
3043 parent_decl = DECL_CONTEXT (current_function_decl);
3045 if ((se->expr == parent_decl && return_value)
3046 || (sym->ns && sym->ns->proc_name
3047 && parent_decl
3048 && sym->ns->proc_name->backend_decl == parent_decl
3049 && (alternate_entry || entry_master)))
3050 parent_flag = 1;
3051 else
3052 parent_flag = 0;
3054 /* Special case for assigning the return value of a function.
3055 Self recursive functions must have an explicit return value. */
3056 if (return_value && (se->expr == current_function_decl || parent_flag))
3057 se_expr = gfc_get_fake_result_decl (sym, parent_flag);
3059 /* Similarly for alternate entry points. */
3060 else if (alternate_entry
3061 && (sym->ns->proc_name->backend_decl == current_function_decl
3062 || parent_flag))
3064 gfc_entry_list *el = NULL;
3066 for (el = sym->ns->entries; el; el = el->next)
3067 if (sym == el->sym)
3069 se_expr = gfc_get_fake_result_decl (sym, parent_flag);
3070 break;
3074 else if (entry_master
3075 && (sym->ns->proc_name->backend_decl == current_function_decl
3076 || parent_flag))
3077 se_expr = gfc_get_fake_result_decl (sym, parent_flag);
3079 if (se_expr)
3080 se->expr = se_expr;
3082 /* Procedure actual arguments. Look out for temporary variables
3083 with the same attributes as function values. */
3084 else if (!sym->attr.temporary
3085 && sym->attr.flavor == FL_PROCEDURE
3086 && se->expr != current_function_decl)
3088 if (!sym->attr.dummy && !sym->attr.proc_pointer)
3090 gcc_assert (TREE_CODE (se->expr) == FUNCTION_DECL);
3091 se->expr = gfc_build_addr_expr (NULL_TREE, se->expr);
3093 return;
3096 if (sym->ts.type == BT_CLASS
3097 && sym->attr.class_ok
3098 && sym->ts.u.derived->attr.is_class)
3099 se->class_container = se->expr;
3101 /* Dereference the expression, where needed. */
3102 se->expr = gfc_maybe_dereference_var (sym, se->expr, se->descriptor_only,
3103 is_classarray);
3105 ref = expr->ref;
3108 /* For character variables, also get the length. */
3109 if (sym->ts.type == BT_CHARACTER)
3111 /* If the character length of an entry isn't set, get the length from
3112 the master function instead. */
3113 if (sym->attr.entry && !sym->ts.u.cl->backend_decl)
3114 se->string_length = sym->ns->proc_name->ts.u.cl->backend_decl;
3115 else
3116 se->string_length = sym->ts.u.cl->backend_decl;
3117 gcc_assert (se->string_length);
3120 gfc_typespec *ts = &sym->ts;
3121 while (ref)
3123 switch (ref->type)
3125 case REF_ARRAY:
3126 /* Return the descriptor if that's what we want and this is an array
3127 section reference. */
3128 if (se->descriptor_only && ref->u.ar.type != AR_ELEMENT)
3129 return;
3130 /* TODO: Pointers to single elements of array sections, eg elemental subs. */
3131 /* Return the descriptor for array pointers and allocations. */
3132 if (se->want_pointer
3133 && ref->next == NULL && (se->descriptor_only))
3134 return;
3136 gfc_conv_array_ref (se, &ref->u.ar, expr, &expr->where);
3137 /* Return a pointer to an element. */
3138 break;
3140 case REF_COMPONENT:
3141 ts = &ref->u.c.component->ts;
3142 if (first_time && is_classarray && sym->attr.dummy
3143 && se->descriptor_only
3144 && !CLASS_DATA (sym)->attr.allocatable
3145 && !CLASS_DATA (sym)->attr.class_pointer
3146 && CLASS_DATA (sym)->as
3147 && CLASS_DATA (sym)->as->type != AS_ASSUMED_RANK
3148 && strcmp ("_data", ref->u.c.component->name) == 0)
3149 /* Skip the first ref of a _data component, because for class
3150 arrays that one is already done by introducing a temporary
3151 array descriptor. */
3152 break;
3154 if (ref->u.c.sym->attr.extension)
3155 conv_parent_component_references (se, ref);
3157 gfc_conv_component_ref (se, ref);
3159 if (ref->u.c.component->ts.type == BT_CLASS
3160 && ref->u.c.component->attr.class_ok
3161 && ref->u.c.component->ts.u.derived->attr.is_class)
3162 se->class_container = se->expr;
3163 else if (!(ref->u.c.sym->attr.flavor == FL_DERIVED
3164 && ref->u.c.sym->attr.is_class))
3165 se->class_container = NULL_TREE;
3167 if (!ref->next && ref->u.c.sym->attr.codimension
3168 && se->want_pointer && se->descriptor_only)
3169 return;
3171 break;
3173 case REF_SUBSTRING:
3174 gfc_conv_substring (se, ref, expr->ts.kind,
3175 expr->symtree->name, &expr->where);
3176 break;
3178 case REF_INQUIRY:
3179 conv_inquiry (se, ref, expr, ts);
3180 break;
3182 default:
3183 gcc_unreachable ();
3184 break;
3186 first_time = false;
3187 ref = ref->next;
3189 /* Pointer assignment, allocation or pass by reference. Arrays are handled
3190 separately. */
3191 if (se->want_pointer)
3193 if (expr->ts.type == BT_CHARACTER && !gfc_is_proc_ptr_comp (expr))
3194 gfc_conv_string_parameter (se);
3195 else
3196 se->expr = gfc_build_addr_expr (NULL_TREE, se->expr);
3201 /* Unary ops are easy... Or they would be if ! was a valid op. */
3203 static void
3204 gfc_conv_unary_op (enum tree_code code, gfc_se * se, gfc_expr * expr)
3206 gfc_se operand;
3207 tree type;
3209 gcc_assert (expr->ts.type != BT_CHARACTER);
3210 /* Initialize the operand. */
3211 gfc_init_se (&operand, se);
3212 gfc_conv_expr_val (&operand, expr->value.op.op1);
3213 gfc_add_block_to_block (&se->pre, &operand.pre);
3215 type = gfc_typenode_for_spec (&expr->ts);
3217 /* TRUTH_NOT_EXPR is not a "true" unary operator in GCC.
3218 We must convert it to a compare to 0 (e.g. EQ_EXPR (op1, 0)).
3219 All other unary operators have an equivalent GIMPLE unary operator. */
3220 if (code == TRUTH_NOT_EXPR)
3221 se->expr = fold_build2_loc (input_location, EQ_EXPR, type, operand.expr,
3222 build_int_cst (type, 0));
3223 else
3224 se->expr = fold_build1_loc (input_location, code, type, operand.expr);
3228 /* Expand power operator to optimal multiplications when a value is raised
3229 to a constant integer n. See section 4.6.3, "Evaluation of Powers" of
3230 Donald E. Knuth, "Seminumerical Algorithms", Vol. 2, "The Art of Computer
3231 Programming", 3rd Edition, 1998. */
3233 /* This code is mostly duplicated from expand_powi in the backend.
3234 We establish the "optimal power tree" lookup table with the defined size.
3235 The items in the table are the exponents used to calculate the index
3236 exponents. Any integer n less than the value can get an "addition chain",
3237 with the first node being one. */
3238 #define POWI_TABLE_SIZE 256
3240 /* The table is from builtins.cc. */
3241 static const unsigned char powi_table[POWI_TABLE_SIZE] =
3243 0, 1, 1, 2, 2, 3, 3, 4, /* 0 - 7 */
3244 4, 6, 5, 6, 6, 10, 7, 9, /* 8 - 15 */
3245 8, 16, 9, 16, 10, 12, 11, 13, /* 16 - 23 */
3246 12, 17, 13, 18, 14, 24, 15, 26, /* 24 - 31 */
3247 16, 17, 17, 19, 18, 33, 19, 26, /* 32 - 39 */
3248 20, 25, 21, 40, 22, 27, 23, 44, /* 40 - 47 */
3249 24, 32, 25, 34, 26, 29, 27, 44, /* 48 - 55 */
3250 28, 31, 29, 34, 30, 60, 31, 36, /* 56 - 63 */
3251 32, 64, 33, 34, 34, 46, 35, 37, /* 64 - 71 */
3252 36, 65, 37, 50, 38, 48, 39, 69, /* 72 - 79 */
3253 40, 49, 41, 43, 42, 51, 43, 58, /* 80 - 87 */
3254 44, 64, 45, 47, 46, 59, 47, 76, /* 88 - 95 */
3255 48, 65, 49, 66, 50, 67, 51, 66, /* 96 - 103 */
3256 52, 70, 53, 74, 54, 104, 55, 74, /* 104 - 111 */
3257 56, 64, 57, 69, 58, 78, 59, 68, /* 112 - 119 */
3258 60, 61, 61, 80, 62, 75, 63, 68, /* 120 - 127 */
3259 64, 65, 65, 128, 66, 129, 67, 90, /* 128 - 135 */
3260 68, 73, 69, 131, 70, 94, 71, 88, /* 136 - 143 */
3261 72, 128, 73, 98, 74, 132, 75, 121, /* 144 - 151 */
3262 76, 102, 77, 124, 78, 132, 79, 106, /* 152 - 159 */
3263 80, 97, 81, 160, 82, 99, 83, 134, /* 160 - 167 */
3264 84, 86, 85, 95, 86, 160, 87, 100, /* 168 - 175 */
3265 88, 113, 89, 98, 90, 107, 91, 122, /* 176 - 183 */
3266 92, 111, 93, 102, 94, 126, 95, 150, /* 184 - 191 */
3267 96, 128, 97, 130, 98, 133, 99, 195, /* 192 - 199 */
3268 100, 128, 101, 123, 102, 164, 103, 138, /* 200 - 207 */
3269 104, 145, 105, 146, 106, 109, 107, 149, /* 208 - 215 */
3270 108, 200, 109, 146, 110, 170, 111, 157, /* 216 - 223 */
3271 112, 128, 113, 130, 114, 182, 115, 132, /* 224 - 231 */
3272 116, 200, 117, 132, 118, 158, 119, 206, /* 232 - 239 */
3273 120, 240, 121, 162, 122, 147, 123, 152, /* 240 - 247 */
3274 124, 166, 125, 214, 126, 138, 127, 153, /* 248 - 255 */
3277 /* If n is larger than lookup table's max index, we use the "window
3278 method". */
3279 #define POWI_WINDOW_SIZE 3
3281 /* Recursive function to expand the power operator. The temporary
3282 values are put in tmpvar. The function returns tmpvar[1] ** n. */
3283 static tree
3284 gfc_conv_powi (gfc_se * se, unsigned HOST_WIDE_INT n, tree * tmpvar)
3286 tree op0;
3287 tree op1;
3288 tree tmp;
3289 int digit;
3291 if (n < POWI_TABLE_SIZE)
3293 if (tmpvar[n])
3294 return tmpvar[n];
3296 op0 = gfc_conv_powi (se, n - powi_table[n], tmpvar);
3297 op1 = gfc_conv_powi (se, powi_table[n], tmpvar);
3299 else if (n & 1)
3301 digit = n & ((1 << POWI_WINDOW_SIZE) - 1);
3302 op0 = gfc_conv_powi (se, n - digit, tmpvar);
3303 op1 = gfc_conv_powi (se, digit, tmpvar);
3305 else
3307 op0 = gfc_conv_powi (se, n >> 1, tmpvar);
3308 op1 = op0;
3311 tmp = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (op0), op0, op1);
3312 tmp = gfc_evaluate_now (tmp, &se->pre);
3314 if (n < POWI_TABLE_SIZE)
3315 tmpvar[n] = tmp;
3317 return tmp;
3321 /* Expand lhs ** rhs. rhs is a constant integer. If it expands successfully,
3322 return 1. Else return 0 and a call to runtime library functions
3323 will have to be built. */
3324 static int
3325 gfc_conv_cst_int_power (gfc_se * se, tree lhs, tree rhs)
3327 tree cond;
3328 tree tmp;
3329 tree type;
3330 tree vartmp[POWI_TABLE_SIZE];
3331 HOST_WIDE_INT m;
3332 unsigned HOST_WIDE_INT n;
3333 int sgn;
3334 wi::tree_to_wide_ref wrhs = wi::to_wide (rhs);
3336 /* If exponent is too large, we won't expand it anyway, so don't bother
3337 with large integer values. */
3338 if (!wi::fits_shwi_p (wrhs))
3339 return 0;
3341 m = wrhs.to_shwi ();
3342 /* Use the wide_int's routine to reliably get the absolute value on all
3343 platforms. Then convert it to a HOST_WIDE_INT like above. */
3344 n = wi::abs (wrhs).to_shwi ();
3346 type = TREE_TYPE (lhs);
3347 sgn = tree_int_cst_sgn (rhs);
3349 if (((FLOAT_TYPE_P (type) && !flag_unsafe_math_optimizations)
3350 || optimize_size) && (m > 2 || m < -1))
3351 return 0;
3353 /* rhs == 0 */
3354 if (sgn == 0)
3356 se->expr = gfc_build_const (type, integer_one_node);
3357 return 1;
3360 /* If rhs < 0 and lhs is an integer, the result is -1, 0 or 1. */
3361 if ((sgn == -1) && (TREE_CODE (type) == INTEGER_TYPE))
3363 tmp = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
3364 lhs, build_int_cst (TREE_TYPE (lhs), -1));
3365 cond = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
3366 lhs, build_int_cst (TREE_TYPE (lhs), 1));
3368 /* If rhs is even,
3369 result = (lhs == 1 || lhs == -1) ? 1 : 0. */
3370 if ((n & 1) == 0)
3372 tmp = fold_build2_loc (input_location, TRUTH_OR_EXPR,
3373 logical_type_node, tmp, cond);
3374 se->expr = fold_build3_loc (input_location, COND_EXPR, type,
3375 tmp, build_int_cst (type, 1),
3376 build_int_cst (type, 0));
3377 return 1;
3379 /* If rhs is odd,
3380 result = (lhs == 1) ? 1 : (lhs == -1) ? -1 : 0. */
3381 tmp = fold_build3_loc (input_location, COND_EXPR, type, tmp,
3382 build_int_cst (type, -1),
3383 build_int_cst (type, 0));
3384 se->expr = fold_build3_loc (input_location, COND_EXPR, type,
3385 cond, build_int_cst (type, 1), tmp);
3386 return 1;
3389 memset (vartmp, 0, sizeof (vartmp));
3390 vartmp[1] = lhs;
3391 if (sgn == -1)
3393 tmp = gfc_build_const (type, integer_one_node);
3394 vartmp[1] = fold_build2_loc (input_location, RDIV_EXPR, type, tmp,
3395 vartmp[1]);
3398 se->expr = gfc_conv_powi (se, n, vartmp);
3400 return 1;
3404 /* Power op (**). Constant integer exponent has special handling. */
3406 static void
3407 gfc_conv_power_op (gfc_se * se, gfc_expr * expr)
3409 tree gfc_int4_type_node;
3410 int kind;
3411 int ikind;
3412 int res_ikind_1, res_ikind_2;
3413 gfc_se lse;
3414 gfc_se rse;
3415 tree fndecl = NULL;
3417 gfc_init_se (&lse, se);
3418 gfc_conv_expr_val (&lse, expr->value.op.op1);
3419 lse.expr = gfc_evaluate_now (lse.expr, &lse.pre);
3420 gfc_add_block_to_block (&se->pre, &lse.pre);
3422 gfc_init_se (&rse, se);
3423 gfc_conv_expr_val (&rse, expr->value.op.op2);
3424 gfc_add_block_to_block (&se->pre, &rse.pre);
3426 if (expr->value.op.op2->ts.type == BT_INTEGER
3427 && expr->value.op.op2->expr_type == EXPR_CONSTANT)
3428 if (gfc_conv_cst_int_power (se, lse.expr, rse.expr))
3429 return;
3431 if (INTEGER_CST_P (lse.expr)
3432 && TREE_CODE (TREE_TYPE (rse.expr)) == INTEGER_TYPE)
3434 wi::tree_to_wide_ref wlhs = wi::to_wide (lse.expr);
3435 HOST_WIDE_INT v;
3436 unsigned HOST_WIDE_INT w;
3437 int kind, ikind, bit_size;
3439 v = wlhs.to_shwi ();
3440 w = absu_hwi (v);
3442 kind = expr->value.op.op1->ts.kind;
3443 ikind = gfc_validate_kind (BT_INTEGER, kind, false);
3444 bit_size = gfc_integer_kinds[ikind].bit_size;
3446 if (v == 1)
3448 /* 1**something is always 1. */
3449 se->expr = build_int_cst (TREE_TYPE (lse.expr), 1);
3450 return;
3452 else if (v == -1)
3454 /* (-1)**n is 1 - ((n & 1) << 1) */
3455 tree type;
3456 tree tmp;
3458 type = TREE_TYPE (lse.expr);
3459 tmp = fold_build2_loc (input_location, BIT_AND_EXPR, type,
3460 rse.expr, build_int_cst (type, 1));
3461 tmp = fold_build2_loc (input_location, LSHIFT_EXPR, type,
3462 tmp, build_int_cst (type, 1));
3463 tmp = fold_build2_loc (input_location, MINUS_EXPR, type,
3464 build_int_cst (type, 1), tmp);
3465 se->expr = tmp;
3466 return;
3468 else if (w > 0 && ((w & (w-1)) == 0) && ((w >> (bit_size-1)) == 0))
3470 /* Here v is +/- 2**e. The further simplification uses
3471 2**n = 1<<n, 4**n = 1<<(n+n), 8**n = 1 <<(3*n), 16**n =
3472 1<<(4*n), etc., but we have to make sure to return zero
3473 if the number of bits is too large. */
3474 tree lshift;
3475 tree type;
3476 tree shift;
3477 tree ge;
3478 tree cond;
3479 tree num_bits;
3480 tree cond2;
3481 tree tmp1;
3483 type = TREE_TYPE (lse.expr);
3485 if (w == 2)
3486 shift = rse.expr;
3487 else if (w == 4)
3488 shift = fold_build2_loc (input_location, PLUS_EXPR,
3489 TREE_TYPE (rse.expr),
3490 rse.expr, rse.expr);
3491 else
3493 /* use popcount for fast log2(w) */
3494 int e = wi::popcount (w-1);
3495 shift = fold_build2_loc (input_location, MULT_EXPR,
3496 TREE_TYPE (rse.expr),
3497 build_int_cst (TREE_TYPE (rse.expr), e),
3498 rse.expr);
3501 lshift = fold_build2_loc (input_location, LSHIFT_EXPR, type,
3502 build_int_cst (type, 1), shift);
3503 ge = fold_build2_loc (input_location, GE_EXPR, logical_type_node,
3504 rse.expr, build_int_cst (type, 0));
3505 cond = fold_build3_loc (input_location, COND_EXPR, type, ge, lshift,
3506 build_int_cst (type, 0));
3507 num_bits = build_int_cst (TREE_TYPE (rse.expr), TYPE_PRECISION (type));
3508 cond2 = fold_build2_loc (input_location, GE_EXPR, logical_type_node,
3509 rse.expr, num_bits);
3510 tmp1 = fold_build3_loc (input_location, COND_EXPR, type, cond2,
3511 build_int_cst (type, 0), cond);
3512 if (v > 0)
3514 se->expr = tmp1;
3516 else
3518 /* for v < 0, calculate v**n = |v|**n * (-1)**n */
3519 tree tmp2;
3520 tmp2 = fold_build2_loc (input_location, BIT_AND_EXPR, type,
3521 rse.expr, build_int_cst (type, 1));
3522 tmp2 = fold_build2_loc (input_location, LSHIFT_EXPR, type,
3523 tmp2, build_int_cst (type, 1));
3524 tmp2 = fold_build2_loc (input_location, MINUS_EXPR, type,
3525 build_int_cst (type, 1), tmp2);
3526 se->expr = fold_build2_loc (input_location, MULT_EXPR, type,
3527 tmp1, tmp2);
3529 return;
3533 gfc_int4_type_node = gfc_get_int_type (4);
3535 /* In case of integer operands with kinds 1 or 2, we call the integer kind 4
3536 library routine. But in the end, we have to convert the result back
3537 if this case applies -- with res_ikind_K, we keep track whether operand K
3538 falls into this case. */
3539 res_ikind_1 = -1;
3540 res_ikind_2 = -1;
3542 kind = expr->value.op.op1->ts.kind;
3543 switch (expr->value.op.op2->ts.type)
3545 case BT_INTEGER:
3546 ikind = expr->value.op.op2->ts.kind;
3547 switch (ikind)
3549 case 1:
3550 case 2:
3551 rse.expr = convert (gfc_int4_type_node, rse.expr);
3552 res_ikind_2 = ikind;
3553 /* Fall through. */
3555 case 4:
3556 ikind = 0;
3557 break;
3559 case 8:
3560 ikind = 1;
3561 break;
3563 case 16:
3564 ikind = 2;
3565 break;
3567 default:
3568 gcc_unreachable ();
3570 switch (kind)
3572 case 1:
3573 case 2:
3574 if (expr->value.op.op1->ts.type == BT_INTEGER)
3576 lse.expr = convert (gfc_int4_type_node, lse.expr);
3577 res_ikind_1 = kind;
3579 else
3580 gcc_unreachable ();
3581 /* Fall through. */
3583 case 4:
3584 kind = 0;
3585 break;
3587 case 8:
3588 kind = 1;
3589 break;
3591 case 10:
3592 kind = 2;
3593 break;
3595 case 16:
3596 kind = 3;
3597 break;
3599 default:
3600 gcc_unreachable ();
3603 switch (expr->value.op.op1->ts.type)
3605 case BT_INTEGER:
3606 if (kind == 3) /* Case 16 was not handled properly above. */
3607 kind = 2;
3608 fndecl = gfor_fndecl_math_powi[kind][ikind].integer;
3609 break;
3611 case BT_REAL:
3612 /* Use builtins for real ** int4. */
3613 if (ikind == 0)
3615 switch (kind)
3617 case 0:
3618 fndecl = builtin_decl_explicit (BUILT_IN_POWIF);
3619 break;
3621 case 1:
3622 fndecl = builtin_decl_explicit (BUILT_IN_POWI);
3623 break;
3625 case 2:
3626 fndecl = builtin_decl_explicit (BUILT_IN_POWIL);
3627 break;
3629 case 3:
3630 /* Use the __builtin_powil() only if real(kind=16) is
3631 actually the C long double type. */
3632 if (!gfc_real16_is_float128)
3633 fndecl = builtin_decl_explicit (BUILT_IN_POWIL);
3634 break;
3636 default:
3637 gcc_unreachable ();
3641 /* If we don't have a good builtin for this, go for the
3642 library function. */
3643 if (!fndecl)
3644 fndecl = gfor_fndecl_math_powi[kind][ikind].real;
3645 break;
3647 case BT_COMPLEX:
3648 fndecl = gfor_fndecl_math_powi[kind][ikind].cmplx;
3649 break;
3651 default:
3652 gcc_unreachable ();
3654 break;
3656 case BT_REAL:
3657 fndecl = gfc_builtin_decl_for_float_kind (BUILT_IN_POW, kind);
3658 break;
3660 case BT_COMPLEX:
3661 fndecl = gfc_builtin_decl_for_float_kind (BUILT_IN_CPOW, kind);
3662 break;
3664 default:
3665 gcc_unreachable ();
3666 break;
3669 se->expr = build_call_expr_loc (input_location,
3670 fndecl, 2, lse.expr, rse.expr);
3672 /* Convert the result back if it is of wrong integer kind. */
3673 if (res_ikind_1 != -1 && res_ikind_2 != -1)
3675 /* We want the maximum of both operand kinds as result. */
3676 if (res_ikind_1 < res_ikind_2)
3677 res_ikind_1 = res_ikind_2;
3678 se->expr = convert (gfc_get_int_type (res_ikind_1), se->expr);
3683 /* Generate code to allocate a string temporary. */
3685 tree
3686 gfc_conv_string_tmp (gfc_se * se, tree type, tree len)
3688 tree var;
3689 tree tmp;
3691 if (gfc_can_put_var_on_stack (len))
3693 /* Create a temporary variable to hold the result. */
3694 tmp = fold_build2_loc (input_location, MINUS_EXPR,
3695 TREE_TYPE (len), len,
3696 build_int_cst (TREE_TYPE (len), 1));
3697 tmp = build_range_type (gfc_charlen_type_node, size_zero_node, tmp);
3699 if (TREE_CODE (TREE_TYPE (type)) == ARRAY_TYPE)
3700 tmp = build_array_type (TREE_TYPE (TREE_TYPE (type)), tmp);
3701 else
3702 tmp = build_array_type (TREE_TYPE (type), tmp);
3704 var = gfc_create_var (tmp, "str");
3705 var = gfc_build_addr_expr (type, var);
3707 else
3709 /* Allocate a temporary to hold the result. */
3710 var = gfc_create_var (type, "pstr");
3711 gcc_assert (POINTER_TYPE_P (type));
3712 tmp = TREE_TYPE (type);
3713 if (TREE_CODE (tmp) == ARRAY_TYPE)
3714 tmp = TREE_TYPE (tmp);
3715 tmp = TYPE_SIZE_UNIT (tmp);
3716 tmp = fold_build2_loc (input_location, MULT_EXPR, size_type_node,
3717 fold_convert (size_type_node, len),
3718 fold_convert (size_type_node, tmp));
3719 tmp = gfc_call_malloc (&se->pre, type, tmp);
3720 gfc_add_modify (&se->pre, var, tmp);
3722 /* Free the temporary afterwards. */
3723 tmp = gfc_call_free (var);
3724 gfc_add_expr_to_block (&se->post, tmp);
3727 return var;
3731 /* Handle a string concatenation operation. A temporary will be allocated to
3732 hold the result. */
3734 static void
3735 gfc_conv_concat_op (gfc_se * se, gfc_expr * expr)
3737 gfc_se lse, rse;
3738 tree len, type, var, tmp, fndecl;
3740 gcc_assert (expr->value.op.op1->ts.type == BT_CHARACTER
3741 && expr->value.op.op2->ts.type == BT_CHARACTER);
3742 gcc_assert (expr->value.op.op1->ts.kind == expr->value.op.op2->ts.kind);
3744 gfc_init_se (&lse, se);
3745 gfc_conv_expr (&lse, expr->value.op.op1);
3746 gfc_conv_string_parameter (&lse);
3747 gfc_init_se (&rse, se);
3748 gfc_conv_expr (&rse, expr->value.op.op2);
3749 gfc_conv_string_parameter (&rse);
3751 gfc_add_block_to_block (&se->pre, &lse.pre);
3752 gfc_add_block_to_block (&se->pre, &rse.pre);
3754 type = gfc_get_character_type (expr->ts.kind, expr->ts.u.cl);
3755 len = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
3756 if (len == NULL_TREE)
3758 len = fold_build2_loc (input_location, PLUS_EXPR,
3759 gfc_charlen_type_node,
3760 fold_convert (gfc_charlen_type_node,
3761 lse.string_length),
3762 fold_convert (gfc_charlen_type_node,
3763 rse.string_length));
3766 type = build_pointer_type (type);
3768 var = gfc_conv_string_tmp (se, type, len);
3770 /* Do the actual concatenation. */
3771 if (expr->ts.kind == 1)
3772 fndecl = gfor_fndecl_concat_string;
3773 else if (expr->ts.kind == 4)
3774 fndecl = gfor_fndecl_concat_string_char4;
3775 else
3776 gcc_unreachable ();
3778 tmp = build_call_expr_loc (input_location,
3779 fndecl, 6, len, var, lse.string_length, lse.expr,
3780 rse.string_length, rse.expr);
3781 gfc_add_expr_to_block (&se->pre, tmp);
3783 /* Add the cleanup for the operands. */
3784 gfc_add_block_to_block (&se->pre, &rse.post);
3785 gfc_add_block_to_block (&se->pre, &lse.post);
3787 se->expr = var;
3788 se->string_length = len;
3791 /* Translates an op expression. Common (binary) cases are handled by this
3792 function, others are passed on. Recursion is used in either case.
3793 We use the fact that (op1.ts == op2.ts) (except for the power
3794 operator **).
3795 Operators need no special handling for scalarized expressions as long as
3796 they call gfc_conv_simple_val to get their operands.
3797 Character strings get special handling. */
3799 static void
3800 gfc_conv_expr_op (gfc_se * se, gfc_expr * expr)
3802 enum tree_code code;
3803 gfc_se lse;
3804 gfc_se rse;
3805 tree tmp, type;
3806 int lop;
3807 int checkstring;
3809 checkstring = 0;
3810 lop = 0;
3811 switch (expr->value.op.op)
3813 case INTRINSIC_PARENTHESES:
3814 if ((expr->ts.type == BT_REAL || expr->ts.type == BT_COMPLEX)
3815 && flag_protect_parens)
3817 gfc_conv_unary_op (PAREN_EXPR, se, expr);
3818 gcc_assert (FLOAT_TYPE_P (TREE_TYPE (se->expr)));
3819 return;
3822 /* Fallthrough. */
3823 case INTRINSIC_UPLUS:
3824 gfc_conv_expr (se, expr->value.op.op1);
3825 return;
3827 case INTRINSIC_UMINUS:
3828 gfc_conv_unary_op (NEGATE_EXPR, se, expr);
3829 return;
3831 case INTRINSIC_NOT:
3832 gfc_conv_unary_op (TRUTH_NOT_EXPR, se, expr);
3833 return;
3835 case INTRINSIC_PLUS:
3836 code = PLUS_EXPR;
3837 break;
3839 case INTRINSIC_MINUS:
3840 code = MINUS_EXPR;
3841 break;
3843 case INTRINSIC_TIMES:
3844 code = MULT_EXPR;
3845 break;
3847 case INTRINSIC_DIVIDE:
3848 /* If expr is a real or complex expr, use an RDIV_EXPR. If op1 is
3849 an integer, we must round towards zero, so we use a
3850 TRUNC_DIV_EXPR. */
3851 if (expr->ts.type == BT_INTEGER)
3852 code = TRUNC_DIV_EXPR;
3853 else
3854 code = RDIV_EXPR;
3855 break;
3857 case INTRINSIC_POWER:
3858 gfc_conv_power_op (se, expr);
3859 return;
3861 case INTRINSIC_CONCAT:
3862 gfc_conv_concat_op (se, expr);
3863 return;
3865 case INTRINSIC_AND:
3866 code = flag_frontend_optimize ? TRUTH_ANDIF_EXPR : TRUTH_AND_EXPR;
3867 lop = 1;
3868 break;
3870 case INTRINSIC_OR:
3871 code = flag_frontend_optimize ? TRUTH_ORIF_EXPR : TRUTH_OR_EXPR;
3872 lop = 1;
3873 break;
3875 /* EQV and NEQV only work on logicals, but since we represent them
3876 as integers, we can use EQ_EXPR and NE_EXPR for them in GIMPLE. */
3877 case INTRINSIC_EQ:
3878 case INTRINSIC_EQ_OS:
3879 case INTRINSIC_EQV:
3880 code = EQ_EXPR;
3881 checkstring = 1;
3882 lop = 1;
3883 break;
3885 case INTRINSIC_NE:
3886 case INTRINSIC_NE_OS:
3887 case INTRINSIC_NEQV:
3888 code = NE_EXPR;
3889 checkstring = 1;
3890 lop = 1;
3891 break;
3893 case INTRINSIC_GT:
3894 case INTRINSIC_GT_OS:
3895 code = GT_EXPR;
3896 checkstring = 1;
3897 lop = 1;
3898 break;
3900 case INTRINSIC_GE:
3901 case INTRINSIC_GE_OS:
3902 code = GE_EXPR;
3903 checkstring = 1;
3904 lop = 1;
3905 break;
3907 case INTRINSIC_LT:
3908 case INTRINSIC_LT_OS:
3909 code = LT_EXPR;
3910 checkstring = 1;
3911 lop = 1;
3912 break;
3914 case INTRINSIC_LE:
3915 case INTRINSIC_LE_OS:
3916 code = LE_EXPR;
3917 checkstring = 1;
3918 lop = 1;
3919 break;
3921 case INTRINSIC_USER:
3922 case INTRINSIC_ASSIGN:
3923 /* These should be converted into function calls by the frontend. */
3924 gcc_unreachable ();
3926 default:
3927 fatal_error (input_location, "Unknown intrinsic op");
3928 return;
3931 /* The only exception to this is **, which is handled separately anyway. */
3932 gcc_assert (expr->value.op.op1->ts.type == expr->value.op.op2->ts.type);
3934 if (checkstring && expr->value.op.op1->ts.type != BT_CHARACTER)
3935 checkstring = 0;
3937 /* lhs */
3938 gfc_init_se (&lse, se);
3939 gfc_conv_expr (&lse, expr->value.op.op1);
3940 gfc_add_block_to_block (&se->pre, &lse.pre);
3942 /* rhs */
3943 gfc_init_se (&rse, se);
3944 gfc_conv_expr (&rse, expr->value.op.op2);
3945 gfc_add_block_to_block (&se->pre, &rse.pre);
3947 if (checkstring)
3949 gfc_conv_string_parameter (&lse);
3950 gfc_conv_string_parameter (&rse);
3952 lse.expr = gfc_build_compare_string (lse.string_length, lse.expr,
3953 rse.string_length, rse.expr,
3954 expr->value.op.op1->ts.kind,
3955 code);
3956 rse.expr = build_int_cst (TREE_TYPE (lse.expr), 0);
3957 gfc_add_block_to_block (&lse.post, &rse.post);
3960 type = gfc_typenode_for_spec (&expr->ts);
3962 if (lop)
3964 /* The result of logical ops is always logical_type_node. */
3965 tmp = fold_build2_loc (input_location, code, logical_type_node,
3966 lse.expr, rse.expr);
3967 se->expr = convert (type, tmp);
3969 else
3970 se->expr = fold_build2_loc (input_location, code, type, lse.expr, rse.expr);
3972 /* Add the post blocks. */
3973 gfc_add_block_to_block (&se->post, &rse.post);
3974 gfc_add_block_to_block (&se->post, &lse.post);
3977 /* If a string's length is one, we convert it to a single character. */
3979 tree
3980 gfc_string_to_single_character (tree len, tree str, int kind)
3983 if (len == NULL
3984 || !tree_fits_uhwi_p (len)
3985 || !POINTER_TYPE_P (TREE_TYPE (str)))
3986 return NULL_TREE;
3988 if (TREE_INT_CST_LOW (len) == 1)
3990 str = fold_convert (gfc_get_pchar_type (kind), str);
3991 return build_fold_indirect_ref_loc (input_location, str);
3994 if (kind == 1
3995 && TREE_CODE (str) == ADDR_EXPR
3996 && TREE_CODE (TREE_OPERAND (str, 0)) == ARRAY_REF
3997 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (str, 0), 0)) == STRING_CST
3998 && array_ref_low_bound (TREE_OPERAND (str, 0))
3999 == TREE_OPERAND (TREE_OPERAND (str, 0), 1)
4000 && TREE_INT_CST_LOW (len) > 1
4001 && TREE_INT_CST_LOW (len)
4002 == (unsigned HOST_WIDE_INT)
4003 TREE_STRING_LENGTH (TREE_OPERAND (TREE_OPERAND (str, 0), 0)))
4005 tree ret = fold_convert (gfc_get_pchar_type (kind), str);
4006 ret = build_fold_indirect_ref_loc (input_location, ret);
4007 if (TREE_CODE (ret) == INTEGER_CST)
4009 tree string_cst = TREE_OPERAND (TREE_OPERAND (str, 0), 0);
4010 int i, length = TREE_STRING_LENGTH (string_cst);
4011 const char *ptr = TREE_STRING_POINTER (string_cst);
4013 for (i = 1; i < length; i++)
4014 if (ptr[i] != ' ')
4015 return NULL_TREE;
4017 return ret;
4021 return NULL_TREE;
4025 static void
4026 conv_scalar_char_value (gfc_symbol *sym, gfc_se *se, gfc_expr **expr)
4028 gcc_assert (expr);
4030 /* We used to modify the tree here. Now it is done earlier in
4031 the front-end, so we only check it here to avoid regressions. */
4032 if (sym->backend_decl)
4034 gcc_assert (TREE_CODE (TREE_TYPE (sym->backend_decl)) == INTEGER_TYPE);
4035 gcc_assert (TYPE_UNSIGNED (TREE_TYPE (sym->backend_decl)) == 1);
4036 gcc_assert (TYPE_PRECISION (TREE_TYPE (sym->backend_decl)) == CHAR_TYPE_SIZE);
4037 gcc_assert (DECL_BY_REFERENCE (sym->backend_decl) == 0);
4040 /* If we have a constant character expression, make it into an
4041 integer of type C char. */
4042 if ((*expr)->expr_type == EXPR_CONSTANT)
4044 gfc_typespec ts;
4045 gfc_clear_ts (&ts);
4047 gfc_expr *tmp = gfc_get_int_expr (gfc_default_character_kind, NULL,
4048 (*expr)->value.character.string[0]);
4049 gfc_replace_expr (*expr, tmp);
4051 else if (se != NULL && (*expr)->expr_type == EXPR_VARIABLE)
4053 if ((*expr)->ref == NULL)
4055 se->expr = gfc_string_to_single_character
4056 (build_int_cst (integer_type_node, 1),
4057 gfc_build_addr_expr (gfc_get_pchar_type ((*expr)->ts.kind),
4058 gfc_get_symbol_decl
4059 ((*expr)->symtree->n.sym)),
4060 (*expr)->ts.kind);
4062 else
4064 gfc_conv_variable (se, *expr);
4065 se->expr = gfc_string_to_single_character
4066 (build_int_cst (integer_type_node, 1),
4067 gfc_build_addr_expr (gfc_get_pchar_type ((*expr)->ts.kind),
4068 se->expr),
4069 (*expr)->ts.kind);
4074 /* Helper function for gfc_build_compare_string. Return LEN_TRIM value
4075 if STR is a string literal, otherwise return -1. */
4077 static int
4078 gfc_optimize_len_trim (tree len, tree str, int kind)
4080 if (kind == 1
4081 && TREE_CODE (str) == ADDR_EXPR
4082 && TREE_CODE (TREE_OPERAND (str, 0)) == ARRAY_REF
4083 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (str, 0), 0)) == STRING_CST
4084 && array_ref_low_bound (TREE_OPERAND (str, 0))
4085 == TREE_OPERAND (TREE_OPERAND (str, 0), 1)
4086 && tree_fits_uhwi_p (len)
4087 && tree_to_uhwi (len) >= 1
4088 && tree_to_uhwi (len)
4089 == (unsigned HOST_WIDE_INT)
4090 TREE_STRING_LENGTH (TREE_OPERAND (TREE_OPERAND (str, 0), 0)))
4092 tree folded = fold_convert (gfc_get_pchar_type (kind), str);
4093 folded = build_fold_indirect_ref_loc (input_location, folded);
4094 if (TREE_CODE (folded) == INTEGER_CST)
4096 tree string_cst = TREE_OPERAND (TREE_OPERAND (str, 0), 0);
4097 int length = TREE_STRING_LENGTH (string_cst);
4098 const char *ptr = TREE_STRING_POINTER (string_cst);
4100 for (; length > 0; length--)
4101 if (ptr[length - 1] != ' ')
4102 break;
4104 return length;
4107 return -1;
4110 /* Helper to build a call to memcmp. */
4112 static tree
4113 build_memcmp_call (tree s1, tree s2, tree n)
4115 tree tmp;
4117 if (!POINTER_TYPE_P (TREE_TYPE (s1)))
4118 s1 = gfc_build_addr_expr (pvoid_type_node, s1);
4119 else
4120 s1 = fold_convert (pvoid_type_node, s1);
4122 if (!POINTER_TYPE_P (TREE_TYPE (s2)))
4123 s2 = gfc_build_addr_expr (pvoid_type_node, s2);
4124 else
4125 s2 = fold_convert (pvoid_type_node, s2);
4127 n = fold_convert (size_type_node, n);
4129 tmp = build_call_expr_loc (input_location,
4130 builtin_decl_explicit (BUILT_IN_MEMCMP),
4131 3, s1, s2, n);
4133 return fold_convert (integer_type_node, tmp);
4136 /* Compare two strings. If they are all single characters, the result is the
4137 subtraction of them. Otherwise, we build a library call. */
4139 tree
4140 gfc_build_compare_string (tree len1, tree str1, tree len2, tree str2, int kind,
4141 enum tree_code code)
4143 tree sc1;
4144 tree sc2;
4145 tree fndecl;
4147 gcc_assert (POINTER_TYPE_P (TREE_TYPE (str1)));
4148 gcc_assert (POINTER_TYPE_P (TREE_TYPE (str2)));
4150 sc1 = gfc_string_to_single_character (len1, str1, kind);
4151 sc2 = gfc_string_to_single_character (len2, str2, kind);
4153 if (sc1 != NULL_TREE && sc2 != NULL_TREE)
4155 /* Deal with single character specially. */
4156 sc1 = fold_convert (integer_type_node, sc1);
4157 sc2 = fold_convert (integer_type_node, sc2);
4158 return fold_build2_loc (input_location, MINUS_EXPR, integer_type_node,
4159 sc1, sc2);
4162 if ((code == EQ_EXPR || code == NE_EXPR)
4163 && optimize
4164 && INTEGER_CST_P (len1) && INTEGER_CST_P (len2))
4166 /* If one string is a string literal with LEN_TRIM longer
4167 than the length of the second string, the strings
4168 compare unequal. */
4169 int len = gfc_optimize_len_trim (len1, str1, kind);
4170 if (len > 0 && compare_tree_int (len2, len) < 0)
4171 return integer_one_node;
4172 len = gfc_optimize_len_trim (len2, str2, kind);
4173 if (len > 0 && compare_tree_int (len1, len) < 0)
4174 return integer_one_node;
4177 /* We can compare via memcpy if the strings are known to be equal
4178 in length and they are
4179 - kind=1
4180 - kind=4 and the comparison is for (in)equality. */
4182 if (INTEGER_CST_P (len1) && INTEGER_CST_P (len2)
4183 && tree_int_cst_equal (len1, len2)
4184 && (kind == 1 || code == EQ_EXPR || code == NE_EXPR))
4186 tree tmp;
4187 tree chartype;
4189 chartype = gfc_get_char_type (kind);
4190 tmp = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE(len1),
4191 fold_convert (TREE_TYPE(len1),
4192 TYPE_SIZE_UNIT(chartype)),
4193 len1);
4194 return build_memcmp_call (str1, str2, tmp);
4197 /* Build a call for the comparison. */
4198 if (kind == 1)
4199 fndecl = gfor_fndecl_compare_string;
4200 else if (kind == 4)
4201 fndecl = gfor_fndecl_compare_string_char4;
4202 else
4203 gcc_unreachable ();
4205 return build_call_expr_loc (input_location, fndecl, 4,
4206 len1, str1, len2, str2);
4210 /* Return the backend_decl for a procedure pointer component. */
4212 static tree
4213 get_proc_ptr_comp (gfc_expr *e)
4215 gfc_se comp_se;
4216 gfc_expr *e2;
4217 expr_t old_type;
4219 gfc_init_se (&comp_se, NULL);
4220 e2 = gfc_copy_expr (e);
4221 /* We have to restore the expr type later so that gfc_free_expr frees
4222 the exact same thing that was allocated.
4223 TODO: This is ugly. */
4224 old_type = e2->expr_type;
4225 e2->expr_type = EXPR_VARIABLE;
4226 gfc_conv_expr (&comp_se, e2);
4227 e2->expr_type = old_type;
4228 gfc_free_expr (e2);
4229 return build_fold_addr_expr_loc (input_location, comp_se.expr);
4233 /* Convert a typebound function reference from a class object. */
4234 static void
4235 conv_base_obj_fcn_val (gfc_se * se, tree base_object, gfc_expr * expr)
4237 gfc_ref *ref;
4238 tree var;
4240 if (!VAR_P (base_object))
4242 var = gfc_create_var (TREE_TYPE (base_object), NULL);
4243 gfc_add_modify (&se->pre, var, base_object);
4245 se->expr = gfc_class_vptr_get (base_object);
4246 se->expr = build_fold_indirect_ref_loc (input_location, se->expr);
4247 ref = expr->ref;
4248 while (ref && ref->next)
4249 ref = ref->next;
4250 gcc_assert (ref && ref->type == REF_COMPONENT);
4251 if (ref->u.c.sym->attr.extension)
4252 conv_parent_component_references (se, ref);
4253 gfc_conv_component_ref (se, ref);
4254 se->expr = build_fold_addr_expr_loc (input_location, se->expr);
4258 static void
4259 conv_function_val (gfc_se * se, gfc_symbol * sym, gfc_expr * expr,
4260 gfc_actual_arglist *actual_args)
4262 tree tmp;
4264 if (gfc_is_proc_ptr_comp (expr))
4265 tmp = get_proc_ptr_comp (expr);
4266 else if (sym->attr.dummy)
4268 tmp = gfc_get_symbol_decl (sym);
4269 if (sym->attr.proc_pointer)
4270 tmp = build_fold_indirect_ref_loc (input_location,
4271 tmp);
4272 gcc_assert (TREE_CODE (TREE_TYPE (tmp)) == POINTER_TYPE
4273 && TREE_CODE (TREE_TYPE (TREE_TYPE (tmp))) == FUNCTION_TYPE);
4275 else
4277 if (!sym->backend_decl)
4278 sym->backend_decl = gfc_get_extern_function_decl (sym, actual_args);
4280 TREE_USED (sym->backend_decl) = 1;
4282 tmp = sym->backend_decl;
4284 if (sym->attr.cray_pointee)
4286 /* TODO - make the cray pointee a pointer to a procedure,
4287 assign the pointer to it and use it for the call. This
4288 will do for now! */
4289 tmp = convert (build_pointer_type (TREE_TYPE (tmp)),
4290 gfc_get_symbol_decl (sym->cp_pointer));
4291 tmp = gfc_evaluate_now (tmp, &se->pre);
4294 if (!POINTER_TYPE_P (TREE_TYPE (tmp)))
4296 gcc_assert (TREE_CODE (tmp) == FUNCTION_DECL);
4297 tmp = gfc_build_addr_expr (NULL_TREE, tmp);
4300 se->expr = tmp;
4304 /* Initialize MAPPING. */
4306 void
4307 gfc_init_interface_mapping (gfc_interface_mapping * mapping)
4309 mapping->syms = NULL;
4310 mapping->charlens = NULL;
4314 /* Free all memory held by MAPPING (but not MAPPING itself). */
4316 void
4317 gfc_free_interface_mapping (gfc_interface_mapping * mapping)
4319 gfc_interface_sym_mapping *sym;
4320 gfc_interface_sym_mapping *nextsym;
4321 gfc_charlen *cl;
4322 gfc_charlen *nextcl;
4324 for (sym = mapping->syms; sym; sym = nextsym)
4326 nextsym = sym->next;
4327 sym->new_sym->n.sym->formal = NULL;
4328 gfc_free_symbol (sym->new_sym->n.sym);
4329 gfc_free_expr (sym->expr);
4330 free (sym->new_sym);
4331 free (sym);
4333 for (cl = mapping->charlens; cl; cl = nextcl)
4335 nextcl = cl->next;
4336 gfc_free_expr (cl->length);
4337 free (cl);
4342 /* Return a copy of gfc_charlen CL. Add the returned structure to
4343 MAPPING so that it will be freed by gfc_free_interface_mapping. */
4345 static gfc_charlen *
4346 gfc_get_interface_mapping_charlen (gfc_interface_mapping * mapping,
4347 gfc_charlen * cl)
4349 gfc_charlen *new_charlen;
4351 new_charlen = gfc_get_charlen ();
4352 new_charlen->next = mapping->charlens;
4353 new_charlen->length = gfc_copy_expr (cl->length);
4355 mapping->charlens = new_charlen;
4356 return new_charlen;
4360 /* A subroutine of gfc_add_interface_mapping. Return a descriptorless
4361 array variable that can be used as the actual argument for dummy
4362 argument SYM. Add any initialization code to BLOCK. PACKED is as
4363 for gfc_get_nodesc_array_type and DATA points to the first element
4364 in the passed array. */
4366 static tree
4367 gfc_get_interface_mapping_array (stmtblock_t * block, gfc_symbol * sym,
4368 gfc_packed packed, tree data)
4370 tree type;
4371 tree var;
4373 type = gfc_typenode_for_spec (&sym->ts);
4374 type = gfc_get_nodesc_array_type (type, sym->as, packed,
4375 !sym->attr.target && !sym->attr.pointer
4376 && !sym->attr.proc_pointer);
4378 var = gfc_create_var (type, "ifm");
4379 gfc_add_modify (block, var, fold_convert (type, data));
4381 return var;
4385 /* A subroutine of gfc_add_interface_mapping. Set the stride, upper bounds
4386 and offset of descriptorless array type TYPE given that it has the same
4387 size as DESC. Add any set-up code to BLOCK. */
4389 static void
4390 gfc_set_interface_mapping_bounds (stmtblock_t * block, tree type, tree desc)
4392 int n;
4393 tree dim;
4394 tree offset;
4395 tree tmp;
4397 offset = gfc_index_zero_node;
4398 for (n = 0; n < GFC_TYPE_ARRAY_RANK (type); n++)
4400 dim = gfc_rank_cst[n];
4401 GFC_TYPE_ARRAY_STRIDE (type, n) = gfc_conv_array_stride (desc, n);
4402 if (GFC_TYPE_ARRAY_LBOUND (type, n) == NULL_TREE)
4404 GFC_TYPE_ARRAY_LBOUND (type, n)
4405 = gfc_conv_descriptor_lbound_get (desc, dim);
4406 GFC_TYPE_ARRAY_UBOUND (type, n)
4407 = gfc_conv_descriptor_ubound_get (desc, dim);
4409 else if (GFC_TYPE_ARRAY_UBOUND (type, n) == NULL_TREE)
4411 tmp = fold_build2_loc (input_location, MINUS_EXPR,
4412 gfc_array_index_type,
4413 gfc_conv_descriptor_ubound_get (desc, dim),
4414 gfc_conv_descriptor_lbound_get (desc, dim));
4415 tmp = fold_build2_loc (input_location, PLUS_EXPR,
4416 gfc_array_index_type,
4417 GFC_TYPE_ARRAY_LBOUND (type, n), tmp);
4418 tmp = gfc_evaluate_now (tmp, block);
4419 GFC_TYPE_ARRAY_UBOUND (type, n) = tmp;
4421 tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
4422 GFC_TYPE_ARRAY_LBOUND (type, n),
4423 GFC_TYPE_ARRAY_STRIDE (type, n));
4424 offset = fold_build2_loc (input_location, MINUS_EXPR,
4425 gfc_array_index_type, offset, tmp);
4427 offset = gfc_evaluate_now (offset, block);
4428 GFC_TYPE_ARRAY_OFFSET (type) = offset;
4432 /* Extend MAPPING so that it maps dummy argument SYM to the value stored
4433 in SE. The caller may still use se->expr and se->string_length after
4434 calling this function. */
4436 void
4437 gfc_add_interface_mapping (gfc_interface_mapping * mapping,
4438 gfc_symbol * sym, gfc_se * se,
4439 gfc_expr *expr)
4441 gfc_interface_sym_mapping *sm;
4442 tree desc;
4443 tree tmp;
4444 tree value;
4445 gfc_symbol *new_sym;
4446 gfc_symtree *root;
4447 gfc_symtree *new_symtree;
4449 /* Create a new symbol to represent the actual argument. */
4450 new_sym = gfc_new_symbol (sym->name, NULL);
4451 new_sym->ts = sym->ts;
4452 new_sym->as = gfc_copy_array_spec (sym->as);
4453 new_sym->attr.referenced = 1;
4454 new_sym->attr.dimension = sym->attr.dimension;
4455 new_sym->attr.contiguous = sym->attr.contiguous;
4456 new_sym->attr.codimension = sym->attr.codimension;
4457 new_sym->attr.pointer = sym->attr.pointer;
4458 new_sym->attr.allocatable = sym->attr.allocatable;
4459 new_sym->attr.flavor = sym->attr.flavor;
4460 new_sym->attr.function = sym->attr.function;
4462 /* Ensure that the interface is available and that
4463 descriptors are passed for array actual arguments. */
4464 if (sym->attr.flavor == FL_PROCEDURE)
4466 new_sym->formal = expr->symtree->n.sym->formal;
4467 new_sym->attr.always_explicit
4468 = expr->symtree->n.sym->attr.always_explicit;
4471 /* Create a fake symtree for it. */
4472 root = NULL;
4473 new_symtree = gfc_new_symtree (&root, sym->name);
4474 new_symtree->n.sym = new_sym;
4475 gcc_assert (new_symtree == root);
4477 /* Create a dummy->actual mapping. */
4478 sm = XCNEW (gfc_interface_sym_mapping);
4479 sm->next = mapping->syms;
4480 sm->old = sym;
4481 sm->new_sym = new_symtree;
4482 sm->expr = gfc_copy_expr (expr);
4483 mapping->syms = sm;
4485 /* Stabilize the argument's value. */
4486 if (!sym->attr.function && se)
4487 se->expr = gfc_evaluate_now (se->expr, &se->pre);
4489 if (sym->ts.type == BT_CHARACTER)
4491 /* Create a copy of the dummy argument's length. */
4492 new_sym->ts.u.cl = gfc_get_interface_mapping_charlen (mapping, sym->ts.u.cl);
4493 sm->expr->ts.u.cl = new_sym->ts.u.cl;
4495 /* If the length is specified as "*", record the length that
4496 the caller is passing. We should use the callee's length
4497 in all other cases. */
4498 if (!new_sym->ts.u.cl->length && se)
4500 se->string_length = gfc_evaluate_now (se->string_length, &se->pre);
4501 new_sym->ts.u.cl->backend_decl = se->string_length;
4505 if (!se)
4506 return;
4508 /* Use the passed value as-is if the argument is a function. */
4509 if (sym->attr.flavor == FL_PROCEDURE)
4510 value = se->expr;
4512 /* If the argument is a pass-by-value scalar, use the value as is. */
4513 else if (!sym->attr.dimension && sym->attr.value)
4514 value = se->expr;
4516 /* If the argument is either a string or a pointer to a string,
4517 convert it to a boundless character type. */
4518 else if (!sym->attr.dimension && sym->ts.type == BT_CHARACTER)
4520 tmp = gfc_get_character_type_len (sym->ts.kind, NULL);
4521 tmp = build_pointer_type (tmp);
4522 if (sym->attr.pointer)
4523 value = build_fold_indirect_ref_loc (input_location,
4524 se->expr);
4525 else
4526 value = se->expr;
4527 value = fold_convert (tmp, value);
4530 /* If the argument is a scalar, a pointer to an array or an allocatable,
4531 dereference it. */
4532 else if (!sym->attr.dimension || sym->attr.pointer || sym->attr.allocatable)
4533 value = build_fold_indirect_ref_loc (input_location,
4534 se->expr);
4536 /* For character(*), use the actual argument's descriptor. */
4537 else if (sym->ts.type == BT_CHARACTER && !new_sym->ts.u.cl->length)
4538 value = build_fold_indirect_ref_loc (input_location,
4539 se->expr);
4541 /* If the argument is an array descriptor, use it to determine
4542 information about the actual argument's shape. */
4543 else if (POINTER_TYPE_P (TREE_TYPE (se->expr))
4544 && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (TREE_TYPE (se->expr))))
4546 /* Get the actual argument's descriptor. */
4547 desc = build_fold_indirect_ref_loc (input_location,
4548 se->expr);
4550 /* Create the replacement variable. */
4551 tmp = gfc_conv_descriptor_data_get (desc);
4552 value = gfc_get_interface_mapping_array (&se->pre, sym,
4553 PACKED_NO, tmp);
4555 /* Use DESC to work out the upper bounds, strides and offset. */
4556 gfc_set_interface_mapping_bounds (&se->pre, TREE_TYPE (value), desc);
4558 else
4559 /* Otherwise we have a packed array. */
4560 value = gfc_get_interface_mapping_array (&se->pre, sym,
4561 PACKED_FULL, se->expr);
4563 new_sym->backend_decl = value;
4567 /* Called once all dummy argument mappings have been added to MAPPING,
4568 but before the mapping is used to evaluate expressions. Pre-evaluate
4569 the length of each argument, adding any initialization code to PRE and
4570 any finalization code to POST. */
4572 static void
4573 gfc_finish_interface_mapping (gfc_interface_mapping * mapping,
4574 stmtblock_t * pre, stmtblock_t * post)
4576 gfc_interface_sym_mapping *sym;
4577 gfc_expr *expr;
4578 gfc_se se;
4580 for (sym = mapping->syms; sym; sym = sym->next)
4581 if (sym->new_sym->n.sym->ts.type == BT_CHARACTER
4582 && !sym->new_sym->n.sym->ts.u.cl->backend_decl)
4584 expr = sym->new_sym->n.sym->ts.u.cl->length;
4585 gfc_apply_interface_mapping_to_expr (mapping, expr);
4586 gfc_init_se (&se, NULL);
4587 gfc_conv_expr (&se, expr);
4588 se.expr = fold_convert (gfc_charlen_type_node, se.expr);
4589 se.expr = gfc_evaluate_now (se.expr, &se.pre);
4590 gfc_add_block_to_block (pre, &se.pre);
4591 gfc_add_block_to_block (post, &se.post);
4593 sym->new_sym->n.sym->ts.u.cl->backend_decl = se.expr;
4598 /* Like gfc_apply_interface_mapping_to_expr, but applied to
4599 constructor C. */
4601 static void
4602 gfc_apply_interface_mapping_to_cons (gfc_interface_mapping * mapping,
4603 gfc_constructor_base base)
4605 gfc_constructor *c;
4606 for (c = gfc_constructor_first (base); c; c = gfc_constructor_next (c))
4608 gfc_apply_interface_mapping_to_expr (mapping, c->expr);
4609 if (c->iterator)
4611 gfc_apply_interface_mapping_to_expr (mapping, c->iterator->start);
4612 gfc_apply_interface_mapping_to_expr (mapping, c->iterator->end);
4613 gfc_apply_interface_mapping_to_expr (mapping, c->iterator->step);
4619 /* Like gfc_apply_interface_mapping_to_expr, but applied to
4620 reference REF. */
4622 static void
4623 gfc_apply_interface_mapping_to_ref (gfc_interface_mapping * mapping,
4624 gfc_ref * ref)
4626 int n;
4628 for (; ref; ref = ref->next)
4629 switch (ref->type)
4631 case REF_ARRAY:
4632 for (n = 0; n < ref->u.ar.dimen; n++)
4634 gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.start[n]);
4635 gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.end[n]);
4636 gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.stride[n]);
4638 break;
4640 case REF_COMPONENT:
4641 case REF_INQUIRY:
4642 break;
4644 case REF_SUBSTRING:
4645 gfc_apply_interface_mapping_to_expr (mapping, ref->u.ss.start);
4646 gfc_apply_interface_mapping_to_expr (mapping, ref->u.ss.end);
4647 break;
4652 /* Convert intrinsic function calls into result expressions. */
4654 static bool
4655 gfc_map_intrinsic_function (gfc_expr *expr, gfc_interface_mapping *mapping)
4657 gfc_symbol *sym;
4658 gfc_expr *new_expr;
4659 gfc_expr *arg1;
4660 gfc_expr *arg2;
4661 int d, dup;
4663 arg1 = expr->value.function.actual->expr;
4664 if (expr->value.function.actual->next)
4665 arg2 = expr->value.function.actual->next->expr;
4666 else
4667 arg2 = NULL;
4669 sym = arg1->symtree->n.sym;
4671 if (sym->attr.dummy)
4672 return false;
4674 new_expr = NULL;
4676 switch (expr->value.function.isym->id)
4678 case GFC_ISYM_LEN:
4679 /* TODO figure out why this condition is necessary. */
4680 if (sym->attr.function
4681 && (arg1->ts.u.cl->length == NULL
4682 || (arg1->ts.u.cl->length->expr_type != EXPR_CONSTANT
4683 && arg1->ts.u.cl->length->expr_type != EXPR_VARIABLE)))
4684 return false;
4686 new_expr = gfc_copy_expr (arg1->ts.u.cl->length);
4687 break;
4689 case GFC_ISYM_LEN_TRIM:
4690 new_expr = gfc_copy_expr (arg1);
4691 gfc_apply_interface_mapping_to_expr (mapping, new_expr);
4693 if (!new_expr)
4694 return false;
4696 gfc_replace_expr (arg1, new_expr);
4697 return true;
4699 case GFC_ISYM_SIZE:
4700 if (!sym->as || sym->as->rank == 0)
4701 return false;
4703 if (arg2 && arg2->expr_type == EXPR_CONSTANT)
4705 dup = mpz_get_si (arg2->value.integer);
4706 d = dup - 1;
4708 else
4710 dup = sym->as->rank;
4711 d = 0;
4714 for (; d < dup; d++)
4716 gfc_expr *tmp;
4718 if (!sym->as->upper[d] || !sym->as->lower[d])
4720 gfc_free_expr (new_expr);
4721 return false;
4724 tmp = gfc_add (gfc_copy_expr (sym->as->upper[d]),
4725 gfc_get_int_expr (gfc_default_integer_kind,
4726 NULL, 1));
4727 tmp = gfc_subtract (tmp, gfc_copy_expr (sym->as->lower[d]));
4728 if (new_expr)
4729 new_expr = gfc_multiply (new_expr, tmp);
4730 else
4731 new_expr = tmp;
4733 break;
4735 case GFC_ISYM_LBOUND:
4736 case GFC_ISYM_UBOUND:
4737 /* TODO These implementations of lbound and ubound do not limit if
4738 the size < 0, according to F95's 13.14.53 and 13.14.113. */
4740 if (!sym->as || sym->as->rank == 0)
4741 return false;
4743 if (arg2 && arg2->expr_type == EXPR_CONSTANT)
4744 d = mpz_get_si (arg2->value.integer) - 1;
4745 else
4746 return false;
4748 if (expr->value.function.isym->id == GFC_ISYM_LBOUND)
4750 if (sym->as->lower[d])
4751 new_expr = gfc_copy_expr (sym->as->lower[d]);
4753 else
4755 if (sym->as->upper[d])
4756 new_expr = gfc_copy_expr (sym->as->upper[d]);
4758 break;
4760 default:
4761 break;
4764 gfc_apply_interface_mapping_to_expr (mapping, new_expr);
4765 if (!new_expr)
4766 return false;
4768 gfc_replace_expr (expr, new_expr);
4769 return true;
4773 static void
4774 gfc_map_fcn_formal_to_actual (gfc_expr *expr, gfc_expr *map_expr,
4775 gfc_interface_mapping * mapping)
4777 gfc_formal_arglist *f;
4778 gfc_actual_arglist *actual;
4780 actual = expr->value.function.actual;
4781 f = gfc_sym_get_dummy_args (map_expr->symtree->n.sym);
4783 for (; f && actual; f = f->next, actual = actual->next)
4785 if (!actual->expr)
4786 continue;
4788 gfc_add_interface_mapping (mapping, f->sym, NULL, actual->expr);
4791 if (map_expr->symtree->n.sym->attr.dimension)
4793 int d;
4794 gfc_array_spec *as;
4796 as = gfc_copy_array_spec (map_expr->symtree->n.sym->as);
4798 for (d = 0; d < as->rank; d++)
4800 gfc_apply_interface_mapping_to_expr (mapping, as->lower[d]);
4801 gfc_apply_interface_mapping_to_expr (mapping, as->upper[d]);
4804 expr->value.function.esym->as = as;
4807 if (map_expr->symtree->n.sym->ts.type == BT_CHARACTER)
4809 expr->value.function.esym->ts.u.cl->length
4810 = gfc_copy_expr (map_expr->symtree->n.sym->ts.u.cl->length);
4812 gfc_apply_interface_mapping_to_expr (mapping,
4813 expr->value.function.esym->ts.u.cl->length);
4818 /* EXPR is a copy of an expression that appeared in the interface
4819 associated with MAPPING. Walk it recursively looking for references to
4820 dummy arguments that MAPPING maps to actual arguments. Replace each such
4821 reference with a reference to the associated actual argument. */
4823 static void
4824 gfc_apply_interface_mapping_to_expr (gfc_interface_mapping * mapping,
4825 gfc_expr * expr)
4827 gfc_interface_sym_mapping *sym;
4828 gfc_actual_arglist *actual;
4830 if (!expr)
4831 return;
4833 /* Copying an expression does not copy its length, so do that here. */
4834 if (expr->ts.type == BT_CHARACTER && expr->ts.u.cl)
4836 expr->ts.u.cl = gfc_get_interface_mapping_charlen (mapping, expr->ts.u.cl);
4837 gfc_apply_interface_mapping_to_expr (mapping, expr->ts.u.cl->length);
4840 /* Apply the mapping to any references. */
4841 gfc_apply_interface_mapping_to_ref (mapping, expr->ref);
4843 /* ...and to the expression's symbol, if it has one. */
4844 /* TODO Find out why the condition on expr->symtree had to be moved into
4845 the loop rather than being outside it, as originally. */
4846 for (sym = mapping->syms; sym; sym = sym->next)
4847 if (expr->symtree && sym->old == expr->symtree->n.sym)
4849 if (sym->new_sym->n.sym->backend_decl)
4850 expr->symtree = sym->new_sym;
4851 else if (sym->expr)
4852 gfc_replace_expr (expr, gfc_copy_expr (sym->expr));
4855 /* ...and to subexpressions in expr->value. */
4856 switch (expr->expr_type)
4858 case EXPR_VARIABLE:
4859 case EXPR_CONSTANT:
4860 case EXPR_NULL:
4861 case EXPR_SUBSTRING:
4862 break;
4864 case EXPR_OP:
4865 gfc_apply_interface_mapping_to_expr (mapping, expr->value.op.op1);
4866 gfc_apply_interface_mapping_to_expr (mapping, expr->value.op.op2);
4867 break;
4869 case EXPR_FUNCTION:
4870 for (actual = expr->value.function.actual; actual; actual = actual->next)
4871 gfc_apply_interface_mapping_to_expr (mapping, actual->expr);
4873 if (expr->value.function.esym == NULL
4874 && expr->value.function.isym != NULL
4875 && expr->value.function.actual
4876 && expr->value.function.actual->expr
4877 && expr->value.function.actual->expr->symtree
4878 && gfc_map_intrinsic_function (expr, mapping))
4879 break;
4881 for (sym = mapping->syms; sym; sym = sym->next)
4882 if (sym->old == expr->value.function.esym)
4884 expr->value.function.esym = sym->new_sym->n.sym;
4885 gfc_map_fcn_formal_to_actual (expr, sym->expr, mapping);
4886 expr->value.function.esym->result = sym->new_sym->n.sym;
4888 break;
4890 case EXPR_ARRAY:
4891 case EXPR_STRUCTURE:
4892 gfc_apply_interface_mapping_to_cons (mapping, expr->value.constructor);
4893 break;
4895 case EXPR_COMPCALL:
4896 case EXPR_PPC:
4897 case EXPR_UNKNOWN:
4898 gcc_unreachable ();
4899 break;
4902 return;
4906 /* Evaluate interface expression EXPR using MAPPING. Store the result
4907 in SE. */
4909 void
4910 gfc_apply_interface_mapping (gfc_interface_mapping * mapping,
4911 gfc_se * se, gfc_expr * expr)
4913 expr = gfc_copy_expr (expr);
4914 gfc_apply_interface_mapping_to_expr (mapping, expr);
4915 gfc_conv_expr (se, expr);
4916 se->expr = gfc_evaluate_now (se->expr, &se->pre);
4917 gfc_free_expr (expr);
4921 /* Returns a reference to a temporary array into which a component of
4922 an actual argument derived type array is copied and then returned
4923 after the function call. */
4924 void
4925 gfc_conv_subref_array_arg (gfc_se *se, gfc_expr * expr, int g77,
4926 sym_intent intent, bool formal_ptr,
4927 const gfc_symbol *fsym, const char *proc_name,
4928 gfc_symbol *sym, bool check_contiguous)
4930 gfc_se lse;
4931 gfc_se rse;
4932 gfc_ss *lss;
4933 gfc_ss *rss;
4934 gfc_loopinfo loop;
4935 gfc_loopinfo loop2;
4936 gfc_array_info *info;
4937 tree offset;
4938 tree tmp_index;
4939 tree tmp;
4940 tree base_type;
4941 tree size;
4942 stmtblock_t body;
4943 int n;
4944 int dimen;
4945 gfc_se work_se;
4946 gfc_se *parmse;
4947 bool pass_optional;
4949 pass_optional = fsym && fsym->attr.optional && sym && sym->attr.optional;
4951 if (pass_optional || check_contiguous)
4953 gfc_init_se (&work_se, NULL);
4954 parmse = &work_se;
4956 else
4957 parmse = se;
4959 if (gfc_option.rtcheck & GFC_RTCHECK_ARRAY_TEMPS)
4961 /* We will create a temporary array, so let us warn. */
4962 char * msg;
4964 if (fsym && proc_name)
4965 msg = xasprintf ("An array temporary was created for argument "
4966 "'%s' of procedure '%s'", fsym->name, proc_name);
4967 else
4968 msg = xasprintf ("An array temporary was created");
4970 tmp = build_int_cst (logical_type_node, 1);
4971 gfc_trans_runtime_check (false, true, tmp, &parmse->pre,
4972 &expr->where, msg);
4973 free (msg);
4976 gfc_init_se (&lse, NULL);
4977 gfc_init_se (&rse, NULL);
4979 /* Walk the argument expression. */
4980 rss = gfc_walk_expr (expr);
4982 gcc_assert (rss != gfc_ss_terminator);
4984 /* Initialize the scalarizer. */
4985 gfc_init_loopinfo (&loop);
4986 gfc_add_ss_to_loop (&loop, rss);
4988 /* Calculate the bounds of the scalarization. */
4989 gfc_conv_ss_startstride (&loop);
4991 /* Build an ss for the temporary. */
4992 if (expr->ts.type == BT_CHARACTER && !expr->ts.u.cl->backend_decl)
4993 gfc_conv_string_length (expr->ts.u.cl, expr, &parmse->pre);
4995 base_type = gfc_typenode_for_spec (&expr->ts);
4996 if (GFC_ARRAY_TYPE_P (base_type)
4997 || GFC_DESCRIPTOR_TYPE_P (base_type))
4998 base_type = gfc_get_element_type (base_type);
5000 if (expr->ts.type == BT_CLASS)
5001 base_type = gfc_typenode_for_spec (&CLASS_DATA (expr)->ts);
5003 loop.temp_ss = gfc_get_temp_ss (base_type, ((expr->ts.type == BT_CHARACTER)
5004 ? expr->ts.u.cl->backend_decl
5005 : NULL),
5006 loop.dimen);
5008 parmse->string_length = loop.temp_ss->info->string_length;
5010 /* Associate the SS with the loop. */
5011 gfc_add_ss_to_loop (&loop, loop.temp_ss);
5013 /* Setup the scalarizing loops. */
5014 gfc_conv_loop_setup (&loop, &expr->where);
5016 /* Pass the temporary descriptor back to the caller. */
5017 info = &loop.temp_ss->info->data.array;
5018 parmse->expr = info->descriptor;
5020 /* Setup the gfc_se structures. */
5021 gfc_copy_loopinfo_to_se (&lse, &loop);
5022 gfc_copy_loopinfo_to_se (&rse, &loop);
5024 rse.ss = rss;
5025 lse.ss = loop.temp_ss;
5026 gfc_mark_ss_chain_used (rss, 1);
5027 gfc_mark_ss_chain_used (loop.temp_ss, 1);
5029 /* Start the scalarized loop body. */
5030 gfc_start_scalarized_body (&loop, &body);
5032 /* Translate the expression. */
5033 gfc_conv_expr (&rse, expr);
5035 /* Reset the offset for the function call since the loop
5036 is zero based on the data pointer. Note that the temp
5037 comes first in the loop chain since it is added second. */
5038 if (gfc_is_class_array_function (expr))
5040 tmp = loop.ss->loop_chain->info->data.array.descriptor;
5041 gfc_conv_descriptor_offset_set (&loop.pre, tmp,
5042 gfc_index_zero_node);
5045 gfc_conv_tmp_array_ref (&lse);
5047 if (intent != INTENT_OUT)
5049 tmp = gfc_trans_scalar_assign (&lse, &rse, expr->ts, false, false);
5050 gfc_add_expr_to_block (&body, tmp);
5051 gcc_assert (rse.ss == gfc_ss_terminator);
5052 gfc_trans_scalarizing_loops (&loop, &body);
5054 else
5056 /* Make sure that the temporary declaration survives by merging
5057 all the loop declarations into the current context. */
5058 for (n = 0; n < loop.dimen; n++)
5060 gfc_merge_block_scope (&body);
5061 body = loop.code[loop.order[n]];
5063 gfc_merge_block_scope (&body);
5066 /* Add the post block after the second loop, so that any
5067 freeing of allocated memory is done at the right time. */
5068 gfc_add_block_to_block (&parmse->pre, &loop.pre);
5070 /**********Copy the temporary back again.*********/
5072 gfc_init_se (&lse, NULL);
5073 gfc_init_se (&rse, NULL);
5075 /* Walk the argument expression. */
5076 lss = gfc_walk_expr (expr);
5077 rse.ss = loop.temp_ss;
5078 lse.ss = lss;
5080 /* Initialize the scalarizer. */
5081 gfc_init_loopinfo (&loop2);
5082 gfc_add_ss_to_loop (&loop2, lss);
5084 dimen = rse.ss->dimen;
5086 /* Skip the write-out loop for this case. */
5087 if (gfc_is_class_array_function (expr))
5088 goto class_array_fcn;
5090 /* Calculate the bounds of the scalarization. */
5091 gfc_conv_ss_startstride (&loop2);
5093 /* Setup the scalarizing loops. */
5094 gfc_conv_loop_setup (&loop2, &expr->where);
5096 gfc_copy_loopinfo_to_se (&lse, &loop2);
5097 gfc_copy_loopinfo_to_se (&rse, &loop2);
5099 gfc_mark_ss_chain_used (lss, 1);
5100 gfc_mark_ss_chain_used (loop.temp_ss, 1);
5102 /* Declare the variable to hold the temporary offset and start the
5103 scalarized loop body. */
5104 offset = gfc_create_var (gfc_array_index_type, NULL);
5105 gfc_start_scalarized_body (&loop2, &body);
5107 /* Build the offsets for the temporary from the loop variables. The
5108 temporary array has lbounds of zero and strides of one in all
5109 dimensions, so this is very simple. The offset is only computed
5110 outside the innermost loop, so the overall transfer could be
5111 optimized further. */
5112 info = &rse.ss->info->data.array;
5114 tmp_index = gfc_index_zero_node;
5115 for (n = dimen - 1; n > 0; n--)
5117 tree tmp_str;
5118 tmp = rse.loop->loopvar[n];
5119 tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
5120 tmp, rse.loop->from[n]);
5121 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
5122 tmp, tmp_index);
5124 tmp_str = fold_build2_loc (input_location, MINUS_EXPR,
5125 gfc_array_index_type,
5126 rse.loop->to[n-1], rse.loop->from[n-1]);
5127 tmp_str = fold_build2_loc (input_location, PLUS_EXPR,
5128 gfc_array_index_type,
5129 tmp_str, gfc_index_one_node);
5131 tmp_index = fold_build2_loc (input_location, MULT_EXPR,
5132 gfc_array_index_type, tmp, tmp_str);
5135 tmp_index = fold_build2_loc (input_location, MINUS_EXPR,
5136 gfc_array_index_type,
5137 tmp_index, rse.loop->from[0]);
5138 gfc_add_modify (&rse.loop->code[0], offset, tmp_index);
5140 tmp_index = fold_build2_loc (input_location, PLUS_EXPR,
5141 gfc_array_index_type,
5142 rse.loop->loopvar[0], offset);
5144 /* Now use the offset for the reference. */
5145 tmp = build_fold_indirect_ref_loc (input_location,
5146 info->data);
5147 rse.expr = gfc_build_array_ref (tmp, tmp_index, NULL);
5149 if (expr->ts.type == BT_CHARACTER)
5150 rse.string_length = expr->ts.u.cl->backend_decl;
5152 gfc_conv_expr (&lse, expr);
5154 gcc_assert (lse.ss == gfc_ss_terminator);
5156 tmp = gfc_trans_scalar_assign (&lse, &rse, expr->ts, false, true);
5157 gfc_add_expr_to_block (&body, tmp);
5159 /* Generate the copying loops. */
5160 gfc_trans_scalarizing_loops (&loop2, &body);
5162 /* Wrap the whole thing up by adding the second loop to the post-block
5163 and following it by the post-block of the first loop. In this way,
5164 if the temporary needs freeing, it is done after use! */
5165 if (intent != INTENT_IN)
5167 gfc_add_block_to_block (&parmse->post, &loop2.pre);
5168 gfc_add_block_to_block (&parmse->post, &loop2.post);
5171 class_array_fcn:
5173 gfc_add_block_to_block (&parmse->post, &loop.post);
5175 gfc_cleanup_loop (&loop);
5176 gfc_cleanup_loop (&loop2);
5178 /* Pass the string length to the argument expression. */
5179 if (expr->ts.type == BT_CHARACTER)
5180 parmse->string_length = expr->ts.u.cl->backend_decl;
5182 /* Determine the offset for pointer formal arguments and set the
5183 lbounds to one. */
5184 if (formal_ptr)
5186 size = gfc_index_one_node;
5187 offset = gfc_index_zero_node;
5188 for (n = 0; n < dimen; n++)
5190 tmp = gfc_conv_descriptor_ubound_get (parmse->expr,
5191 gfc_rank_cst[n]);
5192 tmp = fold_build2_loc (input_location, PLUS_EXPR,
5193 gfc_array_index_type, tmp,
5194 gfc_index_one_node);
5195 gfc_conv_descriptor_ubound_set (&parmse->pre,
5196 parmse->expr,
5197 gfc_rank_cst[n],
5198 tmp);
5199 gfc_conv_descriptor_lbound_set (&parmse->pre,
5200 parmse->expr,
5201 gfc_rank_cst[n],
5202 gfc_index_one_node);
5203 size = gfc_evaluate_now (size, &parmse->pre);
5204 offset = fold_build2_loc (input_location, MINUS_EXPR,
5205 gfc_array_index_type,
5206 offset, size);
5207 offset = gfc_evaluate_now (offset, &parmse->pre);
5208 tmp = fold_build2_loc (input_location, MINUS_EXPR,
5209 gfc_array_index_type,
5210 rse.loop->to[n], rse.loop->from[n]);
5211 tmp = fold_build2_loc (input_location, PLUS_EXPR,
5212 gfc_array_index_type,
5213 tmp, gfc_index_one_node);
5214 size = fold_build2_loc (input_location, MULT_EXPR,
5215 gfc_array_index_type, size, tmp);
5218 gfc_conv_descriptor_offset_set (&parmse->pre, parmse->expr,
5219 offset);
5222 /* We want either the address for the data or the address of the descriptor,
5223 depending on the mode of passing array arguments. */
5224 if (g77)
5225 parmse->expr = gfc_conv_descriptor_data_get (parmse->expr);
5226 else
5227 parmse->expr = gfc_build_addr_expr (NULL_TREE, parmse->expr);
5229 /* Basically make this into
5231 if (present)
5233 if (contiguous)
5235 pointer = a;
5237 else
5239 parmse->pre();
5240 pointer = parmse->expr;
5243 else
5244 pointer = NULL;
5246 foo (pointer);
5247 if (present && !contiguous)
5248 se->post();
5252 if (pass_optional || check_contiguous)
5254 tree type;
5255 stmtblock_t else_block;
5256 tree pre_stmts, post_stmts;
5257 tree pointer;
5258 tree else_stmt;
5259 tree present_var = NULL_TREE;
5260 tree cont_var = NULL_TREE;
5261 tree post_cond;
5263 type = TREE_TYPE (parmse->expr);
5264 if (POINTER_TYPE_P (type) && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (type)))
5265 type = TREE_TYPE (type);
5266 pointer = gfc_create_var (type, "arg_ptr");
5268 if (check_contiguous)
5270 gfc_se cont_se, array_se;
5271 stmtblock_t if_block, else_block;
5272 tree if_stmt, else_stmt;
5273 mpz_t size;
5274 bool size_set;
5276 cont_var = gfc_create_var (boolean_type_node, "contiguous");
5278 /* If the size is known to be one at compile-time, set
5279 cont_var to true unconditionally. This may look
5280 inelegant, but we're only doing this during
5281 optimization, so the statements will be optimized away,
5282 and this saves complexity here. */
5284 size_set = gfc_array_size (expr, &size);
5285 if (size_set && mpz_cmp_ui (size, 1) == 0)
5287 gfc_add_modify (&se->pre, cont_var,
5288 build_one_cst (boolean_type_node));
5290 else
5292 /* cont_var = is_contiguous (expr); . */
5293 gfc_init_se (&cont_se, parmse);
5294 gfc_conv_is_contiguous_expr (&cont_se, expr);
5295 gfc_add_block_to_block (&se->pre, &(&cont_se)->pre);
5296 gfc_add_modify (&se->pre, cont_var, cont_se.expr);
5297 gfc_add_block_to_block (&se->pre, &(&cont_se)->post);
5300 if (size_set)
5301 mpz_clear (size);
5303 /* arrayse->expr = descriptor of a. */
5304 gfc_init_se (&array_se, se);
5305 gfc_conv_expr_descriptor (&array_se, expr);
5306 gfc_add_block_to_block (&se->pre, &(&array_se)->pre);
5307 gfc_add_block_to_block (&se->pre, &(&array_se)->post);
5309 /* if_stmt = { descriptor ? pointer = a : pointer = &a[0]; } . */
5310 gfc_init_block (&if_block);
5311 if (GFC_DESCRIPTOR_TYPE_P (type))
5312 gfc_add_modify (&if_block, pointer, array_se.expr);
5313 else
5315 tmp = gfc_conv_array_data (array_se.expr);
5316 tmp = fold_convert (type, tmp);
5317 gfc_add_modify (&if_block, pointer, tmp);
5319 if_stmt = gfc_finish_block (&if_block);
5321 /* else_stmt = { parmse->pre(); pointer = parmse->expr; } . */
5322 gfc_init_block (&else_block);
5323 gfc_add_block_to_block (&else_block, &parmse->pre);
5324 tmp = (GFC_DESCRIPTOR_TYPE_P (type)
5325 ? build_fold_indirect_ref_loc (input_location, parmse->expr)
5326 : parmse->expr);
5327 gfc_add_modify (&else_block, pointer, tmp);
5328 else_stmt = gfc_finish_block (&else_block);
5330 /* And put the above into an if statement. */
5331 pre_stmts = fold_build3_loc (input_location, COND_EXPR, void_type_node,
5332 gfc_likely (cont_var,
5333 PRED_FORTRAN_CONTIGUOUS),
5334 if_stmt, else_stmt);
5336 else
5338 /* pointer = pramse->expr; . */
5339 gfc_add_modify (&parmse->pre, pointer, parmse->expr);
5340 pre_stmts = gfc_finish_block (&parmse->pre);
5343 if (pass_optional)
5345 present_var = gfc_create_var (boolean_type_node, "present");
5347 /* present_var = present(sym); . */
5348 tmp = gfc_conv_expr_present (sym);
5349 tmp = fold_convert (boolean_type_node, tmp);
5350 gfc_add_modify (&se->pre, present_var, tmp);
5352 /* else_stmt = { pointer = NULL; } . */
5353 gfc_init_block (&else_block);
5354 if (GFC_DESCRIPTOR_TYPE_P (type))
5355 gfc_conv_descriptor_data_set (&else_block, pointer,
5356 null_pointer_node);
5357 else
5358 gfc_add_modify (&else_block, pointer, build_int_cst (type, 0));
5359 else_stmt = gfc_finish_block (&else_block);
5361 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
5362 gfc_likely (present_var,
5363 PRED_FORTRAN_ABSENT_DUMMY),
5364 pre_stmts, else_stmt);
5365 gfc_add_expr_to_block (&se->pre, tmp);
5367 else
5368 gfc_add_expr_to_block (&se->pre, pre_stmts);
5370 post_stmts = gfc_finish_block (&parmse->post);
5372 /* Put together the post stuff, plus the optional
5373 deallocation. */
5374 if (check_contiguous)
5376 /* !cont_var. */
5377 tmp = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
5378 cont_var,
5379 build_zero_cst (boolean_type_node));
5380 tmp = gfc_unlikely (tmp, PRED_FORTRAN_CONTIGUOUS);
5382 if (pass_optional)
5384 tree present_likely = gfc_likely (present_var,
5385 PRED_FORTRAN_ABSENT_DUMMY);
5386 post_cond = fold_build2_loc (input_location, TRUTH_ANDIF_EXPR,
5387 boolean_type_node, present_likely,
5388 tmp);
5390 else
5391 post_cond = tmp;
5393 else
5395 gcc_assert (pass_optional);
5396 post_cond = present_var;
5399 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, post_cond,
5400 post_stmts, build_empty_stmt (input_location));
5401 gfc_add_expr_to_block (&se->post, tmp);
5402 if (GFC_DESCRIPTOR_TYPE_P (type))
5404 type = TREE_TYPE (parmse->expr);
5405 if (POINTER_TYPE_P (type))
5407 pointer = gfc_build_addr_expr (type, pointer);
5408 if (pass_optional)
5410 tmp = gfc_likely (present_var, PRED_FORTRAN_ABSENT_DUMMY);
5411 pointer = fold_build3_loc (input_location, COND_EXPR, type,
5412 tmp, pointer,
5413 fold_convert (type,
5414 null_pointer_node));
5417 else
5418 gcc_assert (!pass_optional);
5420 se->expr = pointer;
5423 return;
5427 /* Generate the code for argument list functions. */
5429 static void
5430 conv_arglist_function (gfc_se *se, gfc_expr *expr, const char *name)
5432 /* Pass by value for g77 %VAL(arg), pass the address
5433 indirectly for %LOC, else by reference. Thus %REF
5434 is a "do-nothing" and %LOC is the same as an F95
5435 pointer. */
5436 if (strcmp (name, "%VAL") == 0)
5437 gfc_conv_expr (se, expr);
5438 else if (strcmp (name, "%LOC") == 0)
5440 gfc_conv_expr_reference (se, expr);
5441 se->expr = gfc_build_addr_expr (NULL, se->expr);
5443 else if (strcmp (name, "%REF") == 0)
5444 gfc_conv_expr_reference (se, expr);
5445 else
5446 gfc_error ("Unknown argument list function at %L", &expr->where);
5450 /* This function tells whether the middle-end representation of the expression
5451 E given as input may point to data otherwise accessible through a variable
5452 (sub-)reference.
5453 It is assumed that the only expressions that may alias are variables,
5454 and array constructors if ARRAY_MAY_ALIAS is true and some of its elements
5455 may alias.
5456 This function is used to decide whether freeing an expression's allocatable
5457 components is safe or should be avoided.
5459 If ARRAY_MAY_ALIAS is true, an array constructor may alias if some of
5460 its elements are copied from a variable. This ARRAY_MAY_ALIAS trick
5461 is necessary because for array constructors, aliasing depends on how
5462 the array is used:
5463 - If E is an array constructor used as argument to an elemental procedure,
5464 the array, which is generated through shallow copy by the scalarizer,
5465 is used directly and can alias the expressions it was copied from.
5466 - If E is an array constructor used as argument to a non-elemental
5467 procedure,the scalarizer is used in gfc_conv_expr_descriptor to generate
5468 the array as in the previous case, but then that array is used
5469 to initialize a new descriptor through deep copy. There is no alias
5470 possible in that case.
5471 Thus, the ARRAY_MAY_ALIAS flag is necessary to distinguish the two cases
5472 above. */
5474 static bool
5475 expr_may_alias_variables (gfc_expr *e, bool array_may_alias)
5477 gfc_constructor *c;
5479 if (e->expr_type == EXPR_VARIABLE)
5480 return true;
5481 else if (e->expr_type == EXPR_FUNCTION)
5483 gfc_symbol *proc_ifc = gfc_get_proc_ifc_for_expr (e);
5485 if (proc_ifc->result != NULL
5486 && ((proc_ifc->result->ts.type == BT_CLASS
5487 && proc_ifc->result->ts.u.derived->attr.is_class
5488 && CLASS_DATA (proc_ifc->result)->attr.class_pointer)
5489 || proc_ifc->result->attr.pointer))
5490 return true;
5491 else
5492 return false;
5494 else if (e->expr_type != EXPR_ARRAY || !array_may_alias)
5495 return false;
5497 for (c = gfc_constructor_first (e->value.constructor);
5498 c; c = gfc_constructor_next (c))
5499 if (c->expr
5500 && expr_may_alias_variables (c->expr, array_may_alias))
5501 return true;
5503 return false;
5507 /* A helper function to set the dtype for unallocated or unassociated
5508 entities. */
5510 static void
5511 set_dtype_for_unallocated (gfc_se *parmse, gfc_expr *e)
5513 tree tmp;
5514 tree desc;
5515 tree cond;
5516 tree type;
5517 stmtblock_t block;
5519 /* TODO Figure out how to handle optional dummies. */
5520 if (e && e->expr_type == EXPR_VARIABLE
5521 && e->symtree->n.sym->attr.optional)
5522 return;
5524 desc = parmse->expr;
5525 if (desc == NULL_TREE)
5526 return;
5528 if (POINTER_TYPE_P (TREE_TYPE (desc)))
5529 desc = build_fold_indirect_ref_loc (input_location, desc);
5530 if (GFC_CLASS_TYPE_P (TREE_TYPE (desc)))
5531 desc = gfc_class_data_get (desc);
5532 if (!GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (desc)))
5533 return;
5535 gfc_init_block (&block);
5536 tmp = gfc_conv_descriptor_data_get (desc);
5537 cond = fold_build2_loc (input_location, EQ_EXPR,
5538 logical_type_node, tmp,
5539 build_int_cst (TREE_TYPE (tmp), 0));
5540 tmp = gfc_conv_descriptor_dtype (desc);
5541 type = gfc_get_element_type (TREE_TYPE (desc));
5542 tmp = fold_build2_loc (input_location, MODIFY_EXPR,
5543 TREE_TYPE (tmp), tmp,
5544 gfc_get_dtype_rank_type (e->rank, type));
5545 gfc_add_expr_to_block (&block, tmp);
5546 cond = build3_v (COND_EXPR, cond,
5547 gfc_finish_block (&block),
5548 build_empty_stmt (input_location));
5549 gfc_add_expr_to_block (&parmse->pre, cond);
5554 /* Provide an interface between gfortran array descriptors and the F2018:18.4
5555 ISO_Fortran_binding array descriptors. */
5557 static void
5558 gfc_conv_gfc_desc_to_cfi_desc (gfc_se *parmse, gfc_expr *e, gfc_symbol *fsym)
5560 stmtblock_t block, block2;
5561 tree cfi, gfc, tmp, tmp2;
5562 tree present = NULL;
5563 tree gfc_strlen = NULL;
5564 tree rank;
5565 gfc_se se;
5567 if (fsym->attr.optional
5568 && e->expr_type == EXPR_VARIABLE
5569 && e->symtree->n.sym->attr.optional)
5570 present = gfc_conv_expr_present (e->symtree->n.sym);
5572 gfc_init_block (&block);
5574 /* Convert original argument to a tree. */
5575 gfc_init_se (&se, NULL);
5576 if (e->rank == 0)
5578 se.want_pointer = 1;
5579 gfc_conv_expr (&se, e);
5580 gfc = se.expr;
5581 /* gfc_conv_constant ignores se.want_poiner, e.g. for string_cst. */
5582 if (!POINTER_TYPE_P (TREE_TYPE (gfc)))
5583 gfc = gfc_build_addr_expr (NULL, gfc);
5585 else
5587 /* If the actual argument can be noncontiguous, copy-in/out is required,
5588 if the dummy has either the CONTIGUOUS attribute or is an assumed-
5589 length assumed-length/assumed-size CHARACTER array. This only
5590 applies if the actual argument is a "variable"; if it's some
5591 non-lvalue expression, we are going to evaluate it to a
5592 temporary below anyway. */
5593 se.force_no_tmp = 1;
5594 if ((fsym->attr.contiguous
5595 || (fsym->ts.type == BT_CHARACTER && !fsym->ts.u.cl->length
5596 && (fsym->as->type == AS_ASSUMED_SIZE
5597 || fsym->as->type == AS_EXPLICIT)))
5598 && !gfc_is_simply_contiguous (e, false, true)
5599 && gfc_expr_is_variable (e))
5601 bool optional = fsym->attr.optional;
5602 fsym->attr.optional = 0;
5603 gfc_conv_subref_array_arg (&se, e, false, fsym->attr.intent,
5604 fsym->attr.pointer, fsym,
5605 fsym->ns->proc_name->name, NULL,
5606 /* check_contiguous= */ true);
5607 fsym->attr.optional = optional;
5609 else
5610 gfc_conv_expr_descriptor (&se, e);
5611 gfc = se.expr;
5612 /* For dt(:)%var the elem_len*stride != sm, hence, GFC uses
5613 elem_len = sizeof(dt) and base_addr = dt(lb) instead.
5614 gfc_get_dataptr_offset fixes the base_addr; for elem_len, see below.
5615 While sm is fine as it uses span*stride and not elem_len. */
5616 if (POINTER_TYPE_P (TREE_TYPE (gfc)))
5617 gfc = build_fold_indirect_ref_loc (input_location, gfc);
5618 else if (is_subref_array (e) && e->ts.type != BT_CHARACTER)
5619 gfc_get_dataptr_offset (&se.pre, gfc, gfc, NULL, true, e);
5621 if (e->ts.type == BT_CHARACTER)
5623 if (se.string_length)
5624 gfc_strlen = se.string_length;
5625 else if (e->ts.u.cl->backend_decl)
5626 gfc_strlen = e->ts.u.cl->backend_decl;
5627 else
5628 gcc_unreachable ();
5630 gfc_add_block_to_block (&block, &se.pre);
5632 /* Create array descriptor and set version, rank, attribute, type. */
5633 cfi = gfc_create_var (gfc_get_cfi_type (e->rank < 0
5634 ? GFC_MAX_DIMENSIONS : e->rank,
5635 false), "cfi");
5636 /* Convert to CFI_cdesc_t, which has dim[] to avoid TBAA issues,*/
5637 if (fsym->attr.dimension && fsym->as->type == AS_ASSUMED_RANK)
5639 tmp = gfc_get_cfi_type (-1, !fsym->attr.pointer && !fsym->attr.target);
5640 tmp = build_pointer_type (tmp);
5641 parmse->expr = cfi = gfc_build_addr_expr (tmp, cfi);
5642 cfi = build_fold_indirect_ref_loc (input_location, cfi);
5644 else
5645 parmse->expr = gfc_build_addr_expr (NULL, cfi);
5647 tmp = gfc_get_cfi_desc_version (cfi);
5648 gfc_add_modify (&block, tmp,
5649 build_int_cst (TREE_TYPE (tmp), CFI_VERSION));
5650 if (e->rank < 0)
5651 rank = fold_convert (signed_char_type_node, gfc_conv_descriptor_rank (gfc));
5652 else
5653 rank = build_int_cst (signed_char_type_node, e->rank);
5654 tmp = gfc_get_cfi_desc_rank (cfi);
5655 gfc_add_modify (&block, tmp, rank);
5656 int itype = CFI_type_other;
5657 if (e->ts.f90_type == BT_VOID)
5658 itype = (e->ts.u.derived->intmod_sym_id == ISOCBINDING_FUNPTR
5659 ? CFI_type_cfunptr : CFI_type_cptr);
5660 else
5662 if (e->expr_type == EXPR_NULL && e->ts.type == BT_UNKNOWN)
5663 e->ts = fsym->ts;
5664 switch (e->ts.type)
5666 case BT_INTEGER:
5667 case BT_LOGICAL:
5668 case BT_REAL:
5669 case BT_COMPLEX:
5670 itype = CFI_type_from_type_kind (e->ts.type, e->ts.kind);
5671 break;
5672 case BT_CHARACTER:
5673 itype = CFI_type_from_type_kind (CFI_type_Character, e->ts.kind);
5674 break;
5675 case BT_DERIVED:
5676 itype = CFI_type_struct;
5677 break;
5678 case BT_VOID:
5679 itype = (e->ts.u.derived->intmod_sym_id == ISOCBINDING_FUNPTR
5680 ? CFI_type_cfunptr : CFI_type_cptr);
5681 break;
5682 case BT_ASSUMED:
5683 itype = CFI_type_other; // FIXME: Or CFI_type_cptr ?
5684 break;
5685 case BT_CLASS:
5686 if (fsym->ts.type == BT_ASSUMED)
5688 // F2017: 7.3.2.2: "An entity that is declared using the TYPE(*)
5689 // type specifier is assumed-type and is an unlimited polymorphic
5690 // entity." The actual argument _data component is passed.
5691 itype = CFI_type_other; // FIXME: Or CFI_type_cptr ?
5692 break;
5694 else
5695 gcc_unreachable ();
5696 case BT_PROCEDURE:
5697 case BT_HOLLERITH:
5698 case BT_UNION:
5699 case BT_BOZ:
5700 case BT_UNKNOWN:
5701 // FIXME: Really unreachable? Or reachable for type(*) ? If so, CFI_type_other?
5702 gcc_unreachable ();
5706 tmp = gfc_get_cfi_desc_type (cfi);
5707 gfc_add_modify (&block, tmp,
5708 build_int_cst (TREE_TYPE (tmp), itype));
5710 int attr = CFI_attribute_other;
5711 if (fsym->attr.pointer)
5712 attr = CFI_attribute_pointer;
5713 else if (fsym->attr.allocatable)
5714 attr = CFI_attribute_allocatable;
5715 tmp = gfc_get_cfi_desc_attribute (cfi);
5716 gfc_add_modify (&block, tmp,
5717 build_int_cst (TREE_TYPE (tmp), attr));
5719 /* The cfi-base_addr assignment could be skipped for 'pointer, intent(out)'.
5720 That is very sensible for undefined pointers, but the C code might assume
5721 that the pointer retains the value, in particular, if it was NULL. */
5722 if (e->rank == 0)
5724 tmp = gfc_get_cfi_desc_base_addr (cfi);
5725 gfc_add_modify (&block, tmp, fold_convert (TREE_TYPE (tmp), gfc));
5727 else
5729 tmp = gfc_get_cfi_desc_base_addr (cfi);
5730 tmp2 = gfc_conv_descriptor_data_get (gfc);
5731 gfc_add_modify (&block, tmp, fold_convert (TREE_TYPE (tmp), tmp2));
5734 /* Set elem_len if known - must be before the next if block.
5735 Note that allocatable implies 'len=:'. */
5736 if (e->ts.type != BT_ASSUMED && e->ts.type != BT_CHARACTER )
5738 /* Length is known at compile time; use 'block' for it. */
5739 tmp = size_in_bytes (gfc_typenode_for_spec (&e->ts));
5740 tmp2 = gfc_get_cfi_desc_elem_len (cfi);
5741 gfc_add_modify (&block, tmp2, fold_convert (TREE_TYPE (tmp2), tmp));
5744 if (fsym->attr.pointer && fsym->attr.intent == INTENT_OUT)
5745 goto done;
5747 /* When allocatable + intent out, free the cfi descriptor. */
5748 if (fsym->attr.allocatable && fsym->attr.intent == INTENT_OUT)
5750 tmp = gfc_get_cfi_desc_base_addr (cfi);
5751 tree call = builtin_decl_explicit (BUILT_IN_FREE);
5752 call = build_call_expr_loc (input_location, call, 1, tmp);
5753 gfc_add_expr_to_block (&block, fold_convert (void_type_node, call));
5754 gfc_add_modify (&block, tmp,
5755 fold_convert (TREE_TYPE (tmp), null_pointer_node));
5756 goto done;
5759 /* If not unallocated/unassociated. */
5760 gfc_init_block (&block2);
5762 /* Set elem_len, which may be only known at run time. */
5763 if (e->ts.type == BT_CHARACTER
5764 && (e->expr_type != EXPR_NULL || gfc_strlen != NULL_TREE))
5766 gcc_assert (gfc_strlen);
5767 tmp = gfc_strlen;
5768 if (e->ts.kind != 1)
5769 tmp = fold_build2_loc (input_location, MULT_EXPR,
5770 gfc_charlen_type_node, tmp,
5771 build_int_cst (gfc_charlen_type_node,
5772 e->ts.kind));
5773 tmp2 = gfc_get_cfi_desc_elem_len (cfi);
5774 gfc_add_modify (&block2, tmp2, fold_convert (TREE_TYPE (tmp2), tmp));
5776 else if (e->ts.type == BT_ASSUMED)
5778 tmp = gfc_conv_descriptor_elem_len (gfc);
5779 tmp2 = gfc_get_cfi_desc_elem_len (cfi);
5780 gfc_add_modify (&block2, tmp2, fold_convert (TREE_TYPE (tmp2), tmp));
5783 if (e->ts.type == BT_ASSUMED)
5785 /* Note: type(*) implies assumed-shape/assumed-rank if fsym requires
5786 an CFI descriptor. Use the type in the descriptor as it provide
5787 mode information. (Quality of implementation feature.) */
5788 tree cond;
5789 tree ctype = gfc_get_cfi_desc_type (cfi);
5790 tree type = fold_convert (TREE_TYPE (ctype),
5791 gfc_conv_descriptor_type (gfc));
5792 tree kind = fold_convert (TREE_TYPE (ctype),
5793 gfc_conv_descriptor_elem_len (gfc));
5794 kind = fold_build2_loc (input_location, LSHIFT_EXPR, TREE_TYPE (type),
5795 kind, build_int_cst (TREE_TYPE (type),
5796 CFI_type_kind_shift));
5798 /* if (BT_VOID) CFI_type_cptr else CFI_type_other */
5799 /* Note: BT_VOID is could also be CFI_type_funcptr, but assume c_ptr. */
5800 cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, type,
5801 build_int_cst (TREE_TYPE (type), BT_VOID));
5802 tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node, ctype,
5803 build_int_cst (TREE_TYPE (type), CFI_type_cptr));
5804 tmp2 = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node,
5805 ctype,
5806 build_int_cst (TREE_TYPE (type), CFI_type_other));
5807 tmp2 = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond,
5808 tmp, tmp2);
5809 /* if (BT_DERIVED) CFI_type_struct else < tmp2 > */
5810 cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, type,
5811 build_int_cst (TREE_TYPE (type), BT_DERIVED));
5812 tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node, ctype,
5813 build_int_cst (TREE_TYPE (type), CFI_type_struct));
5814 tmp2 = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond,
5815 tmp, tmp2);
5816 /* if (BT_CHARACTER) CFI_type_Character + kind=1 else < tmp2 > */
5817 /* Note: could also be kind=4, with cfi->elem_len = gfc->elem_len*4. */
5818 cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, type,
5819 build_int_cst (TREE_TYPE (type), BT_CHARACTER));
5820 tmp = build_int_cst (TREE_TYPE (type),
5821 CFI_type_from_type_kind (CFI_type_Character, 1));
5822 tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node,
5823 ctype, tmp);
5824 tmp2 = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond,
5825 tmp, tmp2);
5826 /* if (BT_COMPLEX) CFI_type_Complex + kind/2 else < tmp2 > */
5827 cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, type,
5828 build_int_cst (TREE_TYPE (type), BT_COMPLEX));
5829 tmp = fold_build2_loc (input_location, TRUNC_DIV_EXPR, TREE_TYPE (type),
5830 kind, build_int_cst (TREE_TYPE (type), 2));
5831 tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (type), tmp,
5832 build_int_cst (TREE_TYPE (type),
5833 CFI_type_Complex));
5834 tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node,
5835 ctype, tmp);
5836 tmp2 = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond,
5837 tmp, tmp2);
5838 /* if (BT_INTEGER || BT_LOGICAL || BT_REAL) type + kind else <tmp2> */
5839 cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, type,
5840 build_int_cst (TREE_TYPE (type), BT_INTEGER));
5841 tmp = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, type,
5842 build_int_cst (TREE_TYPE (type), BT_LOGICAL));
5843 cond = fold_build2_loc (input_location, TRUTH_OR_EXPR, boolean_type_node,
5844 cond, tmp);
5845 tmp = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, type,
5846 build_int_cst (TREE_TYPE (type), BT_REAL));
5847 cond = fold_build2_loc (input_location, TRUTH_OR_EXPR, boolean_type_node,
5848 cond, tmp);
5849 tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (type),
5850 type, kind);
5851 tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node,
5852 ctype, tmp);
5853 tmp2 = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond,
5854 tmp, tmp2);
5855 gfc_add_expr_to_block (&block2, tmp2);
5858 if (e->rank != 0)
5860 /* Loop: for (i = 0; i < rank; ++i). */
5861 tree idx = gfc_create_var (TREE_TYPE (rank), "idx");
5862 /* Loop body. */
5863 stmtblock_t loop_body;
5864 gfc_init_block (&loop_body);
5865 /* cfi->dim[i].lower_bound = (allocatable/pointer)
5866 ? gfc->dim[i].lbound : 0 */
5867 if (fsym->attr.pointer || fsym->attr.allocatable)
5868 tmp = gfc_conv_descriptor_lbound_get (gfc, idx);
5869 else
5870 tmp = gfc_index_zero_node;
5871 gfc_add_modify (&loop_body, gfc_get_cfi_dim_lbound (cfi, idx), tmp);
5872 /* cfi->dim[i].extent = gfc->dim[i].ubound - gfc->dim[i].lbound + 1. */
5873 tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
5874 gfc_conv_descriptor_ubound_get (gfc, idx),
5875 gfc_conv_descriptor_lbound_get (gfc, idx));
5876 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
5877 tmp, gfc_index_one_node);
5878 gfc_add_modify (&loop_body, gfc_get_cfi_dim_extent (cfi, idx), tmp);
5879 /* d->dim[n].sm = gfc->dim[i].stride * gfc->span); */
5880 tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
5881 gfc_conv_descriptor_stride_get (gfc, idx),
5882 gfc_conv_descriptor_span_get (gfc));
5883 gfc_add_modify (&loop_body, gfc_get_cfi_dim_sm (cfi, idx), tmp);
5885 /* Generate loop. */
5886 gfc_simple_for_loop (&block2, idx, build_int_cst (TREE_TYPE (idx), 0),
5887 rank, LT_EXPR, build_int_cst (TREE_TYPE (idx), 1),
5888 gfc_finish_block (&loop_body));
5890 if (e->expr_type == EXPR_VARIABLE
5891 && e->ref
5892 && e->ref->u.ar.type == AR_FULL
5893 && e->symtree->n.sym->attr.dummy
5894 && e->symtree->n.sym->as
5895 && e->symtree->n.sym->as->type == AS_ASSUMED_SIZE)
5897 tmp = gfc_get_cfi_dim_extent (cfi, gfc_rank_cst[e->rank-1]),
5898 gfc_add_modify (&block2, tmp, build_int_cst (TREE_TYPE (tmp), -1));
5902 if (fsym->attr.allocatable || fsym->attr.pointer)
5904 tmp = gfc_get_cfi_desc_base_addr (cfi),
5905 tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
5906 tmp, null_pointer_node);
5907 tmp = build3_v (COND_EXPR, tmp, gfc_finish_block (&block2),
5908 build_empty_stmt (input_location));
5909 gfc_add_expr_to_block (&block, tmp);
5911 else
5912 gfc_add_block_to_block (&block, &block2);
5915 done:
5916 if (present)
5918 parmse->expr = build3_loc (input_location, COND_EXPR,
5919 TREE_TYPE (parmse->expr),
5920 present, parmse->expr, null_pointer_node);
5921 tmp = build3_v (COND_EXPR, present, gfc_finish_block (&block),
5922 build_empty_stmt (input_location));
5923 gfc_add_expr_to_block (&parmse->pre, tmp);
5925 else
5926 gfc_add_block_to_block (&parmse->pre, &block);
5928 gfc_init_block (&block);
5930 if ((!fsym->attr.allocatable && !fsym->attr.pointer)
5931 || fsym->attr.intent == INTENT_IN)
5932 goto post_call;
5934 gfc_init_block (&block2);
5935 if (e->rank == 0)
5937 tmp = gfc_get_cfi_desc_base_addr (cfi);
5938 gfc_add_modify (&block, gfc, fold_convert (TREE_TYPE (gfc), tmp));
5940 else
5942 tmp = gfc_get_cfi_desc_base_addr (cfi);
5943 gfc_conv_descriptor_data_set (&block, gfc, tmp);
5945 if (fsym->attr.allocatable)
5947 /* gfc->span = cfi->elem_len. */
5948 tmp = fold_convert (gfc_array_index_type,
5949 gfc_get_cfi_dim_sm (cfi, gfc_rank_cst[0]));
5951 else
5953 /* gfc->span = ((cfi->dim[0].sm % cfi->elem_len)
5954 ? cfi->dim[0].sm : cfi->elem_len). */
5955 tmp = gfc_get_cfi_dim_sm (cfi, gfc_rank_cst[0]);
5956 tmp2 = fold_convert (gfc_array_index_type,
5957 gfc_get_cfi_desc_elem_len (cfi));
5958 tmp = fold_build2_loc (input_location, TRUNC_MOD_EXPR,
5959 gfc_array_index_type, tmp, tmp2);
5960 tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
5961 tmp, gfc_index_zero_node);
5962 tmp = build3_loc (input_location, COND_EXPR, gfc_array_index_type, tmp,
5963 gfc_get_cfi_dim_sm (cfi, gfc_rank_cst[0]), tmp2);
5965 gfc_conv_descriptor_span_set (&block2, gfc, tmp);
5967 /* Calculate offset + set lbound, ubound and stride. */
5968 gfc_conv_descriptor_offset_set (&block2, gfc, gfc_index_zero_node);
5969 /* Loop: for (i = 0; i < rank; ++i). */
5970 tree idx = gfc_create_var (TREE_TYPE (rank), "idx");
5971 /* Loop body. */
5972 stmtblock_t loop_body;
5973 gfc_init_block (&loop_body);
5974 /* gfc->dim[i].lbound = ... */
5975 tmp = gfc_get_cfi_dim_lbound (cfi, idx);
5976 gfc_conv_descriptor_lbound_set (&loop_body, gfc, idx, tmp);
5978 /* gfc->dim[i].ubound = gfc->dim[i].lbound + cfi->dim[i].extent - 1. */
5979 tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
5980 gfc_conv_descriptor_lbound_get (gfc, idx),
5981 gfc_index_one_node);
5982 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
5983 gfc_get_cfi_dim_extent (cfi, idx), tmp);
5984 gfc_conv_descriptor_ubound_set (&loop_body, gfc, idx, tmp);
5986 /* gfc->dim[i].stride = cfi->dim[i].sm / cfi>elem_len */
5987 tmp = gfc_get_cfi_dim_sm (cfi, idx);
5988 tmp = fold_build2_loc (input_location, TRUNC_DIV_EXPR,
5989 gfc_array_index_type, tmp,
5990 fold_convert (gfc_array_index_type,
5991 gfc_get_cfi_desc_elem_len (cfi)));
5992 gfc_conv_descriptor_stride_set (&loop_body, gfc, idx, tmp);
5994 /* gfc->offset -= gfc->dim[i].stride * gfc->dim[i].lbound. */
5995 tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
5996 gfc_conv_descriptor_stride_get (gfc, idx),
5997 gfc_conv_descriptor_lbound_get (gfc, idx));
5998 tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
5999 gfc_conv_descriptor_offset_get (gfc), tmp);
6000 gfc_conv_descriptor_offset_set (&loop_body, gfc, tmp);
6001 /* Generate loop. */
6002 gfc_simple_for_loop (&block2, idx, build_int_cst (TREE_TYPE (idx), 0),
6003 rank, LT_EXPR, build_int_cst (TREE_TYPE (idx), 1),
6004 gfc_finish_block (&loop_body));
6007 if (e->ts.type == BT_CHARACTER && !e->ts.u.cl->length)
6009 tmp = fold_convert (gfc_charlen_type_node,
6010 gfc_get_cfi_desc_elem_len (cfi));
6011 if (e->ts.kind != 1)
6012 tmp = fold_build2_loc (input_location, TRUNC_DIV_EXPR,
6013 gfc_charlen_type_node, tmp,
6014 build_int_cst (gfc_charlen_type_node,
6015 e->ts.kind));
6016 gfc_add_modify (&block2, gfc_strlen, tmp);
6019 tmp = gfc_get_cfi_desc_base_addr (cfi),
6020 tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
6021 tmp, null_pointer_node);
6022 tmp = build3_v (COND_EXPR, tmp, gfc_finish_block (&block2),
6023 build_empty_stmt (input_location));
6024 gfc_add_expr_to_block (&block, tmp);
6026 post_call:
6027 gfc_add_block_to_block (&block, &se.post);
6028 if (present && block.head)
6030 tmp = build3_v (COND_EXPR, present, gfc_finish_block (&block),
6031 build_empty_stmt (input_location));
6032 gfc_add_expr_to_block (&parmse->post, tmp);
6034 else if (block.head)
6035 gfc_add_block_to_block (&parmse->post, &block);
6039 /* Generate code for a procedure call. Note can return se->post != NULL.
6040 If se->direct_byref is set then se->expr contains the return parameter.
6041 Return nonzero, if the call has alternate specifiers.
6042 'expr' is only needed for procedure pointer components. */
6045 gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
6046 gfc_actual_arglist * args, gfc_expr * expr,
6047 vec<tree, va_gc> *append_args)
6049 gfc_interface_mapping mapping;
6050 vec<tree, va_gc> *arglist;
6051 vec<tree, va_gc> *retargs;
6052 tree tmp;
6053 tree fntype;
6054 gfc_se parmse;
6055 gfc_array_info *info;
6056 int byref;
6057 int parm_kind;
6058 tree type;
6059 tree var;
6060 tree len;
6061 tree base_object;
6062 vec<tree, va_gc> *stringargs;
6063 vec<tree, va_gc> *optionalargs;
6064 tree result = NULL;
6065 gfc_formal_arglist *formal;
6066 gfc_actual_arglist *arg;
6067 int has_alternate_specifier = 0;
6068 bool need_interface_mapping;
6069 bool callee_alloc;
6070 bool ulim_copy;
6071 gfc_typespec ts;
6072 gfc_charlen cl;
6073 gfc_expr *e;
6074 gfc_symbol *fsym;
6075 enum {MISSING = 0, ELEMENTAL, SCALAR, SCALAR_POINTER, ARRAY};
6076 gfc_component *comp = NULL;
6077 int arglen;
6078 unsigned int argc;
6080 arglist = NULL;
6081 retargs = NULL;
6082 stringargs = NULL;
6083 optionalargs = NULL;
6084 var = NULL_TREE;
6085 len = NULL_TREE;
6086 gfc_clear_ts (&ts);
6088 comp = gfc_get_proc_ptr_comp (expr);
6090 bool elemental_proc = (comp
6091 && comp->ts.interface
6092 && comp->ts.interface->attr.elemental)
6093 || (comp && comp->attr.elemental)
6094 || sym->attr.elemental;
6096 if (se->ss != NULL)
6098 if (!elemental_proc)
6100 gcc_assert (se->ss->info->type == GFC_SS_FUNCTION);
6101 if (se->ss->info->useflags)
6103 gcc_assert ((!comp && gfc_return_by_reference (sym)
6104 && sym->result->attr.dimension)
6105 || (comp && comp->attr.dimension)
6106 || gfc_is_class_array_function (expr));
6107 gcc_assert (se->loop != NULL);
6108 /* Access the previously obtained result. */
6109 gfc_conv_tmp_array_ref (se);
6110 return 0;
6113 info = &se->ss->info->data.array;
6115 else
6116 info = NULL;
6118 stmtblock_t post, clobbers, dealloc_blk;
6119 gfc_init_block (&post);
6120 gfc_init_block (&clobbers);
6121 gfc_init_block (&dealloc_blk);
6122 gfc_init_interface_mapping (&mapping);
6123 if (!comp)
6125 formal = gfc_sym_get_dummy_args (sym);
6126 need_interface_mapping = sym->attr.dimension ||
6127 (sym->ts.type == BT_CHARACTER
6128 && sym->ts.u.cl->length
6129 && sym->ts.u.cl->length->expr_type
6130 != EXPR_CONSTANT);
6132 else
6134 formal = comp->ts.interface ? comp->ts.interface->formal : NULL;
6135 need_interface_mapping = comp->attr.dimension ||
6136 (comp->ts.type == BT_CHARACTER
6137 && comp->ts.u.cl->length
6138 && comp->ts.u.cl->length->expr_type
6139 != EXPR_CONSTANT);
6142 base_object = NULL_TREE;
6143 /* For _vprt->_copy () routines no formal symbol is present. Nevertheless
6144 is the third and fourth argument to such a function call a value
6145 denoting the number of elements to copy (i.e., most of the time the
6146 length of a deferred length string). */
6147 ulim_copy = (formal == NULL)
6148 && UNLIMITED_POLY (sym)
6149 && comp && (strcmp ("_copy", comp->name) == 0);
6151 /* Scan for allocatable actual arguments passed to allocatable dummy
6152 arguments with INTENT(OUT). As the corresponding actual arguments are
6153 deallocated before execution of the procedure, we evaluate actual
6154 argument expressions to avoid problems with possible dependencies. */
6155 bool force_eval_args = false;
6156 gfc_formal_arglist *tmp_formal;
6157 for (arg = args, tmp_formal = formal; arg != NULL;
6158 arg = arg->next, tmp_formal = tmp_formal ? tmp_formal->next : NULL)
6160 e = arg->expr;
6161 fsym = tmp_formal ? tmp_formal->sym : NULL;
6162 if (e && fsym
6163 && e->expr_type == EXPR_VARIABLE
6164 && fsym->attr.intent == INTENT_OUT
6165 && (fsym->ts.type == BT_CLASS && fsym->attr.class_ok
6166 ? CLASS_DATA (fsym)->attr.allocatable
6167 : fsym->attr.allocatable)
6168 && e->symtree
6169 && e->symtree->n.sym
6170 && gfc_variable_attr (e, NULL).allocatable)
6172 force_eval_args = true;
6173 break;
6177 /* Evaluate the arguments. */
6178 for (arg = args, argc = 0; arg != NULL;
6179 arg = arg->next, formal = formal ? formal->next : NULL, ++argc)
6181 bool finalized = false;
6182 tree derived_array = NULL_TREE;
6184 e = arg->expr;
6185 fsym = formal ? formal->sym : NULL;
6186 parm_kind = MISSING;
6188 /* If the procedure requires an explicit interface, the actual
6189 argument is passed according to the corresponding formal
6190 argument. If the corresponding formal argument is a POINTER,
6191 ALLOCATABLE or assumed shape, we do not use g77's calling
6192 convention, and pass the address of the array descriptor
6193 instead. Otherwise we use g77's calling convention, in other words
6194 pass the array data pointer without descriptor. */
6195 bool nodesc_arg = fsym != NULL
6196 && !(fsym->attr.pointer || fsym->attr.allocatable)
6197 && fsym->as
6198 && fsym->as->type != AS_ASSUMED_SHAPE
6199 && fsym->as->type != AS_ASSUMED_RANK;
6200 if (comp)
6201 nodesc_arg = nodesc_arg || !comp->attr.always_explicit;
6202 else
6203 nodesc_arg = nodesc_arg || !sym->attr.always_explicit;
6205 /* Class array expressions are sometimes coming completely unadorned
6206 with either arrayspec or _data component. Correct that here.
6207 OOP-TODO: Move this to the frontend. */
6208 if (e && e->expr_type == EXPR_VARIABLE
6209 && !e->ref
6210 && e->ts.type == BT_CLASS
6211 && (CLASS_DATA (e)->attr.codimension
6212 || CLASS_DATA (e)->attr.dimension))
6214 gfc_typespec temp_ts = e->ts;
6215 gfc_add_class_array_ref (e);
6216 e->ts = temp_ts;
6219 if (e == NULL)
6221 if (se->ignore_optional)
6223 /* Some intrinsics have already been resolved to the correct
6224 parameters. */
6225 continue;
6227 else if (arg->label)
6229 has_alternate_specifier = 1;
6230 continue;
6232 else
6234 gfc_init_se (&parmse, NULL);
6236 /* For scalar arguments with VALUE attribute which are passed by
6237 value, pass "0" and a hidden argument gives the optional
6238 status. */
6239 if (fsym && fsym->attr.optional && fsym->attr.value
6240 && !fsym->attr.dimension && fsym->ts.type != BT_CLASS
6241 && !gfc_bt_struct (sym->ts.type))
6243 if (fsym->ts.type == BT_CHARACTER)
6245 /* Pass a NULL pointer for an absent CHARACTER arg
6246 and a length of zero. */
6247 parmse.expr = null_pointer_node;
6248 parmse.string_length
6249 = build_int_cst (gfc_charlen_type_node,
6252 else
6253 parmse.expr = fold_convert (gfc_sym_type (fsym),
6254 integer_zero_node);
6255 vec_safe_push (optionalargs, boolean_false_node);
6257 else
6259 /* Pass a NULL pointer for an absent arg. */
6260 parmse.expr = null_pointer_node;
6261 gfc_dummy_arg * const dummy_arg = arg->associated_dummy;
6262 if (dummy_arg
6263 && gfc_dummy_arg_get_typespec (*dummy_arg).type
6264 == BT_CHARACTER)
6265 parmse.string_length = build_int_cst (gfc_charlen_type_node,
6270 else if (arg->expr->expr_type == EXPR_NULL
6271 && fsym && !fsym->attr.pointer
6272 && (fsym->ts.type != BT_CLASS
6273 || !CLASS_DATA (fsym)->attr.class_pointer))
6275 /* Pass a NULL pointer to denote an absent arg. */
6276 gcc_assert (fsym->attr.optional && !fsym->attr.allocatable
6277 && (fsym->ts.type != BT_CLASS
6278 || !CLASS_DATA (fsym)->attr.allocatable));
6279 gfc_init_se (&parmse, NULL);
6280 parmse.expr = null_pointer_node;
6281 if (arg->associated_dummy
6282 && gfc_dummy_arg_get_typespec (*arg->associated_dummy).type
6283 == BT_CHARACTER)
6284 parmse.string_length = build_int_cst (gfc_charlen_type_node, 0);
6286 else if (fsym && fsym->ts.type == BT_CLASS
6287 && e->ts.type == BT_DERIVED)
6289 /* The derived type needs to be converted to a temporary
6290 CLASS object. */
6291 gfc_init_se (&parmse, se);
6292 gfc_conv_derived_to_class (&parmse, e, fsym->ts, NULL,
6293 fsym->attr.optional
6294 && e->expr_type == EXPR_VARIABLE
6295 && e->symtree->n.sym->attr.optional,
6296 CLASS_DATA (fsym)->attr.class_pointer
6297 || CLASS_DATA (fsym)->attr.allocatable,
6298 &derived_array);
6300 else if (UNLIMITED_POLY (fsym) && e->ts.type != BT_CLASS
6301 && e->ts.type != BT_PROCEDURE
6302 && (gfc_expr_attr (e).flavor != FL_PROCEDURE
6303 || gfc_expr_attr (e).proc != PROC_UNKNOWN))
6305 /* The intrinsic type needs to be converted to a temporary
6306 CLASS object for the unlimited polymorphic formal. */
6307 gfc_find_vtab (&e->ts);
6308 gfc_init_se (&parmse, se);
6309 gfc_conv_intrinsic_to_class (&parmse, e, fsym->ts);
6312 else if (se->ss && se->ss->info->useflags)
6314 gfc_ss *ss;
6316 ss = se->ss;
6318 /* An elemental function inside a scalarized loop. */
6319 gfc_init_se (&parmse, se);
6320 parm_kind = ELEMENTAL;
6322 /* When no fsym is present, ulim_copy is set and this is a third or
6323 fourth argument, use call-by-value instead of by reference to
6324 hand the length properties to the copy routine (i.e., most of the
6325 time this will be a call to a __copy_character_* routine where the
6326 third and fourth arguments are the lengths of a deferred length
6327 char array). */
6328 if ((fsym && fsym->attr.value)
6329 || (ulim_copy && (argc == 2 || argc == 3)))
6330 gfc_conv_expr (&parmse, e);
6331 else
6332 gfc_conv_expr_reference (&parmse, e);
6334 if (e->ts.type == BT_CHARACTER && !e->rank
6335 && e->expr_type == EXPR_FUNCTION)
6336 parmse.expr = build_fold_indirect_ref_loc (input_location,
6337 parmse.expr);
6339 if (fsym && fsym->ts.type == BT_DERIVED
6340 && gfc_is_class_container_ref (e))
6342 parmse.expr = gfc_class_data_get (parmse.expr);
6344 if (fsym->attr.optional && e->expr_type == EXPR_VARIABLE
6345 && e->symtree->n.sym->attr.optional)
6347 tree cond = gfc_conv_expr_present (e->symtree->n.sym);
6348 parmse.expr = build3_loc (input_location, COND_EXPR,
6349 TREE_TYPE (parmse.expr),
6350 cond, parmse.expr,
6351 fold_convert (TREE_TYPE (parmse.expr),
6352 null_pointer_node));
6356 /* If we are passing an absent array as optional dummy to an
6357 elemental procedure, make sure that we pass NULL when the data
6358 pointer is NULL. We need this extra conditional because of
6359 scalarization which passes arrays elements to the procedure,
6360 ignoring the fact that the array can be absent/unallocated/... */
6361 if (ss->info->can_be_null_ref && ss->info->type != GFC_SS_REFERENCE)
6363 tree descriptor_data;
6365 descriptor_data = ss->info->data.array.data;
6366 tmp = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
6367 descriptor_data,
6368 fold_convert (TREE_TYPE (descriptor_data),
6369 null_pointer_node));
6370 parmse.expr
6371 = fold_build3_loc (input_location, COND_EXPR,
6372 TREE_TYPE (parmse.expr),
6373 gfc_unlikely (tmp, PRED_FORTRAN_ABSENT_DUMMY),
6374 fold_convert (TREE_TYPE (parmse.expr),
6375 null_pointer_node),
6376 parmse.expr);
6379 /* The scalarizer does not repackage the reference to a class
6380 array - instead it returns a pointer to the data element. */
6381 if (fsym && fsym->ts.type == BT_CLASS && e->ts.type == BT_CLASS)
6382 gfc_conv_class_to_class (&parmse, e, fsym->ts, true,
6383 fsym->attr.intent != INTENT_IN
6384 && (CLASS_DATA (fsym)->attr.class_pointer
6385 || CLASS_DATA (fsym)->attr.allocatable),
6386 fsym->attr.optional
6387 && e->expr_type == EXPR_VARIABLE
6388 && e->symtree->n.sym->attr.optional,
6389 CLASS_DATA (fsym)->attr.class_pointer
6390 || CLASS_DATA (fsym)->attr.allocatable);
6392 else
6394 bool scalar;
6395 gfc_ss *argss;
6397 gfc_init_se (&parmse, NULL);
6399 /* Check whether the expression is a scalar or not; we cannot use
6400 e->rank as it can be nonzero for functions arguments. */
6401 argss = gfc_walk_expr (e);
6402 scalar = argss == gfc_ss_terminator;
6403 if (!scalar)
6404 gfc_free_ss_chain (argss);
6406 /* Special handling for passing scalar polymorphic coarrays;
6407 otherwise one passes "class->_data.data" instead of "&class". */
6408 if (e->rank == 0 && e->ts.type == BT_CLASS
6409 && fsym && fsym->ts.type == BT_CLASS
6410 && CLASS_DATA (fsym)->attr.codimension
6411 && !CLASS_DATA (fsym)->attr.dimension)
6413 gfc_add_class_array_ref (e);
6414 parmse.want_coarray = 1;
6415 scalar = false;
6418 /* A scalar or transformational function. */
6419 if (scalar)
6421 if (e->expr_type == EXPR_VARIABLE
6422 && e->symtree->n.sym->attr.cray_pointee
6423 && fsym && fsym->attr.flavor == FL_PROCEDURE)
6425 /* The Cray pointer needs to be converted to a pointer to
6426 a type given by the expression. */
6427 gfc_conv_expr (&parmse, e);
6428 type = build_pointer_type (TREE_TYPE (parmse.expr));
6429 tmp = gfc_get_symbol_decl (e->symtree->n.sym->cp_pointer);
6430 parmse.expr = convert (type, tmp);
6433 else if (sym->attr.is_bind_c && e && is_CFI_desc (fsym, NULL))
6434 /* Implement F2018, 18.3.6, list item (5), bullet point 2. */
6435 gfc_conv_gfc_desc_to_cfi_desc (&parmse, e, fsym);
6437 else if (fsym && fsym->attr.value)
6439 if (fsym->ts.type == BT_CHARACTER
6440 && fsym->ts.is_c_interop
6441 && fsym->ns->proc_name != NULL
6442 && fsym->ns->proc_name->attr.is_bind_c)
6444 parmse.expr = NULL;
6445 conv_scalar_char_value (fsym, &parmse, &e);
6446 if (parmse.expr == NULL)
6447 gfc_conv_expr (&parmse, e);
6449 else
6451 gfc_conv_expr (&parmse, e);
6453 /* ABI: actual arguments to CHARACTER(len=1),VALUE
6454 dummy arguments are actually passed by value.
6455 Strings are truncated to length 1. */
6456 if (gfc_length_one_character_type_p (&fsym->ts))
6458 if (e->expr_type == EXPR_CONSTANT
6459 && e->value.character.length > 1)
6461 e->value.character.length = 1;
6462 gfc_conv_expr (&parmse, e);
6465 tree slen1 = build_int_cst (gfc_charlen_type_node, 1);
6466 gfc_conv_string_parameter (&parmse);
6467 parmse.expr
6468 = gfc_string_to_single_character (slen1,
6469 parmse.expr,
6470 e->ts.kind);
6471 /* Truncate resulting string to length 1. */
6472 parmse.string_length = slen1;
6475 if (fsym->attr.optional
6476 && fsym->ts.type != BT_CLASS
6477 && fsym->ts.type != BT_DERIVED)
6479 if (e->expr_type != EXPR_VARIABLE
6480 || !e->symtree->n.sym->attr.optional
6481 || e->ref != NULL)
6482 vec_safe_push (optionalargs, boolean_true_node);
6483 else
6485 tmp = gfc_conv_expr_present (e->symtree->n.sym);
6486 if (!e->symtree->n.sym->attr.value)
6487 parmse.expr
6488 = fold_build3_loc (input_location, COND_EXPR,
6489 TREE_TYPE (parmse.expr),
6490 tmp, parmse.expr,
6491 fold_convert (TREE_TYPE (parmse.expr),
6492 integer_zero_node));
6494 vec_safe_push (optionalargs,
6495 fold_convert (boolean_type_node,
6496 tmp));
6502 else if (arg->name && arg->name[0] == '%')
6503 /* Argument list functions %VAL, %LOC and %REF are signalled
6504 through arg->name. */
6505 conv_arglist_function (&parmse, arg->expr, arg->name);
6506 else if ((e->expr_type == EXPR_FUNCTION)
6507 && ((e->value.function.esym
6508 && e->value.function.esym->result->attr.pointer)
6509 || (!e->value.function.esym
6510 && e->symtree->n.sym->attr.pointer))
6511 && fsym && fsym->attr.target)
6512 /* Make sure the function only gets called once. */
6513 gfc_conv_expr_reference (&parmse, e);
6514 else if (e->expr_type == EXPR_FUNCTION
6515 && e->symtree->n.sym->result
6516 && e->symtree->n.sym->result != e->symtree->n.sym
6517 && e->symtree->n.sym->result->attr.proc_pointer)
6519 /* Functions returning procedure pointers. */
6520 gfc_conv_expr (&parmse, e);
6521 if (fsym && fsym->attr.proc_pointer)
6522 parmse.expr = gfc_build_addr_expr (NULL_TREE, parmse.expr);
6525 else
6527 bool defer_to_dealloc_blk = false;
6528 if (e->ts.type == BT_CLASS && fsym
6529 && fsym->ts.type == BT_CLASS
6530 && (!CLASS_DATA (fsym)->as
6531 || CLASS_DATA (fsym)->as->type != AS_ASSUMED_RANK)
6532 && CLASS_DATA (e)->attr.codimension)
6534 gcc_assert (!CLASS_DATA (fsym)->attr.codimension);
6535 gcc_assert (!CLASS_DATA (fsym)->as);
6536 gfc_add_class_array_ref (e);
6537 parmse.want_coarray = 1;
6538 gfc_conv_expr_reference (&parmse, e);
6539 class_scalar_coarray_to_class (&parmse, e, fsym->ts,
6540 fsym->attr.optional
6541 && e->expr_type == EXPR_VARIABLE);
6543 else if (e->ts.type == BT_CLASS && fsym
6544 && fsym->ts.type == BT_CLASS
6545 && !CLASS_DATA (fsym)->as
6546 && !CLASS_DATA (e)->as
6547 && strcmp (fsym->ts.u.derived->name,
6548 e->ts.u.derived->name))
6550 type = gfc_typenode_for_spec (&fsym->ts);
6551 var = gfc_create_var (type, fsym->name);
6552 gfc_conv_expr (&parmse, e);
6553 if (fsym->attr.optional
6554 && e->expr_type == EXPR_VARIABLE
6555 && e->symtree->n.sym->attr.optional)
6557 stmtblock_t block;
6558 tree cond;
6559 tmp = gfc_build_addr_expr (NULL_TREE, parmse.expr);
6560 cond = fold_build2_loc (input_location, NE_EXPR,
6561 logical_type_node, tmp,
6562 fold_convert (TREE_TYPE (tmp),
6563 null_pointer_node));
6564 gfc_start_block (&block);
6565 gfc_add_modify (&block, var,
6566 fold_build1_loc (input_location,
6567 VIEW_CONVERT_EXPR,
6568 type, parmse.expr));
6569 gfc_add_expr_to_block (&parmse.pre,
6570 fold_build3_loc (input_location,
6571 COND_EXPR, void_type_node,
6572 cond, gfc_finish_block (&block),
6573 build_empty_stmt (input_location)));
6574 parmse.expr = gfc_build_addr_expr (NULL_TREE, var);
6575 parmse.expr = build3_loc (input_location, COND_EXPR,
6576 TREE_TYPE (parmse.expr),
6577 cond, parmse.expr,
6578 fold_convert (TREE_TYPE (parmse.expr),
6579 null_pointer_node));
6581 else
6583 /* Since the internal representation of unlimited
6584 polymorphic expressions includes an extra field
6585 that other class objects do not, a cast to the
6586 formal type does not work. */
6587 if (!UNLIMITED_POLY (e) && UNLIMITED_POLY (fsym))
6589 tree efield;
6591 /* Set the _data field. */
6592 tmp = gfc_class_data_get (var);
6593 efield = fold_convert (TREE_TYPE (tmp),
6594 gfc_class_data_get (parmse.expr));
6595 gfc_add_modify (&parmse.pre, tmp, efield);
6597 /* Set the _vptr field. */
6598 tmp = gfc_class_vptr_get (var);
6599 efield = fold_convert (TREE_TYPE (tmp),
6600 gfc_class_vptr_get (parmse.expr));
6601 gfc_add_modify (&parmse.pre, tmp, efield);
6603 /* Set the _len field. */
6604 tmp = gfc_class_len_get (var);
6605 gfc_add_modify (&parmse.pre, tmp,
6606 build_int_cst (TREE_TYPE (tmp), 0));
6608 else
6610 tmp = fold_build1_loc (input_location,
6611 VIEW_CONVERT_EXPR,
6612 type, parmse.expr);
6613 gfc_add_modify (&parmse.pre, var, tmp);
6616 parmse.expr = gfc_build_addr_expr (NULL_TREE, var);
6619 else
6621 gfc_conv_expr_reference (&parmse, e);
6623 gfc_symbol *dsym = fsym;
6624 gfc_dummy_arg *dummy;
6626 /* Use associated dummy as fallback for formal
6627 argument if there is no explicit interface. */
6628 if (dsym == NULL
6629 && (dummy = arg->associated_dummy)
6630 && dummy->intrinsicness == GFC_NON_INTRINSIC_DUMMY_ARG
6631 && dummy->u.non_intrinsic->sym)
6632 dsym = dummy->u.non_intrinsic->sym;
6634 if (dsym
6635 && dsym->attr.intent == INTENT_OUT
6636 && !dsym->attr.allocatable
6637 && !dsym->attr.pointer
6638 && e->expr_type == EXPR_VARIABLE
6639 && e->ref == NULL
6640 && e->symtree
6641 && e->symtree->n.sym
6642 && !e->symtree->n.sym->attr.dimension
6643 && e->ts.type != BT_CHARACTER
6644 && e->ts.type != BT_CLASS
6645 && (e->ts.type != BT_DERIVED
6646 || (dsym->ts.type == BT_DERIVED
6647 && e->ts.u.derived == dsym->ts.u.derived
6648 /* Types with allocatable components are
6649 excluded from clobbering because we need
6650 the unclobbered pointers to free the
6651 allocatable components in the callee.
6652 Same goes for finalizable types or types
6653 with finalizable components, we need to
6654 pass the unclobbered values to the
6655 finalization routines.
6656 For parameterized types, it's less clear
6657 but they may not have a constant size
6658 so better exclude them in any case. */
6659 && !e->ts.u.derived->attr.alloc_comp
6660 && !e->ts.u.derived->attr.pdt_type
6661 && !gfc_is_finalizable (e->ts.u.derived, NULL)))
6662 && !sym->attr.elemental)
6664 tree var;
6665 var = build_fold_indirect_ref_loc (input_location,
6666 parmse.expr);
6667 tree clobber = build_clobber (TREE_TYPE (var));
6668 gfc_add_modify (&clobbers, var, clobber);
6671 /* Catch base objects that are not variables. */
6672 if (e->ts.type == BT_CLASS
6673 && e->expr_type != EXPR_VARIABLE
6674 && expr && e == expr->base_expr)
6675 base_object = build_fold_indirect_ref_loc (input_location,
6676 parmse.expr);
6678 /* If an ALLOCATABLE dummy argument has INTENT(OUT) and is
6679 allocated on entry, it must be deallocated. */
6680 if (fsym && fsym->attr.intent == INTENT_OUT
6681 && (fsym->attr.allocatable
6682 || (fsym->ts.type == BT_CLASS
6683 && CLASS_DATA (fsym)->attr.allocatable))
6684 && !is_CFI_desc (fsym, NULL))
6686 stmtblock_t block;
6687 tree ptr;
6689 defer_to_dealloc_blk = true;
6691 parmse.expr = gfc_evaluate_data_ref_now (parmse.expr,
6692 &parmse.pre);
6694 if (parmse.class_container != NULL_TREE)
6695 parmse.class_container
6696 = gfc_evaluate_data_ref_now (parmse.class_container,
6697 &parmse.pre);
6699 gfc_init_block (&block);
6700 ptr = parmse.expr;
6701 if (e->ts.type == BT_CLASS)
6702 ptr = gfc_class_data_get (ptr);
6704 tree cls = parmse.class_container;
6705 tmp = gfc_deallocate_scalar_with_status (ptr, NULL_TREE,
6706 NULL_TREE, true,
6707 e, e->ts, cls);
6708 gfc_add_expr_to_block (&block, tmp);
6709 tmp = fold_build2_loc (input_location, MODIFY_EXPR,
6710 void_type_node, ptr,
6711 null_pointer_node);
6712 gfc_add_expr_to_block (&block, tmp);
6714 if (fsym->ts.type == BT_CLASS && UNLIMITED_POLY (fsym))
6716 gfc_add_modify (&block, ptr,
6717 fold_convert (TREE_TYPE (ptr),
6718 null_pointer_node));
6719 gfc_add_expr_to_block (&block, tmp);
6721 else if (fsym->ts.type == BT_CLASS)
6723 gfc_symbol *vtab;
6724 vtab = gfc_find_derived_vtab (fsym->ts.u.derived);
6725 tmp = gfc_get_symbol_decl (vtab);
6726 tmp = gfc_build_addr_expr (NULL_TREE, tmp);
6727 ptr = gfc_class_vptr_get (parmse.expr);
6728 gfc_add_modify (&block, ptr,
6729 fold_convert (TREE_TYPE (ptr), tmp));
6730 gfc_add_expr_to_block (&block, tmp);
6733 if (fsym->attr.optional
6734 && e->expr_type == EXPR_VARIABLE
6735 && e->symtree->n.sym->attr.optional)
6737 tmp = fold_build3_loc (input_location, COND_EXPR,
6738 void_type_node,
6739 gfc_conv_expr_present (e->symtree->n.sym),
6740 gfc_finish_block (&block),
6741 build_empty_stmt (input_location));
6743 else
6744 tmp = gfc_finish_block (&block);
6746 gfc_add_expr_to_block (&dealloc_blk, tmp);
6749 /* A class array element needs converting back to be a
6750 class object, if the formal argument is a class object. */
6751 if (fsym && fsym->ts.type == BT_CLASS
6752 && e->ts.type == BT_CLASS
6753 && ((CLASS_DATA (fsym)->as
6754 && CLASS_DATA (fsym)->as->type == AS_ASSUMED_RANK)
6755 || CLASS_DATA (e)->attr.dimension))
6757 gfc_se class_se = parmse;
6758 gfc_init_block (&class_se.pre);
6759 gfc_init_block (&class_se.post);
6761 gfc_conv_class_to_class (&class_se, e, fsym->ts, false,
6762 fsym->attr.intent != INTENT_IN
6763 && (CLASS_DATA (fsym)->attr.class_pointer
6764 || CLASS_DATA (fsym)->attr.allocatable),
6765 fsym->attr.optional
6766 && e->expr_type == EXPR_VARIABLE
6767 && e->symtree->n.sym->attr.optional,
6768 CLASS_DATA (fsym)->attr.class_pointer
6769 || CLASS_DATA (fsym)->attr.allocatable);
6771 parmse.expr = class_se.expr;
6772 stmtblock_t *class_pre_block = defer_to_dealloc_blk
6773 ? &dealloc_blk
6774 : &parmse.pre;
6775 gfc_add_block_to_block (class_pre_block, &class_se.pre);
6776 gfc_add_block_to_block (&parmse.post, &class_se.post);
6779 if (fsym && (fsym->ts.type == BT_DERIVED
6780 || fsym->ts.type == BT_ASSUMED)
6781 && e->ts.type == BT_CLASS
6782 && !CLASS_DATA (e)->attr.dimension
6783 && !CLASS_DATA (e)->attr.codimension)
6785 parmse.expr = gfc_class_data_get (parmse.expr);
6786 /* The result is a class temporary, whose _data component
6787 must be freed to avoid a memory leak. */
6788 if (e->expr_type == EXPR_FUNCTION
6789 && CLASS_DATA (e)->attr.allocatable)
6791 tree zero;
6793 /* Finalize the expression. */
6794 gfc_finalize_tree_expr (&parmse, NULL,
6795 gfc_expr_attr (e), e->rank);
6796 gfc_add_block_to_block (&parmse.post,
6797 &parmse.finalblock);
6799 /* Then free the class _data. */
6800 zero = build_int_cst (TREE_TYPE (parmse.expr), 0);
6801 tmp = fold_build2_loc (input_location, NE_EXPR,
6802 logical_type_node,
6803 parmse.expr, zero);
6804 tmp = build3_v (COND_EXPR, tmp,
6805 gfc_call_free (parmse.expr),
6806 build_empty_stmt (input_location));
6807 gfc_add_expr_to_block (&parmse.post, tmp);
6808 gfc_add_modify (&parmse.post, parmse.expr, zero);
6812 /* Wrap scalar variable in a descriptor. We need to convert
6813 the address of a pointer back to the pointer itself before,
6814 we can assign it to the data field. */
6816 if (fsym && fsym->as && fsym->as->type == AS_ASSUMED_RANK
6817 && fsym->ts.type != BT_CLASS && e->expr_type != EXPR_NULL)
6819 tmp = parmse.expr;
6820 if (TREE_CODE (tmp) == ADDR_EXPR)
6821 tmp = TREE_OPERAND (tmp, 0);
6822 parmse.expr = gfc_conv_scalar_to_descriptor (&parmse, tmp,
6823 fsym->attr);
6824 parmse.expr = gfc_build_addr_expr (NULL_TREE,
6825 parmse.expr);
6827 else if (fsym && e->expr_type != EXPR_NULL
6828 && ((fsym->attr.pointer
6829 && fsym->attr.flavor != FL_PROCEDURE)
6830 || (fsym->attr.proc_pointer
6831 && !(e->expr_type == EXPR_VARIABLE
6832 && e->symtree->n.sym->attr.dummy))
6833 || (fsym->attr.proc_pointer
6834 && e->expr_type == EXPR_VARIABLE
6835 && gfc_is_proc_ptr_comp (e))
6836 || (fsym->attr.allocatable
6837 && fsym->attr.flavor != FL_PROCEDURE)))
6839 /* Scalar pointer dummy args require an extra level of
6840 indirection. The null pointer already contains
6841 this level of indirection. */
6842 parm_kind = SCALAR_POINTER;
6843 parmse.expr = gfc_build_addr_expr (NULL_TREE, parmse.expr);
6847 else if (e->ts.type == BT_CLASS
6848 && fsym && fsym->ts.type == BT_CLASS
6849 && (CLASS_DATA (fsym)->attr.dimension
6850 || CLASS_DATA (fsym)->attr.codimension))
6852 /* Pass a class array. */
6853 parmse.use_offset = 1;
6854 gfc_conv_expr_descriptor (&parmse, e);
6855 bool defer_to_dealloc_blk = false;
6857 if (fsym->attr.optional
6858 && e->expr_type == EXPR_VARIABLE
6859 && e->symtree->n.sym->attr.optional)
6861 stmtblock_t block;
6863 gfc_init_block (&block);
6864 gfc_add_block_to_block (&block, &parmse.pre);
6866 tree t = fold_build3_loc (input_location, COND_EXPR,
6867 void_type_node,
6868 gfc_conv_expr_present (e->symtree->n.sym),
6869 gfc_finish_block (&block),
6870 build_empty_stmt (input_location));
6872 gfc_add_expr_to_block (&parmse.pre, t);
6875 /* If an ALLOCATABLE dummy argument has INTENT(OUT) and is
6876 allocated on entry, it must be deallocated. */
6877 if (fsym->attr.intent == INTENT_OUT
6878 && CLASS_DATA (fsym)->attr.allocatable)
6880 stmtblock_t block;
6881 tree ptr;
6883 /* In case the data reference to deallocate is dependent on
6884 its own content, save the resulting pointer to a variable
6885 and only use that variable from now on, before the
6886 expression becomes invalid. */
6887 parmse.expr = gfc_evaluate_data_ref_now (parmse.expr,
6888 &parmse.pre);
6890 if (parmse.class_container != NULL_TREE)
6891 parmse.class_container
6892 = gfc_evaluate_data_ref_now (parmse.class_container,
6893 &parmse.pre);
6895 gfc_init_block (&block);
6896 ptr = parmse.expr;
6897 ptr = gfc_class_data_get (ptr);
6899 tree cls = parmse.class_container;
6900 tmp = gfc_deallocate_with_status (ptr, NULL_TREE,
6901 NULL_TREE, NULL_TREE,
6902 NULL_TREE, true, e,
6903 GFC_CAF_COARRAY_NOCOARRAY,
6904 cls);
6905 gfc_add_expr_to_block (&block, tmp);
6906 tmp = fold_build2_loc (input_location, MODIFY_EXPR,
6907 void_type_node, ptr,
6908 null_pointer_node);
6909 gfc_add_expr_to_block (&block, tmp);
6910 gfc_reset_vptr (&block, e, parmse.class_container);
6912 if (fsym->attr.optional
6913 && e->expr_type == EXPR_VARIABLE
6914 && (!e->ref
6915 || (e->ref->type == REF_ARRAY
6916 && e->ref->u.ar.type != AR_FULL))
6917 && e->symtree->n.sym->attr.optional)
6919 tmp = fold_build3_loc (input_location, COND_EXPR,
6920 void_type_node,
6921 gfc_conv_expr_present (e->symtree->n.sym),
6922 gfc_finish_block (&block),
6923 build_empty_stmt (input_location));
6925 else
6926 tmp = gfc_finish_block (&block);
6928 gfc_add_expr_to_block (&dealloc_blk, tmp);
6929 defer_to_dealloc_blk = true;
6932 gfc_se class_se = parmse;
6933 gfc_init_block (&class_se.pre);
6934 gfc_init_block (&class_se.post);
6936 /* The conversion does not repackage the reference to a class
6937 array - _data descriptor. */
6938 gfc_conv_class_to_class (&class_se, e, fsym->ts, false,
6939 fsym->attr.intent != INTENT_IN
6940 && (CLASS_DATA (fsym)->attr.class_pointer
6941 || CLASS_DATA (fsym)->attr.allocatable),
6942 fsym->attr.optional
6943 && e->expr_type == EXPR_VARIABLE
6944 && e->symtree->n.sym->attr.optional,
6945 CLASS_DATA (fsym)->attr.class_pointer
6946 || CLASS_DATA (fsym)->attr.allocatable);
6948 parmse.expr = class_se.expr;
6949 stmtblock_t *class_pre_block = defer_to_dealloc_blk
6950 ? &dealloc_blk
6951 : &parmse.pre;
6952 gfc_add_block_to_block (class_pre_block, &class_se.pre);
6953 gfc_add_block_to_block (&parmse.post, &class_se.post);
6955 else
6957 /* If the argument is a function call that may not create
6958 a temporary for the result, we have to check that we
6959 can do it, i.e. that there is no alias between this
6960 argument and another one. */
6961 if (gfc_get_noncopying_intrinsic_argument (e) != NULL)
6963 gfc_expr *iarg;
6964 sym_intent intent;
6966 if (fsym != NULL)
6967 intent = fsym->attr.intent;
6968 else
6969 intent = INTENT_UNKNOWN;
6971 if (gfc_check_fncall_dependency (e, intent, sym, args,
6972 NOT_ELEMENTAL))
6973 parmse.force_tmp = 1;
6975 iarg = e->value.function.actual->expr;
6977 /* Temporary needed if aliasing due to host association. */
6978 if (sym->attr.contained
6979 && !sym->attr.pure
6980 && !sym->attr.implicit_pure
6981 && !sym->attr.use_assoc
6982 && iarg->expr_type == EXPR_VARIABLE
6983 && sym->ns == iarg->symtree->n.sym->ns)
6984 parmse.force_tmp = 1;
6986 /* Ditto within module. */
6987 if (sym->attr.use_assoc
6988 && !sym->attr.pure
6989 && !sym->attr.implicit_pure
6990 && iarg->expr_type == EXPR_VARIABLE
6991 && sym->module == iarg->symtree->n.sym->module)
6992 parmse.force_tmp = 1;
6995 /* Special case for assumed-rank arrays: when passing an
6996 argument to a nonallocatable/nonpointer dummy, the bounds have
6997 to be reset as otherwise a last-dim ubound of -1 is
6998 indistinguishable from an assumed-size array in the callee. */
6999 if (!sym->attr.is_bind_c && e && fsym && fsym->as
7000 && fsym->as->type == AS_ASSUMED_RANK
7001 && e->rank != -1
7002 && e->expr_type == EXPR_VARIABLE
7003 && ((fsym->ts.type == BT_CLASS
7004 && !CLASS_DATA (fsym)->attr.class_pointer
7005 && !CLASS_DATA (fsym)->attr.allocatable)
7006 || (fsym->ts.type != BT_CLASS
7007 && !fsym->attr.pointer && !fsym->attr.allocatable)))
7009 /* Change AR_FULL to a (:,:,:) ref to force bounds update. */
7010 gfc_ref *ref;
7011 for (ref = e->ref; ref->next; ref = ref->next)
7013 if (ref->u.ar.type == AR_FULL
7014 && ref->u.ar.as->type != AS_ASSUMED_SIZE)
7015 ref->u.ar.type = AR_SECTION;
7018 if (sym->attr.is_bind_c && e && is_CFI_desc (fsym, NULL))
7019 /* Implement F2018, 18.3.6, list item (5), bullet point 2. */
7020 gfc_conv_gfc_desc_to_cfi_desc (&parmse, e, fsym);
7022 else if (e->expr_type == EXPR_VARIABLE
7023 && is_subref_array (e)
7024 && !(fsym && fsym->attr.pointer))
7025 /* The actual argument is a component reference to an
7026 array of derived types. In this case, the argument
7027 is converted to a temporary, which is passed and then
7028 written back after the procedure call. */
7029 gfc_conv_subref_array_arg (&parmse, e, nodesc_arg,
7030 fsym ? fsym->attr.intent : INTENT_INOUT,
7031 fsym && fsym->attr.pointer);
7033 else if (e->ts.type == BT_CLASS && CLASS_DATA (e)->as
7034 && CLASS_DATA (e)->as->type == AS_ASSUMED_SIZE
7035 && nodesc_arg && fsym->ts.type == BT_DERIVED)
7036 /* An assumed size class actual argument being passed to
7037 a 'no descriptor' formal argument just requires the
7038 data pointer to be passed. For class dummy arguments
7039 this is stored in the symbol backend decl.. */
7040 parmse.expr = e->symtree->n.sym->backend_decl;
7042 else if (gfc_is_class_array_ref (e, NULL)
7043 && fsym && fsym->ts.type == BT_DERIVED)
7044 /* The actual argument is a component reference to an
7045 array of derived types. In this case, the argument
7046 is converted to a temporary, which is passed and then
7047 written back after the procedure call.
7048 OOP-TODO: Insert code so that if the dynamic type is
7049 the same as the declared type, copy-in/copy-out does
7050 not occur. */
7051 gfc_conv_subref_array_arg (&parmse, e, nodesc_arg,
7052 fsym->attr.intent,
7053 fsym->attr.pointer);
7055 else if (gfc_is_class_array_function (e)
7056 && fsym && fsym->ts.type == BT_DERIVED)
7057 /* See previous comment. For function actual argument,
7058 the write out is not needed so the intent is set as
7059 intent in. */
7061 e->must_finalize = 1;
7062 gfc_conv_subref_array_arg (&parmse, e, nodesc_arg,
7063 INTENT_IN, fsym->attr.pointer);
7065 else if (fsym && fsym->attr.contiguous
7066 && !gfc_is_simply_contiguous (e, false, true)
7067 && gfc_expr_is_variable (e))
7069 gfc_conv_subref_array_arg (&parmse, e, nodesc_arg,
7070 fsym->attr.intent,
7071 fsym->attr.pointer);
7073 else
7074 /* This is where we introduce a temporary to store the
7075 result of a non-lvalue array expression. */
7076 gfc_conv_array_parameter (&parmse, e, nodesc_arg, fsym,
7077 sym->name, NULL);
7079 /* If an ALLOCATABLE dummy argument has INTENT(OUT) and is
7080 allocated on entry, it must be deallocated.
7081 CFI descriptors are handled elsewhere. */
7082 if (fsym && fsym->attr.allocatable
7083 && fsym->attr.intent == INTENT_OUT
7084 && !is_CFI_desc (fsym, NULL))
7086 if (fsym->ts.type == BT_DERIVED
7087 && fsym->ts.u.derived->attr.alloc_comp)
7089 // deallocate the components first
7090 tmp = gfc_deallocate_alloc_comp (fsym->ts.u.derived,
7091 parmse.expr, e->rank);
7092 /* But check whether dummy argument is optional. */
7093 if (tmp != NULL_TREE
7094 && fsym->attr.optional
7095 && e->expr_type == EXPR_VARIABLE
7096 && e->symtree->n.sym->attr.optional)
7098 tree present;
7099 present = gfc_conv_expr_present (e->symtree->n.sym);
7100 tmp = build3_v (COND_EXPR, present, tmp,
7101 build_empty_stmt (input_location));
7103 if (tmp != NULL_TREE)
7104 gfc_add_expr_to_block (&dealloc_blk, tmp);
7107 tmp = parmse.expr;
7108 /* With bind(C), the actual argument is replaced by a bind-C
7109 descriptor; in this case, the data component arrives here,
7110 which shall not be dereferenced, but still freed and
7111 nullified. */
7112 if (TREE_TYPE(tmp) != pvoid_type_node)
7113 tmp = build_fold_indirect_ref_loc (input_location,
7114 parmse.expr);
7115 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp)))
7116 tmp = gfc_conv_descriptor_data_get (tmp);
7117 tmp = gfc_deallocate_with_status (tmp, NULL_TREE, NULL_TREE,
7118 NULL_TREE, NULL_TREE, true,
7120 GFC_CAF_COARRAY_NOCOARRAY);
7121 if (fsym->attr.optional
7122 && e->expr_type == EXPR_VARIABLE
7123 && e->symtree->n.sym->attr.optional)
7124 tmp = fold_build3_loc (input_location, COND_EXPR,
7125 void_type_node,
7126 gfc_conv_expr_present (e->symtree->n.sym),
7127 tmp, build_empty_stmt (input_location));
7128 gfc_add_expr_to_block (&dealloc_blk, tmp);
7132 /* Special case for an assumed-rank dummy argument. */
7133 if (!sym->attr.is_bind_c && e && fsym && e->rank > 0
7134 && (fsym->ts.type == BT_CLASS
7135 ? (CLASS_DATA (fsym)->as
7136 && CLASS_DATA (fsym)->as->type == AS_ASSUMED_RANK)
7137 : (fsym->as && fsym->as->type == AS_ASSUMED_RANK)))
7139 if (fsym->ts.type == BT_CLASS
7140 ? (CLASS_DATA (fsym)->attr.class_pointer
7141 || CLASS_DATA (fsym)->attr.allocatable)
7142 : (fsym->attr.pointer || fsym->attr.allocatable))
7144 /* Unallocated allocatable arrays and unassociated pointer
7145 arrays need their dtype setting if they are argument
7146 associated with assumed rank dummies to set the rank. */
7147 set_dtype_for_unallocated (&parmse, e);
7149 else if (e->expr_type == EXPR_VARIABLE
7150 && e->symtree->n.sym->attr.dummy
7151 && (e->ts.type == BT_CLASS
7152 ? (e->ref && e->ref->next
7153 && e->ref->next->type == REF_ARRAY
7154 && e->ref->next->u.ar.type == AR_FULL
7155 && e->ref->next->u.ar.as->type == AS_ASSUMED_SIZE)
7156 : (e->ref && e->ref->type == REF_ARRAY
7157 && e->ref->u.ar.type == AR_FULL
7158 && e->ref->u.ar.as->type == AS_ASSUMED_SIZE)))
7160 /* Assumed-size actual to assumed-rank dummy requires
7161 dim[rank-1].ubound = -1. */
7162 tree minus_one;
7163 tmp = build_fold_indirect_ref_loc (input_location, parmse.expr);
7164 if (fsym->ts.type == BT_CLASS)
7165 tmp = gfc_class_data_get (tmp);
7166 minus_one = build_int_cst (gfc_array_index_type, -1);
7167 gfc_conv_descriptor_ubound_set (&parmse.pre, tmp,
7168 gfc_rank_cst[e->rank - 1],
7169 minus_one);
7173 /* The case with fsym->attr.optional is that of a user subroutine
7174 with an interface indicating an optional argument. When we call
7175 an intrinsic subroutine, however, fsym is NULL, but we might still
7176 have an optional argument, so we proceed to the substitution
7177 just in case. */
7178 if (e && (fsym == NULL || fsym->attr.optional))
7180 /* If an optional argument is itself an optional dummy argument,
7181 check its presence and substitute a null if absent. This is
7182 only needed when passing an array to an elemental procedure
7183 as then array elements are accessed - or no NULL pointer is
7184 allowed and a "1" or "0" should be passed if not present.
7185 When passing a non-array-descriptor full array to a
7186 non-array-descriptor dummy, no check is needed. For
7187 array-descriptor actual to array-descriptor dummy, see
7188 PR 41911 for why a check has to be inserted.
7189 fsym == NULL is checked as intrinsics required the descriptor
7190 but do not always set fsym.
7191 Also, it is necessary to pass a NULL pointer to library routines
7192 which usually ignore optional arguments, so they can handle
7193 these themselves. */
7194 if (e->expr_type == EXPR_VARIABLE
7195 && e->symtree->n.sym->attr.optional
7196 && (((e->rank != 0 && elemental_proc)
7197 || e->representation.length || e->ts.type == BT_CHARACTER
7198 || (e->rank != 0
7199 && (fsym == NULL
7200 || (fsym->as
7201 && (fsym->as->type == AS_ASSUMED_SHAPE
7202 || fsym->as->type == AS_ASSUMED_RANK
7203 || fsym->as->type == AS_DEFERRED)))))
7204 || se->ignore_optional))
7205 gfc_conv_missing_dummy (&parmse, e, fsym ? fsym->ts : e->ts,
7206 e->representation.length);
7209 if (fsym && e)
7211 /* Obtain the character length of an assumed character length
7212 length procedure from the typespec. */
7213 if (fsym->ts.type == BT_CHARACTER
7214 && parmse.string_length == NULL_TREE
7215 && e->ts.type == BT_PROCEDURE
7216 && e->symtree->n.sym->ts.type == BT_CHARACTER
7217 && e->symtree->n.sym->ts.u.cl->length != NULL
7218 && e->symtree->n.sym->ts.u.cl->length->expr_type == EXPR_CONSTANT)
7220 gfc_conv_const_charlen (e->symtree->n.sym->ts.u.cl);
7221 parmse.string_length = e->symtree->n.sym->ts.u.cl->backend_decl;
7225 /* If any actual argument of the procedure is allocatable and passed
7226 to an allocatable dummy with INTENT(OUT), we conservatively
7227 evaluate actual argument expressions before deallocations are
7228 performed and the procedure is executed. May create temporaries.
7229 This ensures we conform to F2023:15.5.3, 15.5.4. */
7230 if (e && fsym && force_eval_args
7231 && fsym->attr.intent != INTENT_OUT
7232 && !gfc_is_constant_expr (e))
7233 parmse.expr = gfc_evaluate_now (parmse.expr, &parmse.pre);
7235 if (fsym && need_interface_mapping && e)
7236 gfc_add_interface_mapping (&mapping, fsym, &parmse, e);
7238 gfc_add_block_to_block (&se->pre, &parmse.pre);
7239 gfc_add_block_to_block (&post, &parmse.post);
7240 gfc_add_block_to_block (&se->finalblock, &parmse.finalblock);
7242 /* Allocated allocatable components of derived types must be
7243 deallocated for non-variable scalars, array arguments to elemental
7244 procedures, and array arguments with descriptor to non-elemental
7245 procedures. As bounds information for descriptorless arrays is no
7246 longer available here, they are dealt with in trans-array.cc
7247 (gfc_conv_array_parameter). */
7248 if (e && (e->ts.type == BT_DERIVED || e->ts.type == BT_CLASS)
7249 && e->ts.u.derived->attr.alloc_comp
7250 && (e->rank == 0 || elemental_proc || !nodesc_arg)
7251 && !expr_may_alias_variables (e, elemental_proc))
7253 int parm_rank;
7254 /* It is known the e returns a structure type with at least one
7255 allocatable component. When e is a function, ensure that the
7256 function is called once only by using a temporary variable. */
7257 if (!DECL_P (parmse.expr))
7258 parmse.expr = gfc_evaluate_now_loc (input_location,
7259 parmse.expr, &se->pre);
7261 if (fsym && fsym->attr.value)
7262 tmp = parmse.expr;
7263 else
7264 tmp = build_fold_indirect_ref_loc (input_location,
7265 parmse.expr);
7267 parm_rank = e->rank;
7268 switch (parm_kind)
7270 case (ELEMENTAL):
7271 case (SCALAR):
7272 parm_rank = 0;
7273 break;
7275 case (SCALAR_POINTER):
7276 tmp = build_fold_indirect_ref_loc (input_location,
7277 tmp);
7278 break;
7281 if (e->ts.type == BT_DERIVED && fsym && fsym->ts.type == BT_CLASS)
7283 /* The derived type is passed to gfc_deallocate_alloc_comp.
7284 Therefore, class actuals can be handled correctly but derived
7285 types passed to class formals need the _data component. */
7286 tmp = gfc_class_data_get (tmp);
7287 if (!CLASS_DATA (fsym)->attr.dimension)
7289 if (UNLIMITED_POLY (fsym))
7291 tree type = gfc_typenode_for_spec (&e->ts);
7292 type = build_pointer_type (type);
7293 tmp = fold_convert (type, tmp);
7295 tmp = build_fold_indirect_ref_loc (input_location, tmp);
7299 if (e->expr_type == EXPR_OP
7300 && e->value.op.op == INTRINSIC_PARENTHESES
7301 && e->value.op.op1->expr_type == EXPR_VARIABLE)
7303 tree local_tmp;
7304 local_tmp = gfc_evaluate_now (tmp, &se->pre);
7305 local_tmp = gfc_copy_alloc_comp (e->ts.u.derived, local_tmp, tmp,
7306 parm_rank, 0);
7307 gfc_add_expr_to_block (&se->post, local_tmp);
7310 if (!finalized && !e->must_finalize)
7312 bool scalar_res_outside_loop;
7313 scalar_res_outside_loop = e->expr_type == EXPR_FUNCTION
7314 && parm_rank == 0
7315 && parmse.loop;
7317 /* Scalars passed to an assumed rank argument are converted to
7318 a descriptor. Obtain the data field before deallocating any
7319 allocatable components. */
7320 if (parm_rank == 0 && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp)))
7321 tmp = gfc_conv_descriptor_data_get (tmp);
7323 if (scalar_res_outside_loop)
7325 /* Go through the ss chain to find the argument and use
7326 the stored value. */
7327 gfc_ss *tmp_ss = parmse.loop->ss;
7328 for (; tmp_ss; tmp_ss = tmp_ss->next)
7329 if (tmp_ss->info
7330 && tmp_ss->info->expr == e
7331 && tmp_ss->info->data.scalar.value != NULL_TREE)
7333 tmp = tmp_ss->info->data.scalar.value;
7334 break;
7338 STRIP_NOPS (tmp);
7340 if (derived_array != NULL_TREE)
7341 tmp = gfc_deallocate_alloc_comp (e->ts.u.derived,
7342 derived_array,
7343 parm_rank);
7344 else if ((e->ts.type == BT_CLASS
7345 && GFC_CLASS_TYPE_P (TREE_TYPE (tmp)))
7346 || e->ts.type == BT_DERIVED)
7347 tmp = gfc_deallocate_alloc_comp (e->ts.u.derived, tmp,
7348 parm_rank);
7349 else if (e->ts.type == BT_CLASS)
7350 tmp = gfc_deallocate_alloc_comp (CLASS_DATA (e)->ts.u.derived,
7351 tmp, parm_rank);
7353 if (scalar_res_outside_loop)
7354 gfc_add_expr_to_block (&parmse.loop->post, tmp);
7355 else
7356 gfc_prepend_expr_to_block (&post, tmp);
7360 /* Add argument checking of passing an unallocated/NULL actual to
7361 a nonallocatable/nonpointer dummy. */
7363 if (gfc_option.rtcheck & GFC_RTCHECK_POINTER && e != NULL)
7365 symbol_attribute attr;
7366 char *msg;
7367 tree cond;
7368 tree tmp;
7369 symbol_attribute fsym_attr;
7371 if (fsym)
7373 if (fsym->ts.type == BT_CLASS)
7375 fsym_attr = CLASS_DATA (fsym)->attr;
7376 fsym_attr.pointer = fsym_attr.class_pointer;
7378 else
7379 fsym_attr = fsym->attr;
7382 if (e->expr_type == EXPR_VARIABLE || e->expr_type == EXPR_FUNCTION)
7383 attr = gfc_expr_attr (e);
7384 else
7385 goto end_pointer_check;
7387 /* In Fortran 2008 it's allowed to pass a NULL pointer/nonallocated
7388 allocatable to an optional dummy, cf. 12.5.2.12. */
7389 if (fsym != NULL && fsym->attr.optional && !attr.proc_pointer
7390 && (gfc_option.allow_std & GFC_STD_F2008) != 0)
7391 goto end_pointer_check;
7393 if (attr.optional)
7395 /* If the actual argument is an optional pointer/allocatable and
7396 the formal argument takes an nonpointer optional value,
7397 it is invalid to pass a non-present argument on, even
7398 though there is no technical reason for this in gfortran.
7399 See Fortran 2003, Section 12.4.1.6 item (7)+(8). */
7400 tree present, null_ptr, type;
7402 if (attr.allocatable
7403 && (fsym == NULL || !fsym_attr.allocatable))
7404 msg = xasprintf ("Allocatable actual argument '%s' is not "
7405 "allocated or not present",
7406 e->symtree->n.sym->name);
7407 else if (attr.pointer
7408 && (fsym == NULL || !fsym_attr.pointer))
7409 msg = xasprintf ("Pointer actual argument '%s' is not "
7410 "associated or not present",
7411 e->symtree->n.sym->name);
7412 else if (attr.proc_pointer && !e->value.function.actual
7413 && (fsym == NULL || !fsym_attr.proc_pointer))
7414 msg = xasprintf ("Proc-pointer actual argument '%s' is not "
7415 "associated or not present",
7416 e->symtree->n.sym->name);
7417 else
7418 goto end_pointer_check;
7420 present = gfc_conv_expr_present (e->symtree->n.sym);
7421 type = TREE_TYPE (present);
7422 present = fold_build2_loc (input_location, EQ_EXPR,
7423 logical_type_node, present,
7424 fold_convert (type,
7425 null_pointer_node));
7426 type = TREE_TYPE (parmse.expr);
7427 null_ptr = fold_build2_loc (input_location, EQ_EXPR,
7428 logical_type_node, parmse.expr,
7429 fold_convert (type,
7430 null_pointer_node));
7431 cond = fold_build2_loc (input_location, TRUTH_ORIF_EXPR,
7432 logical_type_node, present, null_ptr);
7434 else
7436 if (attr.allocatable
7437 && (fsym == NULL || !fsym_attr.allocatable))
7438 msg = xasprintf ("Allocatable actual argument '%s' is not "
7439 "allocated", e->symtree->n.sym->name);
7440 else if (attr.pointer
7441 && (fsym == NULL || !fsym_attr.pointer))
7442 msg = xasprintf ("Pointer actual argument '%s' is not "
7443 "associated", e->symtree->n.sym->name);
7444 else if (attr.proc_pointer && !e->value.function.actual
7445 && (fsym == NULL || !fsym_attr.proc_pointer))
7446 msg = xasprintf ("Proc-pointer actual argument '%s' is not "
7447 "associated", e->symtree->n.sym->name);
7448 else
7449 goto end_pointer_check;
7451 tmp = parmse.expr;
7452 if (fsym && fsym->ts.type == BT_CLASS)
7454 if (POINTER_TYPE_P (TREE_TYPE (tmp)))
7455 tmp = build_fold_indirect_ref_loc (input_location, tmp);
7456 tmp = gfc_class_data_get (tmp);
7457 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp)))
7458 tmp = gfc_conv_descriptor_data_get (tmp);
7461 /* If the argument is passed by value, we need to strip the
7462 INDIRECT_REF. */
7463 if (!POINTER_TYPE_P (TREE_TYPE (tmp)))
7464 tmp = gfc_build_addr_expr (NULL_TREE, tmp);
7466 cond = fold_build2_loc (input_location, EQ_EXPR,
7467 logical_type_node, tmp,
7468 fold_convert (TREE_TYPE (tmp),
7469 null_pointer_node));
7472 gfc_trans_runtime_check (true, false, cond, &se->pre, &e->where,
7473 msg);
7474 free (msg);
7476 end_pointer_check:
7478 /* Deferred length dummies pass the character length by reference
7479 so that the value can be returned. */
7480 if (parmse.string_length && fsym && fsym->ts.deferred)
7482 if (INDIRECT_REF_P (parmse.string_length))
7484 /* In chains of functions/procedure calls the string_length already
7485 is a pointer to the variable holding the length. Therefore
7486 remove the deref on call. */
7487 tmp = parmse.string_length;
7488 parmse.string_length = TREE_OPERAND (parmse.string_length, 0);
7490 else
7492 tmp = parmse.string_length;
7493 if (!VAR_P (tmp) && TREE_CODE (tmp) != COMPONENT_REF)
7494 tmp = gfc_evaluate_now (parmse.string_length, &se->pre);
7495 parmse.string_length = gfc_build_addr_expr (NULL_TREE, tmp);
7498 if (e && e->expr_type == EXPR_VARIABLE
7499 && fsym->attr.allocatable
7500 && e->ts.u.cl->backend_decl
7501 && VAR_P (e->ts.u.cl->backend_decl))
7503 if (INDIRECT_REF_P (tmp))
7504 tmp = TREE_OPERAND (tmp, 0);
7505 gfc_add_modify (&se->post, e->ts.u.cl->backend_decl,
7506 fold_convert (gfc_charlen_type_node, tmp));
7510 /* Character strings are passed as two parameters, a length and a
7511 pointer - except for Bind(c) and c_ptrs which only passe the pointer.
7512 An unlimited polymorphic formal argument likewise does not
7513 need the length. */
7514 if (parmse.string_length != NULL_TREE
7515 && !sym->attr.is_bind_c
7516 && !(fsym && fsym->ts.type == BT_DERIVED && fsym->ts.u.derived
7517 && fsym->ts.u.derived->intmod_sym_id == ISOCBINDING_PTR
7518 && fsym->ts.u.derived->from_intmod == INTMOD_ISO_C_BINDING )
7519 && !(fsym && fsym->ts.type == BT_ASSUMED)
7520 && !(fsym && UNLIMITED_POLY (fsym)))
7521 vec_safe_push (stringargs, parmse.string_length);
7523 /* When calling __copy for character expressions to unlimited
7524 polymorphic entities, the dst argument needs a string length. */
7525 if (sym->name[0] == '_' && e && e->ts.type == BT_CHARACTER
7526 && startswith (sym->name, "__vtab_CHARACTER")
7527 && arg->next && arg->next->expr
7528 && (arg->next->expr->ts.type == BT_DERIVED
7529 || arg->next->expr->ts.type == BT_CLASS)
7530 && arg->next->expr->ts.u.derived->attr.unlimited_polymorphic)
7531 vec_safe_push (stringargs, parmse.string_length);
7533 /* For descriptorless coarrays and assumed-shape coarray dummies, we
7534 pass the token and the offset as additional arguments. */
7535 if (fsym && e == NULL && flag_coarray == GFC_FCOARRAY_LIB
7536 && ((fsym->ts.type != BT_CLASS && fsym->attr.codimension
7537 && !fsym->attr.allocatable)
7538 || (fsym->ts.type == BT_CLASS
7539 && CLASS_DATA (fsym)->attr.codimension
7540 && !CLASS_DATA (fsym)->attr.allocatable)))
7542 /* Token and offset. */
7543 vec_safe_push (stringargs, null_pointer_node);
7544 vec_safe_push (stringargs, build_int_cst (gfc_array_index_type, 0));
7545 gcc_assert (fsym->attr.optional);
7547 else if (fsym && flag_coarray == GFC_FCOARRAY_LIB
7548 && ((fsym->ts.type != BT_CLASS && fsym->attr.codimension
7549 && !fsym->attr.allocatable)
7550 || (fsym->ts.type == BT_CLASS
7551 && CLASS_DATA (fsym)->attr.codimension
7552 && !CLASS_DATA (fsym)->attr.allocatable)))
7554 tree caf_decl, caf_type;
7555 tree offset, tmp2;
7557 caf_decl = gfc_get_tree_for_caf_expr (e);
7558 caf_type = TREE_TYPE (caf_decl);
7560 if (GFC_DESCRIPTOR_TYPE_P (caf_type)
7561 && (GFC_TYPE_ARRAY_AKIND (caf_type) == GFC_ARRAY_ALLOCATABLE
7562 || GFC_TYPE_ARRAY_AKIND (caf_type) == GFC_ARRAY_POINTER))
7563 tmp = gfc_conv_descriptor_token (caf_decl);
7564 else if (DECL_LANG_SPECIFIC (caf_decl)
7565 && GFC_DECL_TOKEN (caf_decl) != NULL_TREE)
7566 tmp = GFC_DECL_TOKEN (caf_decl);
7567 else
7569 gcc_assert (GFC_ARRAY_TYPE_P (caf_type)
7570 && GFC_TYPE_ARRAY_CAF_TOKEN (caf_type) != NULL_TREE);
7571 tmp = GFC_TYPE_ARRAY_CAF_TOKEN (caf_type);
7574 vec_safe_push (stringargs, tmp);
7576 if (GFC_DESCRIPTOR_TYPE_P (caf_type)
7577 && GFC_TYPE_ARRAY_AKIND (caf_type) == GFC_ARRAY_ALLOCATABLE)
7578 offset = build_int_cst (gfc_array_index_type, 0);
7579 else if (DECL_LANG_SPECIFIC (caf_decl)
7580 && GFC_DECL_CAF_OFFSET (caf_decl) != NULL_TREE)
7581 offset = GFC_DECL_CAF_OFFSET (caf_decl);
7582 else if (GFC_TYPE_ARRAY_CAF_OFFSET (caf_type) != NULL_TREE)
7583 offset = GFC_TYPE_ARRAY_CAF_OFFSET (caf_type);
7584 else
7585 offset = build_int_cst (gfc_array_index_type, 0);
7587 if (GFC_DESCRIPTOR_TYPE_P (caf_type))
7588 tmp = gfc_conv_descriptor_data_get (caf_decl);
7589 else
7591 gcc_assert (POINTER_TYPE_P (caf_type));
7592 tmp = caf_decl;
7595 tmp2 = fsym->ts.type == BT_CLASS
7596 ? gfc_class_data_get (parmse.expr) : parmse.expr;
7597 if ((fsym->ts.type != BT_CLASS
7598 && (fsym->as->type == AS_ASSUMED_SHAPE
7599 || fsym->as->type == AS_ASSUMED_RANK))
7600 || (fsym->ts.type == BT_CLASS
7601 && (CLASS_DATA (fsym)->as->type == AS_ASSUMED_SHAPE
7602 || CLASS_DATA (fsym)->as->type == AS_ASSUMED_RANK)))
7604 if (fsym->ts.type == BT_CLASS)
7605 gcc_assert (!POINTER_TYPE_P (TREE_TYPE (tmp2)));
7606 else
7608 gcc_assert (POINTER_TYPE_P (TREE_TYPE (tmp2)));
7609 tmp2 = build_fold_indirect_ref_loc (input_location, tmp2);
7611 gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp2)));
7612 tmp2 = gfc_conv_descriptor_data_get (tmp2);
7614 else if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp2)))
7615 tmp2 = gfc_conv_descriptor_data_get (tmp2);
7616 else
7618 gcc_assert (POINTER_TYPE_P (TREE_TYPE (tmp2)));
7621 tmp = fold_build2_loc (input_location, MINUS_EXPR,
7622 gfc_array_index_type,
7623 fold_convert (gfc_array_index_type, tmp2),
7624 fold_convert (gfc_array_index_type, tmp));
7625 offset = fold_build2_loc (input_location, PLUS_EXPR,
7626 gfc_array_index_type, offset, tmp);
7628 vec_safe_push (stringargs, offset);
7631 vec_safe_push (arglist, parmse.expr);
7634 gfc_add_block_to_block (&se->pre, &dealloc_blk);
7635 gfc_add_block_to_block (&se->pre, &clobbers);
7636 gfc_finish_interface_mapping (&mapping, &se->pre, &se->post);
7638 if (comp)
7639 ts = comp->ts;
7640 else if (sym->ts.type == BT_CLASS)
7641 ts = CLASS_DATA (sym)->ts;
7642 else
7643 ts = sym->ts;
7645 if (ts.type == BT_CHARACTER && sym->attr.is_bind_c)
7646 se->string_length = build_int_cst (gfc_charlen_type_node, 1);
7647 else if (ts.type == BT_CHARACTER)
7649 if (ts.u.cl->length == NULL)
7651 /* Assumed character length results are not allowed by C418 of the 2003
7652 standard and are trapped in resolve.cc; except in the case of SPREAD
7653 (and other intrinsics?) and dummy functions. In the case of SPREAD,
7654 we take the character length of the first argument for the result.
7655 For dummies, we have to look through the formal argument list for
7656 this function and use the character length found there.
7657 Likewise, we handle the case of deferred-length character dummy
7658 arguments to intrinsics that determine the characteristics of
7659 the result, which cannot be deferred-length. */
7660 if (expr->value.function.isym)
7661 ts.deferred = false;
7662 if (ts.deferred)
7663 cl.backend_decl = gfc_create_var (gfc_charlen_type_node, "slen");
7664 else if (!sym->attr.dummy)
7665 cl.backend_decl = (*stringargs)[0];
7666 else
7668 formal = gfc_sym_get_dummy_args (sym->ns->proc_name);
7669 for (; formal; formal = formal->next)
7670 if (strcmp (formal->sym->name, sym->name) == 0)
7671 cl.backend_decl = formal->sym->ts.u.cl->backend_decl;
7673 len = cl.backend_decl;
7675 else
7677 tree tmp;
7679 /* Calculate the length of the returned string. */
7680 gfc_init_se (&parmse, NULL);
7681 if (need_interface_mapping)
7682 gfc_apply_interface_mapping (&mapping, &parmse, ts.u.cl->length);
7683 else
7684 gfc_conv_expr (&parmse, ts.u.cl->length);
7685 gfc_add_block_to_block (&se->pre, &parmse.pre);
7686 gfc_add_block_to_block (&se->post, &parmse.post);
7687 tmp = parmse.expr;
7688 /* TODO: It would be better to have the charlens as
7689 gfc_charlen_type_node already when the interface is
7690 created instead of converting it here (see PR 84615). */
7691 tmp = fold_build2_loc (input_location, MAX_EXPR,
7692 gfc_charlen_type_node,
7693 fold_convert (gfc_charlen_type_node, tmp),
7694 build_zero_cst (gfc_charlen_type_node));
7695 cl.backend_decl = tmp;
7698 /* Set up a charlen structure for it. */
7699 cl.next = NULL;
7700 cl.length = NULL;
7701 ts.u.cl = &cl;
7703 len = cl.backend_decl;
7706 byref = (comp && (comp->attr.dimension
7707 || (comp->ts.type == BT_CHARACTER && !sym->attr.is_bind_c)))
7708 || (!comp && gfc_return_by_reference (sym));
7709 if (byref)
7711 if (se->direct_byref)
7713 /* Sometimes, too much indirection can be applied; e.g. for
7714 function_result = array_valued_recursive_function. */
7715 if (TREE_TYPE (TREE_TYPE (se->expr))
7716 && TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr)))
7717 && GFC_DESCRIPTOR_TYPE_P
7718 (TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr)))))
7719 se->expr = build_fold_indirect_ref_loc (input_location,
7720 se->expr);
7722 /* If the lhs of an assignment x = f(..) is allocatable and
7723 f2003 is allowed, we must do the automatic reallocation.
7724 TODO - deal with intrinsics, without using a temporary. */
7725 if (flag_realloc_lhs
7726 && se->ss && se->ss->loop_chain
7727 && se->ss->loop_chain->is_alloc_lhs
7728 && !expr->value.function.isym
7729 && sym->result->as != NULL)
7731 /* Evaluate the bounds of the result, if known. */
7732 gfc_set_loop_bounds_from_array_spec (&mapping, se,
7733 sym->result->as);
7735 /* Perform the automatic reallocation. */
7736 tmp = gfc_alloc_allocatable_for_assignment (se->loop,
7737 expr, NULL);
7738 gfc_add_expr_to_block (&se->pre, tmp);
7740 /* Pass the temporary as the first argument. */
7741 result = info->descriptor;
7743 else
7744 result = build_fold_indirect_ref_loc (input_location,
7745 se->expr);
7746 vec_safe_push (retargs, se->expr);
7748 else if (comp && comp->attr.dimension)
7750 gcc_assert (se->loop && info);
7752 /* Set the type of the array. */
7753 tmp = gfc_typenode_for_spec (&comp->ts);
7754 gcc_assert (se->ss->dimen == se->loop->dimen);
7756 /* Evaluate the bounds of the result, if known. */
7757 gfc_set_loop_bounds_from_array_spec (&mapping, se, comp->as);
7759 /* If the lhs of an assignment x = f(..) is allocatable and
7760 f2003 is allowed, we must not generate the function call
7761 here but should just send back the results of the mapping.
7762 This is signalled by the function ss being flagged. */
7763 if (flag_realloc_lhs && se->ss && se->ss->is_alloc_lhs)
7765 gfc_free_interface_mapping (&mapping);
7766 return has_alternate_specifier;
7769 /* Create a temporary to store the result. In case the function
7770 returns a pointer, the temporary will be a shallow copy and
7771 mustn't be deallocated. */
7772 callee_alloc = comp->attr.allocatable || comp->attr.pointer;
7773 gfc_trans_create_temp_array (&se->pre, &se->post, se->ss,
7774 tmp, NULL_TREE, false,
7775 !comp->attr.pointer, callee_alloc,
7776 &se->ss->info->expr->where);
7778 /* Pass the temporary as the first argument. */
7779 result = info->descriptor;
7780 tmp = gfc_build_addr_expr (NULL_TREE, result);
7781 vec_safe_push (retargs, tmp);
7783 else if (!comp && sym->result->attr.dimension)
7785 gcc_assert (se->loop && info);
7787 /* Set the type of the array. */
7788 tmp = gfc_typenode_for_spec (&ts);
7789 gcc_assert (se->ss->dimen == se->loop->dimen);
7791 /* Evaluate the bounds of the result, if known. */
7792 gfc_set_loop_bounds_from_array_spec (&mapping, se, sym->result->as);
7794 /* If the lhs of an assignment x = f(..) is allocatable and
7795 f2003 is allowed, we must not generate the function call
7796 here but should just send back the results of the mapping.
7797 This is signalled by the function ss being flagged. */
7798 if (flag_realloc_lhs && se->ss && se->ss->is_alloc_lhs)
7800 gfc_free_interface_mapping (&mapping);
7801 return has_alternate_specifier;
7804 /* Create a temporary to store the result. In case the function
7805 returns a pointer, the temporary will be a shallow copy and
7806 mustn't be deallocated. */
7807 callee_alloc = sym->attr.allocatable || sym->attr.pointer;
7808 gfc_trans_create_temp_array (&se->pre, &se->post, se->ss,
7809 tmp, NULL_TREE, false,
7810 !sym->attr.pointer, callee_alloc,
7811 &se->ss->info->expr->where);
7813 /* Pass the temporary as the first argument. */
7814 result = info->descriptor;
7815 tmp = gfc_build_addr_expr (NULL_TREE, result);
7816 vec_safe_push (retargs, tmp);
7818 else if (ts.type == BT_CHARACTER)
7820 /* Pass the string length. */
7821 type = gfc_get_character_type (ts.kind, ts.u.cl);
7822 type = build_pointer_type (type);
7824 /* Emit a DECL_EXPR for the VLA type. */
7825 tmp = TREE_TYPE (type);
7826 if (TYPE_SIZE (tmp)
7827 && TREE_CODE (TYPE_SIZE (tmp)) != INTEGER_CST)
7829 tmp = build_decl (input_location, TYPE_DECL, NULL_TREE, tmp);
7830 DECL_ARTIFICIAL (tmp) = 1;
7831 DECL_IGNORED_P (tmp) = 1;
7832 tmp = fold_build1_loc (input_location, DECL_EXPR,
7833 TREE_TYPE (tmp), tmp);
7834 gfc_add_expr_to_block (&se->pre, tmp);
7837 /* Return an address to a char[0:len-1]* temporary for
7838 character pointers. */
7839 if ((!comp && (sym->attr.pointer || sym->attr.allocatable))
7840 || (comp && (comp->attr.pointer || comp->attr.allocatable)))
7842 var = gfc_create_var (type, "pstr");
7844 if ((!comp && sym->attr.allocatable)
7845 || (comp && comp->attr.allocatable))
7847 gfc_add_modify (&se->pre, var,
7848 fold_convert (TREE_TYPE (var),
7849 null_pointer_node));
7850 tmp = gfc_call_free (var);
7851 gfc_add_expr_to_block (&se->post, tmp);
7854 /* Provide an address expression for the function arguments. */
7855 var = gfc_build_addr_expr (NULL_TREE, var);
7857 else
7858 var = gfc_conv_string_tmp (se, type, len);
7860 vec_safe_push (retargs, var);
7862 else
7864 gcc_assert (flag_f2c && ts.type == BT_COMPLEX);
7866 type = gfc_get_complex_type (ts.kind);
7867 var = gfc_build_addr_expr (NULL_TREE, gfc_create_var (type, "cmplx"));
7868 vec_safe_push (retargs, var);
7871 /* Add the string length to the argument list. */
7872 if (ts.type == BT_CHARACTER && ts.deferred)
7874 tmp = len;
7875 if (!VAR_P (tmp))
7876 tmp = gfc_evaluate_now (len, &se->pre);
7877 TREE_STATIC (tmp) = 1;
7878 gfc_add_modify (&se->pre, tmp,
7879 build_int_cst (TREE_TYPE (tmp), 0));
7880 tmp = gfc_build_addr_expr (NULL_TREE, tmp);
7881 vec_safe_push (retargs, tmp);
7883 else if (ts.type == BT_CHARACTER)
7884 vec_safe_push (retargs, len);
7886 gfc_free_interface_mapping (&mapping);
7888 /* We need to glom RETARGS + ARGLIST + STRINGARGS + APPEND_ARGS. */
7889 arglen = (vec_safe_length (arglist) + vec_safe_length (optionalargs)
7890 + vec_safe_length (stringargs) + vec_safe_length (append_args));
7891 vec_safe_reserve (retargs, arglen);
7893 /* Add the return arguments. */
7894 vec_safe_splice (retargs, arglist);
7896 /* Add the hidden present status for optional+value to the arguments. */
7897 vec_safe_splice (retargs, optionalargs);
7899 /* Add the hidden string length parameters to the arguments. */
7900 vec_safe_splice (retargs, stringargs);
7902 /* We may want to append extra arguments here. This is used e.g. for
7903 calls to libgfortran_matmul_??, which need extra information. */
7904 vec_safe_splice (retargs, append_args);
7906 arglist = retargs;
7908 /* Generate the actual call. */
7909 if (base_object == NULL_TREE)
7910 conv_function_val (se, sym, expr, args);
7911 else
7912 conv_base_obj_fcn_val (se, base_object, expr);
7914 /* If there are alternate return labels, function type should be
7915 integer. Can't modify the type in place though, since it can be shared
7916 with other functions. For dummy arguments, the typing is done to
7917 this result, even if it has to be repeated for each call. */
7918 if (has_alternate_specifier
7919 && TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr))) != integer_type_node)
7921 if (!sym->attr.dummy)
7923 TREE_TYPE (sym->backend_decl)
7924 = build_function_type (integer_type_node,
7925 TYPE_ARG_TYPES (TREE_TYPE (sym->backend_decl)));
7926 se->expr = gfc_build_addr_expr (NULL_TREE, sym->backend_decl);
7928 else
7929 TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr))) = integer_type_node;
7932 fntype = TREE_TYPE (TREE_TYPE (se->expr));
7933 se->expr = build_call_vec (TREE_TYPE (fntype), se->expr, arglist);
7935 /* Allocatable scalar function results must be freed and nullified
7936 after use. This necessitates the creation of a temporary to
7937 hold the result to prevent duplicate calls. */
7938 symbol_attribute attr = comp ? comp->attr : sym->attr;
7939 bool allocatable = attr.allocatable && !attr.dimension;
7940 gfc_symbol *der = comp ?
7941 comp->ts.type == BT_DERIVED ? comp->ts.u.derived : NULL
7943 sym->ts.type == BT_DERIVED ? sym->ts.u.derived : NULL;
7944 bool finalizable = der != NULL && der->ns->proc_name
7945 && gfc_is_finalizable (der, NULL);
7947 if (!byref && finalizable)
7948 gfc_finalize_tree_expr (se, der, attr, expr->rank);
7950 if (!byref && sym->ts.type != BT_CHARACTER
7951 && allocatable && !finalizable)
7953 tmp = gfc_create_var (TREE_TYPE (se->expr), NULL);
7954 gfc_add_modify (&se->pre, tmp, se->expr);
7955 se->expr = tmp;
7956 tmp = gfc_call_free (tmp);
7957 gfc_add_expr_to_block (&post, tmp);
7958 gfc_add_modify (&post, se->expr, build_int_cst (TREE_TYPE (se->expr), 0));
7961 /* If we have a pointer function, but we don't want a pointer, e.g.
7962 something like
7963 x = f()
7964 where f is pointer valued, we have to dereference the result. */
7965 if (!se->want_pointer && !byref
7966 && ((!comp && (sym->attr.pointer || sym->attr.allocatable))
7967 || (comp && (comp->attr.pointer || comp->attr.allocatable))))
7968 se->expr = build_fold_indirect_ref_loc (input_location, se->expr);
7970 /* f2c calling conventions require a scalar default real function to
7971 return a double precision result. Convert this back to default
7972 real. We only care about the cases that can happen in Fortran 77.
7974 if (flag_f2c && sym->ts.type == BT_REAL
7975 && sym->ts.kind == gfc_default_real_kind
7976 && !sym->attr.pointer
7977 && !sym->attr.allocatable
7978 && !sym->attr.always_explicit)
7979 se->expr = fold_convert (gfc_get_real_type (sym->ts.kind), se->expr);
7981 /* A pure function may still have side-effects - it may modify its
7982 parameters. */
7983 TREE_SIDE_EFFECTS (se->expr) = 1;
7984 #if 0
7985 if (!sym->attr.pure)
7986 TREE_SIDE_EFFECTS (se->expr) = 1;
7987 #endif
7989 if (byref)
7991 /* Add the function call to the pre chain. There is no expression. */
7992 gfc_add_expr_to_block (&se->pre, se->expr);
7993 se->expr = NULL_TREE;
7995 if (!se->direct_byref)
7997 if ((sym->attr.dimension && !comp) || (comp && comp->attr.dimension))
7999 if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
8001 /* Check the data pointer hasn't been modified. This would
8002 happen in a function returning a pointer. */
8003 tmp = gfc_conv_descriptor_data_get (info->descriptor);
8004 tmp = fold_build2_loc (input_location, NE_EXPR,
8005 logical_type_node,
8006 tmp, info->data);
8007 gfc_trans_runtime_check (true, false, tmp, &se->pre, NULL,
8008 gfc_msg_fault);
8010 se->expr = info->descriptor;
8011 /* Bundle in the string length. */
8012 se->string_length = len;
8014 if (finalizable)
8015 gfc_finalize_tree_expr (se, der, attr, expr->rank);
8017 else if (ts.type == BT_CHARACTER)
8019 /* Dereference for character pointer results. */
8020 if ((!comp && (sym->attr.pointer || sym->attr.allocatable))
8021 || (comp && (comp->attr.pointer || comp->attr.allocatable)))
8022 se->expr = build_fold_indirect_ref_loc (input_location, var);
8023 else
8024 se->expr = var;
8026 se->string_length = len;
8028 else
8030 gcc_assert (ts.type == BT_COMPLEX && flag_f2c);
8031 se->expr = build_fold_indirect_ref_loc (input_location, var);
8036 /* Associate the rhs class object's meta-data with the result, when the
8037 result is a temporary. */
8038 if (args && args->expr && args->expr->ts.type == BT_CLASS
8039 && sym->ts.type == BT_CLASS && result != NULL_TREE && DECL_P (result)
8040 && !GFC_CLASS_TYPE_P (TREE_TYPE (result)))
8042 gfc_se parmse;
8043 gfc_expr *class_expr = gfc_find_and_cut_at_last_class_ref (args->expr);
8045 gfc_init_se (&parmse, NULL);
8046 parmse.data_not_needed = 1;
8047 gfc_conv_expr (&parmse, class_expr);
8048 if (!DECL_LANG_SPECIFIC (result))
8049 gfc_allocate_lang_decl (result);
8050 GFC_DECL_SAVED_DESCRIPTOR (result) = parmse.expr;
8051 gfc_free_expr (class_expr);
8052 /* -fcheck= can add diagnostic code, which has to be placed before
8053 the call. */
8054 if (parmse.pre.head != NULL)
8055 gfc_add_expr_to_block (&se->pre, parmse.pre.head);
8056 gcc_assert (parmse.post.head == NULL_TREE);
8059 /* Follow the function call with the argument post block. */
8060 if (byref)
8062 gfc_add_block_to_block (&se->pre, &post);
8064 /* Transformational functions of derived types with allocatable
8065 components must have the result allocatable components copied when the
8066 argument is actually given. */
8067 arg = expr->value.function.actual;
8068 if (result && arg && expr->rank
8069 && expr->value.function.isym
8070 && expr->value.function.isym->transformational
8071 && arg->expr
8072 && arg->expr->ts.type == BT_DERIVED
8073 && arg->expr->ts.u.derived->attr.alloc_comp)
8075 tree tmp2;
8076 /* Copy the allocatable components. We have to use a
8077 temporary here to prevent source allocatable components
8078 from being corrupted. */
8079 tmp2 = gfc_evaluate_now (result, &se->pre);
8080 tmp = gfc_copy_alloc_comp (arg->expr->ts.u.derived,
8081 result, tmp2, expr->rank, 0);
8082 gfc_add_expr_to_block (&se->pre, tmp);
8083 tmp = gfc_copy_allocatable_data (result, tmp2, TREE_TYPE(tmp2),
8084 expr->rank);
8085 gfc_add_expr_to_block (&se->pre, tmp);
8087 /* Finally free the temporary's data field. */
8088 tmp = gfc_conv_descriptor_data_get (tmp2);
8089 tmp = gfc_deallocate_with_status (tmp, NULL_TREE, NULL_TREE,
8090 NULL_TREE, NULL_TREE, true,
8091 NULL, GFC_CAF_COARRAY_NOCOARRAY);
8092 gfc_add_expr_to_block (&se->pre, tmp);
8095 else
8097 /* For a function with a class array result, save the result as
8098 a temporary, set the info fields needed by the scalarizer and
8099 call the finalization function of the temporary. Note that the
8100 nullification of allocatable components needed by the result
8101 is done in gfc_trans_assignment_1. */
8102 if (expr && ((gfc_is_class_array_function (expr)
8103 && se->ss && se->ss->loop)
8104 || gfc_is_alloc_class_scalar_function (expr))
8105 && se->expr && GFC_CLASS_TYPE_P (TREE_TYPE (se->expr))
8106 && expr->must_finalize)
8108 int n;
8109 if (se->ss && se->ss->loop)
8111 gfc_add_block_to_block (&se->ss->loop->pre, &se->pre);
8112 se->expr = gfc_evaluate_now (se->expr, &se->ss->loop->pre);
8113 tmp = gfc_class_data_get (se->expr);
8114 info->descriptor = tmp;
8115 info->data = gfc_conv_descriptor_data_get (tmp);
8116 info->offset = gfc_conv_descriptor_offset_get (tmp);
8117 for (n = 0; n < se->ss->loop->dimen; n++)
8119 tree dim = gfc_rank_cst[n];
8120 se->ss->loop->to[n] = gfc_conv_descriptor_ubound_get (tmp, dim);
8121 se->ss->loop->from[n] = gfc_conv_descriptor_lbound_get (tmp, dim);
8124 else
8126 /* TODO Eliminate the doubling of temporaries. This
8127 one is necessary to ensure no memory leakage. */
8128 se->expr = gfc_evaluate_now (se->expr, &se->pre);
8131 /* Finalize the result, if necessary. */
8132 attr = CLASS_DATA (expr->value.function.esym->result)->attr;
8133 if (!((gfc_is_class_array_function (expr)
8134 || gfc_is_alloc_class_scalar_function (expr))
8135 && attr.pointer))
8136 gfc_finalize_tree_expr (se, NULL, attr, expr->rank);
8138 gfc_add_block_to_block (&se->post, &post);
8141 return has_alternate_specifier;
8145 /* Fill a character string with spaces. */
8147 static tree
8148 fill_with_spaces (tree start, tree type, tree size)
8150 stmtblock_t block, loop;
8151 tree i, el, exit_label, cond, tmp;
8153 /* For a simple char type, we can call memset(). */
8154 if (compare_tree_int (TYPE_SIZE_UNIT (type), 1) == 0)
8155 return build_call_expr_loc (input_location,
8156 builtin_decl_explicit (BUILT_IN_MEMSET),
8157 3, start,
8158 build_int_cst (gfc_get_int_type (gfc_c_int_kind),
8159 lang_hooks.to_target_charset (' ')),
8160 fold_convert (size_type_node, size));
8162 /* Otherwise, we use a loop:
8163 for (el = start, i = size; i > 0; el--, i+= TYPE_SIZE_UNIT (type))
8164 *el = (type) ' ';
8167 /* Initialize variables. */
8168 gfc_init_block (&block);
8169 i = gfc_create_var (sizetype, "i");
8170 gfc_add_modify (&block, i, fold_convert (sizetype, size));
8171 el = gfc_create_var (build_pointer_type (type), "el");
8172 gfc_add_modify (&block, el, fold_convert (TREE_TYPE (el), start));
8173 exit_label = gfc_build_label_decl (NULL_TREE);
8174 TREE_USED (exit_label) = 1;
8177 /* Loop body. */
8178 gfc_init_block (&loop);
8180 /* Exit condition. */
8181 cond = fold_build2_loc (input_location, LE_EXPR, logical_type_node, i,
8182 build_zero_cst (sizetype));
8183 tmp = build1_v (GOTO_EXPR, exit_label);
8184 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond, tmp,
8185 build_empty_stmt (input_location));
8186 gfc_add_expr_to_block (&loop, tmp);
8188 /* Assignment. */
8189 gfc_add_modify (&loop,
8190 fold_build1_loc (input_location, INDIRECT_REF, type, el),
8191 build_int_cst (type, lang_hooks.to_target_charset (' ')));
8193 /* Increment loop variables. */
8194 gfc_add_modify (&loop, i,
8195 fold_build2_loc (input_location, MINUS_EXPR, sizetype, i,
8196 TYPE_SIZE_UNIT (type)));
8197 gfc_add_modify (&loop, el,
8198 fold_build_pointer_plus_loc (input_location,
8199 el, TYPE_SIZE_UNIT (type)));
8201 /* Making the loop... actually loop! */
8202 tmp = gfc_finish_block (&loop);
8203 tmp = build1_v (LOOP_EXPR, tmp);
8204 gfc_add_expr_to_block (&block, tmp);
8206 /* The exit label. */
8207 tmp = build1_v (LABEL_EXPR, exit_label);
8208 gfc_add_expr_to_block (&block, tmp);
8211 return gfc_finish_block (&block);
8215 /* Generate code to copy a string. */
8217 void
8218 gfc_trans_string_copy (stmtblock_t * block, tree dlength, tree dest,
8219 int dkind, tree slength, tree src, int skind)
8221 tree tmp, dlen, slen;
8222 tree dsc;
8223 tree ssc;
8224 tree cond;
8225 tree cond2;
8226 tree tmp2;
8227 tree tmp3;
8228 tree tmp4;
8229 tree chartype;
8230 stmtblock_t tempblock;
8232 gcc_assert (dkind == skind);
8234 if (slength != NULL_TREE)
8236 slen = gfc_evaluate_now (fold_convert (gfc_charlen_type_node, slength), block);
8237 ssc = gfc_string_to_single_character (slen, src, skind);
8239 else
8241 slen = build_one_cst (gfc_charlen_type_node);
8242 ssc = src;
8245 if (dlength != NULL_TREE)
8247 dlen = gfc_evaluate_now (fold_convert (gfc_charlen_type_node, dlength), block);
8248 dsc = gfc_string_to_single_character (dlen, dest, dkind);
8250 else
8252 dlen = build_one_cst (gfc_charlen_type_node);
8253 dsc = dest;
8256 /* Assign directly if the types are compatible. */
8257 if (dsc != NULL_TREE && ssc != NULL_TREE
8258 && TREE_TYPE (dsc) == TREE_TYPE (ssc))
8260 gfc_add_modify (block, dsc, ssc);
8261 return;
8264 /* The string copy algorithm below generates code like
8266 if (destlen > 0)
8268 if (srclen < destlen)
8270 memmove (dest, src, srclen);
8271 // Pad with spaces.
8272 memset (&dest[srclen], ' ', destlen - srclen);
8274 else
8276 // Truncate if too long.
8277 memmove (dest, src, destlen);
8282 /* Do nothing if the destination length is zero. */
8283 cond = fold_build2_loc (input_location, GT_EXPR, logical_type_node, dlen,
8284 build_zero_cst (TREE_TYPE (dlen)));
8286 /* For non-default character kinds, we have to multiply the string
8287 length by the base type size. */
8288 chartype = gfc_get_char_type (dkind);
8289 slen = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (slen),
8290 slen,
8291 fold_convert (TREE_TYPE (slen),
8292 TYPE_SIZE_UNIT (chartype)));
8293 dlen = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (dlen),
8294 dlen,
8295 fold_convert (TREE_TYPE (dlen),
8296 TYPE_SIZE_UNIT (chartype)));
8298 if (dlength && POINTER_TYPE_P (TREE_TYPE (dest)))
8299 dest = fold_convert (pvoid_type_node, dest);
8300 else
8301 dest = gfc_build_addr_expr (pvoid_type_node, dest);
8303 if (slength && POINTER_TYPE_P (TREE_TYPE (src)))
8304 src = fold_convert (pvoid_type_node, src);
8305 else
8306 src = gfc_build_addr_expr (pvoid_type_node, src);
8308 /* Truncate string if source is too long. */
8309 cond2 = fold_build2_loc (input_location, LT_EXPR, logical_type_node, slen,
8310 dlen);
8312 /* Pre-evaluate pointers unless one of the IF arms will be optimized away. */
8313 if (!CONSTANT_CLASS_P (cond2))
8315 dest = gfc_evaluate_now (dest, block);
8316 src = gfc_evaluate_now (src, block);
8319 /* Copy and pad with spaces. */
8320 tmp3 = build_call_expr_loc (input_location,
8321 builtin_decl_explicit (BUILT_IN_MEMMOVE),
8322 3, dest, src,
8323 fold_convert (size_type_node, slen));
8325 /* Wstringop-overflow appears at -O3 even though this warning is not
8326 explicitly available in fortran nor can it be switched off. If the
8327 source length is a constant, its negative appears as a very large
8328 positive number and triggers the warning in BUILTIN_MEMSET. Fixing
8329 the result of the MINUS_EXPR suppresses this spurious warning. */
8330 tmp = fold_build2_loc (input_location, MINUS_EXPR,
8331 TREE_TYPE(dlen), dlen, slen);
8332 if (slength && TREE_CONSTANT (slength))
8333 tmp = gfc_evaluate_now (tmp, block);
8335 tmp4 = fold_build_pointer_plus_loc (input_location, dest, slen);
8336 tmp4 = fill_with_spaces (tmp4, chartype, tmp);
8338 gfc_init_block (&tempblock);
8339 gfc_add_expr_to_block (&tempblock, tmp3);
8340 gfc_add_expr_to_block (&tempblock, tmp4);
8341 tmp3 = gfc_finish_block (&tempblock);
8343 /* The truncated memmove if the slen >= dlen. */
8344 tmp2 = build_call_expr_loc (input_location,
8345 builtin_decl_explicit (BUILT_IN_MEMMOVE),
8346 3, dest, src,
8347 fold_convert (size_type_node, dlen));
8349 /* The whole copy_string function is there. */
8350 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond2,
8351 tmp3, tmp2);
8352 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond, tmp,
8353 build_empty_stmt (input_location));
8354 gfc_add_expr_to_block (block, tmp);
8358 /* Translate a statement function.
8359 The value of a statement function reference is obtained by evaluating the
8360 expression using the values of the actual arguments for the values of the
8361 corresponding dummy arguments. */
8363 static void
8364 gfc_conv_statement_function (gfc_se * se, gfc_expr * expr)
8366 gfc_symbol *sym;
8367 gfc_symbol *fsym;
8368 gfc_formal_arglist *fargs;
8369 gfc_actual_arglist *args;
8370 gfc_se lse;
8371 gfc_se rse;
8372 gfc_saved_var *saved_vars;
8373 tree *temp_vars;
8374 tree type;
8375 tree tmp;
8376 int n;
8378 sym = expr->symtree->n.sym;
8379 args = expr->value.function.actual;
8380 gfc_init_se (&lse, NULL);
8381 gfc_init_se (&rse, NULL);
8383 n = 0;
8384 for (fargs = gfc_sym_get_dummy_args (sym); fargs; fargs = fargs->next)
8385 n++;
8386 saved_vars = XCNEWVEC (gfc_saved_var, n);
8387 temp_vars = XCNEWVEC (tree, n);
8389 for (fargs = gfc_sym_get_dummy_args (sym), n = 0; fargs;
8390 fargs = fargs->next, n++)
8392 /* Each dummy shall be specified, explicitly or implicitly, to be
8393 scalar. */
8394 gcc_assert (fargs->sym->attr.dimension == 0);
8395 fsym = fargs->sym;
8397 if (fsym->ts.type == BT_CHARACTER)
8399 /* Copy string arguments. */
8400 tree arglen;
8402 gcc_assert (fsym->ts.u.cl && fsym->ts.u.cl->length
8403 && fsym->ts.u.cl->length->expr_type == EXPR_CONSTANT);
8405 /* Create a temporary to hold the value. */
8406 if (fsym->ts.u.cl->backend_decl == NULL_TREE)
8407 fsym->ts.u.cl->backend_decl
8408 = gfc_conv_constant_to_tree (fsym->ts.u.cl->length);
8410 type = gfc_get_character_type (fsym->ts.kind, fsym->ts.u.cl);
8411 temp_vars[n] = gfc_create_var (type, fsym->name);
8413 arglen = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
8415 gfc_conv_expr (&rse, args->expr);
8416 gfc_conv_string_parameter (&rse);
8417 gfc_add_block_to_block (&se->pre, &lse.pre);
8418 gfc_add_block_to_block (&se->pre, &rse.pre);
8420 gfc_trans_string_copy (&se->pre, arglen, temp_vars[n], fsym->ts.kind,
8421 rse.string_length, rse.expr, fsym->ts.kind);
8422 gfc_add_block_to_block (&se->pre, &lse.post);
8423 gfc_add_block_to_block (&se->pre, &rse.post);
8425 else
8427 /* For everything else, just evaluate the expression. */
8429 /* Create a temporary to hold the value. */
8430 type = gfc_typenode_for_spec (&fsym->ts);
8431 temp_vars[n] = gfc_create_var (type, fsym->name);
8433 gfc_conv_expr (&lse, args->expr);
8435 gfc_add_block_to_block (&se->pre, &lse.pre);
8436 gfc_add_modify (&se->pre, temp_vars[n], lse.expr);
8437 gfc_add_block_to_block (&se->pre, &lse.post);
8440 args = args->next;
8443 /* Use the temporary variables in place of the real ones. */
8444 for (fargs = gfc_sym_get_dummy_args (sym), n = 0; fargs;
8445 fargs = fargs->next, n++)
8446 gfc_shadow_sym (fargs->sym, temp_vars[n], &saved_vars[n]);
8448 gfc_conv_expr (se, sym->value);
8450 if (sym->ts.type == BT_CHARACTER)
8452 gfc_conv_const_charlen (sym->ts.u.cl);
8454 /* Force the expression to the correct length. */
8455 if (!INTEGER_CST_P (se->string_length)
8456 || tree_int_cst_lt (se->string_length,
8457 sym->ts.u.cl->backend_decl))
8459 type = gfc_get_character_type (sym->ts.kind, sym->ts.u.cl);
8460 tmp = gfc_create_var (type, sym->name);
8461 tmp = gfc_build_addr_expr (build_pointer_type (type), tmp);
8462 gfc_trans_string_copy (&se->pre, sym->ts.u.cl->backend_decl, tmp,
8463 sym->ts.kind, se->string_length, se->expr,
8464 sym->ts.kind);
8465 se->expr = tmp;
8467 se->string_length = sym->ts.u.cl->backend_decl;
8470 /* Restore the original variables. */
8471 for (fargs = gfc_sym_get_dummy_args (sym), n = 0; fargs;
8472 fargs = fargs->next, n++)
8473 gfc_restore_sym (fargs->sym, &saved_vars[n]);
8474 free (temp_vars);
8475 free (saved_vars);
8479 /* Translate a function expression. */
8481 static void
8482 gfc_conv_function_expr (gfc_se * se, gfc_expr * expr)
8484 gfc_symbol *sym;
8486 if (expr->value.function.isym)
8488 gfc_conv_intrinsic_function (se, expr);
8489 return;
8492 /* expr.value.function.esym is the resolved (specific) function symbol for
8493 most functions. However this isn't set for dummy procedures. */
8494 sym = expr->value.function.esym;
8495 if (!sym)
8496 sym = expr->symtree->n.sym;
8498 /* The IEEE_ARITHMETIC functions are caught here. */
8499 if (sym->from_intmod == INTMOD_IEEE_ARITHMETIC)
8500 if (gfc_conv_ieee_arithmetic_function (se, expr))
8501 return;
8503 /* We distinguish statement functions from general functions to improve
8504 runtime performance. */
8505 if (sym->attr.proc == PROC_ST_FUNCTION)
8507 gfc_conv_statement_function (se, expr);
8508 return;
8511 gfc_conv_procedure_call (se, sym, expr->value.function.actual, expr,
8512 NULL);
8516 /* Determine whether the given EXPR_CONSTANT is a zero initializer. */
8518 static bool
8519 is_zero_initializer_p (gfc_expr * expr)
8521 if (expr->expr_type != EXPR_CONSTANT)
8522 return false;
8524 /* We ignore constants with prescribed memory representations for now. */
8525 if (expr->representation.string)
8526 return false;
8528 switch (expr->ts.type)
8530 case BT_INTEGER:
8531 return mpz_cmp_si (expr->value.integer, 0) == 0;
8533 case BT_REAL:
8534 return mpfr_zero_p (expr->value.real)
8535 && MPFR_SIGN (expr->value.real) >= 0;
8537 case BT_LOGICAL:
8538 return expr->value.logical == 0;
8540 case BT_COMPLEX:
8541 return mpfr_zero_p (mpc_realref (expr->value.complex))
8542 && MPFR_SIGN (mpc_realref (expr->value.complex)) >= 0
8543 && mpfr_zero_p (mpc_imagref (expr->value.complex))
8544 && MPFR_SIGN (mpc_imagref (expr->value.complex)) >= 0;
8546 default:
8547 break;
8549 return false;
8553 static void
8554 gfc_conv_array_constructor_expr (gfc_se * se, gfc_expr * expr)
8556 gfc_ss *ss;
8558 ss = se->ss;
8559 gcc_assert (ss != NULL && ss != gfc_ss_terminator);
8560 gcc_assert (ss->info->expr == expr && ss->info->type == GFC_SS_CONSTRUCTOR);
8562 gfc_conv_tmp_array_ref (se);
8566 /* Build a static initializer. EXPR is the expression for the initial value.
8567 The other parameters describe the variable of the component being
8568 initialized. EXPR may be null. */
8570 tree
8571 gfc_conv_initializer (gfc_expr * expr, gfc_typespec * ts, tree type,
8572 bool array, bool pointer, bool procptr)
8574 gfc_se se;
8576 if (flag_coarray != GFC_FCOARRAY_LIB && ts->type == BT_DERIVED
8577 && ts->u.derived->from_intmod == INTMOD_ISO_FORTRAN_ENV
8578 && ts->u.derived->intmod_sym_id == ISOFORTRAN_EVENT_TYPE)
8579 return build_constructor (type, NULL);
8581 if (!(expr || pointer || procptr))
8582 return NULL_TREE;
8584 /* Check if we have ISOCBINDING_NULL_PTR or ISOCBINDING_NULL_FUNPTR
8585 (these are the only two iso_c_binding derived types that can be
8586 used as initialization expressions). If so, we need to modify
8587 the 'expr' to be that for a (void *). */
8588 if (expr != NULL && expr->ts.type == BT_DERIVED
8589 && expr->ts.is_iso_c && expr->ts.u.derived)
8591 if (TREE_CODE (type) == ARRAY_TYPE)
8592 return build_constructor (type, NULL);
8593 else if (POINTER_TYPE_P (type))
8594 return build_int_cst (type, 0);
8595 else
8596 gcc_unreachable ();
8599 if (array && !procptr)
8601 tree ctor;
8602 /* Arrays need special handling. */
8603 if (pointer)
8604 ctor = gfc_build_null_descriptor (type);
8605 /* Special case assigning an array to zero. */
8606 else if (is_zero_initializer_p (expr))
8607 ctor = build_constructor (type, NULL);
8608 else
8609 ctor = gfc_conv_array_initializer (type, expr);
8610 TREE_STATIC (ctor) = 1;
8611 return ctor;
8613 else if (pointer || procptr)
8615 if (ts->type == BT_CLASS && !procptr)
8617 gfc_init_se (&se, NULL);
8618 gfc_conv_structure (&se, gfc_class_initializer (ts, expr), 1);
8619 gcc_assert (TREE_CODE (se.expr) == CONSTRUCTOR);
8620 TREE_STATIC (se.expr) = 1;
8621 return se.expr;
8623 else if (!expr || expr->expr_type == EXPR_NULL)
8624 return fold_convert (type, null_pointer_node);
8625 else
8627 gfc_init_se (&se, NULL);
8628 se.want_pointer = 1;
8629 gfc_conv_expr (&se, expr);
8630 gcc_assert (TREE_CODE (se.expr) != CONSTRUCTOR);
8631 return se.expr;
8634 else
8636 switch (ts->type)
8638 case_bt_struct:
8639 case BT_CLASS:
8640 gfc_init_se (&se, NULL);
8641 if (ts->type == BT_CLASS && expr->expr_type == EXPR_NULL)
8642 gfc_conv_structure (&se, gfc_class_initializer (ts, expr), 1);
8643 else
8644 gfc_conv_structure (&se, expr, 1);
8645 gcc_assert (TREE_CODE (se.expr) == CONSTRUCTOR);
8646 TREE_STATIC (se.expr) = 1;
8647 return se.expr;
8649 case BT_CHARACTER:
8650 if (expr->expr_type == EXPR_CONSTANT)
8652 tree ctor = gfc_conv_string_init (ts->u.cl->backend_decl, expr);
8653 TREE_STATIC (ctor) = 1;
8654 return ctor;
8657 /* Fallthrough. */
8658 default:
8659 gfc_init_se (&se, NULL);
8660 gfc_conv_constant (&se, expr);
8661 gcc_assert (TREE_CODE (se.expr) != CONSTRUCTOR);
8662 return se.expr;
8667 static tree
8668 gfc_trans_subarray_assign (tree dest, gfc_component * cm, gfc_expr * expr)
8670 gfc_se rse;
8671 gfc_se lse;
8672 gfc_ss *rss;
8673 gfc_ss *lss;
8674 gfc_array_info *lss_array;
8675 stmtblock_t body;
8676 stmtblock_t block;
8677 gfc_loopinfo loop;
8678 int n;
8679 tree tmp;
8681 gfc_start_block (&block);
8683 /* Initialize the scalarizer. */
8684 gfc_init_loopinfo (&loop);
8686 gfc_init_se (&lse, NULL);
8687 gfc_init_se (&rse, NULL);
8689 /* Walk the rhs. */
8690 rss = gfc_walk_expr (expr);
8691 if (rss == gfc_ss_terminator)
8692 /* The rhs is scalar. Add a ss for the expression. */
8693 rss = gfc_get_scalar_ss (gfc_ss_terminator, expr);
8695 /* Create a SS for the destination. */
8696 lss = gfc_get_array_ss (gfc_ss_terminator, NULL, cm->as->rank,
8697 GFC_SS_COMPONENT);
8698 lss_array = &lss->info->data.array;
8699 lss_array->shape = gfc_get_shape (cm->as->rank);
8700 lss_array->descriptor = dest;
8701 lss_array->data = gfc_conv_array_data (dest);
8702 lss_array->offset = gfc_conv_array_offset (dest);
8703 for (n = 0; n < cm->as->rank; n++)
8705 lss_array->start[n] = gfc_conv_array_lbound (dest, n);
8706 lss_array->stride[n] = gfc_index_one_node;
8708 mpz_init (lss_array->shape[n]);
8709 mpz_sub (lss_array->shape[n], cm->as->upper[n]->value.integer,
8710 cm->as->lower[n]->value.integer);
8711 mpz_add_ui (lss_array->shape[n], lss_array->shape[n], 1);
8714 /* Associate the SS with the loop. */
8715 gfc_add_ss_to_loop (&loop, lss);
8716 gfc_add_ss_to_loop (&loop, rss);
8718 /* Calculate the bounds of the scalarization. */
8719 gfc_conv_ss_startstride (&loop);
8721 /* Setup the scalarizing loops. */
8722 gfc_conv_loop_setup (&loop, &expr->where);
8724 /* Setup the gfc_se structures. */
8725 gfc_copy_loopinfo_to_se (&lse, &loop);
8726 gfc_copy_loopinfo_to_se (&rse, &loop);
8728 rse.ss = rss;
8729 gfc_mark_ss_chain_used (rss, 1);
8730 lse.ss = lss;
8731 gfc_mark_ss_chain_used (lss, 1);
8733 /* Start the scalarized loop body. */
8734 gfc_start_scalarized_body (&loop, &body);
8736 gfc_conv_tmp_array_ref (&lse);
8737 if (cm->ts.type == BT_CHARACTER)
8738 lse.string_length = cm->ts.u.cl->backend_decl;
8740 gfc_conv_expr (&rse, expr);
8742 tmp = gfc_trans_scalar_assign (&lse, &rse, cm->ts, true, false);
8743 gfc_add_expr_to_block (&body, tmp);
8745 gcc_assert (rse.ss == gfc_ss_terminator);
8747 /* Generate the copying loops. */
8748 gfc_trans_scalarizing_loops (&loop, &body);
8750 /* Wrap the whole thing up. */
8751 gfc_add_block_to_block (&block, &loop.pre);
8752 gfc_add_block_to_block (&block, &loop.post);
8754 gcc_assert (lss_array->shape != NULL);
8755 gfc_free_shape (&lss_array->shape, cm->as->rank);
8756 gfc_cleanup_loop (&loop);
8758 return gfc_finish_block (&block);
8762 static tree
8763 gfc_trans_alloc_subarray_assign (tree dest, gfc_component * cm,
8764 gfc_expr * expr)
8766 gfc_se se;
8767 stmtblock_t block;
8768 tree offset;
8769 int n;
8770 tree tmp;
8771 tree tmp2;
8772 gfc_array_spec *as;
8773 gfc_expr *arg = NULL;
8775 gfc_start_block (&block);
8776 gfc_init_se (&se, NULL);
8778 /* Get the descriptor for the expressions. */
8779 se.want_pointer = 0;
8780 gfc_conv_expr_descriptor (&se, expr);
8781 gfc_add_block_to_block (&block, &se.pre);
8782 gfc_add_modify (&block, dest, se.expr);
8783 if (cm->ts.type == BT_CHARACTER
8784 && gfc_deferred_strlen (cm, &tmp))
8786 tmp = fold_build3_loc (input_location, COMPONENT_REF,
8787 TREE_TYPE (tmp),
8788 TREE_OPERAND (dest, 0),
8789 tmp, NULL_TREE);
8790 gfc_add_modify (&block, tmp,
8791 fold_convert (TREE_TYPE (tmp),
8792 se.string_length));
8793 cm->ts.u.cl->backend_decl = gfc_create_var (gfc_charlen_type_node,
8794 "slen");
8795 gfc_add_modify (&block, cm->ts.u.cl->backend_decl, se.string_length);
8798 /* Deal with arrays of derived types with allocatable components. */
8799 if (gfc_bt_struct (cm->ts.type)
8800 && cm->ts.u.derived->attr.alloc_comp)
8801 // TODO: Fix caf_mode
8802 tmp = gfc_copy_alloc_comp (cm->ts.u.derived,
8803 se.expr, dest,
8804 cm->as->rank, 0);
8805 else if (cm->ts.type == BT_CLASS && expr->ts.type == BT_DERIVED
8806 && CLASS_DATA(cm)->attr.allocatable)
8808 if (cm->ts.u.derived->attr.alloc_comp)
8809 // TODO: Fix caf_mode
8810 tmp = gfc_copy_alloc_comp (expr->ts.u.derived,
8811 se.expr, dest,
8812 expr->rank, 0);
8813 else
8815 tmp = TREE_TYPE (dest);
8816 tmp = gfc_duplicate_allocatable (dest, se.expr,
8817 tmp, expr->rank, NULL_TREE);
8820 else if (cm->ts.type == BT_CHARACTER && cm->ts.deferred)
8821 tmp = gfc_duplicate_allocatable (dest, se.expr,
8822 gfc_typenode_for_spec (&cm->ts),
8823 cm->as->rank, NULL_TREE);
8824 else
8825 tmp = gfc_duplicate_allocatable (dest, se.expr,
8826 TREE_TYPE(cm->backend_decl),
8827 cm->as->rank, NULL_TREE);
8830 gfc_add_expr_to_block (&block, tmp);
8831 gfc_add_block_to_block (&block, &se.post);
8833 if (expr->expr_type != EXPR_VARIABLE)
8834 gfc_conv_descriptor_data_set (&block, se.expr,
8835 null_pointer_node);
8837 /* We need to know if the argument of a conversion function is a
8838 variable, so that the correct lower bound can be used. */
8839 if (expr->expr_type == EXPR_FUNCTION
8840 && expr->value.function.isym
8841 && expr->value.function.isym->conversion
8842 && expr->value.function.actual->expr
8843 && expr->value.function.actual->expr->expr_type == EXPR_VARIABLE)
8844 arg = expr->value.function.actual->expr;
8846 /* Obtain the array spec of full array references. */
8847 if (arg)
8848 as = gfc_get_full_arrayspec_from_expr (arg);
8849 else
8850 as = gfc_get_full_arrayspec_from_expr (expr);
8852 /* Shift the lbound and ubound of temporaries to being unity,
8853 rather than zero, based. Always calculate the offset. */
8854 offset = gfc_conv_descriptor_offset_get (dest);
8855 gfc_add_modify (&block, offset, gfc_index_zero_node);
8856 tmp2 =gfc_create_var (gfc_array_index_type, NULL);
8858 for (n = 0; n < expr->rank; n++)
8860 tree span;
8861 tree lbound;
8863 /* Obtain the correct lbound - ISO/IEC TR 15581:2001 page 9.
8864 TODO It looks as if gfc_conv_expr_descriptor should return
8865 the correct bounds and that the following should not be
8866 necessary. This would simplify gfc_conv_intrinsic_bound
8867 as well. */
8868 if (as && as->lower[n])
8870 gfc_se lbse;
8871 gfc_init_se (&lbse, NULL);
8872 gfc_conv_expr (&lbse, as->lower[n]);
8873 gfc_add_block_to_block (&block, &lbse.pre);
8874 lbound = gfc_evaluate_now (lbse.expr, &block);
8876 else if (as && arg)
8878 tmp = gfc_get_symbol_decl (arg->symtree->n.sym);
8879 lbound = gfc_conv_descriptor_lbound_get (tmp,
8880 gfc_rank_cst[n]);
8882 else if (as)
8883 lbound = gfc_conv_descriptor_lbound_get (dest,
8884 gfc_rank_cst[n]);
8885 else
8886 lbound = gfc_index_one_node;
8888 lbound = fold_convert (gfc_array_index_type, lbound);
8890 /* Shift the bounds and set the offset accordingly. */
8891 tmp = gfc_conv_descriptor_ubound_get (dest, gfc_rank_cst[n]);
8892 span = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
8893 tmp, gfc_conv_descriptor_lbound_get (dest, gfc_rank_cst[n]));
8894 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
8895 span, lbound);
8896 gfc_conv_descriptor_ubound_set (&block, dest,
8897 gfc_rank_cst[n], tmp);
8898 gfc_conv_descriptor_lbound_set (&block, dest,
8899 gfc_rank_cst[n], lbound);
8901 tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
8902 gfc_conv_descriptor_lbound_get (dest,
8903 gfc_rank_cst[n]),
8904 gfc_conv_descriptor_stride_get (dest,
8905 gfc_rank_cst[n]));
8906 gfc_add_modify (&block, tmp2, tmp);
8907 tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
8908 offset, tmp2);
8909 gfc_conv_descriptor_offset_set (&block, dest, tmp);
8912 if (arg)
8914 /* If a conversion expression has a null data pointer
8915 argument, nullify the allocatable component. */
8916 tree non_null_expr;
8917 tree null_expr;
8919 if (arg->symtree->n.sym->attr.allocatable
8920 || arg->symtree->n.sym->attr.pointer)
8922 non_null_expr = gfc_finish_block (&block);
8923 gfc_start_block (&block);
8924 gfc_conv_descriptor_data_set (&block, dest,
8925 null_pointer_node);
8926 null_expr = gfc_finish_block (&block);
8927 tmp = gfc_conv_descriptor_data_get (arg->symtree->n.sym->backend_decl);
8928 tmp = build2_loc (input_location, EQ_EXPR, logical_type_node, tmp,
8929 fold_convert (TREE_TYPE (tmp), null_pointer_node));
8930 return build3_v (COND_EXPR, tmp,
8931 null_expr, non_null_expr);
8935 return gfc_finish_block (&block);
8939 /* Allocate or reallocate scalar component, as necessary. */
8941 static void
8942 alloc_scalar_allocatable_subcomponent (stmtblock_t *block, tree comp,
8943 gfc_component *cm, gfc_expr *expr2,
8944 tree slen)
8946 tree tmp;
8947 tree ptr;
8948 tree size;
8949 tree size_in_bytes;
8950 tree lhs_cl_size = NULL_TREE;
8951 gfc_se se;
8953 if (!comp)
8954 return;
8956 if (!expr2 || expr2->rank)
8957 return;
8959 realloc_lhs_warning (expr2->ts.type, false, &expr2->where);
8961 if (cm->ts.type == BT_CHARACTER && cm->ts.deferred)
8963 gcc_assert (expr2->ts.type == BT_CHARACTER);
8964 if (!expr2->ts.u.cl->backend_decl
8965 || !VAR_P (expr2->ts.u.cl->backend_decl))
8966 expr2->ts.u.cl->backend_decl = gfc_create_var (TREE_TYPE (slen),
8967 "slen");
8968 gfc_add_modify (block, expr2->ts.u.cl->backend_decl, slen);
8970 size = expr2->ts.u.cl->backend_decl;
8972 gfc_deferred_strlen (cm, &tmp);
8973 lhs_cl_size = fold_build3_loc (input_location, COMPONENT_REF,
8974 gfc_charlen_type_node,
8975 TREE_OPERAND (comp, 0),
8976 tmp, NULL_TREE);
8978 tmp = TREE_TYPE (gfc_typenode_for_spec (&cm->ts));
8979 tmp = TYPE_SIZE_UNIT (tmp);
8980 size_in_bytes = fold_build2_loc (input_location, MULT_EXPR,
8981 TREE_TYPE (tmp), tmp,
8982 fold_convert (TREE_TYPE (tmp), size));
8984 else if (cm->ts.type == BT_CLASS)
8986 if (expr2->ts.type != BT_CLASS)
8988 if (expr2->ts.type == BT_CHARACTER)
8990 gfc_init_se (&se, NULL);
8991 gfc_conv_expr (&se, expr2);
8992 size = build_int_cst (gfc_charlen_type_node, expr2->ts.kind);
8993 size = fold_build2_loc (input_location, MULT_EXPR,
8994 gfc_charlen_type_node,
8995 se.string_length, size);
8996 size = fold_convert (size_type_node, size);
8998 else
9000 if (expr2->ts.type == BT_DERIVED)
9001 tmp = gfc_get_symbol_decl (expr2->ts.u.derived);
9002 else
9003 tmp = gfc_typenode_for_spec (&expr2->ts);
9004 size = TYPE_SIZE_UNIT (tmp);
9007 else
9009 gfc_expr *e2vtab;
9010 e2vtab = gfc_find_and_cut_at_last_class_ref (expr2);
9011 gfc_add_vptr_component (e2vtab);
9012 gfc_add_size_component (e2vtab);
9013 gfc_init_se (&se, NULL);
9014 gfc_conv_expr (&se, e2vtab);
9015 gfc_add_block_to_block (block, &se.pre);
9016 size = fold_convert (size_type_node, se.expr);
9017 gfc_free_expr (e2vtab);
9019 size_in_bytes = size;
9021 else
9023 /* Otherwise use the length in bytes of the rhs. */
9024 size = TYPE_SIZE_UNIT (gfc_typenode_for_spec (&cm->ts));
9025 size_in_bytes = size;
9028 size_in_bytes = fold_build2_loc (input_location, MAX_EXPR, size_type_node,
9029 size_in_bytes, size_one_node);
9031 if (cm->ts.type == BT_DERIVED && cm->ts.u.derived->attr.alloc_comp)
9033 tmp = build_call_expr_loc (input_location,
9034 builtin_decl_explicit (BUILT_IN_CALLOC),
9035 2, build_one_cst (size_type_node),
9036 size_in_bytes);
9037 tmp = fold_convert (TREE_TYPE (comp), tmp);
9038 gfc_add_modify (block, comp, tmp);
9040 else
9042 tmp = build_call_expr_loc (input_location,
9043 builtin_decl_explicit (BUILT_IN_MALLOC),
9044 1, size_in_bytes);
9045 if (GFC_CLASS_TYPE_P (TREE_TYPE (comp)))
9046 ptr = gfc_class_data_get (comp);
9047 else
9048 ptr = comp;
9049 tmp = fold_convert (TREE_TYPE (ptr), tmp);
9050 gfc_add_modify (block, ptr, tmp);
9053 if (cm->ts.type == BT_CHARACTER && cm->ts.deferred)
9054 /* Update the lhs character length. */
9055 gfc_add_modify (block, lhs_cl_size,
9056 fold_convert (TREE_TYPE (lhs_cl_size), size));
9060 /* Assign a single component of a derived type constructor. */
9062 static tree
9063 gfc_trans_subcomponent_assign (tree dest, gfc_component * cm,
9064 gfc_expr * expr, bool init)
9066 gfc_se se;
9067 gfc_se lse;
9068 stmtblock_t block;
9069 tree tmp;
9070 tree vtab;
9072 gfc_start_block (&block);
9074 if (cm->attr.pointer || cm->attr.proc_pointer)
9076 /* Only care about pointers here, not about allocatables. */
9077 gfc_init_se (&se, NULL);
9078 /* Pointer component. */
9079 if ((cm->attr.dimension || cm->attr.codimension)
9080 && !cm->attr.proc_pointer)
9082 /* Array pointer. */
9083 if (expr->expr_type == EXPR_NULL)
9084 gfc_conv_descriptor_data_set (&block, dest, null_pointer_node);
9085 else
9087 se.direct_byref = 1;
9088 se.expr = dest;
9089 gfc_conv_expr_descriptor (&se, expr);
9090 gfc_add_block_to_block (&block, &se.pre);
9091 gfc_add_block_to_block (&block, &se.post);
9094 else
9096 /* Scalar pointers. */
9097 se.want_pointer = 1;
9098 gfc_conv_expr (&se, expr);
9099 gfc_add_block_to_block (&block, &se.pre);
9101 if (expr->symtree && expr->symtree->n.sym->attr.proc_pointer
9102 && expr->symtree->n.sym->attr.dummy)
9103 se.expr = build_fold_indirect_ref_loc (input_location, se.expr);
9105 gfc_add_modify (&block, dest,
9106 fold_convert (TREE_TYPE (dest), se.expr));
9107 gfc_add_block_to_block (&block, &se.post);
9110 else if (cm->ts.type == BT_CLASS && expr->expr_type == EXPR_NULL)
9112 /* NULL initialization for CLASS components. */
9113 tmp = gfc_trans_structure_assign (dest,
9114 gfc_class_initializer (&cm->ts, expr),
9115 false);
9116 gfc_add_expr_to_block (&block, tmp);
9118 else if ((cm->attr.dimension || cm->attr.codimension)
9119 && !cm->attr.proc_pointer)
9121 if (cm->attr.allocatable && expr->expr_type == EXPR_NULL)
9122 gfc_conv_descriptor_data_set (&block, dest, null_pointer_node);
9123 else if (cm->attr.allocatable || cm->attr.pdt_array)
9125 tmp = gfc_trans_alloc_subarray_assign (dest, cm, expr);
9126 gfc_add_expr_to_block (&block, tmp);
9128 else
9130 tmp = gfc_trans_subarray_assign (dest, cm, expr);
9131 gfc_add_expr_to_block (&block, tmp);
9134 else if (cm->ts.type == BT_CLASS
9135 && CLASS_DATA (cm)->attr.dimension
9136 && CLASS_DATA (cm)->attr.allocatable
9137 && expr->ts.type == BT_DERIVED)
9139 vtab = gfc_get_symbol_decl (gfc_find_vtab (&expr->ts));
9140 vtab = gfc_build_addr_expr (NULL_TREE, vtab);
9141 tmp = gfc_class_vptr_get (dest);
9142 gfc_add_modify (&block, tmp,
9143 fold_convert (TREE_TYPE (tmp), vtab));
9144 tmp = gfc_class_data_get (dest);
9145 tmp = gfc_trans_alloc_subarray_assign (tmp, cm, expr);
9146 gfc_add_expr_to_block (&block, tmp);
9148 else if (init && cm->attr.allocatable && expr->expr_type == EXPR_NULL)
9150 /* NULL initialization for allocatable components. */
9151 gfc_add_modify (&block, dest, fold_convert (TREE_TYPE (dest),
9152 null_pointer_node));
9154 else if (init && (cm->attr.allocatable
9155 || (cm->ts.type == BT_CLASS && CLASS_DATA (cm)->attr.allocatable
9156 && expr->ts.type != BT_CLASS)))
9158 gfc_init_se (&se, NULL);
9159 gfc_conv_expr (&se, expr);
9160 tree size;
9162 /* Take care about non-array allocatable components here. The alloc_*
9163 routine below is motivated by the alloc_scalar_allocatable_for_
9164 assignment() routine, but with the realloc portions removed and
9165 different input. */
9166 alloc_scalar_allocatable_subcomponent (&block, dest, cm, expr,
9167 se.string_length);
9168 /* The remainder of these instructions follow the if (cm->attr.pointer)
9169 if (!cm->attr.dimension) part above. */
9170 gfc_add_block_to_block (&block, &se.pre);
9172 if (expr->symtree && expr->symtree->n.sym->attr.proc_pointer
9173 && expr->symtree->n.sym->attr.dummy)
9174 se.expr = build_fold_indirect_ref_loc (input_location, se.expr);
9176 if (cm->ts.type == BT_CLASS)
9178 tmp = gfc_class_data_get (dest);
9179 tmp = build_fold_indirect_ref_loc (input_location, tmp);
9180 vtab = gfc_get_symbol_decl (gfc_find_vtab (&expr->ts));
9181 vtab = gfc_build_addr_expr (NULL_TREE, vtab);
9182 gfc_add_modify (&block, gfc_class_vptr_get (dest),
9183 fold_convert (TREE_TYPE (gfc_class_vptr_get (dest)), vtab));
9185 else
9186 tmp = build_fold_indirect_ref_loc (input_location, dest);
9188 /* For deferred strings insert a memcpy. */
9189 if (cm->ts.type == BT_CHARACTER && cm->ts.deferred)
9191 gcc_assert (se.string_length || expr->ts.u.cl->backend_decl);
9192 size = size_of_string_in_bytes (cm->ts.kind, se.string_length
9193 ? se.string_length
9194 : expr->ts.u.cl->backend_decl);
9195 tmp = gfc_build_memcpy_call (tmp, se.expr, size);
9196 gfc_add_expr_to_block (&block, tmp);
9198 else if (cm->ts.type == BT_CLASS)
9200 /* Fix the expression for memcpy. */
9201 if (expr->expr_type != EXPR_VARIABLE)
9202 se.expr = gfc_evaluate_now (se.expr, &block);
9204 if (expr->ts.type == BT_CHARACTER)
9206 size = build_int_cst (gfc_charlen_type_node, expr->ts.kind);
9207 size = fold_build2_loc (input_location, MULT_EXPR,
9208 gfc_charlen_type_node,
9209 se.string_length, size);
9210 size = fold_convert (size_type_node, size);
9212 else
9213 size = TYPE_SIZE_UNIT (gfc_typenode_for_spec (&expr->ts));
9215 /* Now copy the expression to the constructor component _data. */
9216 gfc_add_expr_to_block (&block,
9217 gfc_build_memcpy_call (tmp, se.expr, size));
9219 /* Fill the unlimited polymorphic _len field. */
9220 if (UNLIMITED_POLY (cm) && expr->ts.type == BT_CHARACTER)
9222 tmp = gfc_class_len_get (gfc_get_class_from_expr (tmp));
9223 gfc_add_modify (&block, tmp,
9224 fold_convert (TREE_TYPE (tmp),
9225 se.string_length));
9228 else
9229 gfc_add_modify (&block, tmp,
9230 fold_convert (TREE_TYPE (tmp), se.expr));
9231 gfc_add_block_to_block (&block, &se.post);
9233 else if (expr->ts.type == BT_UNION)
9235 tree tmp;
9236 gfc_constructor *c = gfc_constructor_first (expr->value.constructor);
9237 /* We mark that the entire union should be initialized with a contrived
9238 EXPR_NULL expression at the beginning. */
9239 if (c != NULL && c->n.component == NULL
9240 && c->expr != NULL && c->expr->expr_type == EXPR_NULL)
9242 tmp = build2_loc (input_location, MODIFY_EXPR, void_type_node,
9243 dest, build_constructor (TREE_TYPE (dest), NULL));
9244 gfc_add_expr_to_block (&block, tmp);
9245 c = gfc_constructor_next (c);
9247 /* The following constructor expression, if any, represents a specific
9248 map intializer, as given by the user. */
9249 if (c != NULL && c->expr != NULL)
9251 gcc_assert (expr->expr_type == EXPR_STRUCTURE);
9252 tmp = gfc_trans_structure_assign (dest, expr, expr->symtree != NULL);
9253 gfc_add_expr_to_block (&block, tmp);
9256 else if (expr->ts.type == BT_DERIVED && expr->ts.f90_type != BT_VOID)
9258 if (expr->expr_type != EXPR_STRUCTURE)
9260 tree dealloc = NULL_TREE;
9261 gfc_init_se (&se, NULL);
9262 gfc_conv_expr (&se, expr);
9263 gfc_add_block_to_block (&block, &se.pre);
9264 /* Prevent repeat evaluations in gfc_copy_alloc_comp by fixing the
9265 expression in a temporary variable and deallocate the allocatable
9266 components. Then we can the copy the expression to the result. */
9267 if (cm->ts.u.derived->attr.alloc_comp
9268 && expr->expr_type != EXPR_VARIABLE)
9270 se.expr = gfc_evaluate_now (se.expr, &block);
9271 dealloc = gfc_deallocate_alloc_comp (cm->ts.u.derived, se.expr,
9272 expr->rank);
9274 gfc_add_modify (&block, dest,
9275 fold_convert (TREE_TYPE (dest), se.expr));
9276 if (cm->ts.u.derived->attr.alloc_comp
9277 && expr->expr_type != EXPR_NULL)
9279 // TODO: Fix caf_mode
9280 tmp = gfc_copy_alloc_comp (cm->ts.u.derived, se.expr,
9281 dest, expr->rank, 0);
9282 gfc_add_expr_to_block (&block, tmp);
9283 if (dealloc != NULL_TREE)
9284 gfc_add_expr_to_block (&block, dealloc);
9286 gfc_add_block_to_block (&block, &se.post);
9288 else
9290 /* Nested constructors. */
9291 tmp = gfc_trans_structure_assign (dest, expr, expr->symtree != NULL);
9292 gfc_add_expr_to_block (&block, tmp);
9295 else if (gfc_deferred_strlen (cm, &tmp))
9297 tree strlen;
9298 strlen = tmp;
9299 gcc_assert (strlen);
9300 strlen = fold_build3_loc (input_location, COMPONENT_REF,
9301 TREE_TYPE (strlen),
9302 TREE_OPERAND (dest, 0),
9303 strlen, NULL_TREE);
9305 if (expr->expr_type == EXPR_NULL)
9307 tmp = build_int_cst (TREE_TYPE (cm->backend_decl), 0);
9308 gfc_add_modify (&block, dest, tmp);
9309 tmp = build_int_cst (TREE_TYPE (strlen), 0);
9310 gfc_add_modify (&block, strlen, tmp);
9312 else
9314 tree size;
9315 gfc_init_se (&se, NULL);
9316 gfc_conv_expr (&se, expr);
9317 size = size_of_string_in_bytes (cm->ts.kind, se.string_length);
9318 tmp = build_call_expr_loc (input_location,
9319 builtin_decl_explicit (BUILT_IN_MALLOC),
9320 1, size);
9321 gfc_add_modify (&block, dest,
9322 fold_convert (TREE_TYPE (dest), tmp));
9323 gfc_add_modify (&block, strlen,
9324 fold_convert (TREE_TYPE (strlen), se.string_length));
9325 tmp = gfc_build_memcpy_call (dest, se.expr, size);
9326 gfc_add_expr_to_block (&block, tmp);
9329 else if (!cm->attr.artificial)
9331 /* Scalar component (excluding deferred parameters). */
9332 gfc_init_se (&se, NULL);
9333 gfc_init_se (&lse, NULL);
9335 gfc_conv_expr (&se, expr);
9336 if (cm->ts.type == BT_CHARACTER)
9337 lse.string_length = cm->ts.u.cl->backend_decl;
9338 lse.expr = dest;
9339 tmp = gfc_trans_scalar_assign (&lse, &se, cm->ts, false, false);
9340 gfc_add_expr_to_block (&block, tmp);
9342 return gfc_finish_block (&block);
9345 /* Assign a derived type constructor to a variable. */
9347 tree
9348 gfc_trans_structure_assign (tree dest, gfc_expr * expr, bool init, bool coarray)
9350 gfc_constructor *c;
9351 gfc_component *cm;
9352 stmtblock_t block;
9353 tree field;
9354 tree tmp;
9355 gfc_se se;
9357 gfc_start_block (&block);
9359 if (expr->ts.u.derived->from_intmod == INTMOD_ISO_C_BINDING
9360 && (expr->ts.u.derived->intmod_sym_id == ISOCBINDING_PTR
9361 || expr->ts.u.derived->intmod_sym_id == ISOCBINDING_FUNPTR))
9363 gfc_se lse;
9365 gfc_init_se (&se, NULL);
9366 gfc_init_se (&lse, NULL);
9367 gfc_conv_expr (&se, gfc_constructor_first (expr->value.constructor)->expr);
9368 lse.expr = dest;
9369 gfc_add_modify (&block, lse.expr,
9370 fold_convert (TREE_TYPE (lse.expr), se.expr));
9372 return gfc_finish_block (&block);
9375 /* Make sure that the derived type has been completely built. */
9376 if (!expr->ts.u.derived->backend_decl
9377 || !TYPE_FIELDS (expr->ts.u.derived->backend_decl))
9379 tmp = gfc_typenode_for_spec (&expr->ts);
9380 gcc_assert (tmp);
9383 cm = expr->ts.u.derived->components;
9386 if (coarray)
9387 gfc_init_se (&se, NULL);
9389 for (c = gfc_constructor_first (expr->value.constructor);
9390 c; c = gfc_constructor_next (c), cm = cm->next)
9392 /* Skip absent members in default initializers. */
9393 if (!c->expr && !cm->attr.allocatable)
9394 continue;
9396 /* Register the component with the caf-lib before it is initialized.
9397 Register only allocatable components, that are not coarray'ed
9398 components (%comp[*]). Only register when the constructor is not the
9399 null-expression. */
9400 if (coarray && !cm->attr.codimension
9401 && (cm->attr.allocatable || cm->attr.pointer)
9402 && (!c->expr || c->expr->expr_type == EXPR_NULL))
9404 tree token, desc, size;
9405 bool is_array = cm->ts.type == BT_CLASS
9406 ? CLASS_DATA (cm)->attr.dimension : cm->attr.dimension;
9408 field = cm->backend_decl;
9409 field = fold_build3_loc (input_location, COMPONENT_REF,
9410 TREE_TYPE (field), dest, field, NULL_TREE);
9411 if (cm->ts.type == BT_CLASS)
9412 field = gfc_class_data_get (field);
9414 token = is_array ? gfc_conv_descriptor_token (field)
9415 : fold_build3_loc (input_location, COMPONENT_REF,
9416 TREE_TYPE (cm->caf_token), dest,
9417 cm->caf_token, NULL_TREE);
9419 if (is_array)
9421 /* The _caf_register routine looks at the rank of the array
9422 descriptor to decide whether the data registered is an array
9423 or not. */
9424 int rank = cm->ts.type == BT_CLASS ? CLASS_DATA (cm)->as->rank
9425 : cm->as->rank;
9426 /* When the rank is not known just set a positive rank, which
9427 suffices to recognize the data as array. */
9428 if (rank < 0)
9429 rank = 1;
9430 size = build_zero_cst (size_type_node);
9431 desc = field;
9432 gfc_add_modify (&block, gfc_conv_descriptor_rank (desc),
9433 build_int_cst (signed_char_type_node, rank));
9435 else
9437 desc = gfc_conv_scalar_to_descriptor (&se, field,
9438 cm->ts.type == BT_CLASS
9439 ? CLASS_DATA (cm)->attr
9440 : cm->attr);
9441 size = TYPE_SIZE_UNIT (TREE_TYPE (field));
9443 gfc_add_block_to_block (&block, &se.pre);
9444 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_register,
9445 7, size, build_int_cst (
9446 integer_type_node,
9447 GFC_CAF_COARRAY_ALLOC_REGISTER_ONLY),
9448 gfc_build_addr_expr (pvoid_type_node,
9449 token),
9450 gfc_build_addr_expr (NULL_TREE, desc),
9451 null_pointer_node, null_pointer_node,
9452 integer_zero_node);
9453 gfc_add_expr_to_block (&block, tmp);
9455 field = cm->backend_decl;
9456 gcc_assert(field);
9457 tmp = fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field),
9458 dest, field, NULL_TREE);
9459 if (!c->expr)
9461 gfc_expr *e = gfc_get_null_expr (NULL);
9462 tmp = gfc_trans_subcomponent_assign (tmp, cm, e, init);
9463 gfc_free_expr (e);
9465 else
9466 tmp = gfc_trans_subcomponent_assign (tmp, cm, c->expr, init);
9467 gfc_add_expr_to_block (&block, tmp);
9469 return gfc_finish_block (&block);
9472 static void
9473 gfc_conv_union_initializer (vec<constructor_elt, va_gc> *&v,
9474 gfc_component *un, gfc_expr *init)
9476 gfc_constructor *ctor;
9478 if (un->ts.type != BT_UNION || un == NULL || init == NULL)
9479 return;
9481 ctor = gfc_constructor_first (init->value.constructor);
9483 if (ctor == NULL || ctor->expr == NULL)
9484 return;
9486 gcc_assert (init->expr_type == EXPR_STRUCTURE);
9488 /* If we have an 'initialize all' constructor, do it first. */
9489 if (ctor->expr->expr_type == EXPR_NULL)
9491 tree union_type = TREE_TYPE (un->backend_decl);
9492 tree val = build_constructor (union_type, NULL);
9493 CONSTRUCTOR_APPEND_ELT (v, un->backend_decl, val);
9494 ctor = gfc_constructor_next (ctor);
9497 /* Add the map initializer on top. */
9498 if (ctor != NULL && ctor->expr != NULL)
9500 gcc_assert (ctor->expr->expr_type == EXPR_STRUCTURE);
9501 tree val = gfc_conv_initializer (ctor->expr, &un->ts,
9502 TREE_TYPE (un->backend_decl),
9503 un->attr.dimension, un->attr.pointer,
9504 un->attr.proc_pointer);
9505 CONSTRUCTOR_APPEND_ELT (v, un->backend_decl, val);
9509 /* Build an expression for a constructor. If init is nonzero then
9510 this is part of a static variable initializer. */
9512 void
9513 gfc_conv_structure (gfc_se * se, gfc_expr * expr, int init)
9515 gfc_constructor *c;
9516 gfc_component *cm;
9517 tree val;
9518 tree type;
9519 tree tmp;
9520 vec<constructor_elt, va_gc> *v = NULL;
9522 gcc_assert (se->ss == NULL);
9523 gcc_assert (expr->expr_type == EXPR_STRUCTURE);
9524 type = gfc_typenode_for_spec (&expr->ts);
9526 if (!init)
9528 /* Create a temporary variable and fill it in. */
9529 se->expr = gfc_create_var (type, expr->ts.u.derived->name);
9530 /* The symtree in expr is NULL, if the code to generate is for
9531 initializing the static members only. */
9532 tmp = gfc_trans_structure_assign (se->expr, expr, expr->symtree != NULL,
9533 se->want_coarray);
9534 gfc_add_expr_to_block (&se->pre, tmp);
9535 return;
9538 cm = expr->ts.u.derived->components;
9540 for (c = gfc_constructor_first (expr->value.constructor);
9541 c; c = gfc_constructor_next (c), cm = cm->next)
9543 /* Skip absent members in default initializers and allocatable
9544 components. Although the latter have a default initializer
9545 of EXPR_NULL,... by default, the static nullify is not needed
9546 since this is done every time we come into scope. */
9547 if (!c->expr || (cm->attr.allocatable && cm->attr.flavor != FL_PROCEDURE))
9548 continue;
9550 if (cm->initializer && cm->initializer->expr_type != EXPR_NULL
9551 && strcmp (cm->name, "_extends") == 0
9552 && cm->initializer->symtree)
9554 tree vtab;
9555 gfc_symbol *vtabs;
9556 vtabs = cm->initializer->symtree->n.sym;
9557 vtab = gfc_build_addr_expr (NULL_TREE, gfc_get_symbol_decl (vtabs));
9558 vtab = unshare_expr_without_location (vtab);
9559 CONSTRUCTOR_APPEND_ELT (v, cm->backend_decl, vtab);
9561 else if (cm->ts.u.derived && strcmp (cm->name, "_size") == 0)
9563 val = TYPE_SIZE_UNIT (gfc_get_derived_type (cm->ts.u.derived));
9564 CONSTRUCTOR_APPEND_ELT (v, cm->backend_decl,
9565 fold_convert (TREE_TYPE (cm->backend_decl),
9566 val));
9568 else if (cm->ts.type == BT_INTEGER && strcmp (cm->name, "_len") == 0)
9569 CONSTRUCTOR_APPEND_ELT (v, cm->backend_decl,
9570 fold_convert (TREE_TYPE (cm->backend_decl),
9571 integer_zero_node));
9572 else if (cm->ts.type == BT_UNION)
9573 gfc_conv_union_initializer (v, cm, c->expr);
9574 else
9576 val = gfc_conv_initializer (c->expr, &cm->ts,
9577 TREE_TYPE (cm->backend_decl),
9578 cm->attr.dimension, cm->attr.pointer,
9579 cm->attr.proc_pointer);
9580 val = unshare_expr_without_location (val);
9582 /* Append it to the constructor list. */
9583 CONSTRUCTOR_APPEND_ELT (v, cm->backend_decl, val);
9587 se->expr = build_constructor (type, v);
9588 if (init)
9589 TREE_CONSTANT (se->expr) = 1;
9593 /* Translate a substring expression. */
9595 static void
9596 gfc_conv_substring_expr (gfc_se * se, gfc_expr * expr)
9598 gfc_ref *ref;
9600 ref = expr->ref;
9602 gcc_assert (ref == NULL || ref->type == REF_SUBSTRING);
9604 se->expr = gfc_build_wide_string_const (expr->ts.kind,
9605 expr->value.character.length,
9606 expr->value.character.string);
9608 se->string_length = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (se->expr)));
9609 TYPE_STRING_FLAG (TREE_TYPE (se->expr)) = 1;
9611 if (ref)
9612 gfc_conv_substring (se, ref, expr->ts.kind, NULL, &expr->where);
9616 /* Entry point for expression translation. Evaluates a scalar quantity.
9617 EXPR is the expression to be translated, and SE is the state structure if
9618 called from within the scalarized. */
9620 void
9621 gfc_conv_expr (gfc_se * se, gfc_expr * expr)
9623 gfc_ss *ss;
9625 ss = se->ss;
9626 if (ss && ss->info->expr == expr
9627 && (ss->info->type == GFC_SS_SCALAR
9628 || ss->info->type == GFC_SS_REFERENCE))
9630 gfc_ss_info *ss_info;
9632 ss_info = ss->info;
9633 /* Substitute a scalar expression evaluated outside the scalarization
9634 loop. */
9635 se->expr = ss_info->data.scalar.value;
9636 if (gfc_scalar_elemental_arg_saved_as_reference (ss_info))
9637 se->expr = build_fold_indirect_ref_loc (input_location, se->expr);
9639 se->string_length = ss_info->string_length;
9640 gfc_advance_se_ss_chain (se);
9641 return;
9644 /* We need to convert the expressions for the iso_c_binding derived types.
9645 C_NULL_PTR and C_NULL_FUNPTR will be made EXPR_NULL, which evaluates to
9646 null_pointer_node. C_PTR and C_FUNPTR are converted to match the
9647 typespec for the C_PTR and C_FUNPTR symbols, which has already been
9648 updated to be an integer with a kind equal to the size of a (void *). */
9649 if (expr->ts.type == BT_DERIVED && expr->ts.u.derived->ts.f90_type == BT_VOID
9650 && expr->ts.u.derived->attr.is_bind_c)
9652 if (expr->expr_type == EXPR_VARIABLE
9653 && (expr->symtree->n.sym->intmod_sym_id == ISOCBINDING_NULL_PTR
9654 || expr->symtree->n.sym->intmod_sym_id
9655 == ISOCBINDING_NULL_FUNPTR))
9657 /* Set expr_type to EXPR_NULL, which will result in
9658 null_pointer_node being used below. */
9659 expr->expr_type = EXPR_NULL;
9661 else
9663 /* Update the type/kind of the expression to be what the new
9664 type/kind are for the updated symbols of C_PTR/C_FUNPTR. */
9665 expr->ts.type = BT_INTEGER;
9666 expr->ts.f90_type = BT_VOID;
9667 expr->ts.kind = gfc_index_integer_kind;
9671 gfc_fix_class_refs (expr);
9673 switch (expr->expr_type)
9675 case EXPR_OP:
9676 gfc_conv_expr_op (se, expr);
9677 break;
9679 case EXPR_FUNCTION:
9680 gfc_conv_function_expr (se, expr);
9681 break;
9683 case EXPR_CONSTANT:
9684 gfc_conv_constant (se, expr);
9685 break;
9687 case EXPR_VARIABLE:
9688 gfc_conv_variable (se, expr);
9689 break;
9691 case EXPR_NULL:
9692 se->expr = null_pointer_node;
9693 break;
9695 case EXPR_SUBSTRING:
9696 gfc_conv_substring_expr (se, expr);
9697 break;
9699 case EXPR_STRUCTURE:
9700 gfc_conv_structure (se, expr, 0);
9701 /* F2008 4.5.6.3 para 5: If an executable construct references a
9702 structure constructor or array constructor, the entity created by
9703 the constructor is finalized after execution of the innermost
9704 executable construct containing the reference. This, in fact,
9705 was later deleted by the Combined Techical Corrigenda 1 TO 4 for
9706 fortran 2008 (f08/0011). */
9707 if (!gfc_notification_std (GFC_STD_F2018_DEL) && expr->must_finalize
9708 && gfc_may_be_finalized (expr->ts))
9710 gfc_warning (0, "The structure constructor at %C has been"
9711 " finalized. This feature was removed by f08/0011."
9712 " Use -std=f2018 or -std=gnu to eliminate the"
9713 " finalization.");
9714 symbol_attribute attr;
9715 attr.allocatable = attr.pointer = 0;
9716 gfc_finalize_tree_expr (se, expr->ts.u.derived, attr, 0);
9717 gfc_add_block_to_block (&se->post, &se->finalblock);
9719 break;
9721 case EXPR_ARRAY:
9722 gfc_conv_array_constructor_expr (se, expr);
9723 gfc_add_block_to_block (&se->post, &se->finalblock);
9724 break;
9726 default:
9727 gcc_unreachable ();
9728 break;
9732 /* Like gfc_conv_expr_val, but the value is also suitable for use in the lhs
9733 of an assignment. */
9734 void
9735 gfc_conv_expr_lhs (gfc_se * se, gfc_expr * expr)
9737 gfc_conv_expr (se, expr);
9738 /* All numeric lvalues should have empty post chains. If not we need to
9739 figure out a way of rewriting an lvalue so that it has no post chain. */
9740 gcc_assert (expr->ts.type == BT_CHARACTER || !se->post.head);
9743 /* Like gfc_conv_expr, but the POST block is guaranteed to be empty for
9744 numeric expressions. Used for scalar values where inserting cleanup code
9745 is inconvenient. */
9746 void
9747 gfc_conv_expr_val (gfc_se * se, gfc_expr * expr)
9749 tree val;
9751 gcc_assert (expr->ts.type != BT_CHARACTER);
9752 gfc_conv_expr (se, expr);
9753 if (se->post.head)
9755 val = gfc_create_var (TREE_TYPE (se->expr), NULL);
9756 gfc_add_modify (&se->pre, val, se->expr);
9757 se->expr = val;
9758 gfc_add_block_to_block (&se->pre, &se->post);
9762 /* Helper to translate an expression and convert it to a particular type. */
9763 void
9764 gfc_conv_expr_type (gfc_se * se, gfc_expr * expr, tree type)
9766 gfc_conv_expr_val (se, expr);
9767 se->expr = convert (type, se->expr);
9771 /* Converts an expression so that it can be passed by reference. Scalar
9772 values only. */
9774 void
9775 gfc_conv_expr_reference (gfc_se * se, gfc_expr * expr)
9777 gfc_ss *ss;
9778 tree var;
9780 ss = se->ss;
9781 if (ss && ss->info->expr == expr
9782 && ss->info->type == GFC_SS_REFERENCE)
9784 /* Returns a reference to the scalar evaluated outside the loop
9785 for this case. */
9786 gfc_conv_expr (se, expr);
9788 if (expr->ts.type == BT_CHARACTER
9789 && expr->expr_type != EXPR_FUNCTION)
9790 gfc_conv_string_parameter (se);
9791 else
9792 se->expr = gfc_build_addr_expr (NULL_TREE, se->expr);
9794 return;
9797 if (expr->ts.type == BT_CHARACTER)
9799 gfc_conv_expr (se, expr);
9800 gfc_conv_string_parameter (se);
9801 return;
9804 if (expr->expr_type == EXPR_VARIABLE)
9806 se->want_pointer = 1;
9807 gfc_conv_expr (se, expr);
9808 if (se->post.head)
9810 var = gfc_create_var (TREE_TYPE (se->expr), NULL);
9811 gfc_add_modify (&se->pre, var, se->expr);
9812 gfc_add_block_to_block (&se->pre, &se->post);
9813 se->expr = var;
9815 return;
9818 if (expr->expr_type == EXPR_FUNCTION
9819 && ((expr->value.function.esym
9820 && expr->value.function.esym->result
9821 && expr->value.function.esym->result->attr.pointer
9822 && !expr->value.function.esym->result->attr.dimension)
9823 || (!expr->value.function.esym && !expr->ref
9824 && expr->symtree->n.sym->attr.pointer
9825 && !expr->symtree->n.sym->attr.dimension)))
9827 se->want_pointer = 1;
9828 gfc_conv_expr (se, expr);
9829 var = gfc_create_var (TREE_TYPE (se->expr), NULL);
9830 gfc_add_modify (&se->pre, var, se->expr);
9831 se->expr = var;
9832 return;
9835 gfc_conv_expr (se, expr);
9837 /* Create a temporary var to hold the value. */
9838 if (TREE_CONSTANT (se->expr))
9840 tree tmp = se->expr;
9841 STRIP_TYPE_NOPS (tmp);
9842 var = build_decl (input_location,
9843 CONST_DECL, NULL, TREE_TYPE (tmp));
9844 DECL_INITIAL (var) = tmp;
9845 TREE_STATIC (var) = 1;
9846 pushdecl (var);
9848 else
9850 var = gfc_create_var (TREE_TYPE (se->expr), NULL);
9851 gfc_add_modify (&se->pre, var, se->expr);
9854 if (!expr->must_finalize)
9855 gfc_add_block_to_block (&se->pre, &se->post);
9857 /* Take the address of that value. */
9858 se->expr = gfc_build_addr_expr (NULL_TREE, var);
9862 /* Get the _len component for an unlimited polymorphic expression. */
9864 static tree
9865 trans_get_upoly_len (stmtblock_t *block, gfc_expr *expr)
9867 gfc_se se;
9868 gfc_ref *ref = expr->ref;
9870 gfc_init_se (&se, NULL);
9871 while (ref && ref->next)
9872 ref = ref->next;
9873 gfc_add_len_component (expr);
9874 gfc_conv_expr (&se, expr);
9875 gfc_add_block_to_block (block, &se.pre);
9876 gcc_assert (se.post.head == NULL_TREE);
9877 if (ref)
9879 gfc_free_ref_list (ref->next);
9880 ref->next = NULL;
9882 else
9884 gfc_free_ref_list (expr->ref);
9885 expr->ref = NULL;
9887 return se.expr;
9891 /* Assign _vptr and _len components as appropriate. BLOCK should be a
9892 statement-list outside of the scalarizer-loop. When code is generated, that
9893 depends on the scalarized expression, it is added to RSE.PRE.
9894 Returns le's _vptr tree and when set the len expressions in to_lenp and
9895 from_lenp to form a le%_vptr%_copy (re, le, [from_lenp, to_lenp])
9896 expression. */
9898 static tree
9899 trans_class_vptr_len_assignment (stmtblock_t *block, gfc_expr * le,
9900 gfc_expr * re, gfc_se *rse,
9901 tree * to_lenp, tree * from_lenp)
9903 gfc_se se;
9904 gfc_expr * vptr_expr;
9905 tree tmp, to_len = NULL_TREE, from_len = NULL_TREE, lhs_vptr;
9906 bool set_vptr = false, temp_rhs = false;
9907 stmtblock_t *pre = block;
9908 tree class_expr = NULL_TREE;
9910 /* Create a temporary for complicated expressions. */
9911 if (re->expr_type != EXPR_VARIABLE && re->expr_type != EXPR_NULL
9912 && rse->expr != NULL_TREE && !DECL_P (rse->expr))
9914 if (re->ts.type == BT_CLASS && !GFC_CLASS_TYPE_P (TREE_TYPE (rse->expr)))
9915 class_expr = gfc_get_class_from_expr (rse->expr);
9917 if (rse->loop)
9918 pre = &rse->loop->pre;
9919 else
9920 pre = &rse->pre;
9922 if (class_expr != NULL_TREE && UNLIMITED_POLY (re))
9924 tmp = TREE_OPERAND (rse->expr, 0);
9925 tmp = gfc_create_var (TREE_TYPE (tmp), "rhs");
9926 gfc_add_modify (&rse->pre, tmp, TREE_OPERAND (rse->expr, 0));
9928 else
9930 tmp = gfc_create_var (TREE_TYPE (rse->expr), "rhs");
9931 gfc_add_modify (&rse->pre, tmp, rse->expr);
9934 rse->expr = tmp;
9935 temp_rhs = true;
9938 /* Get the _vptr for the left-hand side expression. */
9939 gfc_init_se (&se, NULL);
9940 vptr_expr = gfc_find_and_cut_at_last_class_ref (le);
9941 if (vptr_expr != NULL && gfc_expr_attr (vptr_expr).class_ok)
9943 /* Care about _len for unlimited polymorphic entities. */
9944 if (UNLIMITED_POLY (vptr_expr)
9945 || (vptr_expr->ts.type == BT_DERIVED
9946 && vptr_expr->ts.u.derived->attr.unlimited_polymorphic))
9947 to_len = trans_get_upoly_len (block, vptr_expr);
9948 gfc_add_vptr_component (vptr_expr);
9949 set_vptr = true;
9951 else
9952 vptr_expr = gfc_lval_expr_from_sym (gfc_find_vtab (&le->ts));
9953 se.want_pointer = 1;
9954 gfc_conv_expr (&se, vptr_expr);
9955 gfc_free_expr (vptr_expr);
9956 gfc_add_block_to_block (block, &se.pre);
9957 gcc_assert (se.post.head == NULL_TREE);
9958 lhs_vptr = se.expr;
9959 STRIP_NOPS (lhs_vptr);
9961 /* Set the _vptr only when the left-hand side of the assignment is a
9962 class-object. */
9963 if (set_vptr)
9965 /* Get the vptr from the rhs expression only, when it is variable.
9966 Functions are expected to be assigned to a temporary beforehand. */
9967 vptr_expr = (re->expr_type == EXPR_VARIABLE && re->ts.type == BT_CLASS)
9968 ? gfc_find_and_cut_at_last_class_ref (re)
9969 : NULL;
9970 if (vptr_expr != NULL && vptr_expr->ts.type == BT_CLASS)
9972 if (to_len != NULL_TREE)
9974 /* Get the _len information from the rhs. */
9975 if (UNLIMITED_POLY (vptr_expr)
9976 || (vptr_expr->ts.type == BT_DERIVED
9977 && vptr_expr->ts.u.derived->attr.unlimited_polymorphic))
9978 from_len = trans_get_upoly_len (block, vptr_expr);
9980 gfc_add_vptr_component (vptr_expr);
9982 else
9984 if (re->expr_type == EXPR_VARIABLE
9985 && DECL_P (re->symtree->n.sym->backend_decl)
9986 && DECL_LANG_SPECIFIC (re->symtree->n.sym->backend_decl)
9987 && GFC_DECL_SAVED_DESCRIPTOR (re->symtree->n.sym->backend_decl)
9988 && GFC_CLASS_TYPE_P (TREE_TYPE (GFC_DECL_SAVED_DESCRIPTOR (
9989 re->symtree->n.sym->backend_decl))))
9991 vptr_expr = NULL;
9992 se.expr = gfc_class_vptr_get (GFC_DECL_SAVED_DESCRIPTOR (
9993 re->symtree->n.sym->backend_decl));
9994 if (to_len)
9995 from_len = gfc_class_len_get (GFC_DECL_SAVED_DESCRIPTOR (
9996 re->symtree->n.sym->backend_decl));
9998 else if (temp_rhs && re->ts.type == BT_CLASS)
10000 vptr_expr = NULL;
10001 if (class_expr)
10002 tmp = class_expr;
10003 else if (!GFC_CLASS_TYPE_P (TREE_TYPE (rse->expr)))
10004 tmp = gfc_get_class_from_expr (rse->expr);
10005 else
10006 tmp = rse->expr;
10008 se.expr = gfc_class_vptr_get (tmp);
10009 if (UNLIMITED_POLY (re))
10010 from_len = gfc_class_len_get (tmp);
10013 else if (re->expr_type != EXPR_NULL)
10014 /* Only when rhs is non-NULL use its declared type for vptr
10015 initialisation. */
10016 vptr_expr = gfc_lval_expr_from_sym (gfc_find_vtab (&re->ts));
10017 else
10018 /* When the rhs is NULL use the vtab of lhs' declared type. */
10019 vptr_expr = gfc_lval_expr_from_sym (gfc_find_vtab (&le->ts));
10022 if (vptr_expr)
10024 gfc_init_se (&se, NULL);
10025 se.want_pointer = 1;
10026 gfc_conv_expr (&se, vptr_expr);
10027 gfc_free_expr (vptr_expr);
10028 gfc_add_block_to_block (block, &se.pre);
10029 gcc_assert (se.post.head == NULL_TREE);
10031 gfc_add_modify (pre, lhs_vptr, fold_convert (TREE_TYPE (lhs_vptr),
10032 se.expr));
10034 if (to_len != NULL_TREE)
10036 /* The _len component needs to be set. Figure how to get the
10037 value of the right-hand side. */
10038 if (from_len == NULL_TREE)
10040 if (rse->string_length != NULL_TREE)
10041 from_len = rse->string_length;
10042 else if (re->ts.type == BT_CHARACTER && re->ts.u.cl->length)
10044 gfc_init_se (&se, NULL);
10045 gfc_conv_expr (&se, re->ts.u.cl->length);
10046 gfc_add_block_to_block (block, &se.pre);
10047 gcc_assert (se.post.head == NULL_TREE);
10048 from_len = gfc_evaluate_now (se.expr, block);
10050 else
10051 from_len = build_zero_cst (gfc_charlen_type_node);
10053 gfc_add_modify (pre, to_len, fold_convert (TREE_TYPE (to_len),
10054 from_len));
10058 /* Return the _len trees only, when requested. */
10059 if (to_lenp)
10060 *to_lenp = to_len;
10061 if (from_lenp)
10062 *from_lenp = from_len;
10063 return lhs_vptr;
10067 /* Assign tokens for pointer components. */
10069 static void
10070 trans_caf_token_assign (gfc_se *lse, gfc_se *rse, gfc_expr *expr1,
10071 gfc_expr *expr2)
10073 symbol_attribute lhs_attr, rhs_attr;
10074 tree tmp, lhs_tok, rhs_tok;
10075 /* Flag to indicated component refs on the rhs. */
10076 bool rhs_cr;
10078 lhs_attr = gfc_caf_attr (expr1);
10079 if (expr2->expr_type != EXPR_NULL)
10081 rhs_attr = gfc_caf_attr (expr2, false, &rhs_cr);
10082 if (lhs_attr.codimension && rhs_attr.codimension)
10084 lhs_tok = gfc_get_ultimate_alloc_ptr_comps_caf_token (lse, expr1);
10085 lhs_tok = build_fold_indirect_ref (lhs_tok);
10087 if (rhs_cr)
10088 rhs_tok = gfc_get_ultimate_alloc_ptr_comps_caf_token (rse, expr2);
10089 else
10091 tree caf_decl;
10092 caf_decl = gfc_get_tree_for_caf_expr (expr2);
10093 gfc_get_caf_token_offset (rse, &rhs_tok, NULL, caf_decl,
10094 NULL_TREE, NULL);
10096 tmp = build2_loc (input_location, MODIFY_EXPR, void_type_node,
10097 lhs_tok,
10098 fold_convert (TREE_TYPE (lhs_tok), rhs_tok));
10099 gfc_prepend_expr_to_block (&lse->post, tmp);
10102 else if (lhs_attr.codimension)
10104 lhs_tok = gfc_get_ultimate_alloc_ptr_comps_caf_token (lse, expr1);
10105 lhs_tok = build_fold_indirect_ref (lhs_tok);
10106 tmp = build2_loc (input_location, MODIFY_EXPR, void_type_node,
10107 lhs_tok, null_pointer_node);
10108 gfc_prepend_expr_to_block (&lse->post, tmp);
10113 /* Do everything that is needed for a CLASS function expr2. */
10115 static tree
10116 trans_class_pointer_fcn (stmtblock_t *block, gfc_se *lse, gfc_se *rse,
10117 gfc_expr *expr1, gfc_expr *expr2)
10119 tree expr1_vptr = NULL_TREE;
10120 tree tmp;
10122 gfc_conv_function_expr (rse, expr2);
10123 rse->expr = gfc_evaluate_now (rse->expr, &rse->pre);
10125 if (expr1->ts.type != BT_CLASS)
10126 rse->expr = gfc_class_data_get (rse->expr);
10127 else
10129 expr1_vptr = trans_class_vptr_len_assignment (block, expr1,
10130 expr2, rse,
10131 NULL, NULL);
10132 gfc_add_block_to_block (block, &rse->pre);
10133 tmp = gfc_create_var (TREE_TYPE (rse->expr), "ptrtemp");
10134 gfc_add_modify (&lse->pre, tmp, rse->expr);
10136 gfc_add_modify (&lse->pre, expr1_vptr,
10137 fold_convert (TREE_TYPE (expr1_vptr),
10138 gfc_class_vptr_get (tmp)));
10139 rse->expr = gfc_class_data_get (tmp);
10142 return expr1_vptr;
10146 tree
10147 gfc_trans_pointer_assign (gfc_code * code)
10149 return gfc_trans_pointer_assignment (code->expr1, code->expr2);
10153 /* Generate code for a pointer assignment. */
10155 tree
10156 gfc_trans_pointer_assignment (gfc_expr * expr1, gfc_expr * expr2)
10158 gfc_se lse;
10159 gfc_se rse;
10160 stmtblock_t block;
10161 tree desc;
10162 tree tmp;
10163 tree expr1_vptr = NULL_TREE;
10164 bool scalar, non_proc_ptr_assign;
10165 gfc_ss *ss;
10167 gfc_start_block (&block);
10169 gfc_init_se (&lse, NULL);
10171 /* Usually testing whether this is not a proc pointer assignment. */
10172 non_proc_ptr_assign = !(gfc_expr_attr (expr1).proc_pointer
10173 && expr2->expr_type == EXPR_VARIABLE
10174 && expr2->symtree->n.sym->attr.flavor == FL_PROCEDURE);
10176 /* Check whether the expression is a scalar or not; we cannot use
10177 expr1->rank as it can be nonzero for proc pointers. */
10178 ss = gfc_walk_expr (expr1);
10179 scalar = ss == gfc_ss_terminator;
10180 if (!scalar)
10181 gfc_free_ss_chain (ss);
10183 if (expr1->ts.type == BT_DERIVED && expr2->ts.type == BT_CLASS
10184 && expr2->expr_type != EXPR_FUNCTION && non_proc_ptr_assign)
10186 gfc_add_data_component (expr2);
10187 /* The following is required as gfc_add_data_component doesn't
10188 update ts.type if there is a trailing REF_ARRAY. */
10189 expr2->ts.type = BT_DERIVED;
10192 if (scalar)
10194 /* Scalar pointers. */
10195 lse.want_pointer = 1;
10196 gfc_conv_expr (&lse, expr1);
10197 gfc_init_se (&rse, NULL);
10198 rse.want_pointer = 1;
10199 if (expr2->expr_type == EXPR_FUNCTION && expr2->ts.type == BT_CLASS)
10200 trans_class_pointer_fcn (&block, &lse, &rse, expr1, expr2);
10201 else
10202 gfc_conv_expr (&rse, expr2);
10204 if (non_proc_ptr_assign && expr1->ts.type == BT_CLASS)
10206 trans_class_vptr_len_assignment (&block, expr1, expr2, &rse, NULL,
10207 NULL);
10208 lse.expr = gfc_class_data_get (lse.expr);
10211 if (expr1->symtree->n.sym->attr.proc_pointer
10212 && expr1->symtree->n.sym->attr.dummy)
10213 lse.expr = build_fold_indirect_ref_loc (input_location,
10214 lse.expr);
10216 if (expr2->symtree && expr2->symtree->n.sym->attr.proc_pointer
10217 && expr2->symtree->n.sym->attr.dummy)
10218 rse.expr = build_fold_indirect_ref_loc (input_location,
10219 rse.expr);
10221 gfc_add_block_to_block (&block, &lse.pre);
10222 gfc_add_block_to_block (&block, &rse.pre);
10224 /* Check character lengths if character expression. The test is only
10225 really added if -fbounds-check is enabled. Exclude deferred
10226 character length lefthand sides. */
10227 if (expr1->ts.type == BT_CHARACTER && expr2->expr_type != EXPR_NULL
10228 && !expr1->ts.deferred
10229 && !expr1->symtree->n.sym->attr.proc_pointer
10230 && !gfc_is_proc_ptr_comp (expr1))
10232 gcc_assert (expr2->ts.type == BT_CHARACTER);
10233 gcc_assert (lse.string_length && rse.string_length);
10234 gfc_trans_same_strlen_check ("pointer assignment", &expr1->where,
10235 lse.string_length, rse.string_length,
10236 &block);
10239 /* The assignment to an deferred character length sets the string
10240 length to that of the rhs. */
10241 if (expr1->ts.deferred)
10243 if (expr2->expr_type != EXPR_NULL && lse.string_length != NULL)
10244 gfc_add_modify (&block, lse.string_length,
10245 fold_convert (TREE_TYPE (lse.string_length),
10246 rse.string_length));
10247 else if (lse.string_length != NULL)
10248 gfc_add_modify (&block, lse.string_length,
10249 build_zero_cst (TREE_TYPE (lse.string_length)));
10252 gfc_add_modify (&block, lse.expr,
10253 fold_convert (TREE_TYPE (lse.expr), rse.expr));
10255 /* Also set the tokens for pointer components in derived typed
10256 coarrays. */
10257 if (flag_coarray == GFC_FCOARRAY_LIB)
10258 trans_caf_token_assign (&lse, &rse, expr1, expr2);
10260 gfc_add_block_to_block (&block, &rse.post);
10261 gfc_add_block_to_block (&block, &lse.post);
10263 else
10265 gfc_ref* remap;
10266 bool rank_remap;
10267 tree strlen_lhs;
10268 tree strlen_rhs = NULL_TREE;
10270 /* Array pointer. Find the last reference on the LHS and if it is an
10271 array section ref, we're dealing with bounds remapping. In this case,
10272 set it to AR_FULL so that gfc_conv_expr_descriptor does
10273 not see it and process the bounds remapping afterwards explicitly. */
10274 for (remap = expr1->ref; remap; remap = remap->next)
10275 if (!remap->next && remap->type == REF_ARRAY
10276 && remap->u.ar.type == AR_SECTION)
10277 break;
10278 rank_remap = (remap && remap->u.ar.end[0]);
10280 if (remap && expr2->expr_type == EXPR_NULL)
10282 gfc_error ("If bounds remapping is specified at %L, "
10283 "the pointer target shall not be NULL", &expr1->where);
10284 return NULL_TREE;
10287 gfc_init_se (&lse, NULL);
10288 if (remap)
10289 lse.descriptor_only = 1;
10290 gfc_conv_expr_descriptor (&lse, expr1);
10291 strlen_lhs = lse.string_length;
10292 desc = lse.expr;
10294 if (expr2->expr_type == EXPR_NULL)
10296 /* Just set the data pointer to null. */
10297 gfc_conv_descriptor_data_set (&lse.pre, lse.expr, null_pointer_node);
10299 else if (rank_remap)
10301 /* If we are rank-remapping, just get the RHS's descriptor and
10302 process this later on. */
10303 gfc_init_se (&rse, NULL);
10304 rse.direct_byref = 1;
10305 rse.byref_noassign = 1;
10307 if (expr2->expr_type == EXPR_FUNCTION && expr2->ts.type == BT_CLASS)
10308 expr1_vptr = trans_class_pointer_fcn (&block, &lse, &rse,
10309 expr1, expr2);
10310 else if (expr2->expr_type == EXPR_FUNCTION)
10312 tree bound[GFC_MAX_DIMENSIONS];
10313 int i;
10315 for (i = 0; i < expr2->rank; i++)
10316 bound[i] = NULL_TREE;
10317 tmp = gfc_typenode_for_spec (&expr2->ts);
10318 tmp = gfc_get_array_type_bounds (tmp, expr2->rank, 0,
10319 bound, bound, 0,
10320 GFC_ARRAY_POINTER_CONT, false);
10321 tmp = gfc_create_var (tmp, "ptrtemp");
10322 rse.descriptor_only = 0;
10323 rse.expr = tmp;
10324 rse.direct_byref = 1;
10325 gfc_conv_expr_descriptor (&rse, expr2);
10326 strlen_rhs = rse.string_length;
10327 rse.expr = tmp;
10329 else
10331 gfc_conv_expr_descriptor (&rse, expr2);
10332 strlen_rhs = rse.string_length;
10333 if (expr1->ts.type == BT_CLASS)
10334 expr1_vptr = trans_class_vptr_len_assignment (&block, expr1,
10335 expr2, &rse,
10336 NULL, NULL);
10339 else if (expr2->expr_type == EXPR_VARIABLE)
10341 /* Assign directly to the LHS's descriptor. */
10342 lse.descriptor_only = 0;
10343 lse.direct_byref = 1;
10344 gfc_conv_expr_descriptor (&lse, expr2);
10345 strlen_rhs = lse.string_length;
10346 gfc_init_se (&rse, NULL);
10348 if (expr1->ts.type == BT_CLASS)
10350 rse.expr = NULL_TREE;
10351 rse.string_length = strlen_rhs;
10352 trans_class_vptr_len_assignment (&block, expr1, expr2, &rse,
10353 NULL, NULL);
10356 if (remap == NULL)
10358 /* If the target is not a whole array, use the target array
10359 reference for remap. */
10360 for (remap = expr2->ref; remap; remap = remap->next)
10361 if (remap->type == REF_ARRAY
10362 && remap->u.ar.type == AR_FULL
10363 && remap->next)
10364 break;
10367 else if (expr2->expr_type == EXPR_FUNCTION && expr2->ts.type == BT_CLASS)
10369 gfc_init_se (&rse, NULL);
10370 rse.want_pointer = 1;
10371 gfc_conv_function_expr (&rse, expr2);
10372 if (expr1->ts.type != BT_CLASS)
10374 rse.expr = gfc_class_data_get (rse.expr);
10375 gfc_add_modify (&lse.pre, desc, rse.expr);
10376 /* Set the lhs span. */
10377 tmp = TREE_TYPE (rse.expr);
10378 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (tmp));
10379 tmp = fold_convert (gfc_array_index_type, tmp);
10380 gfc_conv_descriptor_span_set (&lse.pre, desc, tmp);
10382 else
10384 expr1_vptr = trans_class_vptr_len_assignment (&block, expr1,
10385 expr2, &rse, NULL,
10386 NULL);
10387 gfc_add_block_to_block (&block, &rse.pre);
10388 tmp = gfc_create_var (TREE_TYPE (rse.expr), "ptrtemp");
10389 gfc_add_modify (&lse.pre, tmp, rse.expr);
10391 gfc_add_modify (&lse.pre, expr1_vptr,
10392 fold_convert (TREE_TYPE (expr1_vptr),
10393 gfc_class_vptr_get (tmp)));
10394 rse.expr = gfc_class_data_get (tmp);
10395 gfc_add_modify (&lse.pre, desc, rse.expr);
10398 else
10400 /* Assign to a temporary descriptor and then copy that
10401 temporary to the pointer. */
10402 tmp = gfc_create_var (TREE_TYPE (desc), "ptrtemp");
10403 lse.descriptor_only = 0;
10404 lse.expr = tmp;
10405 lse.direct_byref = 1;
10406 gfc_conv_expr_descriptor (&lse, expr2);
10407 strlen_rhs = lse.string_length;
10408 gfc_add_modify (&lse.pre, desc, tmp);
10411 if (expr1->ts.type == BT_CHARACTER
10412 && expr1->symtree->n.sym->ts.deferred
10413 && expr1->symtree->n.sym->ts.u.cl->backend_decl
10414 && VAR_P (expr1->symtree->n.sym->ts.u.cl->backend_decl))
10416 tmp = expr1->symtree->n.sym->ts.u.cl->backend_decl;
10417 if (expr2->expr_type != EXPR_NULL)
10418 gfc_add_modify (&block, tmp,
10419 fold_convert (TREE_TYPE (tmp), strlen_rhs));
10420 else
10421 gfc_add_modify (&block, tmp, build_zero_cst (TREE_TYPE (tmp)));
10424 gfc_add_block_to_block (&block, &lse.pre);
10425 if (rank_remap)
10426 gfc_add_block_to_block (&block, &rse.pre);
10428 /* If we do bounds remapping, update LHS descriptor accordingly. */
10429 if (remap)
10431 int dim;
10432 gcc_assert (remap->u.ar.dimen == expr1->rank);
10434 if (rank_remap)
10436 /* Do rank remapping. We already have the RHS's descriptor
10437 converted in rse and now have to build the correct LHS
10438 descriptor for it. */
10440 tree dtype, data, span;
10441 tree offs, stride;
10442 tree lbound, ubound;
10444 /* Set dtype. */
10445 dtype = gfc_conv_descriptor_dtype (desc);
10446 tmp = gfc_get_dtype (TREE_TYPE (desc));
10447 gfc_add_modify (&block, dtype, tmp);
10449 /* Copy data pointer. */
10450 data = gfc_conv_descriptor_data_get (rse.expr);
10451 gfc_conv_descriptor_data_set (&block, desc, data);
10453 /* Copy the span. */
10454 if (VAR_P (rse.expr)
10455 && GFC_DECL_PTR_ARRAY_P (rse.expr))
10456 span = gfc_conv_descriptor_span_get (rse.expr);
10457 else
10459 tmp = TREE_TYPE (rse.expr);
10460 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (tmp));
10461 span = fold_convert (gfc_array_index_type, tmp);
10463 gfc_conv_descriptor_span_set (&block, desc, span);
10465 /* Copy offset but adjust it such that it would correspond
10466 to a lbound of zero. */
10467 offs = gfc_conv_descriptor_offset_get (rse.expr);
10468 for (dim = 0; dim < expr2->rank; ++dim)
10470 stride = gfc_conv_descriptor_stride_get (rse.expr,
10471 gfc_rank_cst[dim]);
10472 lbound = gfc_conv_descriptor_lbound_get (rse.expr,
10473 gfc_rank_cst[dim]);
10474 tmp = fold_build2_loc (input_location, MULT_EXPR,
10475 gfc_array_index_type, stride, lbound);
10476 offs = fold_build2_loc (input_location, PLUS_EXPR,
10477 gfc_array_index_type, offs, tmp);
10479 gfc_conv_descriptor_offset_set (&block, desc, offs);
10481 /* Set the bounds as declared for the LHS and calculate strides as
10482 well as another offset update accordingly. */
10483 stride = gfc_conv_descriptor_stride_get (rse.expr,
10484 gfc_rank_cst[0]);
10485 for (dim = 0; dim < expr1->rank; ++dim)
10487 gfc_se lower_se;
10488 gfc_se upper_se;
10490 gcc_assert (remap->u.ar.start[dim] && remap->u.ar.end[dim]);
10492 /* Convert declared bounds. */
10493 gfc_init_se (&lower_se, NULL);
10494 gfc_init_se (&upper_se, NULL);
10495 gfc_conv_expr (&lower_se, remap->u.ar.start[dim]);
10496 gfc_conv_expr (&upper_se, remap->u.ar.end[dim]);
10498 gfc_add_block_to_block (&block, &lower_se.pre);
10499 gfc_add_block_to_block (&block, &upper_se.pre);
10501 lbound = fold_convert (gfc_array_index_type, lower_se.expr);
10502 ubound = fold_convert (gfc_array_index_type, upper_se.expr);
10504 lbound = gfc_evaluate_now (lbound, &block);
10505 ubound = gfc_evaluate_now (ubound, &block);
10507 gfc_add_block_to_block (&block, &lower_se.post);
10508 gfc_add_block_to_block (&block, &upper_se.post);
10510 /* Set bounds in descriptor. */
10511 gfc_conv_descriptor_lbound_set (&block, desc,
10512 gfc_rank_cst[dim], lbound);
10513 gfc_conv_descriptor_ubound_set (&block, desc,
10514 gfc_rank_cst[dim], ubound);
10516 /* Set stride. */
10517 stride = gfc_evaluate_now (stride, &block);
10518 gfc_conv_descriptor_stride_set (&block, desc,
10519 gfc_rank_cst[dim], stride);
10521 /* Update offset. */
10522 offs = gfc_conv_descriptor_offset_get (desc);
10523 tmp = fold_build2_loc (input_location, MULT_EXPR,
10524 gfc_array_index_type, lbound, stride);
10525 offs = fold_build2_loc (input_location, MINUS_EXPR,
10526 gfc_array_index_type, offs, tmp);
10527 offs = gfc_evaluate_now (offs, &block);
10528 gfc_conv_descriptor_offset_set (&block, desc, offs);
10530 /* Update stride. */
10531 tmp = gfc_conv_array_extent_dim (lbound, ubound, NULL);
10532 stride = fold_build2_loc (input_location, MULT_EXPR,
10533 gfc_array_index_type, stride, tmp);
10536 else
10538 /* Bounds remapping. Just shift the lower bounds. */
10540 gcc_assert (expr1->rank == expr2->rank);
10542 for (dim = 0; dim < remap->u.ar.dimen; ++dim)
10544 gfc_se lbound_se;
10546 gcc_assert (!remap->u.ar.end[dim]);
10547 gfc_init_se (&lbound_se, NULL);
10548 if (remap->u.ar.start[dim])
10550 gfc_conv_expr (&lbound_se, remap->u.ar.start[dim]);
10551 gfc_add_block_to_block (&block, &lbound_se.pre);
10553 else
10554 /* This remap arises from a target that is not a whole
10555 array. The start expressions will be NULL but we need
10556 the lbounds to be one. */
10557 lbound_se.expr = gfc_index_one_node;
10558 gfc_conv_shift_descriptor_lbound (&block, desc,
10559 dim, lbound_se.expr);
10560 gfc_add_block_to_block (&block, &lbound_se.post);
10565 /* If rank remapping was done, check with -fcheck=bounds that
10566 the target is at least as large as the pointer. */
10567 if (rank_remap && (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS))
10569 tree lsize, rsize;
10570 tree fault;
10571 const char* msg;
10573 lsize = gfc_conv_descriptor_size (lse.expr, expr1->rank);
10574 rsize = gfc_conv_descriptor_size (rse.expr, expr2->rank);
10576 lsize = gfc_evaluate_now (lsize, &block);
10577 rsize = gfc_evaluate_now (rsize, &block);
10578 fault = fold_build2_loc (input_location, LT_EXPR, logical_type_node,
10579 rsize, lsize);
10581 msg = _("Target of rank remapping is too small (%ld < %ld)");
10582 gfc_trans_runtime_check (true, false, fault, &block, &expr2->where,
10583 msg, rsize, lsize);
10586 /* Check string lengths if applicable. The check is only really added
10587 to the output code if -fbounds-check is enabled. */
10588 if (expr1->ts.type == BT_CHARACTER && expr2->expr_type != EXPR_NULL)
10590 gcc_assert (expr2->ts.type == BT_CHARACTER);
10591 gcc_assert (strlen_lhs && strlen_rhs);
10592 gfc_trans_same_strlen_check ("pointer assignment", &expr1->where,
10593 strlen_lhs, strlen_rhs, &block);
10596 gfc_add_block_to_block (&block, &lse.post);
10597 if (rank_remap)
10598 gfc_add_block_to_block (&block, &rse.post);
10601 return gfc_finish_block (&block);
10605 /* Makes sure se is suitable for passing as a function string parameter. */
10606 /* TODO: Need to check all callers of this function. It may be abused. */
10608 void
10609 gfc_conv_string_parameter (gfc_se * se)
10611 tree type;
10613 if (TREE_CODE (TREE_TYPE (se->expr)) == INTEGER_TYPE
10614 && integer_onep (se->string_length))
10616 se->expr = gfc_build_addr_expr (NULL_TREE, se->expr);
10617 return;
10620 if (TREE_CODE (se->expr) == STRING_CST)
10622 type = TREE_TYPE (TREE_TYPE (se->expr));
10623 se->expr = gfc_build_addr_expr (build_pointer_type (type), se->expr);
10624 return;
10627 if ((TREE_CODE (TREE_TYPE (se->expr)) == ARRAY_TYPE
10628 || TREE_CODE (TREE_TYPE (se->expr)) == INTEGER_TYPE)
10629 && TYPE_STRING_FLAG (TREE_TYPE (se->expr)))
10631 type = TREE_TYPE (se->expr);
10632 if (TREE_CODE (se->expr) != INDIRECT_REF)
10633 se->expr = gfc_build_addr_expr (build_pointer_type (type), se->expr);
10634 else
10636 if (TREE_CODE (type) == ARRAY_TYPE)
10637 type = TREE_TYPE (type);
10638 type = gfc_get_character_type_len_for_eltype (type,
10639 se->string_length);
10640 type = build_pointer_type (type);
10641 se->expr = gfc_build_addr_expr (type, se->expr);
10645 gcc_assert (POINTER_TYPE_P (TREE_TYPE (se->expr)));
10649 /* Generate code for assignment of scalar variables. Includes character
10650 strings and derived types with allocatable components.
10651 If you know that the LHS has no allocations, set dealloc to false.
10653 DEEP_COPY has no effect if the typespec TS is not a derived type with
10654 allocatable components. Otherwise, if it is set, an explicit copy of each
10655 allocatable component is made. This is necessary as a simple copy of the
10656 whole object would copy array descriptors as is, so that the lhs's
10657 allocatable components would point to the rhs's after the assignment.
10658 Typically, setting DEEP_COPY is necessary if the rhs is a variable, and not
10659 necessary if the rhs is a non-pointer function, as the allocatable components
10660 are not accessible by other means than the function's result after the
10661 function has returned. It is even more subtle when temporaries are involved,
10662 as the two following examples show:
10663 1. When we evaluate an array constructor, a temporary is created. Thus
10664 there is theoretically no alias possible. However, no deep copy is
10665 made for this temporary, so that if the constructor is made of one or
10666 more variable with allocatable components, those components still point
10667 to the variable's: DEEP_COPY should be set for the assignment from the
10668 temporary to the lhs in that case.
10669 2. When assigning a scalar to an array, we evaluate the scalar value out
10670 of the loop, store it into a temporary variable, and assign from that.
10671 In that case, deep copying when assigning to the temporary would be a
10672 waste of resources; however deep copies should happen when assigning from
10673 the temporary to each array element: again DEEP_COPY should be set for
10674 the assignment from the temporary to the lhs. */
10676 tree
10677 gfc_trans_scalar_assign (gfc_se * lse, gfc_se * rse, gfc_typespec ts,
10678 bool deep_copy, bool dealloc, bool in_coarray)
10680 stmtblock_t block;
10681 tree tmp;
10682 tree cond;
10684 gfc_init_block (&block);
10686 if (ts.type == BT_CHARACTER)
10688 tree rlen = NULL;
10689 tree llen = NULL;
10691 if (lse->string_length != NULL_TREE)
10693 gfc_conv_string_parameter (lse);
10694 gfc_add_block_to_block (&block, &lse->pre);
10695 llen = lse->string_length;
10698 if (rse->string_length != NULL_TREE)
10700 gfc_conv_string_parameter (rse);
10701 gfc_add_block_to_block (&block, &rse->pre);
10702 rlen = rse->string_length;
10705 gfc_trans_string_copy (&block, llen, lse->expr, ts.kind, rlen,
10706 rse->expr, ts.kind);
10708 else if (gfc_bt_struct (ts.type)
10709 && (ts.u.derived->attr.alloc_comp
10710 || (deep_copy && ts.u.derived->attr.pdt_type)))
10712 tree tmp_var = NULL_TREE;
10713 cond = NULL_TREE;
10715 /* Are the rhs and the lhs the same? */
10716 if (deep_copy)
10718 cond = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
10719 gfc_build_addr_expr (NULL_TREE, lse->expr),
10720 gfc_build_addr_expr (NULL_TREE, rse->expr));
10721 cond = gfc_evaluate_now (cond, &lse->pre);
10724 /* Deallocate the lhs allocated components as long as it is not
10725 the same as the rhs. This must be done following the assignment
10726 to prevent deallocating data that could be used in the rhs
10727 expression. */
10728 if (dealloc)
10730 tmp_var = gfc_evaluate_now (lse->expr, &lse->pre);
10731 tmp = gfc_deallocate_alloc_comp_no_caf (ts.u.derived, tmp_var,
10732 0, true);
10733 if (deep_copy)
10734 tmp = build3_v (COND_EXPR, cond, build_empty_stmt (input_location),
10735 tmp);
10736 gfc_add_expr_to_block (&lse->post, tmp);
10739 gfc_add_block_to_block (&block, &rse->pre);
10740 gfc_add_block_to_block (&block, &lse->finalblock);
10741 gfc_add_block_to_block (&block, &lse->pre);
10743 gfc_add_modify (&block, lse->expr,
10744 fold_convert (TREE_TYPE (lse->expr), rse->expr));
10746 /* Restore pointer address of coarray components. */
10747 if (ts.u.derived->attr.coarray_comp && deep_copy && tmp_var != NULL_TREE)
10749 tmp = gfc_reassign_alloc_comp_caf (ts.u.derived, tmp_var, lse->expr);
10750 tmp = build3_v (COND_EXPR, cond, build_empty_stmt (input_location),
10751 tmp);
10752 gfc_add_expr_to_block (&block, tmp);
10755 /* Do a deep copy if the rhs is a variable, if it is not the
10756 same as the lhs. */
10757 if (deep_copy)
10759 int caf_mode = in_coarray ? (GFC_STRUCTURE_CAF_MODE_ENABLE_COARRAY
10760 | GFC_STRUCTURE_CAF_MODE_IN_COARRAY) : 0;
10761 tmp = gfc_copy_alloc_comp (ts.u.derived, rse->expr, lse->expr, 0,
10762 caf_mode);
10763 tmp = build3_v (COND_EXPR, cond, build_empty_stmt (input_location),
10764 tmp);
10765 gfc_add_expr_to_block (&block, tmp);
10768 else if (gfc_bt_struct (ts.type))
10770 gfc_add_block_to_block (&block, &rse->pre);
10771 gfc_add_block_to_block (&block, &lse->finalblock);
10772 gfc_add_block_to_block (&block, &lse->pre);
10773 tmp = fold_build1_loc (input_location, VIEW_CONVERT_EXPR,
10774 TREE_TYPE (lse->expr), rse->expr);
10775 gfc_add_modify (&block, lse->expr, tmp);
10777 /* If possible use the rhs vptr copy with trans_scalar_class_assign.... */
10778 else if (ts.type == BT_CLASS)
10780 gfc_add_block_to_block (&block, &lse->pre);
10781 gfc_add_block_to_block (&block, &rse->pre);
10782 gfc_add_block_to_block (&block, &lse->finalblock);
10784 if (!trans_scalar_class_assign (&block, lse, rse))
10786 /* ...otherwise assignment suffices. Note the use of VIEW_CONVERT_EXPR
10787 for the lhs which ensures that class data rhs cast as a string assigns
10788 correctly. */
10789 tmp = fold_build1_loc (input_location, VIEW_CONVERT_EXPR,
10790 TREE_TYPE (rse->expr), lse->expr);
10791 gfc_add_modify (&block, tmp, rse->expr);
10794 else if (ts.type != BT_CLASS)
10796 gfc_add_block_to_block (&block, &lse->pre);
10797 gfc_add_block_to_block (&block, &rse->pre);
10799 gfc_add_modify (&block, lse->expr,
10800 fold_convert (TREE_TYPE (lse->expr), rse->expr));
10803 gfc_add_block_to_block (&block, &lse->post);
10804 gfc_add_block_to_block (&block, &rse->post);
10806 return gfc_finish_block (&block);
10810 /* There are quite a lot of restrictions on the optimisation in using an
10811 array function assign without a temporary. */
10813 static bool
10814 arrayfunc_assign_needs_temporary (gfc_expr * expr1, gfc_expr * expr2)
10816 gfc_ref * ref;
10817 bool seen_array_ref;
10818 bool c = false;
10819 gfc_symbol *sym = expr1->symtree->n.sym;
10821 /* Play it safe with class functions assigned to a derived type. */
10822 if (gfc_is_class_array_function (expr2)
10823 && expr1->ts.type == BT_DERIVED)
10824 return true;
10826 /* The caller has already checked rank>0 and expr_type == EXPR_FUNCTION. */
10827 if (expr2->value.function.isym && !gfc_is_intrinsic_libcall (expr2))
10828 return true;
10830 /* Elemental functions are scalarized so that they don't need a
10831 temporary in gfc_trans_assignment_1, so return a true. Otherwise,
10832 they would need special treatment in gfc_trans_arrayfunc_assign. */
10833 if (expr2->value.function.esym != NULL
10834 && expr2->value.function.esym->attr.elemental)
10835 return true;
10837 /* Need a temporary if rhs is not FULL or a contiguous section. */
10838 if (expr1->ref && !(gfc_full_array_ref_p (expr1->ref, &c) || c))
10839 return true;
10841 /* Need a temporary if EXPR1 can't be expressed as a descriptor. */
10842 if (gfc_ref_needs_temporary_p (expr1->ref))
10843 return true;
10845 /* Functions returning pointers or allocatables need temporaries. */
10846 if (gfc_expr_attr (expr2).pointer
10847 || gfc_expr_attr (expr2).allocatable)
10848 return true;
10850 /* Character array functions need temporaries unless the
10851 character lengths are the same. */
10852 if (expr2->ts.type == BT_CHARACTER && expr2->rank > 0)
10854 if (expr1->ts.u.cl->length == NULL
10855 || expr1->ts.u.cl->length->expr_type != EXPR_CONSTANT)
10856 return true;
10858 if (expr2->ts.u.cl->length == NULL
10859 || expr2->ts.u.cl->length->expr_type != EXPR_CONSTANT)
10860 return true;
10862 if (mpz_cmp (expr1->ts.u.cl->length->value.integer,
10863 expr2->ts.u.cl->length->value.integer) != 0)
10864 return true;
10867 /* Check that no LHS component references appear during an array
10868 reference. This is needed because we do not have the means to
10869 span any arbitrary stride with an array descriptor. This check
10870 is not needed for the rhs because the function result has to be
10871 a complete type. */
10872 seen_array_ref = false;
10873 for (ref = expr1->ref; ref; ref = ref->next)
10875 if (ref->type == REF_ARRAY)
10876 seen_array_ref= true;
10877 else if (ref->type == REF_COMPONENT && seen_array_ref)
10878 return true;
10881 /* Check for a dependency. */
10882 if (gfc_check_fncall_dependency (expr1, INTENT_OUT,
10883 expr2->value.function.esym,
10884 expr2->value.function.actual,
10885 NOT_ELEMENTAL))
10886 return true;
10888 /* If we have reached here with an intrinsic function, we do not
10889 need a temporary except in the particular case that reallocation
10890 on assignment is active and the lhs is allocatable and a target,
10891 or a pointer which may be a subref pointer. FIXME: The last
10892 condition can go away when we use span in the intrinsics
10893 directly.*/
10894 if (expr2->value.function.isym)
10895 return (flag_realloc_lhs && sym->attr.allocatable && sym->attr.target)
10896 || (sym->attr.pointer && sym->attr.subref_array_pointer);
10898 /* If the LHS is a dummy, we need a temporary if it is not
10899 INTENT(OUT). */
10900 if (sym->attr.dummy && sym->attr.intent != INTENT_OUT)
10901 return true;
10903 /* If the lhs has been host_associated, is in common, a pointer or is
10904 a target and the function is not using a RESULT variable, aliasing
10905 can occur and a temporary is needed. */
10906 if ((sym->attr.host_assoc
10907 || sym->attr.in_common
10908 || sym->attr.pointer
10909 || sym->attr.cray_pointee
10910 || sym->attr.target)
10911 && expr2->symtree != NULL
10912 && expr2->symtree->n.sym == expr2->symtree->n.sym->result)
10913 return true;
10915 /* A PURE function can unconditionally be called without a temporary. */
10916 if (expr2->value.function.esym != NULL
10917 && expr2->value.function.esym->attr.pure)
10918 return false;
10920 /* Implicit_pure functions are those which could legally be declared
10921 to be PURE. */
10922 if (expr2->value.function.esym != NULL
10923 && expr2->value.function.esym->attr.implicit_pure)
10924 return false;
10926 if (!sym->attr.use_assoc
10927 && !sym->attr.in_common
10928 && !sym->attr.pointer
10929 && !sym->attr.target
10930 && !sym->attr.cray_pointee
10931 && expr2->value.function.esym)
10933 /* A temporary is not needed if the function is not contained and
10934 the variable is local or host associated and not a pointer or
10935 a target. */
10936 if (!expr2->value.function.esym->attr.contained)
10937 return false;
10939 /* A temporary is not needed if the lhs has never been host
10940 associated and the procedure is contained. */
10941 else if (!sym->attr.host_assoc)
10942 return false;
10944 /* A temporary is not needed if the variable is local and not
10945 a pointer, a target or a result. */
10946 if (sym->ns->parent
10947 && expr2->value.function.esym->ns == sym->ns->parent)
10948 return false;
10951 /* Default to temporary use. */
10952 return true;
10956 /* Provide the loop info so that the lhs descriptor can be built for
10957 reallocatable assignments from extrinsic function calls. */
10959 static void
10960 realloc_lhs_loop_for_fcn_call (gfc_se *se, locus *where, gfc_ss **ss,
10961 gfc_loopinfo *loop)
10963 /* Signal that the function call should not be made by
10964 gfc_conv_loop_setup. */
10965 se->ss->is_alloc_lhs = 1;
10966 gfc_init_loopinfo (loop);
10967 gfc_add_ss_to_loop (loop, *ss);
10968 gfc_add_ss_to_loop (loop, se->ss);
10969 gfc_conv_ss_startstride (loop);
10970 gfc_conv_loop_setup (loop, where);
10971 gfc_copy_loopinfo_to_se (se, loop);
10972 gfc_add_block_to_block (&se->pre, &loop->pre);
10973 gfc_add_block_to_block (&se->pre, &loop->post);
10974 se->ss->is_alloc_lhs = 0;
10978 /* For assignment to a reallocatable lhs from intrinsic functions,
10979 replace the se.expr (ie. the result) with a temporary descriptor.
10980 Null the data field so that the library allocates space for the
10981 result. Free the data of the original descriptor after the function,
10982 in case it appears in an argument expression and transfer the
10983 result to the original descriptor. */
10985 static void
10986 fcncall_realloc_result (gfc_se *se, int rank)
10988 tree desc;
10989 tree res_desc;
10990 tree tmp;
10991 tree offset;
10992 tree zero_cond;
10993 tree not_same_shape;
10994 stmtblock_t shape_block;
10995 int n;
10997 /* Use the allocation done by the library. Substitute the lhs
10998 descriptor with a copy, whose data field is nulled.*/
10999 desc = build_fold_indirect_ref_loc (input_location, se->expr);
11000 if (POINTER_TYPE_P (TREE_TYPE (desc)))
11001 desc = build_fold_indirect_ref_loc (input_location, desc);
11003 /* Unallocated, the descriptor does not have a dtype. */
11004 tmp = gfc_conv_descriptor_dtype (desc);
11005 gfc_add_modify (&se->pre, tmp, gfc_get_dtype (TREE_TYPE (desc)));
11007 res_desc = gfc_evaluate_now (desc, &se->pre);
11008 gfc_conv_descriptor_data_set (&se->pre, res_desc, null_pointer_node);
11009 se->expr = gfc_build_addr_expr (NULL_TREE, res_desc);
11011 /* Free the lhs after the function call and copy the result data to
11012 the lhs descriptor. */
11013 tmp = gfc_conv_descriptor_data_get (desc);
11014 zero_cond = fold_build2_loc (input_location, EQ_EXPR,
11015 logical_type_node, tmp,
11016 build_int_cst (TREE_TYPE (tmp), 0));
11017 zero_cond = gfc_evaluate_now (zero_cond, &se->post);
11018 tmp = gfc_call_free (tmp);
11019 gfc_add_expr_to_block (&se->post, tmp);
11021 tmp = gfc_conv_descriptor_data_get (res_desc);
11022 gfc_conv_descriptor_data_set (&se->post, desc, tmp);
11024 /* Check that the shapes are the same between lhs and expression.
11025 The evaluation of the shape is done in 'shape_block' to avoid
11026 unitialized warnings from the lhs bounds. */
11027 not_same_shape = boolean_false_node;
11028 gfc_start_block (&shape_block);
11029 for (n = 0 ; n < rank; n++)
11031 tree tmp1;
11032 tmp = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[n]);
11033 tmp1 = gfc_conv_descriptor_lbound_get (res_desc, gfc_rank_cst[n]);
11034 tmp = fold_build2_loc (input_location, MINUS_EXPR,
11035 gfc_array_index_type, tmp, tmp1);
11036 tmp1 = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[n]);
11037 tmp = fold_build2_loc (input_location, MINUS_EXPR,
11038 gfc_array_index_type, tmp, tmp1);
11039 tmp1 = gfc_conv_descriptor_ubound_get (res_desc, gfc_rank_cst[n]);
11040 tmp = fold_build2_loc (input_location, PLUS_EXPR,
11041 gfc_array_index_type, tmp, tmp1);
11042 tmp = fold_build2_loc (input_location, NE_EXPR,
11043 logical_type_node, tmp,
11044 gfc_index_zero_node);
11045 tmp = gfc_evaluate_now (tmp, &shape_block);
11046 if (n == 0)
11047 not_same_shape = tmp;
11048 else
11049 not_same_shape = fold_build2_loc (input_location, TRUTH_OR_EXPR,
11050 logical_type_node, tmp,
11051 not_same_shape);
11054 /* 'zero_cond' being true is equal to lhs not being allocated or the
11055 shapes being different. */
11056 tmp = fold_build2_loc (input_location, TRUTH_OR_EXPR, logical_type_node,
11057 zero_cond, not_same_shape);
11058 gfc_add_modify (&shape_block, zero_cond, tmp);
11059 tmp = gfc_finish_block (&shape_block);
11060 tmp = build3_v (COND_EXPR, zero_cond,
11061 build_empty_stmt (input_location), tmp);
11062 gfc_add_expr_to_block (&se->post, tmp);
11064 /* Now reset the bounds returned from the function call to bounds based
11065 on the lhs lbounds, except where the lhs is not allocated or the shapes
11066 of 'variable and 'expr' are different. Set the offset accordingly. */
11067 offset = gfc_index_zero_node;
11068 for (n = 0 ; n < rank; n++)
11070 tree lbound;
11072 lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[n]);
11073 lbound = fold_build3_loc (input_location, COND_EXPR,
11074 gfc_array_index_type, zero_cond,
11075 gfc_index_one_node, lbound);
11076 lbound = gfc_evaluate_now (lbound, &se->post);
11078 tmp = gfc_conv_descriptor_ubound_get (res_desc, gfc_rank_cst[n]);
11079 tmp = fold_build2_loc (input_location, PLUS_EXPR,
11080 gfc_array_index_type, tmp, lbound);
11081 gfc_conv_descriptor_lbound_set (&se->post, desc,
11082 gfc_rank_cst[n], lbound);
11083 gfc_conv_descriptor_ubound_set (&se->post, desc,
11084 gfc_rank_cst[n], tmp);
11086 /* Set stride and accumulate the offset. */
11087 tmp = gfc_conv_descriptor_stride_get (res_desc, gfc_rank_cst[n]);
11088 gfc_conv_descriptor_stride_set (&se->post, desc,
11089 gfc_rank_cst[n], tmp);
11090 tmp = fold_build2_loc (input_location, MULT_EXPR,
11091 gfc_array_index_type, lbound, tmp);
11092 offset = fold_build2_loc (input_location, MINUS_EXPR,
11093 gfc_array_index_type, offset, tmp);
11094 offset = gfc_evaluate_now (offset, &se->post);
11097 gfc_conv_descriptor_offset_set (&se->post, desc, offset);
11102 /* Try to translate array(:) = func (...), where func is a transformational
11103 array function, without using a temporary. Returns NULL if this isn't the
11104 case. */
11106 static tree
11107 gfc_trans_arrayfunc_assign (gfc_expr * expr1, gfc_expr * expr2)
11109 gfc_se se;
11110 gfc_ss *ss = NULL;
11111 gfc_component *comp = NULL;
11112 gfc_loopinfo loop;
11113 tree tmp;
11114 tree lhs;
11115 gfc_se final_se;
11116 gfc_symbol *sym = expr1->symtree->n.sym;
11117 bool finalizable = gfc_may_be_finalized (expr1->ts);
11119 if (arrayfunc_assign_needs_temporary (expr1, expr2))
11120 return NULL;
11122 /* The frontend doesn't seem to bother filling in expr->symtree for intrinsic
11123 functions. */
11124 comp = gfc_get_proc_ptr_comp (expr2);
11126 if (!(expr2->value.function.isym
11127 || (comp && comp->attr.dimension)
11128 || (!comp && gfc_return_by_reference (expr2->value.function.esym)
11129 && expr2->value.function.esym->result->attr.dimension)))
11130 return NULL;
11132 gfc_init_se (&se, NULL);
11133 gfc_start_block (&se.pre);
11134 se.want_pointer = 1;
11136 /* First the lhs must be finalized, if necessary. We use a copy of the symbol
11137 backend decl, stash the original away for the finalization so that the
11138 value used is that before the assignment. This is necessary because
11139 evaluation of the rhs expression using direct by reference can change
11140 the value. However, the standard mandates that the finalization must occur
11141 after evaluation of the rhs. */
11142 gfc_init_se (&final_se, NULL);
11144 if (finalizable)
11146 tmp = sym->backend_decl;
11147 lhs = sym->backend_decl;
11148 if (INDIRECT_REF_P (tmp))
11149 tmp = TREE_OPERAND (tmp, 0);
11150 sym->backend_decl = gfc_create_var (TREE_TYPE (tmp), "lhs");
11151 gfc_add_modify (&se.pre, sym->backend_decl, tmp);
11152 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp)))
11154 tmp = gfc_copy_alloc_comp (expr1->ts.u.derived, tmp, sym->backend_decl,
11155 expr1->rank, 0);
11156 gfc_add_expr_to_block (&final_se.pre, tmp);
11160 if (finalizable && gfc_assignment_finalizer_call (&final_se, expr1, false))
11162 gfc_add_block_to_block (&se.pre, &final_se.pre);
11163 gfc_add_block_to_block (&se.post, &final_se.finalblock);
11166 if (finalizable)
11167 sym->backend_decl = lhs;
11169 gfc_conv_array_parameter (&se, expr1, false, NULL, NULL, NULL);
11171 if (expr1->ts.type == BT_DERIVED
11172 && expr1->ts.u.derived->attr.alloc_comp)
11174 tmp = build_fold_indirect_ref_loc (input_location, se.expr);
11175 tmp = gfc_deallocate_alloc_comp_no_caf (expr1->ts.u.derived, tmp,
11176 expr1->rank);
11177 gfc_add_expr_to_block (&se.pre, tmp);
11180 se.direct_byref = 1;
11181 se.ss = gfc_walk_expr (expr2);
11182 gcc_assert (se.ss != gfc_ss_terminator);
11184 /* Since this is a direct by reference call, references to the lhs can be
11185 used for finalization of the function result just as long as the blocks
11186 from final_se are added at the right time. */
11187 gfc_init_se (&final_se, NULL);
11188 if (finalizable && expr2->value.function.esym)
11190 final_se.expr = build_fold_indirect_ref_loc (input_location, se.expr);
11191 gfc_finalize_tree_expr (&final_se, expr2->ts.u.derived,
11192 expr2->value.function.esym->attr,
11193 expr2->rank);
11196 /* Reallocate on assignment needs the loopinfo for extrinsic functions.
11197 This is signalled to gfc_conv_procedure_call by setting is_alloc_lhs.
11198 Clearly, this cannot be done for an allocatable function result, since
11199 the shape of the result is unknown and, in any case, the function must
11200 correctly take care of the reallocation internally. For intrinsic
11201 calls, the array data is freed and the library takes care of allocation.
11202 TODO: Add logic of trans-array.cc: gfc_alloc_allocatable_for_assignment
11203 to the library. */
11204 if (flag_realloc_lhs
11205 && gfc_is_reallocatable_lhs (expr1)
11206 && !gfc_expr_attr (expr1).codimension
11207 && !gfc_is_coindexed (expr1)
11208 && !(expr2->value.function.esym
11209 && expr2->value.function.esym->result->attr.allocatable))
11211 realloc_lhs_warning (expr1->ts.type, true, &expr1->where);
11213 if (!expr2->value.function.isym)
11215 ss = gfc_walk_expr (expr1);
11216 gcc_assert (ss != gfc_ss_terminator);
11218 realloc_lhs_loop_for_fcn_call (&se, &expr1->where, &ss, &loop);
11219 ss->is_alloc_lhs = 1;
11221 else
11222 fcncall_realloc_result (&se, expr1->rank);
11225 gfc_conv_function_expr (&se, expr2);
11227 /* Fix the result. */
11228 gfc_add_block_to_block (&se.pre, &se.post);
11229 if (finalizable)
11230 gfc_add_block_to_block (&se.pre, &final_se.pre);
11232 /* Do the finalization, including final calls from function arguments. */
11233 if (finalizable)
11235 gfc_add_block_to_block (&se.pre, &final_se.post);
11236 gfc_add_block_to_block (&se.pre, &se.finalblock);
11237 gfc_add_block_to_block (&se.pre, &final_se.finalblock);
11240 if (ss)
11241 gfc_cleanup_loop (&loop);
11242 else
11243 gfc_free_ss_chain (se.ss);
11245 return gfc_finish_block (&se.pre);
11249 /* Try to efficiently translate array(:) = 0. Return NULL if this
11250 can't be done. */
11252 static tree
11253 gfc_trans_zero_assign (gfc_expr * expr)
11255 tree dest, len, type;
11256 tree tmp;
11257 gfc_symbol *sym;
11259 sym = expr->symtree->n.sym;
11260 dest = gfc_get_symbol_decl (sym);
11262 type = TREE_TYPE (dest);
11263 if (POINTER_TYPE_P (type))
11264 type = TREE_TYPE (type);
11265 if (!GFC_ARRAY_TYPE_P (type))
11266 return NULL_TREE;
11268 /* Determine the length of the array. */
11269 len = GFC_TYPE_ARRAY_SIZE (type);
11270 if (!len || TREE_CODE (len) != INTEGER_CST)
11271 return NULL_TREE;
11273 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type));
11274 len = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type, len,
11275 fold_convert (gfc_array_index_type, tmp));
11277 /* If we are zeroing a local array avoid taking its address by emitting
11278 a = {} instead. */
11279 if (!POINTER_TYPE_P (TREE_TYPE (dest)))
11280 return build2_loc (input_location, MODIFY_EXPR, void_type_node,
11281 dest, build_constructor (TREE_TYPE (dest),
11282 NULL));
11284 /* Convert arguments to the correct types. */
11285 dest = fold_convert (pvoid_type_node, dest);
11286 len = fold_convert (size_type_node, len);
11288 /* Construct call to __builtin_memset. */
11289 tmp = build_call_expr_loc (input_location,
11290 builtin_decl_explicit (BUILT_IN_MEMSET),
11291 3, dest, integer_zero_node, len);
11292 return fold_convert (void_type_node, tmp);
11296 /* Helper for gfc_trans_array_copy and gfc_trans_array_constructor_copy
11297 that constructs the call to __builtin_memcpy. */
11299 tree
11300 gfc_build_memcpy_call (tree dst, tree src, tree len)
11302 tree tmp;
11304 /* Convert arguments to the correct types. */
11305 if (!POINTER_TYPE_P (TREE_TYPE (dst)))
11306 dst = gfc_build_addr_expr (pvoid_type_node, dst);
11307 else
11308 dst = fold_convert (pvoid_type_node, dst);
11310 if (!POINTER_TYPE_P (TREE_TYPE (src)))
11311 src = gfc_build_addr_expr (pvoid_type_node, src);
11312 else
11313 src = fold_convert (pvoid_type_node, src);
11315 len = fold_convert (size_type_node, len);
11317 /* Construct call to __builtin_memcpy. */
11318 tmp = build_call_expr_loc (input_location,
11319 builtin_decl_explicit (BUILT_IN_MEMCPY),
11320 3, dst, src, len);
11321 return fold_convert (void_type_node, tmp);
11325 /* Try to efficiently translate dst(:) = src(:). Return NULL if this
11326 can't be done. EXPR1 is the destination/lhs and EXPR2 is the
11327 source/rhs, both are gfc_full_array_ref_p which have been checked for
11328 dependencies. */
11330 static tree
11331 gfc_trans_array_copy (gfc_expr * expr1, gfc_expr * expr2)
11333 tree dst, dlen, dtype;
11334 tree src, slen, stype;
11335 tree tmp;
11337 dst = gfc_get_symbol_decl (expr1->symtree->n.sym);
11338 src = gfc_get_symbol_decl (expr2->symtree->n.sym);
11340 dtype = TREE_TYPE (dst);
11341 if (POINTER_TYPE_P (dtype))
11342 dtype = TREE_TYPE (dtype);
11343 stype = TREE_TYPE (src);
11344 if (POINTER_TYPE_P (stype))
11345 stype = TREE_TYPE (stype);
11347 if (!GFC_ARRAY_TYPE_P (dtype) || !GFC_ARRAY_TYPE_P (stype))
11348 return NULL_TREE;
11350 /* Determine the lengths of the arrays. */
11351 dlen = GFC_TYPE_ARRAY_SIZE (dtype);
11352 if (!dlen || TREE_CODE (dlen) != INTEGER_CST)
11353 return NULL_TREE;
11354 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (dtype));
11355 dlen = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
11356 dlen, fold_convert (gfc_array_index_type, tmp));
11358 slen = GFC_TYPE_ARRAY_SIZE (stype);
11359 if (!slen || TREE_CODE (slen) != INTEGER_CST)
11360 return NULL_TREE;
11361 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (stype));
11362 slen = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
11363 slen, fold_convert (gfc_array_index_type, tmp));
11365 /* Sanity check that they are the same. This should always be
11366 the case, as we should already have checked for conformance. */
11367 if (!tree_int_cst_equal (slen, dlen))
11368 return NULL_TREE;
11370 return gfc_build_memcpy_call (dst, src, dlen);
11374 /* Try to efficiently translate array(:) = (/ ... /). Return NULL if
11375 this can't be done. EXPR1 is the destination/lhs for which
11376 gfc_full_array_ref_p is true, and EXPR2 is the source/rhs. */
11378 static tree
11379 gfc_trans_array_constructor_copy (gfc_expr * expr1, gfc_expr * expr2)
11381 unsigned HOST_WIDE_INT nelem;
11382 tree dst, dtype;
11383 tree src, stype;
11384 tree len;
11385 tree tmp;
11387 nelem = gfc_constant_array_constructor_p (expr2->value.constructor);
11388 if (nelem == 0)
11389 return NULL_TREE;
11391 dst = gfc_get_symbol_decl (expr1->symtree->n.sym);
11392 dtype = TREE_TYPE (dst);
11393 if (POINTER_TYPE_P (dtype))
11394 dtype = TREE_TYPE (dtype);
11395 if (!GFC_ARRAY_TYPE_P (dtype))
11396 return NULL_TREE;
11398 /* Determine the lengths of the array. */
11399 len = GFC_TYPE_ARRAY_SIZE (dtype);
11400 if (!len || TREE_CODE (len) != INTEGER_CST)
11401 return NULL_TREE;
11403 /* Confirm that the constructor is the same size. */
11404 if (compare_tree_int (len, nelem) != 0)
11405 return NULL_TREE;
11407 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (dtype));
11408 len = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type, len,
11409 fold_convert (gfc_array_index_type, tmp));
11411 stype = gfc_typenode_for_spec (&expr2->ts);
11412 src = gfc_build_constant_array_constructor (expr2, stype);
11414 return gfc_build_memcpy_call (dst, src, len);
11418 /* Tells whether the expression is to be treated as a variable reference. */
11420 bool
11421 gfc_expr_is_variable (gfc_expr *expr)
11423 gfc_expr *arg;
11424 gfc_component *comp;
11425 gfc_symbol *func_ifc;
11427 if (expr->expr_type == EXPR_VARIABLE)
11428 return true;
11430 arg = gfc_get_noncopying_intrinsic_argument (expr);
11431 if (arg)
11433 gcc_assert (expr->value.function.isym->id == GFC_ISYM_TRANSPOSE);
11434 return gfc_expr_is_variable (arg);
11437 /* A data-pointer-returning function should be considered as a variable
11438 too. */
11439 if (expr->expr_type == EXPR_FUNCTION
11440 && expr->ref == NULL)
11442 if (expr->value.function.isym != NULL)
11443 return false;
11445 if (expr->value.function.esym != NULL)
11447 func_ifc = expr->value.function.esym;
11448 goto found_ifc;
11450 gcc_assert (expr->symtree);
11451 func_ifc = expr->symtree->n.sym;
11452 goto found_ifc;
11455 comp = gfc_get_proc_ptr_comp (expr);
11456 if ((expr->expr_type == EXPR_PPC || expr->expr_type == EXPR_FUNCTION)
11457 && comp)
11459 func_ifc = comp->ts.interface;
11460 goto found_ifc;
11463 if (expr->expr_type == EXPR_COMPCALL)
11465 gcc_assert (!expr->value.compcall.tbp->is_generic);
11466 func_ifc = expr->value.compcall.tbp->u.specific->n.sym;
11467 goto found_ifc;
11470 return false;
11472 found_ifc:
11473 gcc_assert (func_ifc->attr.function
11474 && func_ifc->result != NULL);
11475 return func_ifc->result->attr.pointer;
11479 /* Is the lhs OK for automatic reallocation? */
11481 static bool
11482 is_scalar_reallocatable_lhs (gfc_expr *expr)
11484 gfc_ref * ref;
11486 /* An allocatable variable with no reference. */
11487 if (expr->symtree->n.sym->attr.allocatable
11488 && !expr->ref)
11489 return true;
11491 /* All that can be left are allocatable components. However, we do
11492 not check for allocatable components here because the expression
11493 could be an allocatable component of a pointer component. */
11494 if (expr->symtree->n.sym->ts.type != BT_DERIVED
11495 && expr->symtree->n.sym->ts.type != BT_CLASS)
11496 return false;
11498 /* Find an allocatable component ref last. */
11499 for (ref = expr->ref; ref; ref = ref->next)
11500 if (ref->type == REF_COMPONENT
11501 && !ref->next
11502 && ref->u.c.component->attr.allocatable)
11503 return true;
11505 return false;
11509 /* Allocate or reallocate scalar lhs, as necessary. */
11511 static void
11512 alloc_scalar_allocatable_for_assignment (stmtblock_t *block,
11513 tree string_length,
11514 gfc_expr *expr1,
11515 gfc_expr *expr2)
11518 tree cond;
11519 tree tmp;
11520 tree size;
11521 tree size_in_bytes;
11522 tree jump_label1;
11523 tree jump_label2;
11524 gfc_se lse;
11525 gfc_ref *ref;
11527 if (!expr1 || expr1->rank)
11528 return;
11530 if (!expr2 || expr2->rank)
11531 return;
11533 for (ref = expr1->ref; ref; ref = ref->next)
11534 if (ref->type == REF_SUBSTRING)
11535 return;
11537 realloc_lhs_warning (expr2->ts.type, false, &expr2->where);
11539 /* Since this is a scalar lhs, we can afford to do this. That is,
11540 there is no risk of side effects being repeated. */
11541 gfc_init_se (&lse, NULL);
11542 lse.want_pointer = 1;
11543 gfc_conv_expr (&lse, expr1);
11545 jump_label1 = gfc_build_label_decl (NULL_TREE);
11546 jump_label2 = gfc_build_label_decl (NULL_TREE);
11548 /* Do the allocation if the lhs is NULL. Otherwise go to label 1. */
11549 tmp = build_int_cst (TREE_TYPE (lse.expr), 0);
11550 cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
11551 lse.expr, tmp);
11552 tmp = build3_v (COND_EXPR, cond,
11553 build1_v (GOTO_EXPR, jump_label1),
11554 build_empty_stmt (input_location));
11555 gfc_add_expr_to_block (block, tmp);
11557 if (expr1->ts.type == BT_CHARACTER && expr1->ts.deferred)
11559 /* Use the rhs string length and the lhs element size. Note that 'size' is
11560 used below for the string-length comparison, only. */
11561 size = string_length;
11562 tmp = TYPE_SIZE_UNIT (gfc_get_char_type (expr1->ts.kind));
11563 size_in_bytes = fold_build2_loc (input_location, MULT_EXPR,
11564 TREE_TYPE (tmp), tmp,
11565 fold_convert (TREE_TYPE (tmp), size));
11567 else
11569 /* Otherwise use the length in bytes of the rhs. */
11570 size = TYPE_SIZE_UNIT (gfc_typenode_for_spec (&expr1->ts));
11571 size_in_bytes = size;
11574 size_in_bytes = fold_build2_loc (input_location, MAX_EXPR, size_type_node,
11575 size_in_bytes, size_one_node);
11577 if (gfc_caf_attr (expr1).codimension && flag_coarray == GFC_FCOARRAY_LIB)
11579 tree caf_decl, token;
11580 gfc_se caf_se;
11581 symbol_attribute attr;
11583 gfc_clear_attr (&attr);
11584 gfc_init_se (&caf_se, NULL);
11586 caf_decl = gfc_get_tree_for_caf_expr (expr1);
11587 gfc_get_caf_token_offset (&caf_se, &token, NULL, caf_decl, NULL_TREE,
11588 NULL);
11589 gfc_add_block_to_block (block, &caf_se.pre);
11590 gfc_allocate_allocatable (block, lse.expr, size_in_bytes,
11591 gfc_build_addr_expr (NULL_TREE, token),
11592 NULL_TREE, NULL_TREE, NULL_TREE, jump_label1,
11593 expr1, 1);
11595 else if (expr1->ts.type == BT_DERIVED && expr1->ts.u.derived->attr.alloc_comp)
11597 tmp = build_call_expr_loc (input_location,
11598 builtin_decl_explicit (BUILT_IN_CALLOC),
11599 2, build_one_cst (size_type_node),
11600 size_in_bytes);
11601 tmp = fold_convert (TREE_TYPE (lse.expr), tmp);
11602 gfc_add_modify (block, lse.expr, tmp);
11604 else
11606 tmp = build_call_expr_loc (input_location,
11607 builtin_decl_explicit (BUILT_IN_MALLOC),
11608 1, size_in_bytes);
11609 tmp = fold_convert (TREE_TYPE (lse.expr), tmp);
11610 gfc_add_modify (block, lse.expr, tmp);
11613 if (expr1->ts.type == BT_CHARACTER && expr1->ts.deferred)
11615 /* Deferred characters need checking for lhs and rhs string
11616 length. Other deferred parameter variables will have to
11617 come here too. */
11618 tmp = build1_v (GOTO_EXPR, jump_label2);
11619 gfc_add_expr_to_block (block, tmp);
11621 tmp = build1_v (LABEL_EXPR, jump_label1);
11622 gfc_add_expr_to_block (block, tmp);
11624 /* For a deferred length character, reallocate if lengths of lhs and
11625 rhs are different. */
11626 if (expr1->ts.type == BT_CHARACTER && expr1->ts.deferred)
11628 cond = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
11629 lse.string_length,
11630 fold_convert (TREE_TYPE (lse.string_length),
11631 size));
11632 /* Jump past the realloc if the lengths are the same. */
11633 tmp = build3_v (COND_EXPR, cond,
11634 build1_v (GOTO_EXPR, jump_label2),
11635 build_empty_stmt (input_location));
11636 gfc_add_expr_to_block (block, tmp);
11637 tmp = build_call_expr_loc (input_location,
11638 builtin_decl_explicit (BUILT_IN_REALLOC),
11639 2, fold_convert (pvoid_type_node, lse.expr),
11640 size_in_bytes);
11641 tmp = fold_convert (TREE_TYPE (lse.expr), tmp);
11642 gfc_add_modify (block, lse.expr, tmp);
11643 tmp = build1_v (LABEL_EXPR, jump_label2);
11644 gfc_add_expr_to_block (block, tmp);
11646 /* Update the lhs character length. */
11647 size = string_length;
11648 gfc_add_modify (block, lse.string_length,
11649 fold_convert (TREE_TYPE (lse.string_length), size));
11653 /* Check for assignments of the type
11655 a = a + 4
11657 to make sure we do not check for reallocation unneccessarily. */
11660 static bool
11661 is_runtime_conformable (gfc_expr *expr1, gfc_expr *expr2)
11663 gfc_actual_arglist *a;
11664 gfc_expr *e1, *e2;
11666 switch (expr2->expr_type)
11668 case EXPR_VARIABLE:
11669 return gfc_dep_compare_expr (expr1, expr2) == 0;
11671 case EXPR_FUNCTION:
11672 if (expr2->value.function.esym
11673 && expr2->value.function.esym->attr.elemental)
11675 for (a = expr2->value.function.actual; a != NULL; a = a->next)
11677 e1 = a->expr;
11678 if (e1 && e1->rank > 0 && !is_runtime_conformable (expr1, e1))
11679 return false;
11681 return true;
11683 else if (expr2->value.function.isym
11684 && expr2->value.function.isym->elemental)
11686 for (a = expr2->value.function.actual; a != NULL; a = a->next)
11688 e1 = a->expr;
11689 if (e1 && e1->rank > 0 && !is_runtime_conformable (expr1, e1))
11690 return false;
11692 return true;
11695 break;
11697 case EXPR_OP:
11698 switch (expr2->value.op.op)
11700 case INTRINSIC_NOT:
11701 case INTRINSIC_UPLUS:
11702 case INTRINSIC_UMINUS:
11703 case INTRINSIC_PARENTHESES:
11704 return is_runtime_conformable (expr1, expr2->value.op.op1);
11706 case INTRINSIC_PLUS:
11707 case INTRINSIC_MINUS:
11708 case INTRINSIC_TIMES:
11709 case INTRINSIC_DIVIDE:
11710 case INTRINSIC_POWER:
11711 case INTRINSIC_AND:
11712 case INTRINSIC_OR:
11713 case INTRINSIC_EQV:
11714 case INTRINSIC_NEQV:
11715 case INTRINSIC_EQ:
11716 case INTRINSIC_NE:
11717 case INTRINSIC_GT:
11718 case INTRINSIC_GE:
11719 case INTRINSIC_LT:
11720 case INTRINSIC_LE:
11721 case INTRINSIC_EQ_OS:
11722 case INTRINSIC_NE_OS:
11723 case INTRINSIC_GT_OS:
11724 case INTRINSIC_GE_OS:
11725 case INTRINSIC_LT_OS:
11726 case INTRINSIC_LE_OS:
11728 e1 = expr2->value.op.op1;
11729 e2 = expr2->value.op.op2;
11731 if (e1->rank == 0 && e2->rank > 0)
11732 return is_runtime_conformable (expr1, e2);
11733 else if (e1->rank > 0 && e2->rank == 0)
11734 return is_runtime_conformable (expr1, e1);
11735 else if (e1->rank > 0 && e2->rank > 0)
11736 return is_runtime_conformable (expr1, e1)
11737 && is_runtime_conformable (expr1, e2);
11738 break;
11740 default:
11741 break;
11745 break;
11747 default:
11748 break;
11750 return false;
11754 static tree
11755 trans_class_assignment (stmtblock_t *block, gfc_expr *lhs, gfc_expr *rhs,
11756 gfc_se *lse, gfc_se *rse, bool use_vptr_copy,
11757 bool class_realloc)
11759 tree tmp, fcn, stdcopy, to_len, from_len, vptr, old_vptr;
11760 vec<tree, va_gc> *args = NULL;
11761 bool final_expr;
11763 final_expr = gfc_assignment_finalizer_call (lse, lhs, false);
11764 if (final_expr)
11766 if (rse->loop)
11767 gfc_prepend_expr_to_block (&rse->loop->pre,
11768 gfc_finish_block (&lse->finalblock));
11769 else
11770 gfc_add_block_to_block (block, &lse->finalblock);
11773 /* Store the old vptr so that dynamic types can be compared for
11774 reallocation to occur or not. */
11775 if (class_realloc)
11777 tmp = lse->expr;
11778 if (!GFC_CLASS_TYPE_P (TREE_TYPE (tmp)))
11779 tmp = gfc_get_class_from_expr (tmp);
11782 vptr = trans_class_vptr_len_assignment (block, lhs, rhs, rse, &to_len,
11783 &from_len);
11785 /* Generate (re)allocation of the lhs. */
11786 if (class_realloc)
11788 stmtblock_t alloc, re_alloc;
11789 tree class_han, re, size;
11791 if (tmp && GFC_CLASS_TYPE_P (TREE_TYPE (tmp)))
11792 old_vptr = gfc_evaluate_now (gfc_class_vptr_get (tmp), block);
11793 else
11794 old_vptr = build_int_cst (TREE_TYPE (vptr), 0);
11796 size = gfc_vptr_size_get (vptr);
11797 tmp = lse->expr;
11798 class_han = GFC_CLASS_TYPE_P (TREE_TYPE (tmp))
11799 ? gfc_class_data_get (tmp) : tmp;
11801 if (!POINTER_TYPE_P (TREE_TYPE (class_han)))
11802 class_han = gfc_build_addr_expr (NULL_TREE, class_han);
11804 /* Allocate block. */
11805 gfc_init_block (&alloc);
11806 gfc_allocate_using_malloc (&alloc, class_han, size, NULL_TREE);
11808 /* Reallocate if dynamic types are different. */
11809 gfc_init_block (&re_alloc);
11810 re = build_call_expr_loc (input_location,
11811 builtin_decl_explicit (BUILT_IN_REALLOC), 2,
11812 fold_convert (pvoid_type_node, class_han),
11813 size);
11814 tmp = fold_build2_loc (input_location, NE_EXPR,
11815 logical_type_node, vptr, old_vptr);
11816 re = fold_build3_loc (input_location, COND_EXPR, void_type_node,
11817 tmp, re, build_empty_stmt (input_location));
11818 gfc_add_expr_to_block (&re_alloc, re);
11820 tree realloc_expr = lhs->ts.type == BT_CLASS ?
11821 gfc_finish_block (&re_alloc) :
11822 build_empty_stmt (input_location);
11824 /* Allocate if _data is NULL, reallocate otherwise. */
11825 tmp = fold_build2_loc (input_location, EQ_EXPR,
11826 logical_type_node, class_han,
11827 build_int_cst (prvoid_type_node, 0));
11828 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
11829 gfc_unlikely (tmp,
11830 PRED_FORTRAN_FAIL_ALLOC),
11831 gfc_finish_block (&alloc),
11832 realloc_expr);
11833 gfc_add_expr_to_block (&lse->pre, tmp);
11836 fcn = gfc_vptr_copy_get (vptr);
11838 tmp = GFC_CLASS_TYPE_P (TREE_TYPE (rse->expr))
11839 ? gfc_class_data_get (rse->expr) : rse->expr;
11840 if (use_vptr_copy)
11842 if (!POINTER_TYPE_P (TREE_TYPE (tmp))
11843 || INDIRECT_REF_P (tmp)
11844 || (rhs->ts.type == BT_DERIVED
11845 && rhs->ts.u.derived->attr.unlimited_polymorphic
11846 && !rhs->ts.u.derived->attr.pointer
11847 && !rhs->ts.u.derived->attr.allocatable)
11848 || (UNLIMITED_POLY (rhs)
11849 && !CLASS_DATA (rhs)->attr.pointer
11850 && !CLASS_DATA (rhs)->attr.allocatable))
11851 vec_safe_push (args, gfc_build_addr_expr (NULL_TREE, tmp));
11852 else
11853 vec_safe_push (args, tmp);
11854 tmp = GFC_CLASS_TYPE_P (TREE_TYPE (lse->expr))
11855 ? gfc_class_data_get (lse->expr) : lse->expr;
11856 if (!POINTER_TYPE_P (TREE_TYPE (tmp))
11857 || INDIRECT_REF_P (tmp)
11858 || (lhs->ts.type == BT_DERIVED
11859 && lhs->ts.u.derived->attr.unlimited_polymorphic
11860 && !lhs->ts.u.derived->attr.pointer
11861 && !lhs->ts.u.derived->attr.allocatable)
11862 || (UNLIMITED_POLY (lhs)
11863 && !CLASS_DATA (lhs)->attr.pointer
11864 && !CLASS_DATA (lhs)->attr.allocatable))
11865 vec_safe_push (args, gfc_build_addr_expr (NULL_TREE, tmp));
11866 else
11867 vec_safe_push (args, tmp);
11869 stdcopy = build_call_vec (TREE_TYPE (TREE_TYPE (fcn)), fcn, args);
11871 if (to_len != NULL_TREE && !integer_zerop (from_len))
11873 tree extcopy;
11874 vec_safe_push (args, from_len);
11875 vec_safe_push (args, to_len);
11876 extcopy = build_call_vec (TREE_TYPE (TREE_TYPE (fcn)), fcn, args);
11878 tmp = fold_build2_loc (input_location, GT_EXPR,
11879 logical_type_node, from_len,
11880 build_zero_cst (TREE_TYPE (from_len)));
11881 return fold_build3_loc (input_location, COND_EXPR,
11882 void_type_node, tmp,
11883 extcopy, stdcopy);
11885 else
11886 return stdcopy;
11888 else
11890 tree rhst = GFC_CLASS_TYPE_P (TREE_TYPE (lse->expr))
11891 ? gfc_class_data_get (lse->expr) : lse->expr;
11892 stmtblock_t tblock;
11893 gfc_init_block (&tblock);
11894 if (!POINTER_TYPE_P (TREE_TYPE (tmp)))
11895 tmp = gfc_build_addr_expr (NULL_TREE, tmp);
11896 if (!POINTER_TYPE_P (TREE_TYPE (rhst)))
11897 rhst = gfc_build_addr_expr (NULL_TREE, rhst);
11898 /* When coming from a ptr_copy lhs and rhs are swapped. */
11899 gfc_add_modify_loc (input_location, &tblock, rhst,
11900 fold_convert (TREE_TYPE (rhst), tmp));
11901 return gfc_finish_block (&tblock);
11906 /* Subroutine of gfc_trans_assignment that actually scalarizes the
11907 assignment. EXPR1 is the destination/LHS and EXPR2 is the source/RHS.
11908 init_flag indicates initialization expressions and dealloc that no
11909 deallocate prior assignment is needed (if in doubt, set true).
11910 When PTR_COPY is set and expr1 is a class type, then use the _vptr-copy
11911 routine instead of a pointer assignment. Alias resolution is only done,
11912 when MAY_ALIAS is set (the default). This flag is used by ALLOCATE()
11913 where it is known, that newly allocated memory on the lhs can never be
11914 an alias of the rhs. */
11916 static tree
11917 gfc_trans_assignment_1 (gfc_expr * expr1, gfc_expr * expr2, bool init_flag,
11918 bool dealloc, bool use_vptr_copy, bool may_alias)
11920 gfc_se lse;
11921 gfc_se rse;
11922 gfc_ss *lss;
11923 gfc_ss *lss_section;
11924 gfc_ss *rss;
11925 gfc_loopinfo loop;
11926 tree tmp;
11927 stmtblock_t block;
11928 stmtblock_t body;
11929 bool final_expr;
11930 bool l_is_temp;
11931 bool scalar_to_array;
11932 tree string_length;
11933 int n;
11934 bool maybe_workshare = false, lhs_refs_comp = false, rhs_refs_comp = false;
11935 symbol_attribute lhs_caf_attr, rhs_caf_attr, lhs_attr;
11936 bool is_poly_assign;
11937 bool realloc_flag;
11939 /* Assignment of the form lhs = rhs. */
11940 gfc_start_block (&block);
11942 gfc_init_se (&lse, NULL);
11943 gfc_init_se (&rse, NULL);
11945 /* Walk the lhs. */
11946 lss = gfc_walk_expr (expr1);
11947 if (gfc_is_reallocatable_lhs (expr1))
11949 lss->no_bounds_check = 1;
11950 if (!(expr2->expr_type == EXPR_FUNCTION
11951 && expr2->value.function.isym != NULL
11952 && !(expr2->value.function.isym->elemental
11953 || expr2->value.function.isym->conversion)))
11954 lss->is_alloc_lhs = 1;
11956 else
11957 lss->no_bounds_check = expr1->no_bounds_check;
11959 rss = NULL;
11961 if (expr2->expr_type != EXPR_VARIABLE
11962 && expr2->expr_type != EXPR_CONSTANT
11963 && (expr2->ts.type == BT_CLASS || gfc_may_be_finalized (expr2->ts)))
11965 expr2->must_finalize = 1;
11966 /* F2008 4.5.6.3 para 5: If an executable construct references a
11967 structure constructor or array constructor, the entity created by
11968 the constructor is finalized after execution of the innermost
11969 executable construct containing the reference.
11970 These finalizations were later deleted by the Combined Techical
11971 Corrigenda 1 TO 4 for fortran 2008 (f08/0011). */
11972 if (gfc_notification_std (GFC_STD_F2018_DEL)
11973 && (expr2->expr_type == EXPR_STRUCTURE
11974 || expr2->expr_type == EXPR_ARRAY))
11975 expr2->must_finalize = 0;
11979 /* Checking whether a class assignment is desired is quite complicated and
11980 needed at two locations, so do it once only before the information is
11981 needed. */
11982 lhs_attr = gfc_expr_attr (expr1);
11984 is_poly_assign = (use_vptr_copy || lhs_attr.pointer
11985 || (lhs_attr.allocatable && !lhs_attr.dimension))
11986 && (expr1->ts.type == BT_CLASS
11987 || gfc_is_class_array_ref (expr1, NULL)
11988 || gfc_is_class_scalar_expr (expr1)
11989 || gfc_is_class_array_ref (expr2, NULL)
11990 || gfc_is_class_scalar_expr (expr2))
11991 && lhs_attr.flavor != FL_PROCEDURE;
11993 realloc_flag = flag_realloc_lhs
11994 && gfc_is_reallocatable_lhs (expr1)
11995 && expr2->rank
11996 && !is_runtime_conformable (expr1, expr2);
11998 /* Only analyze the expressions for coarray properties, when in coarray-lib
11999 mode. */
12000 if (flag_coarray == GFC_FCOARRAY_LIB)
12002 lhs_caf_attr = gfc_caf_attr (expr1, false, &lhs_refs_comp);
12003 rhs_caf_attr = gfc_caf_attr (expr2, false, &rhs_refs_comp);
12006 if (lss != gfc_ss_terminator)
12008 /* The assignment needs scalarization. */
12009 lss_section = lss;
12011 /* Find a non-scalar SS from the lhs. */
12012 while (lss_section != gfc_ss_terminator
12013 && lss_section->info->type != GFC_SS_SECTION)
12014 lss_section = lss_section->next;
12016 gcc_assert (lss_section != gfc_ss_terminator);
12018 /* Initialize the scalarizer. */
12019 gfc_init_loopinfo (&loop);
12021 /* Walk the rhs. */
12022 rss = gfc_walk_expr (expr2);
12023 if (rss == gfc_ss_terminator)
12024 /* The rhs is scalar. Add a ss for the expression. */
12025 rss = gfc_get_scalar_ss (gfc_ss_terminator, expr2);
12026 /* When doing a class assign, then the handle to the rhs needs to be a
12027 pointer to allow for polymorphism. */
12028 if (is_poly_assign && expr2->rank == 0 && !UNLIMITED_POLY (expr2))
12029 rss->info->type = GFC_SS_REFERENCE;
12031 rss->no_bounds_check = expr2->no_bounds_check;
12032 /* Associate the SS with the loop. */
12033 gfc_add_ss_to_loop (&loop, lss);
12034 gfc_add_ss_to_loop (&loop, rss);
12036 /* Calculate the bounds of the scalarization. */
12037 gfc_conv_ss_startstride (&loop);
12038 /* Enable loop reversal. */
12039 for (n = 0; n < GFC_MAX_DIMENSIONS; n++)
12040 loop.reverse[n] = GFC_ENABLE_REVERSE;
12041 /* Resolve any data dependencies in the statement. */
12042 if (may_alias)
12043 gfc_conv_resolve_dependencies (&loop, lss, rss);
12044 /* Setup the scalarizing loops. */
12045 gfc_conv_loop_setup (&loop, &expr2->where);
12047 /* Setup the gfc_se structures. */
12048 gfc_copy_loopinfo_to_se (&lse, &loop);
12049 gfc_copy_loopinfo_to_se (&rse, &loop);
12051 rse.ss = rss;
12052 gfc_mark_ss_chain_used (rss, 1);
12053 if (loop.temp_ss == NULL)
12055 lse.ss = lss;
12056 gfc_mark_ss_chain_used (lss, 1);
12058 else
12060 lse.ss = loop.temp_ss;
12061 gfc_mark_ss_chain_used (lss, 3);
12062 gfc_mark_ss_chain_used (loop.temp_ss, 3);
12065 /* Allow the scalarizer to workshare array assignments. */
12066 if ((ompws_flags & (OMPWS_WORKSHARE_FLAG | OMPWS_SCALARIZER_BODY))
12067 == OMPWS_WORKSHARE_FLAG
12068 && loop.temp_ss == NULL)
12070 maybe_workshare = true;
12071 ompws_flags |= OMPWS_SCALARIZER_WS | OMPWS_SCALARIZER_BODY;
12074 /* Start the scalarized loop body. */
12075 gfc_start_scalarized_body (&loop, &body);
12077 else
12078 gfc_init_block (&body);
12080 l_is_temp = (lss != gfc_ss_terminator && loop.temp_ss != NULL);
12082 /* Translate the expression. */
12083 rse.want_coarray = flag_coarray == GFC_FCOARRAY_LIB && init_flag
12084 && lhs_caf_attr.codimension;
12085 gfc_conv_expr (&rse, expr2);
12087 /* Deal with the case of a scalar class function assigned to a derived type. */
12088 if (gfc_is_alloc_class_scalar_function (expr2)
12089 && expr1->ts.type == BT_DERIVED)
12091 rse.expr = gfc_class_data_get (rse.expr);
12092 rse.expr = build_fold_indirect_ref_loc (input_location, rse.expr);
12095 /* Stabilize a string length for temporaries. */
12096 if (expr2->ts.type == BT_CHARACTER && !expr1->ts.deferred
12097 && !(VAR_P (rse.string_length)
12098 || TREE_CODE (rse.string_length) == PARM_DECL
12099 || INDIRECT_REF_P (rse.string_length)))
12100 string_length = gfc_evaluate_now (rse.string_length, &rse.pre);
12101 else if (expr2->ts.type == BT_CHARACTER)
12103 if (expr1->ts.deferred
12104 && gfc_expr_attr (expr1).allocatable
12105 && gfc_check_dependency (expr1, expr2, true))
12106 rse.string_length =
12107 gfc_evaluate_now_function_scope (rse.string_length, &rse.pre);
12108 string_length = rse.string_length;
12110 else
12111 string_length = NULL_TREE;
12113 if (l_is_temp)
12115 gfc_conv_tmp_array_ref (&lse);
12116 if (expr2->ts.type == BT_CHARACTER)
12117 lse.string_length = string_length;
12119 else
12121 gfc_conv_expr (&lse, expr1);
12122 if (gfc_option.rtcheck & GFC_RTCHECK_MEM
12123 && !init_flag
12124 && gfc_expr_attr (expr1).allocatable
12125 && expr1->rank
12126 && !expr2->rank)
12128 tree cond;
12129 const char* msg;
12131 tmp = INDIRECT_REF_P (lse.expr)
12132 ? gfc_build_addr_expr (NULL_TREE, lse.expr) : lse.expr;
12133 STRIP_NOPS (tmp);
12135 /* We should only get array references here. */
12136 gcc_assert (TREE_CODE (tmp) == POINTER_PLUS_EXPR
12137 || TREE_CODE (tmp) == ARRAY_REF);
12139 /* 'tmp' is either the pointer to the array(POINTER_PLUS_EXPR)
12140 or the array itself(ARRAY_REF). */
12141 tmp = TREE_OPERAND (tmp, 0);
12143 /* Provide the address of the array. */
12144 if (TREE_CODE (lse.expr) == ARRAY_REF)
12145 tmp = gfc_build_addr_expr (NULL_TREE, tmp);
12147 cond = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
12148 tmp, build_int_cst (TREE_TYPE (tmp), 0));
12149 msg = _("Assignment of scalar to unallocated array");
12150 gfc_trans_runtime_check (true, false, cond, &loop.pre,
12151 &expr1->where, msg);
12154 /* Deallocate the lhs parameterized components if required. */
12155 if (dealloc && expr2->expr_type == EXPR_FUNCTION
12156 && !expr1->symtree->n.sym->attr.associate_var)
12158 if (expr1->ts.type == BT_DERIVED
12159 && expr1->ts.u.derived
12160 && expr1->ts.u.derived->attr.pdt_type)
12162 tmp = gfc_deallocate_pdt_comp (expr1->ts.u.derived, lse.expr,
12163 expr1->rank);
12164 gfc_add_expr_to_block (&lse.pre, tmp);
12166 else if (expr1->ts.type == BT_CLASS
12167 && CLASS_DATA (expr1)->ts.u.derived
12168 && CLASS_DATA (expr1)->ts.u.derived->attr.pdt_type)
12170 tmp = gfc_class_data_get (lse.expr);
12171 tmp = gfc_deallocate_pdt_comp (CLASS_DATA (expr1)->ts.u.derived,
12172 tmp, expr1->rank);
12173 gfc_add_expr_to_block (&lse.pre, tmp);
12178 /* Assignments of scalar derived types with allocatable components
12179 to arrays must be done with a deep copy and the rhs temporary
12180 must have its components deallocated afterwards. */
12181 scalar_to_array = (expr2->ts.type == BT_DERIVED
12182 && expr2->ts.u.derived->attr.alloc_comp
12183 && !gfc_expr_is_variable (expr2)
12184 && expr1->rank && !expr2->rank);
12185 scalar_to_array |= (expr1->ts.type == BT_DERIVED
12186 && expr1->rank
12187 && expr1->ts.u.derived->attr.alloc_comp
12188 && gfc_is_alloc_class_scalar_function (expr2));
12189 if (scalar_to_array && dealloc)
12191 tmp = gfc_deallocate_alloc_comp_no_caf (expr2->ts.u.derived, rse.expr, 0);
12192 gfc_prepend_expr_to_block (&loop.post, tmp);
12195 /* When assigning a character function result to a deferred-length variable,
12196 the function call must happen before the (re)allocation of the lhs -
12197 otherwise the character length of the result is not known.
12198 NOTE 1: This relies on having the exact dependence of the length type
12199 parameter available to the caller; gfortran saves it in the .mod files.
12200 NOTE 2: Vector array references generate an index temporary that must
12201 not go outside the loop. Otherwise, variables should not generate
12202 a pre block.
12203 NOTE 3: The concatenation operation generates a temporary pointer,
12204 whose allocation must go to the innermost loop.
12205 NOTE 4: Elemental functions may generate a temporary, too. */
12206 if (flag_realloc_lhs
12207 && expr2->ts.type == BT_CHARACTER && expr1->ts.deferred
12208 && !(lss != gfc_ss_terminator
12209 && rss != gfc_ss_terminator
12210 && ((expr2->expr_type == EXPR_VARIABLE && expr2->rank)
12211 || (expr2->expr_type == EXPR_FUNCTION
12212 && expr2->value.function.esym != NULL
12213 && expr2->value.function.esym->attr.elemental)
12214 || (expr2->expr_type == EXPR_FUNCTION
12215 && expr2->value.function.isym != NULL
12216 && expr2->value.function.isym->elemental)
12217 || (expr2->expr_type == EXPR_OP
12218 && expr2->value.op.op == INTRINSIC_CONCAT))))
12219 gfc_add_block_to_block (&block, &rse.pre);
12221 /* Nullify the allocatable components corresponding to those of the lhs
12222 derived type, so that the finalization of the function result does not
12223 affect the lhs of the assignment. Prepend is used to ensure that the
12224 nullification occurs before the call to the finalizer. In the case of
12225 a scalar to array assignment, this is done in gfc_trans_scalar_assign
12226 as part of the deep copy. */
12227 if (!scalar_to_array && expr1->ts.type == BT_DERIVED
12228 && (gfc_is_class_array_function (expr2)
12229 || gfc_is_alloc_class_scalar_function (expr2)))
12231 tmp = gfc_nullify_alloc_comp (expr1->ts.u.derived, rse.expr, 0);
12232 gfc_prepend_expr_to_block (&rse.post, tmp);
12233 if (lss != gfc_ss_terminator && rss == gfc_ss_terminator)
12234 gfc_add_block_to_block (&loop.post, &rse.post);
12237 tmp = NULL_TREE;
12239 if (is_poly_assign)
12241 tmp = trans_class_assignment (&body, expr1, expr2, &lse, &rse,
12242 use_vptr_copy || (lhs_attr.allocatable
12243 && !lhs_attr.dimension),
12244 !realloc_flag && flag_realloc_lhs
12245 && !lhs_attr.pointer);
12246 if (expr2->expr_type == EXPR_FUNCTION
12247 && expr2->ts.type == BT_DERIVED
12248 && expr2->ts.u.derived->attr.alloc_comp)
12250 tree tmp2 = gfc_deallocate_alloc_comp (expr2->ts.u.derived,
12251 rse.expr, expr2->rank);
12252 if (lss == gfc_ss_terminator)
12253 gfc_add_expr_to_block (&rse.post, tmp2);
12254 else
12255 gfc_add_expr_to_block (&loop.post, tmp2);
12258 expr1->must_finalize = 0;
12260 else if (flag_coarray == GFC_FCOARRAY_LIB
12261 && lhs_caf_attr.codimension && rhs_caf_attr.codimension
12262 && ((lhs_caf_attr.allocatable && lhs_refs_comp)
12263 || (rhs_caf_attr.allocatable && rhs_refs_comp)))
12265 /* Only detour to caf_send[get][_by_ref] () when the lhs or rhs is an
12266 allocatable component, because those need to be accessed via the
12267 caf-runtime. No need to check for coindexes here, because resolve
12268 has rewritten those already. */
12269 gfc_code code;
12270 gfc_actual_arglist a1, a2;
12271 /* Clear the structures to prevent accessing garbage. */
12272 memset (&code, '\0', sizeof (gfc_code));
12273 memset (&a1, '\0', sizeof (gfc_actual_arglist));
12274 memset (&a2, '\0', sizeof (gfc_actual_arglist));
12275 a1.expr = expr1;
12276 a1.next = &a2;
12277 a2.expr = expr2;
12278 a2.next = NULL;
12279 code.ext.actual = &a1;
12280 code.resolved_isym = gfc_intrinsic_subroutine_by_id (GFC_ISYM_CAF_SEND);
12281 tmp = gfc_conv_intrinsic_subroutine (&code);
12283 else if (!is_poly_assign && expr2->must_finalize
12284 && expr1->ts.type == BT_CLASS
12285 && expr2->ts.type == BT_CLASS)
12287 /* This case comes about when the scalarizer provides array element
12288 references. Use the vptr copy function, since this does a deep
12289 copy of allocatable components, without which the finalizer call
12290 will deallocate the components. */
12291 tmp = gfc_get_vptr_from_expr (rse.expr);
12292 if (tmp != NULL_TREE)
12294 tree fcn = gfc_vptr_copy_get (tmp);
12295 if (POINTER_TYPE_P (TREE_TYPE (fcn)))
12296 fcn = build_fold_indirect_ref_loc (input_location, fcn);
12297 tmp = build_call_expr_loc (input_location,
12298 fcn, 2,
12299 gfc_build_addr_expr (NULL, rse.expr),
12300 gfc_build_addr_expr (NULL, lse.expr));
12304 /* Comply with F2018 (7.5.6.3). Make sure that any finalization code is added
12305 after evaluation of the rhs and before reallocation. */
12306 final_expr = gfc_assignment_finalizer_call (&lse, expr1, init_flag);
12307 if (final_expr && !(expr2->expr_type == EXPR_VARIABLE
12308 && expr2->symtree->n.sym->attr.artificial))
12310 if (lss == gfc_ss_terminator)
12312 gfc_add_block_to_block (&block, &rse.pre);
12313 gfc_add_block_to_block (&block, &lse.finalblock);
12315 else
12317 gfc_add_block_to_block (&body, &rse.pre);
12318 gfc_add_block_to_block (&loop.code[expr1->rank - 1],
12319 &lse.finalblock);
12322 else
12323 gfc_add_block_to_block (&body, &rse.pre);
12325 /* If nothing else works, do it the old fashioned way! */
12326 if (tmp == NULL_TREE)
12327 tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts,
12328 gfc_expr_is_variable (expr2)
12329 || scalar_to_array
12330 || expr2->expr_type == EXPR_ARRAY,
12331 !(l_is_temp || init_flag) && dealloc,
12332 expr1->symtree->n.sym->attr.codimension);
12335 /* Add the lse pre block to the body */
12336 gfc_add_block_to_block (&body, &lse.pre);
12337 gfc_add_expr_to_block (&body, tmp);
12339 /* Add the post blocks to the body. */
12340 if (!l_is_temp)
12342 gfc_add_block_to_block (&rse.finalblock, &rse.post);
12343 gfc_add_block_to_block (&body, &rse.finalblock);
12345 else
12346 gfc_add_block_to_block (&body, &rse.post);
12348 gfc_add_block_to_block (&body, &lse.post);
12350 if (lss == gfc_ss_terminator)
12352 /* F2003: Add the code for reallocation on assignment. */
12353 if (flag_realloc_lhs && is_scalar_reallocatable_lhs (expr1)
12354 && !is_poly_assign)
12355 alloc_scalar_allocatable_for_assignment (&block, string_length,
12356 expr1, expr2);
12358 /* Use the scalar assignment as is. */
12359 gfc_add_block_to_block (&block, &body);
12361 else
12363 gcc_assert (lse.ss == gfc_ss_terminator
12364 && rse.ss == gfc_ss_terminator);
12366 if (l_is_temp)
12368 gfc_trans_scalarized_loop_boundary (&loop, &body);
12370 /* We need to copy the temporary to the actual lhs. */
12371 gfc_init_se (&lse, NULL);
12372 gfc_init_se (&rse, NULL);
12373 gfc_copy_loopinfo_to_se (&lse, &loop);
12374 gfc_copy_loopinfo_to_se (&rse, &loop);
12376 rse.ss = loop.temp_ss;
12377 lse.ss = lss;
12379 gfc_conv_tmp_array_ref (&rse);
12380 gfc_conv_expr (&lse, expr1);
12382 gcc_assert (lse.ss == gfc_ss_terminator
12383 && rse.ss == gfc_ss_terminator);
12385 if (expr2->ts.type == BT_CHARACTER)
12386 rse.string_length = string_length;
12388 tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts,
12389 false, dealloc);
12390 gfc_add_expr_to_block (&body, tmp);
12393 /* F2003: Allocate or reallocate lhs of allocatable array. */
12394 if (realloc_flag)
12396 realloc_lhs_warning (expr1->ts.type, true, &expr1->where);
12397 ompws_flags &= ~OMPWS_SCALARIZER_WS;
12398 tmp = gfc_alloc_allocatable_for_assignment (&loop, expr1, expr2);
12399 if (tmp != NULL_TREE)
12400 gfc_add_expr_to_block (&loop.code[expr1->rank - 1], tmp);
12403 if (maybe_workshare)
12404 ompws_flags &= ~OMPWS_SCALARIZER_BODY;
12406 /* Generate the copying loops. */
12407 gfc_trans_scalarizing_loops (&loop, &body);
12409 /* Wrap the whole thing up. */
12410 gfc_add_block_to_block (&block, &loop.pre);
12411 gfc_add_block_to_block (&block, &loop.post);
12413 gfc_cleanup_loop (&loop);
12416 return gfc_finish_block (&block);
12420 /* Check whether EXPR is a copyable array. */
12422 static bool
12423 copyable_array_p (gfc_expr * expr)
12425 if (expr->expr_type != EXPR_VARIABLE)
12426 return false;
12428 /* First check it's an array. */
12429 if (expr->rank < 1 || !expr->ref || expr->ref->next)
12430 return false;
12432 if (!gfc_full_array_ref_p (expr->ref, NULL))
12433 return false;
12435 /* Next check that it's of a simple enough type. */
12436 switch (expr->ts.type)
12438 case BT_INTEGER:
12439 case BT_REAL:
12440 case BT_COMPLEX:
12441 case BT_LOGICAL:
12442 return true;
12444 case BT_CHARACTER:
12445 return false;
12447 case_bt_struct:
12448 return !expr->ts.u.derived->attr.alloc_comp;
12450 default:
12451 break;
12454 return false;
12457 /* Translate an assignment. */
12459 tree
12460 gfc_trans_assignment (gfc_expr * expr1, gfc_expr * expr2, bool init_flag,
12461 bool dealloc, bool use_vptr_copy, bool may_alias)
12463 tree tmp;
12465 /* Special case a single function returning an array. */
12466 if (expr2->expr_type == EXPR_FUNCTION && expr2->rank > 0)
12468 tmp = gfc_trans_arrayfunc_assign (expr1, expr2);
12469 if (tmp)
12470 return tmp;
12473 /* Special case assigning an array to zero. */
12474 if (copyable_array_p (expr1)
12475 && is_zero_initializer_p (expr2))
12477 tmp = gfc_trans_zero_assign (expr1);
12478 if (tmp)
12479 return tmp;
12482 /* Special case copying one array to another. */
12483 if (copyable_array_p (expr1)
12484 && copyable_array_p (expr2)
12485 && gfc_compare_types (&expr1->ts, &expr2->ts)
12486 && !gfc_check_dependency (expr1, expr2, 0))
12488 tmp = gfc_trans_array_copy (expr1, expr2);
12489 if (tmp)
12490 return tmp;
12493 /* Special case initializing an array from a constant array constructor. */
12494 if (copyable_array_p (expr1)
12495 && expr2->expr_type == EXPR_ARRAY
12496 && gfc_compare_types (&expr1->ts, &expr2->ts))
12498 tmp = gfc_trans_array_constructor_copy (expr1, expr2);
12499 if (tmp)
12500 return tmp;
12503 if (UNLIMITED_POLY (expr1) && expr1->rank)
12504 use_vptr_copy = true;
12506 /* Fallback to the scalarizer to generate explicit loops. */
12507 return gfc_trans_assignment_1 (expr1, expr2, init_flag, dealloc,
12508 use_vptr_copy, may_alias);
12511 tree
12512 gfc_trans_init_assign (gfc_code * code)
12514 return gfc_trans_assignment (code->expr1, code->expr2, true, false, true);
12517 tree
12518 gfc_trans_assign (gfc_code * code)
12520 return gfc_trans_assignment (code->expr1, code->expr2, false, true);
12523 /* Generate a simple loop for internal use of the form
12524 for (var = begin; var <cond> end; var += step)
12525 body; */
12526 void
12527 gfc_simple_for_loop (stmtblock_t *block, tree var, tree begin, tree end,
12528 enum tree_code cond, tree step, tree body)
12530 tree tmp;
12532 /* var = begin. */
12533 gfc_add_modify (block, var, begin);
12535 /* Loop: for (var = begin; var <cond> end; var += step). */
12536 tree label_loop = gfc_build_label_decl (NULL_TREE);
12537 tree label_cond = gfc_build_label_decl (NULL_TREE);
12538 TREE_USED (label_loop) = 1;
12539 TREE_USED (label_cond) = 1;
12541 gfc_add_expr_to_block (block, build1_v (GOTO_EXPR, label_cond));
12542 gfc_add_expr_to_block (block, build1_v (LABEL_EXPR, label_loop));
12544 /* Loop body. */
12545 gfc_add_expr_to_block (block, body);
12547 /* End of loop body. */
12548 tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (var), var, step);
12549 gfc_add_modify (block, var, tmp);
12550 gfc_add_expr_to_block (block, build1_v (LABEL_EXPR, label_cond));
12551 tmp = fold_build2_loc (input_location, cond, boolean_type_node, var, end);
12552 tmp = build3_v (COND_EXPR, tmp, build1_v (GOTO_EXPR, label_loop),
12553 build_empty_stmt (input_location));
12554 gfc_add_expr_to_block (block, tmp);