2018-25-01 Paul Thomas <pault@gcc.gnu.org>
[official-gcc.git] / gcc / fortran / trans-expr.c
blobf03aa18274d51d91d37476d2c1cafcdb56152ec5
1 /* Expression translation
2 Copyright (C) 2002-2018 Free Software Foundation, Inc.
3 Contributed by Paul Brook <paul@nowt.org>
4 and Steven Bosscher <s.bosscher@student.tudelft.nl>
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 3, or (at your option) any later
11 version.
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 for more details.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3. If not see
20 <http://www.gnu.org/licenses/>. */
22 /* trans-expr.c-- generate GENERIC trees for gfc_expr. */
24 #include "config.h"
25 #include "system.h"
26 #include "coretypes.h"
27 #include "options.h"
28 #include "tree.h"
29 #include "gfortran.h"
30 #include "trans.h"
31 #include "stringpool.h"
32 #include "diagnostic-core.h" /* For fatal_error. */
33 #include "fold-const.h"
34 #include "langhooks.h"
35 #include "arith.h"
36 #include "constructor.h"
37 #include "trans-const.h"
38 #include "trans-types.h"
39 #include "trans-array.h"
40 /* Only for gfc_trans_assign and gfc_trans_pointer_assign. */
41 #include "trans-stmt.h"
42 #include "dependency.h"
43 #include "gimplify.h"
45 /* Convert a scalar to an array descriptor. To be used for assumed-rank
46 arrays. */
48 static tree
49 get_scalar_to_descriptor_type (tree scalar, symbol_attribute attr)
51 enum gfc_array_kind akind;
53 if (attr.pointer)
54 akind = GFC_ARRAY_POINTER_CONT;
55 else if (attr.allocatable)
56 akind = GFC_ARRAY_ALLOCATABLE;
57 else
58 akind = GFC_ARRAY_ASSUMED_SHAPE_CONT;
60 if (POINTER_TYPE_P (TREE_TYPE (scalar)))
61 scalar = TREE_TYPE (scalar);
62 return gfc_get_array_type_bounds (TREE_TYPE (scalar), 0, 0, NULL, NULL, 1,
63 akind, !(attr.pointer || attr.target));
66 tree
67 gfc_conv_scalar_to_descriptor (gfc_se *se, tree scalar, symbol_attribute attr)
69 tree desc, type, etype;
71 type = get_scalar_to_descriptor_type (scalar, attr);
72 etype = TREE_TYPE (scalar);
73 desc = gfc_create_var (type, "desc");
74 DECL_ARTIFICIAL (desc) = 1;
76 if (CONSTANT_CLASS_P (scalar))
78 tree tmp;
79 tmp = gfc_create_var (TREE_TYPE (scalar), "scalar");
80 gfc_add_modify (&se->pre, tmp, scalar);
81 scalar = tmp;
83 if (!POINTER_TYPE_P (TREE_TYPE (scalar)))
84 scalar = gfc_build_addr_expr (NULL_TREE, scalar);
85 else if (TREE_TYPE (etype) && TREE_CODE (TREE_TYPE (etype)) == ARRAY_TYPE)
86 etype = TREE_TYPE (etype);
87 gfc_add_modify (&se->pre, gfc_conv_descriptor_dtype (desc),
88 gfc_get_dtype_rank_type (0, etype));
89 gfc_conv_descriptor_data_set (&se->pre, desc, scalar);
91 /* Copy pointer address back - but only if it could have changed and
92 if the actual argument is a pointer and not, e.g., NULL(). */
93 if ((attr.pointer || attr.allocatable) && attr.intent != INTENT_IN)
94 gfc_add_modify (&se->post, scalar,
95 fold_convert (TREE_TYPE (scalar),
96 gfc_conv_descriptor_data_get (desc)));
97 return desc;
101 /* Get the coarray token from the ultimate array or component ref.
102 Returns a NULL_TREE, when the ref object is not allocatable or pointer. */
104 tree
105 gfc_get_ultimate_alloc_ptr_comps_caf_token (gfc_se *outerse, gfc_expr *expr)
107 gfc_symbol *sym = expr->symtree->n.sym;
108 bool is_coarray = sym->attr.codimension;
109 gfc_expr *caf_expr = gfc_copy_expr (expr);
110 gfc_ref *ref = caf_expr->ref, *last_caf_ref = NULL;
112 while (ref)
114 if (ref->type == REF_COMPONENT
115 && (ref->u.c.component->attr.allocatable
116 || ref->u.c.component->attr.pointer)
117 && (is_coarray || ref->u.c.component->attr.codimension))
118 last_caf_ref = ref;
119 ref = ref->next;
122 if (last_caf_ref == NULL)
123 return NULL_TREE;
125 tree comp = last_caf_ref->u.c.component->caf_token, caf;
126 gfc_se se;
127 bool comp_ref = !last_caf_ref->u.c.component->attr.dimension;
128 if (comp == NULL_TREE && comp_ref)
129 return NULL_TREE;
130 gfc_init_se (&se, outerse);
131 gfc_free_ref_list (last_caf_ref->next);
132 last_caf_ref->next = NULL;
133 caf_expr->rank = comp_ref ? 0 : last_caf_ref->u.c.component->as->rank;
134 se.want_pointer = comp_ref;
135 gfc_conv_expr (&se, caf_expr);
136 gfc_add_block_to_block (&outerse->pre, &se.pre);
138 if (TREE_CODE (se.expr) == COMPONENT_REF && comp_ref)
139 se.expr = TREE_OPERAND (se.expr, 0);
140 gfc_free_expr (caf_expr);
142 if (comp_ref)
143 caf = fold_build3_loc (input_location, COMPONENT_REF,
144 TREE_TYPE (comp), se.expr, comp, NULL_TREE);
145 else
146 caf = gfc_conv_descriptor_token (se.expr);
147 return gfc_build_addr_expr (NULL_TREE, caf);
151 /* This is the seed for an eventual trans-class.c
153 The following parameters should not be used directly since they might
154 in future implementations. Use the corresponding APIs. */
155 #define CLASS_DATA_FIELD 0
156 #define CLASS_VPTR_FIELD 1
157 #define CLASS_LEN_FIELD 2
158 #define VTABLE_HASH_FIELD 0
159 #define VTABLE_SIZE_FIELD 1
160 #define VTABLE_EXTENDS_FIELD 2
161 #define VTABLE_DEF_INIT_FIELD 3
162 #define VTABLE_COPY_FIELD 4
163 #define VTABLE_FINAL_FIELD 5
164 #define VTABLE_DEALLOCATE_FIELD 6
167 tree
168 gfc_class_set_static_fields (tree decl, tree vptr, tree data)
170 tree tmp;
171 tree field;
172 vec<constructor_elt, va_gc> *init = NULL;
174 field = TYPE_FIELDS (TREE_TYPE (decl));
175 tmp = gfc_advance_chain (field, CLASS_DATA_FIELD);
176 CONSTRUCTOR_APPEND_ELT (init, tmp, data);
178 tmp = gfc_advance_chain (field, CLASS_VPTR_FIELD);
179 CONSTRUCTOR_APPEND_ELT (init, tmp, vptr);
181 return build_constructor (TREE_TYPE (decl), init);
185 tree
186 gfc_class_data_get (tree decl)
188 tree data;
189 if (POINTER_TYPE_P (TREE_TYPE (decl)))
190 decl = build_fold_indirect_ref_loc (input_location, decl);
191 data = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (decl)),
192 CLASS_DATA_FIELD);
193 return fold_build3_loc (input_location, COMPONENT_REF,
194 TREE_TYPE (data), decl, data,
195 NULL_TREE);
199 tree
200 gfc_class_vptr_get (tree decl)
202 tree vptr;
203 /* For class arrays decl may be a temporary descriptor handle, the vptr is
204 then available through the saved descriptor. */
205 if (VAR_P (decl) && DECL_LANG_SPECIFIC (decl)
206 && GFC_DECL_SAVED_DESCRIPTOR (decl))
207 decl = GFC_DECL_SAVED_DESCRIPTOR (decl);
208 if (POINTER_TYPE_P (TREE_TYPE (decl)))
209 decl = build_fold_indirect_ref_loc (input_location, decl);
210 vptr = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (decl)),
211 CLASS_VPTR_FIELD);
212 return fold_build3_loc (input_location, COMPONENT_REF,
213 TREE_TYPE (vptr), decl, vptr,
214 NULL_TREE);
218 tree
219 gfc_class_len_get (tree decl)
221 tree len;
222 /* For class arrays decl may be a temporary descriptor handle, the len is
223 then available through the saved descriptor. */
224 if (VAR_P (decl) && DECL_LANG_SPECIFIC (decl)
225 && GFC_DECL_SAVED_DESCRIPTOR (decl))
226 decl = GFC_DECL_SAVED_DESCRIPTOR (decl);
227 if (POINTER_TYPE_P (TREE_TYPE (decl)))
228 decl = build_fold_indirect_ref_loc (input_location, decl);
229 len = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (decl)),
230 CLASS_LEN_FIELD);
231 return fold_build3_loc (input_location, COMPONENT_REF,
232 TREE_TYPE (len), decl, len,
233 NULL_TREE);
237 /* Try to get the _len component of a class. When the class is not unlimited
238 poly, i.e. no _len field exists, then return a zero node. */
240 tree
241 gfc_class_len_or_zero_get (tree decl)
243 tree len;
244 /* For class arrays decl may be a temporary descriptor handle, the vptr is
245 then available through the saved descriptor. */
246 if (VAR_P (decl) && DECL_LANG_SPECIFIC (decl)
247 && GFC_DECL_SAVED_DESCRIPTOR (decl))
248 decl = GFC_DECL_SAVED_DESCRIPTOR (decl);
249 if (POINTER_TYPE_P (TREE_TYPE (decl)))
250 decl = build_fold_indirect_ref_loc (input_location, decl);
251 len = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (decl)),
252 CLASS_LEN_FIELD);
253 return len != NULL_TREE ? fold_build3_loc (input_location, COMPONENT_REF,
254 TREE_TYPE (len), decl, len,
255 NULL_TREE)
256 : build_zero_cst (gfc_charlen_type_node);
260 /* Get the specified FIELD from the VPTR. */
262 static tree
263 vptr_field_get (tree vptr, int fieldno)
265 tree field;
266 vptr = build_fold_indirect_ref_loc (input_location, vptr);
267 field = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (vptr)),
268 fieldno);
269 field = fold_build3_loc (input_location, COMPONENT_REF,
270 TREE_TYPE (field), vptr, field,
271 NULL_TREE);
272 gcc_assert (field);
273 return field;
277 /* Get the field from the class' vptr. */
279 static tree
280 class_vtab_field_get (tree decl, int fieldno)
282 tree vptr;
283 vptr = gfc_class_vptr_get (decl);
284 return vptr_field_get (vptr, fieldno);
288 /* Define a macro for creating the class_vtab_* and vptr_* accessors in
289 unison. */
290 #define VTAB_GET_FIELD_GEN(name, field) tree \
291 gfc_class_vtab_## name ##_get (tree cl) \
293 return class_vtab_field_get (cl, field); \
296 tree \
297 gfc_vptr_## name ##_get (tree vptr) \
299 return vptr_field_get (vptr, field); \
302 VTAB_GET_FIELD_GEN (hash, VTABLE_HASH_FIELD)
303 VTAB_GET_FIELD_GEN (extends, VTABLE_EXTENDS_FIELD)
304 VTAB_GET_FIELD_GEN (def_init, VTABLE_DEF_INIT_FIELD)
305 VTAB_GET_FIELD_GEN (copy, VTABLE_COPY_FIELD)
306 VTAB_GET_FIELD_GEN (final, VTABLE_FINAL_FIELD)
307 VTAB_GET_FIELD_GEN (deallocate, VTABLE_DEALLOCATE_FIELD)
310 /* The size field is returned as an array index type. Therefore treat
311 it and only it specially. */
313 tree
314 gfc_class_vtab_size_get (tree cl)
316 tree size;
317 size = class_vtab_field_get (cl, VTABLE_SIZE_FIELD);
318 /* Always return size as an array index type. */
319 size = fold_convert (gfc_array_index_type, size);
320 gcc_assert (size);
321 return size;
324 tree
325 gfc_vptr_size_get (tree vptr)
327 tree size;
328 size = vptr_field_get (vptr, VTABLE_SIZE_FIELD);
329 /* Always return size as an array index type. */
330 size = fold_convert (gfc_array_index_type, size);
331 gcc_assert (size);
332 return size;
336 #undef CLASS_DATA_FIELD
337 #undef CLASS_VPTR_FIELD
338 #undef CLASS_LEN_FIELD
339 #undef VTABLE_HASH_FIELD
340 #undef VTABLE_SIZE_FIELD
341 #undef VTABLE_EXTENDS_FIELD
342 #undef VTABLE_DEF_INIT_FIELD
343 #undef VTABLE_COPY_FIELD
344 #undef VTABLE_FINAL_FIELD
347 /* Search for the last _class ref in the chain of references of this
348 expression and cut the chain there. Albeit this routine is similiar
349 to class.c::gfc_add_component_ref (), is there a significant
350 difference: gfc_add_component_ref () concentrates on an array ref to
351 be the last ref in the chain. This routine is oblivious to the kind
352 of refs following. */
354 gfc_expr *
355 gfc_find_and_cut_at_last_class_ref (gfc_expr *e)
357 gfc_expr *base_expr;
358 gfc_ref *ref, *class_ref, *tail = NULL, *array_ref;
360 /* Find the last class reference. */
361 class_ref = NULL;
362 array_ref = NULL;
363 for (ref = e->ref; ref; ref = ref->next)
365 if (ref->type == REF_ARRAY && ref->u.ar.type != AR_ELEMENT)
366 array_ref = ref;
368 if (ref->type == REF_COMPONENT
369 && ref->u.c.component->ts.type == BT_CLASS)
371 /* Component to the right of a part reference with nonzero rank
372 must not have the ALLOCATABLE attribute. If attempts are
373 made to reference such a component reference, an error results
374 followed by an ICE. */
375 if (array_ref && CLASS_DATA (ref->u.c.component)->attr.allocatable)
376 return NULL;
377 class_ref = ref;
380 if (ref->next == NULL)
381 break;
384 /* Remove and store all subsequent references after the
385 CLASS reference. */
386 if (class_ref)
388 tail = class_ref->next;
389 class_ref->next = NULL;
391 else if (e->symtree && e->symtree->n.sym->ts.type == BT_CLASS)
393 tail = e->ref;
394 e->ref = NULL;
397 base_expr = gfc_expr_to_initialize (e);
399 /* Restore the original tail expression. */
400 if (class_ref)
402 gfc_free_ref_list (class_ref->next);
403 class_ref->next = tail;
405 else if (e->symtree && e->symtree->n.sym->ts.type == BT_CLASS)
407 gfc_free_ref_list (e->ref);
408 e->ref = tail;
410 return base_expr;
414 /* Reset the vptr to the declared type, e.g. after deallocation. */
416 void
417 gfc_reset_vptr (stmtblock_t *block, gfc_expr *e)
419 gfc_symbol *vtab;
420 tree vptr;
421 tree vtable;
422 gfc_se se;
424 /* Evaluate the expression and obtain the vptr from it. */
425 gfc_init_se (&se, NULL);
426 if (e->rank)
427 gfc_conv_expr_descriptor (&se, e);
428 else
429 gfc_conv_expr (&se, e);
430 gfc_add_block_to_block (block, &se.pre);
431 vptr = gfc_get_vptr_from_expr (se.expr);
433 /* If a vptr is not found, we can do nothing more. */
434 if (vptr == NULL_TREE)
435 return;
437 if (UNLIMITED_POLY (e))
438 gfc_add_modify (block, vptr, build_int_cst (TREE_TYPE (vptr), 0));
439 else
441 /* Return the vptr to the address of the declared type. */
442 vtab = gfc_find_derived_vtab (e->ts.u.derived);
443 vtable = vtab->backend_decl;
444 if (vtable == NULL_TREE)
445 vtable = gfc_get_symbol_decl (vtab);
446 vtable = gfc_build_addr_expr (NULL, vtable);
447 vtable = fold_convert (TREE_TYPE (vptr), vtable);
448 gfc_add_modify (block, vptr, vtable);
453 /* Reset the len for unlimited polymorphic objects. */
455 void
456 gfc_reset_len (stmtblock_t *block, gfc_expr *expr)
458 gfc_expr *e;
459 gfc_se se_len;
460 e = gfc_find_and_cut_at_last_class_ref (expr);
461 if (e == NULL)
462 return;
463 gfc_add_len_component (e);
464 gfc_init_se (&se_len, NULL);
465 gfc_conv_expr (&se_len, e);
466 gfc_add_modify (block, se_len.expr,
467 fold_convert (TREE_TYPE (se_len.expr), integer_zero_node));
468 gfc_free_expr (e);
472 /* Obtain the vptr of the last class reference in an expression.
473 Return NULL_TREE if no class reference is found. */
475 tree
476 gfc_get_vptr_from_expr (tree expr)
478 tree tmp;
479 tree type;
481 for (tmp = expr; tmp; tmp = TREE_OPERAND (tmp, 0))
483 type = TREE_TYPE (tmp);
484 while (type)
486 if (GFC_CLASS_TYPE_P (type))
487 return gfc_class_vptr_get (tmp);
488 if (type != TYPE_CANONICAL (type))
489 type = TYPE_CANONICAL (type);
490 else
491 type = NULL_TREE;
493 if (VAR_P (tmp) || TREE_CODE (tmp) == PARM_DECL)
494 break;
497 if (POINTER_TYPE_P (TREE_TYPE (tmp)))
498 tmp = build_fold_indirect_ref_loc (input_location, tmp);
500 if (GFC_CLASS_TYPE_P (TREE_TYPE (tmp)))
501 return gfc_class_vptr_get (tmp);
503 return NULL_TREE;
507 static void
508 class_array_data_assign (stmtblock_t *block, tree lhs_desc, tree rhs_desc,
509 bool lhs_type)
511 tree tmp, tmp2, type;
513 gfc_conv_descriptor_data_set (block, lhs_desc,
514 gfc_conv_descriptor_data_get (rhs_desc));
515 gfc_conv_descriptor_offset_set (block, lhs_desc,
516 gfc_conv_descriptor_offset_get (rhs_desc));
518 gfc_add_modify (block, gfc_conv_descriptor_dtype (lhs_desc),
519 gfc_conv_descriptor_dtype (rhs_desc));
521 /* Assign the dimension as range-ref. */
522 tmp = gfc_get_descriptor_dimension (lhs_desc);
523 tmp2 = gfc_get_descriptor_dimension (rhs_desc);
525 type = lhs_type ? TREE_TYPE (tmp) : TREE_TYPE (tmp2);
526 tmp = build4_loc (input_location, ARRAY_RANGE_REF, type, tmp,
527 gfc_index_zero_node, NULL_TREE, NULL_TREE);
528 tmp2 = build4_loc (input_location, ARRAY_RANGE_REF, type, tmp2,
529 gfc_index_zero_node, NULL_TREE, NULL_TREE);
530 gfc_add_modify (block, tmp, tmp2);
534 /* Takes a derived type expression and returns the address of a temporary
535 class object of the 'declared' type. If vptr is not NULL, this is
536 used for the temporary class object.
537 optional_alloc_ptr is false when the dummy is neither allocatable
538 nor a pointer; that's only relevant for the optional handling. */
539 void
540 gfc_conv_derived_to_class (gfc_se *parmse, gfc_expr *e,
541 gfc_typespec class_ts, tree vptr, bool optional,
542 bool optional_alloc_ptr)
544 gfc_symbol *vtab;
545 tree cond_optional = NULL_TREE;
546 gfc_ss *ss;
547 tree ctree;
548 tree var;
549 tree tmp;
551 /* The derived type needs to be converted to a temporary
552 CLASS object. */
553 tmp = gfc_typenode_for_spec (&class_ts);
554 var = gfc_create_var (tmp, "class");
556 /* Set the vptr. */
557 ctree = gfc_class_vptr_get (var);
559 if (vptr != NULL_TREE)
561 /* Use the dynamic vptr. */
562 tmp = vptr;
564 else
566 /* In this case the vtab corresponds to the derived type and the
567 vptr must point to it. */
568 vtab = gfc_find_derived_vtab (e->ts.u.derived);
569 gcc_assert (vtab);
570 tmp = gfc_build_addr_expr (NULL_TREE, gfc_get_symbol_decl (vtab));
572 gfc_add_modify (&parmse->pre, ctree,
573 fold_convert (TREE_TYPE (ctree), tmp));
575 /* Now set the data field. */
576 ctree = gfc_class_data_get (var);
578 if (optional)
579 cond_optional = gfc_conv_expr_present (e->symtree->n.sym);
581 if (parmse->expr && POINTER_TYPE_P (TREE_TYPE (parmse->expr)))
583 /* If there is a ready made pointer to a derived type, use it
584 rather than evaluating the expression again. */
585 tmp = fold_convert (TREE_TYPE (ctree), parmse->expr);
586 gfc_add_modify (&parmse->pre, ctree, tmp);
588 else if (parmse->ss && parmse->ss->info && parmse->ss->info->useflags)
590 /* For an array reference in an elemental procedure call we need
591 to retain the ss to provide the scalarized array reference. */
592 gfc_conv_expr_reference (parmse, e);
593 tmp = fold_convert (TREE_TYPE (ctree), parmse->expr);
594 if (optional)
595 tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp),
596 cond_optional, tmp,
597 fold_convert (TREE_TYPE (tmp), null_pointer_node));
598 gfc_add_modify (&parmse->pre, ctree, tmp);
600 else
602 ss = gfc_walk_expr (e);
603 if (ss == gfc_ss_terminator)
605 parmse->ss = NULL;
606 gfc_conv_expr_reference (parmse, e);
608 /* Scalar to an assumed-rank array. */
609 if (class_ts.u.derived->components->as)
611 tree type;
612 type = get_scalar_to_descriptor_type (parmse->expr,
613 gfc_expr_attr (e));
614 gfc_add_modify (&parmse->pre, gfc_conv_descriptor_dtype (ctree),
615 gfc_get_dtype (type));
616 if (optional)
617 parmse->expr = build3_loc (input_location, COND_EXPR,
618 TREE_TYPE (parmse->expr),
619 cond_optional, parmse->expr,
620 fold_convert (TREE_TYPE (parmse->expr),
621 null_pointer_node));
622 gfc_conv_descriptor_data_set (&parmse->pre, ctree, parmse->expr);
624 else
626 tmp = fold_convert (TREE_TYPE (ctree), parmse->expr);
627 if (optional)
628 tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp),
629 cond_optional, tmp,
630 fold_convert (TREE_TYPE (tmp),
631 null_pointer_node));
632 gfc_add_modify (&parmse->pre, ctree, tmp);
635 else
637 stmtblock_t block;
638 gfc_init_block (&block);
640 parmse->ss = ss;
641 gfc_conv_expr_descriptor (parmse, e);
643 if (e->rank != class_ts.u.derived->components->as->rank)
645 gcc_assert (class_ts.u.derived->components->as->type
646 == AS_ASSUMED_RANK);
647 class_array_data_assign (&block, ctree, parmse->expr, false);
649 else
651 if (gfc_expr_attr (e).codimension)
652 parmse->expr = fold_build1_loc (input_location,
653 VIEW_CONVERT_EXPR,
654 TREE_TYPE (ctree),
655 parmse->expr);
656 gfc_add_modify (&block, ctree, parmse->expr);
659 if (optional)
661 tmp = gfc_finish_block (&block);
663 gfc_init_block (&block);
664 gfc_conv_descriptor_data_set (&block, ctree, null_pointer_node);
666 tmp = build3_v (COND_EXPR, cond_optional, tmp,
667 gfc_finish_block (&block));
668 gfc_add_expr_to_block (&parmse->pre, tmp);
670 else
671 gfc_add_block_to_block (&parmse->pre, &block);
675 if (class_ts.u.derived->components->ts.type == BT_DERIVED
676 && class_ts.u.derived->components->ts.u.derived
677 ->attr.unlimited_polymorphic)
679 /* Take care about initializing the _len component correctly. */
680 ctree = gfc_class_len_get (var);
681 if (UNLIMITED_POLY (e))
683 gfc_expr *len;
684 gfc_se se;
686 len = gfc_copy_expr (e);
687 gfc_add_len_component (len);
688 gfc_init_se (&se, NULL);
689 gfc_conv_expr (&se, len);
690 if (optional)
691 tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (se.expr),
692 cond_optional, se.expr,
693 fold_convert (TREE_TYPE (se.expr),
694 integer_zero_node));
695 else
696 tmp = se.expr;
698 else
699 tmp = integer_zero_node;
700 gfc_add_modify (&parmse->pre, ctree, fold_convert (TREE_TYPE (ctree),
701 tmp));
703 /* Pass the address of the class object. */
704 parmse->expr = gfc_build_addr_expr (NULL_TREE, var);
706 if (optional && optional_alloc_ptr)
707 parmse->expr = build3_loc (input_location, COND_EXPR,
708 TREE_TYPE (parmse->expr),
709 cond_optional, parmse->expr,
710 fold_convert (TREE_TYPE (parmse->expr),
711 null_pointer_node));
715 /* Create a new class container, which is required as scalar coarrays
716 have an array descriptor while normal scalars haven't. Optionally,
717 NULL pointer checks are added if the argument is OPTIONAL. */
719 static void
720 class_scalar_coarray_to_class (gfc_se *parmse, gfc_expr *e,
721 gfc_typespec class_ts, bool optional)
723 tree var, ctree, tmp;
724 stmtblock_t block;
725 gfc_ref *ref;
726 gfc_ref *class_ref;
728 gfc_init_block (&block);
730 class_ref = NULL;
731 for (ref = e->ref; ref; ref = ref->next)
733 if (ref->type == REF_COMPONENT
734 && ref->u.c.component->ts.type == BT_CLASS)
735 class_ref = ref;
738 if (class_ref == NULL
739 && e->symtree && e->symtree->n.sym->ts.type == BT_CLASS)
740 tmp = e->symtree->n.sym->backend_decl;
741 else
743 /* Remove everything after the last class reference, convert the
744 expression and then recover its tailend once more. */
745 gfc_se tmpse;
746 ref = class_ref->next;
747 class_ref->next = NULL;
748 gfc_init_se (&tmpse, NULL);
749 gfc_conv_expr (&tmpse, e);
750 class_ref->next = ref;
751 tmp = tmpse.expr;
754 var = gfc_typenode_for_spec (&class_ts);
755 var = gfc_create_var (var, "class");
757 ctree = gfc_class_vptr_get (var);
758 gfc_add_modify (&block, ctree,
759 fold_convert (TREE_TYPE (ctree), gfc_class_vptr_get (tmp)));
761 ctree = gfc_class_data_get (var);
762 tmp = gfc_conv_descriptor_data_get (gfc_class_data_get (tmp));
763 gfc_add_modify (&block, ctree, fold_convert (TREE_TYPE (ctree), tmp));
765 /* Pass the address of the class object. */
766 parmse->expr = gfc_build_addr_expr (NULL_TREE, var);
768 if (optional)
770 tree cond = gfc_conv_expr_present (e->symtree->n.sym);
771 tree tmp2;
773 tmp = gfc_finish_block (&block);
775 gfc_init_block (&block);
776 tmp2 = gfc_class_data_get (var);
777 gfc_add_modify (&block, tmp2, fold_convert (TREE_TYPE (tmp2),
778 null_pointer_node));
779 tmp2 = gfc_finish_block (&block);
781 tmp = build3_loc (input_location, COND_EXPR, void_type_node,
782 cond, tmp, tmp2);
783 gfc_add_expr_to_block (&parmse->pre, tmp);
785 else
786 gfc_add_block_to_block (&parmse->pre, &block);
790 /* Takes an intrinsic type expression and returns the address of a temporary
791 class object of the 'declared' type. */
792 void
793 gfc_conv_intrinsic_to_class (gfc_se *parmse, gfc_expr *e,
794 gfc_typespec class_ts)
796 gfc_symbol *vtab;
797 gfc_ss *ss;
798 tree ctree;
799 tree var;
800 tree tmp;
802 /* The intrinsic type needs to be converted to a temporary
803 CLASS object. */
804 tmp = gfc_typenode_for_spec (&class_ts);
805 var = gfc_create_var (tmp, "class");
807 /* Set the vptr. */
808 ctree = gfc_class_vptr_get (var);
810 vtab = gfc_find_vtab (&e->ts);
811 gcc_assert (vtab);
812 tmp = gfc_build_addr_expr (NULL_TREE, gfc_get_symbol_decl (vtab));
813 gfc_add_modify (&parmse->pre, ctree,
814 fold_convert (TREE_TYPE (ctree), tmp));
816 /* Now set the data field. */
817 ctree = gfc_class_data_get (var);
818 if (parmse->ss && parmse->ss->info->useflags)
820 /* For an array reference in an elemental procedure call we need
821 to retain the ss to provide the scalarized array reference. */
822 gfc_conv_expr_reference (parmse, e);
823 tmp = fold_convert (TREE_TYPE (ctree), parmse->expr);
824 gfc_add_modify (&parmse->pre, ctree, tmp);
826 else
828 ss = gfc_walk_expr (e);
829 if (ss == gfc_ss_terminator)
831 parmse->ss = NULL;
832 gfc_conv_expr_reference (parmse, e);
833 if (class_ts.u.derived->components->as
834 && class_ts.u.derived->components->as->type == AS_ASSUMED_RANK)
836 tmp = gfc_conv_scalar_to_descriptor (parmse, parmse->expr,
837 gfc_expr_attr (e));
838 tmp = fold_build1_loc (input_location, VIEW_CONVERT_EXPR,
839 TREE_TYPE (ctree), tmp);
841 else
842 tmp = fold_convert (TREE_TYPE (ctree), parmse->expr);
843 gfc_add_modify (&parmse->pre, ctree, tmp);
845 else
847 parmse->ss = ss;
848 parmse->use_offset = 1;
849 gfc_conv_expr_descriptor (parmse, e);
850 if (class_ts.u.derived->components->as->rank != e->rank)
852 tmp = fold_build1_loc (input_location, VIEW_CONVERT_EXPR,
853 TREE_TYPE (ctree), parmse->expr);
854 gfc_add_modify (&parmse->pre, ctree, tmp);
856 else
857 gfc_add_modify (&parmse->pre, ctree, parmse->expr);
861 gcc_assert (class_ts.type == BT_CLASS);
862 if (class_ts.u.derived->components->ts.type == BT_DERIVED
863 && class_ts.u.derived->components->ts.u.derived
864 ->attr.unlimited_polymorphic)
866 ctree = gfc_class_len_get (var);
867 /* When the actual arg is a char array, then set the _len component of the
868 unlimited polymorphic entity to the length of the string. */
869 if (e->ts.type == BT_CHARACTER)
871 /* Start with parmse->string_length because this seems to be set to a
872 correct value more often. */
873 if (parmse->string_length)
874 tmp = parmse->string_length;
875 /* When the string_length is not yet set, then try the backend_decl of
876 the cl. */
877 else if (e->ts.u.cl->backend_decl)
878 tmp = e->ts.u.cl->backend_decl;
879 /* If both of the above approaches fail, then try to generate an
880 expression from the input, which is only feasible currently, when the
881 expression can be evaluated to a constant one. */
882 else
884 /* Try to simplify the expression. */
885 gfc_simplify_expr (e, 0);
886 if (e->expr_type == EXPR_CONSTANT && !e->ts.u.cl->resolved)
888 /* Amazingly all data is present to compute the length of a
889 constant string, but the expression is not yet there. */
890 e->ts.u.cl->length = gfc_get_constant_expr (BT_INTEGER,
891 gfc_charlen_int_kind,
892 &e->where);
893 mpz_set_ui (e->ts.u.cl->length->value.integer,
894 e->value.character.length);
895 gfc_conv_const_charlen (e->ts.u.cl);
896 e->ts.u.cl->resolved = 1;
897 tmp = e->ts.u.cl->backend_decl;
899 else
901 gfc_error ("Can't compute the length of the char array at %L.",
902 &e->where);
906 else
907 tmp = integer_zero_node;
909 gfc_add_modify (&parmse->pre, ctree, fold_convert (TREE_TYPE (ctree), tmp));
911 else if (class_ts.type == BT_CLASS
912 && class_ts.u.derived->components
913 && class_ts.u.derived->components->ts.u
914 .derived->attr.unlimited_polymorphic)
916 ctree = gfc_class_len_get (var);
917 gfc_add_modify (&parmse->pre, ctree,
918 fold_convert (TREE_TYPE (ctree),
919 integer_zero_node));
921 /* Pass the address of the class object. */
922 parmse->expr = gfc_build_addr_expr (NULL_TREE, var);
926 /* Takes a scalarized class array expression and returns the
927 address of a temporary scalar class object of the 'declared'
928 type.
929 OOP-TODO: This could be improved by adding code that branched on
930 the dynamic type being the same as the declared type. In this case
931 the original class expression can be passed directly.
932 optional_alloc_ptr is false when the dummy is neither allocatable
933 nor a pointer; that's relevant for the optional handling.
934 Set copyback to true if class container's _data and _vtab pointers
935 might get modified. */
937 void
938 gfc_conv_class_to_class (gfc_se *parmse, gfc_expr *e, gfc_typespec class_ts,
939 bool elemental, bool copyback, bool optional,
940 bool optional_alloc_ptr)
942 tree ctree;
943 tree var;
944 tree tmp;
945 tree vptr;
946 tree cond = NULL_TREE;
947 tree slen = NULL_TREE;
948 gfc_ref *ref;
949 gfc_ref *class_ref;
950 stmtblock_t block;
951 bool full_array = false;
953 gfc_init_block (&block);
955 class_ref = NULL;
956 for (ref = e->ref; ref; ref = ref->next)
958 if (ref->type == REF_COMPONENT
959 && ref->u.c.component->ts.type == BT_CLASS)
960 class_ref = ref;
962 if (ref->next == NULL)
963 break;
966 if ((ref == NULL || class_ref == ref)
967 && !(gfc_is_class_array_function (e) && parmse->class_vptr != NULL_TREE)
968 && (!class_ts.u.derived->components->as
969 || class_ts.u.derived->components->as->rank != -1))
970 return;
972 /* Test for FULL_ARRAY. */
973 if (e->rank == 0 && gfc_expr_attr (e).codimension
974 && gfc_expr_attr (e).dimension)
975 full_array = true;
976 else
977 gfc_is_class_array_ref (e, &full_array);
979 /* The derived type needs to be converted to a temporary
980 CLASS object. */
981 tmp = gfc_typenode_for_spec (&class_ts);
982 var = gfc_create_var (tmp, "class");
984 /* Set the data. */
985 ctree = gfc_class_data_get (var);
986 if (class_ts.u.derived->components->as
987 && e->rank != class_ts.u.derived->components->as->rank)
989 if (e->rank == 0)
991 tree type = get_scalar_to_descriptor_type (parmse->expr,
992 gfc_expr_attr (e));
993 gfc_add_modify (&block, gfc_conv_descriptor_dtype (ctree),
994 gfc_get_dtype (type));
996 tmp = gfc_class_data_get (parmse->expr);
997 if (!POINTER_TYPE_P (TREE_TYPE (tmp)))
998 tmp = gfc_build_addr_expr (NULL_TREE, tmp);
1000 gfc_conv_descriptor_data_set (&block, ctree, tmp);
1002 else
1003 class_array_data_assign (&block, ctree, parmse->expr, false);
1005 else
1007 if (TREE_TYPE (parmse->expr) != TREE_TYPE (ctree))
1008 parmse->expr = fold_build1_loc (input_location, VIEW_CONVERT_EXPR,
1009 TREE_TYPE (ctree), parmse->expr);
1010 gfc_add_modify (&block, ctree, parmse->expr);
1013 /* Return the data component, except in the case of scalarized array
1014 references, where nullification of the cannot occur and so there
1015 is no need. */
1016 if (!elemental && full_array && copyback)
1018 if (class_ts.u.derived->components->as
1019 && e->rank != class_ts.u.derived->components->as->rank)
1021 if (e->rank == 0)
1022 gfc_add_modify (&parmse->post, gfc_class_data_get (parmse->expr),
1023 gfc_conv_descriptor_data_get (ctree));
1024 else
1025 class_array_data_assign (&parmse->post, parmse->expr, ctree, true);
1027 else
1028 gfc_add_modify (&parmse->post, parmse->expr, ctree);
1031 /* Set the vptr. */
1032 ctree = gfc_class_vptr_get (var);
1034 /* The vptr is the second field of the actual argument.
1035 First we have to find the corresponding class reference. */
1037 tmp = NULL_TREE;
1038 if (gfc_is_class_array_function (e)
1039 && parmse->class_vptr != NULL_TREE)
1040 tmp = parmse->class_vptr;
1041 else if (class_ref == NULL
1042 && e->symtree && e->symtree->n.sym->ts.type == BT_CLASS)
1044 tmp = e->symtree->n.sym->backend_decl;
1046 if (TREE_CODE (tmp) == FUNCTION_DECL)
1047 tmp = gfc_get_fake_result_decl (e->symtree->n.sym, 0);
1049 if (DECL_LANG_SPECIFIC (tmp) && GFC_DECL_SAVED_DESCRIPTOR (tmp))
1050 tmp = GFC_DECL_SAVED_DESCRIPTOR (tmp);
1052 slen = build_zero_cst (size_type_node);
1054 else
1056 /* Remove everything after the last class reference, convert the
1057 expression and then recover its tailend once more. */
1058 gfc_se tmpse;
1059 ref = class_ref->next;
1060 class_ref->next = NULL;
1061 gfc_init_se (&tmpse, NULL);
1062 gfc_conv_expr (&tmpse, e);
1063 class_ref->next = ref;
1064 tmp = tmpse.expr;
1065 slen = tmpse.string_length;
1068 gcc_assert (tmp != NULL_TREE);
1070 /* Dereference if needs be. */
1071 if (TREE_CODE (TREE_TYPE (tmp)) == REFERENCE_TYPE)
1072 tmp = build_fold_indirect_ref_loc (input_location, tmp);
1074 if (!(gfc_is_class_array_function (e) && parmse->class_vptr))
1075 vptr = gfc_class_vptr_get (tmp);
1076 else
1077 vptr = tmp;
1079 gfc_add_modify (&block, ctree,
1080 fold_convert (TREE_TYPE (ctree), vptr));
1082 /* Return the vptr component, except in the case of scalarized array
1083 references, where the dynamic type cannot change. */
1084 if (!elemental && full_array && copyback)
1085 gfc_add_modify (&parmse->post, vptr,
1086 fold_convert (TREE_TYPE (vptr), ctree));
1088 /* For unlimited polymorphic objects also set the _len component. */
1089 if (class_ts.type == BT_CLASS
1090 && class_ts.u.derived->components
1091 && class_ts.u.derived->components->ts.u
1092 .derived->attr.unlimited_polymorphic)
1094 ctree = gfc_class_len_get (var);
1095 if (UNLIMITED_POLY (e))
1096 tmp = gfc_class_len_get (tmp);
1097 else if (e->ts.type == BT_CHARACTER)
1099 gcc_assert (slen != NULL_TREE);
1100 tmp = slen;
1102 else
1103 tmp = build_zero_cst (size_type_node);
1104 gfc_add_modify (&parmse->pre, ctree,
1105 fold_convert (TREE_TYPE (ctree), tmp));
1107 /* Return the len component, except in the case of scalarized array
1108 references, where the dynamic type cannot change. */
1109 if (!elemental && full_array && copyback)
1110 gfc_add_modify (&parmse->post, tmp,
1111 fold_convert (TREE_TYPE (tmp), ctree));
1114 if (optional)
1116 tree tmp2;
1118 cond = gfc_conv_expr_present (e->symtree->n.sym);
1119 /* parmse->pre may contain some preparatory instructions for the
1120 temporary array descriptor. Those may only be executed when the
1121 optional argument is set, therefore add parmse->pre's instructions
1122 to block, which is later guarded by an if (optional_arg_given). */
1123 gfc_add_block_to_block (&parmse->pre, &block);
1124 block.head = parmse->pre.head;
1125 parmse->pre.head = NULL_TREE;
1126 tmp = gfc_finish_block (&block);
1128 if (optional_alloc_ptr)
1129 tmp2 = build_empty_stmt (input_location);
1130 else
1132 gfc_init_block (&block);
1134 tmp2 = gfc_conv_descriptor_data_get (gfc_class_data_get (var));
1135 gfc_add_modify (&block, tmp2, fold_convert (TREE_TYPE (tmp2),
1136 null_pointer_node));
1137 tmp2 = gfc_finish_block (&block);
1140 tmp = build3_loc (input_location, COND_EXPR, void_type_node,
1141 cond, tmp, tmp2);
1142 gfc_add_expr_to_block (&parmse->pre, tmp);
1144 else
1145 gfc_add_block_to_block (&parmse->pre, &block);
1147 /* Pass the address of the class object. */
1148 parmse->expr = gfc_build_addr_expr (NULL_TREE, var);
1150 if (optional && optional_alloc_ptr)
1151 parmse->expr = build3_loc (input_location, COND_EXPR,
1152 TREE_TYPE (parmse->expr),
1153 cond, parmse->expr,
1154 fold_convert (TREE_TYPE (parmse->expr),
1155 null_pointer_node));
1159 /* Given a class array declaration and an index, returns the address
1160 of the referenced element. */
1162 tree
1163 gfc_get_class_array_ref (tree index, tree class_decl, tree data_comp)
1165 tree data = data_comp != NULL_TREE ? data_comp :
1166 gfc_class_data_get (class_decl);
1167 tree size = gfc_class_vtab_size_get (class_decl);
1168 tree offset = fold_build2_loc (input_location, MULT_EXPR,
1169 gfc_array_index_type,
1170 index, size);
1171 tree ptr;
1172 data = gfc_conv_descriptor_data_get (data);
1173 ptr = fold_convert (pvoid_type_node, data);
1174 ptr = fold_build_pointer_plus_loc (input_location, ptr, offset);
1175 return fold_convert (TREE_TYPE (data), ptr);
1179 /* Copies one class expression to another, assuming that if either
1180 'to' or 'from' are arrays they are packed. Should 'from' be
1181 NULL_TREE, the initialization expression for 'to' is used, assuming
1182 that the _vptr is set. */
1184 tree
1185 gfc_copy_class_to_class (tree from, tree to, tree nelems, bool unlimited)
1187 tree fcn;
1188 tree fcn_type;
1189 tree from_data;
1190 tree from_len;
1191 tree to_data;
1192 tree to_len;
1193 tree to_ref;
1194 tree from_ref;
1195 vec<tree, va_gc> *args;
1196 tree tmp;
1197 tree stdcopy;
1198 tree extcopy;
1199 tree index;
1200 bool is_from_desc = false, is_to_class = false;
1202 args = NULL;
1203 /* To prevent warnings on uninitialized variables. */
1204 from_len = to_len = NULL_TREE;
1206 if (from != NULL_TREE)
1207 fcn = gfc_class_vtab_copy_get (from);
1208 else
1209 fcn = gfc_class_vtab_copy_get (to);
1211 fcn_type = TREE_TYPE (TREE_TYPE (fcn));
1213 if (from != NULL_TREE)
1215 is_from_desc = GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (from));
1216 if (is_from_desc)
1218 from_data = from;
1219 from = GFC_DECL_SAVED_DESCRIPTOR (from);
1221 else
1223 /* Check that from is a class. When the class is part of a coarray,
1224 then from is a common pointer and is to be used as is. */
1225 tmp = POINTER_TYPE_P (TREE_TYPE (from))
1226 ? build_fold_indirect_ref (from) : from;
1227 from_data =
1228 (GFC_CLASS_TYPE_P (TREE_TYPE (tmp))
1229 || (DECL_P (tmp) && GFC_DECL_CLASS (tmp)))
1230 ? gfc_class_data_get (from) : from;
1231 is_from_desc = GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (from_data));
1234 else
1235 from_data = gfc_class_vtab_def_init_get (to);
1237 if (unlimited)
1239 if (from != NULL_TREE && unlimited)
1240 from_len = gfc_class_len_or_zero_get (from);
1241 else
1242 from_len = build_zero_cst (size_type_node);
1245 if (GFC_CLASS_TYPE_P (TREE_TYPE (to)))
1247 is_to_class = true;
1248 to_data = gfc_class_data_get (to);
1249 if (unlimited)
1250 to_len = gfc_class_len_get (to);
1252 else
1253 /* When to is a BT_DERIVED and not a BT_CLASS, then to_data == to. */
1254 to_data = to;
1256 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (to_data)))
1258 stmtblock_t loopbody;
1259 stmtblock_t body;
1260 stmtblock_t ifbody;
1261 gfc_loopinfo loop;
1262 tree orig_nelems = nelems; /* Needed for bounds check. */
1264 gfc_init_block (&body);
1265 tmp = fold_build2_loc (input_location, MINUS_EXPR,
1266 gfc_array_index_type, nelems,
1267 gfc_index_one_node);
1268 nelems = gfc_evaluate_now (tmp, &body);
1269 index = gfc_create_var (gfc_array_index_type, "S");
1271 if (is_from_desc)
1273 from_ref = gfc_get_class_array_ref (index, from, from_data);
1274 vec_safe_push (args, from_ref);
1276 else
1277 vec_safe_push (args, from_data);
1279 if (is_to_class)
1280 to_ref = gfc_get_class_array_ref (index, to, to_data);
1281 else
1283 tmp = gfc_conv_array_data (to);
1284 tmp = build_fold_indirect_ref_loc (input_location, tmp);
1285 to_ref = gfc_build_addr_expr (NULL_TREE,
1286 gfc_build_array_ref (tmp, index, to));
1288 vec_safe_push (args, to_ref);
1290 /* Add bounds check. */
1291 if ((gfc_option.rtcheck & GFC_RTCHECK_BOUNDS) > 0 && is_from_desc)
1293 char *msg;
1294 const char *name = "<<unknown>>";
1295 tree from_len;
1297 if (DECL_P (to))
1298 name = (const char *)(DECL_NAME (to)->identifier.id.str);
1300 from_len = gfc_conv_descriptor_size (from_data, 1);
1301 tmp = fold_build2_loc (input_location, NE_EXPR,
1302 logical_type_node, from_len, orig_nelems);
1303 msg = xasprintf ("Array bound mismatch for dimension %d "
1304 "of array '%s' (%%ld/%%ld)",
1305 1, name);
1307 gfc_trans_runtime_check (true, false, tmp, &body,
1308 &gfc_current_locus, msg,
1309 fold_convert (long_integer_type_node, orig_nelems),
1310 fold_convert (long_integer_type_node, from_len));
1312 free (msg);
1315 tmp = build_call_vec (fcn_type, fcn, args);
1317 /* Build the body of the loop. */
1318 gfc_init_block (&loopbody);
1319 gfc_add_expr_to_block (&loopbody, tmp);
1321 /* Build the loop and return. */
1322 gfc_init_loopinfo (&loop);
1323 loop.dimen = 1;
1324 loop.from[0] = gfc_index_zero_node;
1325 loop.loopvar[0] = index;
1326 loop.to[0] = nelems;
1327 gfc_trans_scalarizing_loops (&loop, &loopbody);
1328 gfc_init_block (&ifbody);
1329 gfc_add_block_to_block (&ifbody, &loop.pre);
1330 stdcopy = gfc_finish_block (&ifbody);
1331 /* In initialization mode from_len is a constant zero. */
1332 if (unlimited && !integer_zerop (from_len))
1334 vec_safe_push (args, from_len);
1335 vec_safe_push (args, to_len);
1336 tmp = build_call_vec (fcn_type, fcn, args);
1337 /* Build the body of the loop. */
1338 gfc_init_block (&loopbody);
1339 gfc_add_expr_to_block (&loopbody, tmp);
1341 /* Build the loop and return. */
1342 gfc_init_loopinfo (&loop);
1343 loop.dimen = 1;
1344 loop.from[0] = gfc_index_zero_node;
1345 loop.loopvar[0] = index;
1346 loop.to[0] = nelems;
1347 gfc_trans_scalarizing_loops (&loop, &loopbody);
1348 gfc_init_block (&ifbody);
1349 gfc_add_block_to_block (&ifbody, &loop.pre);
1350 extcopy = gfc_finish_block (&ifbody);
1352 tmp = fold_build2_loc (input_location, GT_EXPR,
1353 logical_type_node, from_len,
1354 build_zero_cst (TREE_TYPE (from_len)));
1355 tmp = fold_build3_loc (input_location, COND_EXPR,
1356 void_type_node, tmp, extcopy, stdcopy);
1357 gfc_add_expr_to_block (&body, tmp);
1358 tmp = gfc_finish_block (&body);
1360 else
1362 gfc_add_expr_to_block (&body, stdcopy);
1363 tmp = gfc_finish_block (&body);
1365 gfc_cleanup_loop (&loop);
1367 else
1369 gcc_assert (!is_from_desc);
1370 vec_safe_push (args, from_data);
1371 vec_safe_push (args, to_data);
1372 stdcopy = build_call_vec (fcn_type, fcn, args);
1374 /* In initialization mode from_len is a constant zero. */
1375 if (unlimited && !integer_zerop (from_len))
1377 vec_safe_push (args, from_len);
1378 vec_safe_push (args, to_len);
1379 extcopy = build_call_vec (fcn_type, fcn, args);
1380 tmp = fold_build2_loc (input_location, GT_EXPR,
1381 logical_type_node, from_len,
1382 build_zero_cst (TREE_TYPE (from_len)));
1383 tmp = fold_build3_loc (input_location, COND_EXPR,
1384 void_type_node, tmp, extcopy, stdcopy);
1386 else
1387 tmp = stdcopy;
1390 /* Only copy _def_init to to_data, when it is not a NULL-pointer. */
1391 if (from == NULL_TREE)
1393 tree cond;
1394 cond = fold_build2_loc (input_location, NE_EXPR,
1395 logical_type_node,
1396 from_data, null_pointer_node);
1397 tmp = fold_build3_loc (input_location, COND_EXPR,
1398 void_type_node, cond,
1399 tmp, build_empty_stmt (input_location));
1402 return tmp;
1406 static tree
1407 gfc_trans_class_array_init_assign (gfc_expr *rhs, gfc_expr *lhs, gfc_expr *obj)
1409 gfc_actual_arglist *actual;
1410 gfc_expr *ppc;
1411 gfc_code *ppc_code;
1412 tree res;
1414 actual = gfc_get_actual_arglist ();
1415 actual->expr = gfc_copy_expr (rhs);
1416 actual->next = gfc_get_actual_arglist ();
1417 actual->next->expr = gfc_copy_expr (lhs);
1418 ppc = gfc_copy_expr (obj);
1419 gfc_add_vptr_component (ppc);
1420 gfc_add_component_ref (ppc, "_copy");
1421 ppc_code = gfc_get_code (EXEC_CALL);
1422 ppc_code->resolved_sym = ppc->symtree->n.sym;
1423 /* Although '_copy' is set to be elemental in class.c, it is
1424 not staying that way. Find out why, sometime.... */
1425 ppc_code->resolved_sym->attr.elemental = 1;
1426 ppc_code->ext.actual = actual;
1427 ppc_code->expr1 = ppc;
1428 /* Since '_copy' is elemental, the scalarizer will take care
1429 of arrays in gfc_trans_call. */
1430 res = gfc_trans_call (ppc_code, false, NULL, NULL, false);
1431 gfc_free_statements (ppc_code);
1433 if (UNLIMITED_POLY(obj))
1435 /* Check if rhs is non-NULL. */
1436 gfc_se src;
1437 gfc_init_se (&src, NULL);
1438 gfc_conv_expr (&src, rhs);
1439 src.expr = gfc_build_addr_expr (NULL_TREE, src.expr);
1440 tree cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
1441 src.expr, fold_convert (TREE_TYPE (src.expr),
1442 null_pointer_node));
1443 res = build3_loc (input_location, COND_EXPR, TREE_TYPE (res), cond, res,
1444 build_empty_stmt (input_location));
1447 return res;
1450 /* Special case for initializing a polymorphic dummy with INTENT(OUT).
1451 A MEMCPY is needed to copy the full data from the default initializer
1452 of the dynamic type. */
1454 tree
1455 gfc_trans_class_init_assign (gfc_code *code)
1457 stmtblock_t block;
1458 tree tmp;
1459 gfc_se dst,src,memsz;
1460 gfc_expr *lhs, *rhs, *sz;
1462 gfc_start_block (&block);
1464 lhs = gfc_copy_expr (code->expr1);
1465 gfc_add_data_component (lhs);
1467 rhs = gfc_copy_expr (code->expr1);
1468 gfc_add_vptr_component (rhs);
1470 /* Make sure that the component backend_decls have been built, which
1471 will not have happened if the derived types concerned have not
1472 been referenced. */
1473 gfc_get_derived_type (rhs->ts.u.derived);
1474 gfc_add_def_init_component (rhs);
1475 /* The _def_init is always scalar. */
1476 rhs->rank = 0;
1478 if (code->expr1->ts.type == BT_CLASS
1479 && CLASS_DATA (code->expr1)->attr.dimension)
1481 gfc_array_spec *tmparr = gfc_get_array_spec ();
1482 *tmparr = *CLASS_DATA (code->expr1)->as;
1483 gfc_add_full_array_ref (lhs, tmparr);
1484 tmp = gfc_trans_class_array_init_assign (rhs, lhs, code->expr1);
1486 else
1488 sz = gfc_copy_expr (code->expr1);
1489 gfc_add_vptr_component (sz);
1490 gfc_add_size_component (sz);
1492 gfc_init_se (&dst, NULL);
1493 gfc_init_se (&src, NULL);
1494 gfc_init_se (&memsz, NULL);
1495 gfc_conv_expr (&dst, lhs);
1496 gfc_conv_expr (&src, rhs);
1497 gfc_conv_expr (&memsz, sz);
1498 gfc_add_block_to_block (&block, &src.pre);
1499 src.expr = gfc_build_addr_expr (NULL_TREE, src.expr);
1501 tmp = gfc_build_memcpy_call (dst.expr, src.expr, memsz.expr);
1503 if (UNLIMITED_POLY(code->expr1))
1505 /* Check if _def_init is non-NULL. */
1506 tree cond = fold_build2_loc (input_location, NE_EXPR,
1507 logical_type_node, src.expr,
1508 fold_convert (TREE_TYPE (src.expr),
1509 null_pointer_node));
1510 tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp), cond,
1511 tmp, build_empty_stmt (input_location));
1515 if (code->expr1->symtree->n.sym->attr.optional
1516 || code->expr1->symtree->n.sym->ns->proc_name->attr.entry_master)
1518 tree present = gfc_conv_expr_present (code->expr1->symtree->n.sym);
1519 tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp),
1520 present, tmp,
1521 build_empty_stmt (input_location));
1524 gfc_add_expr_to_block (&block, tmp);
1526 return gfc_finish_block (&block);
1530 /* End of prototype trans-class.c */
1533 static void
1534 realloc_lhs_warning (bt type, bool array, locus *where)
1536 if (array && type != BT_CLASS && type != BT_DERIVED && warn_realloc_lhs)
1537 gfc_warning (OPT_Wrealloc_lhs,
1538 "Code for reallocating the allocatable array at %L will "
1539 "be added", where);
1540 else if (warn_realloc_lhs_all)
1541 gfc_warning (OPT_Wrealloc_lhs_all,
1542 "Code for reallocating the allocatable variable at %L "
1543 "will be added", where);
1547 static void gfc_apply_interface_mapping_to_expr (gfc_interface_mapping *,
1548 gfc_expr *);
1550 /* Copy the scalarization loop variables. */
1552 static void
1553 gfc_copy_se_loopvars (gfc_se * dest, gfc_se * src)
1555 dest->ss = src->ss;
1556 dest->loop = src->loop;
1560 /* Initialize a simple expression holder.
1562 Care must be taken when multiple se are created with the same parent.
1563 The child se must be kept in sync. The easiest way is to delay creation
1564 of a child se until after after the previous se has been translated. */
1566 void
1567 gfc_init_se (gfc_se * se, gfc_se * parent)
1569 memset (se, 0, sizeof (gfc_se));
1570 gfc_init_block (&se->pre);
1571 gfc_init_block (&se->post);
1573 se->parent = parent;
1575 if (parent)
1576 gfc_copy_se_loopvars (se, parent);
1580 /* Advances to the next SS in the chain. Use this rather than setting
1581 se->ss = se->ss->next because all the parents needs to be kept in sync.
1582 See gfc_init_se. */
1584 void
1585 gfc_advance_se_ss_chain (gfc_se * se)
1587 gfc_se *p;
1588 gfc_ss *ss;
1590 gcc_assert (se != NULL && se->ss != NULL && se->ss != gfc_ss_terminator);
1592 p = se;
1593 /* Walk down the parent chain. */
1594 while (p != NULL)
1596 /* Simple consistency check. */
1597 gcc_assert (p->parent == NULL || p->parent->ss == p->ss
1598 || p->parent->ss->nested_ss == p->ss);
1600 /* If we were in a nested loop, the next scalarized expression can be
1601 on the parent ss' next pointer. Thus we should not take the next
1602 pointer blindly, but rather go up one nest level as long as next
1603 is the end of chain. */
1604 ss = p->ss;
1605 while (ss->next == gfc_ss_terminator && ss->parent != NULL)
1606 ss = ss->parent;
1608 p->ss = ss->next;
1610 p = p->parent;
1615 /* Ensures the result of the expression as either a temporary variable
1616 or a constant so that it can be used repeatedly. */
1618 void
1619 gfc_make_safe_expr (gfc_se * se)
1621 tree var;
1623 if (CONSTANT_CLASS_P (se->expr))
1624 return;
1626 /* We need a temporary for this result. */
1627 var = gfc_create_var (TREE_TYPE (se->expr), NULL);
1628 gfc_add_modify (&se->pre, var, se->expr);
1629 se->expr = var;
1633 /* Return an expression which determines if a dummy parameter is present.
1634 Also used for arguments to procedures with multiple entry points. */
1636 tree
1637 gfc_conv_expr_present (gfc_symbol * sym)
1639 tree decl, cond;
1641 gcc_assert (sym->attr.dummy);
1642 decl = gfc_get_symbol_decl (sym);
1644 /* Intrinsic scalars with VALUE attribute which are passed by value
1645 use a hidden argument to denote the present status. */
1646 if (sym->attr.value && sym->ts.type != BT_CHARACTER
1647 && sym->ts.type != BT_CLASS && sym->ts.type != BT_DERIVED
1648 && !sym->attr.dimension)
1650 char name[GFC_MAX_SYMBOL_LEN + 2];
1651 tree tree_name;
1653 gcc_assert (TREE_CODE (decl) == PARM_DECL);
1654 name[0] = '_';
1655 strcpy (&name[1], sym->name);
1656 tree_name = get_identifier (name);
1658 /* Walk function argument list to find hidden arg. */
1659 cond = DECL_ARGUMENTS (DECL_CONTEXT (decl));
1660 for ( ; cond != NULL_TREE; cond = TREE_CHAIN (cond))
1661 if (DECL_NAME (cond) == tree_name)
1662 break;
1664 gcc_assert (cond);
1665 return cond;
1668 if (TREE_CODE (decl) != PARM_DECL)
1670 /* Array parameters use a temporary descriptor, we want the real
1671 parameter. */
1672 gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl))
1673 || GFC_ARRAY_TYPE_P (TREE_TYPE (decl)));
1674 decl = GFC_DECL_SAVED_DESCRIPTOR (decl);
1677 cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node, decl,
1678 fold_convert (TREE_TYPE (decl), null_pointer_node));
1680 /* Fortran 2008 allows to pass null pointers and non-associated pointers
1681 as actual argument to denote absent dummies. For array descriptors,
1682 we thus also need to check the array descriptor. For BT_CLASS, it
1683 can also occur for scalars and F2003 due to type->class wrapping and
1684 class->class wrapping. Note further that BT_CLASS always uses an
1685 array descriptor for arrays, also for explicit-shape/assumed-size. */
1687 if (!sym->attr.allocatable
1688 && ((sym->ts.type != BT_CLASS && !sym->attr.pointer)
1689 || (sym->ts.type == BT_CLASS
1690 && !CLASS_DATA (sym)->attr.allocatable
1691 && !CLASS_DATA (sym)->attr.class_pointer))
1692 && ((gfc_option.allow_std & GFC_STD_F2008) != 0
1693 || sym->ts.type == BT_CLASS))
1695 tree tmp;
1697 if ((sym->as && (sym->as->type == AS_ASSUMED_SHAPE
1698 || sym->as->type == AS_ASSUMED_RANK
1699 || sym->attr.codimension))
1700 || (sym->ts.type == BT_CLASS && CLASS_DATA (sym)->as))
1702 tmp = build_fold_indirect_ref_loc (input_location, decl);
1703 if (sym->ts.type == BT_CLASS)
1704 tmp = gfc_class_data_get (tmp);
1705 tmp = gfc_conv_array_data (tmp);
1707 else if (sym->ts.type == BT_CLASS)
1708 tmp = gfc_class_data_get (decl);
1709 else
1710 tmp = NULL_TREE;
1712 if (tmp != NULL_TREE)
1714 tmp = fold_build2_loc (input_location, NE_EXPR, logical_type_node, tmp,
1715 fold_convert (TREE_TYPE (tmp), null_pointer_node));
1716 cond = fold_build2_loc (input_location, TRUTH_ANDIF_EXPR,
1717 logical_type_node, cond, tmp);
1721 return cond;
1725 /* Converts a missing, dummy argument into a null or zero. */
1727 void
1728 gfc_conv_missing_dummy (gfc_se * se, gfc_expr * arg, gfc_typespec ts, int kind)
1730 tree present;
1731 tree tmp;
1733 present = gfc_conv_expr_present (arg->symtree->n.sym);
1735 if (kind > 0)
1737 /* Create a temporary and convert it to the correct type. */
1738 tmp = gfc_get_int_type (kind);
1739 tmp = fold_convert (tmp, build_fold_indirect_ref_loc (input_location,
1740 se->expr));
1742 /* Test for a NULL value. */
1743 tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp), present,
1744 tmp, fold_convert (TREE_TYPE (tmp), integer_one_node));
1745 tmp = gfc_evaluate_now (tmp, &se->pre);
1746 se->expr = gfc_build_addr_expr (NULL_TREE, tmp);
1748 else
1750 tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (se->expr),
1751 present, se->expr,
1752 build_zero_cst (TREE_TYPE (se->expr)));
1753 tmp = gfc_evaluate_now (tmp, &se->pre);
1754 se->expr = tmp;
1757 if (ts.type == BT_CHARACTER)
1759 tmp = build_int_cst (gfc_charlen_type_node, 0);
1760 tmp = fold_build3_loc (input_location, COND_EXPR, gfc_charlen_type_node,
1761 present, se->string_length, tmp);
1762 tmp = gfc_evaluate_now (tmp, &se->pre);
1763 se->string_length = tmp;
1765 return;
1769 /* Get the character length of an expression, looking through gfc_refs
1770 if necessary. */
1772 tree
1773 gfc_get_expr_charlen (gfc_expr *e)
1775 gfc_ref *r;
1776 tree length;
1778 gcc_assert (e->expr_type == EXPR_VARIABLE
1779 && e->ts.type == BT_CHARACTER);
1781 length = NULL; /* To silence compiler warning. */
1783 if (is_subref_array (e) && e->ts.u.cl->length)
1785 gfc_se tmpse;
1786 gfc_init_se (&tmpse, NULL);
1787 gfc_conv_expr_type (&tmpse, e->ts.u.cl->length, gfc_charlen_type_node);
1788 e->ts.u.cl->backend_decl = tmpse.expr;
1789 return tmpse.expr;
1792 /* First candidate: if the variable is of type CHARACTER, the
1793 expression's length could be the length of the character
1794 variable. */
1795 if (e->symtree->n.sym->ts.type == BT_CHARACTER)
1796 length = e->symtree->n.sym->ts.u.cl->backend_decl;
1798 /* Look through the reference chain for component references. */
1799 for (r = e->ref; r; r = r->next)
1801 switch (r->type)
1803 case REF_COMPONENT:
1804 if (r->u.c.component->ts.type == BT_CHARACTER)
1805 length = r->u.c.component->ts.u.cl->backend_decl;
1806 break;
1808 case REF_ARRAY:
1809 /* Do nothing. */
1810 break;
1812 default:
1813 /* We should never got substring references here. These will be
1814 broken down by the scalarizer. */
1815 gcc_unreachable ();
1816 break;
1820 gcc_assert (length != NULL);
1821 return length;
1825 /* Return for an expression the backend decl of the coarray. */
1827 tree
1828 gfc_get_tree_for_caf_expr (gfc_expr *expr)
1830 tree caf_decl;
1831 bool found = false;
1832 gfc_ref *ref;
1834 gcc_assert (expr && expr->expr_type == EXPR_VARIABLE);
1836 /* Not-implemented diagnostic. */
1837 if (expr->symtree->n.sym->ts.type == BT_CLASS
1838 && UNLIMITED_POLY (expr->symtree->n.sym)
1839 && CLASS_DATA (expr->symtree->n.sym)->attr.codimension)
1840 gfc_error ("Sorry, coindexed access to an unlimited polymorphic object at "
1841 "%L is not supported", &expr->where);
1843 for (ref = expr->ref; ref; ref = ref->next)
1844 if (ref->type == REF_COMPONENT)
1846 if (ref->u.c.component->ts.type == BT_CLASS
1847 && UNLIMITED_POLY (ref->u.c.component)
1848 && CLASS_DATA (ref->u.c.component)->attr.codimension)
1849 gfc_error ("Sorry, coindexed access to an unlimited polymorphic "
1850 "component at %L is not supported", &expr->where);
1853 /* Make sure the backend_decl is present before accessing it. */
1854 caf_decl = expr->symtree->n.sym->backend_decl == NULL_TREE
1855 ? gfc_get_symbol_decl (expr->symtree->n.sym)
1856 : expr->symtree->n.sym->backend_decl;
1858 if (expr->symtree->n.sym->ts.type == BT_CLASS)
1860 if (expr->ref && expr->ref->type == REF_ARRAY)
1862 caf_decl = gfc_class_data_get (caf_decl);
1863 if (CLASS_DATA (expr->symtree->n.sym)->attr.codimension)
1864 return caf_decl;
1866 for (ref = expr->ref; ref; ref = ref->next)
1868 if (ref->type == REF_COMPONENT
1869 && strcmp (ref->u.c.component->name, "_data") != 0)
1871 caf_decl = gfc_class_data_get (caf_decl);
1872 if (CLASS_DATA (expr->symtree->n.sym)->attr.codimension)
1873 return caf_decl;
1874 break;
1876 else if (ref->type == REF_ARRAY && ref->u.ar.dimen)
1877 break;
1880 if (expr->symtree->n.sym->attr.codimension)
1881 return caf_decl;
1883 /* The following code assumes that the coarray is a component reachable via
1884 only scalar components/variables; the Fortran standard guarantees this. */
1886 for (ref = expr->ref; ref; ref = ref->next)
1887 if (ref->type == REF_COMPONENT)
1889 gfc_component *comp = ref->u.c.component;
1891 if (POINTER_TYPE_P (TREE_TYPE (caf_decl)))
1892 caf_decl = build_fold_indirect_ref_loc (input_location, caf_decl);
1893 caf_decl = fold_build3_loc (input_location, COMPONENT_REF,
1894 TREE_TYPE (comp->backend_decl), caf_decl,
1895 comp->backend_decl, NULL_TREE);
1896 if (comp->ts.type == BT_CLASS)
1898 caf_decl = gfc_class_data_get (caf_decl);
1899 if (CLASS_DATA (comp)->attr.codimension)
1901 found = true;
1902 break;
1905 if (comp->attr.codimension)
1907 found = true;
1908 break;
1911 gcc_assert (found && caf_decl);
1912 return caf_decl;
1916 /* Obtain the Coarray token - and optionally also the offset. */
1918 void
1919 gfc_get_caf_token_offset (gfc_se *se, tree *token, tree *offset, tree caf_decl,
1920 tree se_expr, gfc_expr *expr)
1922 tree tmp;
1924 /* Coarray token. */
1925 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (caf_decl)))
1927 gcc_assert (GFC_TYPE_ARRAY_AKIND (TREE_TYPE (caf_decl))
1928 == GFC_ARRAY_ALLOCATABLE
1929 || expr->symtree->n.sym->attr.select_type_temporary);
1930 *token = gfc_conv_descriptor_token (caf_decl);
1932 else if (DECL_LANG_SPECIFIC (caf_decl)
1933 && GFC_DECL_TOKEN (caf_decl) != NULL_TREE)
1934 *token = GFC_DECL_TOKEN (caf_decl);
1935 else
1937 gcc_assert (GFC_ARRAY_TYPE_P (TREE_TYPE (caf_decl))
1938 && GFC_TYPE_ARRAY_CAF_TOKEN (TREE_TYPE (caf_decl)) != NULL_TREE);
1939 *token = GFC_TYPE_ARRAY_CAF_TOKEN (TREE_TYPE (caf_decl));
1942 if (offset == NULL)
1943 return;
1945 /* Offset between the coarray base address and the address wanted. */
1946 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (caf_decl))
1947 && (GFC_TYPE_ARRAY_AKIND (TREE_TYPE (caf_decl)) == GFC_ARRAY_ALLOCATABLE
1948 || GFC_TYPE_ARRAY_AKIND (TREE_TYPE (caf_decl)) == GFC_ARRAY_POINTER))
1949 *offset = build_int_cst (gfc_array_index_type, 0);
1950 else if (DECL_LANG_SPECIFIC (caf_decl)
1951 && GFC_DECL_CAF_OFFSET (caf_decl) != NULL_TREE)
1952 *offset = GFC_DECL_CAF_OFFSET (caf_decl);
1953 else if (GFC_TYPE_ARRAY_CAF_OFFSET (TREE_TYPE (caf_decl)) != NULL_TREE)
1954 *offset = GFC_TYPE_ARRAY_CAF_OFFSET (TREE_TYPE (caf_decl));
1955 else
1956 *offset = build_int_cst (gfc_array_index_type, 0);
1958 if (POINTER_TYPE_P (TREE_TYPE (se_expr))
1959 && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (TREE_TYPE (se_expr))))
1961 tmp = build_fold_indirect_ref_loc (input_location, se_expr);
1962 tmp = gfc_conv_descriptor_data_get (tmp);
1964 else if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se_expr)))
1965 tmp = gfc_conv_descriptor_data_get (se_expr);
1966 else
1968 gcc_assert (POINTER_TYPE_P (TREE_TYPE (se_expr)));
1969 tmp = se_expr;
1972 *offset = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
1973 *offset, fold_convert (gfc_array_index_type, tmp));
1975 if (expr->symtree->n.sym->ts.type == BT_DERIVED
1976 && expr->symtree->n.sym->attr.codimension
1977 && expr->symtree->n.sym->ts.u.derived->attr.alloc_comp)
1979 gfc_expr *base_expr = gfc_copy_expr (expr);
1980 gfc_ref *ref = base_expr->ref;
1981 gfc_se base_se;
1983 // Iterate through the refs until the last one.
1984 while (ref->next)
1985 ref = ref->next;
1987 if (ref->type == REF_ARRAY
1988 && ref->u.ar.type != AR_FULL)
1990 const int ranksum = ref->u.ar.dimen + ref->u.ar.codimen;
1991 int i;
1992 for (i = 0; i < ranksum; ++i)
1994 ref->u.ar.start[i] = NULL;
1995 ref->u.ar.end[i] = NULL;
1997 ref->u.ar.type = AR_FULL;
1999 gfc_init_se (&base_se, NULL);
2000 if (gfc_caf_attr (base_expr).dimension)
2002 gfc_conv_expr_descriptor (&base_se, base_expr);
2003 tmp = gfc_conv_descriptor_data_get (base_se.expr);
2005 else
2007 gfc_conv_expr (&base_se, base_expr);
2008 tmp = base_se.expr;
2011 gfc_free_expr (base_expr);
2012 gfc_add_block_to_block (&se->pre, &base_se.pre);
2013 gfc_add_block_to_block (&se->post, &base_se.post);
2015 else if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (caf_decl)))
2016 tmp = gfc_conv_descriptor_data_get (caf_decl);
2017 else
2019 gcc_assert (POINTER_TYPE_P (TREE_TYPE (caf_decl)));
2020 tmp = caf_decl;
2023 *offset = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
2024 fold_convert (gfc_array_index_type, *offset),
2025 fold_convert (gfc_array_index_type, tmp));
2029 /* Convert the coindex of a coarray into an image index; the result is
2030 image_num = (idx(1)-lcobound(1)+1) + (idx(2)-lcobound(2))*extent(1)
2031 + (idx(3)-lcobound(3))*extend(1)*extent(2) + ... */
2033 tree
2034 gfc_caf_get_image_index (stmtblock_t *block, gfc_expr *e, tree desc)
2036 gfc_ref *ref;
2037 tree lbound, ubound, extent, tmp, img_idx;
2038 gfc_se se;
2039 int i;
2041 for (ref = e->ref; ref; ref = ref->next)
2042 if (ref->type == REF_ARRAY && ref->u.ar.codimen > 0)
2043 break;
2044 gcc_assert (ref != NULL);
2046 if (ref->u.ar.dimen_type[ref->u.ar.dimen] == DIMEN_THIS_IMAGE)
2048 return build_call_expr_loc (input_location, gfor_fndecl_caf_this_image, 1,
2049 integer_zero_node);
2052 img_idx = integer_zero_node;
2053 extent = integer_one_node;
2054 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (desc)))
2055 for (i = ref->u.ar.dimen; i < ref->u.ar.dimen + ref->u.ar.codimen; i++)
2057 gfc_init_se (&se, NULL);
2058 gfc_conv_expr_type (&se, ref->u.ar.start[i], integer_type_node);
2059 gfc_add_block_to_block (block, &se.pre);
2060 lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[i]);
2061 tmp = fold_build2_loc (input_location, MINUS_EXPR,
2062 integer_type_node, se.expr,
2063 fold_convert(integer_type_node, lbound));
2064 tmp = fold_build2_loc (input_location, MULT_EXPR, integer_type_node,
2065 extent, tmp);
2066 img_idx = fold_build2_loc (input_location, PLUS_EXPR, integer_type_node,
2067 img_idx, tmp);
2068 if (i < ref->u.ar.dimen + ref->u.ar.codimen - 1)
2070 ubound = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[i]);
2071 tmp = gfc_conv_array_extent_dim (lbound, ubound, NULL);
2072 tmp = fold_convert (integer_type_node, tmp);
2073 extent = fold_build2_loc (input_location, MULT_EXPR,
2074 integer_type_node, extent, tmp);
2077 else
2078 for (i = ref->u.ar.dimen; i < ref->u.ar.dimen + ref->u.ar.codimen; i++)
2080 gfc_init_se (&se, NULL);
2081 gfc_conv_expr_type (&se, ref->u.ar.start[i], integer_type_node);
2082 gfc_add_block_to_block (block, &se.pre);
2083 lbound = GFC_TYPE_ARRAY_LBOUND (TREE_TYPE (desc), i);
2084 lbound = fold_convert (integer_type_node, lbound);
2085 tmp = fold_build2_loc (input_location, MINUS_EXPR,
2086 integer_type_node, se.expr, lbound);
2087 tmp = fold_build2_loc (input_location, MULT_EXPR, integer_type_node,
2088 extent, tmp);
2089 img_idx = fold_build2_loc (input_location, PLUS_EXPR, integer_type_node,
2090 img_idx, tmp);
2091 if (i < ref->u.ar.dimen + ref->u.ar.codimen - 1)
2093 ubound = GFC_TYPE_ARRAY_UBOUND (TREE_TYPE (desc), i);
2094 ubound = fold_convert (integer_type_node, ubound);
2095 tmp = fold_build2_loc (input_location, MINUS_EXPR,
2096 integer_type_node, ubound, lbound);
2097 tmp = fold_build2_loc (input_location, PLUS_EXPR, integer_type_node,
2098 tmp, integer_one_node);
2099 extent = fold_build2_loc (input_location, MULT_EXPR,
2100 integer_type_node, extent, tmp);
2103 img_idx = fold_build2_loc (input_location, PLUS_EXPR, integer_type_node,
2104 img_idx, integer_one_node);
2105 return img_idx;
2109 /* For each character array constructor subexpression without a ts.u.cl->length,
2110 replace it by its first element (if there aren't any elements, the length
2111 should already be set to zero). */
2113 static void
2114 flatten_array_ctors_without_strlen (gfc_expr* e)
2116 gfc_actual_arglist* arg;
2117 gfc_constructor* c;
2119 if (!e)
2120 return;
2122 switch (e->expr_type)
2125 case EXPR_OP:
2126 flatten_array_ctors_without_strlen (e->value.op.op1);
2127 flatten_array_ctors_without_strlen (e->value.op.op2);
2128 break;
2130 case EXPR_COMPCALL:
2131 /* TODO: Implement as with EXPR_FUNCTION when needed. */
2132 gcc_unreachable ();
2134 case EXPR_FUNCTION:
2135 for (arg = e->value.function.actual; arg; arg = arg->next)
2136 flatten_array_ctors_without_strlen (arg->expr);
2137 break;
2139 case EXPR_ARRAY:
2141 /* We've found what we're looking for. */
2142 if (e->ts.type == BT_CHARACTER && !e->ts.u.cl->length)
2144 gfc_constructor *c;
2145 gfc_expr* new_expr;
2147 gcc_assert (e->value.constructor);
2149 c = gfc_constructor_first (e->value.constructor);
2150 new_expr = c->expr;
2151 c->expr = NULL;
2153 flatten_array_ctors_without_strlen (new_expr);
2154 gfc_replace_expr (e, new_expr);
2155 break;
2158 /* Otherwise, fall through to handle constructor elements. */
2159 gcc_fallthrough ();
2160 case EXPR_STRUCTURE:
2161 for (c = gfc_constructor_first (e->value.constructor);
2162 c; c = gfc_constructor_next (c))
2163 flatten_array_ctors_without_strlen (c->expr);
2164 break;
2166 default:
2167 break;
2173 /* Generate code to initialize a string length variable. Returns the
2174 value. For array constructors, cl->length might be NULL and in this case,
2175 the first element of the constructor is needed. expr is the original
2176 expression so we can access it but can be NULL if this is not needed. */
2178 void
2179 gfc_conv_string_length (gfc_charlen * cl, gfc_expr * expr, stmtblock_t * pblock)
2181 gfc_se se;
2183 gfc_init_se (&se, NULL);
2185 if (!cl->length && cl->backend_decl && VAR_P (cl->backend_decl))
2186 return;
2188 /* If cl->length is NULL, use gfc_conv_expr to obtain the string length but
2189 "flatten" array constructors by taking their first element; all elements
2190 should be the same length or a cl->length should be present. */
2191 if (!cl->length)
2193 gfc_expr* expr_flat;
2194 gcc_assert (expr);
2195 expr_flat = gfc_copy_expr (expr);
2196 flatten_array_ctors_without_strlen (expr_flat);
2197 gfc_resolve_expr (expr_flat);
2199 gfc_conv_expr (&se, expr_flat);
2200 gfc_add_block_to_block (pblock, &se.pre);
2201 cl->backend_decl = convert (gfc_charlen_type_node, se.string_length);
2203 gfc_free_expr (expr_flat);
2204 return;
2207 /* Convert cl->length. */
2209 gcc_assert (cl->length);
2211 gfc_conv_expr_type (&se, cl->length, gfc_charlen_type_node);
2212 se.expr = fold_build2_loc (input_location, MAX_EXPR, gfc_charlen_type_node,
2213 se.expr, build_zero_cst (TREE_TYPE (se.expr)));
2214 gfc_add_block_to_block (pblock, &se.pre);
2216 if (cl->backend_decl)
2217 gfc_add_modify (pblock, cl->backend_decl, se.expr);
2218 else
2219 cl->backend_decl = gfc_evaluate_now (se.expr, pblock);
2223 static void
2224 gfc_conv_substring (gfc_se * se, gfc_ref * ref, int kind,
2225 const char *name, locus *where)
2227 tree tmp;
2228 tree type;
2229 tree fault;
2230 gfc_se start;
2231 gfc_se end;
2232 char *msg;
2233 mpz_t length;
2235 type = gfc_get_character_type (kind, ref->u.ss.length);
2236 type = build_pointer_type (type);
2238 gfc_init_se (&start, se);
2239 gfc_conv_expr_type (&start, ref->u.ss.start, gfc_charlen_type_node);
2240 gfc_add_block_to_block (&se->pre, &start.pre);
2242 if (integer_onep (start.expr))
2243 gfc_conv_string_parameter (se);
2244 else
2246 tmp = start.expr;
2247 STRIP_NOPS (tmp);
2248 /* Avoid multiple evaluation of substring start. */
2249 if (!CONSTANT_CLASS_P (tmp) && !DECL_P (tmp))
2250 start.expr = gfc_evaluate_now (start.expr, &se->pre);
2252 /* Change the start of the string. */
2253 if (TYPE_STRING_FLAG (TREE_TYPE (se->expr)))
2254 tmp = se->expr;
2255 else
2256 tmp = build_fold_indirect_ref_loc (input_location,
2257 se->expr);
2258 tmp = gfc_build_array_ref (tmp, start.expr, NULL);
2259 se->expr = gfc_build_addr_expr (type, tmp);
2262 /* Length = end + 1 - start. */
2263 gfc_init_se (&end, se);
2264 if (ref->u.ss.end == NULL)
2265 end.expr = se->string_length;
2266 else
2268 gfc_conv_expr_type (&end, ref->u.ss.end, gfc_charlen_type_node);
2269 gfc_add_block_to_block (&se->pre, &end.pre);
2271 tmp = end.expr;
2272 STRIP_NOPS (tmp);
2273 if (!CONSTANT_CLASS_P (tmp) && !DECL_P (tmp))
2274 end.expr = gfc_evaluate_now (end.expr, &se->pre);
2276 if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
2278 tree nonempty = fold_build2_loc (input_location, LE_EXPR,
2279 logical_type_node, start.expr,
2280 end.expr);
2282 /* Check lower bound. */
2283 fault = fold_build2_loc (input_location, LT_EXPR, logical_type_node,
2284 start.expr,
2285 build_one_cst (TREE_TYPE (start.expr)));
2286 fault = fold_build2_loc (input_location, TRUTH_ANDIF_EXPR,
2287 logical_type_node, nonempty, fault);
2288 if (name)
2289 msg = xasprintf ("Substring out of bounds: lower bound (%%ld) of '%s' "
2290 "is less than one", name);
2291 else
2292 msg = xasprintf ("Substring out of bounds: lower bound (%%ld) "
2293 "is less than one");
2294 gfc_trans_runtime_check (true, false, fault, &se->pre, where, msg,
2295 fold_convert (long_integer_type_node,
2296 start.expr));
2297 free (msg);
2299 /* Check upper bound. */
2300 fault = fold_build2_loc (input_location, GT_EXPR, logical_type_node,
2301 end.expr, se->string_length);
2302 fault = fold_build2_loc (input_location, TRUTH_ANDIF_EXPR,
2303 logical_type_node, nonempty, fault);
2304 if (name)
2305 msg = xasprintf ("Substring out of bounds: upper bound (%%ld) of '%s' "
2306 "exceeds string length (%%ld)", name);
2307 else
2308 msg = xasprintf ("Substring out of bounds: upper bound (%%ld) "
2309 "exceeds string length (%%ld)");
2310 gfc_trans_runtime_check (true, false, fault, &se->pre, where, msg,
2311 fold_convert (long_integer_type_node, end.expr),
2312 fold_convert (long_integer_type_node,
2313 se->string_length));
2314 free (msg);
2317 /* Try to calculate the length from the start and end expressions. */
2318 if (ref->u.ss.end
2319 && gfc_dep_difference (ref->u.ss.end, ref->u.ss.start, &length))
2321 HOST_WIDE_INT i_len;
2323 i_len = gfc_mpz_get_hwi (length) + 1;
2324 if (i_len < 0)
2325 i_len = 0;
2327 tmp = build_int_cst (gfc_charlen_type_node, i_len);
2328 mpz_clear (length); /* Was initialized by gfc_dep_difference. */
2330 else
2332 tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_charlen_type_node,
2333 fold_convert (gfc_charlen_type_node, end.expr),
2334 fold_convert (gfc_charlen_type_node, start.expr));
2335 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_charlen_type_node,
2336 build_int_cst (gfc_charlen_type_node, 1), tmp);
2337 tmp = fold_build2_loc (input_location, MAX_EXPR, gfc_charlen_type_node,
2338 tmp, build_int_cst (gfc_charlen_type_node, 0));
2341 se->string_length = tmp;
2345 /* Convert a derived type component reference. */
2347 static void
2348 gfc_conv_component_ref (gfc_se * se, gfc_ref * ref)
2350 gfc_component *c;
2351 tree tmp;
2352 tree decl;
2353 tree field;
2354 tree context;
2356 c = ref->u.c.component;
2358 if (c->backend_decl == NULL_TREE
2359 && ref->u.c.sym != NULL)
2360 gfc_get_derived_type (ref->u.c.sym);
2362 field = c->backend_decl;
2363 gcc_assert (field && TREE_CODE (field) == FIELD_DECL);
2364 decl = se->expr;
2365 context = DECL_FIELD_CONTEXT (field);
2367 /* Components can correspond to fields of different containing
2368 types, as components are created without context, whereas
2369 a concrete use of a component has the type of decl as context.
2370 So, if the type doesn't match, we search the corresponding
2371 FIELD_DECL in the parent type. To not waste too much time
2372 we cache this result in norestrict_decl.
2373 On the other hand, if the context is a UNION or a MAP (a
2374 RECORD_TYPE within a UNION_TYPE) always use the given FIELD_DECL. */
2376 if (context != TREE_TYPE (decl)
2377 && !( TREE_CODE (TREE_TYPE (field)) == UNION_TYPE /* Field is union */
2378 || TREE_CODE (context) == UNION_TYPE)) /* Field is map */
2380 tree f2 = c->norestrict_decl;
2381 if (!f2 || DECL_FIELD_CONTEXT (f2) != TREE_TYPE (decl))
2382 for (f2 = TYPE_FIELDS (TREE_TYPE (decl)); f2; f2 = DECL_CHAIN (f2))
2383 if (TREE_CODE (f2) == FIELD_DECL
2384 && DECL_NAME (f2) == DECL_NAME (field))
2385 break;
2386 gcc_assert (f2);
2387 c->norestrict_decl = f2;
2388 field = f2;
2391 if (ref->u.c.sym && ref->u.c.sym->ts.type == BT_CLASS
2392 && strcmp ("_data", c->name) == 0)
2394 /* Found a ref to the _data component. Store the associated ref to
2395 the vptr in se->class_vptr. */
2396 se->class_vptr = gfc_class_vptr_get (decl);
2398 else
2399 se->class_vptr = NULL_TREE;
2401 tmp = fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field),
2402 decl, field, NULL_TREE);
2404 se->expr = tmp;
2406 /* Allocatable deferred char arrays are to be handled by the gfc_deferred_
2407 strlen () conditional below. */
2408 if (c->ts.type == BT_CHARACTER && !c->attr.proc_pointer
2409 && !(c->attr.allocatable && c->ts.deferred)
2410 && !c->attr.pdt_string)
2412 tmp = c->ts.u.cl->backend_decl;
2413 /* Components must always be constant length. */
2414 gcc_assert (tmp && INTEGER_CST_P (tmp));
2415 se->string_length = tmp;
2418 if (gfc_deferred_strlen (c, &field))
2420 tmp = fold_build3_loc (input_location, COMPONENT_REF,
2421 TREE_TYPE (field),
2422 decl, field, NULL_TREE);
2423 se->string_length = tmp;
2426 if (((c->attr.pointer || c->attr.allocatable)
2427 && (!c->attr.dimension && !c->attr.codimension)
2428 && c->ts.type != BT_CHARACTER)
2429 || c->attr.proc_pointer)
2430 se->expr = build_fold_indirect_ref_loc (input_location,
2431 se->expr);
2435 /* This function deals with component references to components of the
2436 parent type for derived type extensions. */
2437 static void
2438 conv_parent_component_references (gfc_se * se, gfc_ref * ref)
2440 gfc_component *c;
2441 gfc_component *cmp;
2442 gfc_symbol *dt;
2443 gfc_ref parent;
2445 dt = ref->u.c.sym;
2446 c = ref->u.c.component;
2448 /* Return if the component is in the parent type. */
2449 for (cmp = dt->components; cmp; cmp = cmp->next)
2450 if (strcmp (c->name, cmp->name) == 0)
2451 return;
2453 /* Build a gfc_ref to recursively call gfc_conv_component_ref. */
2454 parent.type = REF_COMPONENT;
2455 parent.next = NULL;
2456 parent.u.c.sym = dt;
2457 parent.u.c.component = dt->components;
2459 if (dt->backend_decl == NULL)
2460 gfc_get_derived_type (dt);
2462 /* Build the reference and call self. */
2463 gfc_conv_component_ref (se, &parent);
2464 parent.u.c.sym = dt->components->ts.u.derived;
2465 parent.u.c.component = c;
2466 conv_parent_component_references (se, &parent);
2469 /* Return the contents of a variable. Also handles reference/pointer
2470 variables (all Fortran pointer references are implicit). */
2472 static void
2473 gfc_conv_variable (gfc_se * se, gfc_expr * expr)
2475 gfc_ss *ss;
2476 gfc_ref *ref;
2477 gfc_symbol *sym;
2478 tree parent_decl = NULL_TREE;
2479 int parent_flag;
2480 bool return_value;
2481 bool alternate_entry;
2482 bool entry_master;
2483 bool is_classarray;
2484 bool first_time = true;
2486 sym = expr->symtree->n.sym;
2487 is_classarray = IS_CLASS_ARRAY (sym);
2488 ss = se->ss;
2489 if (ss != NULL)
2491 gfc_ss_info *ss_info = ss->info;
2493 /* Check that something hasn't gone horribly wrong. */
2494 gcc_assert (ss != gfc_ss_terminator);
2495 gcc_assert (ss_info->expr == expr);
2497 /* A scalarized term. We already know the descriptor. */
2498 se->expr = ss_info->data.array.descriptor;
2499 se->string_length = ss_info->string_length;
2500 ref = ss_info->data.array.ref;
2501 if (ref)
2502 gcc_assert (ref->type == REF_ARRAY
2503 && ref->u.ar.type != AR_ELEMENT);
2504 else
2505 gfc_conv_tmp_array_ref (se);
2507 else
2509 tree se_expr = NULL_TREE;
2511 se->expr = gfc_get_symbol_decl (sym);
2513 /* Deal with references to a parent results or entries by storing
2514 the current_function_decl and moving to the parent_decl. */
2515 return_value = sym->attr.function && sym->result == sym;
2516 alternate_entry = sym->attr.function && sym->attr.entry
2517 && sym->result == sym;
2518 entry_master = sym->attr.result
2519 && sym->ns->proc_name->attr.entry_master
2520 && !gfc_return_by_reference (sym->ns->proc_name);
2521 if (current_function_decl)
2522 parent_decl = DECL_CONTEXT (current_function_decl);
2524 if ((se->expr == parent_decl && return_value)
2525 || (sym->ns && sym->ns->proc_name
2526 && parent_decl
2527 && sym->ns->proc_name->backend_decl == parent_decl
2528 && (alternate_entry || entry_master)))
2529 parent_flag = 1;
2530 else
2531 parent_flag = 0;
2533 /* Special case for assigning the return value of a function.
2534 Self recursive functions must have an explicit return value. */
2535 if (return_value && (se->expr == current_function_decl || parent_flag))
2536 se_expr = gfc_get_fake_result_decl (sym, parent_flag);
2538 /* Similarly for alternate entry points. */
2539 else if (alternate_entry
2540 && (sym->ns->proc_name->backend_decl == current_function_decl
2541 || parent_flag))
2543 gfc_entry_list *el = NULL;
2545 for (el = sym->ns->entries; el; el = el->next)
2546 if (sym == el->sym)
2548 se_expr = gfc_get_fake_result_decl (sym, parent_flag);
2549 break;
2553 else if (entry_master
2554 && (sym->ns->proc_name->backend_decl == current_function_decl
2555 || parent_flag))
2556 se_expr = gfc_get_fake_result_decl (sym, parent_flag);
2558 if (se_expr)
2559 se->expr = se_expr;
2561 /* Procedure actual arguments. Look out for temporary variables
2562 with the same attributes as function values. */
2563 else if (!sym->attr.temporary
2564 && sym->attr.flavor == FL_PROCEDURE
2565 && se->expr != current_function_decl)
2567 if (!sym->attr.dummy && !sym->attr.proc_pointer)
2569 gcc_assert (TREE_CODE (se->expr) == FUNCTION_DECL);
2570 se->expr = gfc_build_addr_expr (NULL_TREE, se->expr);
2572 return;
2576 /* Dereference the expression, where needed. Since characters
2577 are entirely different from other types, they are treated
2578 separately. */
2579 if (sym->ts.type == BT_CHARACTER)
2581 /* Dereference character pointer dummy arguments
2582 or results. */
2583 if ((sym->attr.pointer || sym->attr.allocatable)
2584 && (sym->attr.dummy
2585 || sym->attr.function
2586 || sym->attr.result))
2587 se->expr = build_fold_indirect_ref_loc (input_location,
2588 se->expr);
2591 else if (!sym->attr.value)
2593 /* Dereference temporaries for class array dummy arguments. */
2594 if (sym->attr.dummy && is_classarray
2595 && GFC_ARRAY_TYPE_P (TREE_TYPE (se->expr)))
2597 if (!se->descriptor_only)
2598 se->expr = GFC_DECL_SAVED_DESCRIPTOR (se->expr);
2600 se->expr = build_fold_indirect_ref_loc (input_location,
2601 se->expr);
2604 /* Dereference non-character scalar dummy arguments. */
2605 if (sym->attr.dummy && !sym->attr.dimension
2606 && !(sym->attr.codimension && sym->attr.allocatable)
2607 && (sym->ts.type != BT_CLASS
2608 || (!CLASS_DATA (sym)->attr.dimension
2609 && !(CLASS_DATA (sym)->attr.codimension
2610 && CLASS_DATA (sym)->attr.allocatable))))
2611 se->expr = build_fold_indirect_ref_loc (input_location,
2612 se->expr);
2614 /* Dereference scalar hidden result. */
2615 if (flag_f2c && sym->ts.type == BT_COMPLEX
2616 && (sym->attr.function || sym->attr.result)
2617 && !sym->attr.dimension && !sym->attr.pointer
2618 && !sym->attr.always_explicit)
2619 se->expr = build_fold_indirect_ref_loc (input_location,
2620 se->expr);
2622 /* Dereference non-character, non-class pointer variables.
2623 These must be dummies, results, or scalars. */
2624 if (!is_classarray
2625 && (sym->attr.pointer || sym->attr.allocatable
2626 || gfc_is_associate_pointer (sym)
2627 || (sym->as && sym->as->type == AS_ASSUMED_RANK))
2628 && (sym->attr.dummy
2629 || sym->attr.function
2630 || sym->attr.result
2631 || (!sym->attr.dimension
2632 && (!sym->attr.codimension || !sym->attr.allocatable))))
2633 se->expr = build_fold_indirect_ref_loc (input_location,
2634 se->expr);
2635 /* Now treat the class array pointer variables accordingly. */
2636 else if (sym->ts.type == BT_CLASS
2637 && sym->attr.dummy
2638 && (CLASS_DATA (sym)->attr.dimension
2639 || CLASS_DATA (sym)->attr.codimension)
2640 && ((CLASS_DATA (sym)->as
2641 && CLASS_DATA (sym)->as->type == AS_ASSUMED_RANK)
2642 || CLASS_DATA (sym)->attr.allocatable
2643 || CLASS_DATA (sym)->attr.class_pointer))
2644 se->expr = build_fold_indirect_ref_loc (input_location,
2645 se->expr);
2646 /* And the case where a non-dummy, non-result, non-function,
2647 non-allotable and non-pointer classarray is present. This case was
2648 previously covered by the first if, but with introducing the
2649 condition !is_classarray there, that case has to be covered
2650 explicitly. */
2651 else if (sym->ts.type == BT_CLASS
2652 && !sym->attr.dummy
2653 && !sym->attr.function
2654 && !sym->attr.result
2655 && (CLASS_DATA (sym)->attr.dimension
2656 || CLASS_DATA (sym)->attr.codimension)
2657 && (sym->assoc
2658 || !CLASS_DATA (sym)->attr.allocatable)
2659 && !CLASS_DATA (sym)->attr.class_pointer)
2660 se->expr = build_fold_indirect_ref_loc (input_location,
2661 se->expr);
2664 ref = expr->ref;
2667 /* For character variables, also get the length. */
2668 if (sym->ts.type == BT_CHARACTER)
2670 /* If the character length of an entry isn't set, get the length from
2671 the master function instead. */
2672 if (sym->attr.entry && !sym->ts.u.cl->backend_decl)
2673 se->string_length = sym->ns->proc_name->ts.u.cl->backend_decl;
2674 else
2675 se->string_length = sym->ts.u.cl->backend_decl;
2676 gcc_assert (se->string_length);
2679 while (ref)
2681 switch (ref->type)
2683 case REF_ARRAY:
2684 /* Return the descriptor if that's what we want and this is an array
2685 section reference. */
2686 if (se->descriptor_only && ref->u.ar.type != AR_ELEMENT)
2687 return;
2688 /* TODO: Pointers to single elements of array sections, eg elemental subs. */
2689 /* Return the descriptor for array pointers and allocations. */
2690 if (se->want_pointer
2691 && ref->next == NULL && (se->descriptor_only))
2692 return;
2694 gfc_conv_array_ref (se, &ref->u.ar, expr, &expr->where);
2695 /* Return a pointer to an element. */
2696 break;
2698 case REF_COMPONENT:
2699 if (first_time && is_classarray && sym->attr.dummy
2700 && se->descriptor_only
2701 && !CLASS_DATA (sym)->attr.allocatable
2702 && !CLASS_DATA (sym)->attr.class_pointer
2703 && CLASS_DATA (sym)->as
2704 && CLASS_DATA (sym)->as->type != AS_ASSUMED_RANK
2705 && strcmp ("_data", ref->u.c.component->name) == 0)
2706 /* Skip the first ref of a _data component, because for class
2707 arrays that one is already done by introducing a temporary
2708 array descriptor. */
2709 break;
2711 if (ref->u.c.sym->attr.extension)
2712 conv_parent_component_references (se, ref);
2714 gfc_conv_component_ref (se, ref);
2715 if (!ref->next && ref->u.c.sym->attr.codimension
2716 && se->want_pointer && se->descriptor_only)
2717 return;
2719 break;
2721 case REF_SUBSTRING:
2722 gfc_conv_substring (se, ref, expr->ts.kind,
2723 expr->symtree->name, &expr->where);
2724 break;
2726 default:
2727 gcc_unreachable ();
2728 break;
2730 first_time = false;
2731 ref = ref->next;
2733 /* Pointer assignment, allocation or pass by reference. Arrays are handled
2734 separately. */
2735 if (se->want_pointer)
2737 if (expr->ts.type == BT_CHARACTER && !gfc_is_proc_ptr_comp (expr))
2738 gfc_conv_string_parameter (se);
2739 else
2740 se->expr = gfc_build_addr_expr (NULL_TREE, se->expr);
2745 /* Unary ops are easy... Or they would be if ! was a valid op. */
2747 static void
2748 gfc_conv_unary_op (enum tree_code code, gfc_se * se, gfc_expr * expr)
2750 gfc_se operand;
2751 tree type;
2753 gcc_assert (expr->ts.type != BT_CHARACTER);
2754 /* Initialize the operand. */
2755 gfc_init_se (&operand, se);
2756 gfc_conv_expr_val (&operand, expr->value.op.op1);
2757 gfc_add_block_to_block (&se->pre, &operand.pre);
2759 type = gfc_typenode_for_spec (&expr->ts);
2761 /* TRUTH_NOT_EXPR is not a "true" unary operator in GCC.
2762 We must convert it to a compare to 0 (e.g. EQ_EXPR (op1, 0)).
2763 All other unary operators have an equivalent GIMPLE unary operator. */
2764 if (code == TRUTH_NOT_EXPR)
2765 se->expr = fold_build2_loc (input_location, EQ_EXPR, type, operand.expr,
2766 build_int_cst (type, 0));
2767 else
2768 se->expr = fold_build1_loc (input_location, code, type, operand.expr);
2772 /* Expand power operator to optimal multiplications when a value is raised
2773 to a constant integer n. See section 4.6.3, "Evaluation of Powers" of
2774 Donald E. Knuth, "Seminumerical Algorithms", Vol. 2, "The Art of Computer
2775 Programming", 3rd Edition, 1998. */
2777 /* This code is mostly duplicated from expand_powi in the backend.
2778 We establish the "optimal power tree" lookup table with the defined size.
2779 The items in the table are the exponents used to calculate the index
2780 exponents. Any integer n less than the value can get an "addition chain",
2781 with the first node being one. */
2782 #define POWI_TABLE_SIZE 256
2784 /* The table is from builtins.c. */
2785 static const unsigned char powi_table[POWI_TABLE_SIZE] =
2787 0, 1, 1, 2, 2, 3, 3, 4, /* 0 - 7 */
2788 4, 6, 5, 6, 6, 10, 7, 9, /* 8 - 15 */
2789 8, 16, 9, 16, 10, 12, 11, 13, /* 16 - 23 */
2790 12, 17, 13, 18, 14, 24, 15, 26, /* 24 - 31 */
2791 16, 17, 17, 19, 18, 33, 19, 26, /* 32 - 39 */
2792 20, 25, 21, 40, 22, 27, 23, 44, /* 40 - 47 */
2793 24, 32, 25, 34, 26, 29, 27, 44, /* 48 - 55 */
2794 28, 31, 29, 34, 30, 60, 31, 36, /* 56 - 63 */
2795 32, 64, 33, 34, 34, 46, 35, 37, /* 64 - 71 */
2796 36, 65, 37, 50, 38, 48, 39, 69, /* 72 - 79 */
2797 40, 49, 41, 43, 42, 51, 43, 58, /* 80 - 87 */
2798 44, 64, 45, 47, 46, 59, 47, 76, /* 88 - 95 */
2799 48, 65, 49, 66, 50, 67, 51, 66, /* 96 - 103 */
2800 52, 70, 53, 74, 54, 104, 55, 74, /* 104 - 111 */
2801 56, 64, 57, 69, 58, 78, 59, 68, /* 112 - 119 */
2802 60, 61, 61, 80, 62, 75, 63, 68, /* 120 - 127 */
2803 64, 65, 65, 128, 66, 129, 67, 90, /* 128 - 135 */
2804 68, 73, 69, 131, 70, 94, 71, 88, /* 136 - 143 */
2805 72, 128, 73, 98, 74, 132, 75, 121, /* 144 - 151 */
2806 76, 102, 77, 124, 78, 132, 79, 106, /* 152 - 159 */
2807 80, 97, 81, 160, 82, 99, 83, 134, /* 160 - 167 */
2808 84, 86, 85, 95, 86, 160, 87, 100, /* 168 - 175 */
2809 88, 113, 89, 98, 90, 107, 91, 122, /* 176 - 183 */
2810 92, 111, 93, 102, 94, 126, 95, 150, /* 184 - 191 */
2811 96, 128, 97, 130, 98, 133, 99, 195, /* 192 - 199 */
2812 100, 128, 101, 123, 102, 164, 103, 138, /* 200 - 207 */
2813 104, 145, 105, 146, 106, 109, 107, 149, /* 208 - 215 */
2814 108, 200, 109, 146, 110, 170, 111, 157, /* 216 - 223 */
2815 112, 128, 113, 130, 114, 182, 115, 132, /* 224 - 231 */
2816 116, 200, 117, 132, 118, 158, 119, 206, /* 232 - 239 */
2817 120, 240, 121, 162, 122, 147, 123, 152, /* 240 - 247 */
2818 124, 166, 125, 214, 126, 138, 127, 153, /* 248 - 255 */
2821 /* If n is larger than lookup table's max index, we use the "window
2822 method". */
2823 #define POWI_WINDOW_SIZE 3
2825 /* Recursive function to expand the power operator. The temporary
2826 values are put in tmpvar. The function returns tmpvar[1] ** n. */
2827 static tree
2828 gfc_conv_powi (gfc_se * se, unsigned HOST_WIDE_INT n, tree * tmpvar)
2830 tree op0;
2831 tree op1;
2832 tree tmp;
2833 int digit;
2835 if (n < POWI_TABLE_SIZE)
2837 if (tmpvar[n])
2838 return tmpvar[n];
2840 op0 = gfc_conv_powi (se, n - powi_table[n], tmpvar);
2841 op1 = gfc_conv_powi (se, powi_table[n], tmpvar);
2843 else if (n & 1)
2845 digit = n & ((1 << POWI_WINDOW_SIZE) - 1);
2846 op0 = gfc_conv_powi (se, n - digit, tmpvar);
2847 op1 = gfc_conv_powi (se, digit, tmpvar);
2849 else
2851 op0 = gfc_conv_powi (se, n >> 1, tmpvar);
2852 op1 = op0;
2855 tmp = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (op0), op0, op1);
2856 tmp = gfc_evaluate_now (tmp, &se->pre);
2858 if (n < POWI_TABLE_SIZE)
2859 tmpvar[n] = tmp;
2861 return tmp;
2865 /* Expand lhs ** rhs. rhs is a constant integer. If it expands successfully,
2866 return 1. Else return 0 and a call to runtime library functions
2867 will have to be built. */
2868 static int
2869 gfc_conv_cst_int_power (gfc_se * se, tree lhs, tree rhs)
2871 tree cond;
2872 tree tmp;
2873 tree type;
2874 tree vartmp[POWI_TABLE_SIZE];
2875 HOST_WIDE_INT m;
2876 unsigned HOST_WIDE_INT n;
2877 int sgn;
2878 wi::tree_to_wide_ref wrhs = wi::to_wide (rhs);
2880 /* If exponent is too large, we won't expand it anyway, so don't bother
2881 with large integer values. */
2882 if (!wi::fits_shwi_p (wrhs))
2883 return 0;
2885 m = wrhs.to_shwi ();
2886 /* Use the wide_int's routine to reliably get the absolute value on all
2887 platforms. Then convert it to a HOST_WIDE_INT like above. */
2888 n = wi::abs (wrhs).to_shwi ();
2890 type = TREE_TYPE (lhs);
2891 sgn = tree_int_cst_sgn (rhs);
2893 if (((FLOAT_TYPE_P (type) && !flag_unsafe_math_optimizations)
2894 || optimize_size) && (m > 2 || m < -1))
2895 return 0;
2897 /* rhs == 0 */
2898 if (sgn == 0)
2900 se->expr = gfc_build_const (type, integer_one_node);
2901 return 1;
2904 /* If rhs < 0 and lhs is an integer, the result is -1, 0 or 1. */
2905 if ((sgn == -1) && (TREE_CODE (type) == INTEGER_TYPE))
2907 tmp = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
2908 lhs, build_int_cst (TREE_TYPE (lhs), -1));
2909 cond = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
2910 lhs, build_int_cst (TREE_TYPE (lhs), 1));
2912 /* If rhs is even,
2913 result = (lhs == 1 || lhs == -1) ? 1 : 0. */
2914 if ((n & 1) == 0)
2916 tmp = fold_build2_loc (input_location, TRUTH_OR_EXPR,
2917 logical_type_node, tmp, cond);
2918 se->expr = fold_build3_loc (input_location, COND_EXPR, type,
2919 tmp, build_int_cst (type, 1),
2920 build_int_cst (type, 0));
2921 return 1;
2923 /* If rhs is odd,
2924 result = (lhs == 1) ? 1 : (lhs == -1) ? -1 : 0. */
2925 tmp = fold_build3_loc (input_location, COND_EXPR, type, tmp,
2926 build_int_cst (type, -1),
2927 build_int_cst (type, 0));
2928 se->expr = fold_build3_loc (input_location, COND_EXPR, type,
2929 cond, build_int_cst (type, 1), tmp);
2930 return 1;
2933 memset (vartmp, 0, sizeof (vartmp));
2934 vartmp[1] = lhs;
2935 if (sgn == -1)
2937 tmp = gfc_build_const (type, integer_one_node);
2938 vartmp[1] = fold_build2_loc (input_location, RDIV_EXPR, type, tmp,
2939 vartmp[1]);
2942 se->expr = gfc_conv_powi (se, n, vartmp);
2944 return 1;
2948 /* Power op (**). Constant integer exponent has special handling. */
2950 static void
2951 gfc_conv_power_op (gfc_se * se, gfc_expr * expr)
2953 tree gfc_int4_type_node;
2954 int kind;
2955 int ikind;
2956 int res_ikind_1, res_ikind_2;
2957 gfc_se lse;
2958 gfc_se rse;
2959 tree fndecl = NULL;
2961 gfc_init_se (&lse, se);
2962 gfc_conv_expr_val (&lse, expr->value.op.op1);
2963 lse.expr = gfc_evaluate_now (lse.expr, &lse.pre);
2964 gfc_add_block_to_block (&se->pre, &lse.pre);
2966 gfc_init_se (&rse, se);
2967 gfc_conv_expr_val (&rse, expr->value.op.op2);
2968 gfc_add_block_to_block (&se->pre, &rse.pre);
2970 if (expr->value.op.op2->ts.type == BT_INTEGER
2971 && expr->value.op.op2->expr_type == EXPR_CONSTANT)
2972 if (gfc_conv_cst_int_power (se, lse.expr, rse.expr))
2973 return;
2975 gfc_int4_type_node = gfc_get_int_type (4);
2977 /* In case of integer operands with kinds 1 or 2, we call the integer kind 4
2978 library routine. But in the end, we have to convert the result back
2979 if this case applies -- with res_ikind_K, we keep track whether operand K
2980 falls into this case. */
2981 res_ikind_1 = -1;
2982 res_ikind_2 = -1;
2984 kind = expr->value.op.op1->ts.kind;
2985 switch (expr->value.op.op2->ts.type)
2987 case BT_INTEGER:
2988 ikind = expr->value.op.op2->ts.kind;
2989 switch (ikind)
2991 case 1:
2992 case 2:
2993 rse.expr = convert (gfc_int4_type_node, rse.expr);
2994 res_ikind_2 = ikind;
2995 /* Fall through. */
2997 case 4:
2998 ikind = 0;
2999 break;
3001 case 8:
3002 ikind = 1;
3003 break;
3005 case 16:
3006 ikind = 2;
3007 break;
3009 default:
3010 gcc_unreachable ();
3012 switch (kind)
3014 case 1:
3015 case 2:
3016 if (expr->value.op.op1->ts.type == BT_INTEGER)
3018 lse.expr = convert (gfc_int4_type_node, lse.expr);
3019 res_ikind_1 = kind;
3021 else
3022 gcc_unreachable ();
3023 /* Fall through. */
3025 case 4:
3026 kind = 0;
3027 break;
3029 case 8:
3030 kind = 1;
3031 break;
3033 case 10:
3034 kind = 2;
3035 break;
3037 case 16:
3038 kind = 3;
3039 break;
3041 default:
3042 gcc_unreachable ();
3045 switch (expr->value.op.op1->ts.type)
3047 case BT_INTEGER:
3048 if (kind == 3) /* Case 16 was not handled properly above. */
3049 kind = 2;
3050 fndecl = gfor_fndecl_math_powi[kind][ikind].integer;
3051 break;
3053 case BT_REAL:
3054 /* Use builtins for real ** int4. */
3055 if (ikind == 0)
3057 switch (kind)
3059 case 0:
3060 fndecl = builtin_decl_explicit (BUILT_IN_POWIF);
3061 break;
3063 case 1:
3064 fndecl = builtin_decl_explicit (BUILT_IN_POWI);
3065 break;
3067 case 2:
3068 fndecl = builtin_decl_explicit (BUILT_IN_POWIL);
3069 break;
3071 case 3:
3072 /* Use the __builtin_powil() only if real(kind=16) is
3073 actually the C long double type. */
3074 if (!gfc_real16_is_float128)
3075 fndecl = builtin_decl_explicit (BUILT_IN_POWIL);
3076 break;
3078 default:
3079 gcc_unreachable ();
3083 /* If we don't have a good builtin for this, go for the
3084 library function. */
3085 if (!fndecl)
3086 fndecl = gfor_fndecl_math_powi[kind][ikind].real;
3087 break;
3089 case BT_COMPLEX:
3090 fndecl = gfor_fndecl_math_powi[kind][ikind].cmplx;
3091 break;
3093 default:
3094 gcc_unreachable ();
3096 break;
3098 case BT_REAL:
3099 fndecl = gfc_builtin_decl_for_float_kind (BUILT_IN_POW, kind);
3100 break;
3102 case BT_COMPLEX:
3103 fndecl = gfc_builtin_decl_for_float_kind (BUILT_IN_CPOW, kind);
3104 break;
3106 default:
3107 gcc_unreachable ();
3108 break;
3111 se->expr = build_call_expr_loc (input_location,
3112 fndecl, 2, lse.expr, rse.expr);
3114 /* Convert the result back if it is of wrong integer kind. */
3115 if (res_ikind_1 != -1 && res_ikind_2 != -1)
3117 /* We want the maximum of both operand kinds as result. */
3118 if (res_ikind_1 < res_ikind_2)
3119 res_ikind_1 = res_ikind_2;
3120 se->expr = convert (gfc_get_int_type (res_ikind_1), se->expr);
3125 /* Generate code to allocate a string temporary. */
3127 tree
3128 gfc_conv_string_tmp (gfc_se * se, tree type, tree len)
3130 tree var;
3131 tree tmp;
3133 if (gfc_can_put_var_on_stack (len))
3135 /* Create a temporary variable to hold the result. */
3136 tmp = fold_build2_loc (input_location, MINUS_EXPR,
3137 TREE_TYPE (len), len,
3138 build_int_cst (TREE_TYPE (len), 1));
3139 tmp = build_range_type (gfc_charlen_type_node, size_zero_node, tmp);
3141 if (TREE_CODE (TREE_TYPE (type)) == ARRAY_TYPE)
3142 tmp = build_array_type (TREE_TYPE (TREE_TYPE (type)), tmp);
3143 else
3144 tmp = build_array_type (TREE_TYPE (type), tmp);
3146 var = gfc_create_var (tmp, "str");
3147 var = gfc_build_addr_expr (type, var);
3149 else
3151 /* Allocate a temporary to hold the result. */
3152 var = gfc_create_var (type, "pstr");
3153 gcc_assert (POINTER_TYPE_P (type));
3154 tmp = TREE_TYPE (type);
3155 if (TREE_CODE (tmp) == ARRAY_TYPE)
3156 tmp = TREE_TYPE (tmp);
3157 tmp = TYPE_SIZE_UNIT (tmp);
3158 tmp = fold_build2_loc (input_location, MULT_EXPR, size_type_node,
3159 fold_convert (size_type_node, len),
3160 fold_convert (size_type_node, tmp));
3161 tmp = gfc_call_malloc (&se->pre, type, tmp);
3162 gfc_add_modify (&se->pre, var, tmp);
3164 /* Free the temporary afterwards. */
3165 tmp = gfc_call_free (var);
3166 gfc_add_expr_to_block (&se->post, tmp);
3169 return var;
3173 /* Handle a string concatenation operation. A temporary will be allocated to
3174 hold the result. */
3176 static void
3177 gfc_conv_concat_op (gfc_se * se, gfc_expr * expr)
3179 gfc_se lse, rse;
3180 tree len, type, var, tmp, fndecl;
3182 gcc_assert (expr->value.op.op1->ts.type == BT_CHARACTER
3183 && expr->value.op.op2->ts.type == BT_CHARACTER);
3184 gcc_assert (expr->value.op.op1->ts.kind == expr->value.op.op2->ts.kind);
3186 gfc_init_se (&lse, se);
3187 gfc_conv_expr (&lse, expr->value.op.op1);
3188 gfc_conv_string_parameter (&lse);
3189 gfc_init_se (&rse, se);
3190 gfc_conv_expr (&rse, expr->value.op.op2);
3191 gfc_conv_string_parameter (&rse);
3193 gfc_add_block_to_block (&se->pre, &lse.pre);
3194 gfc_add_block_to_block (&se->pre, &rse.pre);
3196 type = gfc_get_character_type (expr->ts.kind, expr->ts.u.cl);
3197 len = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
3198 if (len == NULL_TREE)
3200 len = fold_build2_loc (input_location, PLUS_EXPR,
3201 gfc_charlen_type_node,
3202 fold_convert (gfc_charlen_type_node,
3203 lse.string_length),
3204 fold_convert (gfc_charlen_type_node,
3205 rse.string_length));
3208 type = build_pointer_type (type);
3210 var = gfc_conv_string_tmp (se, type, len);
3212 /* Do the actual concatenation. */
3213 if (expr->ts.kind == 1)
3214 fndecl = gfor_fndecl_concat_string;
3215 else if (expr->ts.kind == 4)
3216 fndecl = gfor_fndecl_concat_string_char4;
3217 else
3218 gcc_unreachable ();
3220 tmp = build_call_expr_loc (input_location,
3221 fndecl, 6, len, var, lse.string_length, lse.expr,
3222 rse.string_length, rse.expr);
3223 gfc_add_expr_to_block (&se->pre, tmp);
3225 /* Add the cleanup for the operands. */
3226 gfc_add_block_to_block (&se->pre, &rse.post);
3227 gfc_add_block_to_block (&se->pre, &lse.post);
3229 se->expr = var;
3230 se->string_length = len;
3233 /* Translates an op expression. Common (binary) cases are handled by this
3234 function, others are passed on. Recursion is used in either case.
3235 We use the fact that (op1.ts == op2.ts) (except for the power
3236 operator **).
3237 Operators need no special handling for scalarized expressions as long as
3238 they call gfc_conv_simple_val to get their operands.
3239 Character strings get special handling. */
3241 static void
3242 gfc_conv_expr_op (gfc_se * se, gfc_expr * expr)
3244 enum tree_code code;
3245 gfc_se lse;
3246 gfc_se rse;
3247 tree tmp, type;
3248 int lop;
3249 int checkstring;
3251 checkstring = 0;
3252 lop = 0;
3253 switch (expr->value.op.op)
3255 case INTRINSIC_PARENTHESES:
3256 if ((expr->ts.type == BT_REAL || expr->ts.type == BT_COMPLEX)
3257 && flag_protect_parens)
3259 gfc_conv_unary_op (PAREN_EXPR, se, expr);
3260 gcc_assert (FLOAT_TYPE_P (TREE_TYPE (se->expr)));
3261 return;
3264 /* Fallthrough. */
3265 case INTRINSIC_UPLUS:
3266 gfc_conv_expr (se, expr->value.op.op1);
3267 return;
3269 case INTRINSIC_UMINUS:
3270 gfc_conv_unary_op (NEGATE_EXPR, se, expr);
3271 return;
3273 case INTRINSIC_NOT:
3274 gfc_conv_unary_op (TRUTH_NOT_EXPR, se, expr);
3275 return;
3277 case INTRINSIC_PLUS:
3278 code = PLUS_EXPR;
3279 break;
3281 case INTRINSIC_MINUS:
3282 code = MINUS_EXPR;
3283 break;
3285 case INTRINSIC_TIMES:
3286 code = MULT_EXPR;
3287 break;
3289 case INTRINSIC_DIVIDE:
3290 /* If expr is a real or complex expr, use an RDIV_EXPR. If op1 is
3291 an integer, we must round towards zero, so we use a
3292 TRUNC_DIV_EXPR. */
3293 if (expr->ts.type == BT_INTEGER)
3294 code = TRUNC_DIV_EXPR;
3295 else
3296 code = RDIV_EXPR;
3297 break;
3299 case INTRINSIC_POWER:
3300 gfc_conv_power_op (se, expr);
3301 return;
3303 case INTRINSIC_CONCAT:
3304 gfc_conv_concat_op (se, expr);
3305 return;
3307 case INTRINSIC_AND:
3308 code = TRUTH_ANDIF_EXPR;
3309 lop = 1;
3310 break;
3312 case INTRINSIC_OR:
3313 code = TRUTH_ORIF_EXPR;
3314 lop = 1;
3315 break;
3317 /* EQV and NEQV only work on logicals, but since we represent them
3318 as integers, we can use EQ_EXPR and NE_EXPR for them in GIMPLE. */
3319 case INTRINSIC_EQ:
3320 case INTRINSIC_EQ_OS:
3321 case INTRINSIC_EQV:
3322 code = EQ_EXPR;
3323 checkstring = 1;
3324 lop = 1;
3325 break;
3327 case INTRINSIC_NE:
3328 case INTRINSIC_NE_OS:
3329 case INTRINSIC_NEQV:
3330 code = NE_EXPR;
3331 checkstring = 1;
3332 lop = 1;
3333 break;
3335 case INTRINSIC_GT:
3336 case INTRINSIC_GT_OS:
3337 code = GT_EXPR;
3338 checkstring = 1;
3339 lop = 1;
3340 break;
3342 case INTRINSIC_GE:
3343 case INTRINSIC_GE_OS:
3344 code = GE_EXPR;
3345 checkstring = 1;
3346 lop = 1;
3347 break;
3349 case INTRINSIC_LT:
3350 case INTRINSIC_LT_OS:
3351 code = LT_EXPR;
3352 checkstring = 1;
3353 lop = 1;
3354 break;
3356 case INTRINSIC_LE:
3357 case INTRINSIC_LE_OS:
3358 code = LE_EXPR;
3359 checkstring = 1;
3360 lop = 1;
3361 break;
3363 case INTRINSIC_USER:
3364 case INTRINSIC_ASSIGN:
3365 /* These should be converted into function calls by the frontend. */
3366 gcc_unreachable ();
3368 default:
3369 fatal_error (input_location, "Unknown intrinsic op");
3370 return;
3373 /* The only exception to this is **, which is handled separately anyway. */
3374 gcc_assert (expr->value.op.op1->ts.type == expr->value.op.op2->ts.type);
3376 if (checkstring && expr->value.op.op1->ts.type != BT_CHARACTER)
3377 checkstring = 0;
3379 /* lhs */
3380 gfc_init_se (&lse, se);
3381 gfc_conv_expr (&lse, expr->value.op.op1);
3382 gfc_add_block_to_block (&se->pre, &lse.pre);
3384 /* rhs */
3385 gfc_init_se (&rse, se);
3386 gfc_conv_expr (&rse, expr->value.op.op2);
3387 gfc_add_block_to_block (&se->pre, &rse.pre);
3389 if (checkstring)
3391 gfc_conv_string_parameter (&lse);
3392 gfc_conv_string_parameter (&rse);
3394 lse.expr = gfc_build_compare_string (lse.string_length, lse.expr,
3395 rse.string_length, rse.expr,
3396 expr->value.op.op1->ts.kind,
3397 code);
3398 rse.expr = build_int_cst (TREE_TYPE (lse.expr), 0);
3399 gfc_add_block_to_block (&lse.post, &rse.post);
3402 type = gfc_typenode_for_spec (&expr->ts);
3404 if (lop)
3406 /* The result of logical ops is always logical_type_node. */
3407 tmp = fold_build2_loc (input_location, code, logical_type_node,
3408 lse.expr, rse.expr);
3409 se->expr = convert (type, tmp);
3411 else
3412 se->expr = fold_build2_loc (input_location, code, type, lse.expr, rse.expr);
3414 /* Add the post blocks. */
3415 gfc_add_block_to_block (&se->post, &rse.post);
3416 gfc_add_block_to_block (&se->post, &lse.post);
3419 /* If a string's length is one, we convert it to a single character. */
3421 tree
3422 gfc_string_to_single_character (tree len, tree str, int kind)
3425 if (len == NULL
3426 || !tree_fits_uhwi_p (len)
3427 || !POINTER_TYPE_P (TREE_TYPE (str)))
3428 return NULL_TREE;
3430 if (TREE_INT_CST_LOW (len) == 1)
3432 str = fold_convert (gfc_get_pchar_type (kind), str);
3433 return build_fold_indirect_ref_loc (input_location, str);
3436 if (kind == 1
3437 && TREE_CODE (str) == ADDR_EXPR
3438 && TREE_CODE (TREE_OPERAND (str, 0)) == ARRAY_REF
3439 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (str, 0), 0)) == STRING_CST
3440 && array_ref_low_bound (TREE_OPERAND (str, 0))
3441 == TREE_OPERAND (TREE_OPERAND (str, 0), 1)
3442 && TREE_INT_CST_LOW (len) > 1
3443 && TREE_INT_CST_LOW (len)
3444 == (unsigned HOST_WIDE_INT)
3445 TREE_STRING_LENGTH (TREE_OPERAND (TREE_OPERAND (str, 0), 0)))
3447 tree ret = fold_convert (gfc_get_pchar_type (kind), str);
3448 ret = build_fold_indirect_ref_loc (input_location, ret);
3449 if (TREE_CODE (ret) == INTEGER_CST)
3451 tree string_cst = TREE_OPERAND (TREE_OPERAND (str, 0), 0);
3452 int i, length = TREE_STRING_LENGTH (string_cst);
3453 const char *ptr = TREE_STRING_POINTER (string_cst);
3455 for (i = 1; i < length; i++)
3456 if (ptr[i] != ' ')
3457 return NULL_TREE;
3459 return ret;
3463 return NULL_TREE;
3467 void
3468 gfc_conv_scalar_char_value (gfc_symbol *sym, gfc_se *se, gfc_expr **expr)
3471 if (sym->backend_decl)
3473 /* This becomes the nominal_type in
3474 function.c:assign_parm_find_data_types. */
3475 TREE_TYPE (sym->backend_decl) = unsigned_char_type_node;
3476 /* This becomes the passed_type in
3477 function.c:assign_parm_find_data_types. C promotes char to
3478 integer for argument passing. */
3479 DECL_ARG_TYPE (sym->backend_decl) = unsigned_type_node;
3481 DECL_BY_REFERENCE (sym->backend_decl) = 0;
3484 if (expr != NULL)
3486 /* If we have a constant character expression, make it into an
3487 integer. */
3488 if ((*expr)->expr_type == EXPR_CONSTANT)
3490 gfc_typespec ts;
3491 gfc_clear_ts (&ts);
3493 *expr = gfc_get_int_expr (gfc_default_integer_kind, NULL,
3494 (int)(*expr)->value.character.string[0]);
3495 if ((*expr)->ts.kind != gfc_c_int_kind)
3497 /* The expr needs to be compatible with a C int. If the
3498 conversion fails, then the 2 causes an ICE. */
3499 ts.type = BT_INTEGER;
3500 ts.kind = gfc_c_int_kind;
3501 gfc_convert_type (*expr, &ts, 2);
3504 else if (se != NULL && (*expr)->expr_type == EXPR_VARIABLE)
3506 if ((*expr)->ref == NULL)
3508 se->expr = gfc_string_to_single_character
3509 (build_int_cst (integer_type_node, 1),
3510 gfc_build_addr_expr (gfc_get_pchar_type ((*expr)->ts.kind),
3511 gfc_get_symbol_decl
3512 ((*expr)->symtree->n.sym)),
3513 (*expr)->ts.kind);
3515 else
3517 gfc_conv_variable (se, *expr);
3518 se->expr = gfc_string_to_single_character
3519 (build_int_cst (integer_type_node, 1),
3520 gfc_build_addr_expr (gfc_get_pchar_type ((*expr)->ts.kind),
3521 se->expr),
3522 (*expr)->ts.kind);
3528 /* Helper function for gfc_build_compare_string. Return LEN_TRIM value
3529 if STR is a string literal, otherwise return -1. */
3531 static int
3532 gfc_optimize_len_trim (tree len, tree str, int kind)
3534 if (kind == 1
3535 && TREE_CODE (str) == ADDR_EXPR
3536 && TREE_CODE (TREE_OPERAND (str, 0)) == ARRAY_REF
3537 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (str, 0), 0)) == STRING_CST
3538 && array_ref_low_bound (TREE_OPERAND (str, 0))
3539 == TREE_OPERAND (TREE_OPERAND (str, 0), 1)
3540 && tree_fits_uhwi_p (len)
3541 && tree_to_uhwi (len) >= 1
3542 && tree_to_uhwi (len)
3543 == (unsigned HOST_WIDE_INT)
3544 TREE_STRING_LENGTH (TREE_OPERAND (TREE_OPERAND (str, 0), 0)))
3546 tree folded = fold_convert (gfc_get_pchar_type (kind), str);
3547 folded = build_fold_indirect_ref_loc (input_location, folded);
3548 if (TREE_CODE (folded) == INTEGER_CST)
3550 tree string_cst = TREE_OPERAND (TREE_OPERAND (str, 0), 0);
3551 int length = TREE_STRING_LENGTH (string_cst);
3552 const char *ptr = TREE_STRING_POINTER (string_cst);
3554 for (; length > 0; length--)
3555 if (ptr[length - 1] != ' ')
3556 break;
3558 return length;
3561 return -1;
3564 /* Helper to build a call to memcmp. */
3566 static tree
3567 build_memcmp_call (tree s1, tree s2, tree n)
3569 tree tmp;
3571 if (!POINTER_TYPE_P (TREE_TYPE (s1)))
3572 s1 = gfc_build_addr_expr (pvoid_type_node, s1);
3573 else
3574 s1 = fold_convert (pvoid_type_node, s1);
3576 if (!POINTER_TYPE_P (TREE_TYPE (s2)))
3577 s2 = gfc_build_addr_expr (pvoid_type_node, s2);
3578 else
3579 s2 = fold_convert (pvoid_type_node, s2);
3581 n = fold_convert (size_type_node, n);
3583 tmp = build_call_expr_loc (input_location,
3584 builtin_decl_explicit (BUILT_IN_MEMCMP),
3585 3, s1, s2, n);
3587 return fold_convert (integer_type_node, tmp);
3590 /* Compare two strings. If they are all single characters, the result is the
3591 subtraction of them. Otherwise, we build a library call. */
3593 tree
3594 gfc_build_compare_string (tree len1, tree str1, tree len2, tree str2, int kind,
3595 enum tree_code code)
3597 tree sc1;
3598 tree sc2;
3599 tree fndecl;
3601 gcc_assert (POINTER_TYPE_P (TREE_TYPE (str1)));
3602 gcc_assert (POINTER_TYPE_P (TREE_TYPE (str2)));
3604 sc1 = gfc_string_to_single_character (len1, str1, kind);
3605 sc2 = gfc_string_to_single_character (len2, str2, kind);
3607 if (sc1 != NULL_TREE && sc2 != NULL_TREE)
3609 /* Deal with single character specially. */
3610 sc1 = fold_convert (integer_type_node, sc1);
3611 sc2 = fold_convert (integer_type_node, sc2);
3612 return fold_build2_loc (input_location, MINUS_EXPR, integer_type_node,
3613 sc1, sc2);
3616 if ((code == EQ_EXPR || code == NE_EXPR)
3617 && optimize
3618 && INTEGER_CST_P (len1) && INTEGER_CST_P (len2))
3620 /* If one string is a string literal with LEN_TRIM longer
3621 than the length of the second string, the strings
3622 compare unequal. */
3623 int len = gfc_optimize_len_trim (len1, str1, kind);
3624 if (len > 0 && compare_tree_int (len2, len) < 0)
3625 return integer_one_node;
3626 len = gfc_optimize_len_trim (len2, str2, kind);
3627 if (len > 0 && compare_tree_int (len1, len) < 0)
3628 return integer_one_node;
3631 /* We can compare via memcpy if the strings are known to be equal
3632 in length and they are
3633 - kind=1
3634 - kind=4 and the comparison is for (in)equality. */
3636 if (INTEGER_CST_P (len1) && INTEGER_CST_P (len2)
3637 && tree_int_cst_equal (len1, len2)
3638 && (kind == 1 || code == EQ_EXPR || code == NE_EXPR))
3640 tree tmp;
3641 tree chartype;
3643 chartype = gfc_get_char_type (kind);
3644 tmp = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE(len1),
3645 fold_convert (TREE_TYPE(len1),
3646 TYPE_SIZE_UNIT(chartype)),
3647 len1);
3648 return build_memcmp_call (str1, str2, tmp);
3651 /* Build a call for the comparison. */
3652 if (kind == 1)
3653 fndecl = gfor_fndecl_compare_string;
3654 else if (kind == 4)
3655 fndecl = gfor_fndecl_compare_string_char4;
3656 else
3657 gcc_unreachable ();
3659 return build_call_expr_loc (input_location, fndecl, 4,
3660 len1, str1, len2, str2);
3664 /* Return the backend_decl for a procedure pointer component. */
3666 static tree
3667 get_proc_ptr_comp (gfc_expr *e)
3669 gfc_se comp_se;
3670 gfc_expr *e2;
3671 expr_t old_type;
3673 gfc_init_se (&comp_se, NULL);
3674 e2 = gfc_copy_expr (e);
3675 /* We have to restore the expr type later so that gfc_free_expr frees
3676 the exact same thing that was allocated.
3677 TODO: This is ugly. */
3678 old_type = e2->expr_type;
3679 e2->expr_type = EXPR_VARIABLE;
3680 gfc_conv_expr (&comp_se, e2);
3681 e2->expr_type = old_type;
3682 gfc_free_expr (e2);
3683 return build_fold_addr_expr_loc (input_location, comp_se.expr);
3687 /* Convert a typebound function reference from a class object. */
3688 static void
3689 conv_base_obj_fcn_val (gfc_se * se, tree base_object, gfc_expr * expr)
3691 gfc_ref *ref;
3692 tree var;
3694 if (!VAR_P (base_object))
3696 var = gfc_create_var (TREE_TYPE (base_object), NULL);
3697 gfc_add_modify (&se->pre, var, base_object);
3699 se->expr = gfc_class_vptr_get (base_object);
3700 se->expr = build_fold_indirect_ref_loc (input_location, se->expr);
3701 ref = expr->ref;
3702 while (ref && ref->next)
3703 ref = ref->next;
3704 gcc_assert (ref && ref->type == REF_COMPONENT);
3705 if (ref->u.c.sym->attr.extension)
3706 conv_parent_component_references (se, ref);
3707 gfc_conv_component_ref (se, ref);
3708 se->expr = build_fold_addr_expr_loc (input_location, se->expr);
3712 static void
3713 conv_function_val (gfc_se * se, gfc_symbol * sym, gfc_expr * expr)
3715 tree tmp;
3717 if (gfc_is_proc_ptr_comp (expr))
3718 tmp = get_proc_ptr_comp (expr);
3719 else if (sym->attr.dummy)
3721 tmp = gfc_get_symbol_decl (sym);
3722 if (sym->attr.proc_pointer)
3723 tmp = build_fold_indirect_ref_loc (input_location,
3724 tmp);
3725 gcc_assert (TREE_CODE (TREE_TYPE (tmp)) == POINTER_TYPE
3726 && TREE_CODE (TREE_TYPE (TREE_TYPE (tmp))) == FUNCTION_TYPE);
3728 else
3730 if (!sym->backend_decl)
3731 sym->backend_decl = gfc_get_extern_function_decl (sym);
3733 TREE_USED (sym->backend_decl) = 1;
3735 tmp = sym->backend_decl;
3737 if (sym->attr.cray_pointee)
3739 /* TODO - make the cray pointee a pointer to a procedure,
3740 assign the pointer to it and use it for the call. This
3741 will do for now! */
3742 tmp = convert (build_pointer_type (TREE_TYPE (tmp)),
3743 gfc_get_symbol_decl (sym->cp_pointer));
3744 tmp = gfc_evaluate_now (tmp, &se->pre);
3747 if (!POINTER_TYPE_P (TREE_TYPE (tmp)))
3749 gcc_assert (TREE_CODE (tmp) == FUNCTION_DECL);
3750 tmp = gfc_build_addr_expr (NULL_TREE, tmp);
3753 se->expr = tmp;
3757 /* Initialize MAPPING. */
3759 void
3760 gfc_init_interface_mapping (gfc_interface_mapping * mapping)
3762 mapping->syms = NULL;
3763 mapping->charlens = NULL;
3767 /* Free all memory held by MAPPING (but not MAPPING itself). */
3769 void
3770 gfc_free_interface_mapping (gfc_interface_mapping * mapping)
3772 gfc_interface_sym_mapping *sym;
3773 gfc_interface_sym_mapping *nextsym;
3774 gfc_charlen *cl;
3775 gfc_charlen *nextcl;
3777 for (sym = mapping->syms; sym; sym = nextsym)
3779 nextsym = sym->next;
3780 sym->new_sym->n.sym->formal = NULL;
3781 gfc_free_symbol (sym->new_sym->n.sym);
3782 gfc_free_expr (sym->expr);
3783 free (sym->new_sym);
3784 free (sym);
3786 for (cl = mapping->charlens; cl; cl = nextcl)
3788 nextcl = cl->next;
3789 gfc_free_expr (cl->length);
3790 free (cl);
3795 /* Return a copy of gfc_charlen CL. Add the returned structure to
3796 MAPPING so that it will be freed by gfc_free_interface_mapping. */
3798 static gfc_charlen *
3799 gfc_get_interface_mapping_charlen (gfc_interface_mapping * mapping,
3800 gfc_charlen * cl)
3802 gfc_charlen *new_charlen;
3804 new_charlen = gfc_get_charlen ();
3805 new_charlen->next = mapping->charlens;
3806 new_charlen->length = gfc_copy_expr (cl->length);
3808 mapping->charlens = new_charlen;
3809 return new_charlen;
3813 /* A subroutine of gfc_add_interface_mapping. Return a descriptorless
3814 array variable that can be used as the actual argument for dummy
3815 argument SYM. Add any initialization code to BLOCK. PACKED is as
3816 for gfc_get_nodesc_array_type and DATA points to the first element
3817 in the passed array. */
3819 static tree
3820 gfc_get_interface_mapping_array (stmtblock_t * block, gfc_symbol * sym,
3821 gfc_packed packed, tree data)
3823 tree type;
3824 tree var;
3826 type = gfc_typenode_for_spec (&sym->ts);
3827 type = gfc_get_nodesc_array_type (type, sym->as, packed,
3828 !sym->attr.target && !sym->attr.pointer
3829 && !sym->attr.proc_pointer);
3831 var = gfc_create_var (type, "ifm");
3832 gfc_add_modify (block, var, fold_convert (type, data));
3834 return var;
3838 /* A subroutine of gfc_add_interface_mapping. Set the stride, upper bounds
3839 and offset of descriptorless array type TYPE given that it has the same
3840 size as DESC. Add any set-up code to BLOCK. */
3842 static void
3843 gfc_set_interface_mapping_bounds (stmtblock_t * block, tree type, tree desc)
3845 int n;
3846 tree dim;
3847 tree offset;
3848 tree tmp;
3850 offset = gfc_index_zero_node;
3851 for (n = 0; n < GFC_TYPE_ARRAY_RANK (type); n++)
3853 dim = gfc_rank_cst[n];
3854 GFC_TYPE_ARRAY_STRIDE (type, n) = gfc_conv_array_stride (desc, n);
3855 if (GFC_TYPE_ARRAY_LBOUND (type, n) == NULL_TREE)
3857 GFC_TYPE_ARRAY_LBOUND (type, n)
3858 = gfc_conv_descriptor_lbound_get (desc, dim);
3859 GFC_TYPE_ARRAY_UBOUND (type, n)
3860 = gfc_conv_descriptor_ubound_get (desc, dim);
3862 else if (GFC_TYPE_ARRAY_UBOUND (type, n) == NULL_TREE)
3864 tmp = fold_build2_loc (input_location, MINUS_EXPR,
3865 gfc_array_index_type,
3866 gfc_conv_descriptor_ubound_get (desc, dim),
3867 gfc_conv_descriptor_lbound_get (desc, dim));
3868 tmp = fold_build2_loc (input_location, PLUS_EXPR,
3869 gfc_array_index_type,
3870 GFC_TYPE_ARRAY_LBOUND (type, n), tmp);
3871 tmp = gfc_evaluate_now (tmp, block);
3872 GFC_TYPE_ARRAY_UBOUND (type, n) = tmp;
3874 tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
3875 GFC_TYPE_ARRAY_LBOUND (type, n),
3876 GFC_TYPE_ARRAY_STRIDE (type, n));
3877 offset = fold_build2_loc (input_location, MINUS_EXPR,
3878 gfc_array_index_type, offset, tmp);
3880 offset = gfc_evaluate_now (offset, block);
3881 GFC_TYPE_ARRAY_OFFSET (type) = offset;
3885 /* Extend MAPPING so that it maps dummy argument SYM to the value stored
3886 in SE. The caller may still use se->expr and se->string_length after
3887 calling this function. */
3889 void
3890 gfc_add_interface_mapping (gfc_interface_mapping * mapping,
3891 gfc_symbol * sym, gfc_se * se,
3892 gfc_expr *expr)
3894 gfc_interface_sym_mapping *sm;
3895 tree desc;
3896 tree tmp;
3897 tree value;
3898 gfc_symbol *new_sym;
3899 gfc_symtree *root;
3900 gfc_symtree *new_symtree;
3902 /* Create a new symbol to represent the actual argument. */
3903 new_sym = gfc_new_symbol (sym->name, NULL);
3904 new_sym->ts = sym->ts;
3905 new_sym->as = gfc_copy_array_spec (sym->as);
3906 new_sym->attr.referenced = 1;
3907 new_sym->attr.dimension = sym->attr.dimension;
3908 new_sym->attr.contiguous = sym->attr.contiguous;
3909 new_sym->attr.codimension = sym->attr.codimension;
3910 new_sym->attr.pointer = sym->attr.pointer;
3911 new_sym->attr.allocatable = sym->attr.allocatable;
3912 new_sym->attr.flavor = sym->attr.flavor;
3913 new_sym->attr.function = sym->attr.function;
3915 /* Ensure that the interface is available and that
3916 descriptors are passed for array actual arguments. */
3917 if (sym->attr.flavor == FL_PROCEDURE)
3919 new_sym->formal = expr->symtree->n.sym->formal;
3920 new_sym->attr.always_explicit
3921 = expr->symtree->n.sym->attr.always_explicit;
3924 /* Create a fake symtree for it. */
3925 root = NULL;
3926 new_symtree = gfc_new_symtree (&root, sym->name);
3927 new_symtree->n.sym = new_sym;
3928 gcc_assert (new_symtree == root);
3930 /* Create a dummy->actual mapping. */
3931 sm = XCNEW (gfc_interface_sym_mapping);
3932 sm->next = mapping->syms;
3933 sm->old = sym;
3934 sm->new_sym = new_symtree;
3935 sm->expr = gfc_copy_expr (expr);
3936 mapping->syms = sm;
3938 /* Stabilize the argument's value. */
3939 if (!sym->attr.function && se)
3940 se->expr = gfc_evaluate_now (se->expr, &se->pre);
3942 if (sym->ts.type == BT_CHARACTER)
3944 /* Create a copy of the dummy argument's length. */
3945 new_sym->ts.u.cl = gfc_get_interface_mapping_charlen (mapping, sym->ts.u.cl);
3946 sm->expr->ts.u.cl = new_sym->ts.u.cl;
3948 /* If the length is specified as "*", record the length that
3949 the caller is passing. We should use the callee's length
3950 in all other cases. */
3951 if (!new_sym->ts.u.cl->length && se)
3953 se->string_length = gfc_evaluate_now (se->string_length, &se->pre);
3954 new_sym->ts.u.cl->backend_decl = se->string_length;
3958 if (!se)
3959 return;
3961 /* Use the passed value as-is if the argument is a function. */
3962 if (sym->attr.flavor == FL_PROCEDURE)
3963 value = se->expr;
3965 /* If the argument is a pass-by-value scalar, use the value as is. */
3966 else if (!sym->attr.dimension && sym->attr.value)
3967 value = se->expr;
3969 /* If the argument is either a string or a pointer to a string,
3970 convert it to a boundless character type. */
3971 else if (!sym->attr.dimension && sym->ts.type == BT_CHARACTER)
3973 tmp = gfc_get_character_type_len (sym->ts.kind, NULL);
3974 tmp = build_pointer_type (tmp);
3975 if (sym->attr.pointer)
3976 value = build_fold_indirect_ref_loc (input_location,
3977 se->expr);
3978 else
3979 value = se->expr;
3980 value = fold_convert (tmp, value);
3983 /* If the argument is a scalar, a pointer to an array or an allocatable,
3984 dereference it. */
3985 else if (!sym->attr.dimension || sym->attr.pointer || sym->attr.allocatable)
3986 value = build_fold_indirect_ref_loc (input_location,
3987 se->expr);
3989 /* For character(*), use the actual argument's descriptor. */
3990 else if (sym->ts.type == BT_CHARACTER && !new_sym->ts.u.cl->length)
3991 value = build_fold_indirect_ref_loc (input_location,
3992 se->expr);
3994 /* If the argument is an array descriptor, use it to determine
3995 information about the actual argument's shape. */
3996 else if (POINTER_TYPE_P (TREE_TYPE (se->expr))
3997 && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (TREE_TYPE (se->expr))))
3999 /* Get the actual argument's descriptor. */
4000 desc = build_fold_indirect_ref_loc (input_location,
4001 se->expr);
4003 /* Create the replacement variable. */
4004 tmp = gfc_conv_descriptor_data_get (desc);
4005 value = gfc_get_interface_mapping_array (&se->pre, sym,
4006 PACKED_NO, tmp);
4008 /* Use DESC to work out the upper bounds, strides and offset. */
4009 gfc_set_interface_mapping_bounds (&se->pre, TREE_TYPE (value), desc);
4011 else
4012 /* Otherwise we have a packed array. */
4013 value = gfc_get_interface_mapping_array (&se->pre, sym,
4014 PACKED_FULL, se->expr);
4016 new_sym->backend_decl = value;
4020 /* Called once all dummy argument mappings have been added to MAPPING,
4021 but before the mapping is used to evaluate expressions. Pre-evaluate
4022 the length of each argument, adding any initialization code to PRE and
4023 any finalization code to POST. */
4025 void
4026 gfc_finish_interface_mapping (gfc_interface_mapping * mapping,
4027 stmtblock_t * pre, stmtblock_t * post)
4029 gfc_interface_sym_mapping *sym;
4030 gfc_expr *expr;
4031 gfc_se se;
4033 for (sym = mapping->syms; sym; sym = sym->next)
4034 if (sym->new_sym->n.sym->ts.type == BT_CHARACTER
4035 && !sym->new_sym->n.sym->ts.u.cl->backend_decl)
4037 expr = sym->new_sym->n.sym->ts.u.cl->length;
4038 gfc_apply_interface_mapping_to_expr (mapping, expr);
4039 gfc_init_se (&se, NULL);
4040 gfc_conv_expr (&se, expr);
4041 se.expr = fold_convert (gfc_charlen_type_node, se.expr);
4042 se.expr = gfc_evaluate_now (se.expr, &se.pre);
4043 gfc_add_block_to_block (pre, &se.pre);
4044 gfc_add_block_to_block (post, &se.post);
4046 sym->new_sym->n.sym->ts.u.cl->backend_decl = se.expr;
4051 /* Like gfc_apply_interface_mapping_to_expr, but applied to
4052 constructor C. */
4054 static void
4055 gfc_apply_interface_mapping_to_cons (gfc_interface_mapping * mapping,
4056 gfc_constructor_base base)
4058 gfc_constructor *c;
4059 for (c = gfc_constructor_first (base); c; c = gfc_constructor_next (c))
4061 gfc_apply_interface_mapping_to_expr (mapping, c->expr);
4062 if (c->iterator)
4064 gfc_apply_interface_mapping_to_expr (mapping, c->iterator->start);
4065 gfc_apply_interface_mapping_to_expr (mapping, c->iterator->end);
4066 gfc_apply_interface_mapping_to_expr (mapping, c->iterator->step);
4072 /* Like gfc_apply_interface_mapping_to_expr, but applied to
4073 reference REF. */
4075 static void
4076 gfc_apply_interface_mapping_to_ref (gfc_interface_mapping * mapping,
4077 gfc_ref * ref)
4079 int n;
4081 for (; ref; ref = ref->next)
4082 switch (ref->type)
4084 case REF_ARRAY:
4085 for (n = 0; n < ref->u.ar.dimen; n++)
4087 gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.start[n]);
4088 gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.end[n]);
4089 gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.stride[n]);
4091 break;
4093 case REF_COMPONENT:
4094 break;
4096 case REF_SUBSTRING:
4097 gfc_apply_interface_mapping_to_expr (mapping, ref->u.ss.start);
4098 gfc_apply_interface_mapping_to_expr (mapping, ref->u.ss.end);
4099 break;
4104 /* Convert intrinsic function calls into result expressions. */
4106 static bool
4107 gfc_map_intrinsic_function (gfc_expr *expr, gfc_interface_mapping *mapping)
4109 gfc_symbol *sym;
4110 gfc_expr *new_expr;
4111 gfc_expr *arg1;
4112 gfc_expr *arg2;
4113 int d, dup;
4115 arg1 = expr->value.function.actual->expr;
4116 if (expr->value.function.actual->next)
4117 arg2 = expr->value.function.actual->next->expr;
4118 else
4119 arg2 = NULL;
4121 sym = arg1->symtree->n.sym;
4123 if (sym->attr.dummy)
4124 return false;
4126 new_expr = NULL;
4128 switch (expr->value.function.isym->id)
4130 case GFC_ISYM_LEN:
4131 /* TODO figure out why this condition is necessary. */
4132 if (sym->attr.function
4133 && (arg1->ts.u.cl->length == NULL
4134 || (arg1->ts.u.cl->length->expr_type != EXPR_CONSTANT
4135 && arg1->ts.u.cl->length->expr_type != EXPR_VARIABLE)))
4136 return false;
4138 new_expr = gfc_copy_expr (arg1->ts.u.cl->length);
4139 break;
4141 case GFC_ISYM_LEN_TRIM:
4142 new_expr = gfc_copy_expr (arg1);
4143 gfc_apply_interface_mapping_to_expr (mapping, new_expr);
4145 if (!new_expr)
4146 return false;
4148 gfc_replace_expr (arg1, new_expr);
4149 return true;
4151 case GFC_ISYM_SIZE:
4152 if (!sym->as || sym->as->rank == 0)
4153 return false;
4155 if (arg2 && arg2->expr_type == EXPR_CONSTANT)
4157 dup = mpz_get_si (arg2->value.integer);
4158 d = dup - 1;
4160 else
4162 dup = sym->as->rank;
4163 d = 0;
4166 for (; d < dup; d++)
4168 gfc_expr *tmp;
4170 if (!sym->as->upper[d] || !sym->as->lower[d])
4172 gfc_free_expr (new_expr);
4173 return false;
4176 tmp = gfc_add (gfc_copy_expr (sym->as->upper[d]),
4177 gfc_get_int_expr (gfc_default_integer_kind,
4178 NULL, 1));
4179 tmp = gfc_subtract (tmp, gfc_copy_expr (sym->as->lower[d]));
4180 if (new_expr)
4181 new_expr = gfc_multiply (new_expr, tmp);
4182 else
4183 new_expr = tmp;
4185 break;
4187 case GFC_ISYM_LBOUND:
4188 case GFC_ISYM_UBOUND:
4189 /* TODO These implementations of lbound and ubound do not limit if
4190 the size < 0, according to F95's 13.14.53 and 13.14.113. */
4192 if (!sym->as || sym->as->rank == 0)
4193 return false;
4195 if (arg2 && arg2->expr_type == EXPR_CONSTANT)
4196 d = mpz_get_si (arg2->value.integer) - 1;
4197 else
4198 return false;
4200 if (expr->value.function.isym->id == GFC_ISYM_LBOUND)
4202 if (sym->as->lower[d])
4203 new_expr = gfc_copy_expr (sym->as->lower[d]);
4205 else
4207 if (sym->as->upper[d])
4208 new_expr = gfc_copy_expr (sym->as->upper[d]);
4210 break;
4212 default:
4213 break;
4216 gfc_apply_interface_mapping_to_expr (mapping, new_expr);
4217 if (!new_expr)
4218 return false;
4220 gfc_replace_expr (expr, new_expr);
4221 return true;
4225 static void
4226 gfc_map_fcn_formal_to_actual (gfc_expr *expr, gfc_expr *map_expr,
4227 gfc_interface_mapping * mapping)
4229 gfc_formal_arglist *f;
4230 gfc_actual_arglist *actual;
4232 actual = expr->value.function.actual;
4233 f = gfc_sym_get_dummy_args (map_expr->symtree->n.sym);
4235 for (; f && actual; f = f->next, actual = actual->next)
4237 if (!actual->expr)
4238 continue;
4240 gfc_add_interface_mapping (mapping, f->sym, NULL, actual->expr);
4243 if (map_expr->symtree->n.sym->attr.dimension)
4245 int d;
4246 gfc_array_spec *as;
4248 as = gfc_copy_array_spec (map_expr->symtree->n.sym->as);
4250 for (d = 0; d < as->rank; d++)
4252 gfc_apply_interface_mapping_to_expr (mapping, as->lower[d]);
4253 gfc_apply_interface_mapping_to_expr (mapping, as->upper[d]);
4256 expr->value.function.esym->as = as;
4259 if (map_expr->symtree->n.sym->ts.type == BT_CHARACTER)
4261 expr->value.function.esym->ts.u.cl->length
4262 = gfc_copy_expr (map_expr->symtree->n.sym->ts.u.cl->length);
4264 gfc_apply_interface_mapping_to_expr (mapping,
4265 expr->value.function.esym->ts.u.cl->length);
4270 /* EXPR is a copy of an expression that appeared in the interface
4271 associated with MAPPING. Walk it recursively looking for references to
4272 dummy arguments that MAPPING maps to actual arguments. Replace each such
4273 reference with a reference to the associated actual argument. */
4275 static void
4276 gfc_apply_interface_mapping_to_expr (gfc_interface_mapping * mapping,
4277 gfc_expr * expr)
4279 gfc_interface_sym_mapping *sym;
4280 gfc_actual_arglist *actual;
4282 if (!expr)
4283 return;
4285 /* Copying an expression does not copy its length, so do that here. */
4286 if (expr->ts.type == BT_CHARACTER && expr->ts.u.cl)
4288 expr->ts.u.cl = gfc_get_interface_mapping_charlen (mapping, expr->ts.u.cl);
4289 gfc_apply_interface_mapping_to_expr (mapping, expr->ts.u.cl->length);
4292 /* Apply the mapping to any references. */
4293 gfc_apply_interface_mapping_to_ref (mapping, expr->ref);
4295 /* ...and to the expression's symbol, if it has one. */
4296 /* TODO Find out why the condition on expr->symtree had to be moved into
4297 the loop rather than being outside it, as originally. */
4298 for (sym = mapping->syms; sym; sym = sym->next)
4299 if (expr->symtree && sym->old == expr->symtree->n.sym)
4301 if (sym->new_sym->n.sym->backend_decl)
4302 expr->symtree = sym->new_sym;
4303 else if (sym->expr)
4304 gfc_replace_expr (expr, gfc_copy_expr (sym->expr));
4307 /* ...and to subexpressions in expr->value. */
4308 switch (expr->expr_type)
4310 case EXPR_VARIABLE:
4311 case EXPR_CONSTANT:
4312 case EXPR_NULL:
4313 case EXPR_SUBSTRING:
4314 break;
4316 case EXPR_OP:
4317 gfc_apply_interface_mapping_to_expr (mapping, expr->value.op.op1);
4318 gfc_apply_interface_mapping_to_expr (mapping, expr->value.op.op2);
4319 break;
4321 case EXPR_FUNCTION:
4322 for (actual = expr->value.function.actual; actual; actual = actual->next)
4323 gfc_apply_interface_mapping_to_expr (mapping, actual->expr);
4325 if (expr->value.function.esym == NULL
4326 && expr->value.function.isym != NULL
4327 && expr->value.function.actual->expr->symtree
4328 && gfc_map_intrinsic_function (expr, mapping))
4329 break;
4331 for (sym = mapping->syms; sym; sym = sym->next)
4332 if (sym->old == expr->value.function.esym)
4334 expr->value.function.esym = sym->new_sym->n.sym;
4335 gfc_map_fcn_formal_to_actual (expr, sym->expr, mapping);
4336 expr->value.function.esym->result = sym->new_sym->n.sym;
4338 break;
4340 case EXPR_ARRAY:
4341 case EXPR_STRUCTURE:
4342 gfc_apply_interface_mapping_to_cons (mapping, expr->value.constructor);
4343 break;
4345 case EXPR_COMPCALL:
4346 case EXPR_PPC:
4347 gcc_unreachable ();
4348 break;
4351 return;
4355 /* Evaluate interface expression EXPR using MAPPING. Store the result
4356 in SE. */
4358 void
4359 gfc_apply_interface_mapping (gfc_interface_mapping * mapping,
4360 gfc_se * se, gfc_expr * expr)
4362 expr = gfc_copy_expr (expr);
4363 gfc_apply_interface_mapping_to_expr (mapping, expr);
4364 gfc_conv_expr (se, expr);
4365 se->expr = gfc_evaluate_now (se->expr, &se->pre);
4366 gfc_free_expr (expr);
4370 /* Returns a reference to a temporary array into which a component of
4371 an actual argument derived type array is copied and then returned
4372 after the function call. */
4373 void
4374 gfc_conv_subref_array_arg (gfc_se * parmse, gfc_expr * expr, int g77,
4375 sym_intent intent, bool formal_ptr)
4377 gfc_se lse;
4378 gfc_se rse;
4379 gfc_ss *lss;
4380 gfc_ss *rss;
4381 gfc_loopinfo loop;
4382 gfc_loopinfo loop2;
4383 gfc_array_info *info;
4384 tree offset;
4385 tree tmp_index;
4386 tree tmp;
4387 tree base_type;
4388 tree size;
4389 stmtblock_t body;
4390 int n;
4391 int dimen;
4393 gfc_init_se (&lse, NULL);
4394 gfc_init_se (&rse, NULL);
4396 /* Walk the argument expression. */
4397 rss = gfc_walk_expr (expr);
4399 gcc_assert (rss != gfc_ss_terminator);
4401 /* Initialize the scalarizer. */
4402 gfc_init_loopinfo (&loop);
4403 gfc_add_ss_to_loop (&loop, rss);
4405 /* Calculate the bounds of the scalarization. */
4406 gfc_conv_ss_startstride (&loop);
4408 /* Build an ss for the temporary. */
4409 if (expr->ts.type == BT_CHARACTER && !expr->ts.u.cl->backend_decl)
4410 gfc_conv_string_length (expr->ts.u.cl, expr, &parmse->pre);
4412 base_type = gfc_typenode_for_spec (&expr->ts);
4413 if (GFC_ARRAY_TYPE_P (base_type)
4414 || GFC_DESCRIPTOR_TYPE_P (base_type))
4415 base_type = gfc_get_element_type (base_type);
4417 if (expr->ts.type == BT_CLASS)
4418 base_type = gfc_typenode_for_spec (&CLASS_DATA (expr)->ts);
4420 loop.temp_ss = gfc_get_temp_ss (base_type, ((expr->ts.type == BT_CHARACTER)
4421 ? expr->ts.u.cl->backend_decl
4422 : NULL),
4423 loop.dimen);
4425 parmse->string_length = loop.temp_ss->info->string_length;
4427 /* Associate the SS with the loop. */
4428 gfc_add_ss_to_loop (&loop, loop.temp_ss);
4430 /* Setup the scalarizing loops. */
4431 gfc_conv_loop_setup (&loop, &expr->where);
4433 /* Pass the temporary descriptor back to the caller. */
4434 info = &loop.temp_ss->info->data.array;
4435 parmse->expr = info->descriptor;
4437 /* Setup the gfc_se structures. */
4438 gfc_copy_loopinfo_to_se (&lse, &loop);
4439 gfc_copy_loopinfo_to_se (&rse, &loop);
4441 rse.ss = rss;
4442 lse.ss = loop.temp_ss;
4443 gfc_mark_ss_chain_used (rss, 1);
4444 gfc_mark_ss_chain_used (loop.temp_ss, 1);
4446 /* Start the scalarized loop body. */
4447 gfc_start_scalarized_body (&loop, &body);
4449 /* Translate the expression. */
4450 gfc_conv_expr (&rse, expr);
4452 /* Reset the offset for the function call since the loop
4453 is zero based on the data pointer. Note that the temp
4454 comes first in the loop chain since it is added second. */
4455 if (gfc_is_class_array_function (expr))
4457 tmp = loop.ss->loop_chain->info->data.array.descriptor;
4458 gfc_conv_descriptor_offset_set (&loop.pre, tmp,
4459 gfc_index_zero_node);
4462 gfc_conv_tmp_array_ref (&lse);
4464 if (intent != INTENT_OUT)
4466 tmp = gfc_trans_scalar_assign (&lse, &rse, expr->ts, false, false);
4467 gfc_add_expr_to_block (&body, tmp);
4468 gcc_assert (rse.ss == gfc_ss_terminator);
4469 gfc_trans_scalarizing_loops (&loop, &body);
4471 else
4473 /* Make sure that the temporary declaration survives by merging
4474 all the loop declarations into the current context. */
4475 for (n = 0; n < loop.dimen; n++)
4477 gfc_merge_block_scope (&body);
4478 body = loop.code[loop.order[n]];
4480 gfc_merge_block_scope (&body);
4483 /* Add the post block after the second loop, so that any
4484 freeing of allocated memory is done at the right time. */
4485 gfc_add_block_to_block (&parmse->pre, &loop.pre);
4487 /**********Copy the temporary back again.*********/
4489 gfc_init_se (&lse, NULL);
4490 gfc_init_se (&rse, NULL);
4492 /* Walk the argument expression. */
4493 lss = gfc_walk_expr (expr);
4494 rse.ss = loop.temp_ss;
4495 lse.ss = lss;
4497 /* Initialize the scalarizer. */
4498 gfc_init_loopinfo (&loop2);
4499 gfc_add_ss_to_loop (&loop2, lss);
4501 dimen = rse.ss->dimen;
4503 /* Skip the write-out loop for this case. */
4504 if (gfc_is_class_array_function (expr))
4505 goto class_array_fcn;
4507 /* Calculate the bounds of the scalarization. */
4508 gfc_conv_ss_startstride (&loop2);
4510 /* Setup the scalarizing loops. */
4511 gfc_conv_loop_setup (&loop2, &expr->where);
4513 gfc_copy_loopinfo_to_se (&lse, &loop2);
4514 gfc_copy_loopinfo_to_se (&rse, &loop2);
4516 gfc_mark_ss_chain_used (lss, 1);
4517 gfc_mark_ss_chain_used (loop.temp_ss, 1);
4519 /* Declare the variable to hold the temporary offset and start the
4520 scalarized loop body. */
4521 offset = gfc_create_var (gfc_array_index_type, NULL);
4522 gfc_start_scalarized_body (&loop2, &body);
4524 /* Build the offsets for the temporary from the loop variables. The
4525 temporary array has lbounds of zero and strides of one in all
4526 dimensions, so this is very simple. The offset is only computed
4527 outside the innermost loop, so the overall transfer could be
4528 optimized further. */
4529 info = &rse.ss->info->data.array;
4531 tmp_index = gfc_index_zero_node;
4532 for (n = dimen - 1; n > 0; n--)
4534 tree tmp_str;
4535 tmp = rse.loop->loopvar[n];
4536 tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
4537 tmp, rse.loop->from[n]);
4538 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
4539 tmp, tmp_index);
4541 tmp_str = fold_build2_loc (input_location, MINUS_EXPR,
4542 gfc_array_index_type,
4543 rse.loop->to[n-1], rse.loop->from[n-1]);
4544 tmp_str = fold_build2_loc (input_location, PLUS_EXPR,
4545 gfc_array_index_type,
4546 tmp_str, gfc_index_one_node);
4548 tmp_index = fold_build2_loc (input_location, MULT_EXPR,
4549 gfc_array_index_type, tmp, tmp_str);
4552 tmp_index = fold_build2_loc (input_location, MINUS_EXPR,
4553 gfc_array_index_type,
4554 tmp_index, rse.loop->from[0]);
4555 gfc_add_modify (&rse.loop->code[0], offset, tmp_index);
4557 tmp_index = fold_build2_loc (input_location, PLUS_EXPR,
4558 gfc_array_index_type,
4559 rse.loop->loopvar[0], offset);
4561 /* Now use the offset for the reference. */
4562 tmp = build_fold_indirect_ref_loc (input_location,
4563 info->data);
4564 rse.expr = gfc_build_array_ref (tmp, tmp_index, NULL);
4566 if (expr->ts.type == BT_CHARACTER)
4567 rse.string_length = expr->ts.u.cl->backend_decl;
4569 gfc_conv_expr (&lse, expr);
4571 gcc_assert (lse.ss == gfc_ss_terminator);
4573 tmp = gfc_trans_scalar_assign (&lse, &rse, expr->ts, false, true);
4574 gfc_add_expr_to_block (&body, tmp);
4576 /* Generate the copying loops. */
4577 gfc_trans_scalarizing_loops (&loop2, &body);
4579 /* Wrap the whole thing up by adding the second loop to the post-block
4580 and following it by the post-block of the first loop. In this way,
4581 if the temporary needs freeing, it is done after use! */
4582 if (intent != INTENT_IN)
4584 gfc_add_block_to_block (&parmse->post, &loop2.pre);
4585 gfc_add_block_to_block (&parmse->post, &loop2.post);
4588 class_array_fcn:
4590 gfc_add_block_to_block (&parmse->post, &loop.post);
4592 gfc_cleanup_loop (&loop);
4593 gfc_cleanup_loop (&loop2);
4595 /* Pass the string length to the argument expression. */
4596 if (expr->ts.type == BT_CHARACTER)
4597 parmse->string_length = expr->ts.u.cl->backend_decl;
4599 /* Determine the offset for pointer formal arguments and set the
4600 lbounds to one. */
4601 if (formal_ptr)
4603 size = gfc_index_one_node;
4604 offset = gfc_index_zero_node;
4605 for (n = 0; n < dimen; n++)
4607 tmp = gfc_conv_descriptor_ubound_get (parmse->expr,
4608 gfc_rank_cst[n]);
4609 tmp = fold_build2_loc (input_location, PLUS_EXPR,
4610 gfc_array_index_type, tmp,
4611 gfc_index_one_node);
4612 gfc_conv_descriptor_ubound_set (&parmse->pre,
4613 parmse->expr,
4614 gfc_rank_cst[n],
4615 tmp);
4616 gfc_conv_descriptor_lbound_set (&parmse->pre,
4617 parmse->expr,
4618 gfc_rank_cst[n],
4619 gfc_index_one_node);
4620 size = gfc_evaluate_now (size, &parmse->pre);
4621 offset = fold_build2_loc (input_location, MINUS_EXPR,
4622 gfc_array_index_type,
4623 offset, size);
4624 offset = gfc_evaluate_now (offset, &parmse->pre);
4625 tmp = fold_build2_loc (input_location, MINUS_EXPR,
4626 gfc_array_index_type,
4627 rse.loop->to[n], rse.loop->from[n]);
4628 tmp = fold_build2_loc (input_location, PLUS_EXPR,
4629 gfc_array_index_type,
4630 tmp, gfc_index_one_node);
4631 size = fold_build2_loc (input_location, MULT_EXPR,
4632 gfc_array_index_type, size, tmp);
4635 gfc_conv_descriptor_offset_set (&parmse->pre, parmse->expr,
4636 offset);
4639 /* We want either the address for the data or the address of the descriptor,
4640 depending on the mode of passing array arguments. */
4641 if (g77)
4642 parmse->expr = gfc_conv_descriptor_data_get (parmse->expr);
4643 else
4644 parmse->expr = gfc_build_addr_expr (NULL_TREE, parmse->expr);
4646 return;
4650 /* Generate the code for argument list functions. */
4652 static void
4653 conv_arglist_function (gfc_se *se, gfc_expr *expr, const char *name)
4655 /* Pass by value for g77 %VAL(arg), pass the address
4656 indirectly for %LOC, else by reference. Thus %REF
4657 is a "do-nothing" and %LOC is the same as an F95
4658 pointer. */
4659 if (strncmp (name, "%VAL", 4) == 0)
4660 gfc_conv_expr (se, expr);
4661 else if (strncmp (name, "%LOC", 4) == 0)
4663 gfc_conv_expr_reference (se, expr);
4664 se->expr = gfc_build_addr_expr (NULL, se->expr);
4666 else if (strncmp (name, "%REF", 4) == 0)
4667 gfc_conv_expr_reference (se, expr);
4668 else
4669 gfc_error ("Unknown argument list function at %L", &expr->where);
4673 /* This function tells whether the middle-end representation of the expression
4674 E given as input may point to data otherwise accessible through a variable
4675 (sub-)reference.
4676 It is assumed that the only expressions that may alias are variables,
4677 and array constructors if ARRAY_MAY_ALIAS is true and some of its elements
4678 may alias.
4679 This function is used to decide whether freeing an expression's allocatable
4680 components is safe or should be avoided.
4682 If ARRAY_MAY_ALIAS is true, an array constructor may alias if some of
4683 its elements are copied from a variable. This ARRAY_MAY_ALIAS trick
4684 is necessary because for array constructors, aliasing depends on how
4685 the array is used:
4686 - If E is an array constructor used as argument to an elemental procedure,
4687 the array, which is generated through shallow copy by the scalarizer,
4688 is used directly and can alias the expressions it was copied from.
4689 - If E is an array constructor used as argument to a non-elemental
4690 procedure,the scalarizer is used in gfc_conv_expr_descriptor to generate
4691 the array as in the previous case, but then that array is used
4692 to initialize a new descriptor through deep copy. There is no alias
4693 possible in that case.
4694 Thus, the ARRAY_MAY_ALIAS flag is necessary to distinguish the two cases
4695 above. */
4697 static bool
4698 expr_may_alias_variables (gfc_expr *e, bool array_may_alias)
4700 gfc_constructor *c;
4702 if (e->expr_type == EXPR_VARIABLE)
4703 return true;
4704 else if (e->expr_type == EXPR_FUNCTION)
4706 gfc_symbol *proc_ifc = gfc_get_proc_ifc_for_expr (e);
4708 if (proc_ifc->result != NULL
4709 && ((proc_ifc->result->ts.type == BT_CLASS
4710 && proc_ifc->result->ts.u.derived->attr.is_class
4711 && CLASS_DATA (proc_ifc->result)->attr.class_pointer)
4712 || proc_ifc->result->attr.pointer))
4713 return true;
4714 else
4715 return false;
4717 else if (e->expr_type != EXPR_ARRAY || !array_may_alias)
4718 return false;
4720 for (c = gfc_constructor_first (e->value.constructor);
4721 c; c = gfc_constructor_next (c))
4722 if (c->expr
4723 && expr_may_alias_variables (c->expr, array_may_alias))
4724 return true;
4726 return false;
4730 /* Generate code for a procedure call. Note can return se->post != NULL.
4731 If se->direct_byref is set then se->expr contains the return parameter.
4732 Return nonzero, if the call has alternate specifiers.
4733 'expr' is only needed for procedure pointer components. */
4736 gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
4737 gfc_actual_arglist * args, gfc_expr * expr,
4738 vec<tree, va_gc> *append_args)
4740 gfc_interface_mapping mapping;
4741 vec<tree, va_gc> *arglist;
4742 vec<tree, va_gc> *retargs;
4743 tree tmp;
4744 tree fntype;
4745 gfc_se parmse;
4746 gfc_array_info *info;
4747 int byref;
4748 int parm_kind;
4749 tree type;
4750 tree var;
4751 tree len;
4752 tree base_object;
4753 vec<tree, va_gc> *stringargs;
4754 vec<tree, va_gc> *optionalargs;
4755 tree result = NULL;
4756 gfc_formal_arglist *formal;
4757 gfc_actual_arglist *arg;
4758 int has_alternate_specifier = 0;
4759 bool need_interface_mapping;
4760 bool callee_alloc;
4761 bool ulim_copy;
4762 gfc_typespec ts;
4763 gfc_charlen cl;
4764 gfc_expr *e;
4765 gfc_symbol *fsym;
4766 stmtblock_t post;
4767 enum {MISSING = 0, ELEMENTAL, SCALAR, SCALAR_POINTER, ARRAY};
4768 gfc_component *comp = NULL;
4769 int arglen;
4770 unsigned int argc;
4772 arglist = NULL;
4773 retargs = NULL;
4774 stringargs = NULL;
4775 optionalargs = NULL;
4776 var = NULL_TREE;
4777 len = NULL_TREE;
4778 gfc_clear_ts (&ts);
4780 comp = gfc_get_proc_ptr_comp (expr);
4782 bool elemental_proc = (comp
4783 && comp->ts.interface
4784 && comp->ts.interface->attr.elemental)
4785 || (comp && comp->attr.elemental)
4786 || sym->attr.elemental;
4788 if (se->ss != NULL)
4790 if (!elemental_proc)
4792 gcc_assert (se->ss->info->type == GFC_SS_FUNCTION);
4793 if (se->ss->info->useflags)
4795 gcc_assert ((!comp && gfc_return_by_reference (sym)
4796 && sym->result->attr.dimension)
4797 || (comp && comp->attr.dimension)
4798 || gfc_is_class_array_function (expr));
4799 gcc_assert (se->loop != NULL);
4800 /* Access the previously obtained result. */
4801 gfc_conv_tmp_array_ref (se);
4802 return 0;
4805 info = &se->ss->info->data.array;
4807 else
4808 info = NULL;
4810 gfc_init_block (&post);
4811 gfc_init_interface_mapping (&mapping);
4812 if (!comp)
4814 formal = gfc_sym_get_dummy_args (sym);
4815 need_interface_mapping = sym->attr.dimension ||
4816 (sym->ts.type == BT_CHARACTER
4817 && sym->ts.u.cl->length
4818 && sym->ts.u.cl->length->expr_type
4819 != EXPR_CONSTANT);
4821 else
4823 formal = comp->ts.interface ? comp->ts.interface->formal : NULL;
4824 need_interface_mapping = comp->attr.dimension ||
4825 (comp->ts.type == BT_CHARACTER
4826 && comp->ts.u.cl->length
4827 && comp->ts.u.cl->length->expr_type
4828 != EXPR_CONSTANT);
4831 base_object = NULL_TREE;
4832 /* For _vprt->_copy () routines no formal symbol is present. Nevertheless
4833 is the third and fourth argument to such a function call a value
4834 denoting the number of elements to copy (i.e., most of the time the
4835 length of a deferred length string). */
4836 ulim_copy = (formal == NULL)
4837 && UNLIMITED_POLY (sym)
4838 && comp && (strcmp ("_copy", comp->name) == 0);
4840 /* Evaluate the arguments. */
4841 for (arg = args, argc = 0; arg != NULL;
4842 arg = arg->next, formal = formal ? formal->next : NULL, ++argc)
4844 e = arg->expr;
4845 fsym = formal ? formal->sym : NULL;
4846 parm_kind = MISSING;
4848 /* If the procedure requires an explicit interface, the actual
4849 argument is passed according to the corresponding formal
4850 argument. If the corresponding formal argument is a POINTER,
4851 ALLOCATABLE or assumed shape, we do not use g77's calling
4852 convention, and pass the address of the array descriptor
4853 instead. Otherwise we use g77's calling convention, in other words
4854 pass the array data pointer without descriptor. */
4855 bool nodesc_arg = fsym != NULL
4856 && !(fsym->attr.pointer || fsym->attr.allocatable)
4857 && fsym->as
4858 && fsym->as->type != AS_ASSUMED_SHAPE
4859 && fsym->as->type != AS_ASSUMED_RANK;
4860 if (comp)
4861 nodesc_arg = nodesc_arg || !comp->attr.always_explicit;
4862 else
4863 nodesc_arg = nodesc_arg || !sym->attr.always_explicit;
4865 /* Class array expressions are sometimes coming completely unadorned
4866 with either arrayspec or _data component. Correct that here.
4867 OOP-TODO: Move this to the frontend. */
4868 if (e && e->expr_type == EXPR_VARIABLE
4869 && !e->ref
4870 && e->ts.type == BT_CLASS
4871 && (CLASS_DATA (e)->attr.codimension
4872 || CLASS_DATA (e)->attr.dimension))
4874 gfc_typespec temp_ts = e->ts;
4875 gfc_add_class_array_ref (e);
4876 e->ts = temp_ts;
4879 if (e == NULL)
4881 if (se->ignore_optional)
4883 /* Some intrinsics have already been resolved to the correct
4884 parameters. */
4885 continue;
4887 else if (arg->label)
4889 has_alternate_specifier = 1;
4890 continue;
4892 else
4894 gfc_init_se (&parmse, NULL);
4896 /* For scalar arguments with VALUE attribute which are passed by
4897 value, pass "0" and a hidden argument gives the optional
4898 status. */
4899 if (fsym && fsym->attr.optional && fsym->attr.value
4900 && !fsym->attr.dimension && fsym->ts.type != BT_CHARACTER
4901 && fsym->ts.type != BT_CLASS && fsym->ts.type != BT_DERIVED)
4903 parmse.expr = fold_convert (gfc_sym_type (fsym),
4904 integer_zero_node);
4905 vec_safe_push (optionalargs, boolean_false_node);
4907 else
4909 /* Pass a NULL pointer for an absent arg. */
4910 parmse.expr = null_pointer_node;
4911 if (arg->missing_arg_type == BT_CHARACTER)
4912 parmse.string_length = build_int_cst (gfc_charlen_type_node,
4917 else if (arg->expr->expr_type == EXPR_NULL
4918 && fsym && !fsym->attr.pointer
4919 && (fsym->ts.type != BT_CLASS
4920 || !CLASS_DATA (fsym)->attr.class_pointer))
4922 /* Pass a NULL pointer to denote an absent arg. */
4923 gcc_assert (fsym->attr.optional && !fsym->attr.allocatable
4924 && (fsym->ts.type != BT_CLASS
4925 || !CLASS_DATA (fsym)->attr.allocatable));
4926 gfc_init_se (&parmse, NULL);
4927 parmse.expr = null_pointer_node;
4928 if (arg->missing_arg_type == BT_CHARACTER)
4929 parmse.string_length = build_int_cst (gfc_charlen_type_node, 0);
4931 else if (fsym && fsym->ts.type == BT_CLASS
4932 && e->ts.type == BT_DERIVED)
4934 /* The derived type needs to be converted to a temporary
4935 CLASS object. */
4936 gfc_init_se (&parmse, se);
4937 gfc_conv_derived_to_class (&parmse, e, fsym->ts, NULL,
4938 fsym->attr.optional
4939 && e->expr_type == EXPR_VARIABLE
4940 && e->symtree->n.sym->attr.optional,
4941 CLASS_DATA (fsym)->attr.class_pointer
4942 || CLASS_DATA (fsym)->attr.allocatable);
4944 else if (UNLIMITED_POLY (fsym) && e->ts.type != BT_CLASS)
4946 /* The intrinsic type needs to be converted to a temporary
4947 CLASS object for the unlimited polymorphic formal. */
4948 gfc_init_se (&parmse, se);
4949 gfc_conv_intrinsic_to_class (&parmse, e, fsym->ts);
4951 else if (se->ss && se->ss->info->useflags)
4953 gfc_ss *ss;
4955 ss = se->ss;
4957 /* An elemental function inside a scalarized loop. */
4958 gfc_init_se (&parmse, se);
4959 parm_kind = ELEMENTAL;
4961 /* When no fsym is present, ulim_copy is set and this is a third or
4962 fourth argument, use call-by-value instead of by reference to
4963 hand the length properties to the copy routine (i.e., most of the
4964 time this will be a call to a __copy_character_* routine where the
4965 third and fourth arguments are the lengths of a deferred length
4966 char array). */
4967 if ((fsym && fsym->attr.value)
4968 || (ulim_copy && (argc == 2 || argc == 3)))
4969 gfc_conv_expr (&parmse, e);
4970 else
4971 gfc_conv_expr_reference (&parmse, e);
4973 if (e->ts.type == BT_CHARACTER && !e->rank
4974 && e->expr_type == EXPR_FUNCTION)
4975 parmse.expr = build_fold_indirect_ref_loc (input_location,
4976 parmse.expr);
4978 if (fsym && fsym->ts.type == BT_DERIVED
4979 && gfc_is_class_container_ref (e))
4981 parmse.expr = gfc_class_data_get (parmse.expr);
4983 if (fsym->attr.optional && e->expr_type == EXPR_VARIABLE
4984 && e->symtree->n.sym->attr.optional)
4986 tree cond = gfc_conv_expr_present (e->symtree->n.sym);
4987 parmse.expr = build3_loc (input_location, COND_EXPR,
4988 TREE_TYPE (parmse.expr),
4989 cond, parmse.expr,
4990 fold_convert (TREE_TYPE (parmse.expr),
4991 null_pointer_node));
4995 /* If we are passing an absent array as optional dummy to an
4996 elemental procedure, make sure that we pass NULL when the data
4997 pointer is NULL. We need this extra conditional because of
4998 scalarization which passes arrays elements to the procedure,
4999 ignoring the fact that the array can be absent/unallocated/... */
5000 if (ss->info->can_be_null_ref && ss->info->type != GFC_SS_REFERENCE)
5002 tree descriptor_data;
5004 descriptor_data = ss->info->data.array.data;
5005 tmp = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
5006 descriptor_data,
5007 fold_convert (TREE_TYPE (descriptor_data),
5008 null_pointer_node));
5009 parmse.expr
5010 = fold_build3_loc (input_location, COND_EXPR,
5011 TREE_TYPE (parmse.expr),
5012 gfc_unlikely (tmp, PRED_FORTRAN_ABSENT_DUMMY),
5013 fold_convert (TREE_TYPE (parmse.expr),
5014 null_pointer_node),
5015 parmse.expr);
5018 /* The scalarizer does not repackage the reference to a class
5019 array - instead it returns a pointer to the data element. */
5020 if (fsym && fsym->ts.type == BT_CLASS && e->ts.type == BT_CLASS)
5021 gfc_conv_class_to_class (&parmse, e, fsym->ts, true,
5022 fsym->attr.intent != INTENT_IN
5023 && (CLASS_DATA (fsym)->attr.class_pointer
5024 || CLASS_DATA (fsym)->attr.allocatable),
5025 fsym->attr.optional
5026 && e->expr_type == EXPR_VARIABLE
5027 && e->symtree->n.sym->attr.optional,
5028 CLASS_DATA (fsym)->attr.class_pointer
5029 || CLASS_DATA (fsym)->attr.allocatable);
5031 else
5033 bool scalar;
5034 gfc_ss *argss;
5036 gfc_init_se (&parmse, NULL);
5038 /* Check whether the expression is a scalar or not; we cannot use
5039 e->rank as it can be nonzero for functions arguments. */
5040 argss = gfc_walk_expr (e);
5041 scalar = argss == gfc_ss_terminator;
5042 if (!scalar)
5043 gfc_free_ss_chain (argss);
5045 /* Special handling for passing scalar polymorphic coarrays;
5046 otherwise one passes "class->_data.data" instead of "&class". */
5047 if (e->rank == 0 && e->ts.type == BT_CLASS
5048 && fsym && fsym->ts.type == BT_CLASS
5049 && CLASS_DATA (fsym)->attr.codimension
5050 && !CLASS_DATA (fsym)->attr.dimension)
5052 gfc_add_class_array_ref (e);
5053 parmse.want_coarray = 1;
5054 scalar = false;
5057 /* A scalar or transformational function. */
5058 if (scalar)
5060 if (e->expr_type == EXPR_VARIABLE
5061 && e->symtree->n.sym->attr.cray_pointee
5062 && fsym && fsym->attr.flavor == FL_PROCEDURE)
5064 /* The Cray pointer needs to be converted to a pointer to
5065 a type given by the expression. */
5066 gfc_conv_expr (&parmse, e);
5067 type = build_pointer_type (TREE_TYPE (parmse.expr));
5068 tmp = gfc_get_symbol_decl (e->symtree->n.sym->cp_pointer);
5069 parmse.expr = convert (type, tmp);
5071 else if (fsym && fsym->attr.value)
5073 if (fsym->ts.type == BT_CHARACTER
5074 && fsym->ts.is_c_interop
5075 && fsym->ns->proc_name != NULL
5076 && fsym->ns->proc_name->attr.is_bind_c)
5078 parmse.expr = NULL;
5079 gfc_conv_scalar_char_value (fsym, &parmse, &e);
5080 if (parmse.expr == NULL)
5081 gfc_conv_expr (&parmse, e);
5083 else
5085 gfc_conv_expr (&parmse, e);
5086 if (fsym->attr.optional
5087 && fsym->ts.type != BT_CLASS
5088 && fsym->ts.type != BT_DERIVED)
5090 if (e->expr_type != EXPR_VARIABLE
5091 || !e->symtree->n.sym->attr.optional
5092 || e->ref != NULL)
5093 vec_safe_push (optionalargs, boolean_true_node);
5094 else
5096 tmp = gfc_conv_expr_present (e->symtree->n.sym);
5097 if (!e->symtree->n.sym->attr.value)
5098 parmse.expr
5099 = fold_build3_loc (input_location, COND_EXPR,
5100 TREE_TYPE (parmse.expr),
5101 tmp, parmse.expr,
5102 fold_convert (TREE_TYPE (parmse.expr),
5103 integer_zero_node));
5105 vec_safe_push (optionalargs, tmp);
5110 else if (arg->name && arg->name[0] == '%')
5111 /* Argument list functions %VAL, %LOC and %REF are signalled
5112 through arg->name. */
5113 conv_arglist_function (&parmse, arg->expr, arg->name);
5114 else if ((e->expr_type == EXPR_FUNCTION)
5115 && ((e->value.function.esym
5116 && e->value.function.esym->result->attr.pointer)
5117 || (!e->value.function.esym
5118 && e->symtree->n.sym->attr.pointer))
5119 && fsym && fsym->attr.target)
5121 gfc_conv_expr (&parmse, e);
5122 parmse.expr = gfc_build_addr_expr (NULL_TREE, parmse.expr);
5124 else if (e->expr_type == EXPR_FUNCTION
5125 && e->symtree->n.sym->result
5126 && e->symtree->n.sym->result != e->symtree->n.sym
5127 && e->symtree->n.sym->result->attr.proc_pointer)
5129 /* Functions returning procedure pointers. */
5130 gfc_conv_expr (&parmse, e);
5131 if (fsym && fsym->attr.proc_pointer)
5132 parmse.expr = gfc_build_addr_expr (NULL_TREE, parmse.expr);
5134 else
5136 if (e->ts.type == BT_CLASS && fsym
5137 && fsym->ts.type == BT_CLASS
5138 && (!CLASS_DATA (fsym)->as
5139 || CLASS_DATA (fsym)->as->type != AS_ASSUMED_RANK)
5140 && CLASS_DATA (e)->attr.codimension)
5142 gcc_assert (!CLASS_DATA (fsym)->attr.codimension);
5143 gcc_assert (!CLASS_DATA (fsym)->as);
5144 gfc_add_class_array_ref (e);
5145 parmse.want_coarray = 1;
5146 gfc_conv_expr_reference (&parmse, e);
5147 class_scalar_coarray_to_class (&parmse, e, fsym->ts,
5148 fsym->attr.optional
5149 && e->expr_type == EXPR_VARIABLE);
5151 else if (e->ts.type == BT_CLASS && fsym
5152 && fsym->ts.type == BT_CLASS
5153 && !CLASS_DATA (fsym)->as
5154 && !CLASS_DATA (e)->as
5155 && strcmp (fsym->ts.u.derived->name,
5156 e->ts.u.derived->name))
5158 type = gfc_typenode_for_spec (&fsym->ts);
5159 var = gfc_create_var (type, fsym->name);
5160 gfc_conv_expr (&parmse, e);
5161 if (fsym->attr.optional
5162 && e->expr_type == EXPR_VARIABLE
5163 && e->symtree->n.sym->attr.optional)
5165 stmtblock_t block;
5166 tree cond;
5167 tmp = gfc_build_addr_expr (NULL_TREE, parmse.expr);
5168 cond = fold_build2_loc (input_location, NE_EXPR,
5169 logical_type_node, tmp,
5170 fold_convert (TREE_TYPE (tmp),
5171 null_pointer_node));
5172 gfc_start_block (&block);
5173 gfc_add_modify (&block, var,
5174 fold_build1_loc (input_location,
5175 VIEW_CONVERT_EXPR,
5176 type, parmse.expr));
5177 gfc_add_expr_to_block (&parmse.pre,
5178 fold_build3_loc (input_location,
5179 COND_EXPR, void_type_node,
5180 cond, gfc_finish_block (&block),
5181 build_empty_stmt (input_location)));
5182 parmse.expr = gfc_build_addr_expr (NULL_TREE, var);
5183 parmse.expr = build3_loc (input_location, COND_EXPR,
5184 TREE_TYPE (parmse.expr),
5185 cond, parmse.expr,
5186 fold_convert (TREE_TYPE (parmse.expr),
5187 null_pointer_node));
5189 else
5191 /* Since the internal representation of unlimited
5192 polymorphic expressions includes an extra field
5193 that other class objects do not, a cast to the
5194 formal type does not work. */
5195 if (!UNLIMITED_POLY (e) && UNLIMITED_POLY (fsym))
5197 tree efield;
5199 /* Set the _data field. */
5200 tmp = gfc_class_data_get (var);
5201 efield = fold_convert (TREE_TYPE (tmp),
5202 gfc_class_data_get (parmse.expr));
5203 gfc_add_modify (&parmse.pre, tmp, efield);
5205 /* Set the _vptr field. */
5206 tmp = gfc_class_vptr_get (var);
5207 efield = fold_convert (TREE_TYPE (tmp),
5208 gfc_class_vptr_get (parmse.expr));
5209 gfc_add_modify (&parmse.pre, tmp, efield);
5211 /* Set the _len field. */
5212 tmp = gfc_class_len_get (var);
5213 gfc_add_modify (&parmse.pre, tmp,
5214 build_int_cst (TREE_TYPE (tmp), 0));
5216 else
5218 tmp = fold_build1_loc (input_location,
5219 VIEW_CONVERT_EXPR,
5220 type, parmse.expr);
5221 gfc_add_modify (&parmse.pre, var, tmp);
5224 parmse.expr = gfc_build_addr_expr (NULL_TREE, var);
5227 else
5228 gfc_conv_expr_reference (&parmse, e);
5230 /* Catch base objects that are not variables. */
5231 if (e->ts.type == BT_CLASS
5232 && e->expr_type != EXPR_VARIABLE
5233 && expr && e == expr->base_expr)
5234 base_object = build_fold_indirect_ref_loc (input_location,
5235 parmse.expr);
5237 /* A class array element needs converting back to be a
5238 class object, if the formal argument is a class object. */
5239 if (fsym && fsym->ts.type == BT_CLASS
5240 && e->ts.type == BT_CLASS
5241 && ((CLASS_DATA (fsym)->as
5242 && CLASS_DATA (fsym)->as->type == AS_ASSUMED_RANK)
5243 || CLASS_DATA (e)->attr.dimension))
5244 gfc_conv_class_to_class (&parmse, e, fsym->ts, false,
5245 fsym->attr.intent != INTENT_IN
5246 && (CLASS_DATA (fsym)->attr.class_pointer
5247 || CLASS_DATA (fsym)->attr.allocatable),
5248 fsym->attr.optional
5249 && e->expr_type == EXPR_VARIABLE
5250 && e->symtree->n.sym->attr.optional,
5251 CLASS_DATA (fsym)->attr.class_pointer
5252 || CLASS_DATA (fsym)->attr.allocatable);
5254 /* If an ALLOCATABLE dummy argument has INTENT(OUT) and is
5255 allocated on entry, it must be deallocated. */
5256 if (fsym && fsym->attr.intent == INTENT_OUT
5257 && (fsym->attr.allocatable
5258 || (fsym->ts.type == BT_CLASS
5259 && CLASS_DATA (fsym)->attr.allocatable)))
5261 stmtblock_t block;
5262 tree ptr;
5264 gfc_init_block (&block);
5265 ptr = parmse.expr;
5266 if (e->ts.type == BT_CLASS)
5267 ptr = gfc_class_data_get (ptr);
5269 tmp = gfc_deallocate_scalar_with_status (ptr, NULL_TREE,
5270 NULL_TREE, true,
5271 e, e->ts);
5272 gfc_add_expr_to_block (&block, tmp);
5273 tmp = fold_build2_loc (input_location, MODIFY_EXPR,
5274 void_type_node, ptr,
5275 null_pointer_node);
5276 gfc_add_expr_to_block (&block, tmp);
5278 if (fsym->ts.type == BT_CLASS && UNLIMITED_POLY (fsym))
5280 gfc_add_modify (&block, ptr,
5281 fold_convert (TREE_TYPE (ptr),
5282 null_pointer_node));
5283 gfc_add_expr_to_block (&block, tmp);
5285 else if (fsym->ts.type == BT_CLASS)
5287 gfc_symbol *vtab;
5288 vtab = gfc_find_derived_vtab (fsym->ts.u.derived);
5289 tmp = gfc_get_symbol_decl (vtab);
5290 tmp = gfc_build_addr_expr (NULL_TREE, tmp);
5291 ptr = gfc_class_vptr_get (parmse.expr);
5292 gfc_add_modify (&block, ptr,
5293 fold_convert (TREE_TYPE (ptr), tmp));
5294 gfc_add_expr_to_block (&block, tmp);
5297 if (fsym->attr.optional
5298 && e->expr_type == EXPR_VARIABLE
5299 && e->symtree->n.sym->attr.optional)
5301 tmp = fold_build3_loc (input_location, COND_EXPR,
5302 void_type_node,
5303 gfc_conv_expr_present (e->symtree->n.sym),
5304 gfc_finish_block (&block),
5305 build_empty_stmt (input_location));
5307 else
5308 tmp = gfc_finish_block (&block);
5310 gfc_add_expr_to_block (&se->pre, tmp);
5313 if (fsym && (fsym->ts.type == BT_DERIVED
5314 || fsym->ts.type == BT_ASSUMED)
5315 && e->ts.type == BT_CLASS
5316 && !CLASS_DATA (e)->attr.dimension
5317 && !CLASS_DATA (e)->attr.codimension)
5318 parmse.expr = gfc_class_data_get (parmse.expr);
5320 /* Wrap scalar variable in a descriptor. We need to convert
5321 the address of a pointer back to the pointer itself before,
5322 we can assign it to the data field. */
5324 if (fsym && fsym->as && fsym->as->type == AS_ASSUMED_RANK
5325 && fsym->ts.type != BT_CLASS && e->expr_type != EXPR_NULL)
5327 tmp = parmse.expr;
5328 if (TREE_CODE (tmp) == ADDR_EXPR
5329 && (POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (tmp, 0)))
5330 || e->expr_type == EXPR_CONSTANT))
5331 tmp = TREE_OPERAND (tmp, 0);
5332 parmse.expr = gfc_conv_scalar_to_descriptor (&parmse, tmp,
5333 fsym->attr);
5334 parmse.expr = gfc_build_addr_expr (NULL_TREE,
5335 parmse.expr);
5337 else if (fsym && e->expr_type != EXPR_NULL
5338 && ((fsym->attr.pointer
5339 && fsym->attr.flavor != FL_PROCEDURE)
5340 || (fsym->attr.proc_pointer
5341 && !(e->expr_type == EXPR_VARIABLE
5342 && e->symtree->n.sym->attr.dummy))
5343 || (fsym->attr.proc_pointer
5344 && e->expr_type == EXPR_VARIABLE
5345 && gfc_is_proc_ptr_comp (e))
5346 || (fsym->attr.allocatable
5347 && fsym->attr.flavor != FL_PROCEDURE)))
5349 /* Scalar pointer dummy args require an extra level of
5350 indirection. The null pointer already contains
5351 this level of indirection. */
5352 parm_kind = SCALAR_POINTER;
5353 parmse.expr = gfc_build_addr_expr (NULL_TREE, parmse.expr);
5357 else if (e->ts.type == BT_CLASS
5358 && fsym && fsym->ts.type == BT_CLASS
5359 && (CLASS_DATA (fsym)->attr.dimension
5360 || CLASS_DATA (fsym)->attr.codimension))
5362 /* Pass a class array. */
5363 parmse.use_offset = 1;
5364 gfc_conv_expr_descriptor (&parmse, e);
5366 /* If an ALLOCATABLE dummy argument has INTENT(OUT) and is
5367 allocated on entry, it must be deallocated. */
5368 if (fsym->attr.intent == INTENT_OUT
5369 && CLASS_DATA (fsym)->attr.allocatable)
5371 stmtblock_t block;
5372 tree ptr;
5374 gfc_init_block (&block);
5375 ptr = parmse.expr;
5376 ptr = gfc_class_data_get (ptr);
5378 tmp = gfc_deallocate_with_status (ptr, NULL_TREE,
5379 NULL_TREE, NULL_TREE,
5380 NULL_TREE, true, e,
5381 GFC_CAF_COARRAY_NOCOARRAY);
5382 gfc_add_expr_to_block (&block, tmp);
5383 tmp = fold_build2_loc (input_location, MODIFY_EXPR,
5384 void_type_node, ptr,
5385 null_pointer_node);
5386 gfc_add_expr_to_block (&block, tmp);
5387 gfc_reset_vptr (&block, e);
5389 if (fsym->attr.optional
5390 && e->expr_type == EXPR_VARIABLE
5391 && (!e->ref
5392 || (e->ref->type == REF_ARRAY
5393 && e->ref->u.ar.type != AR_FULL))
5394 && e->symtree->n.sym->attr.optional)
5396 tmp = fold_build3_loc (input_location, COND_EXPR,
5397 void_type_node,
5398 gfc_conv_expr_present (e->symtree->n.sym),
5399 gfc_finish_block (&block),
5400 build_empty_stmt (input_location));
5402 else
5403 tmp = gfc_finish_block (&block);
5405 gfc_add_expr_to_block (&se->pre, tmp);
5408 /* The conversion does not repackage the reference to a class
5409 array - _data descriptor. */
5410 gfc_conv_class_to_class (&parmse, e, fsym->ts, false,
5411 fsym->attr.intent != INTENT_IN
5412 && (CLASS_DATA (fsym)->attr.class_pointer
5413 || CLASS_DATA (fsym)->attr.allocatable),
5414 fsym->attr.optional
5415 && e->expr_type == EXPR_VARIABLE
5416 && e->symtree->n.sym->attr.optional,
5417 CLASS_DATA (fsym)->attr.class_pointer
5418 || CLASS_DATA (fsym)->attr.allocatable);
5420 else
5422 /* If the argument is a function call that may not create
5423 a temporary for the result, we have to check that we
5424 can do it, i.e. that there is no alias between this
5425 argument and another one. */
5426 if (gfc_get_noncopying_intrinsic_argument (e) != NULL)
5428 gfc_expr *iarg;
5429 sym_intent intent;
5431 if (fsym != NULL)
5432 intent = fsym->attr.intent;
5433 else
5434 intent = INTENT_UNKNOWN;
5436 if (gfc_check_fncall_dependency (e, intent, sym, args,
5437 NOT_ELEMENTAL))
5438 parmse.force_tmp = 1;
5440 iarg = e->value.function.actual->expr;
5442 /* Temporary needed if aliasing due to host association. */
5443 if (sym->attr.contained
5444 && !sym->attr.pure
5445 && !sym->attr.implicit_pure
5446 && !sym->attr.use_assoc
5447 && iarg->expr_type == EXPR_VARIABLE
5448 && sym->ns == iarg->symtree->n.sym->ns)
5449 parmse.force_tmp = 1;
5451 /* Ditto within module. */
5452 if (sym->attr.use_assoc
5453 && !sym->attr.pure
5454 && !sym->attr.implicit_pure
5455 && iarg->expr_type == EXPR_VARIABLE
5456 && sym->module == iarg->symtree->n.sym->module)
5457 parmse.force_tmp = 1;
5460 if (e->expr_type == EXPR_VARIABLE
5461 && is_subref_array (e)
5462 && !(fsym && fsym->attr.pointer))
5463 /* The actual argument is a component reference to an
5464 array of derived types. In this case, the argument
5465 is converted to a temporary, which is passed and then
5466 written back after the procedure call. */
5467 gfc_conv_subref_array_arg (&parmse, e, nodesc_arg,
5468 fsym ? fsym->attr.intent : INTENT_INOUT,
5469 fsym && fsym->attr.pointer);
5470 else if (gfc_is_class_array_ref (e, NULL)
5471 && fsym && fsym->ts.type == BT_DERIVED)
5472 /* The actual argument is a component reference to an
5473 array of derived types. In this case, the argument
5474 is converted to a temporary, which is passed and then
5475 written back after the procedure call.
5476 OOP-TODO: Insert code so that if the dynamic type is
5477 the same as the declared type, copy-in/copy-out does
5478 not occur. */
5479 gfc_conv_subref_array_arg (&parmse, e, nodesc_arg,
5480 fsym ? fsym->attr.intent : INTENT_INOUT,
5481 fsym && fsym->attr.pointer);
5483 else if (gfc_is_class_array_function (e)
5484 && fsym && fsym->ts.type == BT_DERIVED)
5485 /* See previous comment. For function actual argument,
5486 the write out is not needed so the intent is set as
5487 intent in. */
5489 e->must_finalize = 1;
5490 gfc_conv_subref_array_arg (&parmse, e, nodesc_arg,
5491 INTENT_IN,
5492 fsym && fsym->attr.pointer);
5494 else
5495 gfc_conv_array_parameter (&parmse, e, nodesc_arg, fsym,
5496 sym->name, NULL);
5498 /* If an ALLOCATABLE dummy argument has INTENT(OUT) and is
5499 allocated on entry, it must be deallocated. */
5500 if (fsym && fsym->attr.allocatable
5501 && fsym->attr.intent == INTENT_OUT)
5503 if (fsym->ts.type == BT_DERIVED
5504 && fsym->ts.u.derived->attr.alloc_comp)
5506 // deallocate the components first
5507 tmp = gfc_deallocate_alloc_comp (fsym->ts.u.derived,
5508 parmse.expr, e->rank);
5509 if (tmp != NULL_TREE)
5510 gfc_add_expr_to_block (&se->pre, tmp);
5513 tmp = build_fold_indirect_ref_loc (input_location,
5514 parmse.expr);
5515 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp)))
5516 tmp = gfc_conv_descriptor_data_get (tmp);
5517 tmp = gfc_deallocate_with_status (tmp, NULL_TREE, NULL_TREE,
5518 NULL_TREE, NULL_TREE, true,
5520 GFC_CAF_COARRAY_NOCOARRAY);
5521 if (fsym->attr.optional
5522 && e->expr_type == EXPR_VARIABLE
5523 && e->symtree->n.sym->attr.optional)
5524 tmp = fold_build3_loc (input_location, COND_EXPR,
5525 void_type_node,
5526 gfc_conv_expr_present (e->symtree->n.sym),
5527 tmp, build_empty_stmt (input_location));
5528 gfc_add_expr_to_block (&se->pre, tmp);
5533 /* The case with fsym->attr.optional is that of a user subroutine
5534 with an interface indicating an optional argument. When we call
5535 an intrinsic subroutine, however, fsym is NULL, but we might still
5536 have an optional argument, so we proceed to the substitution
5537 just in case. */
5538 if (e && (fsym == NULL || fsym->attr.optional))
5540 /* If an optional argument is itself an optional dummy argument,
5541 check its presence and substitute a null if absent. This is
5542 only needed when passing an array to an elemental procedure
5543 as then array elements are accessed - or no NULL pointer is
5544 allowed and a "1" or "0" should be passed if not present.
5545 When passing a non-array-descriptor full array to a
5546 non-array-descriptor dummy, no check is needed. For
5547 array-descriptor actual to array-descriptor dummy, see
5548 PR 41911 for why a check has to be inserted.
5549 fsym == NULL is checked as intrinsics required the descriptor
5550 but do not always set fsym. */
5551 if (e->expr_type == EXPR_VARIABLE
5552 && e->symtree->n.sym->attr.optional
5553 && ((e->rank != 0 && elemental_proc)
5554 || e->representation.length || e->ts.type == BT_CHARACTER
5555 || (e->rank != 0
5556 && (fsym == NULL
5557 || (fsym-> as
5558 && (fsym->as->type == AS_ASSUMED_SHAPE
5559 || fsym->as->type == AS_ASSUMED_RANK
5560 || fsym->as->type == AS_DEFERRED))))))
5561 gfc_conv_missing_dummy (&parmse, e, fsym ? fsym->ts : e->ts,
5562 e->representation.length);
5565 if (fsym && e)
5567 /* Obtain the character length of an assumed character length
5568 length procedure from the typespec. */
5569 if (fsym->ts.type == BT_CHARACTER
5570 && parmse.string_length == NULL_TREE
5571 && e->ts.type == BT_PROCEDURE
5572 && e->symtree->n.sym->ts.type == BT_CHARACTER
5573 && e->symtree->n.sym->ts.u.cl->length != NULL
5574 && e->symtree->n.sym->ts.u.cl->length->expr_type == EXPR_CONSTANT)
5576 gfc_conv_const_charlen (e->symtree->n.sym->ts.u.cl);
5577 parmse.string_length = e->symtree->n.sym->ts.u.cl->backend_decl;
5581 if (fsym && need_interface_mapping && e)
5582 gfc_add_interface_mapping (&mapping, fsym, &parmse, e);
5584 gfc_add_block_to_block (&se->pre, &parmse.pre);
5585 gfc_add_block_to_block (&post, &parmse.post);
5587 /* Allocated allocatable components of derived types must be
5588 deallocated for non-variable scalars, array arguments to elemental
5589 procedures, and array arguments with descriptor to non-elemental
5590 procedures. As bounds information for descriptorless arrays is no
5591 longer available here, they are dealt with in trans-array.c
5592 (gfc_conv_array_parameter). */
5593 if (e && (e->ts.type == BT_DERIVED || e->ts.type == BT_CLASS)
5594 && e->ts.u.derived->attr.alloc_comp
5595 && (e->rank == 0 || elemental_proc || !nodesc_arg)
5596 && !expr_may_alias_variables (e, elemental_proc))
5598 int parm_rank;
5599 /* It is known the e returns a structure type with at least one
5600 allocatable component. When e is a function, ensure that the
5601 function is called once only by using a temporary variable. */
5602 if (!DECL_P (parmse.expr))
5603 parmse.expr = gfc_evaluate_now_loc (input_location,
5604 parmse.expr, &se->pre);
5606 if (fsym && fsym->attr.value)
5607 tmp = parmse.expr;
5608 else
5609 tmp = build_fold_indirect_ref_loc (input_location,
5610 parmse.expr);
5612 parm_rank = e->rank;
5613 switch (parm_kind)
5615 case (ELEMENTAL):
5616 case (SCALAR):
5617 parm_rank = 0;
5618 break;
5620 case (SCALAR_POINTER):
5621 tmp = build_fold_indirect_ref_loc (input_location,
5622 tmp);
5623 break;
5626 if (e->expr_type == EXPR_OP
5627 && e->value.op.op == INTRINSIC_PARENTHESES
5628 && e->value.op.op1->expr_type == EXPR_VARIABLE)
5630 tree local_tmp;
5631 local_tmp = gfc_evaluate_now (tmp, &se->pre);
5632 local_tmp = gfc_copy_alloc_comp (e->ts.u.derived, local_tmp, tmp,
5633 parm_rank, 0);
5634 gfc_add_expr_to_block (&se->post, local_tmp);
5637 if (e->ts.type == BT_DERIVED && fsym && fsym->ts.type == BT_CLASS)
5639 /* The derived type is passed to gfc_deallocate_alloc_comp.
5640 Therefore, class actuals can handled correctly but derived
5641 types passed to class formals need the _data component. */
5642 tmp = gfc_class_data_get (tmp);
5643 if (!CLASS_DATA (fsym)->attr.dimension)
5644 tmp = build_fold_indirect_ref_loc (input_location, tmp);
5647 tmp = gfc_deallocate_alloc_comp (e->ts.u.derived, tmp, parm_rank);
5649 gfc_prepend_expr_to_block (&post, tmp);
5652 /* Add argument checking of passing an unallocated/NULL actual to
5653 a nonallocatable/nonpointer dummy. */
5655 if (gfc_option.rtcheck & GFC_RTCHECK_POINTER && e != NULL)
5657 symbol_attribute attr;
5658 char *msg;
5659 tree cond;
5661 if (e->expr_type == EXPR_VARIABLE || e->expr_type == EXPR_FUNCTION)
5662 attr = gfc_expr_attr (e);
5663 else
5664 goto end_pointer_check;
5666 /* In Fortran 2008 it's allowed to pass a NULL pointer/nonallocated
5667 allocatable to an optional dummy, cf. 12.5.2.12. */
5668 if (fsym != NULL && fsym->attr.optional && !attr.proc_pointer
5669 && (gfc_option.allow_std & GFC_STD_F2008) != 0)
5670 goto end_pointer_check;
5672 if (attr.optional)
5674 /* If the actual argument is an optional pointer/allocatable and
5675 the formal argument takes an nonpointer optional value,
5676 it is invalid to pass a non-present argument on, even
5677 though there is no technical reason for this in gfortran.
5678 See Fortran 2003, Section 12.4.1.6 item (7)+(8). */
5679 tree present, null_ptr, type;
5681 if (attr.allocatable
5682 && (fsym == NULL || !fsym->attr.allocatable))
5683 msg = xasprintf ("Allocatable actual argument '%s' is not "
5684 "allocated or not present",
5685 e->symtree->n.sym->name);
5686 else if (attr.pointer
5687 && (fsym == NULL || !fsym->attr.pointer))
5688 msg = xasprintf ("Pointer actual argument '%s' is not "
5689 "associated or not present",
5690 e->symtree->n.sym->name);
5691 else if (attr.proc_pointer
5692 && (fsym == NULL || !fsym->attr.proc_pointer))
5693 msg = xasprintf ("Proc-pointer actual argument '%s' is not "
5694 "associated or not present",
5695 e->symtree->n.sym->name);
5696 else
5697 goto end_pointer_check;
5699 present = gfc_conv_expr_present (e->symtree->n.sym);
5700 type = TREE_TYPE (present);
5701 present = fold_build2_loc (input_location, EQ_EXPR,
5702 logical_type_node, present,
5703 fold_convert (type,
5704 null_pointer_node));
5705 type = TREE_TYPE (parmse.expr);
5706 null_ptr = fold_build2_loc (input_location, EQ_EXPR,
5707 logical_type_node, parmse.expr,
5708 fold_convert (type,
5709 null_pointer_node));
5710 cond = fold_build2_loc (input_location, TRUTH_ORIF_EXPR,
5711 logical_type_node, present, null_ptr);
5713 else
5715 if (attr.allocatable
5716 && (fsym == NULL || !fsym->attr.allocatable))
5717 msg = xasprintf ("Allocatable actual argument '%s' is not "
5718 "allocated", e->symtree->n.sym->name);
5719 else if (attr.pointer
5720 && (fsym == NULL || !fsym->attr.pointer))
5721 msg = xasprintf ("Pointer actual argument '%s' is not "
5722 "associated", e->symtree->n.sym->name);
5723 else if (attr.proc_pointer
5724 && (fsym == NULL || !fsym->attr.proc_pointer))
5725 msg = xasprintf ("Proc-pointer actual argument '%s' is not "
5726 "associated", e->symtree->n.sym->name);
5727 else
5728 goto end_pointer_check;
5730 tmp = parmse.expr;
5732 /* If the argument is passed by value, we need to strip the
5733 INDIRECT_REF. */
5734 if (!POINTER_TYPE_P (TREE_TYPE (parmse.expr)))
5735 tmp = gfc_build_addr_expr (NULL_TREE, tmp);
5737 cond = fold_build2_loc (input_location, EQ_EXPR,
5738 logical_type_node, tmp,
5739 fold_convert (TREE_TYPE (tmp),
5740 null_pointer_node));
5743 gfc_trans_runtime_check (true, false, cond, &se->pre, &e->where,
5744 msg);
5745 free (msg);
5747 end_pointer_check:
5749 /* Deferred length dummies pass the character length by reference
5750 so that the value can be returned. */
5751 if (parmse.string_length && fsym && fsym->ts.deferred)
5753 if (INDIRECT_REF_P (parmse.string_length))
5754 /* In chains of functions/procedure calls the string_length already
5755 is a pointer to the variable holding the length. Therefore
5756 remove the deref on call. */
5757 parmse.string_length = TREE_OPERAND (parmse.string_length, 0);
5758 else
5760 tmp = parmse.string_length;
5761 if (!VAR_P (tmp) && TREE_CODE (tmp) != COMPONENT_REF)
5762 tmp = gfc_evaluate_now (parmse.string_length, &se->pre);
5763 parmse.string_length = gfc_build_addr_expr (NULL_TREE, tmp);
5767 /* Character strings are passed as two parameters, a length and a
5768 pointer - except for Bind(c) which only passes the pointer.
5769 An unlimited polymorphic formal argument likewise does not
5770 need the length. */
5771 if (parmse.string_length != NULL_TREE
5772 && !sym->attr.is_bind_c
5773 && !(fsym && UNLIMITED_POLY (fsym)))
5774 vec_safe_push (stringargs, parmse.string_length);
5776 /* When calling __copy for character expressions to unlimited
5777 polymorphic entities, the dst argument needs a string length. */
5778 if (sym->name[0] == '_' && e && e->ts.type == BT_CHARACTER
5779 && strncmp (sym->name, "__vtab_CHARACTER", 16) == 0
5780 && arg->next && arg->next->expr
5781 && (arg->next->expr->ts.type == BT_DERIVED
5782 || arg->next->expr->ts.type == BT_CLASS)
5783 && arg->next->expr->ts.u.derived->attr.unlimited_polymorphic)
5784 vec_safe_push (stringargs, parmse.string_length);
5786 /* For descriptorless coarrays and assumed-shape coarray dummies, we
5787 pass the token and the offset as additional arguments. */
5788 if (fsym && e == NULL && flag_coarray == GFC_FCOARRAY_LIB
5789 && ((fsym->ts.type != BT_CLASS && fsym->attr.codimension
5790 && !fsym->attr.allocatable)
5791 || (fsym->ts.type == BT_CLASS
5792 && CLASS_DATA (fsym)->attr.codimension
5793 && !CLASS_DATA (fsym)->attr.allocatable)))
5795 /* Token and offset. */
5796 vec_safe_push (stringargs, null_pointer_node);
5797 vec_safe_push (stringargs, build_int_cst (gfc_array_index_type, 0));
5798 gcc_assert (fsym->attr.optional);
5800 else if (fsym && flag_coarray == GFC_FCOARRAY_LIB
5801 && ((fsym->ts.type != BT_CLASS && fsym->attr.codimension
5802 && !fsym->attr.allocatable)
5803 || (fsym->ts.type == BT_CLASS
5804 && CLASS_DATA (fsym)->attr.codimension
5805 && !CLASS_DATA (fsym)->attr.allocatable)))
5807 tree caf_decl, caf_type;
5808 tree offset, tmp2;
5810 caf_decl = gfc_get_tree_for_caf_expr (e);
5811 caf_type = TREE_TYPE (caf_decl);
5813 if (GFC_DESCRIPTOR_TYPE_P (caf_type)
5814 && (GFC_TYPE_ARRAY_AKIND (caf_type) == GFC_ARRAY_ALLOCATABLE
5815 || GFC_TYPE_ARRAY_AKIND (caf_type) == GFC_ARRAY_POINTER))
5816 tmp = gfc_conv_descriptor_token (caf_decl);
5817 else if (DECL_LANG_SPECIFIC (caf_decl)
5818 && GFC_DECL_TOKEN (caf_decl) != NULL_TREE)
5819 tmp = GFC_DECL_TOKEN (caf_decl);
5820 else
5822 gcc_assert (GFC_ARRAY_TYPE_P (caf_type)
5823 && GFC_TYPE_ARRAY_CAF_TOKEN (caf_type) != NULL_TREE);
5824 tmp = GFC_TYPE_ARRAY_CAF_TOKEN (caf_type);
5827 vec_safe_push (stringargs, tmp);
5829 if (GFC_DESCRIPTOR_TYPE_P (caf_type)
5830 && GFC_TYPE_ARRAY_AKIND (caf_type) == GFC_ARRAY_ALLOCATABLE)
5831 offset = build_int_cst (gfc_array_index_type, 0);
5832 else if (DECL_LANG_SPECIFIC (caf_decl)
5833 && GFC_DECL_CAF_OFFSET (caf_decl) != NULL_TREE)
5834 offset = GFC_DECL_CAF_OFFSET (caf_decl);
5835 else if (GFC_TYPE_ARRAY_CAF_OFFSET (caf_type) != NULL_TREE)
5836 offset = GFC_TYPE_ARRAY_CAF_OFFSET (caf_type);
5837 else
5838 offset = build_int_cst (gfc_array_index_type, 0);
5840 if (GFC_DESCRIPTOR_TYPE_P (caf_type))
5841 tmp = gfc_conv_descriptor_data_get (caf_decl);
5842 else
5844 gcc_assert (POINTER_TYPE_P (caf_type));
5845 tmp = caf_decl;
5848 tmp2 = fsym->ts.type == BT_CLASS
5849 ? gfc_class_data_get (parmse.expr) : parmse.expr;
5850 if ((fsym->ts.type != BT_CLASS
5851 && (fsym->as->type == AS_ASSUMED_SHAPE
5852 || fsym->as->type == AS_ASSUMED_RANK))
5853 || (fsym->ts.type == BT_CLASS
5854 && (CLASS_DATA (fsym)->as->type == AS_ASSUMED_SHAPE
5855 || CLASS_DATA (fsym)->as->type == AS_ASSUMED_RANK)))
5857 if (fsym->ts.type == BT_CLASS)
5858 gcc_assert (!POINTER_TYPE_P (TREE_TYPE (tmp2)));
5859 else
5861 gcc_assert (POINTER_TYPE_P (TREE_TYPE (tmp2)));
5862 tmp2 = build_fold_indirect_ref_loc (input_location, tmp2);
5864 gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp2)));
5865 tmp2 = gfc_conv_descriptor_data_get (tmp2);
5867 else if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp2)))
5868 tmp2 = gfc_conv_descriptor_data_get (tmp2);
5869 else
5871 gcc_assert (POINTER_TYPE_P (TREE_TYPE (tmp2)));
5874 tmp = fold_build2_loc (input_location, MINUS_EXPR,
5875 gfc_array_index_type,
5876 fold_convert (gfc_array_index_type, tmp2),
5877 fold_convert (gfc_array_index_type, tmp));
5878 offset = fold_build2_loc (input_location, PLUS_EXPR,
5879 gfc_array_index_type, offset, tmp);
5881 vec_safe_push (stringargs, offset);
5884 vec_safe_push (arglist, parmse.expr);
5886 gfc_finish_interface_mapping (&mapping, &se->pre, &se->post);
5888 if (comp)
5889 ts = comp->ts;
5890 else if (sym->ts.type == BT_CLASS)
5891 ts = CLASS_DATA (sym)->ts;
5892 else
5893 ts = sym->ts;
5895 if (ts.type == BT_CHARACTER && sym->attr.is_bind_c)
5896 se->string_length = build_int_cst (gfc_charlen_type_node, 1);
5897 else if (ts.type == BT_CHARACTER)
5899 if (ts.u.cl->length == NULL)
5901 /* Assumed character length results are not allowed by 5.1.1.5 of the
5902 standard and are trapped in resolve.c; except in the case of SPREAD
5903 (and other intrinsics?) and dummy functions. In the case of SPREAD,
5904 we take the character length of the first argument for the result.
5905 For dummies, we have to look through the formal argument list for
5906 this function and use the character length found there.*/
5907 if (ts.deferred)
5908 cl.backend_decl = gfc_create_var (gfc_charlen_type_node, "slen");
5909 else if (!sym->attr.dummy)
5910 cl.backend_decl = (*stringargs)[0];
5911 else
5913 formal = gfc_sym_get_dummy_args (sym->ns->proc_name);
5914 for (; formal; formal = formal->next)
5915 if (strcmp (formal->sym->name, sym->name) == 0)
5916 cl.backend_decl = formal->sym->ts.u.cl->backend_decl;
5918 len = cl.backend_decl;
5920 else
5922 tree tmp;
5924 /* Calculate the length of the returned string. */
5925 gfc_init_se (&parmse, NULL);
5926 if (need_interface_mapping)
5927 gfc_apply_interface_mapping (&mapping, &parmse, ts.u.cl->length);
5928 else
5929 gfc_conv_expr (&parmse, ts.u.cl->length);
5930 gfc_add_block_to_block (&se->pre, &parmse.pre);
5931 gfc_add_block_to_block (&se->post, &parmse.post);
5932 tmp = parmse.expr;
5933 tmp = fold_build2_loc (input_location, MAX_EXPR,
5934 TREE_TYPE (tmp), tmp,
5935 build_zero_cst (TREE_TYPE (tmp)));
5936 cl.backend_decl = tmp;
5939 /* Set up a charlen structure for it. */
5940 cl.next = NULL;
5941 cl.length = NULL;
5942 ts.u.cl = &cl;
5944 len = cl.backend_decl;
5947 byref = (comp && (comp->attr.dimension
5948 || (comp->ts.type == BT_CHARACTER && !sym->attr.is_bind_c)))
5949 || (!comp && gfc_return_by_reference (sym));
5950 if (byref)
5952 if (se->direct_byref)
5954 /* Sometimes, too much indirection can be applied; e.g. for
5955 function_result = array_valued_recursive_function. */
5956 if (TREE_TYPE (TREE_TYPE (se->expr))
5957 && TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr)))
5958 && GFC_DESCRIPTOR_TYPE_P
5959 (TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr)))))
5960 se->expr = build_fold_indirect_ref_loc (input_location,
5961 se->expr);
5963 /* If the lhs of an assignment x = f(..) is allocatable and
5964 f2003 is allowed, we must do the automatic reallocation.
5965 TODO - deal with intrinsics, without using a temporary. */
5966 if (flag_realloc_lhs
5967 && se->ss && se->ss->loop_chain
5968 && se->ss->loop_chain->is_alloc_lhs
5969 && !expr->value.function.isym
5970 && sym->result->as != NULL)
5972 /* Evaluate the bounds of the result, if known. */
5973 gfc_set_loop_bounds_from_array_spec (&mapping, se,
5974 sym->result->as);
5976 /* Perform the automatic reallocation. */
5977 tmp = gfc_alloc_allocatable_for_assignment (se->loop,
5978 expr, NULL);
5979 gfc_add_expr_to_block (&se->pre, tmp);
5981 /* Pass the temporary as the first argument. */
5982 result = info->descriptor;
5984 else
5985 result = build_fold_indirect_ref_loc (input_location,
5986 se->expr);
5987 vec_safe_push (retargs, se->expr);
5989 else if (comp && comp->attr.dimension)
5991 gcc_assert (se->loop && info);
5993 /* Set the type of the array. */
5994 tmp = gfc_typenode_for_spec (&comp->ts);
5995 gcc_assert (se->ss->dimen == se->loop->dimen);
5997 /* Evaluate the bounds of the result, if known. */
5998 gfc_set_loop_bounds_from_array_spec (&mapping, se, comp->as);
6000 /* If the lhs of an assignment x = f(..) is allocatable and
6001 f2003 is allowed, we must not generate the function call
6002 here but should just send back the results of the mapping.
6003 This is signalled by the function ss being flagged. */
6004 if (flag_realloc_lhs && se->ss && se->ss->is_alloc_lhs)
6006 gfc_free_interface_mapping (&mapping);
6007 return has_alternate_specifier;
6010 /* Create a temporary to store the result. In case the function
6011 returns a pointer, the temporary will be a shallow copy and
6012 mustn't be deallocated. */
6013 callee_alloc = comp->attr.allocatable || comp->attr.pointer;
6014 gfc_trans_create_temp_array (&se->pre, &se->post, se->ss,
6015 tmp, NULL_TREE, false,
6016 !comp->attr.pointer, callee_alloc,
6017 &se->ss->info->expr->where);
6019 /* Pass the temporary as the first argument. */
6020 result = info->descriptor;
6021 tmp = gfc_build_addr_expr (NULL_TREE, result);
6022 vec_safe_push (retargs, tmp);
6024 else if (!comp && sym->result->attr.dimension)
6026 gcc_assert (se->loop && info);
6028 /* Set the type of the array. */
6029 tmp = gfc_typenode_for_spec (&ts);
6030 gcc_assert (se->ss->dimen == se->loop->dimen);
6032 /* Evaluate the bounds of the result, if known. */
6033 gfc_set_loop_bounds_from_array_spec (&mapping, se, sym->result->as);
6035 /* If the lhs of an assignment x = f(..) is allocatable and
6036 f2003 is allowed, we must not generate the function call
6037 here but should just send back the results of the mapping.
6038 This is signalled by the function ss being flagged. */
6039 if (flag_realloc_lhs && se->ss && se->ss->is_alloc_lhs)
6041 gfc_free_interface_mapping (&mapping);
6042 return has_alternate_specifier;
6045 /* Create a temporary to store the result. In case the function
6046 returns a pointer, the temporary will be a shallow copy and
6047 mustn't be deallocated. */
6048 callee_alloc = sym->attr.allocatable || sym->attr.pointer;
6049 gfc_trans_create_temp_array (&se->pre, &se->post, se->ss,
6050 tmp, NULL_TREE, false,
6051 !sym->attr.pointer, callee_alloc,
6052 &se->ss->info->expr->where);
6054 /* Pass the temporary as the first argument. */
6055 result = info->descriptor;
6056 tmp = gfc_build_addr_expr (NULL_TREE, result);
6057 vec_safe_push (retargs, tmp);
6059 else if (ts.type == BT_CHARACTER)
6061 /* Pass the string length. */
6062 type = gfc_get_character_type (ts.kind, ts.u.cl);
6063 type = build_pointer_type (type);
6065 /* Emit a DECL_EXPR for the VLA type. */
6066 tmp = TREE_TYPE (type);
6067 if (TYPE_SIZE (tmp)
6068 && TREE_CODE (TYPE_SIZE (tmp)) != INTEGER_CST)
6070 tmp = build_decl (input_location, TYPE_DECL, NULL_TREE, tmp);
6071 DECL_ARTIFICIAL (tmp) = 1;
6072 DECL_IGNORED_P (tmp) = 1;
6073 tmp = fold_build1_loc (input_location, DECL_EXPR,
6074 TREE_TYPE (tmp), tmp);
6075 gfc_add_expr_to_block (&se->pre, tmp);
6078 /* Return an address to a char[0:len-1]* temporary for
6079 character pointers. */
6080 if ((!comp && (sym->attr.pointer || sym->attr.allocatable))
6081 || (comp && (comp->attr.pointer || comp->attr.allocatable)))
6083 var = gfc_create_var (type, "pstr");
6085 if ((!comp && sym->attr.allocatable)
6086 || (comp && comp->attr.allocatable))
6088 gfc_add_modify (&se->pre, var,
6089 fold_convert (TREE_TYPE (var),
6090 null_pointer_node));
6091 tmp = gfc_call_free (var);
6092 gfc_add_expr_to_block (&se->post, tmp);
6095 /* Provide an address expression for the function arguments. */
6096 var = gfc_build_addr_expr (NULL_TREE, var);
6098 else
6099 var = gfc_conv_string_tmp (se, type, len);
6101 vec_safe_push (retargs, var);
6103 else
6105 gcc_assert (flag_f2c && ts.type == BT_COMPLEX);
6107 type = gfc_get_complex_type (ts.kind);
6108 var = gfc_build_addr_expr (NULL_TREE, gfc_create_var (type, "cmplx"));
6109 vec_safe_push (retargs, var);
6112 /* Add the string length to the argument list. */
6113 if (ts.type == BT_CHARACTER && ts.deferred)
6115 tmp = len;
6116 if (!VAR_P (tmp))
6117 tmp = gfc_evaluate_now (len, &se->pre);
6118 TREE_STATIC (tmp) = 1;
6119 gfc_add_modify (&se->pre, tmp,
6120 build_int_cst (TREE_TYPE (tmp), 0));
6121 tmp = gfc_build_addr_expr (NULL_TREE, tmp);
6122 vec_safe_push (retargs, tmp);
6124 else if (ts.type == BT_CHARACTER)
6125 vec_safe_push (retargs, len);
6127 gfc_free_interface_mapping (&mapping);
6129 /* We need to glom RETARGS + ARGLIST + STRINGARGS + APPEND_ARGS. */
6130 arglen = (vec_safe_length (arglist) + vec_safe_length (optionalargs)
6131 + vec_safe_length (stringargs) + vec_safe_length (append_args));
6132 vec_safe_reserve (retargs, arglen);
6134 /* Add the return arguments. */
6135 vec_safe_splice (retargs, arglist);
6137 /* Add the hidden present status for optional+value to the arguments. */
6138 vec_safe_splice (retargs, optionalargs);
6140 /* Add the hidden string length parameters to the arguments. */
6141 vec_safe_splice (retargs, stringargs);
6143 /* We may want to append extra arguments here. This is used e.g. for
6144 calls to libgfortran_matmul_??, which need extra information. */
6145 vec_safe_splice (retargs, append_args);
6147 arglist = retargs;
6149 /* Generate the actual call. */
6150 if (base_object == NULL_TREE)
6151 conv_function_val (se, sym, expr);
6152 else
6153 conv_base_obj_fcn_val (se, base_object, expr);
6155 /* If there are alternate return labels, function type should be
6156 integer. Can't modify the type in place though, since it can be shared
6157 with other functions. For dummy arguments, the typing is done to
6158 this result, even if it has to be repeated for each call. */
6159 if (has_alternate_specifier
6160 && TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr))) != integer_type_node)
6162 if (!sym->attr.dummy)
6164 TREE_TYPE (sym->backend_decl)
6165 = build_function_type (integer_type_node,
6166 TYPE_ARG_TYPES (TREE_TYPE (sym->backend_decl)));
6167 se->expr = gfc_build_addr_expr (NULL_TREE, sym->backend_decl);
6169 else
6170 TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr))) = integer_type_node;
6173 fntype = TREE_TYPE (TREE_TYPE (se->expr));
6174 se->expr = build_call_vec (TREE_TYPE (fntype), se->expr, arglist);
6176 /* Allocatable scalar function results must be freed and nullified
6177 after use. This necessitates the creation of a temporary to
6178 hold the result to prevent duplicate calls. */
6179 if (!byref && sym->ts.type != BT_CHARACTER
6180 && ((sym->attr.allocatable && !sym->attr.dimension && !comp)
6181 || (comp && comp->attr.allocatable && !comp->attr.dimension)))
6183 tmp = gfc_create_var (TREE_TYPE (se->expr), NULL);
6184 gfc_add_modify (&se->pre, tmp, se->expr);
6185 se->expr = tmp;
6186 tmp = gfc_call_free (tmp);
6187 gfc_add_expr_to_block (&post, tmp);
6188 gfc_add_modify (&post, se->expr, build_int_cst (TREE_TYPE (se->expr), 0));
6191 /* If we have a pointer function, but we don't want a pointer, e.g.
6192 something like
6193 x = f()
6194 where f is pointer valued, we have to dereference the result. */
6195 if (!se->want_pointer && !byref
6196 && ((!comp && (sym->attr.pointer || sym->attr.allocatable))
6197 || (comp && (comp->attr.pointer || comp->attr.allocatable))))
6198 se->expr = build_fold_indirect_ref_loc (input_location, se->expr);
6200 /* f2c calling conventions require a scalar default real function to
6201 return a double precision result. Convert this back to default
6202 real. We only care about the cases that can happen in Fortran 77.
6204 if (flag_f2c && sym->ts.type == BT_REAL
6205 && sym->ts.kind == gfc_default_real_kind
6206 && !sym->attr.always_explicit)
6207 se->expr = fold_convert (gfc_get_real_type (sym->ts.kind), se->expr);
6209 /* A pure function may still have side-effects - it may modify its
6210 parameters. */
6211 TREE_SIDE_EFFECTS (se->expr) = 1;
6212 #if 0
6213 if (!sym->attr.pure)
6214 TREE_SIDE_EFFECTS (se->expr) = 1;
6215 #endif
6217 if (byref)
6219 /* Add the function call to the pre chain. There is no expression. */
6220 gfc_add_expr_to_block (&se->pre, se->expr);
6221 se->expr = NULL_TREE;
6223 if (!se->direct_byref)
6225 if ((sym->attr.dimension && !comp) || (comp && comp->attr.dimension))
6227 if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
6229 /* Check the data pointer hasn't been modified. This would
6230 happen in a function returning a pointer. */
6231 tmp = gfc_conv_descriptor_data_get (info->descriptor);
6232 tmp = fold_build2_loc (input_location, NE_EXPR,
6233 logical_type_node,
6234 tmp, info->data);
6235 gfc_trans_runtime_check (true, false, tmp, &se->pre, NULL,
6236 gfc_msg_fault);
6238 se->expr = info->descriptor;
6239 /* Bundle in the string length. */
6240 se->string_length = len;
6242 else if (ts.type == BT_CHARACTER)
6244 /* Dereference for character pointer results. */
6245 if ((!comp && (sym->attr.pointer || sym->attr.allocatable))
6246 || (comp && (comp->attr.pointer || comp->attr.allocatable)))
6247 se->expr = build_fold_indirect_ref_loc (input_location, var);
6248 else
6249 se->expr = var;
6251 se->string_length = len;
6253 else
6255 gcc_assert (ts.type == BT_COMPLEX && flag_f2c);
6256 se->expr = build_fold_indirect_ref_loc (input_location, var);
6261 /* Associate the rhs class object's meta-data with the result, when the
6262 result is a temporary. */
6263 if (args && args->expr && args->expr->ts.type == BT_CLASS
6264 && sym->ts.type == BT_CLASS && result != NULL_TREE && DECL_P (result)
6265 && !GFC_CLASS_TYPE_P (TREE_TYPE (result)))
6267 gfc_se parmse;
6268 gfc_expr *class_expr = gfc_find_and_cut_at_last_class_ref (args->expr);
6270 gfc_init_se (&parmse, NULL);
6271 parmse.data_not_needed = 1;
6272 gfc_conv_expr (&parmse, class_expr);
6273 if (!DECL_LANG_SPECIFIC (result))
6274 gfc_allocate_lang_decl (result);
6275 GFC_DECL_SAVED_DESCRIPTOR (result) = parmse.expr;
6276 gfc_free_expr (class_expr);
6277 gcc_assert (parmse.pre.head == NULL_TREE
6278 && parmse.post.head == NULL_TREE);
6281 /* Follow the function call with the argument post block. */
6282 if (byref)
6284 gfc_add_block_to_block (&se->pre, &post);
6286 /* Transformational functions of derived types with allocatable
6287 components must have the result allocatable components copied when the
6288 argument is actually given. */
6289 arg = expr->value.function.actual;
6290 if (result && arg && expr->rank
6291 && expr->value.function.isym
6292 && expr->value.function.isym->transformational
6293 && arg->expr
6294 && arg->expr->ts.type == BT_DERIVED
6295 && arg->expr->ts.u.derived->attr.alloc_comp)
6297 tree tmp2;
6298 /* Copy the allocatable components. We have to use a
6299 temporary here to prevent source allocatable components
6300 from being corrupted. */
6301 tmp2 = gfc_evaluate_now (result, &se->pre);
6302 tmp = gfc_copy_alloc_comp (arg->expr->ts.u.derived,
6303 result, tmp2, expr->rank, 0);
6304 gfc_add_expr_to_block (&se->pre, tmp);
6305 tmp = gfc_copy_allocatable_data (result, tmp2, TREE_TYPE(tmp2),
6306 expr->rank);
6307 gfc_add_expr_to_block (&se->pre, tmp);
6309 /* Finally free the temporary's data field. */
6310 tmp = gfc_conv_descriptor_data_get (tmp2);
6311 tmp = gfc_deallocate_with_status (tmp, NULL_TREE, NULL_TREE,
6312 NULL_TREE, NULL_TREE, true,
6313 NULL, GFC_CAF_COARRAY_NOCOARRAY);
6314 gfc_add_expr_to_block (&se->pre, tmp);
6317 else
6319 /* For a function with a class array result, save the result as
6320 a temporary, set the info fields needed by the scalarizer and
6321 call the finalization function of the temporary. Note that the
6322 nullification of allocatable components needed by the result
6323 is done in gfc_trans_assignment_1. */
6324 if (expr && ((gfc_is_class_array_function (expr)
6325 && se->ss && se->ss->loop)
6326 || gfc_is_alloc_class_scalar_function (expr))
6327 && se->expr && GFC_CLASS_TYPE_P (TREE_TYPE (se->expr))
6328 && expr->must_finalize)
6330 tree final_fndecl;
6331 tree is_final;
6332 int n;
6333 if (se->ss && se->ss->loop)
6335 gfc_add_block_to_block (&se->ss->loop->pre, &se->pre);
6336 se->expr = gfc_evaluate_now (se->expr, &se->ss->loop->pre);
6337 tmp = gfc_class_data_get (se->expr);
6338 info->descriptor = tmp;
6339 info->data = gfc_conv_descriptor_data_get (tmp);
6340 info->offset = gfc_conv_descriptor_offset_get (tmp);
6341 for (n = 0; n < se->ss->loop->dimen; n++)
6343 tree dim = gfc_rank_cst[n];
6344 se->ss->loop->to[n] = gfc_conv_descriptor_ubound_get (tmp, dim);
6345 se->ss->loop->from[n] = gfc_conv_descriptor_lbound_get (tmp, dim);
6348 else
6350 /* TODO Eliminate the doubling of temporaries. This
6351 one is necessary to ensure no memory leakage. */
6352 se->expr = gfc_evaluate_now (se->expr, &se->pre);
6353 tmp = gfc_class_data_get (se->expr);
6354 tmp = gfc_conv_scalar_to_descriptor (se, tmp,
6355 CLASS_DATA (expr->value.function.esym->result)->attr);
6358 if ((gfc_is_class_array_function (expr)
6359 || gfc_is_alloc_class_scalar_function (expr))
6360 && CLASS_DATA (expr->value.function.esym->result)->attr.pointer)
6361 goto no_finalization;
6363 final_fndecl = gfc_class_vtab_final_get (se->expr);
6364 is_final = fold_build2_loc (input_location, NE_EXPR,
6365 logical_type_node,
6366 final_fndecl,
6367 fold_convert (TREE_TYPE (final_fndecl),
6368 null_pointer_node));
6369 final_fndecl = build_fold_indirect_ref_loc (input_location,
6370 final_fndecl);
6371 tmp = build_call_expr_loc (input_location,
6372 final_fndecl, 3,
6373 gfc_build_addr_expr (NULL, tmp),
6374 gfc_class_vtab_size_get (se->expr),
6375 boolean_false_node);
6376 tmp = fold_build3_loc (input_location, COND_EXPR,
6377 void_type_node, is_final, tmp,
6378 build_empty_stmt (input_location));
6380 if (se->ss && se->ss->loop)
6382 gfc_add_expr_to_block (&se->ss->loop->post, tmp);
6383 tmp = gfc_call_free (info->data);
6384 gfc_add_expr_to_block (&se->ss->loop->post, tmp);
6386 else
6388 gfc_add_expr_to_block (&se->post, tmp);
6389 tmp = gfc_class_data_get (se->expr);
6390 tmp = gfc_call_free (tmp);
6391 gfc_add_expr_to_block (&se->post, tmp);
6394 no_finalization:
6395 expr->must_finalize = 0;
6398 gfc_add_block_to_block (&se->post, &post);
6401 return has_alternate_specifier;
6405 /* Fill a character string with spaces. */
6407 static tree
6408 fill_with_spaces (tree start, tree type, tree size)
6410 stmtblock_t block, loop;
6411 tree i, el, exit_label, cond, tmp;
6413 /* For a simple char type, we can call memset(). */
6414 /* TODO: This code does work and is potentially more efficient, but
6415 causes spurious -Wstringop-overflow warnings.
6416 if (compare_tree_int (TYPE_SIZE_UNIT (type), 1) == 0)
6417 return build_call_expr_loc (input_location,
6418 builtin_decl_explicit (BUILT_IN_MEMSET),
6419 3, start,
6420 build_int_cst (gfc_get_int_type (gfc_c_int_kind),
6421 lang_hooks.to_target_charset (' ')),
6422 fold_convert (size_type_node, size));
6425 /* Otherwise, we use a loop:
6426 for (el = start, i = size; i > 0; el--, i+= TYPE_SIZE_UNIT (type))
6427 *el = (type) ' ';
6430 /* Initialize variables. */
6431 gfc_init_block (&block);
6432 i = gfc_create_var (sizetype, "i");
6433 gfc_add_modify (&block, i, fold_convert (sizetype, size));
6434 el = gfc_create_var (build_pointer_type (type), "el");
6435 gfc_add_modify (&block, el, fold_convert (TREE_TYPE (el), start));
6436 exit_label = gfc_build_label_decl (NULL_TREE);
6437 TREE_USED (exit_label) = 1;
6440 /* Loop body. */
6441 gfc_init_block (&loop);
6443 /* Exit condition. */
6444 cond = fold_build2_loc (input_location, LE_EXPR, logical_type_node, i,
6445 build_zero_cst (sizetype));
6446 tmp = build1_v (GOTO_EXPR, exit_label);
6447 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond, tmp,
6448 build_empty_stmt (input_location));
6449 gfc_add_expr_to_block (&loop, tmp);
6451 /* Assignment. */
6452 gfc_add_modify (&loop,
6453 fold_build1_loc (input_location, INDIRECT_REF, type, el),
6454 build_int_cst (type, lang_hooks.to_target_charset (' ')));
6456 /* Increment loop variables. */
6457 gfc_add_modify (&loop, i,
6458 fold_build2_loc (input_location, MINUS_EXPR, sizetype, i,
6459 TYPE_SIZE_UNIT (type)));
6460 gfc_add_modify (&loop, el,
6461 fold_build_pointer_plus_loc (input_location,
6462 el, TYPE_SIZE_UNIT (type)));
6464 /* Making the loop... actually loop! */
6465 tmp = gfc_finish_block (&loop);
6466 tmp = build1_v (LOOP_EXPR, tmp);
6467 gfc_add_expr_to_block (&block, tmp);
6469 /* The exit label. */
6470 tmp = build1_v (LABEL_EXPR, exit_label);
6471 gfc_add_expr_to_block (&block, tmp);
6474 return gfc_finish_block (&block);
6478 /* Generate code to copy a string. */
6480 void
6481 gfc_trans_string_copy (stmtblock_t * block, tree dlength, tree dest,
6482 int dkind, tree slength, tree src, int skind)
6484 tree tmp, dlen, slen;
6485 tree dsc;
6486 tree ssc;
6487 tree cond;
6488 tree cond2;
6489 tree tmp2;
6490 tree tmp3;
6491 tree tmp4;
6492 tree chartype;
6493 stmtblock_t tempblock;
6495 gcc_assert (dkind == skind);
6497 if (slength != NULL_TREE)
6499 slen = gfc_evaluate_now (fold_convert (gfc_charlen_type_node, slength), block);
6500 ssc = gfc_string_to_single_character (slen, src, skind);
6502 else
6504 slen = build_one_cst (gfc_charlen_type_node);
6505 ssc = src;
6508 if (dlength != NULL_TREE)
6510 dlen = gfc_evaluate_now (fold_convert (gfc_charlen_type_node, dlength), block);
6511 dsc = gfc_string_to_single_character (dlen, dest, dkind);
6513 else
6515 dlen = build_one_cst (gfc_charlen_type_node);
6516 dsc = dest;
6519 /* Assign directly if the types are compatible. */
6520 if (dsc != NULL_TREE && ssc != NULL_TREE
6521 && TREE_TYPE (dsc) == TREE_TYPE (ssc))
6523 gfc_add_modify (block, dsc, ssc);
6524 return;
6527 /* The string copy algorithm below generates code like
6529 if (dlen > 0) {
6530 memmove (dest, src, min(dlen, slen));
6531 if (slen < dlen)
6532 memset(&dest[slen], ' ', dlen - slen);
6536 /* Do nothing if the destination length is zero. */
6537 cond = fold_build2_loc (input_location, GT_EXPR, logical_type_node, dlen,
6538 build_zero_cst (TREE_TYPE (dlen)));
6540 /* For non-default character kinds, we have to multiply the string
6541 length by the base type size. */
6542 chartype = gfc_get_char_type (dkind);
6543 slen = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (slen),
6544 slen,
6545 fold_convert (TREE_TYPE (slen),
6546 TYPE_SIZE_UNIT (chartype)));
6547 dlen = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (dlen),
6548 dlen,
6549 fold_convert (TREE_TYPE (dlen),
6550 TYPE_SIZE_UNIT (chartype)));
6552 if (dlength && POINTER_TYPE_P (TREE_TYPE (dest)))
6553 dest = fold_convert (pvoid_type_node, dest);
6554 else
6555 dest = gfc_build_addr_expr (pvoid_type_node, dest);
6557 if (slength && POINTER_TYPE_P (TREE_TYPE (src)))
6558 src = fold_convert (pvoid_type_node, src);
6559 else
6560 src = gfc_build_addr_expr (pvoid_type_node, src);
6562 /* First do the memmove. */
6563 tmp2 = fold_build2_loc (input_location, MIN_EXPR, TREE_TYPE (dlen), dlen,
6564 slen);
6565 tmp2 = build_call_expr_loc (input_location,
6566 builtin_decl_explicit (BUILT_IN_MEMMOVE),
6567 3, dest, src,
6568 fold_convert (size_type_node, tmp2));
6569 stmtblock_t tmpblock2;
6570 gfc_init_block (&tmpblock2);
6571 gfc_add_expr_to_block (&tmpblock2, tmp2);
6573 /* If the destination is longer, fill the end with spaces. */
6574 cond2 = fold_build2_loc (input_location, LT_EXPR, logical_type_node, slen,
6575 dlen);
6577 /* Wstringop-overflow appears at -O3 even though this warning is not
6578 explicitly available in fortran nor can it be switched off. If the
6579 source length is a constant, its negative appears as a very large
6580 postive number and triggers the warning in BUILTIN_MEMSET. Fixing
6581 the result of the MINUS_EXPR suppresses this spurious warning. */
6582 tmp = fold_build2_loc (input_location, MINUS_EXPR,
6583 TREE_TYPE(dlen), dlen, slen);
6584 if (slength && TREE_CONSTANT (slength))
6585 tmp = gfc_evaluate_now (tmp, block);
6587 tmp4 = fold_build_pointer_plus_loc (input_location, dest, slen);
6588 tmp4 = fill_with_spaces (tmp4, chartype, tmp);
6590 gfc_init_block (&tempblock);
6591 gfc_add_expr_to_block (&tempblock, tmp4);
6592 tmp3 = gfc_finish_block (&tempblock);
6594 /* The whole copy_string function is there. */
6595 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond2,
6596 tmp3, build_empty_stmt (input_location));
6597 gfc_add_expr_to_block (&tmpblock2, tmp);
6598 tmp = gfc_finish_block (&tmpblock2);
6599 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond, tmp,
6600 build_empty_stmt (input_location));
6601 gfc_add_expr_to_block (block, tmp);
6605 /* Translate a statement function.
6606 The value of a statement function reference is obtained by evaluating the
6607 expression using the values of the actual arguments for the values of the
6608 corresponding dummy arguments. */
6610 static void
6611 gfc_conv_statement_function (gfc_se * se, gfc_expr * expr)
6613 gfc_symbol *sym;
6614 gfc_symbol *fsym;
6615 gfc_formal_arglist *fargs;
6616 gfc_actual_arglist *args;
6617 gfc_se lse;
6618 gfc_se rse;
6619 gfc_saved_var *saved_vars;
6620 tree *temp_vars;
6621 tree type;
6622 tree tmp;
6623 int n;
6625 sym = expr->symtree->n.sym;
6626 args = expr->value.function.actual;
6627 gfc_init_se (&lse, NULL);
6628 gfc_init_se (&rse, NULL);
6630 n = 0;
6631 for (fargs = gfc_sym_get_dummy_args (sym); fargs; fargs = fargs->next)
6632 n++;
6633 saved_vars = XCNEWVEC (gfc_saved_var, n);
6634 temp_vars = XCNEWVEC (tree, n);
6636 for (fargs = gfc_sym_get_dummy_args (sym), n = 0; fargs;
6637 fargs = fargs->next, n++)
6639 /* Each dummy shall be specified, explicitly or implicitly, to be
6640 scalar. */
6641 gcc_assert (fargs->sym->attr.dimension == 0);
6642 fsym = fargs->sym;
6644 if (fsym->ts.type == BT_CHARACTER)
6646 /* Copy string arguments. */
6647 tree arglen;
6649 gcc_assert (fsym->ts.u.cl && fsym->ts.u.cl->length
6650 && fsym->ts.u.cl->length->expr_type == EXPR_CONSTANT);
6652 /* Create a temporary to hold the value. */
6653 if (fsym->ts.u.cl->backend_decl == NULL_TREE)
6654 fsym->ts.u.cl->backend_decl
6655 = gfc_conv_constant_to_tree (fsym->ts.u.cl->length);
6657 type = gfc_get_character_type (fsym->ts.kind, fsym->ts.u.cl);
6658 temp_vars[n] = gfc_create_var (type, fsym->name);
6660 arglen = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
6662 gfc_conv_expr (&rse, args->expr);
6663 gfc_conv_string_parameter (&rse);
6664 gfc_add_block_to_block (&se->pre, &lse.pre);
6665 gfc_add_block_to_block (&se->pre, &rse.pre);
6667 gfc_trans_string_copy (&se->pre, arglen, temp_vars[n], fsym->ts.kind,
6668 rse.string_length, rse.expr, fsym->ts.kind);
6669 gfc_add_block_to_block (&se->pre, &lse.post);
6670 gfc_add_block_to_block (&se->pre, &rse.post);
6672 else
6674 /* For everything else, just evaluate the expression. */
6676 /* Create a temporary to hold the value. */
6677 type = gfc_typenode_for_spec (&fsym->ts);
6678 temp_vars[n] = gfc_create_var (type, fsym->name);
6680 gfc_conv_expr (&lse, args->expr);
6682 gfc_add_block_to_block (&se->pre, &lse.pre);
6683 gfc_add_modify (&se->pre, temp_vars[n], lse.expr);
6684 gfc_add_block_to_block (&se->pre, &lse.post);
6687 args = args->next;
6690 /* Use the temporary variables in place of the real ones. */
6691 for (fargs = gfc_sym_get_dummy_args (sym), n = 0; fargs;
6692 fargs = fargs->next, n++)
6693 gfc_shadow_sym (fargs->sym, temp_vars[n], &saved_vars[n]);
6695 gfc_conv_expr (se, sym->value);
6697 if (sym->ts.type == BT_CHARACTER)
6699 gfc_conv_const_charlen (sym->ts.u.cl);
6701 /* Force the expression to the correct length. */
6702 if (!INTEGER_CST_P (se->string_length)
6703 || tree_int_cst_lt (se->string_length,
6704 sym->ts.u.cl->backend_decl))
6706 type = gfc_get_character_type (sym->ts.kind, sym->ts.u.cl);
6707 tmp = gfc_create_var (type, sym->name);
6708 tmp = gfc_build_addr_expr (build_pointer_type (type), tmp);
6709 gfc_trans_string_copy (&se->pre, sym->ts.u.cl->backend_decl, tmp,
6710 sym->ts.kind, se->string_length, se->expr,
6711 sym->ts.kind);
6712 se->expr = tmp;
6714 se->string_length = sym->ts.u.cl->backend_decl;
6717 /* Restore the original variables. */
6718 for (fargs = gfc_sym_get_dummy_args (sym), n = 0; fargs;
6719 fargs = fargs->next, n++)
6720 gfc_restore_sym (fargs->sym, &saved_vars[n]);
6721 free (temp_vars);
6722 free (saved_vars);
6726 /* Translate a function expression. */
6728 static void
6729 gfc_conv_function_expr (gfc_se * se, gfc_expr * expr)
6731 gfc_symbol *sym;
6733 if (expr->value.function.isym)
6735 gfc_conv_intrinsic_function (se, expr);
6736 return;
6739 /* expr.value.function.esym is the resolved (specific) function symbol for
6740 most functions. However this isn't set for dummy procedures. */
6741 sym = expr->value.function.esym;
6742 if (!sym)
6743 sym = expr->symtree->n.sym;
6745 /* The IEEE_ARITHMETIC functions are caught here. */
6746 if (sym->from_intmod == INTMOD_IEEE_ARITHMETIC)
6747 if (gfc_conv_ieee_arithmetic_function (se, expr))
6748 return;
6750 /* We distinguish statement functions from general functions to improve
6751 runtime performance. */
6752 if (sym->attr.proc == PROC_ST_FUNCTION)
6754 gfc_conv_statement_function (se, expr);
6755 return;
6758 gfc_conv_procedure_call (se, sym, expr->value.function.actual, expr,
6759 NULL);
6763 /* Determine whether the given EXPR_CONSTANT is a zero initializer. */
6765 static bool
6766 is_zero_initializer_p (gfc_expr * expr)
6768 if (expr->expr_type != EXPR_CONSTANT)
6769 return false;
6771 /* We ignore constants with prescribed memory representations for now. */
6772 if (expr->representation.string)
6773 return false;
6775 switch (expr->ts.type)
6777 case BT_INTEGER:
6778 return mpz_cmp_si (expr->value.integer, 0) == 0;
6780 case BT_REAL:
6781 return mpfr_zero_p (expr->value.real)
6782 && MPFR_SIGN (expr->value.real) >= 0;
6784 case BT_LOGICAL:
6785 return expr->value.logical == 0;
6787 case BT_COMPLEX:
6788 return mpfr_zero_p (mpc_realref (expr->value.complex))
6789 && MPFR_SIGN (mpc_realref (expr->value.complex)) >= 0
6790 && mpfr_zero_p (mpc_imagref (expr->value.complex))
6791 && MPFR_SIGN (mpc_imagref (expr->value.complex)) >= 0;
6793 default:
6794 break;
6796 return false;
6800 static void
6801 gfc_conv_array_constructor_expr (gfc_se * se, gfc_expr * expr)
6803 gfc_ss *ss;
6805 ss = se->ss;
6806 gcc_assert (ss != NULL && ss != gfc_ss_terminator);
6807 gcc_assert (ss->info->expr == expr && ss->info->type == GFC_SS_CONSTRUCTOR);
6809 gfc_conv_tmp_array_ref (se);
6813 /* Build a static initializer. EXPR is the expression for the initial value.
6814 The other parameters describe the variable of the component being
6815 initialized. EXPR may be null. */
6817 tree
6818 gfc_conv_initializer (gfc_expr * expr, gfc_typespec * ts, tree type,
6819 bool array, bool pointer, bool procptr)
6821 gfc_se se;
6823 if (flag_coarray != GFC_FCOARRAY_LIB && ts->type == BT_DERIVED
6824 && ts->u.derived->from_intmod == INTMOD_ISO_FORTRAN_ENV
6825 && ts->u.derived->intmod_sym_id == ISOFORTRAN_EVENT_TYPE)
6826 return build_constructor (type, NULL);
6828 if (!(expr || pointer || procptr))
6829 return NULL_TREE;
6831 /* Check if we have ISOCBINDING_NULL_PTR or ISOCBINDING_NULL_FUNPTR
6832 (these are the only two iso_c_binding derived types that can be
6833 used as initialization expressions). If so, we need to modify
6834 the 'expr' to be that for a (void *). */
6835 if (expr != NULL && expr->ts.type == BT_DERIVED
6836 && expr->ts.is_iso_c && expr->ts.u.derived)
6838 gfc_symbol *derived = expr->ts.u.derived;
6840 /* The derived symbol has already been converted to a (void *). Use
6841 its kind. */
6842 expr = gfc_get_int_expr (derived->ts.kind, NULL, 0);
6843 expr->ts.f90_type = derived->ts.f90_type;
6845 gfc_init_se (&se, NULL);
6846 gfc_conv_constant (&se, expr);
6847 gcc_assert (TREE_CODE (se.expr) != CONSTRUCTOR);
6848 return se.expr;
6851 if (array && !procptr)
6853 tree ctor;
6854 /* Arrays need special handling. */
6855 if (pointer)
6856 ctor = gfc_build_null_descriptor (type);
6857 /* Special case assigning an array to zero. */
6858 else if (is_zero_initializer_p (expr))
6859 ctor = build_constructor (type, NULL);
6860 else
6861 ctor = gfc_conv_array_initializer (type, expr);
6862 TREE_STATIC (ctor) = 1;
6863 return ctor;
6865 else if (pointer || procptr)
6867 if (ts->type == BT_CLASS && !procptr)
6869 gfc_init_se (&se, NULL);
6870 gfc_conv_structure (&se, gfc_class_initializer (ts, expr), 1);
6871 gcc_assert (TREE_CODE (se.expr) == CONSTRUCTOR);
6872 TREE_STATIC (se.expr) = 1;
6873 return se.expr;
6875 else if (!expr || expr->expr_type == EXPR_NULL)
6876 return fold_convert (type, null_pointer_node);
6877 else
6879 gfc_init_se (&se, NULL);
6880 se.want_pointer = 1;
6881 gfc_conv_expr (&se, expr);
6882 gcc_assert (TREE_CODE (se.expr) != CONSTRUCTOR);
6883 return se.expr;
6886 else
6888 switch (ts->type)
6890 case_bt_struct:
6891 case BT_CLASS:
6892 gfc_init_se (&se, NULL);
6893 if (ts->type == BT_CLASS && expr->expr_type == EXPR_NULL)
6894 gfc_conv_structure (&se, gfc_class_initializer (ts, expr), 1);
6895 else
6896 gfc_conv_structure (&se, expr, 1);
6897 gcc_assert (TREE_CODE (se.expr) == CONSTRUCTOR);
6898 TREE_STATIC (se.expr) = 1;
6899 return se.expr;
6901 case BT_CHARACTER:
6903 tree ctor = gfc_conv_string_init (ts->u.cl->backend_decl,expr);
6904 TREE_STATIC (ctor) = 1;
6905 return ctor;
6908 default:
6909 gfc_init_se (&se, NULL);
6910 gfc_conv_constant (&se, expr);
6911 gcc_assert (TREE_CODE (se.expr) != CONSTRUCTOR);
6912 return se.expr;
6917 static tree
6918 gfc_trans_subarray_assign (tree dest, gfc_component * cm, gfc_expr * expr)
6920 gfc_se rse;
6921 gfc_se lse;
6922 gfc_ss *rss;
6923 gfc_ss *lss;
6924 gfc_array_info *lss_array;
6925 stmtblock_t body;
6926 stmtblock_t block;
6927 gfc_loopinfo loop;
6928 int n;
6929 tree tmp;
6931 gfc_start_block (&block);
6933 /* Initialize the scalarizer. */
6934 gfc_init_loopinfo (&loop);
6936 gfc_init_se (&lse, NULL);
6937 gfc_init_se (&rse, NULL);
6939 /* Walk the rhs. */
6940 rss = gfc_walk_expr (expr);
6941 if (rss == gfc_ss_terminator)
6942 /* The rhs is scalar. Add a ss for the expression. */
6943 rss = gfc_get_scalar_ss (gfc_ss_terminator, expr);
6945 /* Create a SS for the destination. */
6946 lss = gfc_get_array_ss (gfc_ss_terminator, NULL, cm->as->rank,
6947 GFC_SS_COMPONENT);
6948 lss_array = &lss->info->data.array;
6949 lss_array->shape = gfc_get_shape (cm->as->rank);
6950 lss_array->descriptor = dest;
6951 lss_array->data = gfc_conv_array_data (dest);
6952 lss_array->offset = gfc_conv_array_offset (dest);
6953 for (n = 0; n < cm->as->rank; n++)
6955 lss_array->start[n] = gfc_conv_array_lbound (dest, n);
6956 lss_array->stride[n] = gfc_index_one_node;
6958 mpz_init (lss_array->shape[n]);
6959 mpz_sub (lss_array->shape[n], cm->as->upper[n]->value.integer,
6960 cm->as->lower[n]->value.integer);
6961 mpz_add_ui (lss_array->shape[n], lss_array->shape[n], 1);
6964 /* Associate the SS with the loop. */
6965 gfc_add_ss_to_loop (&loop, lss);
6966 gfc_add_ss_to_loop (&loop, rss);
6968 /* Calculate the bounds of the scalarization. */
6969 gfc_conv_ss_startstride (&loop);
6971 /* Setup the scalarizing loops. */
6972 gfc_conv_loop_setup (&loop, &expr->where);
6974 /* Setup the gfc_se structures. */
6975 gfc_copy_loopinfo_to_se (&lse, &loop);
6976 gfc_copy_loopinfo_to_se (&rse, &loop);
6978 rse.ss = rss;
6979 gfc_mark_ss_chain_used (rss, 1);
6980 lse.ss = lss;
6981 gfc_mark_ss_chain_used (lss, 1);
6983 /* Start the scalarized loop body. */
6984 gfc_start_scalarized_body (&loop, &body);
6986 gfc_conv_tmp_array_ref (&lse);
6987 if (cm->ts.type == BT_CHARACTER)
6988 lse.string_length = cm->ts.u.cl->backend_decl;
6990 gfc_conv_expr (&rse, expr);
6992 tmp = gfc_trans_scalar_assign (&lse, &rse, cm->ts, true, false);
6993 gfc_add_expr_to_block (&body, tmp);
6995 gcc_assert (rse.ss == gfc_ss_terminator);
6997 /* Generate the copying loops. */
6998 gfc_trans_scalarizing_loops (&loop, &body);
7000 /* Wrap the whole thing up. */
7001 gfc_add_block_to_block (&block, &loop.pre);
7002 gfc_add_block_to_block (&block, &loop.post);
7004 gcc_assert (lss_array->shape != NULL);
7005 gfc_free_shape (&lss_array->shape, cm->as->rank);
7006 gfc_cleanup_loop (&loop);
7008 return gfc_finish_block (&block);
7012 static tree
7013 gfc_trans_alloc_subarray_assign (tree dest, gfc_component * cm,
7014 gfc_expr * expr)
7016 gfc_se se;
7017 stmtblock_t block;
7018 tree offset;
7019 int n;
7020 tree tmp;
7021 tree tmp2;
7022 gfc_array_spec *as;
7023 gfc_expr *arg = NULL;
7025 gfc_start_block (&block);
7026 gfc_init_se (&se, NULL);
7028 /* Get the descriptor for the expressions. */
7029 se.want_pointer = 0;
7030 gfc_conv_expr_descriptor (&se, expr);
7031 gfc_add_block_to_block (&block, &se.pre);
7032 gfc_add_modify (&block, dest, se.expr);
7034 /* Deal with arrays of derived types with allocatable components. */
7035 if (gfc_bt_struct (cm->ts.type)
7036 && cm->ts.u.derived->attr.alloc_comp)
7037 // TODO: Fix caf_mode
7038 tmp = gfc_copy_alloc_comp (cm->ts.u.derived,
7039 se.expr, dest,
7040 cm->as->rank, 0);
7041 else if (cm->ts.type == BT_CLASS && expr->ts.type == BT_DERIVED
7042 && CLASS_DATA(cm)->attr.allocatable)
7044 if (cm->ts.u.derived->attr.alloc_comp)
7045 // TODO: Fix caf_mode
7046 tmp = gfc_copy_alloc_comp (expr->ts.u.derived,
7047 se.expr, dest,
7048 expr->rank, 0);
7049 else
7051 tmp = TREE_TYPE (dest);
7052 tmp = gfc_duplicate_allocatable (dest, se.expr,
7053 tmp, expr->rank, NULL_TREE);
7056 else
7057 tmp = gfc_duplicate_allocatable (dest, se.expr,
7058 TREE_TYPE(cm->backend_decl),
7059 cm->as->rank, NULL_TREE);
7061 gfc_add_expr_to_block (&block, tmp);
7062 gfc_add_block_to_block (&block, &se.post);
7064 if (expr->expr_type != EXPR_VARIABLE)
7065 gfc_conv_descriptor_data_set (&block, se.expr,
7066 null_pointer_node);
7068 /* We need to know if the argument of a conversion function is a
7069 variable, so that the correct lower bound can be used. */
7070 if (expr->expr_type == EXPR_FUNCTION
7071 && expr->value.function.isym
7072 && expr->value.function.isym->conversion
7073 && expr->value.function.actual->expr
7074 && expr->value.function.actual->expr->expr_type == EXPR_VARIABLE)
7075 arg = expr->value.function.actual->expr;
7077 /* Obtain the array spec of full array references. */
7078 if (arg)
7079 as = gfc_get_full_arrayspec_from_expr (arg);
7080 else
7081 as = gfc_get_full_arrayspec_from_expr (expr);
7083 /* Shift the lbound and ubound of temporaries to being unity,
7084 rather than zero, based. Always calculate the offset. */
7085 offset = gfc_conv_descriptor_offset_get (dest);
7086 gfc_add_modify (&block, offset, gfc_index_zero_node);
7087 tmp2 =gfc_create_var (gfc_array_index_type, NULL);
7089 for (n = 0; n < expr->rank; n++)
7091 tree span;
7092 tree lbound;
7094 /* Obtain the correct lbound - ISO/IEC TR 15581:2001 page 9.
7095 TODO It looks as if gfc_conv_expr_descriptor should return
7096 the correct bounds and that the following should not be
7097 necessary. This would simplify gfc_conv_intrinsic_bound
7098 as well. */
7099 if (as && as->lower[n])
7101 gfc_se lbse;
7102 gfc_init_se (&lbse, NULL);
7103 gfc_conv_expr (&lbse, as->lower[n]);
7104 gfc_add_block_to_block (&block, &lbse.pre);
7105 lbound = gfc_evaluate_now (lbse.expr, &block);
7107 else if (as && arg)
7109 tmp = gfc_get_symbol_decl (arg->symtree->n.sym);
7110 lbound = gfc_conv_descriptor_lbound_get (tmp,
7111 gfc_rank_cst[n]);
7113 else if (as)
7114 lbound = gfc_conv_descriptor_lbound_get (dest,
7115 gfc_rank_cst[n]);
7116 else
7117 lbound = gfc_index_one_node;
7119 lbound = fold_convert (gfc_array_index_type, lbound);
7121 /* Shift the bounds and set the offset accordingly. */
7122 tmp = gfc_conv_descriptor_ubound_get (dest, gfc_rank_cst[n]);
7123 span = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
7124 tmp, gfc_conv_descriptor_lbound_get (dest, gfc_rank_cst[n]));
7125 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
7126 span, lbound);
7127 gfc_conv_descriptor_ubound_set (&block, dest,
7128 gfc_rank_cst[n], tmp);
7129 gfc_conv_descriptor_lbound_set (&block, dest,
7130 gfc_rank_cst[n], lbound);
7132 tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
7133 gfc_conv_descriptor_lbound_get (dest,
7134 gfc_rank_cst[n]),
7135 gfc_conv_descriptor_stride_get (dest,
7136 gfc_rank_cst[n]));
7137 gfc_add_modify (&block, tmp2, tmp);
7138 tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
7139 offset, tmp2);
7140 gfc_conv_descriptor_offset_set (&block, dest, tmp);
7143 if (arg)
7145 /* If a conversion expression has a null data pointer
7146 argument, nullify the allocatable component. */
7147 tree non_null_expr;
7148 tree null_expr;
7150 if (arg->symtree->n.sym->attr.allocatable
7151 || arg->symtree->n.sym->attr.pointer)
7153 non_null_expr = gfc_finish_block (&block);
7154 gfc_start_block (&block);
7155 gfc_conv_descriptor_data_set (&block, dest,
7156 null_pointer_node);
7157 null_expr = gfc_finish_block (&block);
7158 tmp = gfc_conv_descriptor_data_get (arg->symtree->n.sym->backend_decl);
7159 tmp = build2_loc (input_location, EQ_EXPR, logical_type_node, tmp,
7160 fold_convert (TREE_TYPE (tmp), null_pointer_node));
7161 return build3_v (COND_EXPR, tmp,
7162 null_expr, non_null_expr);
7166 return gfc_finish_block (&block);
7170 /* Allocate or reallocate scalar component, as necessary. */
7172 static void
7173 alloc_scalar_allocatable_for_subcomponent_assignment (stmtblock_t *block,
7174 tree comp,
7175 gfc_component *cm,
7176 gfc_expr *expr2,
7177 gfc_symbol *sym)
7179 tree tmp;
7180 tree ptr;
7181 tree size;
7182 tree size_in_bytes;
7183 tree lhs_cl_size = NULL_TREE;
7185 if (!comp)
7186 return;
7188 if (!expr2 || expr2->rank)
7189 return;
7191 realloc_lhs_warning (expr2->ts.type, false, &expr2->where);
7193 if (cm->ts.type == BT_CHARACTER && cm->ts.deferred)
7195 char name[GFC_MAX_SYMBOL_LEN+9];
7196 gfc_component *strlen;
7197 /* Use the rhs string length and the lhs element size. */
7198 gcc_assert (expr2->ts.type == BT_CHARACTER);
7199 if (!expr2->ts.u.cl->backend_decl)
7201 gfc_conv_string_length (expr2->ts.u.cl, expr2, block);
7202 gcc_assert (expr2->ts.u.cl->backend_decl);
7205 size = expr2->ts.u.cl->backend_decl;
7207 /* Ensure that cm->ts.u.cl->backend_decl is a componentref to _%s_length
7208 component. */
7209 sprintf (name, "_%s_length", cm->name);
7210 strlen = gfc_find_component (sym, name, true, true, NULL);
7211 lhs_cl_size = fold_build3_loc (input_location, COMPONENT_REF,
7212 gfc_charlen_type_node,
7213 TREE_OPERAND (comp, 0),
7214 strlen->backend_decl, NULL_TREE);
7216 tmp = TREE_TYPE (gfc_typenode_for_spec (&cm->ts));
7217 tmp = TYPE_SIZE_UNIT (tmp);
7218 size_in_bytes = fold_build2_loc (input_location, MULT_EXPR,
7219 TREE_TYPE (tmp), tmp,
7220 fold_convert (TREE_TYPE (tmp), size));
7222 else if (cm->ts.type == BT_CLASS)
7224 gcc_assert (expr2->ts.type == BT_CLASS || expr2->ts.type == BT_DERIVED);
7225 if (expr2->ts.type == BT_DERIVED)
7227 tmp = gfc_get_symbol_decl (expr2->ts.u.derived);
7228 size = TYPE_SIZE_UNIT (tmp);
7230 else
7232 gfc_expr *e2vtab;
7233 gfc_se se;
7234 e2vtab = gfc_find_and_cut_at_last_class_ref (expr2);
7235 gfc_add_vptr_component (e2vtab);
7236 gfc_add_size_component (e2vtab);
7237 gfc_init_se (&se, NULL);
7238 gfc_conv_expr (&se, e2vtab);
7239 gfc_add_block_to_block (block, &se.pre);
7240 size = fold_convert (size_type_node, se.expr);
7241 gfc_free_expr (e2vtab);
7243 size_in_bytes = size;
7245 else
7247 /* Otherwise use the length in bytes of the rhs. */
7248 size = TYPE_SIZE_UNIT (gfc_typenode_for_spec (&cm->ts));
7249 size_in_bytes = size;
7252 size_in_bytes = fold_build2_loc (input_location, MAX_EXPR, size_type_node,
7253 size_in_bytes, size_one_node);
7255 if (cm->ts.type == BT_DERIVED && cm->ts.u.derived->attr.alloc_comp)
7257 tmp = build_call_expr_loc (input_location,
7258 builtin_decl_explicit (BUILT_IN_CALLOC),
7259 2, build_one_cst (size_type_node),
7260 size_in_bytes);
7261 tmp = fold_convert (TREE_TYPE (comp), tmp);
7262 gfc_add_modify (block, comp, tmp);
7264 else
7266 tmp = build_call_expr_loc (input_location,
7267 builtin_decl_explicit (BUILT_IN_MALLOC),
7268 1, size_in_bytes);
7269 if (GFC_CLASS_TYPE_P (TREE_TYPE (comp)))
7270 ptr = gfc_class_data_get (comp);
7271 else
7272 ptr = comp;
7273 tmp = fold_convert (TREE_TYPE (ptr), tmp);
7274 gfc_add_modify (block, ptr, tmp);
7277 if (cm->ts.type == BT_CHARACTER && cm->ts.deferred)
7278 /* Update the lhs character length. */
7279 gfc_add_modify (block, lhs_cl_size,
7280 fold_convert (TREE_TYPE (lhs_cl_size), size));
7284 /* Assign a single component of a derived type constructor. */
7286 static tree
7287 gfc_trans_subcomponent_assign (tree dest, gfc_component * cm, gfc_expr * expr,
7288 gfc_symbol *sym, bool init)
7290 gfc_se se;
7291 gfc_se lse;
7292 stmtblock_t block;
7293 tree tmp;
7294 tree vtab;
7296 gfc_start_block (&block);
7298 if (cm->attr.pointer || cm->attr.proc_pointer)
7300 /* Only care about pointers here, not about allocatables. */
7301 gfc_init_se (&se, NULL);
7302 /* Pointer component. */
7303 if ((cm->attr.dimension || cm->attr.codimension)
7304 && !cm->attr.proc_pointer)
7306 /* Array pointer. */
7307 if (expr->expr_type == EXPR_NULL)
7308 gfc_conv_descriptor_data_set (&block, dest, null_pointer_node);
7309 else
7311 se.direct_byref = 1;
7312 se.expr = dest;
7313 gfc_conv_expr_descriptor (&se, expr);
7314 gfc_add_block_to_block (&block, &se.pre);
7315 gfc_add_block_to_block (&block, &se.post);
7318 else
7320 /* Scalar pointers. */
7321 se.want_pointer = 1;
7322 gfc_conv_expr (&se, expr);
7323 gfc_add_block_to_block (&block, &se.pre);
7325 if (expr->symtree && expr->symtree->n.sym->attr.proc_pointer
7326 && expr->symtree->n.sym->attr.dummy)
7327 se.expr = build_fold_indirect_ref_loc (input_location, se.expr);
7329 gfc_add_modify (&block, dest,
7330 fold_convert (TREE_TYPE (dest), se.expr));
7331 gfc_add_block_to_block (&block, &se.post);
7334 else if (cm->ts.type == BT_CLASS && expr->expr_type == EXPR_NULL)
7336 /* NULL initialization for CLASS components. */
7337 tmp = gfc_trans_structure_assign (dest,
7338 gfc_class_initializer (&cm->ts, expr),
7339 false);
7340 gfc_add_expr_to_block (&block, tmp);
7342 else if ((cm->attr.dimension || cm->attr.codimension)
7343 && !cm->attr.proc_pointer)
7345 if (cm->attr.allocatable && expr->expr_type == EXPR_NULL)
7346 gfc_conv_descriptor_data_set (&block, dest, null_pointer_node);
7347 else if (cm->attr.allocatable || cm->attr.pdt_array)
7349 tmp = gfc_trans_alloc_subarray_assign (dest, cm, expr);
7350 gfc_add_expr_to_block (&block, tmp);
7352 else
7354 tmp = gfc_trans_subarray_assign (dest, cm, expr);
7355 gfc_add_expr_to_block (&block, tmp);
7358 else if (cm->ts.type == BT_CLASS
7359 && CLASS_DATA (cm)->attr.dimension
7360 && CLASS_DATA (cm)->attr.allocatable
7361 && expr->ts.type == BT_DERIVED)
7363 vtab = gfc_get_symbol_decl (gfc_find_vtab (&expr->ts));
7364 vtab = gfc_build_addr_expr (NULL_TREE, vtab);
7365 tmp = gfc_class_vptr_get (dest);
7366 gfc_add_modify (&block, tmp,
7367 fold_convert (TREE_TYPE (tmp), vtab));
7368 tmp = gfc_class_data_get (dest);
7369 tmp = gfc_trans_alloc_subarray_assign (tmp, cm, expr);
7370 gfc_add_expr_to_block (&block, tmp);
7372 else if (init && cm->attr.allocatable && expr->expr_type == EXPR_NULL)
7374 /* NULL initialization for allocatable components. */
7375 gfc_add_modify (&block, dest, fold_convert (TREE_TYPE (dest),
7376 null_pointer_node));
7378 else if (init && (cm->attr.allocatable
7379 || (cm->ts.type == BT_CLASS && CLASS_DATA (cm)->attr.allocatable
7380 && expr->ts.type != BT_CLASS)))
7382 /* Take care about non-array allocatable components here. The alloc_*
7383 routine below is motivated by the alloc_scalar_allocatable_for_
7384 assignment() routine, but with the realloc portions removed and
7385 different input. */
7386 alloc_scalar_allocatable_for_subcomponent_assignment (&block,
7387 dest,
7389 expr,
7390 sym);
7391 /* The remainder of these instructions follow the if (cm->attr.pointer)
7392 if (!cm->attr.dimension) part above. */
7393 gfc_init_se (&se, NULL);
7394 gfc_conv_expr (&se, expr);
7395 gfc_add_block_to_block (&block, &se.pre);
7397 if (expr->symtree && expr->symtree->n.sym->attr.proc_pointer
7398 && expr->symtree->n.sym->attr.dummy)
7399 se.expr = build_fold_indirect_ref_loc (input_location, se.expr);
7401 if (cm->ts.type == BT_CLASS && expr->ts.type == BT_DERIVED)
7403 tmp = gfc_class_data_get (dest);
7404 tmp = build_fold_indirect_ref_loc (input_location, tmp);
7405 vtab = gfc_get_symbol_decl (gfc_find_vtab (&expr->ts));
7406 vtab = gfc_build_addr_expr (NULL_TREE, vtab);
7407 gfc_add_modify (&block, gfc_class_vptr_get (dest),
7408 fold_convert (TREE_TYPE (gfc_class_vptr_get (dest)), vtab));
7410 else
7411 tmp = build_fold_indirect_ref_loc (input_location, dest);
7413 /* For deferred strings insert a memcpy. */
7414 if (cm->ts.type == BT_CHARACTER && cm->ts.deferred)
7416 tree size;
7417 gcc_assert (se.string_length || expr->ts.u.cl->backend_decl);
7418 size = size_of_string_in_bytes (cm->ts.kind, se.string_length
7419 ? se.string_length
7420 : expr->ts.u.cl->backend_decl);
7421 tmp = gfc_build_memcpy_call (tmp, se.expr, size);
7422 gfc_add_expr_to_block (&block, tmp);
7424 else
7425 gfc_add_modify (&block, tmp,
7426 fold_convert (TREE_TYPE (tmp), se.expr));
7427 gfc_add_block_to_block (&block, &se.post);
7429 else if (expr->ts.type == BT_UNION)
7431 tree tmp;
7432 gfc_constructor *c = gfc_constructor_first (expr->value.constructor);
7433 /* We mark that the entire union should be initialized with a contrived
7434 EXPR_NULL expression at the beginning. */
7435 if (c != NULL && c->n.component == NULL
7436 && c->expr != NULL && c->expr->expr_type == EXPR_NULL)
7438 tmp = build2_loc (input_location, MODIFY_EXPR, void_type_node,
7439 dest, build_constructor (TREE_TYPE (dest), NULL));
7440 gfc_add_expr_to_block (&block, tmp);
7441 c = gfc_constructor_next (c);
7443 /* The following constructor expression, if any, represents a specific
7444 map intializer, as given by the user. */
7445 if (c != NULL && c->expr != NULL)
7447 gcc_assert (expr->expr_type == EXPR_STRUCTURE);
7448 tmp = gfc_trans_structure_assign (dest, expr, expr->symtree != NULL);
7449 gfc_add_expr_to_block (&block, tmp);
7452 else if (expr->ts.type == BT_DERIVED && expr->ts.f90_type != BT_VOID)
7454 if (expr->expr_type != EXPR_STRUCTURE)
7456 tree dealloc = NULL_TREE;
7457 gfc_init_se (&se, NULL);
7458 gfc_conv_expr (&se, expr);
7459 gfc_add_block_to_block (&block, &se.pre);
7460 /* Prevent repeat evaluations in gfc_copy_alloc_comp by fixing the
7461 expression in a temporary variable and deallocate the allocatable
7462 components. Then we can the copy the expression to the result. */
7463 if (cm->ts.u.derived->attr.alloc_comp
7464 && expr->expr_type != EXPR_VARIABLE)
7466 se.expr = gfc_evaluate_now (se.expr, &block);
7467 dealloc = gfc_deallocate_alloc_comp (cm->ts.u.derived, se.expr,
7468 expr->rank);
7470 gfc_add_modify (&block, dest,
7471 fold_convert (TREE_TYPE (dest), se.expr));
7472 if (cm->ts.u.derived->attr.alloc_comp
7473 && expr->expr_type != EXPR_NULL)
7475 // TODO: Fix caf_mode
7476 tmp = gfc_copy_alloc_comp (cm->ts.u.derived, se.expr,
7477 dest, expr->rank, 0);
7478 gfc_add_expr_to_block (&block, tmp);
7479 if (dealloc != NULL_TREE)
7480 gfc_add_expr_to_block (&block, dealloc);
7482 gfc_add_block_to_block (&block, &se.post);
7484 else
7486 /* Nested constructors. */
7487 tmp = gfc_trans_structure_assign (dest, expr, expr->symtree != NULL);
7488 gfc_add_expr_to_block (&block, tmp);
7491 else if (gfc_deferred_strlen (cm, &tmp))
7493 tree strlen;
7494 strlen = tmp;
7495 gcc_assert (strlen);
7496 strlen = fold_build3_loc (input_location, COMPONENT_REF,
7497 TREE_TYPE (strlen),
7498 TREE_OPERAND (dest, 0),
7499 strlen, NULL_TREE);
7501 if (expr->expr_type == EXPR_NULL)
7503 tmp = build_int_cst (TREE_TYPE (cm->backend_decl), 0);
7504 gfc_add_modify (&block, dest, tmp);
7505 tmp = build_int_cst (TREE_TYPE (strlen), 0);
7506 gfc_add_modify (&block, strlen, tmp);
7508 else
7510 tree size;
7511 gfc_init_se (&se, NULL);
7512 gfc_conv_expr (&se, expr);
7513 size = size_of_string_in_bytes (cm->ts.kind, se.string_length);
7514 tmp = build_call_expr_loc (input_location,
7515 builtin_decl_explicit (BUILT_IN_MALLOC),
7516 1, size);
7517 gfc_add_modify (&block, dest,
7518 fold_convert (TREE_TYPE (dest), tmp));
7519 gfc_add_modify (&block, strlen,
7520 fold_convert (TREE_TYPE (strlen), se.string_length));
7521 tmp = gfc_build_memcpy_call (dest, se.expr, size);
7522 gfc_add_expr_to_block (&block, tmp);
7525 else if (!cm->attr.artificial)
7527 /* Scalar component (excluding deferred parameters). */
7528 gfc_init_se (&se, NULL);
7529 gfc_init_se (&lse, NULL);
7531 gfc_conv_expr (&se, expr);
7532 if (cm->ts.type == BT_CHARACTER)
7533 lse.string_length = cm->ts.u.cl->backend_decl;
7534 lse.expr = dest;
7535 tmp = gfc_trans_scalar_assign (&lse, &se, cm->ts, false, false);
7536 gfc_add_expr_to_block (&block, tmp);
7538 return gfc_finish_block (&block);
7541 /* Assign a derived type constructor to a variable. */
7543 tree
7544 gfc_trans_structure_assign (tree dest, gfc_expr * expr, bool init, bool coarray)
7546 gfc_constructor *c;
7547 gfc_component *cm;
7548 stmtblock_t block;
7549 tree field;
7550 tree tmp;
7551 gfc_se se;
7553 gfc_start_block (&block);
7554 cm = expr->ts.u.derived->components;
7556 if (expr->ts.u.derived->from_intmod == INTMOD_ISO_C_BINDING
7557 && (expr->ts.u.derived->intmod_sym_id == ISOCBINDING_PTR
7558 || expr->ts.u.derived->intmod_sym_id == ISOCBINDING_FUNPTR))
7560 gfc_se lse;
7562 gfc_init_se (&se, NULL);
7563 gfc_init_se (&lse, NULL);
7564 gfc_conv_expr (&se, gfc_constructor_first (expr->value.constructor)->expr);
7565 lse.expr = dest;
7566 gfc_add_modify (&block, lse.expr,
7567 fold_convert (TREE_TYPE (lse.expr), se.expr));
7569 return gfc_finish_block (&block);
7572 if (coarray)
7573 gfc_init_se (&se, NULL);
7575 for (c = gfc_constructor_first (expr->value.constructor);
7576 c; c = gfc_constructor_next (c), cm = cm->next)
7578 /* Skip absent members in default initializers. */
7579 if (!c->expr && !cm->attr.allocatable)
7580 continue;
7582 /* Register the component with the caf-lib before it is initialized.
7583 Register only allocatable components, that are not coarray'ed
7584 components (%comp[*]). Only register when the constructor is not the
7585 null-expression. */
7586 if (coarray && !cm->attr.codimension
7587 && (cm->attr.allocatable || cm->attr.pointer)
7588 && (!c->expr || c->expr->expr_type == EXPR_NULL))
7590 tree token, desc, size;
7591 bool is_array = cm->ts.type == BT_CLASS
7592 ? CLASS_DATA (cm)->attr.dimension : cm->attr.dimension;
7594 field = cm->backend_decl;
7595 field = fold_build3_loc (input_location, COMPONENT_REF,
7596 TREE_TYPE (field), dest, field, NULL_TREE);
7597 if (cm->ts.type == BT_CLASS)
7598 field = gfc_class_data_get (field);
7600 token = is_array ? gfc_conv_descriptor_token (field)
7601 : fold_build3_loc (input_location, COMPONENT_REF,
7602 TREE_TYPE (cm->caf_token), dest,
7603 cm->caf_token, NULL_TREE);
7605 if (is_array)
7607 /* The _caf_register routine looks at the rank of the array
7608 descriptor to decide whether the data registered is an array
7609 or not. */
7610 int rank = cm->ts.type == BT_CLASS ? CLASS_DATA (cm)->as->rank
7611 : cm->as->rank;
7612 /* When the rank is not known just set a positive rank, which
7613 suffices to recognize the data as array. */
7614 if (rank < 0)
7615 rank = 1;
7616 size = integer_zero_node;
7617 desc = field;
7618 gfc_add_modify (&block, gfc_conv_descriptor_rank (desc),
7619 build_int_cst (signed_char_type_node, rank));
7621 else
7623 desc = gfc_conv_scalar_to_descriptor (&se, field,
7624 cm->ts.type == BT_CLASS
7625 ? CLASS_DATA (cm)->attr
7626 : cm->attr);
7627 size = TYPE_SIZE_UNIT (TREE_TYPE (field));
7629 gfc_add_block_to_block (&block, &se.pre);
7630 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_register,
7631 7, size, build_int_cst (
7632 integer_type_node,
7633 GFC_CAF_COARRAY_ALLOC_REGISTER_ONLY),
7634 gfc_build_addr_expr (pvoid_type_node,
7635 token),
7636 gfc_build_addr_expr (NULL_TREE, desc),
7637 null_pointer_node, null_pointer_node,
7638 integer_zero_node);
7639 gfc_add_expr_to_block (&block, tmp);
7641 field = cm->backend_decl;
7642 tmp = fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field),
7643 dest, field, NULL_TREE);
7644 if (!c->expr)
7646 gfc_expr *e = gfc_get_null_expr (NULL);
7647 tmp = gfc_trans_subcomponent_assign (tmp, cm, e, expr->ts.u.derived,
7648 init);
7649 gfc_free_expr (e);
7651 else
7652 tmp = gfc_trans_subcomponent_assign (tmp, cm, c->expr,
7653 expr->ts.u.derived, init);
7654 gfc_add_expr_to_block (&block, tmp);
7656 return gfc_finish_block (&block);
7659 void
7660 gfc_conv_union_initializer (vec<constructor_elt, va_gc> *v,
7661 gfc_component *un, gfc_expr *init)
7663 gfc_constructor *ctor;
7665 if (un->ts.type != BT_UNION || un == NULL || init == NULL)
7666 return;
7668 ctor = gfc_constructor_first (init->value.constructor);
7670 if (ctor == NULL || ctor->expr == NULL)
7671 return;
7673 gcc_assert (init->expr_type == EXPR_STRUCTURE);
7675 /* If we have an 'initialize all' constructor, do it first. */
7676 if (ctor->expr->expr_type == EXPR_NULL)
7678 tree union_type = TREE_TYPE (un->backend_decl);
7679 tree val = build_constructor (union_type, NULL);
7680 CONSTRUCTOR_APPEND_ELT (v, un->backend_decl, val);
7681 ctor = gfc_constructor_next (ctor);
7684 /* Add the map initializer on top. */
7685 if (ctor != NULL && ctor->expr != NULL)
7687 gcc_assert (ctor->expr->expr_type == EXPR_STRUCTURE);
7688 tree val = gfc_conv_initializer (ctor->expr, &un->ts,
7689 TREE_TYPE (un->backend_decl),
7690 un->attr.dimension, un->attr.pointer,
7691 un->attr.proc_pointer);
7692 CONSTRUCTOR_APPEND_ELT (v, un->backend_decl, val);
7696 /* Build an expression for a constructor. If init is nonzero then
7697 this is part of a static variable initializer. */
7699 void
7700 gfc_conv_structure (gfc_se * se, gfc_expr * expr, int init)
7702 gfc_constructor *c;
7703 gfc_component *cm;
7704 tree val;
7705 tree type;
7706 tree tmp;
7707 vec<constructor_elt, va_gc> *v = NULL;
7709 gcc_assert (se->ss == NULL);
7710 gcc_assert (expr->expr_type == EXPR_STRUCTURE);
7711 type = gfc_typenode_for_spec (&expr->ts);
7713 if (!init)
7715 /* Create a temporary variable and fill it in. */
7716 se->expr = gfc_create_var (type, expr->ts.u.derived->name);
7717 /* The symtree in expr is NULL, if the code to generate is for
7718 initializing the static members only. */
7719 tmp = gfc_trans_structure_assign (se->expr, expr, expr->symtree != NULL,
7720 se->want_coarray);
7721 gfc_add_expr_to_block (&se->pre, tmp);
7722 return;
7725 cm = expr->ts.u.derived->components;
7727 for (c = gfc_constructor_first (expr->value.constructor);
7728 c; c = gfc_constructor_next (c), cm = cm->next)
7730 /* Skip absent members in default initializers and allocatable
7731 components. Although the latter have a default initializer
7732 of EXPR_NULL,... by default, the static nullify is not needed
7733 since this is done every time we come into scope. */
7734 if (!c->expr || (cm->attr.allocatable && cm->attr.flavor != FL_PROCEDURE))
7735 continue;
7737 if (cm->initializer && cm->initializer->expr_type != EXPR_NULL
7738 && strcmp (cm->name, "_extends") == 0
7739 && cm->initializer->symtree)
7741 tree vtab;
7742 gfc_symbol *vtabs;
7743 vtabs = cm->initializer->symtree->n.sym;
7744 vtab = gfc_build_addr_expr (NULL_TREE, gfc_get_symbol_decl (vtabs));
7745 vtab = unshare_expr_without_location (vtab);
7746 CONSTRUCTOR_APPEND_ELT (v, cm->backend_decl, vtab);
7748 else if (cm->ts.u.derived && strcmp (cm->name, "_size") == 0)
7750 val = TYPE_SIZE_UNIT (gfc_get_derived_type (cm->ts.u.derived));
7751 CONSTRUCTOR_APPEND_ELT (v, cm->backend_decl,
7752 fold_convert (TREE_TYPE (cm->backend_decl),
7753 val));
7755 else if (cm->ts.type == BT_INTEGER && strcmp (cm->name, "_len") == 0)
7756 CONSTRUCTOR_APPEND_ELT (v, cm->backend_decl,
7757 fold_convert (TREE_TYPE (cm->backend_decl),
7758 integer_zero_node));
7759 else if (cm->ts.type == BT_UNION)
7760 gfc_conv_union_initializer (v, cm, c->expr);
7761 else
7763 val = gfc_conv_initializer (c->expr, &cm->ts,
7764 TREE_TYPE (cm->backend_decl),
7765 cm->attr.dimension, cm->attr.pointer,
7766 cm->attr.proc_pointer);
7767 val = unshare_expr_without_location (val);
7769 /* Append it to the constructor list. */
7770 CONSTRUCTOR_APPEND_ELT (v, cm->backend_decl, val);
7774 se->expr = build_constructor (type, v);
7775 if (init)
7776 TREE_CONSTANT (se->expr) = 1;
7780 /* Translate a substring expression. */
7782 static void
7783 gfc_conv_substring_expr (gfc_se * se, gfc_expr * expr)
7785 gfc_ref *ref;
7787 ref = expr->ref;
7789 gcc_assert (ref == NULL || ref->type == REF_SUBSTRING);
7791 se->expr = gfc_build_wide_string_const (expr->ts.kind,
7792 expr->value.character.length,
7793 expr->value.character.string);
7795 se->string_length = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (se->expr)));
7796 TYPE_STRING_FLAG (TREE_TYPE (se->expr)) = 1;
7798 if (ref)
7799 gfc_conv_substring (se, ref, expr->ts.kind, NULL, &expr->where);
7803 /* Entry point for expression translation. Evaluates a scalar quantity.
7804 EXPR is the expression to be translated, and SE is the state structure if
7805 called from within the scalarized. */
7807 void
7808 gfc_conv_expr (gfc_se * se, gfc_expr * expr)
7810 gfc_ss *ss;
7812 ss = se->ss;
7813 if (ss && ss->info->expr == expr
7814 && (ss->info->type == GFC_SS_SCALAR
7815 || ss->info->type == GFC_SS_REFERENCE))
7817 gfc_ss_info *ss_info;
7819 ss_info = ss->info;
7820 /* Substitute a scalar expression evaluated outside the scalarization
7821 loop. */
7822 se->expr = ss_info->data.scalar.value;
7823 if (gfc_scalar_elemental_arg_saved_as_reference (ss_info))
7824 se->expr = build_fold_indirect_ref_loc (input_location, se->expr);
7826 se->string_length = ss_info->string_length;
7827 gfc_advance_se_ss_chain (se);
7828 return;
7831 /* We need to convert the expressions for the iso_c_binding derived types.
7832 C_NULL_PTR and C_NULL_FUNPTR will be made EXPR_NULL, which evaluates to
7833 null_pointer_node. C_PTR and C_FUNPTR are converted to match the
7834 typespec for the C_PTR and C_FUNPTR symbols, which has already been
7835 updated to be an integer with a kind equal to the size of a (void *). */
7836 if (expr->ts.type == BT_DERIVED && expr->ts.u.derived->ts.f90_type == BT_VOID
7837 && expr->ts.u.derived->attr.is_bind_c)
7839 if (expr->expr_type == EXPR_VARIABLE
7840 && (expr->symtree->n.sym->intmod_sym_id == ISOCBINDING_NULL_PTR
7841 || expr->symtree->n.sym->intmod_sym_id
7842 == ISOCBINDING_NULL_FUNPTR))
7844 /* Set expr_type to EXPR_NULL, which will result in
7845 null_pointer_node being used below. */
7846 expr->expr_type = EXPR_NULL;
7848 else
7850 /* Update the type/kind of the expression to be what the new
7851 type/kind are for the updated symbols of C_PTR/C_FUNPTR. */
7852 expr->ts.type = BT_INTEGER;
7853 expr->ts.f90_type = BT_VOID;
7854 expr->ts.kind = gfc_index_integer_kind;
7858 gfc_fix_class_refs (expr);
7860 switch (expr->expr_type)
7862 case EXPR_OP:
7863 gfc_conv_expr_op (se, expr);
7864 break;
7866 case EXPR_FUNCTION:
7867 gfc_conv_function_expr (se, expr);
7868 break;
7870 case EXPR_CONSTANT:
7871 gfc_conv_constant (se, expr);
7872 break;
7874 case EXPR_VARIABLE:
7875 gfc_conv_variable (se, expr);
7876 break;
7878 case EXPR_NULL:
7879 se->expr = null_pointer_node;
7880 break;
7882 case EXPR_SUBSTRING:
7883 gfc_conv_substring_expr (se, expr);
7884 break;
7886 case EXPR_STRUCTURE:
7887 gfc_conv_structure (se, expr, 0);
7888 break;
7890 case EXPR_ARRAY:
7891 gfc_conv_array_constructor_expr (se, expr);
7892 break;
7894 default:
7895 gcc_unreachable ();
7896 break;
7900 /* Like gfc_conv_expr_val, but the value is also suitable for use in the lhs
7901 of an assignment. */
7902 void
7903 gfc_conv_expr_lhs (gfc_se * se, gfc_expr * expr)
7905 gfc_conv_expr (se, expr);
7906 /* All numeric lvalues should have empty post chains. If not we need to
7907 figure out a way of rewriting an lvalue so that it has no post chain. */
7908 gcc_assert (expr->ts.type == BT_CHARACTER || !se->post.head);
7911 /* Like gfc_conv_expr, but the POST block is guaranteed to be empty for
7912 numeric expressions. Used for scalar values where inserting cleanup code
7913 is inconvenient. */
7914 void
7915 gfc_conv_expr_val (gfc_se * se, gfc_expr * expr)
7917 tree val;
7919 gcc_assert (expr->ts.type != BT_CHARACTER);
7920 gfc_conv_expr (se, expr);
7921 if (se->post.head)
7923 val = gfc_create_var (TREE_TYPE (se->expr), NULL);
7924 gfc_add_modify (&se->pre, val, se->expr);
7925 se->expr = val;
7926 gfc_add_block_to_block (&se->pre, &se->post);
7930 /* Helper to translate an expression and convert it to a particular type. */
7931 void
7932 gfc_conv_expr_type (gfc_se * se, gfc_expr * expr, tree type)
7934 gfc_conv_expr_val (se, expr);
7935 se->expr = convert (type, se->expr);
7939 /* Converts an expression so that it can be passed by reference. Scalar
7940 values only. */
7942 void
7943 gfc_conv_expr_reference (gfc_se * se, gfc_expr * expr)
7945 gfc_ss *ss;
7946 tree var;
7948 ss = se->ss;
7949 if (ss && ss->info->expr == expr
7950 && ss->info->type == GFC_SS_REFERENCE)
7952 /* Returns a reference to the scalar evaluated outside the loop
7953 for this case. */
7954 gfc_conv_expr (se, expr);
7956 if (expr->ts.type == BT_CHARACTER
7957 && expr->expr_type != EXPR_FUNCTION)
7958 gfc_conv_string_parameter (se);
7959 else
7960 se->expr = gfc_build_addr_expr (NULL_TREE, se->expr);
7962 return;
7965 if (expr->ts.type == BT_CHARACTER)
7967 gfc_conv_expr (se, expr);
7968 gfc_conv_string_parameter (se);
7969 return;
7972 if (expr->expr_type == EXPR_VARIABLE)
7974 se->want_pointer = 1;
7975 gfc_conv_expr (se, expr);
7976 if (se->post.head)
7978 var = gfc_create_var (TREE_TYPE (se->expr), NULL);
7979 gfc_add_modify (&se->pre, var, se->expr);
7980 gfc_add_block_to_block (&se->pre, &se->post);
7981 se->expr = var;
7983 return;
7986 if (expr->expr_type == EXPR_FUNCTION
7987 && ((expr->value.function.esym
7988 && expr->value.function.esym->result->attr.pointer
7989 && !expr->value.function.esym->result->attr.dimension)
7990 || (!expr->value.function.esym && !expr->ref
7991 && expr->symtree->n.sym->attr.pointer
7992 && !expr->symtree->n.sym->attr.dimension)))
7994 se->want_pointer = 1;
7995 gfc_conv_expr (se, expr);
7996 var = gfc_create_var (TREE_TYPE (se->expr), NULL);
7997 gfc_add_modify (&se->pre, var, se->expr);
7998 se->expr = var;
7999 return;
8002 gfc_conv_expr (se, expr);
8004 /* Create a temporary var to hold the value. */
8005 if (TREE_CONSTANT (se->expr))
8007 tree tmp = se->expr;
8008 STRIP_TYPE_NOPS (tmp);
8009 var = build_decl (input_location,
8010 CONST_DECL, NULL, TREE_TYPE (tmp));
8011 DECL_INITIAL (var) = tmp;
8012 TREE_STATIC (var) = 1;
8013 pushdecl (var);
8015 else
8017 var = gfc_create_var (TREE_TYPE (se->expr), NULL);
8018 gfc_add_modify (&se->pre, var, se->expr);
8020 gfc_add_block_to_block (&se->pre, &se->post);
8022 /* Take the address of that value. */
8023 se->expr = gfc_build_addr_expr (NULL_TREE, var);
8027 /* Get the _len component for an unlimited polymorphic expression. */
8029 static tree
8030 trans_get_upoly_len (stmtblock_t *block, gfc_expr *expr)
8032 gfc_se se;
8033 gfc_ref *ref = expr->ref;
8035 gfc_init_se (&se, NULL);
8036 while (ref && ref->next)
8037 ref = ref->next;
8038 gfc_add_len_component (expr);
8039 gfc_conv_expr (&se, expr);
8040 gfc_add_block_to_block (block, &se.pre);
8041 gcc_assert (se.post.head == NULL_TREE);
8042 if (ref)
8044 gfc_free_ref_list (ref->next);
8045 ref->next = NULL;
8047 else
8049 gfc_free_ref_list (expr->ref);
8050 expr->ref = NULL;
8052 return se.expr;
8056 /* Assign _vptr and _len components as appropriate. BLOCK should be a
8057 statement-list outside of the scalarizer-loop. When code is generated, that
8058 depends on the scalarized expression, it is added to RSE.PRE.
8059 Returns le's _vptr tree and when set the len expressions in to_lenp and
8060 from_lenp to form a le%_vptr%_copy (re, le, [from_lenp, to_lenp])
8061 expression. */
8063 static tree
8064 trans_class_vptr_len_assignment (stmtblock_t *block, gfc_expr * le,
8065 gfc_expr * re, gfc_se *rse,
8066 tree * to_lenp, tree * from_lenp)
8068 gfc_se se;
8069 gfc_expr * vptr_expr;
8070 tree tmp, to_len = NULL_TREE, from_len = NULL_TREE, lhs_vptr;
8071 bool set_vptr = false, temp_rhs = false;
8072 stmtblock_t *pre = block;
8074 /* Create a temporary for complicated expressions. */
8075 if (re->expr_type != EXPR_VARIABLE && re->expr_type != EXPR_NULL
8076 && rse->expr != NULL_TREE && !DECL_P (rse->expr))
8078 tmp = gfc_create_var (TREE_TYPE (rse->expr), "rhs");
8079 pre = &rse->pre;
8080 gfc_add_modify (&rse->pre, tmp, rse->expr);
8081 rse->expr = tmp;
8082 temp_rhs = true;
8085 /* Get the _vptr for the left-hand side expression. */
8086 gfc_init_se (&se, NULL);
8087 vptr_expr = gfc_find_and_cut_at_last_class_ref (le);
8088 if (vptr_expr != NULL && gfc_expr_attr (vptr_expr).class_ok)
8090 /* Care about _len for unlimited polymorphic entities. */
8091 if (UNLIMITED_POLY (vptr_expr)
8092 || (vptr_expr->ts.type == BT_DERIVED
8093 && vptr_expr->ts.u.derived->attr.unlimited_polymorphic))
8094 to_len = trans_get_upoly_len (block, vptr_expr);
8095 gfc_add_vptr_component (vptr_expr);
8096 set_vptr = true;
8098 else
8099 vptr_expr = gfc_lval_expr_from_sym (gfc_find_vtab (&le->ts));
8100 se.want_pointer = 1;
8101 gfc_conv_expr (&se, vptr_expr);
8102 gfc_free_expr (vptr_expr);
8103 gfc_add_block_to_block (block, &se.pre);
8104 gcc_assert (se.post.head == NULL_TREE);
8105 lhs_vptr = se.expr;
8106 STRIP_NOPS (lhs_vptr);
8108 /* Set the _vptr only when the left-hand side of the assignment is a
8109 class-object. */
8110 if (set_vptr)
8112 /* Get the vptr from the rhs expression only, when it is variable.
8113 Functions are expected to be assigned to a temporary beforehand. */
8114 vptr_expr = (re->expr_type == EXPR_VARIABLE && re->ts.type == BT_CLASS)
8115 ? gfc_find_and_cut_at_last_class_ref (re)
8116 : NULL;
8117 if (vptr_expr != NULL && vptr_expr->ts.type == BT_CLASS)
8119 if (to_len != NULL_TREE)
8121 /* Get the _len information from the rhs. */
8122 if (UNLIMITED_POLY (vptr_expr)
8123 || (vptr_expr->ts.type == BT_DERIVED
8124 && vptr_expr->ts.u.derived->attr.unlimited_polymorphic))
8125 from_len = trans_get_upoly_len (block, vptr_expr);
8127 gfc_add_vptr_component (vptr_expr);
8129 else
8131 if (re->expr_type == EXPR_VARIABLE
8132 && DECL_P (re->symtree->n.sym->backend_decl)
8133 && DECL_LANG_SPECIFIC (re->symtree->n.sym->backend_decl)
8134 && GFC_DECL_SAVED_DESCRIPTOR (re->symtree->n.sym->backend_decl)
8135 && GFC_CLASS_TYPE_P (TREE_TYPE (GFC_DECL_SAVED_DESCRIPTOR (
8136 re->symtree->n.sym->backend_decl))))
8138 vptr_expr = NULL;
8139 se.expr = gfc_class_vptr_get (GFC_DECL_SAVED_DESCRIPTOR (
8140 re->symtree->n.sym->backend_decl));
8141 if (to_len)
8142 from_len = gfc_class_len_get (GFC_DECL_SAVED_DESCRIPTOR (
8143 re->symtree->n.sym->backend_decl));
8145 else if (temp_rhs && re->ts.type == BT_CLASS)
8147 vptr_expr = NULL;
8148 se.expr = gfc_class_vptr_get (rse->expr);
8149 if (UNLIMITED_POLY (re))
8150 from_len = gfc_class_len_get (rse->expr);
8152 else if (re->expr_type != EXPR_NULL)
8153 /* Only when rhs is non-NULL use its declared type for vptr
8154 initialisation. */
8155 vptr_expr = gfc_lval_expr_from_sym (gfc_find_vtab (&re->ts));
8156 else
8157 /* When the rhs is NULL use the vtab of lhs' declared type. */
8158 vptr_expr = gfc_lval_expr_from_sym (gfc_find_vtab (&le->ts));
8161 if (vptr_expr)
8163 gfc_init_se (&se, NULL);
8164 se.want_pointer = 1;
8165 gfc_conv_expr (&se, vptr_expr);
8166 gfc_free_expr (vptr_expr);
8167 gfc_add_block_to_block (block, &se.pre);
8168 gcc_assert (se.post.head == NULL_TREE);
8170 gfc_add_modify (pre, lhs_vptr, fold_convert (TREE_TYPE (lhs_vptr),
8171 se.expr));
8173 if (to_len != NULL_TREE)
8175 /* The _len component needs to be set. Figure how to get the
8176 value of the right-hand side. */
8177 if (from_len == NULL_TREE)
8179 if (rse->string_length != NULL_TREE)
8180 from_len = rse->string_length;
8181 else if (re->ts.type == BT_CHARACTER && re->ts.u.cl->length)
8183 from_len = gfc_get_expr_charlen (re);
8184 gfc_init_se (&se, NULL);
8185 gfc_conv_expr (&se, re->ts.u.cl->length);
8186 gfc_add_block_to_block (block, &se.pre);
8187 gcc_assert (se.post.head == NULL_TREE);
8188 from_len = gfc_evaluate_now (se.expr, block);
8190 else
8191 from_len = build_zero_cst (gfc_charlen_type_node);
8193 gfc_add_modify (pre, to_len, fold_convert (TREE_TYPE (to_len),
8194 from_len));
8198 /* Return the _len trees only, when requested. */
8199 if (to_lenp)
8200 *to_lenp = to_len;
8201 if (from_lenp)
8202 *from_lenp = from_len;
8203 return lhs_vptr;
8207 /* Assign tokens for pointer components. */
8209 static void
8210 trans_caf_token_assign (gfc_se *lse, gfc_se *rse, gfc_expr *expr1,
8211 gfc_expr *expr2)
8213 symbol_attribute lhs_attr, rhs_attr;
8214 tree tmp, lhs_tok, rhs_tok;
8215 /* Flag to indicated component refs on the rhs. */
8216 bool rhs_cr;
8218 lhs_attr = gfc_caf_attr (expr1);
8219 if (expr2->expr_type != EXPR_NULL)
8221 rhs_attr = gfc_caf_attr (expr2, false, &rhs_cr);
8222 if (lhs_attr.codimension && rhs_attr.codimension)
8224 lhs_tok = gfc_get_ultimate_alloc_ptr_comps_caf_token (lse, expr1);
8225 lhs_tok = build_fold_indirect_ref (lhs_tok);
8227 if (rhs_cr)
8228 rhs_tok = gfc_get_ultimate_alloc_ptr_comps_caf_token (rse, expr2);
8229 else
8231 tree caf_decl;
8232 caf_decl = gfc_get_tree_for_caf_expr (expr2);
8233 gfc_get_caf_token_offset (rse, &rhs_tok, NULL, caf_decl,
8234 NULL_TREE, NULL);
8236 tmp = build2_loc (input_location, MODIFY_EXPR, void_type_node,
8237 lhs_tok,
8238 fold_convert (TREE_TYPE (lhs_tok), rhs_tok));
8239 gfc_prepend_expr_to_block (&lse->post, tmp);
8242 else if (lhs_attr.codimension)
8244 lhs_tok = gfc_get_ultimate_alloc_ptr_comps_caf_token (lse, expr1);
8245 lhs_tok = build_fold_indirect_ref (lhs_tok);
8246 tmp = build2_loc (input_location, MODIFY_EXPR, void_type_node,
8247 lhs_tok, null_pointer_node);
8248 gfc_prepend_expr_to_block (&lse->post, tmp);
8252 /* Indentify class valued proc_pointer assignments. */
8254 static bool
8255 pointer_assignment_is_proc_pointer (gfc_expr * expr1, gfc_expr * expr2)
8257 gfc_ref * ref;
8259 ref = expr1->ref;
8260 while (ref && ref->next)
8261 ref = ref->next;
8263 return ref && ref->type == REF_COMPONENT
8264 && ref->u.c.component->attr.proc_pointer
8265 && expr2->expr_type == EXPR_VARIABLE
8266 && expr2->symtree->n.sym->attr.flavor == FL_PROCEDURE;
8270 /* Do everything that is needed for a CLASS function expr2. */
8272 static tree
8273 trans_class_pointer_fcn (stmtblock_t *block, gfc_se *lse, gfc_se *rse,
8274 gfc_expr *expr1, gfc_expr *expr2)
8276 tree expr1_vptr = NULL_TREE;
8277 tree tmp;
8279 gfc_conv_function_expr (rse, expr2);
8280 rse->expr = gfc_evaluate_now (rse->expr, &rse->pre);
8282 if (expr1->ts.type != BT_CLASS)
8283 rse->expr = gfc_class_data_get (rse->expr);
8284 else
8286 expr1_vptr = trans_class_vptr_len_assignment (block, expr1,
8287 expr2, rse,
8288 NULL, NULL);
8289 gfc_add_block_to_block (block, &rse->pre);
8290 tmp = gfc_create_var (TREE_TYPE (rse->expr), "ptrtemp");
8291 gfc_add_modify (&lse->pre, tmp, rse->expr);
8293 gfc_add_modify (&lse->pre, expr1_vptr,
8294 fold_convert (TREE_TYPE (expr1_vptr),
8295 gfc_class_vptr_get (tmp)));
8296 rse->expr = gfc_class_data_get (tmp);
8299 return expr1_vptr;
8303 tree
8304 gfc_trans_pointer_assign (gfc_code * code)
8306 return gfc_trans_pointer_assignment (code->expr1, code->expr2);
8310 /* Generate code for a pointer assignment. */
8312 tree
8313 gfc_trans_pointer_assignment (gfc_expr * expr1, gfc_expr * expr2)
8315 gfc_se lse;
8316 gfc_se rse;
8317 stmtblock_t block;
8318 tree desc;
8319 tree tmp;
8320 tree expr1_vptr = NULL_TREE;
8321 bool scalar, non_proc_pointer_assign;
8322 gfc_ss *ss;
8324 gfc_start_block (&block);
8326 gfc_init_se (&lse, NULL);
8328 /* Usually testing whether this is not a proc pointer assignment. */
8329 non_proc_pointer_assign = !pointer_assignment_is_proc_pointer (expr1, expr2);
8331 /* Check whether the expression is a scalar or not; we cannot use
8332 expr1->rank as it can be nonzero for proc pointers. */
8333 ss = gfc_walk_expr (expr1);
8334 scalar = ss == gfc_ss_terminator;
8335 if (!scalar)
8336 gfc_free_ss_chain (ss);
8338 if (expr1->ts.type == BT_DERIVED && expr2->ts.type == BT_CLASS
8339 && expr2->expr_type != EXPR_FUNCTION && non_proc_pointer_assign)
8341 gfc_add_data_component (expr2);
8342 /* The following is required as gfc_add_data_component doesn't
8343 update ts.type if there is a tailing REF_ARRAY. */
8344 expr2->ts.type = BT_DERIVED;
8347 if (scalar)
8349 /* Scalar pointers. */
8350 lse.want_pointer = 1;
8351 gfc_conv_expr (&lse, expr1);
8352 gfc_init_se (&rse, NULL);
8353 rse.want_pointer = 1;
8354 if (expr2->expr_type == EXPR_FUNCTION && expr2->ts.type == BT_CLASS)
8355 trans_class_pointer_fcn (&block, &lse, &rse, expr1, expr2);
8356 else
8357 gfc_conv_expr (&rse, expr2);
8359 if (non_proc_pointer_assign && expr1->ts.type == BT_CLASS)
8361 trans_class_vptr_len_assignment (&block, expr1, expr2, &rse, NULL,
8362 NULL);
8363 lse.expr = gfc_class_data_get (lse.expr);
8366 if (expr1->symtree->n.sym->attr.proc_pointer
8367 && expr1->symtree->n.sym->attr.dummy)
8368 lse.expr = build_fold_indirect_ref_loc (input_location,
8369 lse.expr);
8371 if (expr2->symtree && expr2->symtree->n.sym->attr.proc_pointer
8372 && expr2->symtree->n.sym->attr.dummy)
8373 rse.expr = build_fold_indirect_ref_loc (input_location,
8374 rse.expr);
8376 gfc_add_block_to_block (&block, &lse.pre);
8377 gfc_add_block_to_block (&block, &rse.pre);
8379 /* Check character lengths if character expression. The test is only
8380 really added if -fbounds-check is enabled. Exclude deferred
8381 character length lefthand sides. */
8382 if (expr1->ts.type == BT_CHARACTER && expr2->expr_type != EXPR_NULL
8383 && !expr1->ts.deferred
8384 && !expr1->symtree->n.sym->attr.proc_pointer
8385 && !gfc_is_proc_ptr_comp (expr1))
8387 gcc_assert (expr2->ts.type == BT_CHARACTER);
8388 gcc_assert (lse.string_length && rse.string_length);
8389 gfc_trans_same_strlen_check ("pointer assignment", &expr1->where,
8390 lse.string_length, rse.string_length,
8391 &block);
8394 /* The assignment to an deferred character length sets the string
8395 length to that of the rhs. */
8396 if (expr1->ts.deferred)
8398 if (expr2->expr_type != EXPR_NULL && lse.string_length != NULL)
8399 gfc_add_modify (&block, lse.string_length,
8400 fold_convert (TREE_TYPE (lse.string_length),
8401 rse.string_length));
8402 else if (lse.string_length != NULL)
8403 gfc_add_modify (&block, lse.string_length,
8404 build_zero_cst (TREE_TYPE (lse.string_length)));
8407 gfc_add_modify (&block, lse.expr,
8408 fold_convert (TREE_TYPE (lse.expr), rse.expr));
8410 /* Also set the tokens for pointer components in derived typed
8411 coarrays. */
8412 if (flag_coarray == GFC_FCOARRAY_LIB)
8413 trans_caf_token_assign (&lse, &rse, expr1, expr2);
8415 gfc_add_block_to_block (&block, &rse.post);
8416 gfc_add_block_to_block (&block, &lse.post);
8418 else
8420 gfc_ref* remap;
8421 bool rank_remap;
8422 tree strlen_lhs;
8423 tree strlen_rhs = NULL_TREE;
8425 /* Array pointer. Find the last reference on the LHS and if it is an
8426 array section ref, we're dealing with bounds remapping. In this case,
8427 set it to AR_FULL so that gfc_conv_expr_descriptor does
8428 not see it and process the bounds remapping afterwards explicitly. */
8429 for (remap = expr1->ref; remap; remap = remap->next)
8430 if (!remap->next && remap->type == REF_ARRAY
8431 && remap->u.ar.type == AR_SECTION)
8432 break;
8433 rank_remap = (remap && remap->u.ar.end[0]);
8435 gfc_init_se (&lse, NULL);
8436 if (remap)
8437 lse.descriptor_only = 1;
8438 gfc_conv_expr_descriptor (&lse, expr1);
8439 strlen_lhs = lse.string_length;
8440 desc = lse.expr;
8442 if (expr2->expr_type == EXPR_NULL)
8444 /* Just set the data pointer to null. */
8445 gfc_conv_descriptor_data_set (&lse.pre, lse.expr, null_pointer_node);
8447 else if (rank_remap)
8449 /* If we are rank-remapping, just get the RHS's descriptor and
8450 process this later on. */
8451 gfc_init_se (&rse, NULL);
8452 rse.direct_byref = 1;
8453 rse.byref_noassign = 1;
8455 if (expr2->expr_type == EXPR_FUNCTION && expr2->ts.type == BT_CLASS)
8456 expr1_vptr = trans_class_pointer_fcn (&block, &lse, &rse,
8457 expr1, expr2);
8458 else if (expr2->expr_type == EXPR_FUNCTION)
8460 tree bound[GFC_MAX_DIMENSIONS];
8461 int i;
8463 for (i = 0; i < expr2->rank; i++)
8464 bound[i] = NULL_TREE;
8465 tmp = gfc_typenode_for_spec (&expr2->ts);
8466 tmp = gfc_get_array_type_bounds (tmp, expr2->rank, 0,
8467 bound, bound, 0,
8468 GFC_ARRAY_POINTER_CONT, false);
8469 tmp = gfc_create_var (tmp, "ptrtemp");
8470 rse.descriptor_only = 0;
8471 rse.expr = tmp;
8472 rse.direct_byref = 1;
8473 gfc_conv_expr_descriptor (&rse, expr2);
8474 strlen_rhs = rse.string_length;
8475 rse.expr = tmp;
8477 else
8479 gfc_conv_expr_descriptor (&rse, expr2);
8480 strlen_rhs = rse.string_length;
8481 if (expr1->ts.type == BT_CLASS)
8482 expr1_vptr = trans_class_vptr_len_assignment (&block, expr1,
8483 expr2, &rse,
8484 NULL, NULL);
8487 else if (expr2->expr_type == EXPR_VARIABLE)
8489 /* Assign directly to the LHS's descriptor. */
8490 lse.descriptor_only = 0;
8491 lse.direct_byref = 1;
8492 gfc_conv_expr_descriptor (&lse, expr2);
8493 strlen_rhs = lse.string_length;
8495 if (expr1->ts.type == BT_CLASS)
8497 rse.expr = NULL_TREE;
8498 rse.string_length = NULL_TREE;
8499 trans_class_vptr_len_assignment (&block, expr1, expr2, &rse,
8500 NULL, NULL);
8503 if (remap == NULL)
8505 /* If the target is not a whole array, use the target array
8506 reference for remap. */
8507 for (remap = expr2->ref; remap; remap = remap->next)
8508 if (remap->type == REF_ARRAY
8509 && remap->u.ar.type == AR_FULL
8510 && remap->next)
8511 break;
8514 else if (expr2->expr_type == EXPR_FUNCTION && expr2->ts.type == BT_CLASS)
8516 gfc_init_se (&rse, NULL);
8517 rse.want_pointer = 1;
8518 gfc_conv_function_expr (&rse, expr2);
8519 if (expr1->ts.type != BT_CLASS)
8521 rse.expr = gfc_class_data_get (rse.expr);
8522 gfc_add_modify (&lse.pre, desc, rse.expr);
8523 /* Set the lhs span. */
8524 tmp = TREE_TYPE (rse.expr);
8525 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (tmp));
8526 tmp = fold_convert (gfc_array_index_type, tmp);
8527 gfc_conv_descriptor_span_set (&lse.pre, desc, tmp);
8529 else
8531 expr1_vptr = trans_class_vptr_len_assignment (&block, expr1,
8532 expr2, &rse, NULL,
8533 NULL);
8534 gfc_add_block_to_block (&block, &rse.pre);
8535 tmp = gfc_create_var (TREE_TYPE (rse.expr), "ptrtemp");
8536 gfc_add_modify (&lse.pre, tmp, rse.expr);
8538 gfc_add_modify (&lse.pre, expr1_vptr,
8539 fold_convert (TREE_TYPE (expr1_vptr),
8540 gfc_class_vptr_get (tmp)));
8541 rse.expr = gfc_class_data_get (tmp);
8542 gfc_add_modify (&lse.pre, desc, rse.expr);
8545 else
8547 /* Assign to a temporary descriptor and then copy that
8548 temporary to the pointer. */
8549 tmp = gfc_create_var (TREE_TYPE (desc), "ptrtemp");
8550 lse.descriptor_only = 0;
8551 lse.expr = tmp;
8552 lse.direct_byref = 1;
8553 gfc_conv_expr_descriptor (&lse, expr2);
8554 strlen_rhs = lse.string_length;
8555 gfc_add_modify (&lse.pre, desc, tmp);
8558 gfc_add_block_to_block (&block, &lse.pre);
8559 if (rank_remap)
8560 gfc_add_block_to_block (&block, &rse.pre);
8562 /* If we do bounds remapping, update LHS descriptor accordingly. */
8563 if (remap)
8565 int dim;
8566 gcc_assert (remap->u.ar.dimen == expr1->rank);
8568 if (rank_remap)
8570 /* Do rank remapping. We already have the RHS's descriptor
8571 converted in rse and now have to build the correct LHS
8572 descriptor for it. */
8574 tree dtype, data, span;
8575 tree offs, stride;
8576 tree lbound, ubound;
8578 /* Set dtype. */
8579 dtype = gfc_conv_descriptor_dtype (desc);
8580 tmp = gfc_get_dtype (TREE_TYPE (desc));
8581 gfc_add_modify (&block, dtype, tmp);
8583 /* Copy data pointer. */
8584 data = gfc_conv_descriptor_data_get (rse.expr);
8585 gfc_conv_descriptor_data_set (&block, desc, data);
8587 /* Copy the span. */
8588 if (TREE_CODE (rse.expr) == VAR_DECL
8589 && GFC_DECL_PTR_ARRAY_P (rse.expr))
8590 span = gfc_conv_descriptor_span_get (rse.expr);
8591 else
8593 tmp = TREE_TYPE (rse.expr);
8594 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (tmp));
8595 span = fold_convert (gfc_array_index_type, tmp);
8597 gfc_conv_descriptor_span_set (&block, desc, span);
8599 /* Copy offset but adjust it such that it would correspond
8600 to a lbound of zero. */
8601 offs = gfc_conv_descriptor_offset_get (rse.expr);
8602 for (dim = 0; dim < expr2->rank; ++dim)
8604 stride = gfc_conv_descriptor_stride_get (rse.expr,
8605 gfc_rank_cst[dim]);
8606 lbound = gfc_conv_descriptor_lbound_get (rse.expr,
8607 gfc_rank_cst[dim]);
8608 tmp = fold_build2_loc (input_location, MULT_EXPR,
8609 gfc_array_index_type, stride, lbound);
8610 offs = fold_build2_loc (input_location, PLUS_EXPR,
8611 gfc_array_index_type, offs, tmp);
8613 gfc_conv_descriptor_offset_set (&block, desc, offs);
8615 /* Set the bounds as declared for the LHS and calculate strides as
8616 well as another offset update accordingly. */
8617 stride = gfc_conv_descriptor_stride_get (rse.expr,
8618 gfc_rank_cst[0]);
8619 for (dim = 0; dim < expr1->rank; ++dim)
8621 gfc_se lower_se;
8622 gfc_se upper_se;
8624 gcc_assert (remap->u.ar.start[dim] && remap->u.ar.end[dim]);
8626 /* Convert declared bounds. */
8627 gfc_init_se (&lower_se, NULL);
8628 gfc_init_se (&upper_se, NULL);
8629 gfc_conv_expr (&lower_se, remap->u.ar.start[dim]);
8630 gfc_conv_expr (&upper_se, remap->u.ar.end[dim]);
8632 gfc_add_block_to_block (&block, &lower_se.pre);
8633 gfc_add_block_to_block (&block, &upper_se.pre);
8635 lbound = fold_convert (gfc_array_index_type, lower_se.expr);
8636 ubound = fold_convert (gfc_array_index_type, upper_se.expr);
8638 lbound = gfc_evaluate_now (lbound, &block);
8639 ubound = gfc_evaluate_now (ubound, &block);
8641 gfc_add_block_to_block (&block, &lower_se.post);
8642 gfc_add_block_to_block (&block, &upper_se.post);
8644 /* Set bounds in descriptor. */
8645 gfc_conv_descriptor_lbound_set (&block, desc,
8646 gfc_rank_cst[dim], lbound);
8647 gfc_conv_descriptor_ubound_set (&block, desc,
8648 gfc_rank_cst[dim], ubound);
8650 /* Set stride. */
8651 stride = gfc_evaluate_now (stride, &block);
8652 gfc_conv_descriptor_stride_set (&block, desc,
8653 gfc_rank_cst[dim], stride);
8655 /* Update offset. */
8656 offs = gfc_conv_descriptor_offset_get (desc);
8657 tmp = fold_build2_loc (input_location, MULT_EXPR,
8658 gfc_array_index_type, lbound, stride);
8659 offs = fold_build2_loc (input_location, MINUS_EXPR,
8660 gfc_array_index_type, offs, tmp);
8661 offs = gfc_evaluate_now (offs, &block);
8662 gfc_conv_descriptor_offset_set (&block, desc, offs);
8664 /* Update stride. */
8665 tmp = gfc_conv_array_extent_dim (lbound, ubound, NULL);
8666 stride = fold_build2_loc (input_location, MULT_EXPR,
8667 gfc_array_index_type, stride, tmp);
8670 else
8672 /* Bounds remapping. Just shift the lower bounds. */
8674 gcc_assert (expr1->rank == expr2->rank);
8676 for (dim = 0; dim < remap->u.ar.dimen; ++dim)
8678 gfc_se lbound_se;
8680 gcc_assert (!remap->u.ar.end[dim]);
8681 gfc_init_se (&lbound_se, NULL);
8682 if (remap->u.ar.start[dim])
8684 gfc_conv_expr (&lbound_se, remap->u.ar.start[dim]);
8685 gfc_add_block_to_block (&block, &lbound_se.pre);
8687 else
8688 /* This remap arises from a target that is not a whole
8689 array. The start expressions will be NULL but we need
8690 the lbounds to be one. */
8691 lbound_se.expr = gfc_index_one_node;
8692 gfc_conv_shift_descriptor_lbound (&block, desc,
8693 dim, lbound_se.expr);
8694 gfc_add_block_to_block (&block, &lbound_se.post);
8699 /* Check string lengths if applicable. The check is only really added
8700 to the output code if -fbounds-check is enabled. */
8701 if (expr1->ts.type == BT_CHARACTER && expr2->expr_type != EXPR_NULL)
8703 gcc_assert (expr2->ts.type == BT_CHARACTER);
8704 gcc_assert (strlen_lhs && strlen_rhs);
8705 gfc_trans_same_strlen_check ("pointer assignment", &expr1->where,
8706 strlen_lhs, strlen_rhs, &block);
8709 /* If rank remapping was done, check with -fcheck=bounds that
8710 the target is at least as large as the pointer. */
8711 if (rank_remap && (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS))
8713 tree lsize, rsize;
8714 tree fault;
8715 const char* msg;
8717 lsize = gfc_conv_descriptor_size (lse.expr, expr1->rank);
8718 rsize = gfc_conv_descriptor_size (rse.expr, expr2->rank);
8720 lsize = gfc_evaluate_now (lsize, &block);
8721 rsize = gfc_evaluate_now (rsize, &block);
8722 fault = fold_build2_loc (input_location, LT_EXPR, logical_type_node,
8723 rsize, lsize);
8725 msg = _("Target of rank remapping is too small (%ld < %ld)");
8726 gfc_trans_runtime_check (true, false, fault, &block, &expr2->where,
8727 msg, rsize, lsize);
8730 gfc_add_block_to_block (&block, &lse.post);
8731 if (rank_remap)
8732 gfc_add_block_to_block (&block, &rse.post);
8735 return gfc_finish_block (&block);
8739 /* Makes sure se is suitable for passing as a function string parameter. */
8740 /* TODO: Need to check all callers of this function. It may be abused. */
8742 void
8743 gfc_conv_string_parameter (gfc_se * se)
8745 tree type;
8747 if (TREE_CODE (se->expr) == STRING_CST)
8749 type = TREE_TYPE (TREE_TYPE (se->expr));
8750 se->expr = gfc_build_addr_expr (build_pointer_type (type), se->expr);
8751 return;
8754 if (TYPE_STRING_FLAG (TREE_TYPE (se->expr)))
8756 if (TREE_CODE (se->expr) != INDIRECT_REF)
8758 type = TREE_TYPE (se->expr);
8759 se->expr = gfc_build_addr_expr (build_pointer_type (type), se->expr);
8761 else
8763 type = gfc_get_character_type_len (gfc_default_character_kind,
8764 se->string_length);
8765 type = build_pointer_type (type);
8766 se->expr = gfc_build_addr_expr (type, se->expr);
8770 gcc_assert (POINTER_TYPE_P (TREE_TYPE (se->expr)));
8774 /* Generate code for assignment of scalar variables. Includes character
8775 strings and derived types with allocatable components.
8776 If you know that the LHS has no allocations, set dealloc to false.
8778 DEEP_COPY has no effect if the typespec TS is not a derived type with
8779 allocatable components. Otherwise, if it is set, an explicit copy of each
8780 allocatable component is made. This is necessary as a simple copy of the
8781 whole object would copy array descriptors as is, so that the lhs's
8782 allocatable components would point to the rhs's after the assignment.
8783 Typically, setting DEEP_COPY is necessary if the rhs is a variable, and not
8784 necessary if the rhs is a non-pointer function, as the allocatable components
8785 are not accessible by other means than the function's result after the
8786 function has returned. It is even more subtle when temporaries are involved,
8787 as the two following examples show:
8788 1. When we evaluate an array constructor, a temporary is created. Thus
8789 there is theoretically no alias possible. However, no deep copy is
8790 made for this temporary, so that if the constructor is made of one or
8791 more variable with allocatable components, those components still point
8792 to the variable's: DEEP_COPY should be set for the assignment from the
8793 temporary to the lhs in that case.
8794 2. When assigning a scalar to an array, we evaluate the scalar value out
8795 of the loop, store it into a temporary variable, and assign from that.
8796 In that case, deep copying when assigning to the temporary would be a
8797 waste of resources; however deep copies should happen when assigning from
8798 the temporary to each array element: again DEEP_COPY should be set for
8799 the assignment from the temporary to the lhs. */
8801 tree
8802 gfc_trans_scalar_assign (gfc_se * lse, gfc_se * rse, gfc_typespec ts,
8803 bool deep_copy, bool dealloc, bool in_coarray)
8805 stmtblock_t block;
8806 tree tmp;
8807 tree cond;
8809 gfc_init_block (&block);
8811 if (ts.type == BT_CHARACTER)
8813 tree rlen = NULL;
8814 tree llen = NULL;
8816 if (lse->string_length != NULL_TREE)
8818 gfc_conv_string_parameter (lse);
8819 gfc_add_block_to_block (&block, &lse->pre);
8820 llen = lse->string_length;
8823 if (rse->string_length != NULL_TREE)
8825 gfc_conv_string_parameter (rse);
8826 gfc_add_block_to_block (&block, &rse->pre);
8827 rlen = rse->string_length;
8830 gfc_trans_string_copy (&block, llen, lse->expr, ts.kind, rlen,
8831 rse->expr, ts.kind);
8833 else if (gfc_bt_struct (ts.type)
8834 && (ts.u.derived->attr.alloc_comp
8835 || (deep_copy && ts.u.derived->attr.pdt_type)))
8837 tree tmp_var = NULL_TREE;
8838 cond = NULL_TREE;
8840 /* Are the rhs and the lhs the same? */
8841 if (deep_copy)
8843 cond = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
8844 gfc_build_addr_expr (NULL_TREE, lse->expr),
8845 gfc_build_addr_expr (NULL_TREE, rse->expr));
8846 cond = gfc_evaluate_now (cond, &lse->pre);
8849 /* Deallocate the lhs allocated components as long as it is not
8850 the same as the rhs. This must be done following the assignment
8851 to prevent deallocating data that could be used in the rhs
8852 expression. */
8853 if (dealloc)
8855 tmp_var = gfc_evaluate_now (lse->expr, &lse->pre);
8856 tmp = gfc_deallocate_alloc_comp_no_caf (ts.u.derived, tmp_var, 0);
8857 if (deep_copy)
8858 tmp = build3_v (COND_EXPR, cond, build_empty_stmt (input_location),
8859 tmp);
8860 gfc_add_expr_to_block (&lse->post, tmp);
8863 gfc_add_block_to_block (&block, &rse->pre);
8864 gfc_add_block_to_block (&block, &lse->pre);
8866 gfc_add_modify (&block, lse->expr,
8867 fold_convert (TREE_TYPE (lse->expr), rse->expr));
8869 /* Restore pointer address of coarray components. */
8870 if (ts.u.derived->attr.coarray_comp && deep_copy && tmp_var != NULL_TREE)
8872 tmp = gfc_reassign_alloc_comp_caf (ts.u.derived, tmp_var, lse->expr);
8873 tmp = build3_v (COND_EXPR, cond, build_empty_stmt (input_location),
8874 tmp);
8875 gfc_add_expr_to_block (&block, tmp);
8878 /* Do a deep copy if the rhs is a variable, if it is not the
8879 same as the lhs. */
8880 if (deep_copy)
8882 int caf_mode = in_coarray ? (GFC_STRUCTURE_CAF_MODE_ENABLE_COARRAY
8883 | GFC_STRUCTURE_CAF_MODE_IN_COARRAY) : 0;
8884 tmp = gfc_copy_alloc_comp (ts.u.derived, rse->expr, lse->expr, 0,
8885 caf_mode);
8886 tmp = build3_v (COND_EXPR, cond, build_empty_stmt (input_location),
8887 tmp);
8888 gfc_add_expr_to_block (&block, tmp);
8891 else if (gfc_bt_struct (ts.type) || ts.type == BT_CLASS)
8893 gfc_add_block_to_block (&block, &lse->pre);
8894 gfc_add_block_to_block (&block, &rse->pre);
8895 tmp = fold_build1_loc (input_location, VIEW_CONVERT_EXPR,
8896 TREE_TYPE (lse->expr), rse->expr);
8897 gfc_add_modify (&block, lse->expr, tmp);
8899 else
8901 gfc_add_block_to_block (&block, &lse->pre);
8902 gfc_add_block_to_block (&block, &rse->pre);
8904 gfc_add_modify (&block, lse->expr,
8905 fold_convert (TREE_TYPE (lse->expr), rse->expr));
8908 gfc_add_block_to_block (&block, &lse->post);
8909 gfc_add_block_to_block (&block, &rse->post);
8911 return gfc_finish_block (&block);
8915 /* There are quite a lot of restrictions on the optimisation in using an
8916 array function assign without a temporary. */
8918 static bool
8919 arrayfunc_assign_needs_temporary (gfc_expr * expr1, gfc_expr * expr2)
8921 gfc_ref * ref;
8922 bool seen_array_ref;
8923 bool c = false;
8924 gfc_symbol *sym = expr1->symtree->n.sym;
8926 /* Play it safe with class functions assigned to a derived type. */
8927 if (gfc_is_class_array_function (expr2)
8928 && expr1->ts.type == BT_DERIVED)
8929 return true;
8931 /* The caller has already checked rank>0 and expr_type == EXPR_FUNCTION. */
8932 if (expr2->value.function.isym && !gfc_is_intrinsic_libcall (expr2))
8933 return true;
8935 /* Elemental functions are scalarized so that they don't need a
8936 temporary in gfc_trans_assignment_1, so return a true. Otherwise,
8937 they would need special treatment in gfc_trans_arrayfunc_assign. */
8938 if (expr2->value.function.esym != NULL
8939 && expr2->value.function.esym->attr.elemental)
8940 return true;
8942 /* Need a temporary if rhs is not FULL or a contiguous section. */
8943 if (expr1->ref && !(gfc_full_array_ref_p (expr1->ref, &c) || c))
8944 return true;
8946 /* Need a temporary if EXPR1 can't be expressed as a descriptor. */
8947 if (gfc_ref_needs_temporary_p (expr1->ref))
8948 return true;
8950 /* Functions returning pointers or allocatables need temporaries. */
8951 c = expr2->value.function.esym
8952 ? (expr2->value.function.esym->attr.pointer
8953 || expr2->value.function.esym->attr.allocatable)
8954 : (expr2->symtree->n.sym->attr.pointer
8955 || expr2->symtree->n.sym->attr.allocatable);
8956 if (c)
8957 return true;
8959 /* Character array functions need temporaries unless the
8960 character lengths are the same. */
8961 if (expr2->ts.type == BT_CHARACTER && expr2->rank > 0)
8963 if (expr1->ts.u.cl->length == NULL
8964 || expr1->ts.u.cl->length->expr_type != EXPR_CONSTANT)
8965 return true;
8967 if (expr2->ts.u.cl->length == NULL
8968 || expr2->ts.u.cl->length->expr_type != EXPR_CONSTANT)
8969 return true;
8971 if (mpz_cmp (expr1->ts.u.cl->length->value.integer,
8972 expr2->ts.u.cl->length->value.integer) != 0)
8973 return true;
8976 /* Check that no LHS component references appear during an array
8977 reference. This is needed because we do not have the means to
8978 span any arbitrary stride with an array descriptor. This check
8979 is not needed for the rhs because the function result has to be
8980 a complete type. */
8981 seen_array_ref = false;
8982 for (ref = expr1->ref; ref; ref = ref->next)
8984 if (ref->type == REF_ARRAY)
8985 seen_array_ref= true;
8986 else if (ref->type == REF_COMPONENT && seen_array_ref)
8987 return true;
8990 /* Check for a dependency. */
8991 if (gfc_check_fncall_dependency (expr1, INTENT_OUT,
8992 expr2->value.function.esym,
8993 expr2->value.function.actual,
8994 NOT_ELEMENTAL))
8995 return true;
8997 /* If we have reached here with an intrinsic function, we do not
8998 need a temporary except in the particular case that reallocation
8999 on assignment is active and the lhs is allocatable and a target. */
9000 if (expr2->value.function.isym)
9001 return (flag_realloc_lhs && sym->attr.allocatable && sym->attr.target);
9003 /* If the LHS is a dummy, we need a temporary if it is not
9004 INTENT(OUT). */
9005 if (sym->attr.dummy && sym->attr.intent != INTENT_OUT)
9006 return true;
9008 /* If the lhs has been host_associated, is in common, a pointer or is
9009 a target and the function is not using a RESULT variable, aliasing
9010 can occur and a temporary is needed. */
9011 if ((sym->attr.host_assoc
9012 || sym->attr.in_common
9013 || sym->attr.pointer
9014 || sym->attr.cray_pointee
9015 || sym->attr.target)
9016 && expr2->symtree != NULL
9017 && expr2->symtree->n.sym == expr2->symtree->n.sym->result)
9018 return true;
9020 /* A PURE function can unconditionally be called without a temporary. */
9021 if (expr2->value.function.esym != NULL
9022 && expr2->value.function.esym->attr.pure)
9023 return false;
9025 /* Implicit_pure functions are those which could legally be declared
9026 to be PURE. */
9027 if (expr2->value.function.esym != NULL
9028 && expr2->value.function.esym->attr.implicit_pure)
9029 return false;
9031 if (!sym->attr.use_assoc
9032 && !sym->attr.in_common
9033 && !sym->attr.pointer
9034 && !sym->attr.target
9035 && !sym->attr.cray_pointee
9036 && expr2->value.function.esym)
9038 /* A temporary is not needed if the function is not contained and
9039 the variable is local or host associated and not a pointer or
9040 a target. */
9041 if (!expr2->value.function.esym->attr.contained)
9042 return false;
9044 /* A temporary is not needed if the lhs has never been host
9045 associated and the procedure is contained. */
9046 else if (!sym->attr.host_assoc)
9047 return false;
9049 /* A temporary is not needed if the variable is local and not
9050 a pointer, a target or a result. */
9051 if (sym->ns->parent
9052 && expr2->value.function.esym->ns == sym->ns->parent)
9053 return false;
9056 /* Default to temporary use. */
9057 return true;
9061 /* Provide the loop info so that the lhs descriptor can be built for
9062 reallocatable assignments from extrinsic function calls. */
9064 static void
9065 realloc_lhs_loop_for_fcn_call (gfc_se *se, locus *where, gfc_ss **ss,
9066 gfc_loopinfo *loop)
9068 /* Signal that the function call should not be made by
9069 gfc_conv_loop_setup. */
9070 se->ss->is_alloc_lhs = 1;
9071 gfc_init_loopinfo (loop);
9072 gfc_add_ss_to_loop (loop, *ss);
9073 gfc_add_ss_to_loop (loop, se->ss);
9074 gfc_conv_ss_startstride (loop);
9075 gfc_conv_loop_setup (loop, where);
9076 gfc_copy_loopinfo_to_se (se, loop);
9077 gfc_add_block_to_block (&se->pre, &loop->pre);
9078 gfc_add_block_to_block (&se->pre, &loop->post);
9079 se->ss->is_alloc_lhs = 0;
9083 /* For assignment to a reallocatable lhs from intrinsic functions,
9084 replace the se.expr (ie. the result) with a temporary descriptor.
9085 Null the data field so that the library allocates space for the
9086 result. Free the data of the original descriptor after the function,
9087 in case it appears in an argument expression and transfer the
9088 result to the original descriptor. */
9090 static void
9091 fcncall_realloc_result (gfc_se *se, int rank)
9093 tree desc;
9094 tree res_desc;
9095 tree tmp;
9096 tree offset;
9097 tree zero_cond;
9098 int n;
9100 /* Use the allocation done by the library. Substitute the lhs
9101 descriptor with a copy, whose data field is nulled.*/
9102 desc = build_fold_indirect_ref_loc (input_location, se->expr);
9103 if (POINTER_TYPE_P (TREE_TYPE (desc)))
9104 desc = build_fold_indirect_ref_loc (input_location, desc);
9106 /* Unallocated, the descriptor does not have a dtype. */
9107 tmp = gfc_conv_descriptor_dtype (desc);
9108 gfc_add_modify (&se->pre, tmp, gfc_get_dtype (TREE_TYPE (desc)));
9110 res_desc = gfc_evaluate_now (desc, &se->pre);
9111 gfc_conv_descriptor_data_set (&se->pre, res_desc, null_pointer_node);
9112 se->expr = gfc_build_addr_expr (NULL_TREE, res_desc);
9114 /* Free the lhs after the function call and copy the result data to
9115 the lhs descriptor. */
9116 tmp = gfc_conv_descriptor_data_get (desc);
9117 zero_cond = fold_build2_loc (input_location, EQ_EXPR,
9118 logical_type_node, tmp,
9119 build_int_cst (TREE_TYPE (tmp), 0));
9120 zero_cond = gfc_evaluate_now (zero_cond, &se->post);
9121 tmp = gfc_call_free (tmp);
9122 gfc_add_expr_to_block (&se->post, tmp);
9124 tmp = gfc_conv_descriptor_data_get (res_desc);
9125 gfc_conv_descriptor_data_set (&se->post, desc, tmp);
9127 /* Check that the shapes are the same between lhs and expression. */
9128 for (n = 0 ; n < rank; n++)
9130 tree tmp1;
9131 tmp = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[n]);
9132 tmp1 = gfc_conv_descriptor_lbound_get (res_desc, gfc_rank_cst[n]);
9133 tmp = fold_build2_loc (input_location, MINUS_EXPR,
9134 gfc_array_index_type, tmp, tmp1);
9135 tmp1 = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[n]);
9136 tmp = fold_build2_loc (input_location, MINUS_EXPR,
9137 gfc_array_index_type, tmp, tmp1);
9138 tmp1 = gfc_conv_descriptor_ubound_get (res_desc, gfc_rank_cst[n]);
9139 tmp = fold_build2_loc (input_location, PLUS_EXPR,
9140 gfc_array_index_type, tmp, tmp1);
9141 tmp = fold_build2_loc (input_location, NE_EXPR,
9142 logical_type_node, tmp,
9143 gfc_index_zero_node);
9144 tmp = gfc_evaluate_now (tmp, &se->post);
9145 zero_cond = fold_build2_loc (input_location, TRUTH_OR_EXPR,
9146 logical_type_node, tmp,
9147 zero_cond);
9150 /* 'zero_cond' being true is equal to lhs not being allocated or the
9151 shapes being different. */
9152 zero_cond = gfc_evaluate_now (zero_cond, &se->post);
9154 /* Now reset the bounds returned from the function call to bounds based
9155 on the lhs lbounds, except where the lhs is not allocated or the shapes
9156 of 'variable and 'expr' are different. Set the offset accordingly. */
9157 offset = gfc_index_zero_node;
9158 for (n = 0 ; n < rank; n++)
9160 tree lbound;
9162 lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[n]);
9163 lbound = fold_build3_loc (input_location, COND_EXPR,
9164 gfc_array_index_type, zero_cond,
9165 gfc_index_one_node, lbound);
9166 lbound = gfc_evaluate_now (lbound, &se->post);
9168 tmp = gfc_conv_descriptor_ubound_get (res_desc, gfc_rank_cst[n]);
9169 tmp = fold_build2_loc (input_location, PLUS_EXPR,
9170 gfc_array_index_type, tmp, lbound);
9171 gfc_conv_descriptor_lbound_set (&se->post, desc,
9172 gfc_rank_cst[n], lbound);
9173 gfc_conv_descriptor_ubound_set (&se->post, desc,
9174 gfc_rank_cst[n], tmp);
9176 /* Set stride and accumulate the offset. */
9177 tmp = gfc_conv_descriptor_stride_get (res_desc, gfc_rank_cst[n]);
9178 gfc_conv_descriptor_stride_set (&se->post, desc,
9179 gfc_rank_cst[n], tmp);
9180 tmp = fold_build2_loc (input_location, MULT_EXPR,
9181 gfc_array_index_type, lbound, tmp);
9182 offset = fold_build2_loc (input_location, MINUS_EXPR,
9183 gfc_array_index_type, offset, tmp);
9184 offset = gfc_evaluate_now (offset, &se->post);
9187 gfc_conv_descriptor_offset_set (&se->post, desc, offset);
9192 /* Try to translate array(:) = func (...), where func is a transformational
9193 array function, without using a temporary. Returns NULL if this isn't the
9194 case. */
9196 static tree
9197 gfc_trans_arrayfunc_assign (gfc_expr * expr1, gfc_expr * expr2)
9199 gfc_se se;
9200 gfc_ss *ss = NULL;
9201 gfc_component *comp = NULL;
9202 gfc_loopinfo loop;
9204 if (arrayfunc_assign_needs_temporary (expr1, expr2))
9205 return NULL;
9207 /* The frontend doesn't seem to bother filling in expr->symtree for intrinsic
9208 functions. */
9209 comp = gfc_get_proc_ptr_comp (expr2);
9210 gcc_assert (expr2->value.function.isym
9211 || (comp && comp->attr.dimension)
9212 || (!comp && gfc_return_by_reference (expr2->value.function.esym)
9213 && expr2->value.function.esym->result->attr.dimension));
9215 gfc_init_se (&se, NULL);
9216 gfc_start_block (&se.pre);
9217 se.want_pointer = 1;
9219 gfc_conv_array_parameter (&se, expr1, false, NULL, NULL, NULL);
9221 if (expr1->ts.type == BT_DERIVED
9222 && expr1->ts.u.derived->attr.alloc_comp)
9224 tree tmp;
9225 tmp = gfc_deallocate_alloc_comp_no_caf (expr1->ts.u.derived, se.expr,
9226 expr1->rank);
9227 gfc_add_expr_to_block (&se.pre, tmp);
9230 se.direct_byref = 1;
9231 se.ss = gfc_walk_expr (expr2);
9232 gcc_assert (se.ss != gfc_ss_terminator);
9234 /* Reallocate on assignment needs the loopinfo for extrinsic functions.
9235 This is signalled to gfc_conv_procedure_call by setting is_alloc_lhs.
9236 Clearly, this cannot be done for an allocatable function result, since
9237 the shape of the result is unknown and, in any case, the function must
9238 correctly take care of the reallocation internally. For intrinsic
9239 calls, the array data is freed and the library takes care of allocation.
9240 TODO: Add logic of trans-array.c: gfc_alloc_allocatable_for_assignment
9241 to the library. */
9242 if (flag_realloc_lhs
9243 && gfc_is_reallocatable_lhs (expr1)
9244 && !gfc_expr_attr (expr1).codimension
9245 && !gfc_is_coindexed (expr1)
9246 && !(expr2->value.function.esym
9247 && expr2->value.function.esym->result->attr.allocatable))
9249 realloc_lhs_warning (expr1->ts.type, true, &expr1->where);
9251 if (!expr2->value.function.isym)
9253 ss = gfc_walk_expr (expr1);
9254 gcc_assert (ss != gfc_ss_terminator);
9256 realloc_lhs_loop_for_fcn_call (&se, &expr1->where, &ss, &loop);
9257 ss->is_alloc_lhs = 1;
9259 else
9260 fcncall_realloc_result (&se, expr1->rank);
9263 gfc_conv_function_expr (&se, expr2);
9264 gfc_add_block_to_block (&se.pre, &se.post);
9266 if (ss)
9267 gfc_cleanup_loop (&loop);
9268 else
9269 gfc_free_ss_chain (se.ss);
9271 return gfc_finish_block (&se.pre);
9275 /* Try to efficiently translate array(:) = 0. Return NULL if this
9276 can't be done. */
9278 static tree
9279 gfc_trans_zero_assign (gfc_expr * expr)
9281 tree dest, len, type;
9282 tree tmp;
9283 gfc_symbol *sym;
9285 sym = expr->symtree->n.sym;
9286 dest = gfc_get_symbol_decl (sym);
9288 type = TREE_TYPE (dest);
9289 if (POINTER_TYPE_P (type))
9290 type = TREE_TYPE (type);
9291 if (!GFC_ARRAY_TYPE_P (type))
9292 return NULL_TREE;
9294 /* Determine the length of the array. */
9295 len = GFC_TYPE_ARRAY_SIZE (type);
9296 if (!len || TREE_CODE (len) != INTEGER_CST)
9297 return NULL_TREE;
9299 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type));
9300 len = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type, len,
9301 fold_convert (gfc_array_index_type, tmp));
9303 /* If we are zeroing a local array avoid taking its address by emitting
9304 a = {} instead. */
9305 if (!POINTER_TYPE_P (TREE_TYPE (dest)))
9306 return build2_loc (input_location, MODIFY_EXPR, void_type_node,
9307 dest, build_constructor (TREE_TYPE (dest),
9308 NULL));
9310 /* Convert arguments to the correct types. */
9311 dest = fold_convert (pvoid_type_node, dest);
9312 len = fold_convert (size_type_node, len);
9314 /* Construct call to __builtin_memset. */
9315 tmp = build_call_expr_loc (input_location,
9316 builtin_decl_explicit (BUILT_IN_MEMSET),
9317 3, dest, integer_zero_node, len);
9318 return fold_convert (void_type_node, tmp);
9322 /* Helper for gfc_trans_array_copy and gfc_trans_array_constructor_copy
9323 that constructs the call to __builtin_memcpy. */
9325 tree
9326 gfc_build_memcpy_call (tree dst, tree src, tree len)
9328 tree tmp;
9330 /* Convert arguments to the correct types. */
9331 if (!POINTER_TYPE_P (TREE_TYPE (dst)))
9332 dst = gfc_build_addr_expr (pvoid_type_node, dst);
9333 else
9334 dst = fold_convert (pvoid_type_node, dst);
9336 if (!POINTER_TYPE_P (TREE_TYPE (src)))
9337 src = gfc_build_addr_expr (pvoid_type_node, src);
9338 else
9339 src = fold_convert (pvoid_type_node, src);
9341 len = fold_convert (size_type_node, len);
9343 /* Construct call to __builtin_memcpy. */
9344 tmp = build_call_expr_loc (input_location,
9345 builtin_decl_explicit (BUILT_IN_MEMCPY),
9346 3, dst, src, len);
9347 return fold_convert (void_type_node, tmp);
9351 /* Try to efficiently translate dst(:) = src(:). Return NULL if this
9352 can't be done. EXPR1 is the destination/lhs and EXPR2 is the
9353 source/rhs, both are gfc_full_array_ref_p which have been checked for
9354 dependencies. */
9356 static tree
9357 gfc_trans_array_copy (gfc_expr * expr1, gfc_expr * expr2)
9359 tree dst, dlen, dtype;
9360 tree src, slen, stype;
9361 tree tmp;
9363 dst = gfc_get_symbol_decl (expr1->symtree->n.sym);
9364 src = gfc_get_symbol_decl (expr2->symtree->n.sym);
9366 dtype = TREE_TYPE (dst);
9367 if (POINTER_TYPE_P (dtype))
9368 dtype = TREE_TYPE (dtype);
9369 stype = TREE_TYPE (src);
9370 if (POINTER_TYPE_P (stype))
9371 stype = TREE_TYPE (stype);
9373 if (!GFC_ARRAY_TYPE_P (dtype) || !GFC_ARRAY_TYPE_P (stype))
9374 return NULL_TREE;
9376 /* Determine the lengths of the arrays. */
9377 dlen = GFC_TYPE_ARRAY_SIZE (dtype);
9378 if (!dlen || TREE_CODE (dlen) != INTEGER_CST)
9379 return NULL_TREE;
9380 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (dtype));
9381 dlen = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
9382 dlen, fold_convert (gfc_array_index_type, tmp));
9384 slen = GFC_TYPE_ARRAY_SIZE (stype);
9385 if (!slen || TREE_CODE (slen) != INTEGER_CST)
9386 return NULL_TREE;
9387 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (stype));
9388 slen = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
9389 slen, fold_convert (gfc_array_index_type, tmp));
9391 /* Sanity check that they are the same. This should always be
9392 the case, as we should already have checked for conformance. */
9393 if (!tree_int_cst_equal (slen, dlen))
9394 return NULL_TREE;
9396 return gfc_build_memcpy_call (dst, src, dlen);
9400 /* Try to efficiently translate array(:) = (/ ... /). Return NULL if
9401 this can't be done. EXPR1 is the destination/lhs for which
9402 gfc_full_array_ref_p is true, and EXPR2 is the source/rhs. */
9404 static tree
9405 gfc_trans_array_constructor_copy (gfc_expr * expr1, gfc_expr * expr2)
9407 unsigned HOST_WIDE_INT nelem;
9408 tree dst, dtype;
9409 tree src, stype;
9410 tree len;
9411 tree tmp;
9413 nelem = gfc_constant_array_constructor_p (expr2->value.constructor);
9414 if (nelem == 0)
9415 return NULL_TREE;
9417 dst = gfc_get_symbol_decl (expr1->symtree->n.sym);
9418 dtype = TREE_TYPE (dst);
9419 if (POINTER_TYPE_P (dtype))
9420 dtype = TREE_TYPE (dtype);
9421 if (!GFC_ARRAY_TYPE_P (dtype))
9422 return NULL_TREE;
9424 /* Determine the lengths of the array. */
9425 len = GFC_TYPE_ARRAY_SIZE (dtype);
9426 if (!len || TREE_CODE (len) != INTEGER_CST)
9427 return NULL_TREE;
9429 /* Confirm that the constructor is the same size. */
9430 if (compare_tree_int (len, nelem) != 0)
9431 return NULL_TREE;
9433 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (dtype));
9434 len = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type, len,
9435 fold_convert (gfc_array_index_type, tmp));
9437 stype = gfc_typenode_for_spec (&expr2->ts);
9438 src = gfc_build_constant_array_constructor (expr2, stype);
9440 stype = TREE_TYPE (src);
9441 if (POINTER_TYPE_P (stype))
9442 stype = TREE_TYPE (stype);
9444 return gfc_build_memcpy_call (dst, src, len);
9448 /* Tells whether the expression is to be treated as a variable reference. */
9450 bool
9451 gfc_expr_is_variable (gfc_expr *expr)
9453 gfc_expr *arg;
9454 gfc_component *comp;
9455 gfc_symbol *func_ifc;
9457 if (expr->expr_type == EXPR_VARIABLE)
9458 return true;
9460 arg = gfc_get_noncopying_intrinsic_argument (expr);
9461 if (arg)
9463 gcc_assert (expr->value.function.isym->id == GFC_ISYM_TRANSPOSE);
9464 return gfc_expr_is_variable (arg);
9467 /* A data-pointer-returning function should be considered as a variable
9468 too. */
9469 if (expr->expr_type == EXPR_FUNCTION
9470 && expr->ref == NULL)
9472 if (expr->value.function.isym != NULL)
9473 return false;
9475 if (expr->value.function.esym != NULL)
9477 func_ifc = expr->value.function.esym;
9478 goto found_ifc;
9480 else
9482 gcc_assert (expr->symtree);
9483 func_ifc = expr->symtree->n.sym;
9484 goto found_ifc;
9487 gcc_unreachable ();
9490 comp = gfc_get_proc_ptr_comp (expr);
9491 if ((expr->expr_type == EXPR_PPC || expr->expr_type == EXPR_FUNCTION)
9492 && comp)
9494 func_ifc = comp->ts.interface;
9495 goto found_ifc;
9498 if (expr->expr_type == EXPR_COMPCALL)
9500 gcc_assert (!expr->value.compcall.tbp->is_generic);
9501 func_ifc = expr->value.compcall.tbp->u.specific->n.sym;
9502 goto found_ifc;
9505 return false;
9507 found_ifc:
9508 gcc_assert (func_ifc->attr.function
9509 && func_ifc->result != NULL);
9510 return func_ifc->result->attr.pointer;
9514 /* Is the lhs OK for automatic reallocation? */
9516 static bool
9517 is_scalar_reallocatable_lhs (gfc_expr *expr)
9519 gfc_ref * ref;
9521 /* An allocatable variable with no reference. */
9522 if (expr->symtree->n.sym->attr.allocatable
9523 && !expr->ref)
9524 return true;
9526 /* All that can be left are allocatable components. However, we do
9527 not check for allocatable components here because the expression
9528 could be an allocatable component of a pointer component. */
9529 if (expr->symtree->n.sym->ts.type != BT_DERIVED
9530 && expr->symtree->n.sym->ts.type != BT_CLASS)
9531 return false;
9533 /* Find an allocatable component ref last. */
9534 for (ref = expr->ref; ref; ref = ref->next)
9535 if (ref->type == REF_COMPONENT
9536 && !ref->next
9537 && ref->u.c.component->attr.allocatable)
9538 return true;
9540 return false;
9544 /* Allocate or reallocate scalar lhs, as necessary. */
9546 static void
9547 alloc_scalar_allocatable_for_assignment (stmtblock_t *block,
9548 tree string_length,
9549 gfc_expr *expr1,
9550 gfc_expr *expr2)
9553 tree cond;
9554 tree tmp;
9555 tree size;
9556 tree size_in_bytes;
9557 tree jump_label1;
9558 tree jump_label2;
9559 gfc_se lse;
9560 gfc_ref *ref;
9562 if (!expr1 || expr1->rank)
9563 return;
9565 if (!expr2 || expr2->rank)
9566 return;
9568 for (ref = expr1->ref; ref; ref = ref->next)
9569 if (ref->type == REF_SUBSTRING)
9570 return;
9572 realloc_lhs_warning (expr2->ts.type, false, &expr2->where);
9574 /* Since this is a scalar lhs, we can afford to do this. That is,
9575 there is no risk of side effects being repeated. */
9576 gfc_init_se (&lse, NULL);
9577 lse.want_pointer = 1;
9578 gfc_conv_expr (&lse, expr1);
9580 jump_label1 = gfc_build_label_decl (NULL_TREE);
9581 jump_label2 = gfc_build_label_decl (NULL_TREE);
9583 /* Do the allocation if the lhs is NULL. Otherwise go to label 1. */
9584 tmp = build_int_cst (TREE_TYPE (lse.expr), 0);
9585 cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
9586 lse.expr, tmp);
9587 tmp = build3_v (COND_EXPR, cond,
9588 build1_v (GOTO_EXPR, jump_label1),
9589 build_empty_stmt (input_location));
9590 gfc_add_expr_to_block (block, tmp);
9592 if (expr1->ts.type == BT_CHARACTER && expr1->ts.deferred)
9594 /* Use the rhs string length and the lhs element size. */
9595 size = string_length;
9596 tmp = TREE_TYPE (gfc_typenode_for_spec (&expr1->ts));
9597 tmp = TYPE_SIZE_UNIT (tmp);
9598 size_in_bytes = fold_build2_loc (input_location, MULT_EXPR,
9599 TREE_TYPE (tmp), tmp,
9600 fold_convert (TREE_TYPE (tmp), size));
9602 else
9604 /* Otherwise use the length in bytes of the rhs. */
9605 size = TYPE_SIZE_UNIT (gfc_typenode_for_spec (&expr1->ts));
9606 size_in_bytes = size;
9609 size_in_bytes = fold_build2_loc (input_location, MAX_EXPR, size_type_node,
9610 size_in_bytes, size_one_node);
9612 if (gfc_caf_attr (expr1).codimension && flag_coarray == GFC_FCOARRAY_LIB)
9614 tree caf_decl, token;
9615 gfc_se caf_se;
9616 symbol_attribute attr;
9618 gfc_clear_attr (&attr);
9619 gfc_init_se (&caf_se, NULL);
9621 caf_decl = gfc_get_tree_for_caf_expr (expr1);
9622 gfc_get_caf_token_offset (&caf_se, &token, NULL, caf_decl, NULL_TREE,
9623 NULL);
9624 gfc_add_block_to_block (block, &caf_se.pre);
9625 gfc_allocate_allocatable (block, lse.expr, size_in_bytes,
9626 gfc_build_addr_expr (NULL_TREE, token),
9627 NULL_TREE, NULL_TREE, NULL_TREE, jump_label1,
9628 expr1, 1);
9630 else if (expr1->ts.type == BT_DERIVED && expr1->ts.u.derived->attr.alloc_comp)
9632 tmp = build_call_expr_loc (input_location,
9633 builtin_decl_explicit (BUILT_IN_CALLOC),
9634 2, build_one_cst (size_type_node),
9635 size_in_bytes);
9636 tmp = fold_convert (TREE_TYPE (lse.expr), tmp);
9637 gfc_add_modify (block, lse.expr, tmp);
9639 else
9641 tmp = build_call_expr_loc (input_location,
9642 builtin_decl_explicit (BUILT_IN_MALLOC),
9643 1, size_in_bytes);
9644 tmp = fold_convert (TREE_TYPE (lse.expr), tmp);
9645 gfc_add_modify (block, lse.expr, tmp);
9648 if (expr1->ts.type == BT_CHARACTER && expr1->ts.deferred)
9650 /* Deferred characters need checking for lhs and rhs string
9651 length. Other deferred parameter variables will have to
9652 come here too. */
9653 tmp = build1_v (GOTO_EXPR, jump_label2);
9654 gfc_add_expr_to_block (block, tmp);
9656 tmp = build1_v (LABEL_EXPR, jump_label1);
9657 gfc_add_expr_to_block (block, tmp);
9659 /* For a deferred length character, reallocate if lengths of lhs and
9660 rhs are different. */
9661 if (expr1->ts.type == BT_CHARACTER && expr1->ts.deferred)
9663 cond = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
9664 lse.string_length,
9665 fold_convert (TREE_TYPE (lse.string_length),
9666 size));
9667 /* Jump past the realloc if the lengths are the same. */
9668 tmp = build3_v (COND_EXPR, cond,
9669 build1_v (GOTO_EXPR, jump_label2),
9670 build_empty_stmt (input_location));
9671 gfc_add_expr_to_block (block, tmp);
9672 tmp = build_call_expr_loc (input_location,
9673 builtin_decl_explicit (BUILT_IN_REALLOC),
9674 2, fold_convert (pvoid_type_node, lse.expr),
9675 size_in_bytes);
9676 tmp = fold_convert (TREE_TYPE (lse.expr), tmp);
9677 gfc_add_modify (block, lse.expr, tmp);
9678 tmp = build1_v (LABEL_EXPR, jump_label2);
9679 gfc_add_expr_to_block (block, tmp);
9681 /* Update the lhs character length. */
9682 size = string_length;
9683 gfc_add_modify (block, lse.string_length,
9684 fold_convert (TREE_TYPE (lse.string_length), size));
9688 /* Check for assignments of the type
9690 a = a + 4
9692 to make sure we do not check for reallocation unneccessarily. */
9695 static bool
9696 is_runtime_conformable (gfc_expr *expr1, gfc_expr *expr2)
9698 gfc_actual_arglist *a;
9699 gfc_expr *e1, *e2;
9701 switch (expr2->expr_type)
9703 case EXPR_VARIABLE:
9704 return gfc_dep_compare_expr (expr1, expr2) == 0;
9706 case EXPR_FUNCTION:
9707 if (expr2->value.function.esym
9708 && expr2->value.function.esym->attr.elemental)
9710 for (a = expr2->value.function.actual; a != NULL; a = a->next)
9712 e1 = a->expr;
9713 if (e1 && e1->rank > 0 && !is_runtime_conformable (expr1, e1))
9714 return false;
9716 return true;
9718 else if (expr2->value.function.isym
9719 && expr2->value.function.isym->elemental)
9721 for (a = expr2->value.function.actual; a != NULL; a = a->next)
9723 e1 = a->expr;
9724 if (e1 && e1->rank > 0 && !is_runtime_conformable (expr1, e1))
9725 return false;
9727 return true;
9730 break;
9732 case EXPR_OP:
9733 switch (expr2->value.op.op)
9735 case INTRINSIC_NOT:
9736 case INTRINSIC_UPLUS:
9737 case INTRINSIC_UMINUS:
9738 case INTRINSIC_PARENTHESES:
9739 return is_runtime_conformable (expr1, expr2->value.op.op1);
9741 case INTRINSIC_PLUS:
9742 case INTRINSIC_MINUS:
9743 case INTRINSIC_TIMES:
9744 case INTRINSIC_DIVIDE:
9745 case INTRINSIC_POWER:
9746 case INTRINSIC_AND:
9747 case INTRINSIC_OR:
9748 case INTRINSIC_EQV:
9749 case INTRINSIC_NEQV:
9750 case INTRINSIC_EQ:
9751 case INTRINSIC_NE:
9752 case INTRINSIC_GT:
9753 case INTRINSIC_GE:
9754 case INTRINSIC_LT:
9755 case INTRINSIC_LE:
9756 case INTRINSIC_EQ_OS:
9757 case INTRINSIC_NE_OS:
9758 case INTRINSIC_GT_OS:
9759 case INTRINSIC_GE_OS:
9760 case INTRINSIC_LT_OS:
9761 case INTRINSIC_LE_OS:
9763 e1 = expr2->value.op.op1;
9764 e2 = expr2->value.op.op2;
9766 if (e1->rank == 0 && e2->rank > 0)
9767 return is_runtime_conformable (expr1, e2);
9768 else if (e1->rank > 0 && e2->rank == 0)
9769 return is_runtime_conformable (expr1, e1);
9770 else if (e1->rank > 0 && e2->rank > 0)
9771 return is_runtime_conformable (expr1, e1)
9772 && is_runtime_conformable (expr1, e2);
9773 break;
9775 default:
9776 break;
9780 break;
9782 default:
9783 break;
9785 return false;
9789 static tree
9790 trans_class_assignment (stmtblock_t *block, gfc_expr *lhs, gfc_expr *rhs,
9791 gfc_se *lse, gfc_se *rse, bool use_vptr_copy,
9792 bool class_realloc)
9794 tree tmp, fcn, stdcopy, to_len, from_len, vptr;
9795 vec<tree, va_gc> *args = NULL;
9797 vptr = trans_class_vptr_len_assignment (block, lhs, rhs, rse, &to_len,
9798 &from_len);
9800 /* Generate allocation of the lhs. */
9801 if (class_realloc)
9803 stmtblock_t alloc;
9804 tree class_han;
9806 tmp = gfc_vptr_size_get (vptr);
9807 class_han = GFC_CLASS_TYPE_P (TREE_TYPE (lse->expr))
9808 ? gfc_class_data_get (lse->expr) : lse->expr;
9809 gfc_init_block (&alloc);
9810 gfc_allocate_using_malloc (&alloc, class_han, tmp, NULL_TREE);
9811 tmp = fold_build2_loc (input_location, EQ_EXPR,
9812 logical_type_node, class_han,
9813 build_int_cst (prvoid_type_node, 0));
9814 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
9815 gfc_unlikely (tmp,
9816 PRED_FORTRAN_FAIL_ALLOC),
9817 gfc_finish_block (&alloc),
9818 build_empty_stmt (input_location));
9819 gfc_add_expr_to_block (&lse->pre, tmp);
9822 fcn = gfc_vptr_copy_get (vptr);
9824 tmp = GFC_CLASS_TYPE_P (TREE_TYPE (rse->expr))
9825 ? gfc_class_data_get (rse->expr) : rse->expr;
9826 if (use_vptr_copy)
9828 if (!POINTER_TYPE_P (TREE_TYPE (tmp))
9829 || INDIRECT_REF_P (tmp)
9830 || (rhs->ts.type == BT_DERIVED
9831 && rhs->ts.u.derived->attr.unlimited_polymorphic
9832 && !rhs->ts.u.derived->attr.pointer
9833 && !rhs->ts.u.derived->attr.allocatable)
9834 || (UNLIMITED_POLY (rhs)
9835 && !CLASS_DATA (rhs)->attr.pointer
9836 && !CLASS_DATA (rhs)->attr.allocatable))
9837 vec_safe_push (args, gfc_build_addr_expr (NULL_TREE, tmp));
9838 else
9839 vec_safe_push (args, tmp);
9840 tmp = GFC_CLASS_TYPE_P (TREE_TYPE (lse->expr))
9841 ? gfc_class_data_get (lse->expr) : lse->expr;
9842 if (!POINTER_TYPE_P (TREE_TYPE (tmp))
9843 || INDIRECT_REF_P (tmp)
9844 || (lhs->ts.type == BT_DERIVED
9845 && lhs->ts.u.derived->attr.unlimited_polymorphic
9846 && !lhs->ts.u.derived->attr.pointer
9847 && !lhs->ts.u.derived->attr.allocatable)
9848 || (UNLIMITED_POLY (lhs)
9849 && !CLASS_DATA (lhs)->attr.pointer
9850 && !CLASS_DATA (lhs)->attr.allocatable))
9851 vec_safe_push (args, gfc_build_addr_expr (NULL_TREE, tmp));
9852 else
9853 vec_safe_push (args, tmp);
9855 stdcopy = build_call_vec (TREE_TYPE (TREE_TYPE (fcn)), fcn, args);
9857 if (to_len != NULL_TREE && !integer_zerop (from_len))
9859 tree extcopy;
9860 vec_safe_push (args, from_len);
9861 vec_safe_push (args, to_len);
9862 extcopy = build_call_vec (TREE_TYPE (TREE_TYPE (fcn)), fcn, args);
9864 tmp = fold_build2_loc (input_location, GT_EXPR,
9865 logical_type_node, from_len,
9866 build_zero_cst (TREE_TYPE (from_len)));
9867 return fold_build3_loc (input_location, COND_EXPR,
9868 void_type_node, tmp,
9869 extcopy, stdcopy);
9871 else
9872 return stdcopy;
9874 else
9876 tree rhst = GFC_CLASS_TYPE_P (TREE_TYPE (lse->expr))
9877 ? gfc_class_data_get (lse->expr) : lse->expr;
9878 stmtblock_t tblock;
9879 gfc_init_block (&tblock);
9880 if (!POINTER_TYPE_P (TREE_TYPE (tmp)))
9881 tmp = gfc_build_addr_expr (NULL_TREE, tmp);
9882 if (!POINTER_TYPE_P (TREE_TYPE (rhst)))
9883 rhst = gfc_build_addr_expr (NULL_TREE, rhst);
9884 /* When coming from a ptr_copy lhs and rhs are swapped. */
9885 gfc_add_modify_loc (input_location, &tblock, rhst,
9886 fold_convert (TREE_TYPE (rhst), tmp));
9887 return gfc_finish_block (&tblock);
9891 /* Subroutine of gfc_trans_assignment that actually scalarizes the
9892 assignment. EXPR1 is the destination/LHS and EXPR2 is the source/RHS.
9893 init_flag indicates initialization expressions and dealloc that no
9894 deallocate prior assignment is needed (if in doubt, set true).
9895 When PTR_COPY is set and expr1 is a class type, then use the _vptr-copy
9896 routine instead of a pointer assignment. Alias resolution is only done,
9897 when MAY_ALIAS is set (the default). This flag is used by ALLOCATE()
9898 where it is known, that newly allocated memory on the lhs can never be
9899 an alias of the rhs. */
9901 static tree
9902 gfc_trans_assignment_1 (gfc_expr * expr1, gfc_expr * expr2, bool init_flag,
9903 bool dealloc, bool use_vptr_copy, bool may_alias)
9905 gfc_se lse;
9906 gfc_se rse;
9907 gfc_ss *lss;
9908 gfc_ss *lss_section;
9909 gfc_ss *rss;
9910 gfc_loopinfo loop;
9911 tree tmp;
9912 stmtblock_t block;
9913 stmtblock_t body;
9914 bool l_is_temp;
9915 bool scalar_to_array;
9916 tree string_length;
9917 int n;
9918 bool maybe_workshare = false, lhs_refs_comp = false, rhs_refs_comp = false;
9919 symbol_attribute lhs_caf_attr, rhs_caf_attr, lhs_attr;
9920 bool is_poly_assign;
9922 /* Assignment of the form lhs = rhs. */
9923 gfc_start_block (&block);
9925 gfc_init_se (&lse, NULL);
9926 gfc_init_se (&rse, NULL);
9928 /* Walk the lhs. */
9929 lss = gfc_walk_expr (expr1);
9930 if (gfc_is_reallocatable_lhs (expr1)
9931 && !(expr2->expr_type == EXPR_FUNCTION
9932 && expr2->value.function.isym != NULL
9933 && !(expr2->value.function.isym->elemental
9934 || expr2->value.function.isym->conversion)))
9935 lss->is_alloc_lhs = 1;
9937 rss = NULL;
9939 if ((expr1->ts.type == BT_DERIVED)
9940 && (gfc_is_class_array_function (expr2)
9941 || gfc_is_alloc_class_scalar_function (expr2)))
9942 expr2->must_finalize = 1;
9944 /* Checking whether a class assignment is desired is quite complicated and
9945 needed at two locations, so do it once only before the information is
9946 needed. */
9947 lhs_attr = gfc_expr_attr (expr1);
9948 is_poly_assign = (use_vptr_copy || lhs_attr.pointer
9949 || (lhs_attr.allocatable && !lhs_attr.dimension))
9950 && (expr1->ts.type == BT_CLASS
9951 || gfc_is_class_array_ref (expr1, NULL)
9952 || gfc_is_class_scalar_expr (expr1)
9953 || gfc_is_class_array_ref (expr2, NULL)
9954 || gfc_is_class_scalar_expr (expr2));
9957 /* Only analyze the expressions for coarray properties, when in coarray-lib
9958 mode. */
9959 if (flag_coarray == GFC_FCOARRAY_LIB)
9961 lhs_caf_attr = gfc_caf_attr (expr1, false, &lhs_refs_comp);
9962 rhs_caf_attr = gfc_caf_attr (expr2, false, &rhs_refs_comp);
9965 if (lss != gfc_ss_terminator)
9967 /* The assignment needs scalarization. */
9968 lss_section = lss;
9970 /* Find a non-scalar SS from the lhs. */
9971 while (lss_section != gfc_ss_terminator
9972 && lss_section->info->type != GFC_SS_SECTION)
9973 lss_section = lss_section->next;
9975 gcc_assert (lss_section != gfc_ss_terminator);
9977 /* Initialize the scalarizer. */
9978 gfc_init_loopinfo (&loop);
9980 /* Walk the rhs. */
9981 rss = gfc_walk_expr (expr2);
9982 if (rss == gfc_ss_terminator)
9983 /* The rhs is scalar. Add a ss for the expression. */
9984 rss = gfc_get_scalar_ss (gfc_ss_terminator, expr2);
9985 /* When doing a class assign, then the handle to the rhs needs to be a
9986 pointer to allow for polymorphism. */
9987 if (is_poly_assign && expr2->rank == 0 && !UNLIMITED_POLY (expr2))
9988 rss->info->type = GFC_SS_REFERENCE;
9990 /* Associate the SS with the loop. */
9991 gfc_add_ss_to_loop (&loop, lss);
9992 gfc_add_ss_to_loop (&loop, rss);
9994 /* Calculate the bounds of the scalarization. */
9995 gfc_conv_ss_startstride (&loop);
9996 /* Enable loop reversal. */
9997 for (n = 0; n < GFC_MAX_DIMENSIONS; n++)
9998 loop.reverse[n] = GFC_ENABLE_REVERSE;
9999 /* Resolve any data dependencies in the statement. */
10000 if (may_alias)
10001 gfc_conv_resolve_dependencies (&loop, lss, rss);
10002 /* Setup the scalarizing loops. */
10003 gfc_conv_loop_setup (&loop, &expr2->where);
10005 /* Setup the gfc_se structures. */
10006 gfc_copy_loopinfo_to_se (&lse, &loop);
10007 gfc_copy_loopinfo_to_se (&rse, &loop);
10009 rse.ss = rss;
10010 gfc_mark_ss_chain_used (rss, 1);
10011 if (loop.temp_ss == NULL)
10013 lse.ss = lss;
10014 gfc_mark_ss_chain_used (lss, 1);
10016 else
10018 lse.ss = loop.temp_ss;
10019 gfc_mark_ss_chain_used (lss, 3);
10020 gfc_mark_ss_chain_used (loop.temp_ss, 3);
10023 /* Allow the scalarizer to workshare array assignments. */
10024 if ((ompws_flags & (OMPWS_WORKSHARE_FLAG | OMPWS_SCALARIZER_BODY))
10025 == OMPWS_WORKSHARE_FLAG
10026 && loop.temp_ss == NULL)
10028 maybe_workshare = true;
10029 ompws_flags |= OMPWS_SCALARIZER_WS | OMPWS_SCALARIZER_BODY;
10032 /* Start the scalarized loop body. */
10033 gfc_start_scalarized_body (&loop, &body);
10035 else
10036 gfc_init_block (&body);
10038 l_is_temp = (lss != gfc_ss_terminator && loop.temp_ss != NULL);
10040 /* Translate the expression. */
10041 rse.want_coarray = flag_coarray == GFC_FCOARRAY_LIB && init_flag
10042 && lhs_caf_attr.codimension;
10043 gfc_conv_expr (&rse, expr2);
10045 /* Deal with the case of a scalar class function assigned to a derived type. */
10046 if (gfc_is_alloc_class_scalar_function (expr2)
10047 && expr1->ts.type == BT_DERIVED)
10049 rse.expr = gfc_class_data_get (rse.expr);
10050 rse.expr = build_fold_indirect_ref_loc (input_location, rse.expr);
10053 /* Stabilize a string length for temporaries. */
10054 if (expr2->ts.type == BT_CHARACTER && !expr1->ts.deferred
10055 && !(VAR_P (rse.string_length)
10056 || TREE_CODE (rse.string_length) == PARM_DECL
10057 || TREE_CODE (rse.string_length) == INDIRECT_REF))
10058 string_length = gfc_evaluate_now (rse.string_length, &rse.pre);
10059 else if (expr2->ts.type == BT_CHARACTER)
10060 string_length = rse.string_length;
10061 else
10062 string_length = NULL_TREE;
10064 if (l_is_temp)
10066 gfc_conv_tmp_array_ref (&lse);
10067 if (expr2->ts.type == BT_CHARACTER)
10068 lse.string_length = string_length;
10070 else
10072 gfc_conv_expr (&lse, expr1);
10073 if (gfc_option.rtcheck & GFC_RTCHECK_MEM
10074 && !init_flag
10075 && gfc_expr_attr (expr1).allocatable
10076 && expr1->rank
10077 && !expr2->rank)
10079 tree cond;
10080 const char* msg;
10082 tmp = INDIRECT_REF_P (lse.expr)
10083 ? gfc_build_addr_expr (NULL_TREE, lse.expr) : lse.expr;
10085 /* We should only get array references here. */
10086 gcc_assert (TREE_CODE (tmp) == POINTER_PLUS_EXPR
10087 || TREE_CODE (tmp) == ARRAY_REF);
10089 /* 'tmp' is either the pointer to the array(POINTER_PLUS_EXPR)
10090 or the array itself(ARRAY_REF). */
10091 tmp = TREE_OPERAND (tmp, 0);
10093 /* Provide the address of the array. */
10094 if (TREE_CODE (lse.expr) == ARRAY_REF)
10095 tmp = gfc_build_addr_expr (NULL_TREE, tmp);
10097 cond = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
10098 tmp, build_int_cst (TREE_TYPE (tmp), 0));
10099 msg = _("Assignment of scalar to unallocated array");
10100 gfc_trans_runtime_check (true, false, cond, &loop.pre,
10101 &expr1->where, msg);
10104 /* Deallocate the lhs parameterized components if required. */
10105 if (dealloc && expr2->expr_type == EXPR_FUNCTION
10106 && !expr1->symtree->n.sym->attr.associate_var)
10108 if (expr1->ts.type == BT_DERIVED
10109 && expr1->ts.u.derived
10110 && expr1->ts.u.derived->attr.pdt_type)
10112 tmp = gfc_deallocate_pdt_comp (expr1->ts.u.derived, lse.expr,
10113 expr1->rank);
10114 gfc_add_expr_to_block (&lse.pre, tmp);
10116 else if (expr1->ts.type == BT_CLASS
10117 && CLASS_DATA (expr1)->ts.u.derived
10118 && CLASS_DATA (expr1)->ts.u.derived->attr.pdt_type)
10120 tmp = gfc_class_data_get (lse.expr);
10121 tmp = gfc_deallocate_pdt_comp (CLASS_DATA (expr1)->ts.u.derived,
10122 tmp, expr1->rank);
10123 gfc_add_expr_to_block (&lse.pre, tmp);
10128 /* Assignments of scalar derived types with allocatable components
10129 to arrays must be done with a deep copy and the rhs temporary
10130 must have its components deallocated afterwards. */
10131 scalar_to_array = (expr2->ts.type == BT_DERIVED
10132 && expr2->ts.u.derived->attr.alloc_comp
10133 && !gfc_expr_is_variable (expr2)
10134 && expr1->rank && !expr2->rank);
10135 scalar_to_array |= (expr1->ts.type == BT_DERIVED
10136 && expr1->rank
10137 && expr1->ts.u.derived->attr.alloc_comp
10138 && gfc_is_alloc_class_scalar_function (expr2));
10139 if (scalar_to_array && dealloc)
10141 tmp = gfc_deallocate_alloc_comp_no_caf (expr2->ts.u.derived, rse.expr, 0);
10142 gfc_prepend_expr_to_block (&loop.post, tmp);
10145 /* When assigning a character function result to a deferred-length variable,
10146 the function call must happen before the (re)allocation of the lhs -
10147 otherwise the character length of the result is not known.
10148 NOTE: This relies on having the exact dependence of the length type
10149 parameter available to the caller; gfortran saves it in the .mod files.
10150 NOTE ALSO: The concatenation operation generates a temporary pointer,
10151 whose allocation must go to the innermost loop.
10152 NOTE ALSO (2): A character conversion may generate a temporary, too. */
10153 if (flag_realloc_lhs
10154 && expr2->ts.type == BT_CHARACTER && expr1->ts.deferred
10155 && !(lss != gfc_ss_terminator
10156 && ((expr2->expr_type == EXPR_OP
10157 && expr2->value.op.op == INTRINSIC_CONCAT)
10158 || (expr2->expr_type == EXPR_FUNCTION
10159 && expr2->value.function.isym != NULL
10160 && expr2->value.function.isym->id == GFC_ISYM_CONVERSION))))
10161 gfc_add_block_to_block (&block, &rse.pre);
10163 /* Nullify the allocatable components corresponding to those of the lhs
10164 derived type, so that the finalization of the function result does not
10165 affect the lhs of the assignment. Prepend is used to ensure that the
10166 nullification occurs before the call to the finalizer. In the case of
10167 a scalar to array assignment, this is done in gfc_trans_scalar_assign
10168 as part of the deep copy. */
10169 if (!scalar_to_array && expr1->ts.type == BT_DERIVED
10170 && (gfc_is_class_array_function (expr2)
10171 || gfc_is_alloc_class_scalar_function (expr2)))
10173 tmp = rse.expr;
10174 tmp = gfc_nullify_alloc_comp (expr1->ts.u.derived, rse.expr, 0);
10175 gfc_prepend_expr_to_block (&rse.post, tmp);
10176 if (lss != gfc_ss_terminator && rss == gfc_ss_terminator)
10177 gfc_add_block_to_block (&loop.post, &rse.post);
10180 if (is_poly_assign)
10181 tmp = trans_class_assignment (&body, expr1, expr2, &lse, &rse,
10182 use_vptr_copy || (lhs_attr.allocatable
10183 && !lhs_attr.dimension),
10184 flag_realloc_lhs && !lhs_attr.pointer);
10185 else if (flag_coarray == GFC_FCOARRAY_LIB
10186 && lhs_caf_attr.codimension && rhs_caf_attr.codimension
10187 && ((lhs_caf_attr.allocatable && lhs_refs_comp)
10188 || (rhs_caf_attr.allocatable && rhs_refs_comp)))
10190 /* Only detour to caf_send[get][_by_ref] () when the lhs or rhs is an
10191 allocatable component, because those need to be accessed via the
10192 caf-runtime. No need to check for coindexes here, because resolve
10193 has rewritten those already. */
10194 gfc_code code;
10195 gfc_actual_arglist a1, a2;
10196 /* Clear the structures to prevent accessing garbage. */
10197 memset (&code, '\0', sizeof (gfc_code));
10198 memset (&a1, '\0', sizeof (gfc_actual_arglist));
10199 memset (&a2, '\0', sizeof (gfc_actual_arglist));
10200 a1.expr = expr1;
10201 a1.next = &a2;
10202 a2.expr = expr2;
10203 a2.next = NULL;
10204 code.ext.actual = &a1;
10205 code.resolved_isym = gfc_intrinsic_subroutine_by_id (GFC_ISYM_CAF_SEND);
10206 tmp = gfc_conv_intrinsic_subroutine (&code);
10208 else
10209 tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts,
10210 gfc_expr_is_variable (expr2)
10211 || scalar_to_array
10212 || expr2->expr_type == EXPR_ARRAY,
10213 !(l_is_temp || init_flag) && dealloc,
10214 expr1->symtree->n.sym->attr.codimension);
10215 /* Add the pre blocks to the body. */
10216 gfc_add_block_to_block (&body, &rse.pre);
10217 gfc_add_block_to_block (&body, &lse.pre);
10218 gfc_add_expr_to_block (&body, tmp);
10219 /* Add the post blocks to the body. */
10220 gfc_add_block_to_block (&body, &rse.post);
10221 gfc_add_block_to_block (&body, &lse.post);
10223 if (lss == gfc_ss_terminator)
10225 /* F2003: Add the code for reallocation on assignment. */
10226 if (flag_realloc_lhs && is_scalar_reallocatable_lhs (expr1)
10227 && !is_poly_assign)
10228 alloc_scalar_allocatable_for_assignment (&block, string_length,
10229 expr1, expr2);
10231 /* Use the scalar assignment as is. */
10232 gfc_add_block_to_block (&block, &body);
10234 else
10236 gcc_assert (lse.ss == gfc_ss_terminator
10237 && rse.ss == gfc_ss_terminator);
10239 if (l_is_temp)
10241 gfc_trans_scalarized_loop_boundary (&loop, &body);
10243 /* We need to copy the temporary to the actual lhs. */
10244 gfc_init_se (&lse, NULL);
10245 gfc_init_se (&rse, NULL);
10246 gfc_copy_loopinfo_to_se (&lse, &loop);
10247 gfc_copy_loopinfo_to_se (&rse, &loop);
10249 rse.ss = loop.temp_ss;
10250 lse.ss = lss;
10252 gfc_conv_tmp_array_ref (&rse);
10253 gfc_conv_expr (&lse, expr1);
10255 gcc_assert (lse.ss == gfc_ss_terminator
10256 && rse.ss == gfc_ss_terminator);
10258 if (expr2->ts.type == BT_CHARACTER)
10259 rse.string_length = string_length;
10261 tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts,
10262 false, dealloc);
10263 gfc_add_expr_to_block (&body, tmp);
10266 /* F2003: Allocate or reallocate lhs of allocatable array. */
10267 if (flag_realloc_lhs
10268 && gfc_is_reallocatable_lhs (expr1)
10269 && expr2->rank
10270 && !is_runtime_conformable (expr1, expr2))
10272 realloc_lhs_warning (expr1->ts.type, true, &expr1->where);
10273 ompws_flags &= ~OMPWS_SCALARIZER_WS;
10274 tmp = gfc_alloc_allocatable_for_assignment (&loop, expr1, expr2);
10275 if (tmp != NULL_TREE)
10276 gfc_add_expr_to_block (&loop.code[expr1->rank - 1], tmp);
10279 if (maybe_workshare)
10280 ompws_flags &= ~OMPWS_SCALARIZER_BODY;
10282 /* Generate the copying loops. */
10283 gfc_trans_scalarizing_loops (&loop, &body);
10285 /* Wrap the whole thing up. */
10286 gfc_add_block_to_block (&block, &loop.pre);
10287 gfc_add_block_to_block (&block, &loop.post);
10289 gfc_cleanup_loop (&loop);
10292 return gfc_finish_block (&block);
10296 /* Check whether EXPR is a copyable array. */
10298 static bool
10299 copyable_array_p (gfc_expr * expr)
10301 if (expr->expr_type != EXPR_VARIABLE)
10302 return false;
10304 /* First check it's an array. */
10305 if (expr->rank < 1 || !expr->ref || expr->ref->next)
10306 return false;
10308 if (!gfc_full_array_ref_p (expr->ref, NULL))
10309 return false;
10311 /* Next check that it's of a simple enough type. */
10312 switch (expr->ts.type)
10314 case BT_INTEGER:
10315 case BT_REAL:
10316 case BT_COMPLEX:
10317 case BT_LOGICAL:
10318 return true;
10320 case BT_CHARACTER:
10321 return false;
10323 case_bt_struct:
10324 return !expr->ts.u.derived->attr.alloc_comp;
10326 default:
10327 break;
10330 return false;
10333 /* Translate an assignment. */
10335 tree
10336 gfc_trans_assignment (gfc_expr * expr1, gfc_expr * expr2, bool init_flag,
10337 bool dealloc, bool use_vptr_copy, bool may_alias)
10339 tree tmp;
10341 /* Special case a single function returning an array. */
10342 if (expr2->expr_type == EXPR_FUNCTION && expr2->rank > 0)
10344 tmp = gfc_trans_arrayfunc_assign (expr1, expr2);
10345 if (tmp)
10346 return tmp;
10349 /* Special case assigning an array to zero. */
10350 if (copyable_array_p (expr1)
10351 && is_zero_initializer_p (expr2))
10353 tmp = gfc_trans_zero_assign (expr1);
10354 if (tmp)
10355 return tmp;
10358 /* Special case copying one array to another. */
10359 if (copyable_array_p (expr1)
10360 && copyable_array_p (expr2)
10361 && gfc_compare_types (&expr1->ts, &expr2->ts)
10362 && !gfc_check_dependency (expr1, expr2, 0))
10364 tmp = gfc_trans_array_copy (expr1, expr2);
10365 if (tmp)
10366 return tmp;
10369 /* Special case initializing an array from a constant array constructor. */
10370 if (copyable_array_p (expr1)
10371 && expr2->expr_type == EXPR_ARRAY
10372 && gfc_compare_types (&expr1->ts, &expr2->ts))
10374 tmp = gfc_trans_array_constructor_copy (expr1, expr2);
10375 if (tmp)
10376 return tmp;
10379 /* Fallback to the scalarizer to generate explicit loops. */
10380 return gfc_trans_assignment_1 (expr1, expr2, init_flag, dealloc,
10381 use_vptr_copy, may_alias);
10384 tree
10385 gfc_trans_init_assign (gfc_code * code)
10387 return gfc_trans_assignment (code->expr1, code->expr2, true, false, true);
10390 tree
10391 gfc_trans_assign (gfc_code * code)
10393 return gfc_trans_assignment (code->expr1, code->expr2, false, true);