Fix co-array allocation
[official-gcc.git] / gcc / fortran / trans-expr.c
blob1f94dcf11dd5f6f8f404cbbf872f0cf70671867d
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;
550 int dim;
552 /* The derived type needs to be converted to a temporary
553 CLASS object. */
554 tmp = gfc_typenode_for_spec (&class_ts);
555 var = gfc_create_var (tmp, "class");
557 /* Set the vptr. */
558 ctree = gfc_class_vptr_get (var);
560 if (vptr != NULL_TREE)
562 /* Use the dynamic vptr. */
563 tmp = vptr;
565 else
567 /* In this case the vtab corresponds to the derived type and the
568 vptr must point to it. */
569 vtab = gfc_find_derived_vtab (e->ts.u.derived);
570 gcc_assert (vtab);
571 tmp = gfc_build_addr_expr (NULL_TREE, gfc_get_symbol_decl (vtab));
573 gfc_add_modify (&parmse->pre, ctree,
574 fold_convert (TREE_TYPE (ctree), tmp));
576 /* Now set the data field. */
577 ctree = gfc_class_data_get (var);
579 if (optional)
580 cond_optional = gfc_conv_expr_present (e->symtree->n.sym);
582 if (parmse->expr && POINTER_TYPE_P (TREE_TYPE (parmse->expr)))
584 /* If there is a ready made pointer to a derived type, use it
585 rather than evaluating the expression again. */
586 tmp = fold_convert (TREE_TYPE (ctree), parmse->expr);
587 gfc_add_modify (&parmse->pre, ctree, tmp);
589 else if (parmse->ss && parmse->ss->info && parmse->ss->info->useflags)
591 /* For an array reference in an elemental procedure call we need
592 to retain the ss to provide the scalarized array reference. */
593 gfc_conv_expr_reference (parmse, e);
594 tmp = fold_convert (TREE_TYPE (ctree), parmse->expr);
595 if (optional)
596 tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp),
597 cond_optional, tmp,
598 fold_convert (TREE_TYPE (tmp), null_pointer_node));
599 gfc_add_modify (&parmse->pre, ctree, tmp);
601 else
603 ss = gfc_walk_expr (e);
604 if (ss == gfc_ss_terminator)
606 parmse->ss = NULL;
607 gfc_conv_expr_reference (parmse, e);
609 /* Scalar to an assumed-rank array. */
610 if (class_ts.u.derived->components->as)
612 tree type;
613 type = get_scalar_to_descriptor_type (parmse->expr,
614 gfc_expr_attr (e));
615 gfc_add_modify (&parmse->pre, gfc_conv_descriptor_dtype (ctree),
616 gfc_get_dtype (type));
617 if (optional)
618 parmse->expr = build3_loc (input_location, COND_EXPR,
619 TREE_TYPE (parmse->expr),
620 cond_optional, parmse->expr,
621 fold_convert (TREE_TYPE (parmse->expr),
622 null_pointer_node));
623 gfc_conv_descriptor_data_set (&parmse->pre, ctree, parmse->expr);
625 else
627 tmp = fold_convert (TREE_TYPE (ctree), parmse->expr);
628 if (optional)
629 tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp),
630 cond_optional, tmp,
631 fold_convert (TREE_TYPE (tmp),
632 null_pointer_node));
633 gfc_add_modify (&parmse->pre, ctree, tmp);
636 else
638 stmtblock_t block;
639 gfc_init_block (&block);
640 gfc_ref *ref;
642 parmse->ss = ss;
643 parmse->use_offset = 1;
644 gfc_conv_expr_descriptor (parmse, e);
646 /* Detect any array references with vector subscripts. */
647 for (ref = e->ref; ref; ref = ref->next)
648 if (ref->type == REF_ARRAY
649 && ref->u.ar.type != AR_ELEMENT
650 && ref->u.ar.type != AR_FULL)
652 for (dim = 0; dim < ref->u.ar.dimen; dim++)
653 if (ref->u.ar.dimen_type[dim] == DIMEN_VECTOR)
654 break;
655 if (dim < ref->u.ar.dimen)
656 break;
659 /* Array references with vector subscripts and non-variable expressions
660 need be converted to a one-based descriptor. */
661 if (ref || e->expr_type != EXPR_VARIABLE)
663 for (dim = 0; dim < e->rank; ++dim)
664 gfc_conv_shift_descriptor_lbound (&block, parmse->expr, dim,
665 gfc_index_one_node);
668 if (e->rank != class_ts.u.derived->components->as->rank)
670 gcc_assert (class_ts.u.derived->components->as->type
671 == AS_ASSUMED_RANK);
672 class_array_data_assign (&block, ctree, parmse->expr, false);
674 else
676 if (gfc_expr_attr (e).codimension)
677 parmse->expr = fold_build1_loc (input_location,
678 VIEW_CONVERT_EXPR,
679 TREE_TYPE (ctree),
680 parmse->expr);
681 gfc_add_modify (&block, ctree, parmse->expr);
684 if (optional)
686 tmp = gfc_finish_block (&block);
688 gfc_init_block (&block);
689 gfc_conv_descriptor_data_set (&block, ctree, null_pointer_node);
691 tmp = build3_v (COND_EXPR, cond_optional, tmp,
692 gfc_finish_block (&block));
693 gfc_add_expr_to_block (&parmse->pre, tmp);
695 else
696 gfc_add_block_to_block (&parmse->pre, &block);
700 if (class_ts.u.derived->components->ts.type == BT_DERIVED
701 && class_ts.u.derived->components->ts.u.derived
702 ->attr.unlimited_polymorphic)
704 /* Take care about initializing the _len component correctly. */
705 ctree = gfc_class_len_get (var);
706 if (UNLIMITED_POLY (e))
708 gfc_expr *len;
709 gfc_se se;
711 len = gfc_copy_expr (e);
712 gfc_add_len_component (len);
713 gfc_init_se (&se, NULL);
714 gfc_conv_expr (&se, len);
715 if (optional)
716 tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (se.expr),
717 cond_optional, se.expr,
718 fold_convert (TREE_TYPE (se.expr),
719 integer_zero_node));
720 else
721 tmp = se.expr;
723 else
724 tmp = integer_zero_node;
725 gfc_add_modify (&parmse->pre, ctree, fold_convert (TREE_TYPE (ctree),
726 tmp));
728 /* Pass the address of the class object. */
729 parmse->expr = gfc_build_addr_expr (NULL_TREE, var);
731 if (optional && optional_alloc_ptr)
732 parmse->expr = build3_loc (input_location, COND_EXPR,
733 TREE_TYPE (parmse->expr),
734 cond_optional, parmse->expr,
735 fold_convert (TREE_TYPE (parmse->expr),
736 null_pointer_node));
740 /* Create a new class container, which is required as scalar coarrays
741 have an array descriptor while normal scalars haven't. Optionally,
742 NULL pointer checks are added if the argument is OPTIONAL. */
744 static void
745 class_scalar_coarray_to_class (gfc_se *parmse, gfc_expr *e,
746 gfc_typespec class_ts, bool optional)
748 tree var, ctree, tmp;
749 stmtblock_t block;
750 gfc_ref *ref;
751 gfc_ref *class_ref;
753 gfc_init_block (&block);
755 class_ref = NULL;
756 for (ref = e->ref; ref; ref = ref->next)
758 if (ref->type == REF_COMPONENT
759 && ref->u.c.component->ts.type == BT_CLASS)
760 class_ref = ref;
763 if (class_ref == NULL
764 && e->symtree && e->symtree->n.sym->ts.type == BT_CLASS)
765 tmp = e->symtree->n.sym->backend_decl;
766 else
768 /* Remove everything after the last class reference, convert the
769 expression and then recover its tailend once more. */
770 gfc_se tmpse;
771 ref = class_ref->next;
772 class_ref->next = NULL;
773 gfc_init_se (&tmpse, NULL);
774 gfc_conv_expr (&tmpse, e);
775 class_ref->next = ref;
776 tmp = tmpse.expr;
779 var = gfc_typenode_for_spec (&class_ts);
780 var = gfc_create_var (var, "class");
782 ctree = gfc_class_vptr_get (var);
783 gfc_add_modify (&block, ctree,
784 fold_convert (TREE_TYPE (ctree), gfc_class_vptr_get (tmp)));
786 ctree = gfc_class_data_get (var);
787 tmp = gfc_conv_descriptor_data_get (gfc_class_data_get (tmp));
788 gfc_add_modify (&block, ctree, fold_convert (TREE_TYPE (ctree), tmp));
790 /* Pass the address of the class object. */
791 parmse->expr = gfc_build_addr_expr (NULL_TREE, var);
793 if (optional)
795 tree cond = gfc_conv_expr_present (e->symtree->n.sym);
796 tree tmp2;
798 tmp = gfc_finish_block (&block);
800 gfc_init_block (&block);
801 tmp2 = gfc_class_data_get (var);
802 gfc_add_modify (&block, tmp2, fold_convert (TREE_TYPE (tmp2),
803 null_pointer_node));
804 tmp2 = gfc_finish_block (&block);
806 tmp = build3_loc (input_location, COND_EXPR, void_type_node,
807 cond, tmp, tmp2);
808 gfc_add_expr_to_block (&parmse->pre, tmp);
810 else
811 gfc_add_block_to_block (&parmse->pre, &block);
815 /* Takes an intrinsic type expression and returns the address of a temporary
816 class object of the 'declared' type. */
817 void
818 gfc_conv_intrinsic_to_class (gfc_se *parmse, gfc_expr *e,
819 gfc_typespec class_ts)
821 gfc_symbol *vtab;
822 gfc_ss *ss;
823 tree ctree;
824 tree var;
825 tree tmp;
827 /* The intrinsic type needs to be converted to a temporary
828 CLASS object. */
829 tmp = gfc_typenode_for_spec (&class_ts);
830 var = gfc_create_var (tmp, "class");
832 /* Set the vptr. */
833 ctree = gfc_class_vptr_get (var);
835 vtab = gfc_find_vtab (&e->ts);
836 gcc_assert (vtab);
837 tmp = gfc_build_addr_expr (NULL_TREE, gfc_get_symbol_decl (vtab));
838 gfc_add_modify (&parmse->pre, ctree,
839 fold_convert (TREE_TYPE (ctree), tmp));
841 /* Now set the data field. */
842 ctree = gfc_class_data_get (var);
843 if (parmse->ss && parmse->ss->info->useflags)
845 /* For an array reference in an elemental procedure call we need
846 to retain the ss to provide the scalarized array reference. */
847 gfc_conv_expr_reference (parmse, e);
848 tmp = fold_convert (TREE_TYPE (ctree), parmse->expr);
849 gfc_add_modify (&parmse->pre, ctree, tmp);
851 else
853 ss = gfc_walk_expr (e);
854 if (ss == gfc_ss_terminator)
856 parmse->ss = NULL;
857 gfc_conv_expr_reference (parmse, e);
858 if (class_ts.u.derived->components->as
859 && class_ts.u.derived->components->as->type == AS_ASSUMED_RANK)
861 tmp = gfc_conv_scalar_to_descriptor (parmse, parmse->expr,
862 gfc_expr_attr (e));
863 tmp = fold_build1_loc (input_location, VIEW_CONVERT_EXPR,
864 TREE_TYPE (ctree), tmp);
866 else
867 tmp = fold_convert (TREE_TYPE (ctree), parmse->expr);
868 gfc_add_modify (&parmse->pre, ctree, tmp);
870 else
872 parmse->ss = ss;
873 parmse->use_offset = 1;
874 gfc_conv_expr_descriptor (parmse, e);
875 if (class_ts.u.derived->components->as->rank != e->rank)
877 tmp = fold_build1_loc (input_location, VIEW_CONVERT_EXPR,
878 TREE_TYPE (ctree), parmse->expr);
879 gfc_add_modify (&parmse->pre, ctree, tmp);
881 else
882 gfc_add_modify (&parmse->pre, ctree, parmse->expr);
886 gcc_assert (class_ts.type == BT_CLASS);
887 if (class_ts.u.derived->components->ts.type == BT_DERIVED
888 && class_ts.u.derived->components->ts.u.derived
889 ->attr.unlimited_polymorphic)
891 ctree = gfc_class_len_get (var);
892 /* When the actual arg is a char array, then set the _len component of the
893 unlimited polymorphic entity to the length of the string. */
894 if (e->ts.type == BT_CHARACTER)
896 /* Start with parmse->string_length because this seems to be set to a
897 correct value more often. */
898 if (parmse->string_length)
899 tmp = parmse->string_length;
900 /* When the string_length is not yet set, then try the backend_decl of
901 the cl. */
902 else if (e->ts.u.cl->backend_decl)
903 tmp = e->ts.u.cl->backend_decl;
904 /* If both of the above approaches fail, then try to generate an
905 expression from the input, which is only feasible currently, when the
906 expression can be evaluated to a constant one. */
907 else
909 /* Try to simplify the expression. */
910 gfc_simplify_expr (e, 0);
911 if (e->expr_type == EXPR_CONSTANT && !e->ts.u.cl->resolved)
913 /* Amazingly all data is present to compute the length of a
914 constant string, but the expression is not yet there. */
915 e->ts.u.cl->length = gfc_get_constant_expr (BT_INTEGER,
916 gfc_charlen_int_kind,
917 &e->where);
918 mpz_set_ui (e->ts.u.cl->length->value.integer,
919 e->value.character.length);
920 gfc_conv_const_charlen (e->ts.u.cl);
921 e->ts.u.cl->resolved = 1;
922 tmp = e->ts.u.cl->backend_decl;
924 else
926 gfc_error ("Can't compute the length of the char array at %L.",
927 &e->where);
931 else
932 tmp = integer_zero_node;
934 gfc_add_modify (&parmse->pre, ctree, fold_convert (TREE_TYPE (ctree), tmp));
936 else if (class_ts.type == BT_CLASS
937 && class_ts.u.derived->components
938 && class_ts.u.derived->components->ts.u
939 .derived->attr.unlimited_polymorphic)
941 ctree = gfc_class_len_get (var);
942 gfc_add_modify (&parmse->pre, ctree,
943 fold_convert (TREE_TYPE (ctree),
944 integer_zero_node));
946 /* Pass the address of the class object. */
947 parmse->expr = gfc_build_addr_expr (NULL_TREE, var);
951 /* Takes a scalarized class array expression and returns the
952 address of a temporary scalar class object of the 'declared'
953 type.
954 OOP-TODO: This could be improved by adding code that branched on
955 the dynamic type being the same as the declared type. In this case
956 the original class expression can be passed directly.
957 optional_alloc_ptr is false when the dummy is neither allocatable
958 nor a pointer; that's relevant for the optional handling.
959 Set copyback to true if class container's _data and _vtab pointers
960 might get modified. */
962 void
963 gfc_conv_class_to_class (gfc_se *parmse, gfc_expr *e, gfc_typespec class_ts,
964 bool elemental, bool copyback, bool optional,
965 bool optional_alloc_ptr)
967 tree ctree;
968 tree var;
969 tree tmp;
970 tree vptr;
971 tree cond = NULL_TREE;
972 tree slen = NULL_TREE;
973 gfc_ref *ref;
974 gfc_ref *class_ref;
975 stmtblock_t block;
976 bool full_array = false;
978 gfc_init_block (&block);
980 class_ref = NULL;
981 for (ref = e->ref; ref; ref = ref->next)
983 if (ref->type == REF_COMPONENT
984 && ref->u.c.component->ts.type == BT_CLASS)
985 class_ref = ref;
987 if (ref->next == NULL)
988 break;
991 if ((ref == NULL || class_ref == ref)
992 && !(gfc_is_class_array_function (e) && parmse->class_vptr != NULL_TREE)
993 && (!class_ts.u.derived->components->as
994 || class_ts.u.derived->components->as->rank != -1))
995 return;
997 /* Test for FULL_ARRAY. */
998 if (e->rank == 0 && gfc_expr_attr (e).codimension
999 && gfc_expr_attr (e).dimension)
1000 full_array = true;
1001 else
1002 gfc_is_class_array_ref (e, &full_array);
1004 /* The derived type needs to be converted to a temporary
1005 CLASS object. */
1006 tmp = gfc_typenode_for_spec (&class_ts);
1007 var = gfc_create_var (tmp, "class");
1009 /* Set the data. */
1010 ctree = gfc_class_data_get (var);
1011 if (class_ts.u.derived->components->as
1012 && e->rank != class_ts.u.derived->components->as->rank)
1014 if (e->rank == 0)
1016 tree type = get_scalar_to_descriptor_type (parmse->expr,
1017 gfc_expr_attr (e));
1018 gfc_add_modify (&block, gfc_conv_descriptor_dtype (ctree),
1019 gfc_get_dtype (type));
1021 tmp = gfc_class_data_get (parmse->expr);
1022 if (!POINTER_TYPE_P (TREE_TYPE (tmp)))
1023 tmp = gfc_build_addr_expr (NULL_TREE, tmp);
1025 gfc_conv_descriptor_data_set (&block, ctree, tmp);
1027 else
1028 class_array_data_assign (&block, ctree, parmse->expr, false);
1030 else
1032 if (TREE_TYPE (parmse->expr) != TREE_TYPE (ctree))
1033 parmse->expr = fold_build1_loc (input_location, VIEW_CONVERT_EXPR,
1034 TREE_TYPE (ctree), parmse->expr);
1035 gfc_add_modify (&block, ctree, parmse->expr);
1038 /* Return the data component, except in the case of scalarized array
1039 references, where nullification of the cannot occur and so there
1040 is no need. */
1041 if (!elemental && full_array && copyback)
1043 if (class_ts.u.derived->components->as
1044 && e->rank != class_ts.u.derived->components->as->rank)
1046 if (e->rank == 0)
1047 gfc_add_modify (&parmse->post, gfc_class_data_get (parmse->expr),
1048 gfc_conv_descriptor_data_get (ctree));
1049 else
1050 class_array_data_assign (&parmse->post, parmse->expr, ctree, true);
1052 else
1053 gfc_add_modify (&parmse->post, parmse->expr, ctree);
1056 /* Set the vptr. */
1057 ctree = gfc_class_vptr_get (var);
1059 /* The vptr is the second field of the actual argument.
1060 First we have to find the corresponding class reference. */
1062 tmp = NULL_TREE;
1063 if (gfc_is_class_array_function (e)
1064 && parmse->class_vptr != NULL_TREE)
1065 tmp = parmse->class_vptr;
1066 else if (class_ref == NULL
1067 && e->symtree && e->symtree->n.sym->ts.type == BT_CLASS)
1069 tmp = e->symtree->n.sym->backend_decl;
1071 if (TREE_CODE (tmp) == FUNCTION_DECL)
1072 tmp = gfc_get_fake_result_decl (e->symtree->n.sym, 0);
1074 if (DECL_LANG_SPECIFIC (tmp) && GFC_DECL_SAVED_DESCRIPTOR (tmp))
1075 tmp = GFC_DECL_SAVED_DESCRIPTOR (tmp);
1077 slen = build_zero_cst (size_type_node);
1079 else
1081 /* Remove everything after the last class reference, convert the
1082 expression and then recover its tailend once more. */
1083 gfc_se tmpse;
1084 ref = class_ref->next;
1085 class_ref->next = NULL;
1086 gfc_init_se (&tmpse, NULL);
1087 gfc_conv_expr (&tmpse, e);
1088 class_ref->next = ref;
1089 tmp = tmpse.expr;
1090 slen = tmpse.string_length;
1093 gcc_assert (tmp != NULL_TREE);
1095 /* Dereference if needs be. */
1096 if (TREE_CODE (TREE_TYPE (tmp)) == REFERENCE_TYPE)
1097 tmp = build_fold_indirect_ref_loc (input_location, tmp);
1099 if (!(gfc_is_class_array_function (e) && parmse->class_vptr))
1100 vptr = gfc_class_vptr_get (tmp);
1101 else
1102 vptr = tmp;
1104 gfc_add_modify (&block, ctree,
1105 fold_convert (TREE_TYPE (ctree), vptr));
1107 /* Return the vptr 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, vptr,
1111 fold_convert (TREE_TYPE (vptr), ctree));
1113 /* For unlimited polymorphic objects also set the _len component. */
1114 if (class_ts.type == BT_CLASS
1115 && class_ts.u.derived->components
1116 && class_ts.u.derived->components->ts.u
1117 .derived->attr.unlimited_polymorphic)
1119 ctree = gfc_class_len_get (var);
1120 if (UNLIMITED_POLY (e))
1121 tmp = gfc_class_len_get (tmp);
1122 else if (e->ts.type == BT_CHARACTER)
1124 gcc_assert (slen != NULL_TREE);
1125 tmp = slen;
1127 else
1128 tmp = build_zero_cst (size_type_node);
1129 gfc_add_modify (&parmse->pre, ctree,
1130 fold_convert (TREE_TYPE (ctree), tmp));
1132 /* Return the len component, except in the case of scalarized array
1133 references, where the dynamic type cannot change. */
1134 if (!elemental && full_array && copyback)
1135 gfc_add_modify (&parmse->post, tmp,
1136 fold_convert (TREE_TYPE (tmp), ctree));
1139 if (optional)
1141 tree tmp2;
1143 cond = gfc_conv_expr_present (e->symtree->n.sym);
1144 /* parmse->pre may contain some preparatory instructions for the
1145 temporary array descriptor. Those may only be executed when the
1146 optional argument is set, therefore add parmse->pre's instructions
1147 to block, which is later guarded by an if (optional_arg_given). */
1148 gfc_add_block_to_block (&parmse->pre, &block);
1149 block.head = parmse->pre.head;
1150 parmse->pre.head = NULL_TREE;
1151 tmp = gfc_finish_block (&block);
1153 if (optional_alloc_ptr)
1154 tmp2 = build_empty_stmt (input_location);
1155 else
1157 gfc_init_block (&block);
1159 tmp2 = gfc_conv_descriptor_data_get (gfc_class_data_get (var));
1160 gfc_add_modify (&block, tmp2, fold_convert (TREE_TYPE (tmp2),
1161 null_pointer_node));
1162 tmp2 = gfc_finish_block (&block);
1165 tmp = build3_loc (input_location, COND_EXPR, void_type_node,
1166 cond, tmp, tmp2);
1167 gfc_add_expr_to_block (&parmse->pre, tmp);
1169 else
1170 gfc_add_block_to_block (&parmse->pre, &block);
1172 /* Pass the address of the class object. */
1173 parmse->expr = gfc_build_addr_expr (NULL_TREE, var);
1175 if (optional && optional_alloc_ptr)
1176 parmse->expr = build3_loc (input_location, COND_EXPR,
1177 TREE_TYPE (parmse->expr),
1178 cond, parmse->expr,
1179 fold_convert (TREE_TYPE (parmse->expr),
1180 null_pointer_node));
1184 /* Given a class array declaration and an index, returns the address
1185 of the referenced element. */
1187 tree
1188 gfc_get_class_array_ref (tree index, tree class_decl, tree data_comp,
1189 bool unlimited)
1191 tree data, size, tmp, ctmp, offset, ptr;
1193 data = data_comp != NULL_TREE ? data_comp :
1194 gfc_class_data_get (class_decl);
1195 size = gfc_class_vtab_size_get (class_decl);
1197 if (unlimited)
1199 tmp = fold_convert (gfc_array_index_type,
1200 gfc_class_len_get (class_decl));
1201 ctmp = fold_build2_loc (input_location, MULT_EXPR,
1202 gfc_array_index_type, size, tmp);
1203 tmp = fold_build2_loc (input_location, GT_EXPR,
1204 logical_type_node, tmp,
1205 build_zero_cst (TREE_TYPE (tmp)));
1206 size = fold_build3_loc (input_location, COND_EXPR,
1207 gfc_array_index_type, tmp, ctmp, size);
1210 offset = fold_build2_loc (input_location, MULT_EXPR,
1211 gfc_array_index_type,
1212 index, size);
1214 data = gfc_conv_descriptor_data_get (data);
1215 ptr = fold_convert (pvoid_type_node, data);
1216 ptr = fold_build_pointer_plus_loc (input_location, ptr, offset);
1217 return fold_convert (TREE_TYPE (data), ptr);
1221 /* Copies one class expression to another, assuming that if either
1222 'to' or 'from' are arrays they are packed. Should 'from' be
1223 NULL_TREE, the initialization expression for 'to' is used, assuming
1224 that the _vptr is set. */
1226 tree
1227 gfc_copy_class_to_class (tree from, tree to, tree nelems, bool unlimited)
1229 tree fcn;
1230 tree fcn_type;
1231 tree from_data;
1232 tree from_len;
1233 tree to_data;
1234 tree to_len;
1235 tree to_ref;
1236 tree from_ref;
1237 vec<tree, va_gc> *args;
1238 tree tmp;
1239 tree stdcopy;
1240 tree extcopy;
1241 tree index;
1242 bool is_from_desc = false, is_to_class = false;
1244 args = NULL;
1245 /* To prevent warnings on uninitialized variables. */
1246 from_len = to_len = NULL_TREE;
1248 if (from != NULL_TREE)
1249 fcn = gfc_class_vtab_copy_get (from);
1250 else
1251 fcn = gfc_class_vtab_copy_get (to);
1253 fcn_type = TREE_TYPE (TREE_TYPE (fcn));
1255 if (from != NULL_TREE)
1257 is_from_desc = GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (from));
1258 if (is_from_desc)
1260 from_data = from;
1261 from = GFC_DECL_SAVED_DESCRIPTOR (from);
1263 else
1265 /* Check that from is a class. When the class is part of a coarray,
1266 then from is a common pointer and is to be used as is. */
1267 tmp = POINTER_TYPE_P (TREE_TYPE (from))
1268 ? build_fold_indirect_ref (from) : from;
1269 from_data =
1270 (GFC_CLASS_TYPE_P (TREE_TYPE (tmp))
1271 || (DECL_P (tmp) && GFC_DECL_CLASS (tmp)))
1272 ? gfc_class_data_get (from) : from;
1273 is_from_desc = GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (from_data));
1276 else
1277 from_data = gfc_class_vtab_def_init_get (to);
1279 if (unlimited)
1281 if (from != NULL_TREE && unlimited)
1282 from_len = gfc_class_len_or_zero_get (from);
1283 else
1284 from_len = build_zero_cst (size_type_node);
1287 if (GFC_CLASS_TYPE_P (TREE_TYPE (to)))
1289 is_to_class = true;
1290 to_data = gfc_class_data_get (to);
1291 if (unlimited)
1292 to_len = gfc_class_len_get (to);
1294 else
1295 /* When to is a BT_DERIVED and not a BT_CLASS, then to_data == to. */
1296 to_data = to;
1298 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (to_data)))
1300 stmtblock_t loopbody;
1301 stmtblock_t body;
1302 stmtblock_t ifbody;
1303 gfc_loopinfo loop;
1304 tree orig_nelems = nelems; /* Needed for bounds check. */
1306 gfc_init_block (&body);
1307 tmp = fold_build2_loc (input_location, MINUS_EXPR,
1308 gfc_array_index_type, nelems,
1309 gfc_index_one_node);
1310 nelems = gfc_evaluate_now (tmp, &body);
1311 index = gfc_create_var (gfc_array_index_type, "S");
1313 if (is_from_desc)
1315 from_ref = gfc_get_class_array_ref (index, from, from_data,
1316 unlimited);
1317 vec_safe_push (args, from_ref);
1319 else
1320 vec_safe_push (args, from_data);
1322 if (is_to_class)
1323 to_ref = gfc_get_class_array_ref (index, to, to_data, unlimited);
1324 else
1326 tmp = gfc_conv_array_data (to);
1327 tmp = build_fold_indirect_ref_loc (input_location, tmp);
1328 to_ref = gfc_build_addr_expr (NULL_TREE,
1329 gfc_build_array_ref (tmp, index, to));
1331 vec_safe_push (args, to_ref);
1333 /* Add bounds check. */
1334 if ((gfc_option.rtcheck & GFC_RTCHECK_BOUNDS) > 0 && is_from_desc)
1336 char *msg;
1337 const char *name = "<<unknown>>";
1338 tree from_len;
1340 if (DECL_P (to))
1341 name = (const char *)(DECL_NAME (to)->identifier.id.str);
1343 from_len = gfc_conv_descriptor_size (from_data, 1);
1344 tmp = fold_build2_loc (input_location, NE_EXPR,
1345 logical_type_node, from_len, orig_nelems);
1346 msg = xasprintf ("Array bound mismatch for dimension %d "
1347 "of array '%s' (%%ld/%%ld)",
1348 1, name);
1350 gfc_trans_runtime_check (true, false, tmp, &body,
1351 &gfc_current_locus, msg,
1352 fold_convert (long_integer_type_node, orig_nelems),
1353 fold_convert (long_integer_type_node, from_len));
1355 free (msg);
1358 tmp = build_call_vec (fcn_type, fcn, args);
1360 /* Build the body of the loop. */
1361 gfc_init_block (&loopbody);
1362 gfc_add_expr_to_block (&loopbody, tmp);
1364 /* Build the loop and return. */
1365 gfc_init_loopinfo (&loop);
1366 loop.dimen = 1;
1367 loop.from[0] = gfc_index_zero_node;
1368 loop.loopvar[0] = index;
1369 loop.to[0] = nelems;
1370 gfc_trans_scalarizing_loops (&loop, &loopbody);
1371 gfc_init_block (&ifbody);
1372 gfc_add_block_to_block (&ifbody, &loop.pre);
1373 stdcopy = gfc_finish_block (&ifbody);
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 tmp = build_call_vec (fcn_type, fcn, args);
1380 /* Build the body of the loop. */
1381 gfc_init_block (&loopbody);
1382 gfc_add_expr_to_block (&loopbody, tmp);
1384 /* Build the loop and return. */
1385 gfc_init_loopinfo (&loop);
1386 loop.dimen = 1;
1387 loop.from[0] = gfc_index_zero_node;
1388 loop.loopvar[0] = index;
1389 loop.to[0] = nelems;
1390 gfc_trans_scalarizing_loops (&loop, &loopbody);
1391 gfc_init_block (&ifbody);
1392 gfc_add_block_to_block (&ifbody, &loop.pre);
1393 extcopy = gfc_finish_block (&ifbody);
1395 tmp = fold_build2_loc (input_location, GT_EXPR,
1396 logical_type_node, from_len,
1397 build_zero_cst (TREE_TYPE (from_len)));
1398 tmp = fold_build3_loc (input_location, COND_EXPR,
1399 void_type_node, tmp, extcopy, stdcopy);
1400 gfc_add_expr_to_block (&body, tmp);
1401 tmp = gfc_finish_block (&body);
1403 else
1405 gfc_add_expr_to_block (&body, stdcopy);
1406 tmp = gfc_finish_block (&body);
1408 gfc_cleanup_loop (&loop);
1410 else
1412 gcc_assert (!is_from_desc);
1413 vec_safe_push (args, from_data);
1414 vec_safe_push (args, to_data);
1415 stdcopy = build_call_vec (fcn_type, fcn, args);
1417 /* In initialization mode from_len is a constant zero. */
1418 if (unlimited && !integer_zerop (from_len))
1420 vec_safe_push (args, from_len);
1421 vec_safe_push (args, to_len);
1422 extcopy = build_call_vec (fcn_type, fcn, args);
1423 tmp = fold_build2_loc (input_location, GT_EXPR,
1424 logical_type_node, from_len,
1425 build_zero_cst (TREE_TYPE (from_len)));
1426 tmp = fold_build3_loc (input_location, COND_EXPR,
1427 void_type_node, tmp, extcopy, stdcopy);
1429 else
1430 tmp = stdcopy;
1433 /* Only copy _def_init to to_data, when it is not a NULL-pointer. */
1434 if (from == NULL_TREE)
1436 tree cond;
1437 cond = fold_build2_loc (input_location, NE_EXPR,
1438 logical_type_node,
1439 from_data, null_pointer_node);
1440 tmp = fold_build3_loc (input_location, COND_EXPR,
1441 void_type_node, cond,
1442 tmp, build_empty_stmt (input_location));
1445 return tmp;
1449 static tree
1450 gfc_trans_class_array_init_assign (gfc_expr *rhs, gfc_expr *lhs, gfc_expr *obj)
1452 gfc_actual_arglist *actual;
1453 gfc_expr *ppc;
1454 gfc_code *ppc_code;
1455 tree res;
1457 actual = gfc_get_actual_arglist ();
1458 actual->expr = gfc_copy_expr (rhs);
1459 actual->next = gfc_get_actual_arglist ();
1460 actual->next->expr = gfc_copy_expr (lhs);
1461 ppc = gfc_copy_expr (obj);
1462 gfc_add_vptr_component (ppc);
1463 gfc_add_component_ref (ppc, "_copy");
1464 ppc_code = gfc_get_code (EXEC_CALL);
1465 ppc_code->resolved_sym = ppc->symtree->n.sym;
1466 /* Although '_copy' is set to be elemental in class.c, it is
1467 not staying that way. Find out why, sometime.... */
1468 ppc_code->resolved_sym->attr.elemental = 1;
1469 ppc_code->ext.actual = actual;
1470 ppc_code->expr1 = ppc;
1471 /* Since '_copy' is elemental, the scalarizer will take care
1472 of arrays in gfc_trans_call. */
1473 res = gfc_trans_call (ppc_code, false, NULL, NULL, false);
1474 gfc_free_statements (ppc_code);
1476 if (UNLIMITED_POLY(obj))
1478 /* Check if rhs is non-NULL. */
1479 gfc_se src;
1480 gfc_init_se (&src, NULL);
1481 gfc_conv_expr (&src, rhs);
1482 src.expr = gfc_build_addr_expr (NULL_TREE, src.expr);
1483 tree cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
1484 src.expr, fold_convert (TREE_TYPE (src.expr),
1485 null_pointer_node));
1486 res = build3_loc (input_location, COND_EXPR, TREE_TYPE (res), cond, res,
1487 build_empty_stmt (input_location));
1490 return res;
1493 /* Special case for initializing a polymorphic dummy with INTENT(OUT).
1494 A MEMCPY is needed to copy the full data from the default initializer
1495 of the dynamic type. */
1497 tree
1498 gfc_trans_class_init_assign (gfc_code *code)
1500 stmtblock_t block;
1501 tree tmp;
1502 gfc_se dst,src,memsz;
1503 gfc_expr *lhs, *rhs, *sz;
1505 gfc_start_block (&block);
1507 lhs = gfc_copy_expr (code->expr1);
1509 rhs = gfc_copy_expr (code->expr1);
1510 gfc_add_vptr_component (rhs);
1512 /* Make sure that the component backend_decls have been built, which
1513 will not have happened if the derived types concerned have not
1514 been referenced. */
1515 gfc_get_derived_type (rhs->ts.u.derived);
1516 gfc_add_def_init_component (rhs);
1517 /* The _def_init is always scalar. */
1518 rhs->rank = 0;
1520 if (code->expr1->ts.type == BT_CLASS
1521 && CLASS_DATA (code->expr1)->attr.dimension)
1523 gfc_array_spec *tmparr = gfc_get_array_spec ();
1524 *tmparr = *CLASS_DATA (code->expr1)->as;
1525 /* Adding the array ref to the class expression results in correct
1526 indexing to the dynamic type. */
1527 gfc_add_full_array_ref (lhs, tmparr);
1528 tmp = gfc_trans_class_array_init_assign (rhs, lhs, code->expr1);
1530 else
1532 /* Scalar initialization needs the _data component. */
1533 gfc_add_data_component (lhs);
1534 sz = gfc_copy_expr (code->expr1);
1535 gfc_add_vptr_component (sz);
1536 gfc_add_size_component (sz);
1538 gfc_init_se (&dst, NULL);
1539 gfc_init_se (&src, NULL);
1540 gfc_init_se (&memsz, NULL);
1541 gfc_conv_expr (&dst, lhs);
1542 gfc_conv_expr (&src, rhs);
1543 gfc_conv_expr (&memsz, sz);
1544 gfc_add_block_to_block (&block, &src.pre);
1545 src.expr = gfc_build_addr_expr (NULL_TREE, src.expr);
1547 tmp = gfc_build_memcpy_call (dst.expr, src.expr, memsz.expr);
1549 if (UNLIMITED_POLY(code->expr1))
1551 /* Check if _def_init is non-NULL. */
1552 tree cond = fold_build2_loc (input_location, NE_EXPR,
1553 logical_type_node, src.expr,
1554 fold_convert (TREE_TYPE (src.expr),
1555 null_pointer_node));
1556 tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp), cond,
1557 tmp, build_empty_stmt (input_location));
1561 if (code->expr1->symtree->n.sym->attr.optional
1562 || code->expr1->symtree->n.sym->ns->proc_name->attr.entry_master)
1564 tree present = gfc_conv_expr_present (code->expr1->symtree->n.sym);
1565 tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp),
1566 present, tmp,
1567 build_empty_stmt (input_location));
1570 gfc_add_expr_to_block (&block, tmp);
1572 return gfc_finish_block (&block);
1576 /* End of prototype trans-class.c */
1579 static void
1580 realloc_lhs_warning (bt type, bool array, locus *where)
1582 if (array && type != BT_CLASS && type != BT_DERIVED && warn_realloc_lhs)
1583 gfc_warning (OPT_Wrealloc_lhs,
1584 "Code for reallocating the allocatable array at %L will "
1585 "be added", where);
1586 else if (warn_realloc_lhs_all)
1587 gfc_warning (OPT_Wrealloc_lhs_all,
1588 "Code for reallocating the allocatable variable at %L "
1589 "will be added", where);
1593 static void gfc_apply_interface_mapping_to_expr (gfc_interface_mapping *,
1594 gfc_expr *);
1596 /* Copy the scalarization loop variables. */
1598 static void
1599 gfc_copy_se_loopvars (gfc_se * dest, gfc_se * src)
1601 dest->ss = src->ss;
1602 dest->loop = src->loop;
1606 /* Initialize a simple expression holder.
1608 Care must be taken when multiple se are created with the same parent.
1609 The child se must be kept in sync. The easiest way is to delay creation
1610 of a child se until after after the previous se has been translated. */
1612 void
1613 gfc_init_se (gfc_se * se, gfc_se * parent)
1615 memset (se, 0, sizeof (gfc_se));
1616 gfc_init_block (&se->pre);
1617 gfc_init_block (&se->post);
1619 se->parent = parent;
1621 if (parent)
1622 gfc_copy_se_loopvars (se, parent);
1626 /* Advances to the next SS in the chain. Use this rather than setting
1627 se->ss = se->ss->next because all the parents needs to be kept in sync.
1628 See gfc_init_se. */
1630 void
1631 gfc_advance_se_ss_chain (gfc_se * se)
1633 gfc_se *p;
1634 gfc_ss *ss;
1636 gcc_assert (se != NULL && se->ss != NULL && se->ss != gfc_ss_terminator);
1638 p = se;
1639 /* Walk down the parent chain. */
1640 while (p != NULL)
1642 /* Simple consistency check. */
1643 gcc_assert (p->parent == NULL || p->parent->ss == p->ss
1644 || p->parent->ss->nested_ss == p->ss);
1646 /* If we were in a nested loop, the next scalarized expression can be
1647 on the parent ss' next pointer. Thus we should not take the next
1648 pointer blindly, but rather go up one nest level as long as next
1649 is the end of chain. */
1650 ss = p->ss;
1651 while (ss->next == gfc_ss_terminator && ss->parent != NULL)
1652 ss = ss->parent;
1654 p->ss = ss->next;
1656 p = p->parent;
1661 /* Ensures the result of the expression as either a temporary variable
1662 or a constant so that it can be used repeatedly. */
1664 void
1665 gfc_make_safe_expr (gfc_se * se)
1667 tree var;
1669 if (CONSTANT_CLASS_P (se->expr))
1670 return;
1672 /* We need a temporary for this result. */
1673 var = gfc_create_var (TREE_TYPE (se->expr), NULL);
1674 gfc_add_modify (&se->pre, var, se->expr);
1675 se->expr = var;
1679 /* Return an expression which determines if a dummy parameter is present.
1680 Also used for arguments to procedures with multiple entry points. */
1682 tree
1683 gfc_conv_expr_present (gfc_symbol * sym)
1685 tree decl, cond;
1687 gcc_assert (sym->attr.dummy);
1688 decl = gfc_get_symbol_decl (sym);
1690 /* Intrinsic scalars with VALUE attribute which are passed by value
1691 use a hidden argument to denote the present status. */
1692 if (sym->attr.value && sym->ts.type != BT_CHARACTER
1693 && sym->ts.type != BT_CLASS && sym->ts.type != BT_DERIVED
1694 && !sym->attr.dimension)
1696 char name[GFC_MAX_SYMBOL_LEN + 2];
1697 tree tree_name;
1699 gcc_assert (TREE_CODE (decl) == PARM_DECL);
1700 name[0] = '_';
1701 strcpy (&name[1], sym->name);
1702 tree_name = get_identifier (name);
1704 /* Walk function argument list to find hidden arg. */
1705 cond = DECL_ARGUMENTS (DECL_CONTEXT (decl));
1706 for ( ; cond != NULL_TREE; cond = TREE_CHAIN (cond))
1707 if (DECL_NAME (cond) == tree_name)
1708 break;
1710 gcc_assert (cond);
1711 return cond;
1714 if (TREE_CODE (decl) != PARM_DECL)
1716 /* Array parameters use a temporary descriptor, we want the real
1717 parameter. */
1718 gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl))
1719 || GFC_ARRAY_TYPE_P (TREE_TYPE (decl)));
1720 decl = GFC_DECL_SAVED_DESCRIPTOR (decl);
1723 cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node, decl,
1724 fold_convert (TREE_TYPE (decl), null_pointer_node));
1726 /* Fortran 2008 allows to pass null pointers and non-associated pointers
1727 as actual argument to denote absent dummies. For array descriptors,
1728 we thus also need to check the array descriptor. For BT_CLASS, it
1729 can also occur for scalars and F2003 due to type->class wrapping and
1730 class->class wrapping. Note further that BT_CLASS always uses an
1731 array descriptor for arrays, also for explicit-shape/assumed-size. */
1733 if (!sym->attr.allocatable
1734 && ((sym->ts.type != BT_CLASS && !sym->attr.pointer)
1735 || (sym->ts.type == BT_CLASS
1736 && !CLASS_DATA (sym)->attr.allocatable
1737 && !CLASS_DATA (sym)->attr.class_pointer))
1738 && ((gfc_option.allow_std & GFC_STD_F2008) != 0
1739 || sym->ts.type == BT_CLASS))
1741 tree tmp;
1743 if ((sym->as && (sym->as->type == AS_ASSUMED_SHAPE
1744 || sym->as->type == AS_ASSUMED_RANK
1745 || sym->attr.codimension))
1746 || (sym->ts.type == BT_CLASS && CLASS_DATA (sym)->as))
1748 tmp = build_fold_indirect_ref_loc (input_location, decl);
1749 if (sym->ts.type == BT_CLASS)
1750 tmp = gfc_class_data_get (tmp);
1751 tmp = gfc_conv_array_data (tmp);
1753 else if (sym->ts.type == BT_CLASS)
1754 tmp = gfc_class_data_get (decl);
1755 else
1756 tmp = NULL_TREE;
1758 if (tmp != NULL_TREE)
1760 tmp = fold_build2_loc (input_location, NE_EXPR, logical_type_node, tmp,
1761 fold_convert (TREE_TYPE (tmp), null_pointer_node));
1762 cond = fold_build2_loc (input_location, TRUTH_ANDIF_EXPR,
1763 logical_type_node, cond, tmp);
1767 return cond;
1771 /* Converts a missing, dummy argument into a null or zero. */
1773 void
1774 gfc_conv_missing_dummy (gfc_se * se, gfc_expr * arg, gfc_typespec ts, int kind)
1776 tree present;
1777 tree tmp;
1779 present = gfc_conv_expr_present (arg->symtree->n.sym);
1781 if (kind > 0)
1783 /* Create a temporary and convert it to the correct type. */
1784 tmp = gfc_get_int_type (kind);
1785 tmp = fold_convert (tmp, build_fold_indirect_ref_loc (input_location,
1786 se->expr));
1788 /* Test for a NULL value. */
1789 tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp), present,
1790 tmp, fold_convert (TREE_TYPE (tmp), integer_one_node));
1791 tmp = gfc_evaluate_now (tmp, &se->pre);
1792 se->expr = gfc_build_addr_expr (NULL_TREE, tmp);
1794 else
1796 tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (se->expr),
1797 present, se->expr,
1798 build_zero_cst (TREE_TYPE (se->expr)));
1799 tmp = gfc_evaluate_now (tmp, &se->pre);
1800 se->expr = tmp;
1803 if (ts.type == BT_CHARACTER)
1805 tmp = build_int_cst (gfc_charlen_type_node, 0);
1806 tmp = fold_build3_loc (input_location, COND_EXPR, gfc_charlen_type_node,
1807 present, se->string_length, tmp);
1808 tmp = gfc_evaluate_now (tmp, &se->pre);
1809 se->string_length = tmp;
1811 return;
1815 /* Get the character length of an expression, looking through gfc_refs
1816 if necessary. */
1818 tree
1819 gfc_get_expr_charlen (gfc_expr *e)
1821 gfc_ref *r;
1822 tree length;
1824 gcc_assert (e->expr_type == EXPR_VARIABLE
1825 && e->ts.type == BT_CHARACTER);
1827 length = NULL; /* To silence compiler warning. */
1829 if (is_subref_array (e) && e->ts.u.cl->length)
1831 gfc_se tmpse;
1832 gfc_init_se (&tmpse, NULL);
1833 gfc_conv_expr_type (&tmpse, e->ts.u.cl->length, gfc_charlen_type_node);
1834 e->ts.u.cl->backend_decl = tmpse.expr;
1835 return tmpse.expr;
1838 /* First candidate: if the variable is of type CHARACTER, the
1839 expression's length could be the length of the character
1840 variable. */
1841 if (e->symtree->n.sym->ts.type == BT_CHARACTER)
1842 length = e->symtree->n.sym->ts.u.cl->backend_decl;
1844 /* Look through the reference chain for component references. */
1845 for (r = e->ref; r; r = r->next)
1847 switch (r->type)
1849 case REF_COMPONENT:
1850 if (r->u.c.component->ts.type == BT_CHARACTER)
1851 length = r->u.c.component->ts.u.cl->backend_decl;
1852 break;
1854 case REF_ARRAY:
1855 /* Do nothing. */
1856 break;
1858 default:
1859 /* We should never got substring references here. These will be
1860 broken down by the scalarizer. */
1861 gcc_unreachable ();
1862 break;
1866 gcc_assert (length != NULL);
1867 return length;
1871 /* Return for an expression the backend decl of the coarray. */
1873 tree
1874 gfc_get_tree_for_caf_expr (gfc_expr *expr)
1876 tree caf_decl;
1877 bool found = false;
1878 gfc_ref *ref;
1880 gcc_assert (expr && expr->expr_type == EXPR_VARIABLE);
1882 /* Not-implemented diagnostic. */
1883 if (expr->symtree->n.sym->ts.type == BT_CLASS
1884 && UNLIMITED_POLY (expr->symtree->n.sym)
1885 && CLASS_DATA (expr->symtree->n.sym)->attr.codimension)
1886 gfc_error ("Sorry, coindexed access to an unlimited polymorphic object at "
1887 "%L is not supported", &expr->where);
1889 for (ref = expr->ref; ref; ref = ref->next)
1890 if (ref->type == REF_COMPONENT)
1892 if (ref->u.c.component->ts.type == BT_CLASS
1893 && UNLIMITED_POLY (ref->u.c.component)
1894 && CLASS_DATA (ref->u.c.component)->attr.codimension)
1895 gfc_error ("Sorry, coindexed access to an unlimited polymorphic "
1896 "component at %L is not supported", &expr->where);
1899 /* Make sure the backend_decl is present before accessing it. */
1900 caf_decl = expr->symtree->n.sym->backend_decl == NULL_TREE
1901 ? gfc_get_symbol_decl (expr->symtree->n.sym)
1902 : expr->symtree->n.sym->backend_decl;
1904 if (expr->symtree->n.sym->ts.type == BT_CLASS)
1906 if (expr->ref && expr->ref->type == REF_ARRAY)
1908 caf_decl = gfc_class_data_get (caf_decl);
1909 if (CLASS_DATA (expr->symtree->n.sym)->attr.codimension)
1910 return caf_decl;
1912 for (ref = expr->ref; ref; ref = ref->next)
1914 if (ref->type == REF_COMPONENT
1915 && strcmp (ref->u.c.component->name, "_data") != 0)
1917 caf_decl = gfc_class_data_get (caf_decl);
1918 if (CLASS_DATA (expr->symtree->n.sym)->attr.codimension)
1919 return caf_decl;
1920 break;
1922 else if (ref->type == REF_ARRAY && ref->u.ar.dimen)
1923 break;
1926 if (expr->symtree->n.sym->attr.codimension)
1927 return caf_decl;
1929 /* The following code assumes that the coarray is a component reachable via
1930 only scalar components/variables; the Fortran standard guarantees this. */
1932 for (ref = expr->ref; ref; ref = ref->next)
1933 if (ref->type == REF_COMPONENT)
1935 gfc_component *comp = ref->u.c.component;
1937 if (POINTER_TYPE_P (TREE_TYPE (caf_decl)))
1938 caf_decl = build_fold_indirect_ref_loc (input_location, caf_decl);
1939 caf_decl = fold_build3_loc (input_location, COMPONENT_REF,
1940 TREE_TYPE (comp->backend_decl), caf_decl,
1941 comp->backend_decl, NULL_TREE);
1942 if (comp->ts.type == BT_CLASS)
1944 caf_decl = gfc_class_data_get (caf_decl);
1945 if (CLASS_DATA (comp)->attr.codimension)
1947 found = true;
1948 break;
1951 if (comp->attr.codimension)
1953 found = true;
1954 break;
1957 gcc_assert (found && caf_decl);
1958 return caf_decl;
1962 /* Obtain the Coarray token - and optionally also the offset. */
1964 void
1965 gfc_get_caf_token_offset (gfc_se *se, tree *token, tree *offset, tree caf_decl,
1966 tree se_expr, gfc_expr *expr)
1968 tree tmp;
1970 /* Coarray token. */
1971 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (caf_decl)))
1973 gcc_assert (GFC_TYPE_ARRAY_AKIND (TREE_TYPE (caf_decl))
1974 == GFC_ARRAY_ALLOCATABLE
1975 || expr->symtree->n.sym->attr.select_type_temporary);
1976 *token = gfc_conv_descriptor_token (caf_decl);
1978 else if (DECL_LANG_SPECIFIC (caf_decl)
1979 && GFC_DECL_TOKEN (caf_decl) != NULL_TREE)
1980 *token = GFC_DECL_TOKEN (caf_decl);
1981 else
1983 gcc_assert (GFC_ARRAY_TYPE_P (TREE_TYPE (caf_decl))
1984 && GFC_TYPE_ARRAY_CAF_TOKEN (TREE_TYPE (caf_decl)) != NULL_TREE);
1985 *token = GFC_TYPE_ARRAY_CAF_TOKEN (TREE_TYPE (caf_decl));
1988 if (offset == NULL)
1989 return;
1991 /* Offset between the coarray base address and the address wanted. */
1992 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (caf_decl))
1993 && (GFC_TYPE_ARRAY_AKIND (TREE_TYPE (caf_decl)) == GFC_ARRAY_ALLOCATABLE
1994 || GFC_TYPE_ARRAY_AKIND (TREE_TYPE (caf_decl)) == GFC_ARRAY_POINTER))
1995 *offset = build_int_cst (gfc_array_index_type, 0);
1996 else if (DECL_LANG_SPECIFIC (caf_decl)
1997 && GFC_DECL_CAF_OFFSET (caf_decl) != NULL_TREE)
1998 *offset = GFC_DECL_CAF_OFFSET (caf_decl);
1999 else if (GFC_TYPE_ARRAY_CAF_OFFSET (TREE_TYPE (caf_decl)) != NULL_TREE)
2000 *offset = GFC_TYPE_ARRAY_CAF_OFFSET (TREE_TYPE (caf_decl));
2001 else
2002 *offset = build_int_cst (gfc_array_index_type, 0);
2004 if (POINTER_TYPE_P (TREE_TYPE (se_expr))
2005 && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (TREE_TYPE (se_expr))))
2007 tmp = build_fold_indirect_ref_loc (input_location, se_expr);
2008 tmp = gfc_conv_descriptor_data_get (tmp);
2010 else if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se_expr)))
2011 tmp = gfc_conv_descriptor_data_get (se_expr);
2012 else
2014 gcc_assert (POINTER_TYPE_P (TREE_TYPE (se_expr)));
2015 tmp = se_expr;
2018 *offset = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
2019 *offset, fold_convert (gfc_array_index_type, tmp));
2021 if (expr->symtree->n.sym->ts.type == BT_DERIVED
2022 && expr->symtree->n.sym->attr.codimension
2023 && expr->symtree->n.sym->ts.u.derived->attr.alloc_comp)
2025 gfc_expr *base_expr = gfc_copy_expr (expr);
2026 gfc_ref *ref = base_expr->ref;
2027 gfc_se base_se;
2029 // Iterate through the refs until the last one.
2030 while (ref->next)
2031 ref = ref->next;
2033 if (ref->type == REF_ARRAY
2034 && ref->u.ar.type != AR_FULL)
2036 const int ranksum = ref->u.ar.dimen + ref->u.ar.codimen;
2037 int i;
2038 for (i = 0; i < ranksum; ++i)
2040 ref->u.ar.start[i] = NULL;
2041 ref->u.ar.end[i] = NULL;
2043 ref->u.ar.type = AR_FULL;
2045 gfc_init_se (&base_se, NULL);
2046 if (gfc_caf_attr (base_expr).dimension)
2048 gfc_conv_expr_descriptor (&base_se, base_expr);
2049 tmp = gfc_conv_descriptor_data_get (base_se.expr);
2051 else
2053 gfc_conv_expr (&base_se, base_expr);
2054 tmp = base_se.expr;
2057 gfc_free_expr (base_expr);
2058 gfc_add_block_to_block (&se->pre, &base_se.pre);
2059 gfc_add_block_to_block (&se->post, &base_se.post);
2061 else if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (caf_decl)))
2062 tmp = gfc_conv_descriptor_data_get (caf_decl);
2063 else
2065 gcc_assert (POINTER_TYPE_P (TREE_TYPE (caf_decl)));
2066 tmp = caf_decl;
2069 *offset = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
2070 fold_convert (gfc_array_index_type, *offset),
2071 fold_convert (gfc_array_index_type, tmp));
2075 /* Convert the coindex of a coarray into an image index; the result is
2076 image_num = (idx(1)-lcobound(1)+1) + (idx(2)-lcobound(2))*extent(1)
2077 + (idx(3)-lcobound(3))*extend(1)*extent(2) + ... */
2079 tree
2080 gfc_caf_get_image_index (stmtblock_t *block, gfc_expr *e, tree desc)
2082 gfc_ref *ref;
2083 tree lbound, ubound, extent, tmp, img_idx;
2084 gfc_se se;
2085 int i;
2087 for (ref = e->ref; ref; ref = ref->next)
2088 if (ref->type == REF_ARRAY && ref->u.ar.codimen > 0)
2089 break;
2090 gcc_assert (ref != NULL);
2092 if (ref->u.ar.dimen_type[ref->u.ar.dimen] == DIMEN_THIS_IMAGE)
2094 return build_call_expr_loc (input_location, gfor_fndecl_caf_this_image, 1,
2095 integer_zero_node);
2098 img_idx = integer_zero_node;
2099 extent = integer_one_node;
2100 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (desc)))
2101 for (i = ref->u.ar.dimen; i < ref->u.ar.dimen + ref->u.ar.codimen; i++)
2103 gfc_init_se (&se, NULL);
2104 gfc_conv_expr_type (&se, ref->u.ar.start[i], integer_type_node);
2105 gfc_add_block_to_block (block, &se.pre);
2106 lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[i]);
2107 tmp = fold_build2_loc (input_location, MINUS_EXPR,
2108 integer_type_node, se.expr,
2109 fold_convert(integer_type_node, lbound));
2110 tmp = fold_build2_loc (input_location, MULT_EXPR, integer_type_node,
2111 extent, tmp);
2112 img_idx = fold_build2_loc (input_location, PLUS_EXPR, integer_type_node,
2113 img_idx, tmp);
2114 if (i < ref->u.ar.dimen + ref->u.ar.codimen - 1)
2116 ubound = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[i]);
2117 tmp = gfc_conv_array_extent_dim (lbound, ubound, NULL);
2118 tmp = fold_convert (integer_type_node, tmp);
2119 extent = fold_build2_loc (input_location, MULT_EXPR,
2120 integer_type_node, extent, tmp);
2123 else
2124 for (i = ref->u.ar.dimen; i < ref->u.ar.dimen + ref->u.ar.codimen; i++)
2126 gfc_init_se (&se, NULL);
2127 gfc_conv_expr_type (&se, ref->u.ar.start[i], integer_type_node);
2128 gfc_add_block_to_block (block, &se.pre);
2129 lbound = GFC_TYPE_ARRAY_LBOUND (TREE_TYPE (desc), i);
2130 lbound = fold_convert (integer_type_node, lbound);
2131 tmp = fold_build2_loc (input_location, MINUS_EXPR,
2132 integer_type_node, se.expr, lbound);
2133 tmp = fold_build2_loc (input_location, MULT_EXPR, integer_type_node,
2134 extent, tmp);
2135 img_idx = fold_build2_loc (input_location, PLUS_EXPR, integer_type_node,
2136 img_idx, tmp);
2137 if (i < ref->u.ar.dimen + ref->u.ar.codimen - 1)
2139 ubound = GFC_TYPE_ARRAY_UBOUND (TREE_TYPE (desc), i);
2140 ubound = fold_convert (integer_type_node, ubound);
2141 tmp = fold_build2_loc (input_location, MINUS_EXPR,
2142 integer_type_node, ubound, lbound);
2143 tmp = fold_build2_loc (input_location, PLUS_EXPR, integer_type_node,
2144 tmp, integer_one_node);
2145 extent = fold_build2_loc (input_location, MULT_EXPR,
2146 integer_type_node, extent, tmp);
2149 img_idx = fold_build2_loc (input_location, PLUS_EXPR, integer_type_node,
2150 img_idx, integer_one_node);
2151 return img_idx;
2155 /* For each character array constructor subexpression without a ts.u.cl->length,
2156 replace it by its first element (if there aren't any elements, the length
2157 should already be set to zero). */
2159 static void
2160 flatten_array_ctors_without_strlen (gfc_expr* e)
2162 gfc_actual_arglist* arg;
2163 gfc_constructor* c;
2165 if (!e)
2166 return;
2168 switch (e->expr_type)
2171 case EXPR_OP:
2172 flatten_array_ctors_without_strlen (e->value.op.op1);
2173 flatten_array_ctors_without_strlen (e->value.op.op2);
2174 break;
2176 case EXPR_COMPCALL:
2177 /* TODO: Implement as with EXPR_FUNCTION when needed. */
2178 gcc_unreachable ();
2180 case EXPR_FUNCTION:
2181 for (arg = e->value.function.actual; arg; arg = arg->next)
2182 flatten_array_ctors_without_strlen (arg->expr);
2183 break;
2185 case EXPR_ARRAY:
2187 /* We've found what we're looking for. */
2188 if (e->ts.type == BT_CHARACTER && !e->ts.u.cl->length)
2190 gfc_constructor *c;
2191 gfc_expr* new_expr;
2193 gcc_assert (e->value.constructor);
2195 c = gfc_constructor_first (e->value.constructor);
2196 new_expr = c->expr;
2197 c->expr = NULL;
2199 flatten_array_ctors_without_strlen (new_expr);
2200 gfc_replace_expr (e, new_expr);
2201 break;
2204 /* Otherwise, fall through to handle constructor elements. */
2205 gcc_fallthrough ();
2206 case EXPR_STRUCTURE:
2207 for (c = gfc_constructor_first (e->value.constructor);
2208 c; c = gfc_constructor_next (c))
2209 flatten_array_ctors_without_strlen (c->expr);
2210 break;
2212 default:
2213 break;
2219 /* Generate code to initialize a string length variable. Returns the
2220 value. For array constructors, cl->length might be NULL and in this case,
2221 the first element of the constructor is needed. expr is the original
2222 expression so we can access it but can be NULL if this is not needed. */
2224 void
2225 gfc_conv_string_length (gfc_charlen * cl, gfc_expr * expr, stmtblock_t * pblock)
2227 gfc_se se;
2229 gfc_init_se (&se, NULL);
2231 if (!cl->length && cl->backend_decl && VAR_P (cl->backend_decl))
2232 return;
2234 /* If cl->length is NULL, use gfc_conv_expr to obtain the string length but
2235 "flatten" array constructors by taking their first element; all elements
2236 should be the same length or a cl->length should be present. */
2237 if (!cl->length)
2239 gfc_expr* expr_flat;
2240 if (!expr)
2241 return;
2242 expr_flat = gfc_copy_expr (expr);
2243 flatten_array_ctors_without_strlen (expr_flat);
2244 gfc_resolve_expr (expr_flat);
2246 gfc_conv_expr (&se, expr_flat);
2247 gfc_add_block_to_block (pblock, &se.pre);
2248 cl->backend_decl = convert (gfc_charlen_type_node, se.string_length);
2250 gfc_free_expr (expr_flat);
2251 return;
2254 /* Convert cl->length. */
2256 gcc_assert (cl->length);
2258 gfc_conv_expr_type (&se, cl->length, gfc_charlen_type_node);
2259 se.expr = fold_build2_loc (input_location, MAX_EXPR, gfc_charlen_type_node,
2260 se.expr, build_zero_cst (TREE_TYPE (se.expr)));
2261 gfc_add_block_to_block (pblock, &se.pre);
2263 if (cl->backend_decl)
2264 gfc_add_modify (pblock, cl->backend_decl, se.expr);
2265 else
2266 cl->backend_decl = gfc_evaluate_now (se.expr, pblock);
2270 static void
2271 gfc_conv_substring (gfc_se * se, gfc_ref * ref, int kind,
2272 const char *name, locus *where)
2274 tree tmp;
2275 tree type;
2276 tree fault;
2277 gfc_se start;
2278 gfc_se end;
2279 char *msg;
2280 mpz_t length;
2282 type = gfc_get_character_type (kind, ref->u.ss.length);
2283 type = build_pointer_type (type);
2285 gfc_init_se (&start, se);
2286 gfc_conv_expr_type (&start, ref->u.ss.start, gfc_charlen_type_node);
2287 gfc_add_block_to_block (&se->pre, &start.pre);
2289 if (integer_onep (start.expr))
2290 gfc_conv_string_parameter (se);
2291 else
2293 tmp = start.expr;
2294 STRIP_NOPS (tmp);
2295 /* Avoid multiple evaluation of substring start. */
2296 if (!CONSTANT_CLASS_P (tmp) && !DECL_P (tmp))
2297 start.expr = gfc_evaluate_now (start.expr, &se->pre);
2299 /* Change the start of the string. */
2300 if (TYPE_STRING_FLAG (TREE_TYPE (se->expr)))
2301 tmp = se->expr;
2302 else
2303 tmp = build_fold_indirect_ref_loc (input_location,
2304 se->expr);
2305 tmp = gfc_build_array_ref (tmp, start.expr, NULL);
2306 se->expr = gfc_build_addr_expr (type, tmp);
2309 /* Length = end + 1 - start. */
2310 gfc_init_se (&end, se);
2311 if (ref->u.ss.end == NULL)
2312 end.expr = se->string_length;
2313 else
2315 gfc_conv_expr_type (&end, ref->u.ss.end, gfc_charlen_type_node);
2316 gfc_add_block_to_block (&se->pre, &end.pre);
2318 tmp = end.expr;
2319 STRIP_NOPS (tmp);
2320 if (!CONSTANT_CLASS_P (tmp) && !DECL_P (tmp))
2321 end.expr = gfc_evaluate_now (end.expr, &se->pre);
2323 if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
2325 tree nonempty = fold_build2_loc (input_location, LE_EXPR,
2326 logical_type_node, start.expr,
2327 end.expr);
2329 /* Check lower bound. */
2330 fault = fold_build2_loc (input_location, LT_EXPR, logical_type_node,
2331 start.expr,
2332 build_one_cst (TREE_TYPE (start.expr)));
2333 fault = fold_build2_loc (input_location, TRUTH_ANDIF_EXPR,
2334 logical_type_node, nonempty, fault);
2335 if (name)
2336 msg = xasprintf ("Substring out of bounds: lower bound (%%ld) of '%s' "
2337 "is less than one", name);
2338 else
2339 msg = xasprintf ("Substring out of bounds: lower bound (%%ld) "
2340 "is less than one");
2341 gfc_trans_runtime_check (true, false, fault, &se->pre, where, msg,
2342 fold_convert (long_integer_type_node,
2343 start.expr));
2344 free (msg);
2346 /* Check upper bound. */
2347 fault = fold_build2_loc (input_location, GT_EXPR, logical_type_node,
2348 end.expr, se->string_length);
2349 fault = fold_build2_loc (input_location, TRUTH_ANDIF_EXPR,
2350 logical_type_node, nonempty, fault);
2351 if (name)
2352 msg = xasprintf ("Substring out of bounds: upper bound (%%ld) of '%s' "
2353 "exceeds string length (%%ld)", name);
2354 else
2355 msg = xasprintf ("Substring out of bounds: upper bound (%%ld) "
2356 "exceeds string length (%%ld)");
2357 gfc_trans_runtime_check (true, false, fault, &se->pre, where, msg,
2358 fold_convert (long_integer_type_node, end.expr),
2359 fold_convert (long_integer_type_node,
2360 se->string_length));
2361 free (msg);
2364 /* Try to calculate the length from the start and end expressions. */
2365 if (ref->u.ss.end
2366 && gfc_dep_difference (ref->u.ss.end, ref->u.ss.start, &length))
2368 HOST_WIDE_INT i_len;
2370 i_len = gfc_mpz_get_hwi (length) + 1;
2371 if (i_len < 0)
2372 i_len = 0;
2374 tmp = build_int_cst (gfc_charlen_type_node, i_len);
2375 mpz_clear (length); /* Was initialized by gfc_dep_difference. */
2377 else
2379 tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_charlen_type_node,
2380 fold_convert (gfc_charlen_type_node, end.expr),
2381 fold_convert (gfc_charlen_type_node, start.expr));
2382 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_charlen_type_node,
2383 build_int_cst (gfc_charlen_type_node, 1), tmp);
2384 tmp = fold_build2_loc (input_location, MAX_EXPR, gfc_charlen_type_node,
2385 tmp, build_int_cst (gfc_charlen_type_node, 0));
2388 se->string_length = tmp;
2392 /* Convert a derived type component reference. */
2394 static void
2395 gfc_conv_component_ref (gfc_se * se, gfc_ref * ref)
2397 gfc_component *c;
2398 tree tmp;
2399 tree decl;
2400 tree field;
2401 tree context;
2403 c = ref->u.c.component;
2405 if (c->backend_decl == NULL_TREE
2406 && ref->u.c.sym != NULL)
2407 gfc_get_derived_type (ref->u.c.sym);
2409 field = c->backend_decl;
2410 gcc_assert (field && TREE_CODE (field) == FIELD_DECL);
2411 decl = se->expr;
2412 context = DECL_FIELD_CONTEXT (field);
2414 /* Components can correspond to fields of different containing
2415 types, as components are created without context, whereas
2416 a concrete use of a component has the type of decl as context.
2417 So, if the type doesn't match, we search the corresponding
2418 FIELD_DECL in the parent type. To not waste too much time
2419 we cache this result in norestrict_decl.
2420 On the other hand, if the context is a UNION or a MAP (a
2421 RECORD_TYPE within a UNION_TYPE) always use the given FIELD_DECL. */
2423 if (context != TREE_TYPE (decl)
2424 && !( TREE_CODE (TREE_TYPE (field)) == UNION_TYPE /* Field is union */
2425 || TREE_CODE (context) == UNION_TYPE)) /* Field is map */
2427 tree f2 = c->norestrict_decl;
2428 if (!f2 || DECL_FIELD_CONTEXT (f2) != TREE_TYPE (decl))
2429 for (f2 = TYPE_FIELDS (TREE_TYPE (decl)); f2; f2 = DECL_CHAIN (f2))
2430 if (TREE_CODE (f2) == FIELD_DECL
2431 && DECL_NAME (f2) == DECL_NAME (field))
2432 break;
2433 gcc_assert (f2);
2434 c->norestrict_decl = f2;
2435 field = f2;
2438 if (ref->u.c.sym && ref->u.c.sym->ts.type == BT_CLASS
2439 && strcmp ("_data", c->name) == 0)
2441 /* Found a ref to the _data component. Store the associated ref to
2442 the vptr in se->class_vptr. */
2443 se->class_vptr = gfc_class_vptr_get (decl);
2445 else
2446 se->class_vptr = NULL_TREE;
2448 tmp = fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field),
2449 decl, field, NULL_TREE);
2451 se->expr = tmp;
2453 /* Allocatable deferred char arrays are to be handled by the gfc_deferred_
2454 strlen () conditional below. */
2455 if (c->ts.type == BT_CHARACTER && !c->attr.proc_pointer
2456 && !(c->attr.allocatable && c->ts.deferred)
2457 && !c->attr.pdt_string)
2459 tmp = c->ts.u.cl->backend_decl;
2460 /* Components must always be constant length. */
2461 gcc_assert (tmp && INTEGER_CST_P (tmp));
2462 se->string_length = tmp;
2465 if (gfc_deferred_strlen (c, &field))
2467 tmp = fold_build3_loc (input_location, COMPONENT_REF,
2468 TREE_TYPE (field),
2469 decl, field, NULL_TREE);
2470 se->string_length = tmp;
2473 if (((c->attr.pointer || c->attr.allocatable)
2474 && (!c->attr.dimension && !c->attr.codimension)
2475 && c->ts.type != BT_CHARACTER)
2476 || c->attr.proc_pointer)
2477 se->expr = build_fold_indirect_ref_loc (input_location,
2478 se->expr);
2482 /* This function deals with component references to components of the
2483 parent type for derived type extensions. */
2484 static void
2485 conv_parent_component_references (gfc_se * se, gfc_ref * ref)
2487 gfc_component *c;
2488 gfc_component *cmp;
2489 gfc_symbol *dt;
2490 gfc_ref parent;
2492 dt = ref->u.c.sym;
2493 c = ref->u.c.component;
2495 /* Return if the component is in the parent type. */
2496 for (cmp = dt->components; cmp; cmp = cmp->next)
2497 if (strcmp (c->name, cmp->name) == 0)
2498 return;
2500 /* Build a gfc_ref to recursively call gfc_conv_component_ref. */
2501 parent.type = REF_COMPONENT;
2502 parent.next = NULL;
2503 parent.u.c.sym = dt;
2504 parent.u.c.component = dt->components;
2506 if (dt->backend_decl == NULL)
2507 gfc_get_derived_type (dt);
2509 /* Build the reference and call self. */
2510 gfc_conv_component_ref (se, &parent);
2511 parent.u.c.sym = dt->components->ts.u.derived;
2512 parent.u.c.component = c;
2513 conv_parent_component_references (se, &parent);
2516 /* Return the contents of a variable. Also handles reference/pointer
2517 variables (all Fortran pointer references are implicit). */
2519 static void
2520 gfc_conv_variable (gfc_se * se, gfc_expr * expr)
2522 gfc_ss *ss;
2523 gfc_ref *ref;
2524 gfc_symbol *sym;
2525 tree parent_decl = NULL_TREE;
2526 int parent_flag;
2527 bool return_value;
2528 bool alternate_entry;
2529 bool entry_master;
2530 bool is_classarray;
2531 bool first_time = true;
2533 sym = expr->symtree->n.sym;
2534 is_classarray = IS_CLASS_ARRAY (sym);
2535 ss = se->ss;
2536 if (ss != NULL)
2538 gfc_ss_info *ss_info = ss->info;
2540 /* Check that something hasn't gone horribly wrong. */
2541 gcc_assert (ss != gfc_ss_terminator);
2542 gcc_assert (ss_info->expr == expr);
2544 /* A scalarized term. We already know the descriptor. */
2545 se->expr = ss_info->data.array.descriptor;
2546 se->string_length = ss_info->string_length;
2547 ref = ss_info->data.array.ref;
2548 if (ref)
2549 gcc_assert (ref->type == REF_ARRAY
2550 && ref->u.ar.type != AR_ELEMENT);
2551 else
2552 gfc_conv_tmp_array_ref (se);
2554 else
2556 tree se_expr = NULL_TREE;
2558 se->expr = gfc_get_symbol_decl (sym);
2560 /* Deal with references to a parent results or entries by storing
2561 the current_function_decl and moving to the parent_decl. */
2562 return_value = sym->attr.function && sym->result == sym;
2563 alternate_entry = sym->attr.function && sym->attr.entry
2564 && sym->result == sym;
2565 entry_master = sym->attr.result
2566 && sym->ns->proc_name->attr.entry_master
2567 && !gfc_return_by_reference (sym->ns->proc_name);
2568 if (current_function_decl)
2569 parent_decl = DECL_CONTEXT (current_function_decl);
2571 if ((se->expr == parent_decl && return_value)
2572 || (sym->ns && sym->ns->proc_name
2573 && parent_decl
2574 && sym->ns->proc_name->backend_decl == parent_decl
2575 && (alternate_entry || entry_master)))
2576 parent_flag = 1;
2577 else
2578 parent_flag = 0;
2580 /* Special case for assigning the return value of a function.
2581 Self recursive functions must have an explicit return value. */
2582 if (return_value && (se->expr == current_function_decl || parent_flag))
2583 se_expr = gfc_get_fake_result_decl (sym, parent_flag);
2585 /* Similarly for alternate entry points. */
2586 else if (alternate_entry
2587 && (sym->ns->proc_name->backend_decl == current_function_decl
2588 || parent_flag))
2590 gfc_entry_list *el = NULL;
2592 for (el = sym->ns->entries; el; el = el->next)
2593 if (sym == el->sym)
2595 se_expr = gfc_get_fake_result_decl (sym, parent_flag);
2596 break;
2600 else if (entry_master
2601 && (sym->ns->proc_name->backend_decl == current_function_decl
2602 || parent_flag))
2603 se_expr = gfc_get_fake_result_decl (sym, parent_flag);
2605 if (se_expr)
2606 se->expr = se_expr;
2608 /* Procedure actual arguments. Look out for temporary variables
2609 with the same attributes as function values. */
2610 else if (!sym->attr.temporary
2611 && sym->attr.flavor == FL_PROCEDURE
2612 && se->expr != current_function_decl)
2614 if (!sym->attr.dummy && !sym->attr.proc_pointer)
2616 gcc_assert (TREE_CODE (se->expr) == FUNCTION_DECL);
2617 se->expr = gfc_build_addr_expr (NULL_TREE, se->expr);
2619 return;
2623 /* Dereference the expression, where needed. Since characters
2624 are entirely different from other types, they are treated
2625 separately. */
2626 if (sym->ts.type == BT_CHARACTER)
2628 /* Dereference character pointer dummy arguments
2629 or results. */
2630 if ((sym->attr.pointer || sym->attr.allocatable)
2631 && (sym->attr.dummy
2632 || sym->attr.function
2633 || sym->attr.result))
2634 se->expr = build_fold_indirect_ref_loc (input_location,
2635 se->expr);
2638 else if (!sym->attr.value)
2640 /* Dereference temporaries for class array dummy arguments. */
2641 if (sym->attr.dummy && is_classarray
2642 && GFC_ARRAY_TYPE_P (TREE_TYPE (se->expr)))
2644 if (!se->descriptor_only)
2645 se->expr = GFC_DECL_SAVED_DESCRIPTOR (se->expr);
2647 se->expr = build_fold_indirect_ref_loc (input_location,
2648 se->expr);
2651 /* Dereference non-character scalar dummy arguments. */
2652 if (sym->attr.dummy && !sym->attr.dimension
2653 && !(sym->attr.codimension && sym->attr.allocatable)
2654 && (sym->ts.type != BT_CLASS
2655 || (!CLASS_DATA (sym)->attr.dimension
2656 && !(CLASS_DATA (sym)->attr.codimension
2657 && CLASS_DATA (sym)->attr.allocatable))))
2658 se->expr = build_fold_indirect_ref_loc (input_location,
2659 se->expr);
2661 /* Dereference scalar hidden result. */
2662 if (flag_f2c && sym->ts.type == BT_COMPLEX
2663 && (sym->attr.function || sym->attr.result)
2664 && !sym->attr.dimension && !sym->attr.pointer
2665 && !sym->attr.always_explicit)
2666 se->expr = build_fold_indirect_ref_loc (input_location,
2667 se->expr);
2669 /* Dereference non-character, non-class pointer variables.
2670 These must be dummies, results, or scalars. */
2671 if (!is_classarray
2672 && (sym->attr.pointer || sym->attr.allocatable
2673 || gfc_is_associate_pointer (sym)
2674 || (sym->as && sym->as->type == AS_ASSUMED_RANK))
2675 && (sym->attr.dummy
2676 || sym->attr.function
2677 || sym->attr.result
2678 || (!sym->attr.dimension
2679 && (!sym->attr.codimension || !sym->attr.allocatable))))
2680 se->expr = build_fold_indirect_ref_loc (input_location,
2681 se->expr);
2682 /* Now treat the class array pointer variables accordingly. */
2683 else if (sym->ts.type == BT_CLASS
2684 && sym->attr.dummy
2685 && (CLASS_DATA (sym)->attr.dimension
2686 || CLASS_DATA (sym)->attr.codimension)
2687 && ((CLASS_DATA (sym)->as
2688 && CLASS_DATA (sym)->as->type == AS_ASSUMED_RANK)
2689 || CLASS_DATA (sym)->attr.allocatable
2690 || CLASS_DATA (sym)->attr.class_pointer))
2691 se->expr = build_fold_indirect_ref_loc (input_location,
2692 se->expr);
2693 /* And the case where a non-dummy, non-result, non-function,
2694 non-allotable and non-pointer classarray is present. This case was
2695 previously covered by the first if, but with introducing the
2696 condition !is_classarray there, that case has to be covered
2697 explicitly. */
2698 else if (sym->ts.type == BT_CLASS
2699 && !sym->attr.dummy
2700 && !sym->attr.function
2701 && !sym->attr.result
2702 && (CLASS_DATA (sym)->attr.dimension
2703 || CLASS_DATA (sym)->attr.codimension)
2704 && (sym->assoc
2705 || !CLASS_DATA (sym)->attr.allocatable)
2706 && !CLASS_DATA (sym)->attr.class_pointer)
2707 se->expr = build_fold_indirect_ref_loc (input_location,
2708 se->expr);
2711 ref = expr->ref;
2714 /* For character variables, also get the length. */
2715 if (sym->ts.type == BT_CHARACTER)
2717 /* If the character length of an entry isn't set, get the length from
2718 the master function instead. */
2719 if (sym->attr.entry && !sym->ts.u.cl->backend_decl)
2720 se->string_length = sym->ns->proc_name->ts.u.cl->backend_decl;
2721 else
2722 se->string_length = sym->ts.u.cl->backend_decl;
2723 gcc_assert (se->string_length);
2726 while (ref)
2728 switch (ref->type)
2730 case REF_ARRAY:
2731 /* Return the descriptor if that's what we want and this is an array
2732 section reference. */
2733 if (se->descriptor_only && ref->u.ar.type != AR_ELEMENT)
2734 return;
2735 /* TODO: Pointers to single elements of array sections, eg elemental subs. */
2736 /* Return the descriptor for array pointers and allocations. */
2737 if (se->want_pointer
2738 && ref->next == NULL && (se->descriptor_only))
2739 return;
2741 gfc_conv_array_ref (se, &ref->u.ar, expr, &expr->where);
2742 /* Return a pointer to an element. */
2743 break;
2745 case REF_COMPONENT:
2746 if (first_time && is_classarray && sym->attr.dummy
2747 && se->descriptor_only
2748 && !CLASS_DATA (sym)->attr.allocatable
2749 && !CLASS_DATA (sym)->attr.class_pointer
2750 && CLASS_DATA (sym)->as
2751 && CLASS_DATA (sym)->as->type != AS_ASSUMED_RANK
2752 && strcmp ("_data", ref->u.c.component->name) == 0)
2753 /* Skip the first ref of a _data component, because for class
2754 arrays that one is already done by introducing a temporary
2755 array descriptor. */
2756 break;
2758 if (ref->u.c.sym->attr.extension)
2759 conv_parent_component_references (se, ref);
2761 gfc_conv_component_ref (se, ref);
2762 if (!ref->next && ref->u.c.sym->attr.codimension
2763 && se->want_pointer && se->descriptor_only)
2764 return;
2766 break;
2768 case REF_SUBSTRING:
2769 gfc_conv_substring (se, ref, expr->ts.kind,
2770 expr->symtree->name, &expr->where);
2771 break;
2773 default:
2774 gcc_unreachable ();
2775 break;
2777 first_time = false;
2778 ref = ref->next;
2780 /* Pointer assignment, allocation or pass by reference. Arrays are handled
2781 separately. */
2782 if (se->want_pointer)
2784 if (expr->ts.type == BT_CHARACTER && !gfc_is_proc_ptr_comp (expr))
2785 gfc_conv_string_parameter (se);
2786 else
2787 se->expr = gfc_build_addr_expr (NULL_TREE, se->expr);
2792 /* Unary ops are easy... Or they would be if ! was a valid op. */
2794 static void
2795 gfc_conv_unary_op (enum tree_code code, gfc_se * se, gfc_expr * expr)
2797 gfc_se operand;
2798 tree type;
2800 gcc_assert (expr->ts.type != BT_CHARACTER);
2801 /* Initialize the operand. */
2802 gfc_init_se (&operand, se);
2803 gfc_conv_expr_val (&operand, expr->value.op.op1);
2804 gfc_add_block_to_block (&se->pre, &operand.pre);
2806 type = gfc_typenode_for_spec (&expr->ts);
2808 /* TRUTH_NOT_EXPR is not a "true" unary operator in GCC.
2809 We must convert it to a compare to 0 (e.g. EQ_EXPR (op1, 0)).
2810 All other unary operators have an equivalent GIMPLE unary operator. */
2811 if (code == TRUTH_NOT_EXPR)
2812 se->expr = fold_build2_loc (input_location, EQ_EXPR, type, operand.expr,
2813 build_int_cst (type, 0));
2814 else
2815 se->expr = fold_build1_loc (input_location, code, type, operand.expr);
2819 /* Expand power operator to optimal multiplications when a value is raised
2820 to a constant integer n. See section 4.6.3, "Evaluation of Powers" of
2821 Donald E. Knuth, "Seminumerical Algorithms", Vol. 2, "The Art of Computer
2822 Programming", 3rd Edition, 1998. */
2824 /* This code is mostly duplicated from expand_powi in the backend.
2825 We establish the "optimal power tree" lookup table with the defined size.
2826 The items in the table are the exponents used to calculate the index
2827 exponents. Any integer n less than the value can get an "addition chain",
2828 with the first node being one. */
2829 #define POWI_TABLE_SIZE 256
2831 /* The table is from builtins.c. */
2832 static const unsigned char powi_table[POWI_TABLE_SIZE] =
2834 0, 1, 1, 2, 2, 3, 3, 4, /* 0 - 7 */
2835 4, 6, 5, 6, 6, 10, 7, 9, /* 8 - 15 */
2836 8, 16, 9, 16, 10, 12, 11, 13, /* 16 - 23 */
2837 12, 17, 13, 18, 14, 24, 15, 26, /* 24 - 31 */
2838 16, 17, 17, 19, 18, 33, 19, 26, /* 32 - 39 */
2839 20, 25, 21, 40, 22, 27, 23, 44, /* 40 - 47 */
2840 24, 32, 25, 34, 26, 29, 27, 44, /* 48 - 55 */
2841 28, 31, 29, 34, 30, 60, 31, 36, /* 56 - 63 */
2842 32, 64, 33, 34, 34, 46, 35, 37, /* 64 - 71 */
2843 36, 65, 37, 50, 38, 48, 39, 69, /* 72 - 79 */
2844 40, 49, 41, 43, 42, 51, 43, 58, /* 80 - 87 */
2845 44, 64, 45, 47, 46, 59, 47, 76, /* 88 - 95 */
2846 48, 65, 49, 66, 50, 67, 51, 66, /* 96 - 103 */
2847 52, 70, 53, 74, 54, 104, 55, 74, /* 104 - 111 */
2848 56, 64, 57, 69, 58, 78, 59, 68, /* 112 - 119 */
2849 60, 61, 61, 80, 62, 75, 63, 68, /* 120 - 127 */
2850 64, 65, 65, 128, 66, 129, 67, 90, /* 128 - 135 */
2851 68, 73, 69, 131, 70, 94, 71, 88, /* 136 - 143 */
2852 72, 128, 73, 98, 74, 132, 75, 121, /* 144 - 151 */
2853 76, 102, 77, 124, 78, 132, 79, 106, /* 152 - 159 */
2854 80, 97, 81, 160, 82, 99, 83, 134, /* 160 - 167 */
2855 84, 86, 85, 95, 86, 160, 87, 100, /* 168 - 175 */
2856 88, 113, 89, 98, 90, 107, 91, 122, /* 176 - 183 */
2857 92, 111, 93, 102, 94, 126, 95, 150, /* 184 - 191 */
2858 96, 128, 97, 130, 98, 133, 99, 195, /* 192 - 199 */
2859 100, 128, 101, 123, 102, 164, 103, 138, /* 200 - 207 */
2860 104, 145, 105, 146, 106, 109, 107, 149, /* 208 - 215 */
2861 108, 200, 109, 146, 110, 170, 111, 157, /* 216 - 223 */
2862 112, 128, 113, 130, 114, 182, 115, 132, /* 224 - 231 */
2863 116, 200, 117, 132, 118, 158, 119, 206, /* 232 - 239 */
2864 120, 240, 121, 162, 122, 147, 123, 152, /* 240 - 247 */
2865 124, 166, 125, 214, 126, 138, 127, 153, /* 248 - 255 */
2868 /* If n is larger than lookup table's max index, we use the "window
2869 method". */
2870 #define POWI_WINDOW_SIZE 3
2872 /* Recursive function to expand the power operator. The temporary
2873 values are put in tmpvar. The function returns tmpvar[1] ** n. */
2874 static tree
2875 gfc_conv_powi (gfc_se * se, unsigned HOST_WIDE_INT n, tree * tmpvar)
2877 tree op0;
2878 tree op1;
2879 tree tmp;
2880 int digit;
2882 if (n < POWI_TABLE_SIZE)
2884 if (tmpvar[n])
2885 return tmpvar[n];
2887 op0 = gfc_conv_powi (se, n - powi_table[n], tmpvar);
2888 op1 = gfc_conv_powi (se, powi_table[n], tmpvar);
2890 else if (n & 1)
2892 digit = n & ((1 << POWI_WINDOW_SIZE) - 1);
2893 op0 = gfc_conv_powi (se, n - digit, tmpvar);
2894 op1 = gfc_conv_powi (se, digit, tmpvar);
2896 else
2898 op0 = gfc_conv_powi (se, n >> 1, tmpvar);
2899 op1 = op0;
2902 tmp = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (op0), op0, op1);
2903 tmp = gfc_evaluate_now (tmp, &se->pre);
2905 if (n < POWI_TABLE_SIZE)
2906 tmpvar[n] = tmp;
2908 return tmp;
2912 /* Expand lhs ** rhs. rhs is a constant integer. If it expands successfully,
2913 return 1. Else return 0 and a call to runtime library functions
2914 will have to be built. */
2915 static int
2916 gfc_conv_cst_int_power (gfc_se * se, tree lhs, tree rhs)
2918 tree cond;
2919 tree tmp;
2920 tree type;
2921 tree vartmp[POWI_TABLE_SIZE];
2922 HOST_WIDE_INT m;
2923 unsigned HOST_WIDE_INT n;
2924 int sgn;
2925 wi::tree_to_wide_ref wrhs = wi::to_wide (rhs);
2927 /* If exponent is too large, we won't expand it anyway, so don't bother
2928 with large integer values. */
2929 if (!wi::fits_shwi_p (wrhs))
2930 return 0;
2932 m = wrhs.to_shwi ();
2933 /* Use the wide_int's routine to reliably get the absolute value on all
2934 platforms. Then convert it to a HOST_WIDE_INT like above. */
2935 n = wi::abs (wrhs).to_shwi ();
2937 type = TREE_TYPE (lhs);
2938 sgn = tree_int_cst_sgn (rhs);
2940 if (((FLOAT_TYPE_P (type) && !flag_unsafe_math_optimizations)
2941 || optimize_size) && (m > 2 || m < -1))
2942 return 0;
2944 /* rhs == 0 */
2945 if (sgn == 0)
2947 se->expr = gfc_build_const (type, integer_one_node);
2948 return 1;
2951 /* If rhs < 0 and lhs is an integer, the result is -1, 0 or 1. */
2952 if ((sgn == -1) && (TREE_CODE (type) == INTEGER_TYPE))
2954 tmp = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
2955 lhs, build_int_cst (TREE_TYPE (lhs), -1));
2956 cond = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
2957 lhs, build_int_cst (TREE_TYPE (lhs), 1));
2959 /* If rhs is even,
2960 result = (lhs == 1 || lhs == -1) ? 1 : 0. */
2961 if ((n & 1) == 0)
2963 tmp = fold_build2_loc (input_location, TRUTH_OR_EXPR,
2964 logical_type_node, tmp, cond);
2965 se->expr = fold_build3_loc (input_location, COND_EXPR, type,
2966 tmp, build_int_cst (type, 1),
2967 build_int_cst (type, 0));
2968 return 1;
2970 /* If rhs is odd,
2971 result = (lhs == 1) ? 1 : (lhs == -1) ? -1 : 0. */
2972 tmp = fold_build3_loc (input_location, COND_EXPR, type, tmp,
2973 build_int_cst (type, -1),
2974 build_int_cst (type, 0));
2975 se->expr = fold_build3_loc (input_location, COND_EXPR, type,
2976 cond, build_int_cst (type, 1), tmp);
2977 return 1;
2980 memset (vartmp, 0, sizeof (vartmp));
2981 vartmp[1] = lhs;
2982 if (sgn == -1)
2984 tmp = gfc_build_const (type, integer_one_node);
2985 vartmp[1] = fold_build2_loc (input_location, RDIV_EXPR, type, tmp,
2986 vartmp[1]);
2989 se->expr = gfc_conv_powi (se, n, vartmp);
2991 return 1;
2995 /* Power op (**). Constant integer exponent has special handling. */
2997 static void
2998 gfc_conv_power_op (gfc_se * se, gfc_expr * expr)
3000 tree gfc_int4_type_node;
3001 int kind;
3002 int ikind;
3003 int res_ikind_1, res_ikind_2;
3004 gfc_se lse;
3005 gfc_se rse;
3006 tree fndecl = NULL;
3008 gfc_init_se (&lse, se);
3009 gfc_conv_expr_val (&lse, expr->value.op.op1);
3010 lse.expr = gfc_evaluate_now (lse.expr, &lse.pre);
3011 gfc_add_block_to_block (&se->pre, &lse.pre);
3013 gfc_init_se (&rse, se);
3014 gfc_conv_expr_val (&rse, expr->value.op.op2);
3015 gfc_add_block_to_block (&se->pre, &rse.pre);
3017 if (expr->value.op.op2->ts.type == BT_INTEGER
3018 && expr->value.op.op2->expr_type == EXPR_CONSTANT)
3019 if (gfc_conv_cst_int_power (se, lse.expr, rse.expr))
3020 return;
3022 gfc_int4_type_node = gfc_get_int_type (4);
3024 /* In case of integer operands with kinds 1 or 2, we call the integer kind 4
3025 library routine. But in the end, we have to convert the result back
3026 if this case applies -- with res_ikind_K, we keep track whether operand K
3027 falls into this case. */
3028 res_ikind_1 = -1;
3029 res_ikind_2 = -1;
3031 kind = expr->value.op.op1->ts.kind;
3032 switch (expr->value.op.op2->ts.type)
3034 case BT_INTEGER:
3035 ikind = expr->value.op.op2->ts.kind;
3036 switch (ikind)
3038 case 1:
3039 case 2:
3040 rse.expr = convert (gfc_int4_type_node, rse.expr);
3041 res_ikind_2 = ikind;
3042 /* Fall through. */
3044 case 4:
3045 ikind = 0;
3046 break;
3048 case 8:
3049 ikind = 1;
3050 break;
3052 case 16:
3053 ikind = 2;
3054 break;
3056 default:
3057 gcc_unreachable ();
3059 switch (kind)
3061 case 1:
3062 case 2:
3063 if (expr->value.op.op1->ts.type == BT_INTEGER)
3065 lse.expr = convert (gfc_int4_type_node, lse.expr);
3066 res_ikind_1 = kind;
3068 else
3069 gcc_unreachable ();
3070 /* Fall through. */
3072 case 4:
3073 kind = 0;
3074 break;
3076 case 8:
3077 kind = 1;
3078 break;
3080 case 10:
3081 kind = 2;
3082 break;
3084 case 16:
3085 kind = 3;
3086 break;
3088 default:
3089 gcc_unreachable ();
3092 switch (expr->value.op.op1->ts.type)
3094 case BT_INTEGER:
3095 if (kind == 3) /* Case 16 was not handled properly above. */
3096 kind = 2;
3097 fndecl = gfor_fndecl_math_powi[kind][ikind].integer;
3098 break;
3100 case BT_REAL:
3101 /* Use builtins for real ** int4. */
3102 if (ikind == 0)
3104 switch (kind)
3106 case 0:
3107 fndecl = builtin_decl_explicit (BUILT_IN_POWIF);
3108 break;
3110 case 1:
3111 fndecl = builtin_decl_explicit (BUILT_IN_POWI);
3112 break;
3114 case 2:
3115 fndecl = builtin_decl_explicit (BUILT_IN_POWIL);
3116 break;
3118 case 3:
3119 /* Use the __builtin_powil() only if real(kind=16) is
3120 actually the C long double type. */
3121 if (!gfc_real16_is_float128)
3122 fndecl = builtin_decl_explicit (BUILT_IN_POWIL);
3123 break;
3125 default:
3126 gcc_unreachable ();
3130 /* If we don't have a good builtin for this, go for the
3131 library function. */
3132 if (!fndecl)
3133 fndecl = gfor_fndecl_math_powi[kind][ikind].real;
3134 break;
3136 case BT_COMPLEX:
3137 fndecl = gfor_fndecl_math_powi[kind][ikind].cmplx;
3138 break;
3140 default:
3141 gcc_unreachable ();
3143 break;
3145 case BT_REAL:
3146 fndecl = gfc_builtin_decl_for_float_kind (BUILT_IN_POW, kind);
3147 break;
3149 case BT_COMPLEX:
3150 fndecl = gfc_builtin_decl_for_float_kind (BUILT_IN_CPOW, kind);
3151 break;
3153 default:
3154 gcc_unreachable ();
3155 break;
3158 se->expr = build_call_expr_loc (input_location,
3159 fndecl, 2, lse.expr, rse.expr);
3161 /* Convert the result back if it is of wrong integer kind. */
3162 if (res_ikind_1 != -1 && res_ikind_2 != -1)
3164 /* We want the maximum of both operand kinds as result. */
3165 if (res_ikind_1 < res_ikind_2)
3166 res_ikind_1 = res_ikind_2;
3167 se->expr = convert (gfc_get_int_type (res_ikind_1), se->expr);
3172 /* Generate code to allocate a string temporary. */
3174 tree
3175 gfc_conv_string_tmp (gfc_se * se, tree type, tree len)
3177 tree var;
3178 tree tmp;
3180 if (gfc_can_put_var_on_stack (len))
3182 /* Create a temporary variable to hold the result. */
3183 tmp = fold_build2_loc (input_location, MINUS_EXPR,
3184 TREE_TYPE (len), len,
3185 build_int_cst (TREE_TYPE (len), 1));
3186 tmp = build_range_type (gfc_charlen_type_node, size_zero_node, tmp);
3188 if (TREE_CODE (TREE_TYPE (type)) == ARRAY_TYPE)
3189 tmp = build_array_type (TREE_TYPE (TREE_TYPE (type)), tmp);
3190 else
3191 tmp = build_array_type (TREE_TYPE (type), tmp);
3193 var = gfc_create_var (tmp, "str");
3194 var = gfc_build_addr_expr (type, var);
3196 else
3198 /* Allocate a temporary to hold the result. */
3199 var = gfc_create_var (type, "pstr");
3200 gcc_assert (POINTER_TYPE_P (type));
3201 tmp = TREE_TYPE (type);
3202 if (TREE_CODE (tmp) == ARRAY_TYPE)
3203 tmp = TREE_TYPE (tmp);
3204 tmp = TYPE_SIZE_UNIT (tmp);
3205 tmp = fold_build2_loc (input_location, MULT_EXPR, size_type_node,
3206 fold_convert (size_type_node, len),
3207 fold_convert (size_type_node, tmp));
3208 tmp = gfc_call_malloc (&se->pre, type, tmp);
3209 gfc_add_modify (&se->pre, var, tmp);
3211 /* Free the temporary afterwards. */
3212 tmp = gfc_call_free (var);
3213 gfc_add_expr_to_block (&se->post, tmp);
3216 return var;
3220 /* Handle a string concatenation operation. A temporary will be allocated to
3221 hold the result. */
3223 static void
3224 gfc_conv_concat_op (gfc_se * se, gfc_expr * expr)
3226 gfc_se lse, rse;
3227 tree len, type, var, tmp, fndecl;
3229 gcc_assert (expr->value.op.op1->ts.type == BT_CHARACTER
3230 && expr->value.op.op2->ts.type == BT_CHARACTER);
3231 gcc_assert (expr->value.op.op1->ts.kind == expr->value.op.op2->ts.kind);
3233 gfc_init_se (&lse, se);
3234 gfc_conv_expr (&lse, expr->value.op.op1);
3235 gfc_conv_string_parameter (&lse);
3236 gfc_init_se (&rse, se);
3237 gfc_conv_expr (&rse, expr->value.op.op2);
3238 gfc_conv_string_parameter (&rse);
3240 gfc_add_block_to_block (&se->pre, &lse.pre);
3241 gfc_add_block_to_block (&se->pre, &rse.pre);
3243 type = gfc_get_character_type (expr->ts.kind, expr->ts.u.cl);
3244 len = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
3245 if (len == NULL_TREE)
3247 len = fold_build2_loc (input_location, PLUS_EXPR,
3248 gfc_charlen_type_node,
3249 fold_convert (gfc_charlen_type_node,
3250 lse.string_length),
3251 fold_convert (gfc_charlen_type_node,
3252 rse.string_length));
3255 type = build_pointer_type (type);
3257 var = gfc_conv_string_tmp (se, type, len);
3259 /* Do the actual concatenation. */
3260 if (expr->ts.kind == 1)
3261 fndecl = gfor_fndecl_concat_string;
3262 else if (expr->ts.kind == 4)
3263 fndecl = gfor_fndecl_concat_string_char4;
3264 else
3265 gcc_unreachable ();
3267 tmp = build_call_expr_loc (input_location,
3268 fndecl, 6, len, var, lse.string_length, lse.expr,
3269 rse.string_length, rse.expr);
3270 gfc_add_expr_to_block (&se->pre, tmp);
3272 /* Add the cleanup for the operands. */
3273 gfc_add_block_to_block (&se->pre, &rse.post);
3274 gfc_add_block_to_block (&se->pre, &lse.post);
3276 se->expr = var;
3277 se->string_length = len;
3280 /* Translates an op expression. Common (binary) cases are handled by this
3281 function, others are passed on. Recursion is used in either case.
3282 We use the fact that (op1.ts == op2.ts) (except for the power
3283 operator **).
3284 Operators need no special handling for scalarized expressions as long as
3285 they call gfc_conv_simple_val to get their operands.
3286 Character strings get special handling. */
3288 static void
3289 gfc_conv_expr_op (gfc_se * se, gfc_expr * expr)
3291 enum tree_code code;
3292 gfc_se lse;
3293 gfc_se rse;
3294 tree tmp, type;
3295 int lop;
3296 int checkstring;
3298 checkstring = 0;
3299 lop = 0;
3300 switch (expr->value.op.op)
3302 case INTRINSIC_PARENTHESES:
3303 if ((expr->ts.type == BT_REAL || expr->ts.type == BT_COMPLEX)
3304 && flag_protect_parens)
3306 gfc_conv_unary_op (PAREN_EXPR, se, expr);
3307 gcc_assert (FLOAT_TYPE_P (TREE_TYPE (se->expr)));
3308 return;
3311 /* Fallthrough. */
3312 case INTRINSIC_UPLUS:
3313 gfc_conv_expr (se, expr->value.op.op1);
3314 return;
3316 case INTRINSIC_UMINUS:
3317 gfc_conv_unary_op (NEGATE_EXPR, se, expr);
3318 return;
3320 case INTRINSIC_NOT:
3321 gfc_conv_unary_op (TRUTH_NOT_EXPR, se, expr);
3322 return;
3324 case INTRINSIC_PLUS:
3325 code = PLUS_EXPR;
3326 break;
3328 case INTRINSIC_MINUS:
3329 code = MINUS_EXPR;
3330 break;
3332 case INTRINSIC_TIMES:
3333 code = MULT_EXPR;
3334 break;
3336 case INTRINSIC_DIVIDE:
3337 /* If expr is a real or complex expr, use an RDIV_EXPR. If op1 is
3338 an integer, we must round towards zero, so we use a
3339 TRUNC_DIV_EXPR. */
3340 if (expr->ts.type == BT_INTEGER)
3341 code = TRUNC_DIV_EXPR;
3342 else
3343 code = RDIV_EXPR;
3344 break;
3346 case INTRINSIC_POWER:
3347 gfc_conv_power_op (se, expr);
3348 return;
3350 case INTRINSIC_CONCAT:
3351 gfc_conv_concat_op (se, expr);
3352 return;
3354 case INTRINSIC_AND:
3355 code = flag_frontend_optimize ? TRUTH_ANDIF_EXPR : TRUTH_AND_EXPR;
3356 lop = 1;
3357 break;
3359 case INTRINSIC_OR:
3360 code = flag_frontend_optimize ? TRUTH_ORIF_EXPR : TRUTH_OR_EXPR;
3361 lop = 1;
3362 break;
3364 /* EQV and NEQV only work on logicals, but since we represent them
3365 as integers, we can use EQ_EXPR and NE_EXPR for them in GIMPLE. */
3366 case INTRINSIC_EQ:
3367 case INTRINSIC_EQ_OS:
3368 case INTRINSIC_EQV:
3369 code = EQ_EXPR;
3370 checkstring = 1;
3371 lop = 1;
3372 break;
3374 case INTRINSIC_NE:
3375 case INTRINSIC_NE_OS:
3376 case INTRINSIC_NEQV:
3377 code = NE_EXPR;
3378 checkstring = 1;
3379 lop = 1;
3380 break;
3382 case INTRINSIC_GT:
3383 case INTRINSIC_GT_OS:
3384 code = GT_EXPR;
3385 checkstring = 1;
3386 lop = 1;
3387 break;
3389 case INTRINSIC_GE:
3390 case INTRINSIC_GE_OS:
3391 code = GE_EXPR;
3392 checkstring = 1;
3393 lop = 1;
3394 break;
3396 case INTRINSIC_LT:
3397 case INTRINSIC_LT_OS:
3398 code = LT_EXPR;
3399 checkstring = 1;
3400 lop = 1;
3401 break;
3403 case INTRINSIC_LE:
3404 case INTRINSIC_LE_OS:
3405 code = LE_EXPR;
3406 checkstring = 1;
3407 lop = 1;
3408 break;
3410 case INTRINSIC_USER:
3411 case INTRINSIC_ASSIGN:
3412 /* These should be converted into function calls by the frontend. */
3413 gcc_unreachable ();
3415 default:
3416 fatal_error (input_location, "Unknown intrinsic op");
3417 return;
3420 /* The only exception to this is **, which is handled separately anyway. */
3421 gcc_assert (expr->value.op.op1->ts.type == expr->value.op.op2->ts.type);
3423 if (checkstring && expr->value.op.op1->ts.type != BT_CHARACTER)
3424 checkstring = 0;
3426 /* lhs */
3427 gfc_init_se (&lse, se);
3428 gfc_conv_expr (&lse, expr->value.op.op1);
3429 gfc_add_block_to_block (&se->pre, &lse.pre);
3431 /* rhs */
3432 gfc_init_se (&rse, se);
3433 gfc_conv_expr (&rse, expr->value.op.op2);
3434 gfc_add_block_to_block (&se->pre, &rse.pre);
3436 if (checkstring)
3438 gfc_conv_string_parameter (&lse);
3439 gfc_conv_string_parameter (&rse);
3441 lse.expr = gfc_build_compare_string (lse.string_length, lse.expr,
3442 rse.string_length, rse.expr,
3443 expr->value.op.op1->ts.kind,
3444 code);
3445 rse.expr = build_int_cst (TREE_TYPE (lse.expr), 0);
3446 gfc_add_block_to_block (&lse.post, &rse.post);
3449 type = gfc_typenode_for_spec (&expr->ts);
3451 if (lop)
3453 /* The result of logical ops is always logical_type_node. */
3454 tmp = fold_build2_loc (input_location, code, logical_type_node,
3455 lse.expr, rse.expr);
3456 se->expr = convert (type, tmp);
3458 else
3459 se->expr = fold_build2_loc (input_location, code, type, lse.expr, rse.expr);
3461 /* Add the post blocks. */
3462 gfc_add_block_to_block (&se->post, &rse.post);
3463 gfc_add_block_to_block (&se->post, &lse.post);
3466 /* If a string's length is one, we convert it to a single character. */
3468 tree
3469 gfc_string_to_single_character (tree len, tree str, int kind)
3472 if (len == NULL
3473 || !tree_fits_uhwi_p (len)
3474 || !POINTER_TYPE_P (TREE_TYPE (str)))
3475 return NULL_TREE;
3477 if (TREE_INT_CST_LOW (len) == 1)
3479 str = fold_convert (gfc_get_pchar_type (kind), str);
3480 return build_fold_indirect_ref_loc (input_location, str);
3483 if (kind == 1
3484 && TREE_CODE (str) == ADDR_EXPR
3485 && TREE_CODE (TREE_OPERAND (str, 0)) == ARRAY_REF
3486 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (str, 0), 0)) == STRING_CST
3487 && array_ref_low_bound (TREE_OPERAND (str, 0))
3488 == TREE_OPERAND (TREE_OPERAND (str, 0), 1)
3489 && TREE_INT_CST_LOW (len) > 1
3490 && TREE_INT_CST_LOW (len)
3491 == (unsigned HOST_WIDE_INT)
3492 TREE_STRING_LENGTH (TREE_OPERAND (TREE_OPERAND (str, 0), 0)))
3494 tree ret = fold_convert (gfc_get_pchar_type (kind), str);
3495 ret = build_fold_indirect_ref_loc (input_location, ret);
3496 if (TREE_CODE (ret) == INTEGER_CST)
3498 tree string_cst = TREE_OPERAND (TREE_OPERAND (str, 0), 0);
3499 int i, length = TREE_STRING_LENGTH (string_cst);
3500 const char *ptr = TREE_STRING_POINTER (string_cst);
3502 for (i = 1; i < length; i++)
3503 if (ptr[i] != ' ')
3504 return NULL_TREE;
3506 return ret;
3510 return NULL_TREE;
3514 void
3515 gfc_conv_scalar_char_value (gfc_symbol *sym, gfc_se *se, gfc_expr **expr)
3518 if (sym->backend_decl)
3520 /* This becomes the nominal_type in
3521 function.c:assign_parm_find_data_types. */
3522 TREE_TYPE (sym->backend_decl) = unsigned_char_type_node;
3523 /* This becomes the passed_type in
3524 function.c:assign_parm_find_data_types. C promotes char to
3525 integer for argument passing. */
3526 DECL_ARG_TYPE (sym->backend_decl) = unsigned_type_node;
3528 DECL_BY_REFERENCE (sym->backend_decl) = 0;
3531 if (expr != NULL)
3533 /* If we have a constant character expression, make it into an
3534 integer. */
3535 if ((*expr)->expr_type == EXPR_CONSTANT)
3537 gfc_typespec ts;
3538 gfc_clear_ts (&ts);
3540 *expr = gfc_get_int_expr (gfc_default_integer_kind, NULL,
3541 (int)(*expr)->value.character.string[0]);
3542 if ((*expr)->ts.kind != gfc_c_int_kind)
3544 /* The expr needs to be compatible with a C int. If the
3545 conversion fails, then the 2 causes an ICE. */
3546 ts.type = BT_INTEGER;
3547 ts.kind = gfc_c_int_kind;
3548 gfc_convert_type (*expr, &ts, 2);
3551 else if (se != NULL && (*expr)->expr_type == EXPR_VARIABLE)
3553 if ((*expr)->ref == NULL)
3555 se->expr = gfc_string_to_single_character
3556 (build_int_cst (integer_type_node, 1),
3557 gfc_build_addr_expr (gfc_get_pchar_type ((*expr)->ts.kind),
3558 gfc_get_symbol_decl
3559 ((*expr)->symtree->n.sym)),
3560 (*expr)->ts.kind);
3562 else
3564 gfc_conv_variable (se, *expr);
3565 se->expr = gfc_string_to_single_character
3566 (build_int_cst (integer_type_node, 1),
3567 gfc_build_addr_expr (gfc_get_pchar_type ((*expr)->ts.kind),
3568 se->expr),
3569 (*expr)->ts.kind);
3575 /* Helper function for gfc_build_compare_string. Return LEN_TRIM value
3576 if STR is a string literal, otherwise return -1. */
3578 static int
3579 gfc_optimize_len_trim (tree len, tree str, int kind)
3581 if (kind == 1
3582 && TREE_CODE (str) == ADDR_EXPR
3583 && TREE_CODE (TREE_OPERAND (str, 0)) == ARRAY_REF
3584 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (str, 0), 0)) == STRING_CST
3585 && array_ref_low_bound (TREE_OPERAND (str, 0))
3586 == TREE_OPERAND (TREE_OPERAND (str, 0), 1)
3587 && tree_fits_uhwi_p (len)
3588 && tree_to_uhwi (len) >= 1
3589 && tree_to_uhwi (len)
3590 == (unsigned HOST_WIDE_INT)
3591 TREE_STRING_LENGTH (TREE_OPERAND (TREE_OPERAND (str, 0), 0)))
3593 tree folded = fold_convert (gfc_get_pchar_type (kind), str);
3594 folded = build_fold_indirect_ref_loc (input_location, folded);
3595 if (TREE_CODE (folded) == INTEGER_CST)
3597 tree string_cst = TREE_OPERAND (TREE_OPERAND (str, 0), 0);
3598 int length = TREE_STRING_LENGTH (string_cst);
3599 const char *ptr = TREE_STRING_POINTER (string_cst);
3601 for (; length > 0; length--)
3602 if (ptr[length - 1] != ' ')
3603 break;
3605 return length;
3608 return -1;
3611 /* Helper to build a call to memcmp. */
3613 static tree
3614 build_memcmp_call (tree s1, tree s2, tree n)
3616 tree tmp;
3618 if (!POINTER_TYPE_P (TREE_TYPE (s1)))
3619 s1 = gfc_build_addr_expr (pvoid_type_node, s1);
3620 else
3621 s1 = fold_convert (pvoid_type_node, s1);
3623 if (!POINTER_TYPE_P (TREE_TYPE (s2)))
3624 s2 = gfc_build_addr_expr (pvoid_type_node, s2);
3625 else
3626 s2 = fold_convert (pvoid_type_node, s2);
3628 n = fold_convert (size_type_node, n);
3630 tmp = build_call_expr_loc (input_location,
3631 builtin_decl_explicit (BUILT_IN_MEMCMP),
3632 3, s1, s2, n);
3634 return fold_convert (integer_type_node, tmp);
3637 /* Compare two strings. If they are all single characters, the result is the
3638 subtraction of them. Otherwise, we build a library call. */
3640 tree
3641 gfc_build_compare_string (tree len1, tree str1, tree len2, tree str2, int kind,
3642 enum tree_code code)
3644 tree sc1;
3645 tree sc2;
3646 tree fndecl;
3648 gcc_assert (POINTER_TYPE_P (TREE_TYPE (str1)));
3649 gcc_assert (POINTER_TYPE_P (TREE_TYPE (str2)));
3651 sc1 = gfc_string_to_single_character (len1, str1, kind);
3652 sc2 = gfc_string_to_single_character (len2, str2, kind);
3654 if (sc1 != NULL_TREE && sc2 != NULL_TREE)
3656 /* Deal with single character specially. */
3657 sc1 = fold_convert (integer_type_node, sc1);
3658 sc2 = fold_convert (integer_type_node, sc2);
3659 return fold_build2_loc (input_location, MINUS_EXPR, integer_type_node,
3660 sc1, sc2);
3663 if ((code == EQ_EXPR || code == NE_EXPR)
3664 && optimize
3665 && INTEGER_CST_P (len1) && INTEGER_CST_P (len2))
3667 /* If one string is a string literal with LEN_TRIM longer
3668 than the length of the second string, the strings
3669 compare unequal. */
3670 int len = gfc_optimize_len_trim (len1, str1, kind);
3671 if (len > 0 && compare_tree_int (len2, len) < 0)
3672 return integer_one_node;
3673 len = gfc_optimize_len_trim (len2, str2, kind);
3674 if (len > 0 && compare_tree_int (len1, len) < 0)
3675 return integer_one_node;
3678 /* We can compare via memcpy if the strings are known to be equal
3679 in length and they are
3680 - kind=1
3681 - kind=4 and the comparison is for (in)equality. */
3683 if (INTEGER_CST_P (len1) && INTEGER_CST_P (len2)
3684 && tree_int_cst_equal (len1, len2)
3685 && (kind == 1 || code == EQ_EXPR || code == NE_EXPR))
3687 tree tmp;
3688 tree chartype;
3690 chartype = gfc_get_char_type (kind);
3691 tmp = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE(len1),
3692 fold_convert (TREE_TYPE(len1),
3693 TYPE_SIZE_UNIT(chartype)),
3694 len1);
3695 return build_memcmp_call (str1, str2, tmp);
3698 /* Build a call for the comparison. */
3699 if (kind == 1)
3700 fndecl = gfor_fndecl_compare_string;
3701 else if (kind == 4)
3702 fndecl = gfor_fndecl_compare_string_char4;
3703 else
3704 gcc_unreachable ();
3706 return build_call_expr_loc (input_location, fndecl, 4,
3707 len1, str1, len2, str2);
3711 /* Return the backend_decl for a procedure pointer component. */
3713 static tree
3714 get_proc_ptr_comp (gfc_expr *e)
3716 gfc_se comp_se;
3717 gfc_expr *e2;
3718 expr_t old_type;
3720 gfc_init_se (&comp_se, NULL);
3721 e2 = gfc_copy_expr (e);
3722 /* We have to restore the expr type later so that gfc_free_expr frees
3723 the exact same thing that was allocated.
3724 TODO: This is ugly. */
3725 old_type = e2->expr_type;
3726 e2->expr_type = EXPR_VARIABLE;
3727 gfc_conv_expr (&comp_se, e2);
3728 e2->expr_type = old_type;
3729 gfc_free_expr (e2);
3730 return build_fold_addr_expr_loc (input_location, comp_se.expr);
3734 /* Convert a typebound function reference from a class object. */
3735 static void
3736 conv_base_obj_fcn_val (gfc_se * se, tree base_object, gfc_expr * expr)
3738 gfc_ref *ref;
3739 tree var;
3741 if (!VAR_P (base_object))
3743 var = gfc_create_var (TREE_TYPE (base_object), NULL);
3744 gfc_add_modify (&se->pre, var, base_object);
3746 se->expr = gfc_class_vptr_get (base_object);
3747 se->expr = build_fold_indirect_ref_loc (input_location, se->expr);
3748 ref = expr->ref;
3749 while (ref && ref->next)
3750 ref = ref->next;
3751 gcc_assert (ref && ref->type == REF_COMPONENT);
3752 if (ref->u.c.sym->attr.extension)
3753 conv_parent_component_references (se, ref);
3754 gfc_conv_component_ref (se, ref);
3755 se->expr = build_fold_addr_expr_loc (input_location, se->expr);
3759 static void
3760 conv_function_val (gfc_se * se, gfc_symbol * sym, gfc_expr * expr)
3762 tree tmp;
3764 if (gfc_is_proc_ptr_comp (expr))
3765 tmp = get_proc_ptr_comp (expr);
3766 else if (sym->attr.dummy)
3768 tmp = gfc_get_symbol_decl (sym);
3769 if (sym->attr.proc_pointer)
3770 tmp = build_fold_indirect_ref_loc (input_location,
3771 tmp);
3772 gcc_assert (TREE_CODE (TREE_TYPE (tmp)) == POINTER_TYPE
3773 && TREE_CODE (TREE_TYPE (TREE_TYPE (tmp))) == FUNCTION_TYPE);
3775 else
3777 if (!sym->backend_decl)
3778 sym->backend_decl = gfc_get_extern_function_decl (sym);
3780 TREE_USED (sym->backend_decl) = 1;
3782 tmp = sym->backend_decl;
3784 if (sym->attr.cray_pointee)
3786 /* TODO - make the cray pointee a pointer to a procedure,
3787 assign the pointer to it and use it for the call. This
3788 will do for now! */
3789 tmp = convert (build_pointer_type (TREE_TYPE (tmp)),
3790 gfc_get_symbol_decl (sym->cp_pointer));
3791 tmp = gfc_evaluate_now (tmp, &se->pre);
3794 if (!POINTER_TYPE_P (TREE_TYPE (tmp)))
3796 gcc_assert (TREE_CODE (tmp) == FUNCTION_DECL);
3797 tmp = gfc_build_addr_expr (NULL_TREE, tmp);
3800 se->expr = tmp;
3804 /* Initialize MAPPING. */
3806 void
3807 gfc_init_interface_mapping (gfc_interface_mapping * mapping)
3809 mapping->syms = NULL;
3810 mapping->charlens = NULL;
3814 /* Free all memory held by MAPPING (but not MAPPING itself). */
3816 void
3817 gfc_free_interface_mapping (gfc_interface_mapping * mapping)
3819 gfc_interface_sym_mapping *sym;
3820 gfc_interface_sym_mapping *nextsym;
3821 gfc_charlen *cl;
3822 gfc_charlen *nextcl;
3824 for (sym = mapping->syms; sym; sym = nextsym)
3826 nextsym = sym->next;
3827 sym->new_sym->n.sym->formal = NULL;
3828 gfc_free_symbol (sym->new_sym->n.sym);
3829 gfc_free_expr (sym->expr);
3830 free (sym->new_sym);
3831 free (sym);
3833 for (cl = mapping->charlens; cl; cl = nextcl)
3835 nextcl = cl->next;
3836 gfc_free_expr (cl->length);
3837 free (cl);
3842 /* Return a copy of gfc_charlen CL. Add the returned structure to
3843 MAPPING so that it will be freed by gfc_free_interface_mapping. */
3845 static gfc_charlen *
3846 gfc_get_interface_mapping_charlen (gfc_interface_mapping * mapping,
3847 gfc_charlen * cl)
3849 gfc_charlen *new_charlen;
3851 new_charlen = gfc_get_charlen ();
3852 new_charlen->next = mapping->charlens;
3853 new_charlen->length = gfc_copy_expr (cl->length);
3855 mapping->charlens = new_charlen;
3856 return new_charlen;
3860 /* A subroutine of gfc_add_interface_mapping. Return a descriptorless
3861 array variable that can be used as the actual argument for dummy
3862 argument SYM. Add any initialization code to BLOCK. PACKED is as
3863 for gfc_get_nodesc_array_type and DATA points to the first element
3864 in the passed array. */
3866 static tree
3867 gfc_get_interface_mapping_array (stmtblock_t * block, gfc_symbol * sym,
3868 gfc_packed packed, tree data)
3870 tree type;
3871 tree var;
3873 type = gfc_typenode_for_spec (&sym->ts);
3874 type = gfc_get_nodesc_array_type (type, sym->as, packed,
3875 !sym->attr.target && !sym->attr.pointer
3876 && !sym->attr.proc_pointer);
3878 var = gfc_create_var (type, "ifm");
3879 gfc_add_modify (block, var, fold_convert (type, data));
3881 return var;
3885 /* A subroutine of gfc_add_interface_mapping. Set the stride, upper bounds
3886 and offset of descriptorless array type TYPE given that it has the same
3887 size as DESC. Add any set-up code to BLOCK. */
3889 static void
3890 gfc_set_interface_mapping_bounds (stmtblock_t * block, tree type, tree desc)
3892 int n;
3893 tree dim;
3894 tree offset;
3895 tree tmp;
3897 offset = gfc_index_zero_node;
3898 for (n = 0; n < GFC_TYPE_ARRAY_RANK (type); n++)
3900 dim = gfc_rank_cst[n];
3901 GFC_TYPE_ARRAY_STRIDE (type, n) = gfc_conv_array_stride (desc, n);
3902 if (GFC_TYPE_ARRAY_LBOUND (type, n) == NULL_TREE)
3904 GFC_TYPE_ARRAY_LBOUND (type, n)
3905 = gfc_conv_descriptor_lbound_get (desc, dim);
3906 GFC_TYPE_ARRAY_UBOUND (type, n)
3907 = gfc_conv_descriptor_ubound_get (desc, dim);
3909 else if (GFC_TYPE_ARRAY_UBOUND (type, n) == NULL_TREE)
3911 tmp = fold_build2_loc (input_location, MINUS_EXPR,
3912 gfc_array_index_type,
3913 gfc_conv_descriptor_ubound_get (desc, dim),
3914 gfc_conv_descriptor_lbound_get (desc, dim));
3915 tmp = fold_build2_loc (input_location, PLUS_EXPR,
3916 gfc_array_index_type,
3917 GFC_TYPE_ARRAY_LBOUND (type, n), tmp);
3918 tmp = gfc_evaluate_now (tmp, block);
3919 GFC_TYPE_ARRAY_UBOUND (type, n) = tmp;
3921 tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
3922 GFC_TYPE_ARRAY_LBOUND (type, n),
3923 GFC_TYPE_ARRAY_STRIDE (type, n));
3924 offset = fold_build2_loc (input_location, MINUS_EXPR,
3925 gfc_array_index_type, offset, tmp);
3927 offset = gfc_evaluate_now (offset, block);
3928 GFC_TYPE_ARRAY_OFFSET (type) = offset;
3932 /* Extend MAPPING so that it maps dummy argument SYM to the value stored
3933 in SE. The caller may still use se->expr and se->string_length after
3934 calling this function. */
3936 void
3937 gfc_add_interface_mapping (gfc_interface_mapping * mapping,
3938 gfc_symbol * sym, gfc_se * se,
3939 gfc_expr *expr)
3941 gfc_interface_sym_mapping *sm;
3942 tree desc;
3943 tree tmp;
3944 tree value;
3945 gfc_symbol *new_sym;
3946 gfc_symtree *root;
3947 gfc_symtree *new_symtree;
3949 /* Create a new symbol to represent the actual argument. */
3950 new_sym = gfc_new_symbol (sym->name, NULL);
3951 new_sym->ts = sym->ts;
3952 new_sym->as = gfc_copy_array_spec (sym->as);
3953 new_sym->attr.referenced = 1;
3954 new_sym->attr.dimension = sym->attr.dimension;
3955 new_sym->attr.contiguous = sym->attr.contiguous;
3956 new_sym->attr.codimension = sym->attr.codimension;
3957 new_sym->attr.pointer = sym->attr.pointer;
3958 new_sym->attr.allocatable = sym->attr.allocatable;
3959 new_sym->attr.flavor = sym->attr.flavor;
3960 new_sym->attr.function = sym->attr.function;
3962 /* Ensure that the interface is available and that
3963 descriptors are passed for array actual arguments. */
3964 if (sym->attr.flavor == FL_PROCEDURE)
3966 new_sym->formal = expr->symtree->n.sym->formal;
3967 new_sym->attr.always_explicit
3968 = expr->symtree->n.sym->attr.always_explicit;
3971 /* Create a fake symtree for it. */
3972 root = NULL;
3973 new_symtree = gfc_new_symtree (&root, sym->name);
3974 new_symtree->n.sym = new_sym;
3975 gcc_assert (new_symtree == root);
3977 /* Create a dummy->actual mapping. */
3978 sm = XCNEW (gfc_interface_sym_mapping);
3979 sm->next = mapping->syms;
3980 sm->old = sym;
3981 sm->new_sym = new_symtree;
3982 sm->expr = gfc_copy_expr (expr);
3983 mapping->syms = sm;
3985 /* Stabilize the argument's value. */
3986 if (!sym->attr.function && se)
3987 se->expr = gfc_evaluate_now (se->expr, &se->pre);
3989 if (sym->ts.type == BT_CHARACTER)
3991 /* Create a copy of the dummy argument's length. */
3992 new_sym->ts.u.cl = gfc_get_interface_mapping_charlen (mapping, sym->ts.u.cl);
3993 sm->expr->ts.u.cl = new_sym->ts.u.cl;
3995 /* If the length is specified as "*", record the length that
3996 the caller is passing. We should use the callee's length
3997 in all other cases. */
3998 if (!new_sym->ts.u.cl->length && se)
4000 se->string_length = gfc_evaluate_now (se->string_length, &se->pre);
4001 new_sym->ts.u.cl->backend_decl = se->string_length;
4005 if (!se)
4006 return;
4008 /* Use the passed value as-is if the argument is a function. */
4009 if (sym->attr.flavor == FL_PROCEDURE)
4010 value = se->expr;
4012 /* If the argument is a pass-by-value scalar, use the value as is. */
4013 else if (!sym->attr.dimension && sym->attr.value)
4014 value = se->expr;
4016 /* If the argument is either a string or a pointer to a string,
4017 convert it to a boundless character type. */
4018 else if (!sym->attr.dimension && sym->ts.type == BT_CHARACTER)
4020 tmp = gfc_get_character_type_len (sym->ts.kind, NULL);
4021 tmp = build_pointer_type (tmp);
4022 if (sym->attr.pointer)
4023 value = build_fold_indirect_ref_loc (input_location,
4024 se->expr);
4025 else
4026 value = se->expr;
4027 value = fold_convert (tmp, value);
4030 /* If the argument is a scalar, a pointer to an array or an allocatable,
4031 dereference it. */
4032 else if (!sym->attr.dimension || sym->attr.pointer || sym->attr.allocatable)
4033 value = build_fold_indirect_ref_loc (input_location,
4034 se->expr);
4036 /* For character(*), use the actual argument's descriptor. */
4037 else if (sym->ts.type == BT_CHARACTER && !new_sym->ts.u.cl->length)
4038 value = build_fold_indirect_ref_loc (input_location,
4039 se->expr);
4041 /* If the argument is an array descriptor, use it to determine
4042 information about the actual argument's shape. */
4043 else if (POINTER_TYPE_P (TREE_TYPE (se->expr))
4044 && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (TREE_TYPE (se->expr))))
4046 /* Get the actual argument's descriptor. */
4047 desc = build_fold_indirect_ref_loc (input_location,
4048 se->expr);
4050 /* Create the replacement variable. */
4051 tmp = gfc_conv_descriptor_data_get (desc);
4052 value = gfc_get_interface_mapping_array (&se->pre, sym,
4053 PACKED_NO, tmp);
4055 /* Use DESC to work out the upper bounds, strides and offset. */
4056 gfc_set_interface_mapping_bounds (&se->pre, TREE_TYPE (value), desc);
4058 else
4059 /* Otherwise we have a packed array. */
4060 value = gfc_get_interface_mapping_array (&se->pre, sym,
4061 PACKED_FULL, se->expr);
4063 new_sym->backend_decl = value;
4067 /* Called once all dummy argument mappings have been added to MAPPING,
4068 but before the mapping is used to evaluate expressions. Pre-evaluate
4069 the length of each argument, adding any initialization code to PRE and
4070 any finalization code to POST. */
4072 void
4073 gfc_finish_interface_mapping (gfc_interface_mapping * mapping,
4074 stmtblock_t * pre, stmtblock_t * post)
4076 gfc_interface_sym_mapping *sym;
4077 gfc_expr *expr;
4078 gfc_se se;
4080 for (sym = mapping->syms; sym; sym = sym->next)
4081 if (sym->new_sym->n.sym->ts.type == BT_CHARACTER
4082 && !sym->new_sym->n.sym->ts.u.cl->backend_decl)
4084 expr = sym->new_sym->n.sym->ts.u.cl->length;
4085 gfc_apply_interface_mapping_to_expr (mapping, expr);
4086 gfc_init_se (&se, NULL);
4087 gfc_conv_expr (&se, expr);
4088 se.expr = fold_convert (gfc_charlen_type_node, se.expr);
4089 se.expr = gfc_evaluate_now (se.expr, &se.pre);
4090 gfc_add_block_to_block (pre, &se.pre);
4091 gfc_add_block_to_block (post, &se.post);
4093 sym->new_sym->n.sym->ts.u.cl->backend_decl = se.expr;
4098 /* Like gfc_apply_interface_mapping_to_expr, but applied to
4099 constructor C. */
4101 static void
4102 gfc_apply_interface_mapping_to_cons (gfc_interface_mapping * mapping,
4103 gfc_constructor_base base)
4105 gfc_constructor *c;
4106 for (c = gfc_constructor_first (base); c; c = gfc_constructor_next (c))
4108 gfc_apply_interface_mapping_to_expr (mapping, c->expr);
4109 if (c->iterator)
4111 gfc_apply_interface_mapping_to_expr (mapping, c->iterator->start);
4112 gfc_apply_interface_mapping_to_expr (mapping, c->iterator->end);
4113 gfc_apply_interface_mapping_to_expr (mapping, c->iterator->step);
4119 /* Like gfc_apply_interface_mapping_to_expr, but applied to
4120 reference REF. */
4122 static void
4123 gfc_apply_interface_mapping_to_ref (gfc_interface_mapping * mapping,
4124 gfc_ref * ref)
4126 int n;
4128 for (; ref; ref = ref->next)
4129 switch (ref->type)
4131 case REF_ARRAY:
4132 for (n = 0; n < ref->u.ar.dimen; n++)
4134 gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.start[n]);
4135 gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.end[n]);
4136 gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.stride[n]);
4138 break;
4140 case REF_COMPONENT:
4141 break;
4143 case REF_SUBSTRING:
4144 gfc_apply_interface_mapping_to_expr (mapping, ref->u.ss.start);
4145 gfc_apply_interface_mapping_to_expr (mapping, ref->u.ss.end);
4146 break;
4151 /* Convert intrinsic function calls into result expressions. */
4153 static bool
4154 gfc_map_intrinsic_function (gfc_expr *expr, gfc_interface_mapping *mapping)
4156 gfc_symbol *sym;
4157 gfc_expr *new_expr;
4158 gfc_expr *arg1;
4159 gfc_expr *arg2;
4160 int d, dup;
4162 arg1 = expr->value.function.actual->expr;
4163 if (expr->value.function.actual->next)
4164 arg2 = expr->value.function.actual->next->expr;
4165 else
4166 arg2 = NULL;
4168 sym = arg1->symtree->n.sym;
4170 if (sym->attr.dummy)
4171 return false;
4173 new_expr = NULL;
4175 switch (expr->value.function.isym->id)
4177 case GFC_ISYM_LEN:
4178 /* TODO figure out why this condition is necessary. */
4179 if (sym->attr.function
4180 && (arg1->ts.u.cl->length == NULL
4181 || (arg1->ts.u.cl->length->expr_type != EXPR_CONSTANT
4182 && arg1->ts.u.cl->length->expr_type != EXPR_VARIABLE)))
4183 return false;
4185 new_expr = gfc_copy_expr (arg1->ts.u.cl->length);
4186 break;
4188 case GFC_ISYM_LEN_TRIM:
4189 new_expr = gfc_copy_expr (arg1);
4190 gfc_apply_interface_mapping_to_expr (mapping, new_expr);
4192 if (!new_expr)
4193 return false;
4195 gfc_replace_expr (arg1, new_expr);
4196 return true;
4198 case GFC_ISYM_SIZE:
4199 if (!sym->as || sym->as->rank == 0)
4200 return false;
4202 if (arg2 && arg2->expr_type == EXPR_CONSTANT)
4204 dup = mpz_get_si (arg2->value.integer);
4205 d = dup - 1;
4207 else
4209 dup = sym->as->rank;
4210 d = 0;
4213 for (; d < dup; d++)
4215 gfc_expr *tmp;
4217 if (!sym->as->upper[d] || !sym->as->lower[d])
4219 gfc_free_expr (new_expr);
4220 return false;
4223 tmp = gfc_add (gfc_copy_expr (sym->as->upper[d]),
4224 gfc_get_int_expr (gfc_default_integer_kind,
4225 NULL, 1));
4226 tmp = gfc_subtract (tmp, gfc_copy_expr (sym->as->lower[d]));
4227 if (new_expr)
4228 new_expr = gfc_multiply (new_expr, tmp);
4229 else
4230 new_expr = tmp;
4232 break;
4234 case GFC_ISYM_LBOUND:
4235 case GFC_ISYM_UBOUND:
4236 /* TODO These implementations of lbound and ubound do not limit if
4237 the size < 0, according to F95's 13.14.53 and 13.14.113. */
4239 if (!sym->as || sym->as->rank == 0)
4240 return false;
4242 if (arg2 && arg2->expr_type == EXPR_CONSTANT)
4243 d = mpz_get_si (arg2->value.integer) - 1;
4244 else
4245 return false;
4247 if (expr->value.function.isym->id == GFC_ISYM_LBOUND)
4249 if (sym->as->lower[d])
4250 new_expr = gfc_copy_expr (sym->as->lower[d]);
4252 else
4254 if (sym->as->upper[d])
4255 new_expr = gfc_copy_expr (sym->as->upper[d]);
4257 break;
4259 default:
4260 break;
4263 gfc_apply_interface_mapping_to_expr (mapping, new_expr);
4264 if (!new_expr)
4265 return false;
4267 gfc_replace_expr (expr, new_expr);
4268 return true;
4272 static void
4273 gfc_map_fcn_formal_to_actual (gfc_expr *expr, gfc_expr *map_expr,
4274 gfc_interface_mapping * mapping)
4276 gfc_formal_arglist *f;
4277 gfc_actual_arglist *actual;
4279 actual = expr->value.function.actual;
4280 f = gfc_sym_get_dummy_args (map_expr->symtree->n.sym);
4282 for (; f && actual; f = f->next, actual = actual->next)
4284 if (!actual->expr)
4285 continue;
4287 gfc_add_interface_mapping (mapping, f->sym, NULL, actual->expr);
4290 if (map_expr->symtree->n.sym->attr.dimension)
4292 int d;
4293 gfc_array_spec *as;
4295 as = gfc_copy_array_spec (map_expr->symtree->n.sym->as);
4297 for (d = 0; d < as->rank; d++)
4299 gfc_apply_interface_mapping_to_expr (mapping, as->lower[d]);
4300 gfc_apply_interface_mapping_to_expr (mapping, as->upper[d]);
4303 expr->value.function.esym->as = as;
4306 if (map_expr->symtree->n.sym->ts.type == BT_CHARACTER)
4308 expr->value.function.esym->ts.u.cl->length
4309 = gfc_copy_expr (map_expr->symtree->n.sym->ts.u.cl->length);
4311 gfc_apply_interface_mapping_to_expr (mapping,
4312 expr->value.function.esym->ts.u.cl->length);
4317 /* EXPR is a copy of an expression that appeared in the interface
4318 associated with MAPPING. Walk it recursively looking for references to
4319 dummy arguments that MAPPING maps to actual arguments. Replace each such
4320 reference with a reference to the associated actual argument. */
4322 static void
4323 gfc_apply_interface_mapping_to_expr (gfc_interface_mapping * mapping,
4324 gfc_expr * expr)
4326 gfc_interface_sym_mapping *sym;
4327 gfc_actual_arglist *actual;
4329 if (!expr)
4330 return;
4332 /* Copying an expression does not copy its length, so do that here. */
4333 if (expr->ts.type == BT_CHARACTER && expr->ts.u.cl)
4335 expr->ts.u.cl = gfc_get_interface_mapping_charlen (mapping, expr->ts.u.cl);
4336 gfc_apply_interface_mapping_to_expr (mapping, expr->ts.u.cl->length);
4339 /* Apply the mapping to any references. */
4340 gfc_apply_interface_mapping_to_ref (mapping, expr->ref);
4342 /* ...and to the expression's symbol, if it has one. */
4343 /* TODO Find out why the condition on expr->symtree had to be moved into
4344 the loop rather than being outside it, as originally. */
4345 for (sym = mapping->syms; sym; sym = sym->next)
4346 if (expr->symtree && sym->old == expr->symtree->n.sym)
4348 if (sym->new_sym->n.sym->backend_decl)
4349 expr->symtree = sym->new_sym;
4350 else if (sym->expr)
4351 gfc_replace_expr (expr, gfc_copy_expr (sym->expr));
4354 /* ...and to subexpressions in expr->value. */
4355 switch (expr->expr_type)
4357 case EXPR_VARIABLE:
4358 case EXPR_CONSTANT:
4359 case EXPR_NULL:
4360 case EXPR_SUBSTRING:
4361 break;
4363 case EXPR_OP:
4364 gfc_apply_interface_mapping_to_expr (mapping, expr->value.op.op1);
4365 gfc_apply_interface_mapping_to_expr (mapping, expr->value.op.op2);
4366 break;
4368 case EXPR_FUNCTION:
4369 for (actual = expr->value.function.actual; actual; actual = actual->next)
4370 gfc_apply_interface_mapping_to_expr (mapping, actual->expr);
4372 if (expr->value.function.esym == NULL
4373 && expr->value.function.isym != NULL
4374 && expr->value.function.actual
4375 && expr->value.function.actual->expr
4376 && expr->value.function.actual->expr->symtree
4377 && gfc_map_intrinsic_function (expr, mapping))
4378 break;
4380 for (sym = mapping->syms; sym; sym = sym->next)
4381 if (sym->old == expr->value.function.esym)
4383 expr->value.function.esym = sym->new_sym->n.sym;
4384 gfc_map_fcn_formal_to_actual (expr, sym->expr, mapping);
4385 expr->value.function.esym->result = sym->new_sym->n.sym;
4387 break;
4389 case EXPR_ARRAY:
4390 case EXPR_STRUCTURE:
4391 gfc_apply_interface_mapping_to_cons (mapping, expr->value.constructor);
4392 break;
4394 case EXPR_COMPCALL:
4395 case EXPR_PPC:
4396 gcc_unreachable ();
4397 break;
4400 return;
4404 /* Evaluate interface expression EXPR using MAPPING. Store the result
4405 in SE. */
4407 void
4408 gfc_apply_interface_mapping (gfc_interface_mapping * mapping,
4409 gfc_se * se, gfc_expr * expr)
4411 expr = gfc_copy_expr (expr);
4412 gfc_apply_interface_mapping_to_expr (mapping, expr);
4413 gfc_conv_expr (se, expr);
4414 se->expr = gfc_evaluate_now (se->expr, &se->pre);
4415 gfc_free_expr (expr);
4419 /* Returns a reference to a temporary array into which a component of
4420 an actual argument derived type array is copied and then returned
4421 after the function call. */
4422 void
4423 gfc_conv_subref_array_arg (gfc_se * parmse, gfc_expr * expr, int g77,
4424 sym_intent intent, bool formal_ptr)
4426 gfc_se lse;
4427 gfc_se rse;
4428 gfc_ss *lss;
4429 gfc_ss *rss;
4430 gfc_loopinfo loop;
4431 gfc_loopinfo loop2;
4432 gfc_array_info *info;
4433 tree offset;
4434 tree tmp_index;
4435 tree tmp;
4436 tree base_type;
4437 tree size;
4438 stmtblock_t body;
4439 int n;
4440 int dimen;
4442 gfc_init_se (&lse, NULL);
4443 gfc_init_se (&rse, NULL);
4445 /* Walk the argument expression. */
4446 rss = gfc_walk_expr (expr);
4448 gcc_assert (rss != gfc_ss_terminator);
4450 /* Initialize the scalarizer. */
4451 gfc_init_loopinfo (&loop);
4452 gfc_add_ss_to_loop (&loop, rss);
4454 /* Calculate the bounds of the scalarization. */
4455 gfc_conv_ss_startstride (&loop);
4457 /* Build an ss for the temporary. */
4458 if (expr->ts.type == BT_CHARACTER && !expr->ts.u.cl->backend_decl)
4459 gfc_conv_string_length (expr->ts.u.cl, expr, &parmse->pre);
4461 base_type = gfc_typenode_for_spec (&expr->ts);
4462 if (GFC_ARRAY_TYPE_P (base_type)
4463 || GFC_DESCRIPTOR_TYPE_P (base_type))
4464 base_type = gfc_get_element_type (base_type);
4466 if (expr->ts.type == BT_CLASS)
4467 base_type = gfc_typenode_for_spec (&CLASS_DATA (expr)->ts);
4469 loop.temp_ss = gfc_get_temp_ss (base_type, ((expr->ts.type == BT_CHARACTER)
4470 ? expr->ts.u.cl->backend_decl
4471 : NULL),
4472 loop.dimen);
4474 parmse->string_length = loop.temp_ss->info->string_length;
4476 /* Associate the SS with the loop. */
4477 gfc_add_ss_to_loop (&loop, loop.temp_ss);
4479 /* Setup the scalarizing loops. */
4480 gfc_conv_loop_setup (&loop, &expr->where);
4482 /* Pass the temporary descriptor back to the caller. */
4483 info = &loop.temp_ss->info->data.array;
4484 parmse->expr = info->descriptor;
4486 /* Setup the gfc_se structures. */
4487 gfc_copy_loopinfo_to_se (&lse, &loop);
4488 gfc_copy_loopinfo_to_se (&rse, &loop);
4490 rse.ss = rss;
4491 lse.ss = loop.temp_ss;
4492 gfc_mark_ss_chain_used (rss, 1);
4493 gfc_mark_ss_chain_used (loop.temp_ss, 1);
4495 /* Start the scalarized loop body. */
4496 gfc_start_scalarized_body (&loop, &body);
4498 /* Translate the expression. */
4499 gfc_conv_expr (&rse, expr);
4501 /* Reset the offset for the function call since the loop
4502 is zero based on the data pointer. Note that the temp
4503 comes first in the loop chain since it is added second. */
4504 if (gfc_is_class_array_function (expr))
4506 tmp = loop.ss->loop_chain->info->data.array.descriptor;
4507 gfc_conv_descriptor_offset_set (&loop.pre, tmp,
4508 gfc_index_zero_node);
4511 gfc_conv_tmp_array_ref (&lse);
4513 if (intent != INTENT_OUT)
4515 tmp = gfc_trans_scalar_assign (&lse, &rse, expr->ts, false, false);
4516 gfc_add_expr_to_block (&body, tmp);
4517 gcc_assert (rse.ss == gfc_ss_terminator);
4518 gfc_trans_scalarizing_loops (&loop, &body);
4520 else
4522 /* Make sure that the temporary declaration survives by merging
4523 all the loop declarations into the current context. */
4524 for (n = 0; n < loop.dimen; n++)
4526 gfc_merge_block_scope (&body);
4527 body = loop.code[loop.order[n]];
4529 gfc_merge_block_scope (&body);
4532 /* Add the post block after the second loop, so that any
4533 freeing of allocated memory is done at the right time. */
4534 gfc_add_block_to_block (&parmse->pre, &loop.pre);
4536 /**********Copy the temporary back again.*********/
4538 gfc_init_se (&lse, NULL);
4539 gfc_init_se (&rse, NULL);
4541 /* Walk the argument expression. */
4542 lss = gfc_walk_expr (expr);
4543 rse.ss = loop.temp_ss;
4544 lse.ss = lss;
4546 /* Initialize the scalarizer. */
4547 gfc_init_loopinfo (&loop2);
4548 gfc_add_ss_to_loop (&loop2, lss);
4550 dimen = rse.ss->dimen;
4552 /* Skip the write-out loop for this case. */
4553 if (gfc_is_class_array_function (expr))
4554 goto class_array_fcn;
4556 /* Calculate the bounds of the scalarization. */
4557 gfc_conv_ss_startstride (&loop2);
4559 /* Setup the scalarizing loops. */
4560 gfc_conv_loop_setup (&loop2, &expr->where);
4562 gfc_copy_loopinfo_to_se (&lse, &loop2);
4563 gfc_copy_loopinfo_to_se (&rse, &loop2);
4565 gfc_mark_ss_chain_used (lss, 1);
4566 gfc_mark_ss_chain_used (loop.temp_ss, 1);
4568 /* Declare the variable to hold the temporary offset and start the
4569 scalarized loop body. */
4570 offset = gfc_create_var (gfc_array_index_type, NULL);
4571 gfc_start_scalarized_body (&loop2, &body);
4573 /* Build the offsets for the temporary from the loop variables. The
4574 temporary array has lbounds of zero and strides of one in all
4575 dimensions, so this is very simple. The offset is only computed
4576 outside the innermost loop, so the overall transfer could be
4577 optimized further. */
4578 info = &rse.ss->info->data.array;
4580 tmp_index = gfc_index_zero_node;
4581 for (n = dimen - 1; n > 0; n--)
4583 tree tmp_str;
4584 tmp = rse.loop->loopvar[n];
4585 tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
4586 tmp, rse.loop->from[n]);
4587 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
4588 tmp, tmp_index);
4590 tmp_str = fold_build2_loc (input_location, MINUS_EXPR,
4591 gfc_array_index_type,
4592 rse.loop->to[n-1], rse.loop->from[n-1]);
4593 tmp_str = fold_build2_loc (input_location, PLUS_EXPR,
4594 gfc_array_index_type,
4595 tmp_str, gfc_index_one_node);
4597 tmp_index = fold_build2_loc (input_location, MULT_EXPR,
4598 gfc_array_index_type, tmp, tmp_str);
4601 tmp_index = fold_build2_loc (input_location, MINUS_EXPR,
4602 gfc_array_index_type,
4603 tmp_index, rse.loop->from[0]);
4604 gfc_add_modify (&rse.loop->code[0], offset, tmp_index);
4606 tmp_index = fold_build2_loc (input_location, PLUS_EXPR,
4607 gfc_array_index_type,
4608 rse.loop->loopvar[0], offset);
4610 /* Now use the offset for the reference. */
4611 tmp = build_fold_indirect_ref_loc (input_location,
4612 info->data);
4613 rse.expr = gfc_build_array_ref (tmp, tmp_index, NULL);
4615 if (expr->ts.type == BT_CHARACTER)
4616 rse.string_length = expr->ts.u.cl->backend_decl;
4618 gfc_conv_expr (&lse, expr);
4620 gcc_assert (lse.ss == gfc_ss_terminator);
4622 tmp = gfc_trans_scalar_assign (&lse, &rse, expr->ts, false, true);
4623 gfc_add_expr_to_block (&body, tmp);
4625 /* Generate the copying loops. */
4626 gfc_trans_scalarizing_loops (&loop2, &body);
4628 /* Wrap the whole thing up by adding the second loop to the post-block
4629 and following it by the post-block of the first loop. In this way,
4630 if the temporary needs freeing, it is done after use! */
4631 if (intent != INTENT_IN)
4633 gfc_add_block_to_block (&parmse->post, &loop2.pre);
4634 gfc_add_block_to_block (&parmse->post, &loop2.post);
4637 class_array_fcn:
4639 gfc_add_block_to_block (&parmse->post, &loop.post);
4641 gfc_cleanup_loop (&loop);
4642 gfc_cleanup_loop (&loop2);
4644 /* Pass the string length to the argument expression. */
4645 if (expr->ts.type == BT_CHARACTER)
4646 parmse->string_length = expr->ts.u.cl->backend_decl;
4648 /* Determine the offset for pointer formal arguments and set the
4649 lbounds to one. */
4650 if (formal_ptr)
4652 size = gfc_index_one_node;
4653 offset = gfc_index_zero_node;
4654 for (n = 0; n < dimen; n++)
4656 tmp = gfc_conv_descriptor_ubound_get (parmse->expr,
4657 gfc_rank_cst[n]);
4658 tmp = fold_build2_loc (input_location, PLUS_EXPR,
4659 gfc_array_index_type, tmp,
4660 gfc_index_one_node);
4661 gfc_conv_descriptor_ubound_set (&parmse->pre,
4662 parmse->expr,
4663 gfc_rank_cst[n],
4664 tmp);
4665 gfc_conv_descriptor_lbound_set (&parmse->pre,
4666 parmse->expr,
4667 gfc_rank_cst[n],
4668 gfc_index_one_node);
4669 size = gfc_evaluate_now (size, &parmse->pre);
4670 offset = fold_build2_loc (input_location, MINUS_EXPR,
4671 gfc_array_index_type,
4672 offset, size);
4673 offset = gfc_evaluate_now (offset, &parmse->pre);
4674 tmp = fold_build2_loc (input_location, MINUS_EXPR,
4675 gfc_array_index_type,
4676 rse.loop->to[n], rse.loop->from[n]);
4677 tmp = fold_build2_loc (input_location, PLUS_EXPR,
4678 gfc_array_index_type,
4679 tmp, gfc_index_one_node);
4680 size = fold_build2_loc (input_location, MULT_EXPR,
4681 gfc_array_index_type, size, tmp);
4684 gfc_conv_descriptor_offset_set (&parmse->pre, parmse->expr,
4685 offset);
4688 /* We want either the address for the data or the address of the descriptor,
4689 depending on the mode of passing array arguments. */
4690 if (g77)
4691 parmse->expr = gfc_conv_descriptor_data_get (parmse->expr);
4692 else
4693 parmse->expr = gfc_build_addr_expr (NULL_TREE, parmse->expr);
4695 return;
4699 /* Generate the code for argument list functions. */
4701 static void
4702 conv_arglist_function (gfc_se *se, gfc_expr *expr, const char *name)
4704 /* Pass by value for g77 %VAL(arg), pass the address
4705 indirectly for %LOC, else by reference. Thus %REF
4706 is a "do-nothing" and %LOC is the same as an F95
4707 pointer. */
4708 if (strcmp (name, "%VAL") == 0)
4709 gfc_conv_expr (se, expr);
4710 else if (strcmp (name, "%LOC") == 0)
4712 gfc_conv_expr_reference (se, expr);
4713 se->expr = gfc_build_addr_expr (NULL, se->expr);
4715 else if (strcmp (name, "%REF") == 0)
4716 gfc_conv_expr_reference (se, expr);
4717 else
4718 gfc_error ("Unknown argument list function at %L", &expr->where);
4722 /* This function tells whether the middle-end representation of the expression
4723 E given as input may point to data otherwise accessible through a variable
4724 (sub-)reference.
4725 It is assumed that the only expressions that may alias are variables,
4726 and array constructors if ARRAY_MAY_ALIAS is true and some of its elements
4727 may alias.
4728 This function is used to decide whether freeing an expression's allocatable
4729 components is safe or should be avoided.
4731 If ARRAY_MAY_ALIAS is true, an array constructor may alias if some of
4732 its elements are copied from a variable. This ARRAY_MAY_ALIAS trick
4733 is necessary because for array constructors, aliasing depends on how
4734 the array is used:
4735 - If E is an array constructor used as argument to an elemental procedure,
4736 the array, which is generated through shallow copy by the scalarizer,
4737 is used directly and can alias the expressions it was copied from.
4738 - If E is an array constructor used as argument to a non-elemental
4739 procedure,the scalarizer is used in gfc_conv_expr_descriptor to generate
4740 the array as in the previous case, but then that array is used
4741 to initialize a new descriptor through deep copy. There is no alias
4742 possible in that case.
4743 Thus, the ARRAY_MAY_ALIAS flag is necessary to distinguish the two cases
4744 above. */
4746 static bool
4747 expr_may_alias_variables (gfc_expr *e, bool array_may_alias)
4749 gfc_constructor *c;
4751 if (e->expr_type == EXPR_VARIABLE)
4752 return true;
4753 else if (e->expr_type == EXPR_FUNCTION)
4755 gfc_symbol *proc_ifc = gfc_get_proc_ifc_for_expr (e);
4757 if (proc_ifc->result != NULL
4758 && ((proc_ifc->result->ts.type == BT_CLASS
4759 && proc_ifc->result->ts.u.derived->attr.is_class
4760 && CLASS_DATA (proc_ifc->result)->attr.class_pointer)
4761 || proc_ifc->result->attr.pointer))
4762 return true;
4763 else
4764 return false;
4766 else if (e->expr_type != EXPR_ARRAY || !array_may_alias)
4767 return false;
4769 for (c = gfc_constructor_first (e->value.constructor);
4770 c; c = gfc_constructor_next (c))
4771 if (c->expr
4772 && expr_may_alias_variables (c->expr, array_may_alias))
4773 return true;
4775 return false;
4779 /* Generate code for a procedure call. Note can return se->post != NULL.
4780 If se->direct_byref is set then se->expr contains the return parameter.
4781 Return nonzero, if the call has alternate specifiers.
4782 'expr' is only needed for procedure pointer components. */
4785 gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
4786 gfc_actual_arglist * args, gfc_expr * expr,
4787 vec<tree, va_gc> *append_args)
4789 gfc_interface_mapping mapping;
4790 vec<tree, va_gc> *arglist;
4791 vec<tree, va_gc> *retargs;
4792 tree tmp;
4793 tree fntype;
4794 gfc_se parmse;
4795 gfc_array_info *info;
4796 int byref;
4797 int parm_kind;
4798 tree type;
4799 tree var;
4800 tree len;
4801 tree base_object;
4802 vec<tree, va_gc> *stringargs;
4803 vec<tree, va_gc> *optionalargs;
4804 tree result = NULL;
4805 gfc_formal_arglist *formal;
4806 gfc_actual_arglist *arg;
4807 int has_alternate_specifier = 0;
4808 bool need_interface_mapping;
4809 bool callee_alloc;
4810 bool ulim_copy;
4811 gfc_typespec ts;
4812 gfc_charlen cl;
4813 gfc_expr *e;
4814 gfc_symbol *fsym;
4815 stmtblock_t post;
4816 enum {MISSING = 0, ELEMENTAL, SCALAR, SCALAR_POINTER, ARRAY};
4817 gfc_component *comp = NULL;
4818 int arglen;
4819 unsigned int argc;
4821 arglist = NULL;
4822 retargs = NULL;
4823 stringargs = NULL;
4824 optionalargs = NULL;
4825 var = NULL_TREE;
4826 len = NULL_TREE;
4827 gfc_clear_ts (&ts);
4829 comp = gfc_get_proc_ptr_comp (expr);
4831 bool elemental_proc = (comp
4832 && comp->ts.interface
4833 && comp->ts.interface->attr.elemental)
4834 || (comp && comp->attr.elemental)
4835 || sym->attr.elemental;
4837 if (se->ss != NULL)
4839 if (!elemental_proc)
4841 gcc_assert (se->ss->info->type == GFC_SS_FUNCTION);
4842 if (se->ss->info->useflags)
4844 gcc_assert ((!comp && gfc_return_by_reference (sym)
4845 && sym->result->attr.dimension)
4846 || (comp && comp->attr.dimension)
4847 || gfc_is_class_array_function (expr));
4848 gcc_assert (se->loop != NULL);
4849 /* Access the previously obtained result. */
4850 gfc_conv_tmp_array_ref (se);
4851 return 0;
4854 info = &se->ss->info->data.array;
4856 else
4857 info = NULL;
4859 gfc_init_block (&post);
4860 gfc_init_interface_mapping (&mapping);
4861 if (!comp)
4863 formal = gfc_sym_get_dummy_args (sym);
4864 need_interface_mapping = sym->attr.dimension ||
4865 (sym->ts.type == BT_CHARACTER
4866 && sym->ts.u.cl->length
4867 && sym->ts.u.cl->length->expr_type
4868 != EXPR_CONSTANT);
4870 else
4872 formal = comp->ts.interface ? comp->ts.interface->formal : NULL;
4873 need_interface_mapping = comp->attr.dimension ||
4874 (comp->ts.type == BT_CHARACTER
4875 && comp->ts.u.cl->length
4876 && comp->ts.u.cl->length->expr_type
4877 != EXPR_CONSTANT);
4880 base_object = NULL_TREE;
4881 /* For _vprt->_copy () routines no formal symbol is present. Nevertheless
4882 is the third and fourth argument to such a function call a value
4883 denoting the number of elements to copy (i.e., most of the time the
4884 length of a deferred length string). */
4885 ulim_copy = (formal == NULL)
4886 && UNLIMITED_POLY (sym)
4887 && comp && (strcmp ("_copy", comp->name) == 0);
4889 /* Evaluate the arguments. */
4890 for (arg = args, argc = 0; arg != NULL;
4891 arg = arg->next, formal = formal ? formal->next : NULL, ++argc)
4893 bool finalized = false;
4895 e = arg->expr;
4896 fsym = formal ? formal->sym : NULL;
4897 parm_kind = MISSING;
4899 /* If the procedure requires an explicit interface, the actual
4900 argument is passed according to the corresponding formal
4901 argument. If the corresponding formal argument is a POINTER,
4902 ALLOCATABLE or assumed shape, we do not use g77's calling
4903 convention, and pass the address of the array descriptor
4904 instead. Otherwise we use g77's calling convention, in other words
4905 pass the array data pointer without descriptor. */
4906 bool nodesc_arg = fsym != NULL
4907 && !(fsym->attr.pointer || fsym->attr.allocatable)
4908 && fsym->as
4909 && fsym->as->type != AS_ASSUMED_SHAPE
4910 && fsym->as->type != AS_ASSUMED_RANK;
4911 if (comp)
4912 nodesc_arg = nodesc_arg || !comp->attr.always_explicit;
4913 else
4914 nodesc_arg = nodesc_arg || !sym->attr.always_explicit;
4916 /* Class array expressions are sometimes coming completely unadorned
4917 with either arrayspec or _data component. Correct that here.
4918 OOP-TODO: Move this to the frontend. */
4919 if (e && e->expr_type == EXPR_VARIABLE
4920 && !e->ref
4921 && e->ts.type == BT_CLASS
4922 && (CLASS_DATA (e)->attr.codimension
4923 || CLASS_DATA (e)->attr.dimension))
4925 gfc_typespec temp_ts = e->ts;
4926 gfc_add_class_array_ref (e);
4927 e->ts = temp_ts;
4930 if (e == NULL)
4932 if (se->ignore_optional)
4934 /* Some intrinsics have already been resolved to the correct
4935 parameters. */
4936 continue;
4938 else if (arg->label)
4940 has_alternate_specifier = 1;
4941 continue;
4943 else
4945 gfc_init_se (&parmse, NULL);
4947 /* For scalar arguments with VALUE attribute which are passed by
4948 value, pass "0" and a hidden argument gives the optional
4949 status. */
4950 if (fsym && fsym->attr.optional && fsym->attr.value
4951 && !fsym->attr.dimension && fsym->ts.type != BT_CHARACTER
4952 && fsym->ts.type != BT_CLASS && fsym->ts.type != BT_DERIVED)
4954 parmse.expr = fold_convert (gfc_sym_type (fsym),
4955 integer_zero_node);
4956 vec_safe_push (optionalargs, boolean_false_node);
4958 else
4960 /* Pass a NULL pointer for an absent arg. */
4961 parmse.expr = null_pointer_node;
4962 if (arg->missing_arg_type == BT_CHARACTER)
4963 parmse.string_length = build_int_cst (gfc_charlen_type_node,
4968 else if (arg->expr->expr_type == EXPR_NULL
4969 && fsym && !fsym->attr.pointer
4970 && (fsym->ts.type != BT_CLASS
4971 || !CLASS_DATA (fsym)->attr.class_pointer))
4973 /* Pass a NULL pointer to denote an absent arg. */
4974 gcc_assert (fsym->attr.optional && !fsym->attr.allocatable
4975 && (fsym->ts.type != BT_CLASS
4976 || !CLASS_DATA (fsym)->attr.allocatable));
4977 gfc_init_se (&parmse, NULL);
4978 parmse.expr = null_pointer_node;
4979 if (arg->missing_arg_type == BT_CHARACTER)
4980 parmse.string_length = build_int_cst (gfc_charlen_type_node, 0);
4982 else if (fsym && fsym->ts.type == BT_CLASS
4983 && e->ts.type == BT_DERIVED)
4985 /* The derived type needs to be converted to a temporary
4986 CLASS object. */
4987 gfc_init_se (&parmse, se);
4988 gfc_conv_derived_to_class (&parmse, e, fsym->ts, NULL,
4989 fsym->attr.optional
4990 && e->expr_type == EXPR_VARIABLE
4991 && e->symtree->n.sym->attr.optional,
4992 CLASS_DATA (fsym)->attr.class_pointer
4993 || CLASS_DATA (fsym)->attr.allocatable);
4995 else if (UNLIMITED_POLY (fsym) && e->ts.type != BT_CLASS)
4997 /* The intrinsic type needs to be converted to a temporary
4998 CLASS object for the unlimited polymorphic formal. */
4999 gfc_init_se (&parmse, se);
5000 gfc_conv_intrinsic_to_class (&parmse, e, fsym->ts);
5002 else if (se->ss && se->ss->info->useflags)
5004 gfc_ss *ss;
5006 ss = se->ss;
5008 /* An elemental function inside a scalarized loop. */
5009 gfc_init_se (&parmse, se);
5010 parm_kind = ELEMENTAL;
5012 /* When no fsym is present, ulim_copy is set and this is a third or
5013 fourth argument, use call-by-value instead of by reference to
5014 hand the length properties to the copy routine (i.e., most of the
5015 time this will be a call to a __copy_character_* routine where the
5016 third and fourth arguments are the lengths of a deferred length
5017 char array). */
5018 if ((fsym && fsym->attr.value)
5019 || (ulim_copy && (argc == 2 || argc == 3)))
5020 gfc_conv_expr (&parmse, e);
5021 else
5022 gfc_conv_expr_reference (&parmse, e);
5024 if (e->ts.type == BT_CHARACTER && !e->rank
5025 && e->expr_type == EXPR_FUNCTION)
5026 parmse.expr = build_fold_indirect_ref_loc (input_location,
5027 parmse.expr);
5029 if (fsym && fsym->ts.type == BT_DERIVED
5030 && gfc_is_class_container_ref (e))
5032 parmse.expr = gfc_class_data_get (parmse.expr);
5034 if (fsym->attr.optional && e->expr_type == EXPR_VARIABLE
5035 && e->symtree->n.sym->attr.optional)
5037 tree cond = gfc_conv_expr_present (e->symtree->n.sym);
5038 parmse.expr = build3_loc (input_location, COND_EXPR,
5039 TREE_TYPE (parmse.expr),
5040 cond, parmse.expr,
5041 fold_convert (TREE_TYPE (parmse.expr),
5042 null_pointer_node));
5046 /* If we are passing an absent array as optional dummy to an
5047 elemental procedure, make sure that we pass NULL when the data
5048 pointer is NULL. We need this extra conditional because of
5049 scalarization which passes arrays elements to the procedure,
5050 ignoring the fact that the array can be absent/unallocated/... */
5051 if (ss->info->can_be_null_ref && ss->info->type != GFC_SS_REFERENCE)
5053 tree descriptor_data;
5055 descriptor_data = ss->info->data.array.data;
5056 tmp = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
5057 descriptor_data,
5058 fold_convert (TREE_TYPE (descriptor_data),
5059 null_pointer_node));
5060 parmse.expr
5061 = fold_build3_loc (input_location, COND_EXPR,
5062 TREE_TYPE (parmse.expr),
5063 gfc_unlikely (tmp, PRED_FORTRAN_ABSENT_DUMMY),
5064 fold_convert (TREE_TYPE (parmse.expr),
5065 null_pointer_node),
5066 parmse.expr);
5069 /* The scalarizer does not repackage the reference to a class
5070 array - instead it returns a pointer to the data element. */
5071 if (fsym && fsym->ts.type == BT_CLASS && e->ts.type == BT_CLASS)
5072 gfc_conv_class_to_class (&parmse, e, fsym->ts, true,
5073 fsym->attr.intent != INTENT_IN
5074 && (CLASS_DATA (fsym)->attr.class_pointer
5075 || CLASS_DATA (fsym)->attr.allocatable),
5076 fsym->attr.optional
5077 && e->expr_type == EXPR_VARIABLE
5078 && e->symtree->n.sym->attr.optional,
5079 CLASS_DATA (fsym)->attr.class_pointer
5080 || CLASS_DATA (fsym)->attr.allocatable);
5082 else
5084 bool scalar;
5085 gfc_ss *argss;
5087 gfc_init_se (&parmse, NULL);
5089 /* Check whether the expression is a scalar or not; we cannot use
5090 e->rank as it can be nonzero for functions arguments. */
5091 argss = gfc_walk_expr (e);
5092 scalar = argss == gfc_ss_terminator;
5093 if (!scalar)
5094 gfc_free_ss_chain (argss);
5096 /* Special handling for passing scalar polymorphic coarrays;
5097 otherwise one passes "class->_data.data" instead of "&class". */
5098 if (e->rank == 0 && e->ts.type == BT_CLASS
5099 && fsym && fsym->ts.type == BT_CLASS
5100 && CLASS_DATA (fsym)->attr.codimension
5101 && !CLASS_DATA (fsym)->attr.dimension)
5103 gfc_add_class_array_ref (e);
5104 parmse.want_coarray = 1;
5105 scalar = false;
5108 /* A scalar or transformational function. */
5109 if (scalar)
5111 if (e->expr_type == EXPR_VARIABLE
5112 && e->symtree->n.sym->attr.cray_pointee
5113 && fsym && fsym->attr.flavor == FL_PROCEDURE)
5115 /* The Cray pointer needs to be converted to a pointer to
5116 a type given by the expression. */
5117 gfc_conv_expr (&parmse, e);
5118 type = build_pointer_type (TREE_TYPE (parmse.expr));
5119 tmp = gfc_get_symbol_decl (e->symtree->n.sym->cp_pointer);
5120 parmse.expr = convert (type, tmp);
5122 else if (fsym && fsym->attr.value)
5124 if (fsym->ts.type == BT_CHARACTER
5125 && fsym->ts.is_c_interop
5126 && fsym->ns->proc_name != NULL
5127 && fsym->ns->proc_name->attr.is_bind_c)
5129 parmse.expr = NULL;
5130 gfc_conv_scalar_char_value (fsym, &parmse, &e);
5131 if (parmse.expr == NULL)
5132 gfc_conv_expr (&parmse, e);
5134 else
5136 gfc_conv_expr (&parmse, e);
5137 if (fsym->attr.optional
5138 && fsym->ts.type != BT_CLASS
5139 && fsym->ts.type != BT_DERIVED)
5141 if (e->expr_type != EXPR_VARIABLE
5142 || !e->symtree->n.sym->attr.optional
5143 || e->ref != NULL)
5144 vec_safe_push (optionalargs, boolean_true_node);
5145 else
5147 tmp = gfc_conv_expr_present (e->symtree->n.sym);
5148 if (!e->symtree->n.sym->attr.value)
5149 parmse.expr
5150 = fold_build3_loc (input_location, COND_EXPR,
5151 TREE_TYPE (parmse.expr),
5152 tmp, parmse.expr,
5153 fold_convert (TREE_TYPE (parmse.expr),
5154 integer_zero_node));
5156 vec_safe_push (optionalargs, tmp);
5161 else if (arg->name && arg->name[0] == '%')
5162 /* Argument list functions %VAL, %LOC and %REF are signalled
5163 through arg->name. */
5164 conv_arglist_function (&parmse, arg->expr, arg->name);
5165 else if ((e->expr_type == EXPR_FUNCTION)
5166 && ((e->value.function.esym
5167 && e->value.function.esym->result->attr.pointer)
5168 || (!e->value.function.esym
5169 && e->symtree->n.sym->attr.pointer))
5170 && fsym && fsym->attr.target)
5172 gfc_conv_expr (&parmse, e);
5173 parmse.expr = gfc_build_addr_expr (NULL_TREE, parmse.expr);
5175 else if (e->expr_type == EXPR_FUNCTION
5176 && e->symtree->n.sym->result
5177 && e->symtree->n.sym->result != e->symtree->n.sym
5178 && e->symtree->n.sym->result->attr.proc_pointer)
5180 /* Functions returning procedure pointers. */
5181 gfc_conv_expr (&parmse, e);
5182 if (fsym && fsym->attr.proc_pointer)
5183 parmse.expr = gfc_build_addr_expr (NULL_TREE, parmse.expr);
5185 else
5187 if (e->ts.type == BT_CLASS && fsym
5188 && fsym->ts.type == BT_CLASS
5189 && (!CLASS_DATA (fsym)->as
5190 || CLASS_DATA (fsym)->as->type != AS_ASSUMED_RANK)
5191 && CLASS_DATA (e)->attr.codimension)
5193 gcc_assert (!CLASS_DATA (fsym)->attr.codimension);
5194 gcc_assert (!CLASS_DATA (fsym)->as);
5195 gfc_add_class_array_ref (e);
5196 parmse.want_coarray = 1;
5197 gfc_conv_expr_reference (&parmse, e);
5198 class_scalar_coarray_to_class (&parmse, e, fsym->ts,
5199 fsym->attr.optional
5200 && e->expr_type == EXPR_VARIABLE);
5202 else if (e->ts.type == BT_CLASS && fsym
5203 && fsym->ts.type == BT_CLASS
5204 && !CLASS_DATA (fsym)->as
5205 && !CLASS_DATA (e)->as
5206 && strcmp (fsym->ts.u.derived->name,
5207 e->ts.u.derived->name))
5209 type = gfc_typenode_for_spec (&fsym->ts);
5210 var = gfc_create_var (type, fsym->name);
5211 gfc_conv_expr (&parmse, e);
5212 if (fsym->attr.optional
5213 && e->expr_type == EXPR_VARIABLE
5214 && e->symtree->n.sym->attr.optional)
5216 stmtblock_t block;
5217 tree cond;
5218 tmp = gfc_build_addr_expr (NULL_TREE, parmse.expr);
5219 cond = fold_build2_loc (input_location, NE_EXPR,
5220 logical_type_node, tmp,
5221 fold_convert (TREE_TYPE (tmp),
5222 null_pointer_node));
5223 gfc_start_block (&block);
5224 gfc_add_modify (&block, var,
5225 fold_build1_loc (input_location,
5226 VIEW_CONVERT_EXPR,
5227 type, parmse.expr));
5228 gfc_add_expr_to_block (&parmse.pre,
5229 fold_build3_loc (input_location,
5230 COND_EXPR, void_type_node,
5231 cond, gfc_finish_block (&block),
5232 build_empty_stmt (input_location)));
5233 parmse.expr = gfc_build_addr_expr (NULL_TREE, var);
5234 parmse.expr = build3_loc (input_location, COND_EXPR,
5235 TREE_TYPE (parmse.expr),
5236 cond, parmse.expr,
5237 fold_convert (TREE_TYPE (parmse.expr),
5238 null_pointer_node));
5240 else
5242 /* Since the internal representation of unlimited
5243 polymorphic expressions includes an extra field
5244 that other class objects do not, a cast to the
5245 formal type does not work. */
5246 if (!UNLIMITED_POLY (e) && UNLIMITED_POLY (fsym))
5248 tree efield;
5250 /* Set the _data field. */
5251 tmp = gfc_class_data_get (var);
5252 efield = fold_convert (TREE_TYPE (tmp),
5253 gfc_class_data_get (parmse.expr));
5254 gfc_add_modify (&parmse.pre, tmp, efield);
5256 /* Set the _vptr field. */
5257 tmp = gfc_class_vptr_get (var);
5258 efield = fold_convert (TREE_TYPE (tmp),
5259 gfc_class_vptr_get (parmse.expr));
5260 gfc_add_modify (&parmse.pre, tmp, efield);
5262 /* Set the _len field. */
5263 tmp = gfc_class_len_get (var);
5264 gfc_add_modify (&parmse.pre, tmp,
5265 build_int_cst (TREE_TYPE (tmp), 0));
5267 else
5269 tmp = fold_build1_loc (input_location,
5270 VIEW_CONVERT_EXPR,
5271 type, parmse.expr);
5272 gfc_add_modify (&parmse.pre, var, tmp);
5275 parmse.expr = gfc_build_addr_expr (NULL_TREE, var);
5278 else
5279 gfc_conv_expr_reference (&parmse, e);
5281 /* Catch base objects that are not variables. */
5282 if (e->ts.type == BT_CLASS
5283 && e->expr_type != EXPR_VARIABLE
5284 && expr && e == expr->base_expr)
5285 base_object = build_fold_indirect_ref_loc (input_location,
5286 parmse.expr);
5288 /* A class array element needs converting back to be a
5289 class object, if the formal argument is a class object. */
5290 if (fsym && fsym->ts.type == BT_CLASS
5291 && e->ts.type == BT_CLASS
5292 && ((CLASS_DATA (fsym)->as
5293 && CLASS_DATA (fsym)->as->type == AS_ASSUMED_RANK)
5294 || CLASS_DATA (e)->attr.dimension))
5295 gfc_conv_class_to_class (&parmse, e, fsym->ts, false,
5296 fsym->attr.intent != INTENT_IN
5297 && (CLASS_DATA (fsym)->attr.class_pointer
5298 || CLASS_DATA (fsym)->attr.allocatable),
5299 fsym->attr.optional
5300 && e->expr_type == EXPR_VARIABLE
5301 && e->symtree->n.sym->attr.optional,
5302 CLASS_DATA (fsym)->attr.class_pointer
5303 || CLASS_DATA (fsym)->attr.allocatable);
5305 /* If an ALLOCATABLE dummy argument has INTENT(OUT) and is
5306 allocated on entry, it must be deallocated. */
5307 if (fsym && fsym->attr.intent == INTENT_OUT
5308 && (fsym->attr.allocatable
5309 || (fsym->ts.type == BT_CLASS
5310 && CLASS_DATA (fsym)->attr.allocatable)))
5312 stmtblock_t block;
5313 tree ptr;
5315 gfc_init_block (&block);
5316 ptr = parmse.expr;
5317 if (e->ts.type == BT_CLASS)
5318 ptr = gfc_class_data_get (ptr);
5320 tmp = gfc_deallocate_scalar_with_status (ptr, NULL_TREE,
5321 NULL_TREE, true,
5322 e, e->ts);
5323 gfc_add_expr_to_block (&block, tmp);
5324 tmp = fold_build2_loc (input_location, MODIFY_EXPR,
5325 void_type_node, ptr,
5326 null_pointer_node);
5327 gfc_add_expr_to_block (&block, tmp);
5329 if (fsym->ts.type == BT_CLASS && UNLIMITED_POLY (fsym))
5331 gfc_add_modify (&block, ptr,
5332 fold_convert (TREE_TYPE (ptr),
5333 null_pointer_node));
5334 gfc_add_expr_to_block (&block, tmp);
5336 else if (fsym->ts.type == BT_CLASS)
5338 gfc_symbol *vtab;
5339 vtab = gfc_find_derived_vtab (fsym->ts.u.derived);
5340 tmp = gfc_get_symbol_decl (vtab);
5341 tmp = gfc_build_addr_expr (NULL_TREE, tmp);
5342 ptr = gfc_class_vptr_get (parmse.expr);
5343 gfc_add_modify (&block, ptr,
5344 fold_convert (TREE_TYPE (ptr), tmp));
5345 gfc_add_expr_to_block (&block, tmp);
5348 if (fsym->attr.optional
5349 && e->expr_type == EXPR_VARIABLE
5350 && e->symtree->n.sym->attr.optional)
5352 tmp = fold_build3_loc (input_location, COND_EXPR,
5353 void_type_node,
5354 gfc_conv_expr_present (e->symtree->n.sym),
5355 gfc_finish_block (&block),
5356 build_empty_stmt (input_location));
5358 else
5359 tmp = gfc_finish_block (&block);
5361 gfc_add_expr_to_block (&se->pre, tmp);
5364 if (fsym && (fsym->ts.type == BT_DERIVED
5365 || fsym->ts.type == BT_ASSUMED)
5366 && e->ts.type == BT_CLASS
5367 && !CLASS_DATA (e)->attr.dimension
5368 && !CLASS_DATA (e)->attr.codimension)
5370 parmse.expr = gfc_class_data_get (parmse.expr);
5371 /* The result is a class temporary, whose _data component
5372 must be freed to avoid a memory leak. */
5373 if (e->expr_type == EXPR_FUNCTION
5374 && CLASS_DATA (e)->attr.allocatable)
5376 tree zero;
5378 gfc_expr *var;
5380 /* Borrow the function symbol to make a call to
5381 gfc_add_finalizer_call and then restore it. */
5382 tmp = e->symtree->n.sym->backend_decl;
5383 e->symtree->n.sym->backend_decl
5384 = TREE_OPERAND (parmse.expr, 0);
5385 e->symtree->n.sym->attr.flavor = FL_VARIABLE;
5386 var = gfc_lval_expr_from_sym (e->symtree->n.sym);
5387 finalized = gfc_add_finalizer_call (&parmse.post,
5388 var);
5389 gfc_free_expr (var);
5390 e->symtree->n.sym->backend_decl = tmp;
5391 e->symtree->n.sym->attr.flavor = FL_PROCEDURE;
5393 /* Then free the class _data. */
5394 zero = build_int_cst (TREE_TYPE (parmse.expr), 0);
5395 tmp = fold_build2_loc (input_location, NE_EXPR,
5396 logical_type_node,
5397 parmse.expr, zero);
5398 tmp = build3_v (COND_EXPR, tmp,
5399 gfc_call_free (parmse.expr),
5400 build_empty_stmt (input_location));
5401 gfc_add_expr_to_block (&parmse.post, tmp);
5402 gfc_add_modify (&parmse.post, parmse.expr, zero);
5406 /* Wrap scalar variable in a descriptor. We need to convert
5407 the address of a pointer back to the pointer itself before,
5408 we can assign it to the data field. */
5410 if (fsym && fsym->as && fsym->as->type == AS_ASSUMED_RANK
5411 && fsym->ts.type != BT_CLASS && e->expr_type != EXPR_NULL)
5413 tmp = parmse.expr;
5414 if (TREE_CODE (tmp) == ADDR_EXPR)
5415 tmp = build_fold_indirect_ref_loc (input_location, tmp);
5416 parmse.expr = gfc_conv_scalar_to_descriptor (&parmse, tmp,
5417 fsym->attr);
5418 parmse.expr = gfc_build_addr_expr (NULL_TREE,
5419 parmse.expr);
5421 else if (fsym && e->expr_type != EXPR_NULL
5422 && ((fsym->attr.pointer
5423 && fsym->attr.flavor != FL_PROCEDURE)
5424 || (fsym->attr.proc_pointer
5425 && !(e->expr_type == EXPR_VARIABLE
5426 && e->symtree->n.sym->attr.dummy))
5427 || (fsym->attr.proc_pointer
5428 && e->expr_type == EXPR_VARIABLE
5429 && gfc_is_proc_ptr_comp (e))
5430 || (fsym->attr.allocatable
5431 && fsym->attr.flavor != FL_PROCEDURE)))
5433 /* Scalar pointer dummy args require an extra level of
5434 indirection. The null pointer already contains
5435 this level of indirection. */
5436 parm_kind = SCALAR_POINTER;
5437 parmse.expr = gfc_build_addr_expr (NULL_TREE, parmse.expr);
5441 else if (e->ts.type == BT_CLASS
5442 && fsym && fsym->ts.type == BT_CLASS
5443 && (CLASS_DATA (fsym)->attr.dimension
5444 || CLASS_DATA (fsym)->attr.codimension))
5446 /* Pass a class array. */
5447 parmse.use_offset = 1;
5448 gfc_conv_expr_descriptor (&parmse, e);
5450 /* If an ALLOCATABLE dummy argument has INTENT(OUT) and is
5451 allocated on entry, it must be deallocated. */
5452 if (fsym->attr.intent == INTENT_OUT
5453 && CLASS_DATA (fsym)->attr.allocatable)
5455 stmtblock_t block;
5456 tree ptr;
5458 gfc_init_block (&block);
5459 ptr = parmse.expr;
5460 ptr = gfc_class_data_get (ptr);
5462 tmp = gfc_deallocate_with_status (ptr, NULL_TREE,
5463 NULL_TREE, NULL_TREE,
5464 NULL_TREE, true, e,
5465 GFC_CAF_COARRAY_NOCOARRAY);
5466 gfc_add_expr_to_block (&block, tmp);
5467 tmp = fold_build2_loc (input_location, MODIFY_EXPR,
5468 void_type_node, ptr,
5469 null_pointer_node);
5470 gfc_add_expr_to_block (&block, tmp);
5471 gfc_reset_vptr (&block, e);
5473 if (fsym->attr.optional
5474 && e->expr_type == EXPR_VARIABLE
5475 && (!e->ref
5476 || (e->ref->type == REF_ARRAY
5477 && e->ref->u.ar.type != AR_FULL))
5478 && e->symtree->n.sym->attr.optional)
5480 tmp = fold_build3_loc (input_location, COND_EXPR,
5481 void_type_node,
5482 gfc_conv_expr_present (e->symtree->n.sym),
5483 gfc_finish_block (&block),
5484 build_empty_stmt (input_location));
5486 else
5487 tmp = gfc_finish_block (&block);
5489 gfc_add_expr_to_block (&se->pre, tmp);
5492 /* The conversion does not repackage the reference to a class
5493 array - _data descriptor. */
5494 gfc_conv_class_to_class (&parmse, e, fsym->ts, false,
5495 fsym->attr.intent != INTENT_IN
5496 && (CLASS_DATA (fsym)->attr.class_pointer
5497 || CLASS_DATA (fsym)->attr.allocatable),
5498 fsym->attr.optional
5499 && e->expr_type == EXPR_VARIABLE
5500 && e->symtree->n.sym->attr.optional,
5501 CLASS_DATA (fsym)->attr.class_pointer
5502 || CLASS_DATA (fsym)->attr.allocatable);
5504 else
5506 /* If the argument is a function call that may not create
5507 a temporary for the result, we have to check that we
5508 can do it, i.e. that there is no alias between this
5509 argument and another one. */
5510 if (gfc_get_noncopying_intrinsic_argument (e) != NULL)
5512 gfc_expr *iarg;
5513 sym_intent intent;
5515 if (fsym != NULL)
5516 intent = fsym->attr.intent;
5517 else
5518 intent = INTENT_UNKNOWN;
5520 if (gfc_check_fncall_dependency (e, intent, sym, args,
5521 NOT_ELEMENTAL))
5522 parmse.force_tmp = 1;
5524 iarg = e->value.function.actual->expr;
5526 /* Temporary needed if aliasing due to host association. */
5527 if (sym->attr.contained
5528 && !sym->attr.pure
5529 && !sym->attr.implicit_pure
5530 && !sym->attr.use_assoc
5531 && iarg->expr_type == EXPR_VARIABLE
5532 && sym->ns == iarg->symtree->n.sym->ns)
5533 parmse.force_tmp = 1;
5535 /* Ditto within module. */
5536 if (sym->attr.use_assoc
5537 && !sym->attr.pure
5538 && !sym->attr.implicit_pure
5539 && iarg->expr_type == EXPR_VARIABLE
5540 && sym->module == iarg->symtree->n.sym->module)
5541 parmse.force_tmp = 1;
5544 if (e->expr_type == EXPR_VARIABLE
5545 && is_subref_array (e)
5546 && !(fsym && fsym->attr.pointer))
5547 /* The actual argument is a component reference to an
5548 array of derived types. In this case, the argument
5549 is converted to a temporary, which is passed and then
5550 written back after the procedure call. */
5551 gfc_conv_subref_array_arg (&parmse, e, nodesc_arg,
5552 fsym ? fsym->attr.intent : INTENT_INOUT,
5553 fsym && fsym->attr.pointer);
5554 else if (gfc_is_class_array_ref (e, NULL)
5555 && fsym && fsym->ts.type == BT_DERIVED)
5556 /* The actual argument is a component reference to an
5557 array of derived types. In this case, the argument
5558 is converted to a temporary, which is passed and then
5559 written back after the procedure call.
5560 OOP-TODO: Insert code so that if the dynamic type is
5561 the same as the declared type, copy-in/copy-out does
5562 not occur. */
5563 gfc_conv_subref_array_arg (&parmse, e, nodesc_arg,
5564 fsym ? fsym->attr.intent : INTENT_INOUT,
5565 fsym && fsym->attr.pointer);
5567 else if (gfc_is_class_array_function (e)
5568 && fsym && fsym->ts.type == BT_DERIVED)
5569 /* See previous comment. For function actual argument,
5570 the write out is not needed so the intent is set as
5571 intent in. */
5573 e->must_finalize = 1;
5574 gfc_conv_subref_array_arg (&parmse, e, nodesc_arg,
5575 INTENT_IN,
5576 fsym && fsym->attr.pointer);
5578 else
5579 gfc_conv_array_parameter (&parmse, e, nodesc_arg, fsym,
5580 sym->name, NULL);
5582 /* If an ALLOCATABLE dummy argument has INTENT(OUT) and is
5583 allocated on entry, it must be deallocated. */
5584 if (fsym && fsym->attr.allocatable
5585 && fsym->attr.intent == INTENT_OUT)
5587 if (fsym->ts.type == BT_DERIVED
5588 && fsym->ts.u.derived->attr.alloc_comp)
5590 // deallocate the components first
5591 tmp = gfc_deallocate_alloc_comp (fsym->ts.u.derived,
5592 parmse.expr, e->rank);
5593 if (tmp != NULL_TREE)
5594 gfc_add_expr_to_block (&se->pre, tmp);
5597 tmp = build_fold_indirect_ref_loc (input_location,
5598 parmse.expr);
5599 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp)))
5600 tmp = gfc_conv_descriptor_data_get (tmp);
5601 tmp = gfc_deallocate_with_status (tmp, NULL_TREE, NULL_TREE,
5602 NULL_TREE, NULL_TREE, true,
5604 GFC_CAF_COARRAY_NOCOARRAY);
5605 if (fsym->attr.optional
5606 && e->expr_type == EXPR_VARIABLE
5607 && e->symtree->n.sym->attr.optional)
5608 tmp = fold_build3_loc (input_location, COND_EXPR,
5609 void_type_node,
5610 gfc_conv_expr_present (e->symtree->n.sym),
5611 tmp, build_empty_stmt (input_location));
5612 gfc_add_expr_to_block (&se->pre, tmp);
5617 /* The case with fsym->attr.optional is that of a user subroutine
5618 with an interface indicating an optional argument. When we call
5619 an intrinsic subroutine, however, fsym is NULL, but we might still
5620 have an optional argument, so we proceed to the substitution
5621 just in case. */
5622 if (e && (fsym == NULL || fsym->attr.optional))
5624 /* If an optional argument is itself an optional dummy argument,
5625 check its presence and substitute a null if absent. This is
5626 only needed when passing an array to an elemental procedure
5627 as then array elements are accessed - or no NULL pointer is
5628 allowed and a "1" or "0" should be passed if not present.
5629 When passing a non-array-descriptor full array to a
5630 non-array-descriptor dummy, no check is needed. For
5631 array-descriptor actual to array-descriptor dummy, see
5632 PR 41911 for why a check has to be inserted.
5633 fsym == NULL is checked as intrinsics required the descriptor
5634 but do not always set fsym. */
5635 if (e->expr_type == EXPR_VARIABLE
5636 && e->symtree->n.sym->attr.optional
5637 && ((e->rank != 0 && elemental_proc)
5638 || e->representation.length || e->ts.type == BT_CHARACTER
5639 || (e->rank != 0
5640 && (fsym == NULL
5641 || (fsym-> as
5642 && (fsym->as->type == AS_ASSUMED_SHAPE
5643 || fsym->as->type == AS_ASSUMED_RANK
5644 || fsym->as->type == AS_DEFERRED))))))
5645 gfc_conv_missing_dummy (&parmse, e, fsym ? fsym->ts : e->ts,
5646 e->representation.length);
5649 if (fsym && e)
5651 /* Obtain the character length of an assumed character length
5652 length procedure from the typespec. */
5653 if (fsym->ts.type == BT_CHARACTER
5654 && parmse.string_length == NULL_TREE
5655 && e->ts.type == BT_PROCEDURE
5656 && e->symtree->n.sym->ts.type == BT_CHARACTER
5657 && e->symtree->n.sym->ts.u.cl->length != NULL
5658 && e->symtree->n.sym->ts.u.cl->length->expr_type == EXPR_CONSTANT)
5660 gfc_conv_const_charlen (e->symtree->n.sym->ts.u.cl);
5661 parmse.string_length = e->symtree->n.sym->ts.u.cl->backend_decl;
5665 if (fsym && need_interface_mapping && e)
5666 gfc_add_interface_mapping (&mapping, fsym, &parmse, e);
5668 gfc_add_block_to_block (&se->pre, &parmse.pre);
5669 gfc_add_block_to_block (&post, &parmse.post);
5671 /* Allocated allocatable components of derived types must be
5672 deallocated for non-variable scalars, array arguments to elemental
5673 procedures, and array arguments with descriptor to non-elemental
5674 procedures. As bounds information for descriptorless arrays is no
5675 longer available here, they are dealt with in trans-array.c
5676 (gfc_conv_array_parameter). */
5677 if (e && (e->ts.type == BT_DERIVED || e->ts.type == BT_CLASS)
5678 && e->ts.u.derived->attr.alloc_comp
5679 && (e->rank == 0 || elemental_proc || !nodesc_arg)
5680 && !expr_may_alias_variables (e, elemental_proc))
5682 int parm_rank;
5683 /* It is known the e returns a structure type with at least one
5684 allocatable component. When e is a function, ensure that the
5685 function is called once only by using a temporary variable. */
5686 if (!DECL_P (parmse.expr))
5687 parmse.expr = gfc_evaluate_now_loc (input_location,
5688 parmse.expr, &se->pre);
5690 if (fsym && fsym->attr.value)
5691 tmp = parmse.expr;
5692 else
5693 tmp = build_fold_indirect_ref_loc (input_location,
5694 parmse.expr);
5696 parm_rank = e->rank;
5697 switch (parm_kind)
5699 case (ELEMENTAL):
5700 case (SCALAR):
5701 parm_rank = 0;
5702 break;
5704 case (SCALAR_POINTER):
5705 tmp = build_fold_indirect_ref_loc (input_location,
5706 tmp);
5707 break;
5710 if (e->expr_type == EXPR_OP
5711 && e->value.op.op == INTRINSIC_PARENTHESES
5712 && e->value.op.op1->expr_type == EXPR_VARIABLE)
5714 tree local_tmp;
5715 local_tmp = gfc_evaluate_now (tmp, &se->pre);
5716 local_tmp = gfc_copy_alloc_comp (e->ts.u.derived, local_tmp, tmp,
5717 parm_rank, 0);
5718 gfc_add_expr_to_block (&se->post, local_tmp);
5721 if (e->ts.type == BT_DERIVED && fsym && fsym->ts.type == BT_CLASS)
5723 /* The derived type is passed to gfc_deallocate_alloc_comp.
5724 Therefore, class actuals can handled correctly but derived
5725 types passed to class formals need the _data component. */
5726 tmp = gfc_class_data_get (tmp);
5727 if (!CLASS_DATA (fsym)->attr.dimension)
5728 tmp = build_fold_indirect_ref_loc (input_location, tmp);
5731 if (!finalized && !e->must_finalize)
5733 if ((e->ts.type == BT_CLASS
5734 && GFC_CLASS_TYPE_P (TREE_TYPE (tmp)))
5735 || e->ts.type == BT_DERIVED)
5736 tmp = gfc_deallocate_alloc_comp (e->ts.u.derived, tmp,
5737 parm_rank);
5738 else if (e->ts.type == BT_CLASS)
5739 tmp = gfc_deallocate_alloc_comp (CLASS_DATA (e)->ts.u.derived,
5740 tmp, parm_rank);
5741 gfc_prepend_expr_to_block (&post, tmp);
5745 /* Add argument checking of passing an unallocated/NULL actual to
5746 a nonallocatable/nonpointer dummy. */
5748 if (gfc_option.rtcheck & GFC_RTCHECK_POINTER && e != NULL)
5750 symbol_attribute attr;
5751 char *msg;
5752 tree cond;
5754 if (e->expr_type == EXPR_VARIABLE || e->expr_type == EXPR_FUNCTION)
5755 attr = gfc_expr_attr (e);
5756 else
5757 goto end_pointer_check;
5759 /* In Fortran 2008 it's allowed to pass a NULL pointer/nonallocated
5760 allocatable to an optional dummy, cf. 12.5.2.12. */
5761 if (fsym != NULL && fsym->attr.optional && !attr.proc_pointer
5762 && (gfc_option.allow_std & GFC_STD_F2008) != 0)
5763 goto end_pointer_check;
5765 if (attr.optional)
5767 /* If the actual argument is an optional pointer/allocatable and
5768 the formal argument takes an nonpointer optional value,
5769 it is invalid to pass a non-present argument on, even
5770 though there is no technical reason for this in gfortran.
5771 See Fortran 2003, Section 12.4.1.6 item (7)+(8). */
5772 tree present, null_ptr, type;
5774 if (attr.allocatable
5775 && (fsym == NULL || !fsym->attr.allocatable))
5776 msg = xasprintf ("Allocatable actual argument '%s' is not "
5777 "allocated or not present",
5778 e->symtree->n.sym->name);
5779 else if (attr.pointer
5780 && (fsym == NULL || !fsym->attr.pointer))
5781 msg = xasprintf ("Pointer actual argument '%s' is not "
5782 "associated or not present",
5783 e->symtree->n.sym->name);
5784 else if (attr.proc_pointer
5785 && (fsym == NULL || !fsym->attr.proc_pointer))
5786 msg = xasprintf ("Proc-pointer actual argument '%s' is not "
5787 "associated or not present",
5788 e->symtree->n.sym->name);
5789 else
5790 goto end_pointer_check;
5792 present = gfc_conv_expr_present (e->symtree->n.sym);
5793 type = TREE_TYPE (present);
5794 present = fold_build2_loc (input_location, EQ_EXPR,
5795 logical_type_node, present,
5796 fold_convert (type,
5797 null_pointer_node));
5798 type = TREE_TYPE (parmse.expr);
5799 null_ptr = fold_build2_loc (input_location, EQ_EXPR,
5800 logical_type_node, parmse.expr,
5801 fold_convert (type,
5802 null_pointer_node));
5803 cond = fold_build2_loc (input_location, TRUTH_ORIF_EXPR,
5804 logical_type_node, present, null_ptr);
5806 else
5808 if (attr.allocatable
5809 && (fsym == NULL || !fsym->attr.allocatable))
5810 msg = xasprintf ("Allocatable actual argument '%s' is not "
5811 "allocated", e->symtree->n.sym->name);
5812 else if (attr.pointer
5813 && (fsym == NULL || !fsym->attr.pointer))
5814 msg = xasprintf ("Pointer actual argument '%s' is not "
5815 "associated", e->symtree->n.sym->name);
5816 else if (attr.proc_pointer
5817 && (fsym == NULL || !fsym->attr.proc_pointer))
5818 msg = xasprintf ("Proc-pointer actual argument '%s' is not "
5819 "associated", e->symtree->n.sym->name);
5820 else
5821 goto end_pointer_check;
5823 tmp = parmse.expr;
5825 /* If the argument is passed by value, we need to strip the
5826 INDIRECT_REF. */
5827 if (!POINTER_TYPE_P (TREE_TYPE (parmse.expr)))
5828 tmp = gfc_build_addr_expr (NULL_TREE, tmp);
5830 cond = fold_build2_loc (input_location, EQ_EXPR,
5831 logical_type_node, tmp,
5832 fold_convert (TREE_TYPE (tmp),
5833 null_pointer_node));
5836 gfc_trans_runtime_check (true, false, cond, &se->pre, &e->where,
5837 msg);
5838 free (msg);
5840 end_pointer_check:
5842 /* Deferred length dummies pass the character length by reference
5843 so that the value can be returned. */
5844 if (parmse.string_length && fsym && fsym->ts.deferred)
5846 if (INDIRECT_REF_P (parmse.string_length))
5847 /* In chains of functions/procedure calls the string_length already
5848 is a pointer to the variable holding the length. Therefore
5849 remove the deref on call. */
5850 parmse.string_length = TREE_OPERAND (parmse.string_length, 0);
5851 else
5853 tmp = parmse.string_length;
5854 if (!VAR_P (tmp) && TREE_CODE (tmp) != COMPONENT_REF)
5855 tmp = gfc_evaluate_now (parmse.string_length, &se->pre);
5856 parmse.string_length = gfc_build_addr_expr (NULL_TREE, tmp);
5860 /* Character strings are passed as two parameters, a length and a
5861 pointer - except for Bind(c) which only passes the pointer.
5862 An unlimited polymorphic formal argument likewise does not
5863 need the length. */
5864 if (parmse.string_length != NULL_TREE
5865 && !sym->attr.is_bind_c
5866 && !(fsym && UNLIMITED_POLY (fsym)))
5867 vec_safe_push (stringargs, parmse.string_length);
5869 /* When calling __copy for character expressions to unlimited
5870 polymorphic entities, the dst argument needs a string length. */
5871 if (sym->name[0] == '_' && e && e->ts.type == BT_CHARACTER
5872 && gfc_str_startswith (sym->name, "__vtab_CHARACTER")
5873 && arg->next && arg->next->expr
5874 && (arg->next->expr->ts.type == BT_DERIVED
5875 || arg->next->expr->ts.type == BT_CLASS)
5876 && arg->next->expr->ts.u.derived->attr.unlimited_polymorphic)
5877 vec_safe_push (stringargs, parmse.string_length);
5879 /* For descriptorless coarrays and assumed-shape coarray dummies, we
5880 pass the token and the offset as additional arguments. */
5881 if (fsym && e == NULL && flag_coarray == GFC_FCOARRAY_LIB
5882 && ((fsym->ts.type != BT_CLASS && fsym->attr.codimension
5883 && !fsym->attr.allocatable)
5884 || (fsym->ts.type == BT_CLASS
5885 && CLASS_DATA (fsym)->attr.codimension
5886 && !CLASS_DATA (fsym)->attr.allocatable)))
5888 /* Token and offset. */
5889 vec_safe_push (stringargs, null_pointer_node);
5890 vec_safe_push (stringargs, build_int_cst (gfc_array_index_type, 0));
5891 gcc_assert (fsym->attr.optional);
5893 else if (fsym && flag_coarray == GFC_FCOARRAY_LIB
5894 && ((fsym->ts.type != BT_CLASS && fsym->attr.codimension
5895 && !fsym->attr.allocatable)
5896 || (fsym->ts.type == BT_CLASS
5897 && CLASS_DATA (fsym)->attr.codimension
5898 && !CLASS_DATA (fsym)->attr.allocatable)))
5900 tree caf_decl, caf_type;
5901 tree offset, tmp2;
5903 caf_decl = gfc_get_tree_for_caf_expr (e);
5904 caf_type = TREE_TYPE (caf_decl);
5906 if (GFC_DESCRIPTOR_TYPE_P (caf_type)
5907 && (GFC_TYPE_ARRAY_AKIND (caf_type) == GFC_ARRAY_ALLOCATABLE
5908 || GFC_TYPE_ARRAY_AKIND (caf_type) == GFC_ARRAY_POINTER))
5909 tmp = gfc_conv_descriptor_token (caf_decl);
5910 else if (DECL_LANG_SPECIFIC (caf_decl)
5911 && GFC_DECL_TOKEN (caf_decl) != NULL_TREE)
5912 tmp = GFC_DECL_TOKEN (caf_decl);
5913 else
5915 gcc_assert (GFC_ARRAY_TYPE_P (caf_type)
5916 && GFC_TYPE_ARRAY_CAF_TOKEN (caf_type) != NULL_TREE);
5917 tmp = GFC_TYPE_ARRAY_CAF_TOKEN (caf_type);
5920 vec_safe_push (stringargs, tmp);
5922 if (GFC_DESCRIPTOR_TYPE_P (caf_type)
5923 && GFC_TYPE_ARRAY_AKIND (caf_type) == GFC_ARRAY_ALLOCATABLE)
5924 offset = build_int_cst (gfc_array_index_type, 0);
5925 else if (DECL_LANG_SPECIFIC (caf_decl)
5926 && GFC_DECL_CAF_OFFSET (caf_decl) != NULL_TREE)
5927 offset = GFC_DECL_CAF_OFFSET (caf_decl);
5928 else if (GFC_TYPE_ARRAY_CAF_OFFSET (caf_type) != NULL_TREE)
5929 offset = GFC_TYPE_ARRAY_CAF_OFFSET (caf_type);
5930 else
5931 offset = build_int_cst (gfc_array_index_type, 0);
5933 if (GFC_DESCRIPTOR_TYPE_P (caf_type))
5934 tmp = gfc_conv_descriptor_data_get (caf_decl);
5935 else
5937 gcc_assert (POINTER_TYPE_P (caf_type));
5938 tmp = caf_decl;
5941 tmp2 = fsym->ts.type == BT_CLASS
5942 ? gfc_class_data_get (parmse.expr) : parmse.expr;
5943 if ((fsym->ts.type != BT_CLASS
5944 && (fsym->as->type == AS_ASSUMED_SHAPE
5945 || fsym->as->type == AS_ASSUMED_RANK))
5946 || (fsym->ts.type == BT_CLASS
5947 && (CLASS_DATA (fsym)->as->type == AS_ASSUMED_SHAPE
5948 || CLASS_DATA (fsym)->as->type == AS_ASSUMED_RANK)))
5950 if (fsym->ts.type == BT_CLASS)
5951 gcc_assert (!POINTER_TYPE_P (TREE_TYPE (tmp2)));
5952 else
5954 gcc_assert (POINTER_TYPE_P (TREE_TYPE (tmp2)));
5955 tmp2 = build_fold_indirect_ref_loc (input_location, tmp2);
5957 gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp2)));
5958 tmp2 = gfc_conv_descriptor_data_get (tmp2);
5960 else if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp2)))
5961 tmp2 = gfc_conv_descriptor_data_get (tmp2);
5962 else
5964 gcc_assert (POINTER_TYPE_P (TREE_TYPE (tmp2)));
5967 tmp = fold_build2_loc (input_location, MINUS_EXPR,
5968 gfc_array_index_type,
5969 fold_convert (gfc_array_index_type, tmp2),
5970 fold_convert (gfc_array_index_type, tmp));
5971 offset = fold_build2_loc (input_location, PLUS_EXPR,
5972 gfc_array_index_type, offset, tmp);
5974 vec_safe_push (stringargs, offset);
5977 vec_safe_push (arglist, parmse.expr);
5979 gfc_finish_interface_mapping (&mapping, &se->pre, &se->post);
5981 if (comp)
5982 ts = comp->ts;
5983 else if (sym->ts.type == BT_CLASS)
5984 ts = CLASS_DATA (sym)->ts;
5985 else
5986 ts = sym->ts;
5988 if (ts.type == BT_CHARACTER && sym->attr.is_bind_c)
5989 se->string_length = build_int_cst (gfc_charlen_type_node, 1);
5990 else if (ts.type == BT_CHARACTER)
5992 if (ts.u.cl->length == NULL)
5994 /* Assumed character length results are not allowed by C418 of the 2003
5995 standard and are trapped in resolve.c; except in the case of SPREAD
5996 (and other intrinsics?) and dummy functions. In the case of SPREAD,
5997 we take the character length of the first argument for the result.
5998 For dummies, we have to look through the formal argument list for
5999 this function and use the character length found there.*/
6000 if (ts.deferred)
6001 cl.backend_decl = gfc_create_var (gfc_charlen_type_node, "slen");
6002 else if (!sym->attr.dummy)
6003 cl.backend_decl = (*stringargs)[0];
6004 else
6006 formal = gfc_sym_get_dummy_args (sym->ns->proc_name);
6007 for (; formal; formal = formal->next)
6008 if (strcmp (formal->sym->name, sym->name) == 0)
6009 cl.backend_decl = formal->sym->ts.u.cl->backend_decl;
6011 len = cl.backend_decl;
6013 else
6015 tree tmp;
6017 /* Calculate the length of the returned string. */
6018 gfc_init_se (&parmse, NULL);
6019 if (need_interface_mapping)
6020 gfc_apply_interface_mapping (&mapping, &parmse, ts.u.cl->length);
6021 else
6022 gfc_conv_expr (&parmse, ts.u.cl->length);
6023 gfc_add_block_to_block (&se->pre, &parmse.pre);
6024 gfc_add_block_to_block (&se->post, &parmse.post);
6025 tmp = parmse.expr;
6026 /* TODO: It would be better to have the charlens as
6027 gfc_charlen_type_node already when the interface is
6028 created instead of converting it here (see PR 84615). */
6029 tmp = fold_build2_loc (input_location, MAX_EXPR,
6030 gfc_charlen_type_node,
6031 fold_convert (gfc_charlen_type_node, tmp),
6032 build_zero_cst (gfc_charlen_type_node));
6033 cl.backend_decl = tmp;
6036 /* Set up a charlen structure for it. */
6037 cl.next = NULL;
6038 cl.length = NULL;
6039 ts.u.cl = &cl;
6041 len = cl.backend_decl;
6044 byref = (comp && (comp->attr.dimension
6045 || (comp->ts.type == BT_CHARACTER && !sym->attr.is_bind_c)))
6046 || (!comp && gfc_return_by_reference (sym));
6047 if (byref)
6049 if (se->direct_byref)
6051 /* Sometimes, too much indirection can be applied; e.g. for
6052 function_result = array_valued_recursive_function. */
6053 if (TREE_TYPE (TREE_TYPE (se->expr))
6054 && TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr)))
6055 && GFC_DESCRIPTOR_TYPE_P
6056 (TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr)))))
6057 se->expr = build_fold_indirect_ref_loc (input_location,
6058 se->expr);
6060 /* If the lhs of an assignment x = f(..) is allocatable and
6061 f2003 is allowed, we must do the automatic reallocation.
6062 TODO - deal with intrinsics, without using a temporary. */
6063 if (flag_realloc_lhs
6064 && se->ss && se->ss->loop_chain
6065 && se->ss->loop_chain->is_alloc_lhs
6066 && !expr->value.function.isym
6067 && sym->result->as != NULL)
6069 /* Evaluate the bounds of the result, if known. */
6070 gfc_set_loop_bounds_from_array_spec (&mapping, se,
6071 sym->result->as);
6073 /* Perform the automatic reallocation. */
6074 tmp = gfc_alloc_allocatable_for_assignment (se->loop,
6075 expr, NULL);
6076 gfc_add_expr_to_block (&se->pre, tmp);
6078 /* Pass the temporary as the first argument. */
6079 result = info->descriptor;
6081 else
6082 result = build_fold_indirect_ref_loc (input_location,
6083 se->expr);
6084 vec_safe_push (retargs, se->expr);
6086 else if (comp && comp->attr.dimension)
6088 gcc_assert (se->loop && info);
6090 /* Set the type of the array. */
6091 tmp = gfc_typenode_for_spec (&comp->ts);
6092 gcc_assert (se->ss->dimen == se->loop->dimen);
6094 /* Evaluate the bounds of the result, if known. */
6095 gfc_set_loop_bounds_from_array_spec (&mapping, se, comp->as);
6097 /* If the lhs of an assignment x = f(..) is allocatable and
6098 f2003 is allowed, we must not generate the function call
6099 here but should just send back the results of the mapping.
6100 This is signalled by the function ss being flagged. */
6101 if (flag_realloc_lhs && se->ss && se->ss->is_alloc_lhs)
6103 gfc_free_interface_mapping (&mapping);
6104 return has_alternate_specifier;
6107 /* Create a temporary to store the result. In case the function
6108 returns a pointer, the temporary will be a shallow copy and
6109 mustn't be deallocated. */
6110 callee_alloc = comp->attr.allocatable || comp->attr.pointer;
6111 gfc_trans_create_temp_array (&se->pre, &se->post, se->ss,
6112 tmp, NULL_TREE, false,
6113 !comp->attr.pointer, callee_alloc,
6114 &se->ss->info->expr->where);
6116 /* Pass the temporary as the first argument. */
6117 result = info->descriptor;
6118 tmp = gfc_build_addr_expr (NULL_TREE, result);
6119 vec_safe_push (retargs, tmp);
6121 else if (!comp && sym->result->attr.dimension)
6123 gcc_assert (se->loop && info);
6125 /* Set the type of the array. */
6126 tmp = gfc_typenode_for_spec (&ts);
6127 gcc_assert (se->ss->dimen == se->loop->dimen);
6129 /* Evaluate the bounds of the result, if known. */
6130 gfc_set_loop_bounds_from_array_spec (&mapping, se, sym->result->as);
6132 /* If the lhs of an assignment x = f(..) is allocatable and
6133 f2003 is allowed, we must not generate the function call
6134 here but should just send back the results of the mapping.
6135 This is signalled by the function ss being flagged. */
6136 if (flag_realloc_lhs && se->ss && se->ss->is_alloc_lhs)
6138 gfc_free_interface_mapping (&mapping);
6139 return has_alternate_specifier;
6142 /* Create a temporary to store the result. In case the function
6143 returns a pointer, the temporary will be a shallow copy and
6144 mustn't be deallocated. */
6145 callee_alloc = sym->attr.allocatable || sym->attr.pointer;
6146 gfc_trans_create_temp_array (&se->pre, &se->post, se->ss,
6147 tmp, NULL_TREE, false,
6148 !sym->attr.pointer, callee_alloc,
6149 &se->ss->info->expr->where);
6151 /* Pass the temporary as the first argument. */
6152 result = info->descriptor;
6153 tmp = gfc_build_addr_expr (NULL_TREE, result);
6154 vec_safe_push (retargs, tmp);
6156 else if (ts.type == BT_CHARACTER)
6158 /* Pass the string length. */
6159 type = gfc_get_character_type (ts.kind, ts.u.cl);
6160 type = build_pointer_type (type);
6162 /* Emit a DECL_EXPR for the VLA type. */
6163 tmp = TREE_TYPE (type);
6164 if (TYPE_SIZE (tmp)
6165 && TREE_CODE (TYPE_SIZE (tmp)) != INTEGER_CST)
6167 tmp = build_decl (input_location, TYPE_DECL, NULL_TREE, tmp);
6168 DECL_ARTIFICIAL (tmp) = 1;
6169 DECL_IGNORED_P (tmp) = 1;
6170 tmp = fold_build1_loc (input_location, DECL_EXPR,
6171 TREE_TYPE (tmp), tmp);
6172 gfc_add_expr_to_block (&se->pre, tmp);
6175 /* Return an address to a char[0:len-1]* temporary for
6176 character pointers. */
6177 if ((!comp && (sym->attr.pointer || sym->attr.allocatable))
6178 || (comp && (comp->attr.pointer || comp->attr.allocatable)))
6180 var = gfc_create_var (type, "pstr");
6182 if ((!comp && sym->attr.allocatable)
6183 || (comp && comp->attr.allocatable))
6185 gfc_add_modify (&se->pre, var,
6186 fold_convert (TREE_TYPE (var),
6187 null_pointer_node));
6188 tmp = gfc_call_free (var);
6189 gfc_add_expr_to_block (&se->post, tmp);
6192 /* Provide an address expression for the function arguments. */
6193 var = gfc_build_addr_expr (NULL_TREE, var);
6195 else
6196 var = gfc_conv_string_tmp (se, type, len);
6198 vec_safe_push (retargs, var);
6200 else
6202 gcc_assert (flag_f2c && ts.type == BT_COMPLEX);
6204 type = gfc_get_complex_type (ts.kind);
6205 var = gfc_build_addr_expr (NULL_TREE, gfc_create_var (type, "cmplx"));
6206 vec_safe_push (retargs, var);
6209 /* Add the string length to the argument list. */
6210 if (ts.type == BT_CHARACTER && ts.deferred)
6212 tmp = len;
6213 if (!VAR_P (tmp))
6214 tmp = gfc_evaluate_now (len, &se->pre);
6215 TREE_STATIC (tmp) = 1;
6216 gfc_add_modify (&se->pre, tmp,
6217 build_int_cst (TREE_TYPE (tmp), 0));
6218 tmp = gfc_build_addr_expr (NULL_TREE, tmp);
6219 vec_safe_push (retargs, tmp);
6221 else if (ts.type == BT_CHARACTER)
6222 vec_safe_push (retargs, len);
6224 gfc_free_interface_mapping (&mapping);
6226 /* We need to glom RETARGS + ARGLIST + STRINGARGS + APPEND_ARGS. */
6227 arglen = (vec_safe_length (arglist) + vec_safe_length (optionalargs)
6228 + vec_safe_length (stringargs) + vec_safe_length (append_args));
6229 vec_safe_reserve (retargs, arglen);
6231 /* Add the return arguments. */
6232 vec_safe_splice (retargs, arglist);
6234 /* Add the hidden present status for optional+value to the arguments. */
6235 vec_safe_splice (retargs, optionalargs);
6237 /* Add the hidden string length parameters to the arguments. */
6238 vec_safe_splice (retargs, stringargs);
6240 /* We may want to append extra arguments here. This is used e.g. for
6241 calls to libgfortran_matmul_??, which need extra information. */
6242 vec_safe_splice (retargs, append_args);
6244 arglist = retargs;
6246 /* Generate the actual call. */
6247 if (base_object == NULL_TREE)
6248 conv_function_val (se, sym, expr);
6249 else
6250 conv_base_obj_fcn_val (se, base_object, expr);
6252 /* If there are alternate return labels, function type should be
6253 integer. Can't modify the type in place though, since it can be shared
6254 with other functions. For dummy arguments, the typing is done to
6255 this result, even if it has to be repeated for each call. */
6256 if (has_alternate_specifier
6257 && TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr))) != integer_type_node)
6259 if (!sym->attr.dummy)
6261 TREE_TYPE (sym->backend_decl)
6262 = build_function_type (integer_type_node,
6263 TYPE_ARG_TYPES (TREE_TYPE (sym->backend_decl)));
6264 se->expr = gfc_build_addr_expr (NULL_TREE, sym->backend_decl);
6266 else
6267 TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr))) = integer_type_node;
6270 fntype = TREE_TYPE (TREE_TYPE (se->expr));
6271 se->expr = build_call_vec (TREE_TYPE (fntype), se->expr, arglist);
6273 /* Allocatable scalar function results must be freed and nullified
6274 after use. This necessitates the creation of a temporary to
6275 hold the result to prevent duplicate calls. */
6276 if (!byref && sym->ts.type != BT_CHARACTER
6277 && ((sym->attr.allocatable && !sym->attr.dimension && !comp)
6278 || (comp && comp->attr.allocatable && !comp->attr.dimension)))
6280 tmp = gfc_create_var (TREE_TYPE (se->expr), NULL);
6281 gfc_add_modify (&se->pre, tmp, se->expr);
6282 se->expr = tmp;
6283 tmp = gfc_call_free (tmp);
6284 gfc_add_expr_to_block (&post, tmp);
6285 gfc_add_modify (&post, se->expr, build_int_cst (TREE_TYPE (se->expr), 0));
6288 /* If we have a pointer function, but we don't want a pointer, e.g.
6289 something like
6290 x = f()
6291 where f is pointer valued, we have to dereference the result. */
6292 if (!se->want_pointer && !byref
6293 && ((!comp && (sym->attr.pointer || sym->attr.allocatable))
6294 || (comp && (comp->attr.pointer || comp->attr.allocatable))))
6295 se->expr = build_fold_indirect_ref_loc (input_location, se->expr);
6297 /* f2c calling conventions require a scalar default real function to
6298 return a double precision result. Convert this back to default
6299 real. We only care about the cases that can happen in Fortran 77.
6301 if (flag_f2c && sym->ts.type == BT_REAL
6302 && sym->ts.kind == gfc_default_real_kind
6303 && !sym->attr.always_explicit)
6304 se->expr = fold_convert (gfc_get_real_type (sym->ts.kind), se->expr);
6306 /* A pure function may still have side-effects - it may modify its
6307 parameters. */
6308 TREE_SIDE_EFFECTS (se->expr) = 1;
6309 #if 0
6310 if (!sym->attr.pure)
6311 TREE_SIDE_EFFECTS (se->expr) = 1;
6312 #endif
6314 if (byref)
6316 /* Add the function call to the pre chain. There is no expression. */
6317 gfc_add_expr_to_block (&se->pre, se->expr);
6318 se->expr = NULL_TREE;
6320 if (!se->direct_byref)
6322 if ((sym->attr.dimension && !comp) || (comp && comp->attr.dimension))
6324 if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
6326 /* Check the data pointer hasn't been modified. This would
6327 happen in a function returning a pointer. */
6328 tmp = gfc_conv_descriptor_data_get (info->descriptor);
6329 tmp = fold_build2_loc (input_location, NE_EXPR,
6330 logical_type_node,
6331 tmp, info->data);
6332 gfc_trans_runtime_check (true, false, tmp, &se->pre, NULL,
6333 gfc_msg_fault);
6335 se->expr = info->descriptor;
6336 /* Bundle in the string length. */
6337 se->string_length = len;
6339 else if (ts.type == BT_CHARACTER)
6341 /* Dereference for character pointer results. */
6342 if ((!comp && (sym->attr.pointer || sym->attr.allocatable))
6343 || (comp && (comp->attr.pointer || comp->attr.allocatable)))
6344 se->expr = build_fold_indirect_ref_loc (input_location, var);
6345 else
6346 se->expr = var;
6348 se->string_length = len;
6350 else
6352 gcc_assert (ts.type == BT_COMPLEX && flag_f2c);
6353 se->expr = build_fold_indirect_ref_loc (input_location, var);
6358 /* Associate the rhs class object's meta-data with the result, when the
6359 result is a temporary. */
6360 if (args && args->expr && args->expr->ts.type == BT_CLASS
6361 && sym->ts.type == BT_CLASS && result != NULL_TREE && DECL_P (result)
6362 && !GFC_CLASS_TYPE_P (TREE_TYPE (result)))
6364 gfc_se parmse;
6365 gfc_expr *class_expr = gfc_find_and_cut_at_last_class_ref (args->expr);
6367 gfc_init_se (&parmse, NULL);
6368 parmse.data_not_needed = 1;
6369 gfc_conv_expr (&parmse, class_expr);
6370 if (!DECL_LANG_SPECIFIC (result))
6371 gfc_allocate_lang_decl (result);
6372 GFC_DECL_SAVED_DESCRIPTOR (result) = parmse.expr;
6373 gfc_free_expr (class_expr);
6374 gcc_assert (parmse.pre.head == NULL_TREE
6375 && parmse.post.head == NULL_TREE);
6378 /* Follow the function call with the argument post block. */
6379 if (byref)
6381 gfc_add_block_to_block (&se->pre, &post);
6383 /* Transformational functions of derived types with allocatable
6384 components must have the result allocatable components copied when the
6385 argument is actually given. */
6386 arg = expr->value.function.actual;
6387 if (result && arg && expr->rank
6388 && expr->value.function.isym
6389 && expr->value.function.isym->transformational
6390 && arg->expr
6391 && arg->expr->ts.type == BT_DERIVED
6392 && arg->expr->ts.u.derived->attr.alloc_comp)
6394 tree tmp2;
6395 /* Copy the allocatable components. We have to use a
6396 temporary here to prevent source allocatable components
6397 from being corrupted. */
6398 tmp2 = gfc_evaluate_now (result, &se->pre);
6399 tmp = gfc_copy_alloc_comp (arg->expr->ts.u.derived,
6400 result, tmp2, expr->rank, 0);
6401 gfc_add_expr_to_block (&se->pre, tmp);
6402 tmp = gfc_copy_allocatable_data (result, tmp2, TREE_TYPE(tmp2),
6403 expr->rank);
6404 gfc_add_expr_to_block (&se->pre, tmp);
6406 /* Finally free the temporary's data field. */
6407 tmp = gfc_conv_descriptor_data_get (tmp2);
6408 tmp = gfc_deallocate_with_status (tmp, NULL_TREE, NULL_TREE,
6409 NULL_TREE, NULL_TREE, true,
6410 NULL, GFC_CAF_COARRAY_NOCOARRAY);
6411 gfc_add_expr_to_block (&se->pre, tmp);
6414 else
6416 /* For a function with a class array result, save the result as
6417 a temporary, set the info fields needed by the scalarizer and
6418 call the finalization function of the temporary. Note that the
6419 nullification of allocatable components needed by the result
6420 is done in gfc_trans_assignment_1. */
6421 if (expr && ((gfc_is_class_array_function (expr)
6422 && se->ss && se->ss->loop)
6423 || gfc_is_alloc_class_scalar_function (expr))
6424 && se->expr && GFC_CLASS_TYPE_P (TREE_TYPE (se->expr))
6425 && expr->must_finalize)
6427 tree final_fndecl;
6428 tree is_final;
6429 int n;
6430 if (se->ss && se->ss->loop)
6432 gfc_add_block_to_block (&se->ss->loop->pre, &se->pre);
6433 se->expr = gfc_evaluate_now (se->expr, &se->ss->loop->pre);
6434 tmp = gfc_class_data_get (se->expr);
6435 info->descriptor = tmp;
6436 info->data = gfc_conv_descriptor_data_get (tmp);
6437 info->offset = gfc_conv_descriptor_offset_get (tmp);
6438 for (n = 0; n < se->ss->loop->dimen; n++)
6440 tree dim = gfc_rank_cst[n];
6441 se->ss->loop->to[n] = gfc_conv_descriptor_ubound_get (tmp, dim);
6442 se->ss->loop->from[n] = gfc_conv_descriptor_lbound_get (tmp, dim);
6445 else
6447 /* TODO Eliminate the doubling of temporaries. This
6448 one is necessary to ensure no memory leakage. */
6449 se->expr = gfc_evaluate_now (se->expr, &se->pre);
6450 tmp = gfc_class_data_get (se->expr);
6451 tmp = gfc_conv_scalar_to_descriptor (se, tmp,
6452 CLASS_DATA (expr->value.function.esym->result)->attr);
6455 if ((gfc_is_class_array_function (expr)
6456 || gfc_is_alloc_class_scalar_function (expr))
6457 && CLASS_DATA (expr->value.function.esym->result)->attr.pointer)
6458 goto no_finalization;
6460 final_fndecl = gfc_class_vtab_final_get (se->expr);
6461 is_final = fold_build2_loc (input_location, NE_EXPR,
6462 logical_type_node,
6463 final_fndecl,
6464 fold_convert (TREE_TYPE (final_fndecl),
6465 null_pointer_node));
6466 final_fndecl = build_fold_indirect_ref_loc (input_location,
6467 final_fndecl);
6468 tmp = build_call_expr_loc (input_location,
6469 final_fndecl, 3,
6470 gfc_build_addr_expr (NULL, tmp),
6471 gfc_class_vtab_size_get (se->expr),
6472 boolean_false_node);
6473 tmp = fold_build3_loc (input_location, COND_EXPR,
6474 void_type_node, is_final, tmp,
6475 build_empty_stmt (input_location));
6477 if (se->ss && se->ss->loop)
6479 gfc_prepend_expr_to_block (&se->ss->loop->post, tmp);
6480 tmp = fold_build2_loc (input_location, NE_EXPR,
6481 logical_type_node,
6482 info->data,
6483 fold_convert (TREE_TYPE (info->data),
6484 null_pointer_node));
6485 tmp = fold_build3_loc (input_location, COND_EXPR,
6486 void_type_node, tmp,
6487 gfc_call_free (info->data),
6488 build_empty_stmt (input_location));
6489 gfc_add_expr_to_block (&se->ss->loop->post, tmp);
6491 else
6493 tree classdata;
6494 gfc_prepend_expr_to_block (&se->post, tmp);
6495 classdata = gfc_class_data_get (se->expr);
6496 tmp = fold_build2_loc (input_location, NE_EXPR,
6497 logical_type_node,
6498 classdata,
6499 fold_convert (TREE_TYPE (classdata),
6500 null_pointer_node));
6501 tmp = fold_build3_loc (input_location, COND_EXPR,
6502 void_type_node, tmp,
6503 gfc_call_free (classdata),
6504 build_empty_stmt (input_location));
6505 gfc_add_expr_to_block (&se->post, tmp);
6509 no_finalization:
6510 gfc_add_block_to_block (&se->post, &post);
6513 return has_alternate_specifier;
6517 /* Fill a character string with spaces. */
6519 static tree
6520 fill_with_spaces (tree start, tree type, tree size)
6522 stmtblock_t block, loop;
6523 tree i, el, exit_label, cond, tmp;
6525 /* For a simple char type, we can call memset(). */
6526 if (compare_tree_int (TYPE_SIZE_UNIT (type), 1) == 0)
6527 return build_call_expr_loc (input_location,
6528 builtin_decl_explicit (BUILT_IN_MEMSET),
6529 3, start,
6530 build_int_cst (gfc_get_int_type (gfc_c_int_kind),
6531 lang_hooks.to_target_charset (' ')),
6532 fold_convert (size_type_node, size));
6534 /* Otherwise, we use a loop:
6535 for (el = start, i = size; i > 0; el--, i+= TYPE_SIZE_UNIT (type))
6536 *el = (type) ' ';
6539 /* Initialize variables. */
6540 gfc_init_block (&block);
6541 i = gfc_create_var (sizetype, "i");
6542 gfc_add_modify (&block, i, fold_convert (sizetype, size));
6543 el = gfc_create_var (build_pointer_type (type), "el");
6544 gfc_add_modify (&block, el, fold_convert (TREE_TYPE (el), start));
6545 exit_label = gfc_build_label_decl (NULL_TREE);
6546 TREE_USED (exit_label) = 1;
6549 /* Loop body. */
6550 gfc_init_block (&loop);
6552 /* Exit condition. */
6553 cond = fold_build2_loc (input_location, LE_EXPR, logical_type_node, i,
6554 build_zero_cst (sizetype));
6555 tmp = build1_v (GOTO_EXPR, exit_label);
6556 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond, tmp,
6557 build_empty_stmt (input_location));
6558 gfc_add_expr_to_block (&loop, tmp);
6560 /* Assignment. */
6561 gfc_add_modify (&loop,
6562 fold_build1_loc (input_location, INDIRECT_REF, type, el),
6563 build_int_cst (type, lang_hooks.to_target_charset (' ')));
6565 /* Increment loop variables. */
6566 gfc_add_modify (&loop, i,
6567 fold_build2_loc (input_location, MINUS_EXPR, sizetype, i,
6568 TYPE_SIZE_UNIT (type)));
6569 gfc_add_modify (&loop, el,
6570 fold_build_pointer_plus_loc (input_location,
6571 el, TYPE_SIZE_UNIT (type)));
6573 /* Making the loop... actually loop! */
6574 tmp = gfc_finish_block (&loop);
6575 tmp = build1_v (LOOP_EXPR, tmp);
6576 gfc_add_expr_to_block (&block, tmp);
6578 /* The exit label. */
6579 tmp = build1_v (LABEL_EXPR, exit_label);
6580 gfc_add_expr_to_block (&block, tmp);
6583 return gfc_finish_block (&block);
6587 /* Generate code to copy a string. */
6589 void
6590 gfc_trans_string_copy (stmtblock_t * block, tree dlength, tree dest,
6591 int dkind, tree slength, tree src, int skind)
6593 tree tmp, dlen, slen;
6594 tree dsc;
6595 tree ssc;
6596 tree cond;
6597 tree cond2;
6598 tree tmp2;
6599 tree tmp3;
6600 tree tmp4;
6601 tree chartype;
6602 stmtblock_t tempblock;
6604 gcc_assert (dkind == skind);
6606 if (slength != NULL_TREE)
6608 slen = gfc_evaluate_now (fold_convert (gfc_charlen_type_node, slength), block);
6609 ssc = gfc_string_to_single_character (slen, src, skind);
6611 else
6613 slen = build_one_cst (gfc_charlen_type_node);
6614 ssc = src;
6617 if (dlength != NULL_TREE)
6619 dlen = gfc_evaluate_now (fold_convert (gfc_charlen_type_node, dlength), block);
6620 dsc = gfc_string_to_single_character (dlen, dest, dkind);
6622 else
6624 dlen = build_one_cst (gfc_charlen_type_node);
6625 dsc = dest;
6628 /* Assign directly if the types are compatible. */
6629 if (dsc != NULL_TREE && ssc != NULL_TREE
6630 && TREE_TYPE (dsc) == TREE_TYPE (ssc))
6632 gfc_add_modify (block, dsc, ssc);
6633 return;
6636 /* The string copy algorithm below generates code like
6638 if (destlen > 0)
6640 if (srclen < destlen)
6642 memmove (dest, src, srclen);
6643 // Pad with spaces.
6644 memset (&dest[srclen], ' ', destlen - srclen);
6646 else
6648 // Truncate if too long.
6649 memmove (dest, src, destlen);
6654 /* Do nothing if the destination length is zero. */
6655 cond = fold_build2_loc (input_location, GT_EXPR, logical_type_node, dlen,
6656 build_zero_cst (TREE_TYPE (dlen)));
6658 /* For non-default character kinds, we have to multiply the string
6659 length by the base type size. */
6660 chartype = gfc_get_char_type (dkind);
6661 slen = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (slen),
6662 slen,
6663 fold_convert (TREE_TYPE (slen),
6664 TYPE_SIZE_UNIT (chartype)));
6665 dlen = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (dlen),
6666 dlen,
6667 fold_convert (TREE_TYPE (dlen),
6668 TYPE_SIZE_UNIT (chartype)));
6670 if (dlength && POINTER_TYPE_P (TREE_TYPE (dest)))
6671 dest = fold_convert (pvoid_type_node, dest);
6672 else
6673 dest = gfc_build_addr_expr (pvoid_type_node, dest);
6675 if (slength && POINTER_TYPE_P (TREE_TYPE (src)))
6676 src = fold_convert (pvoid_type_node, src);
6677 else
6678 src = gfc_build_addr_expr (pvoid_type_node, src);
6680 /* Truncate string if source is too long. */
6681 cond2 = fold_build2_loc (input_location, LT_EXPR, logical_type_node, slen,
6682 dlen);
6684 /* Copy and pad with spaces. */
6685 tmp3 = build_call_expr_loc (input_location,
6686 builtin_decl_explicit (BUILT_IN_MEMMOVE),
6687 3, dest, src,
6688 fold_convert (size_type_node, slen));
6690 /* Wstringop-overflow appears at -O3 even though this warning is not
6691 explicitly available in fortran nor can it be switched off. If the
6692 source length is a constant, its negative appears as a very large
6693 postive number and triggers the warning in BUILTIN_MEMSET. Fixing
6694 the result of the MINUS_EXPR suppresses this spurious warning. */
6695 tmp = fold_build2_loc (input_location, MINUS_EXPR,
6696 TREE_TYPE(dlen), dlen, slen);
6697 if (slength && TREE_CONSTANT (slength))
6698 tmp = gfc_evaluate_now (tmp, block);
6700 tmp4 = fold_build_pointer_plus_loc (input_location, dest, slen);
6701 tmp4 = fill_with_spaces (tmp4, chartype, tmp);
6703 gfc_init_block (&tempblock);
6704 gfc_add_expr_to_block (&tempblock, tmp3);
6705 gfc_add_expr_to_block (&tempblock, tmp4);
6706 tmp3 = gfc_finish_block (&tempblock);
6708 /* The truncated memmove if the slen >= dlen. */
6709 tmp2 = build_call_expr_loc (input_location,
6710 builtin_decl_explicit (BUILT_IN_MEMMOVE),
6711 3, dest, src,
6712 fold_convert (size_type_node, dlen));
6714 /* The whole copy_string function is there. */
6715 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond2,
6716 tmp3, tmp2);
6717 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond, tmp,
6718 build_empty_stmt (input_location));
6719 gfc_add_expr_to_block (block, tmp);
6723 /* Translate a statement function.
6724 The value of a statement function reference is obtained by evaluating the
6725 expression using the values of the actual arguments for the values of the
6726 corresponding dummy arguments. */
6728 static void
6729 gfc_conv_statement_function (gfc_se * se, gfc_expr * expr)
6731 gfc_symbol *sym;
6732 gfc_symbol *fsym;
6733 gfc_formal_arglist *fargs;
6734 gfc_actual_arglist *args;
6735 gfc_se lse;
6736 gfc_se rse;
6737 gfc_saved_var *saved_vars;
6738 tree *temp_vars;
6739 tree type;
6740 tree tmp;
6741 int n;
6743 sym = expr->symtree->n.sym;
6744 args = expr->value.function.actual;
6745 gfc_init_se (&lse, NULL);
6746 gfc_init_se (&rse, NULL);
6748 n = 0;
6749 for (fargs = gfc_sym_get_dummy_args (sym); fargs; fargs = fargs->next)
6750 n++;
6751 saved_vars = XCNEWVEC (gfc_saved_var, n);
6752 temp_vars = XCNEWVEC (tree, n);
6754 for (fargs = gfc_sym_get_dummy_args (sym), n = 0; fargs;
6755 fargs = fargs->next, n++)
6757 /* Each dummy shall be specified, explicitly or implicitly, to be
6758 scalar. */
6759 gcc_assert (fargs->sym->attr.dimension == 0);
6760 fsym = fargs->sym;
6762 if (fsym->ts.type == BT_CHARACTER)
6764 /* Copy string arguments. */
6765 tree arglen;
6767 gcc_assert (fsym->ts.u.cl && fsym->ts.u.cl->length
6768 && fsym->ts.u.cl->length->expr_type == EXPR_CONSTANT);
6770 /* Create a temporary to hold the value. */
6771 if (fsym->ts.u.cl->backend_decl == NULL_TREE)
6772 fsym->ts.u.cl->backend_decl
6773 = gfc_conv_constant_to_tree (fsym->ts.u.cl->length);
6775 type = gfc_get_character_type (fsym->ts.kind, fsym->ts.u.cl);
6776 temp_vars[n] = gfc_create_var (type, fsym->name);
6778 arglen = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
6780 gfc_conv_expr (&rse, args->expr);
6781 gfc_conv_string_parameter (&rse);
6782 gfc_add_block_to_block (&se->pre, &lse.pre);
6783 gfc_add_block_to_block (&se->pre, &rse.pre);
6785 gfc_trans_string_copy (&se->pre, arglen, temp_vars[n], fsym->ts.kind,
6786 rse.string_length, rse.expr, fsym->ts.kind);
6787 gfc_add_block_to_block (&se->pre, &lse.post);
6788 gfc_add_block_to_block (&se->pre, &rse.post);
6790 else
6792 /* For everything else, just evaluate the expression. */
6794 /* Create a temporary to hold the value. */
6795 type = gfc_typenode_for_spec (&fsym->ts);
6796 temp_vars[n] = gfc_create_var (type, fsym->name);
6798 gfc_conv_expr (&lse, args->expr);
6800 gfc_add_block_to_block (&se->pre, &lse.pre);
6801 gfc_add_modify (&se->pre, temp_vars[n], lse.expr);
6802 gfc_add_block_to_block (&se->pre, &lse.post);
6805 args = args->next;
6808 /* Use the temporary variables in place of the real ones. */
6809 for (fargs = gfc_sym_get_dummy_args (sym), n = 0; fargs;
6810 fargs = fargs->next, n++)
6811 gfc_shadow_sym (fargs->sym, temp_vars[n], &saved_vars[n]);
6813 gfc_conv_expr (se, sym->value);
6815 if (sym->ts.type == BT_CHARACTER)
6817 gfc_conv_const_charlen (sym->ts.u.cl);
6819 /* Force the expression to the correct length. */
6820 if (!INTEGER_CST_P (se->string_length)
6821 || tree_int_cst_lt (se->string_length,
6822 sym->ts.u.cl->backend_decl))
6824 type = gfc_get_character_type (sym->ts.kind, sym->ts.u.cl);
6825 tmp = gfc_create_var (type, sym->name);
6826 tmp = gfc_build_addr_expr (build_pointer_type (type), tmp);
6827 gfc_trans_string_copy (&se->pre, sym->ts.u.cl->backend_decl, tmp,
6828 sym->ts.kind, se->string_length, se->expr,
6829 sym->ts.kind);
6830 se->expr = tmp;
6832 se->string_length = sym->ts.u.cl->backend_decl;
6835 /* Restore the original variables. */
6836 for (fargs = gfc_sym_get_dummy_args (sym), n = 0; fargs;
6837 fargs = fargs->next, n++)
6838 gfc_restore_sym (fargs->sym, &saved_vars[n]);
6839 free (temp_vars);
6840 free (saved_vars);
6844 /* Translate a function expression. */
6846 static void
6847 gfc_conv_function_expr (gfc_se * se, gfc_expr * expr)
6849 gfc_symbol *sym;
6851 if (expr->value.function.isym)
6853 gfc_conv_intrinsic_function (se, expr);
6854 return;
6857 /* expr.value.function.esym is the resolved (specific) function symbol for
6858 most functions. However this isn't set for dummy procedures. */
6859 sym = expr->value.function.esym;
6860 if (!sym)
6861 sym = expr->symtree->n.sym;
6863 /* The IEEE_ARITHMETIC functions are caught here. */
6864 if (sym->from_intmod == INTMOD_IEEE_ARITHMETIC)
6865 if (gfc_conv_ieee_arithmetic_function (se, expr))
6866 return;
6868 /* We distinguish statement functions from general functions to improve
6869 runtime performance. */
6870 if (sym->attr.proc == PROC_ST_FUNCTION)
6872 gfc_conv_statement_function (se, expr);
6873 return;
6876 gfc_conv_procedure_call (se, sym, expr->value.function.actual, expr,
6877 NULL);
6881 /* Determine whether the given EXPR_CONSTANT is a zero initializer. */
6883 static bool
6884 is_zero_initializer_p (gfc_expr * expr)
6886 if (expr->expr_type != EXPR_CONSTANT)
6887 return false;
6889 /* We ignore constants with prescribed memory representations for now. */
6890 if (expr->representation.string)
6891 return false;
6893 switch (expr->ts.type)
6895 case BT_INTEGER:
6896 return mpz_cmp_si (expr->value.integer, 0) == 0;
6898 case BT_REAL:
6899 return mpfr_zero_p (expr->value.real)
6900 && MPFR_SIGN (expr->value.real) >= 0;
6902 case BT_LOGICAL:
6903 return expr->value.logical == 0;
6905 case BT_COMPLEX:
6906 return mpfr_zero_p (mpc_realref (expr->value.complex))
6907 && MPFR_SIGN (mpc_realref (expr->value.complex)) >= 0
6908 && mpfr_zero_p (mpc_imagref (expr->value.complex))
6909 && MPFR_SIGN (mpc_imagref (expr->value.complex)) >= 0;
6911 default:
6912 break;
6914 return false;
6918 static void
6919 gfc_conv_array_constructor_expr (gfc_se * se, gfc_expr * expr)
6921 gfc_ss *ss;
6923 ss = se->ss;
6924 gcc_assert (ss != NULL && ss != gfc_ss_terminator);
6925 gcc_assert (ss->info->expr == expr && ss->info->type == GFC_SS_CONSTRUCTOR);
6927 gfc_conv_tmp_array_ref (se);
6931 /* Build a static initializer. EXPR is the expression for the initial value.
6932 The other parameters describe the variable of the component being
6933 initialized. EXPR may be null. */
6935 tree
6936 gfc_conv_initializer (gfc_expr * expr, gfc_typespec * ts, tree type,
6937 bool array, bool pointer, bool procptr)
6939 gfc_se se;
6941 if (flag_coarray != GFC_FCOARRAY_LIB && ts->type == BT_DERIVED
6942 && ts->u.derived->from_intmod == INTMOD_ISO_FORTRAN_ENV
6943 && ts->u.derived->intmod_sym_id == ISOFORTRAN_EVENT_TYPE)
6944 return build_constructor (type, NULL);
6946 if (!(expr || pointer || procptr))
6947 return NULL_TREE;
6949 /* Check if we have ISOCBINDING_NULL_PTR or ISOCBINDING_NULL_FUNPTR
6950 (these are the only two iso_c_binding derived types that can be
6951 used as initialization expressions). If so, we need to modify
6952 the 'expr' to be that for a (void *). */
6953 if (expr != NULL && expr->ts.type == BT_DERIVED
6954 && expr->ts.is_iso_c && expr->ts.u.derived)
6956 gfc_symbol *derived = expr->ts.u.derived;
6958 /* The derived symbol has already been converted to a (void *). Use
6959 its kind. */
6960 if (derived->ts.kind == 0)
6961 derived->ts.kind = gfc_default_integer_kind;
6962 expr = gfc_get_int_expr (derived->ts.kind, NULL, 0);
6963 expr->ts.f90_type = derived->ts.f90_type;
6965 gfc_init_se (&se, NULL);
6966 gfc_conv_constant (&se, expr);
6967 gcc_assert (TREE_CODE (se.expr) != CONSTRUCTOR);
6968 return se.expr;
6971 if (array && !procptr)
6973 tree ctor;
6974 /* Arrays need special handling. */
6975 if (pointer)
6976 ctor = gfc_build_null_descriptor (type);
6977 /* Special case assigning an array to zero. */
6978 else if (is_zero_initializer_p (expr))
6979 ctor = build_constructor (type, NULL);
6980 else
6981 ctor = gfc_conv_array_initializer (type, expr);
6982 TREE_STATIC (ctor) = 1;
6983 return ctor;
6985 else if (pointer || procptr)
6987 if (ts->type == BT_CLASS && !procptr)
6989 gfc_init_se (&se, NULL);
6990 gfc_conv_structure (&se, gfc_class_initializer (ts, expr), 1);
6991 gcc_assert (TREE_CODE (se.expr) == CONSTRUCTOR);
6992 TREE_STATIC (se.expr) = 1;
6993 return se.expr;
6995 else if (!expr || expr->expr_type == EXPR_NULL)
6996 return fold_convert (type, null_pointer_node);
6997 else
6999 gfc_init_se (&se, NULL);
7000 se.want_pointer = 1;
7001 gfc_conv_expr (&se, expr);
7002 gcc_assert (TREE_CODE (se.expr) != CONSTRUCTOR);
7003 return se.expr;
7006 else
7008 switch (ts->type)
7010 case_bt_struct:
7011 case BT_CLASS:
7012 gfc_init_se (&se, NULL);
7013 if (ts->type == BT_CLASS && expr->expr_type == EXPR_NULL)
7014 gfc_conv_structure (&se, gfc_class_initializer (ts, expr), 1);
7015 else
7016 gfc_conv_structure (&se, expr, 1);
7017 gcc_assert (TREE_CODE (se.expr) == CONSTRUCTOR);
7018 TREE_STATIC (se.expr) = 1;
7019 return se.expr;
7021 case BT_CHARACTER:
7023 tree ctor = gfc_conv_string_init (ts->u.cl->backend_decl,expr);
7024 TREE_STATIC (ctor) = 1;
7025 return ctor;
7028 default:
7029 gfc_init_se (&se, NULL);
7030 gfc_conv_constant (&se, expr);
7031 gcc_assert (TREE_CODE (se.expr) != CONSTRUCTOR);
7032 return se.expr;
7037 static tree
7038 gfc_trans_subarray_assign (tree dest, gfc_component * cm, gfc_expr * expr)
7040 gfc_se rse;
7041 gfc_se lse;
7042 gfc_ss *rss;
7043 gfc_ss *lss;
7044 gfc_array_info *lss_array;
7045 stmtblock_t body;
7046 stmtblock_t block;
7047 gfc_loopinfo loop;
7048 int n;
7049 tree tmp;
7051 gfc_start_block (&block);
7053 /* Initialize the scalarizer. */
7054 gfc_init_loopinfo (&loop);
7056 gfc_init_se (&lse, NULL);
7057 gfc_init_se (&rse, NULL);
7059 /* Walk the rhs. */
7060 rss = gfc_walk_expr (expr);
7061 if (rss == gfc_ss_terminator)
7062 /* The rhs is scalar. Add a ss for the expression. */
7063 rss = gfc_get_scalar_ss (gfc_ss_terminator, expr);
7065 /* Create a SS for the destination. */
7066 lss = gfc_get_array_ss (gfc_ss_terminator, NULL, cm->as->rank,
7067 GFC_SS_COMPONENT);
7068 lss_array = &lss->info->data.array;
7069 lss_array->shape = gfc_get_shape (cm->as->rank);
7070 lss_array->descriptor = dest;
7071 lss_array->data = gfc_conv_array_data (dest);
7072 lss_array->offset = gfc_conv_array_offset (dest);
7073 for (n = 0; n < cm->as->rank; n++)
7075 lss_array->start[n] = gfc_conv_array_lbound (dest, n);
7076 lss_array->stride[n] = gfc_index_one_node;
7078 mpz_init (lss_array->shape[n]);
7079 mpz_sub (lss_array->shape[n], cm->as->upper[n]->value.integer,
7080 cm->as->lower[n]->value.integer);
7081 mpz_add_ui (lss_array->shape[n], lss_array->shape[n], 1);
7084 /* Associate the SS with the loop. */
7085 gfc_add_ss_to_loop (&loop, lss);
7086 gfc_add_ss_to_loop (&loop, rss);
7088 /* Calculate the bounds of the scalarization. */
7089 gfc_conv_ss_startstride (&loop);
7091 /* Setup the scalarizing loops. */
7092 gfc_conv_loop_setup (&loop, &expr->where);
7094 /* Setup the gfc_se structures. */
7095 gfc_copy_loopinfo_to_se (&lse, &loop);
7096 gfc_copy_loopinfo_to_se (&rse, &loop);
7098 rse.ss = rss;
7099 gfc_mark_ss_chain_used (rss, 1);
7100 lse.ss = lss;
7101 gfc_mark_ss_chain_used (lss, 1);
7103 /* Start the scalarized loop body. */
7104 gfc_start_scalarized_body (&loop, &body);
7106 gfc_conv_tmp_array_ref (&lse);
7107 if (cm->ts.type == BT_CHARACTER)
7108 lse.string_length = cm->ts.u.cl->backend_decl;
7110 gfc_conv_expr (&rse, expr);
7112 tmp = gfc_trans_scalar_assign (&lse, &rse, cm->ts, true, false);
7113 gfc_add_expr_to_block (&body, tmp);
7115 gcc_assert (rse.ss == gfc_ss_terminator);
7117 /* Generate the copying loops. */
7118 gfc_trans_scalarizing_loops (&loop, &body);
7120 /* Wrap the whole thing up. */
7121 gfc_add_block_to_block (&block, &loop.pre);
7122 gfc_add_block_to_block (&block, &loop.post);
7124 gcc_assert (lss_array->shape != NULL);
7125 gfc_free_shape (&lss_array->shape, cm->as->rank);
7126 gfc_cleanup_loop (&loop);
7128 return gfc_finish_block (&block);
7132 static tree
7133 gfc_trans_alloc_subarray_assign (tree dest, gfc_component * cm,
7134 gfc_expr * expr)
7136 gfc_se se;
7137 stmtblock_t block;
7138 tree offset;
7139 int n;
7140 tree tmp;
7141 tree tmp2;
7142 gfc_array_spec *as;
7143 gfc_expr *arg = NULL;
7145 gfc_start_block (&block);
7146 gfc_init_se (&se, NULL);
7148 /* Get the descriptor for the expressions. */
7149 se.want_pointer = 0;
7150 gfc_conv_expr_descriptor (&se, expr);
7151 gfc_add_block_to_block (&block, &se.pre);
7152 gfc_add_modify (&block, dest, se.expr);
7154 /* Deal with arrays of derived types with allocatable components. */
7155 if (gfc_bt_struct (cm->ts.type)
7156 && cm->ts.u.derived->attr.alloc_comp)
7157 // TODO: Fix caf_mode
7158 tmp = gfc_copy_alloc_comp (cm->ts.u.derived,
7159 se.expr, dest,
7160 cm->as->rank, 0);
7161 else if (cm->ts.type == BT_CLASS && expr->ts.type == BT_DERIVED
7162 && CLASS_DATA(cm)->attr.allocatable)
7164 if (cm->ts.u.derived->attr.alloc_comp)
7165 // TODO: Fix caf_mode
7166 tmp = gfc_copy_alloc_comp (expr->ts.u.derived,
7167 se.expr, dest,
7168 expr->rank, 0);
7169 else
7171 tmp = TREE_TYPE (dest);
7172 tmp = gfc_duplicate_allocatable (dest, se.expr,
7173 tmp, expr->rank, NULL_TREE);
7176 else
7177 tmp = gfc_duplicate_allocatable (dest, se.expr,
7178 TREE_TYPE(cm->backend_decl),
7179 cm->as->rank, NULL_TREE);
7181 gfc_add_expr_to_block (&block, tmp);
7182 gfc_add_block_to_block (&block, &se.post);
7184 if (expr->expr_type != EXPR_VARIABLE)
7185 gfc_conv_descriptor_data_set (&block, se.expr,
7186 null_pointer_node);
7188 /* We need to know if the argument of a conversion function is a
7189 variable, so that the correct lower bound can be used. */
7190 if (expr->expr_type == EXPR_FUNCTION
7191 && expr->value.function.isym
7192 && expr->value.function.isym->conversion
7193 && expr->value.function.actual->expr
7194 && expr->value.function.actual->expr->expr_type == EXPR_VARIABLE)
7195 arg = expr->value.function.actual->expr;
7197 /* Obtain the array spec of full array references. */
7198 if (arg)
7199 as = gfc_get_full_arrayspec_from_expr (arg);
7200 else
7201 as = gfc_get_full_arrayspec_from_expr (expr);
7203 /* Shift the lbound and ubound of temporaries to being unity,
7204 rather than zero, based. Always calculate the offset. */
7205 offset = gfc_conv_descriptor_offset_get (dest);
7206 gfc_add_modify (&block, offset, gfc_index_zero_node);
7207 tmp2 =gfc_create_var (gfc_array_index_type, NULL);
7209 for (n = 0; n < expr->rank; n++)
7211 tree span;
7212 tree lbound;
7214 /* Obtain the correct lbound - ISO/IEC TR 15581:2001 page 9.
7215 TODO It looks as if gfc_conv_expr_descriptor should return
7216 the correct bounds and that the following should not be
7217 necessary. This would simplify gfc_conv_intrinsic_bound
7218 as well. */
7219 if (as && as->lower[n])
7221 gfc_se lbse;
7222 gfc_init_se (&lbse, NULL);
7223 gfc_conv_expr (&lbse, as->lower[n]);
7224 gfc_add_block_to_block (&block, &lbse.pre);
7225 lbound = gfc_evaluate_now (lbse.expr, &block);
7227 else if (as && arg)
7229 tmp = gfc_get_symbol_decl (arg->symtree->n.sym);
7230 lbound = gfc_conv_descriptor_lbound_get (tmp,
7231 gfc_rank_cst[n]);
7233 else if (as)
7234 lbound = gfc_conv_descriptor_lbound_get (dest,
7235 gfc_rank_cst[n]);
7236 else
7237 lbound = gfc_index_one_node;
7239 lbound = fold_convert (gfc_array_index_type, lbound);
7241 /* Shift the bounds and set the offset accordingly. */
7242 tmp = gfc_conv_descriptor_ubound_get (dest, gfc_rank_cst[n]);
7243 span = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
7244 tmp, gfc_conv_descriptor_lbound_get (dest, gfc_rank_cst[n]));
7245 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
7246 span, lbound);
7247 gfc_conv_descriptor_ubound_set (&block, dest,
7248 gfc_rank_cst[n], tmp);
7249 gfc_conv_descriptor_lbound_set (&block, dest,
7250 gfc_rank_cst[n], lbound);
7252 tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
7253 gfc_conv_descriptor_lbound_get (dest,
7254 gfc_rank_cst[n]),
7255 gfc_conv_descriptor_stride_get (dest,
7256 gfc_rank_cst[n]));
7257 gfc_add_modify (&block, tmp2, tmp);
7258 tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
7259 offset, tmp2);
7260 gfc_conv_descriptor_offset_set (&block, dest, tmp);
7263 if (arg)
7265 /* If a conversion expression has a null data pointer
7266 argument, nullify the allocatable component. */
7267 tree non_null_expr;
7268 tree null_expr;
7270 if (arg->symtree->n.sym->attr.allocatable
7271 || arg->symtree->n.sym->attr.pointer)
7273 non_null_expr = gfc_finish_block (&block);
7274 gfc_start_block (&block);
7275 gfc_conv_descriptor_data_set (&block, dest,
7276 null_pointer_node);
7277 null_expr = gfc_finish_block (&block);
7278 tmp = gfc_conv_descriptor_data_get (arg->symtree->n.sym->backend_decl);
7279 tmp = build2_loc (input_location, EQ_EXPR, logical_type_node, tmp,
7280 fold_convert (TREE_TYPE (tmp), null_pointer_node));
7281 return build3_v (COND_EXPR, tmp,
7282 null_expr, non_null_expr);
7286 return gfc_finish_block (&block);
7290 /* Allocate or reallocate scalar component, as necessary. */
7292 static void
7293 alloc_scalar_allocatable_for_subcomponent_assignment (stmtblock_t *block,
7294 tree comp,
7295 gfc_component *cm,
7296 gfc_expr *expr2,
7297 gfc_symbol *sym)
7299 tree tmp;
7300 tree ptr;
7301 tree size;
7302 tree size_in_bytes;
7303 tree lhs_cl_size = NULL_TREE;
7305 if (!comp)
7306 return;
7308 if (!expr2 || expr2->rank)
7309 return;
7311 realloc_lhs_warning (expr2->ts.type, false, &expr2->where);
7313 if (cm->ts.type == BT_CHARACTER && cm->ts.deferred)
7315 char name[GFC_MAX_SYMBOL_LEN+9];
7316 gfc_component *strlen;
7317 /* Use the rhs string length and the lhs element size. */
7318 gcc_assert (expr2->ts.type == BT_CHARACTER);
7319 if (!expr2->ts.u.cl->backend_decl)
7321 gfc_conv_string_length (expr2->ts.u.cl, expr2, block);
7322 gcc_assert (expr2->ts.u.cl->backend_decl);
7325 size = expr2->ts.u.cl->backend_decl;
7327 /* Ensure that cm->ts.u.cl->backend_decl is a componentref to _%s_length
7328 component. */
7329 sprintf (name, "_%s_length", cm->name);
7330 strlen = gfc_find_component (sym, name, true, true, NULL);
7331 lhs_cl_size = fold_build3_loc (input_location, COMPONENT_REF,
7332 gfc_charlen_type_node,
7333 TREE_OPERAND (comp, 0),
7334 strlen->backend_decl, NULL_TREE);
7336 tmp = TREE_TYPE (gfc_typenode_for_spec (&cm->ts));
7337 tmp = TYPE_SIZE_UNIT (tmp);
7338 size_in_bytes = fold_build2_loc (input_location, MULT_EXPR,
7339 TREE_TYPE (tmp), tmp,
7340 fold_convert (TREE_TYPE (tmp), size));
7342 else if (cm->ts.type == BT_CLASS)
7344 gcc_assert (expr2->ts.type == BT_CLASS || expr2->ts.type == BT_DERIVED);
7345 if (expr2->ts.type == BT_DERIVED)
7347 tmp = gfc_get_symbol_decl (expr2->ts.u.derived);
7348 size = TYPE_SIZE_UNIT (tmp);
7350 else
7352 gfc_expr *e2vtab;
7353 gfc_se se;
7354 e2vtab = gfc_find_and_cut_at_last_class_ref (expr2);
7355 gfc_add_vptr_component (e2vtab);
7356 gfc_add_size_component (e2vtab);
7357 gfc_init_se (&se, NULL);
7358 gfc_conv_expr (&se, e2vtab);
7359 gfc_add_block_to_block (block, &se.pre);
7360 size = fold_convert (size_type_node, se.expr);
7361 gfc_free_expr (e2vtab);
7363 size_in_bytes = size;
7365 else
7367 /* Otherwise use the length in bytes of the rhs. */
7368 size = TYPE_SIZE_UNIT (gfc_typenode_for_spec (&cm->ts));
7369 size_in_bytes = size;
7372 size_in_bytes = fold_build2_loc (input_location, MAX_EXPR, size_type_node,
7373 size_in_bytes, size_one_node);
7375 if (cm->ts.type == BT_DERIVED && cm->ts.u.derived->attr.alloc_comp)
7377 tmp = build_call_expr_loc (input_location,
7378 builtin_decl_explicit (BUILT_IN_CALLOC),
7379 2, build_one_cst (size_type_node),
7380 size_in_bytes);
7381 tmp = fold_convert (TREE_TYPE (comp), tmp);
7382 gfc_add_modify (block, comp, tmp);
7384 else
7386 tmp = build_call_expr_loc (input_location,
7387 builtin_decl_explicit (BUILT_IN_MALLOC),
7388 1, size_in_bytes);
7389 if (GFC_CLASS_TYPE_P (TREE_TYPE (comp)))
7390 ptr = gfc_class_data_get (comp);
7391 else
7392 ptr = comp;
7393 tmp = fold_convert (TREE_TYPE (ptr), tmp);
7394 gfc_add_modify (block, ptr, tmp);
7397 if (cm->ts.type == BT_CHARACTER && cm->ts.deferred)
7398 /* Update the lhs character length. */
7399 gfc_add_modify (block, lhs_cl_size,
7400 fold_convert (TREE_TYPE (lhs_cl_size), size));
7404 /* Assign a single component of a derived type constructor. */
7406 static tree
7407 gfc_trans_subcomponent_assign (tree dest, gfc_component * cm, gfc_expr * expr,
7408 gfc_symbol *sym, bool init)
7410 gfc_se se;
7411 gfc_se lse;
7412 stmtblock_t block;
7413 tree tmp;
7414 tree vtab;
7416 gfc_start_block (&block);
7418 if (cm->attr.pointer || cm->attr.proc_pointer)
7420 /* Only care about pointers here, not about allocatables. */
7421 gfc_init_se (&se, NULL);
7422 /* Pointer component. */
7423 if ((cm->attr.dimension || cm->attr.codimension)
7424 && !cm->attr.proc_pointer)
7426 /* Array pointer. */
7427 if (expr->expr_type == EXPR_NULL)
7428 gfc_conv_descriptor_data_set (&block, dest, null_pointer_node);
7429 else
7431 se.direct_byref = 1;
7432 se.expr = dest;
7433 gfc_conv_expr_descriptor (&se, expr);
7434 gfc_add_block_to_block (&block, &se.pre);
7435 gfc_add_block_to_block (&block, &se.post);
7438 else
7440 /* Scalar pointers. */
7441 se.want_pointer = 1;
7442 gfc_conv_expr (&se, expr);
7443 gfc_add_block_to_block (&block, &se.pre);
7445 if (expr->symtree && expr->symtree->n.sym->attr.proc_pointer
7446 && expr->symtree->n.sym->attr.dummy)
7447 se.expr = build_fold_indirect_ref_loc (input_location, se.expr);
7449 gfc_add_modify (&block, dest,
7450 fold_convert (TREE_TYPE (dest), se.expr));
7451 gfc_add_block_to_block (&block, &se.post);
7454 else if (cm->ts.type == BT_CLASS && expr->expr_type == EXPR_NULL)
7456 /* NULL initialization for CLASS components. */
7457 tmp = gfc_trans_structure_assign (dest,
7458 gfc_class_initializer (&cm->ts, expr),
7459 false);
7460 gfc_add_expr_to_block (&block, tmp);
7462 else if ((cm->attr.dimension || cm->attr.codimension)
7463 && !cm->attr.proc_pointer)
7465 if (cm->attr.allocatable && expr->expr_type == EXPR_NULL)
7466 gfc_conv_descriptor_data_set (&block, dest, null_pointer_node);
7467 else if (cm->attr.allocatable || cm->attr.pdt_array)
7469 tmp = gfc_trans_alloc_subarray_assign (dest, cm, expr);
7470 gfc_add_expr_to_block (&block, tmp);
7472 else
7474 tmp = gfc_trans_subarray_assign (dest, cm, expr);
7475 gfc_add_expr_to_block (&block, tmp);
7478 else if (cm->ts.type == BT_CLASS
7479 && CLASS_DATA (cm)->attr.dimension
7480 && CLASS_DATA (cm)->attr.allocatable
7481 && expr->ts.type == BT_DERIVED)
7483 vtab = gfc_get_symbol_decl (gfc_find_vtab (&expr->ts));
7484 vtab = gfc_build_addr_expr (NULL_TREE, vtab);
7485 tmp = gfc_class_vptr_get (dest);
7486 gfc_add_modify (&block, tmp,
7487 fold_convert (TREE_TYPE (tmp), vtab));
7488 tmp = gfc_class_data_get (dest);
7489 tmp = gfc_trans_alloc_subarray_assign (tmp, cm, expr);
7490 gfc_add_expr_to_block (&block, tmp);
7492 else if (init && cm->attr.allocatable && expr->expr_type == EXPR_NULL)
7494 /* NULL initialization for allocatable components. */
7495 gfc_add_modify (&block, dest, fold_convert (TREE_TYPE (dest),
7496 null_pointer_node));
7498 else if (init && (cm->attr.allocatable
7499 || (cm->ts.type == BT_CLASS && CLASS_DATA (cm)->attr.allocatable
7500 && expr->ts.type != BT_CLASS)))
7502 /* Take care about non-array allocatable components here. The alloc_*
7503 routine below is motivated by the alloc_scalar_allocatable_for_
7504 assignment() routine, but with the realloc portions removed and
7505 different input. */
7506 alloc_scalar_allocatable_for_subcomponent_assignment (&block,
7507 dest,
7509 expr,
7510 sym);
7511 /* The remainder of these instructions follow the if (cm->attr.pointer)
7512 if (!cm->attr.dimension) part above. */
7513 gfc_init_se (&se, NULL);
7514 gfc_conv_expr (&se, expr);
7515 gfc_add_block_to_block (&block, &se.pre);
7517 if (expr->symtree && expr->symtree->n.sym->attr.proc_pointer
7518 && expr->symtree->n.sym->attr.dummy)
7519 se.expr = build_fold_indirect_ref_loc (input_location, se.expr);
7521 if (cm->ts.type == BT_CLASS && expr->ts.type == BT_DERIVED)
7523 tmp = gfc_class_data_get (dest);
7524 tmp = build_fold_indirect_ref_loc (input_location, tmp);
7525 vtab = gfc_get_symbol_decl (gfc_find_vtab (&expr->ts));
7526 vtab = gfc_build_addr_expr (NULL_TREE, vtab);
7527 gfc_add_modify (&block, gfc_class_vptr_get (dest),
7528 fold_convert (TREE_TYPE (gfc_class_vptr_get (dest)), vtab));
7530 else
7531 tmp = build_fold_indirect_ref_loc (input_location, dest);
7533 /* For deferred strings insert a memcpy. */
7534 if (cm->ts.type == BT_CHARACTER && cm->ts.deferred)
7536 tree size;
7537 gcc_assert (se.string_length || expr->ts.u.cl->backend_decl);
7538 size = size_of_string_in_bytes (cm->ts.kind, se.string_length
7539 ? se.string_length
7540 : expr->ts.u.cl->backend_decl);
7541 tmp = gfc_build_memcpy_call (tmp, se.expr, size);
7542 gfc_add_expr_to_block (&block, tmp);
7544 else
7545 gfc_add_modify (&block, tmp,
7546 fold_convert (TREE_TYPE (tmp), se.expr));
7547 gfc_add_block_to_block (&block, &se.post);
7549 else if (expr->ts.type == BT_UNION)
7551 tree tmp;
7552 gfc_constructor *c = gfc_constructor_first (expr->value.constructor);
7553 /* We mark that the entire union should be initialized with a contrived
7554 EXPR_NULL expression at the beginning. */
7555 if (c != NULL && c->n.component == NULL
7556 && c->expr != NULL && c->expr->expr_type == EXPR_NULL)
7558 tmp = build2_loc (input_location, MODIFY_EXPR, void_type_node,
7559 dest, build_constructor (TREE_TYPE (dest), NULL));
7560 gfc_add_expr_to_block (&block, tmp);
7561 c = gfc_constructor_next (c);
7563 /* The following constructor expression, if any, represents a specific
7564 map intializer, as given by the user. */
7565 if (c != NULL && c->expr != NULL)
7567 gcc_assert (expr->expr_type == EXPR_STRUCTURE);
7568 tmp = gfc_trans_structure_assign (dest, expr, expr->symtree != NULL);
7569 gfc_add_expr_to_block (&block, tmp);
7572 else if (expr->ts.type == BT_DERIVED && expr->ts.f90_type != BT_VOID)
7574 if (expr->expr_type != EXPR_STRUCTURE)
7576 tree dealloc = NULL_TREE;
7577 gfc_init_se (&se, NULL);
7578 gfc_conv_expr (&se, expr);
7579 gfc_add_block_to_block (&block, &se.pre);
7580 /* Prevent repeat evaluations in gfc_copy_alloc_comp by fixing the
7581 expression in a temporary variable and deallocate the allocatable
7582 components. Then we can the copy the expression to the result. */
7583 if (cm->ts.u.derived->attr.alloc_comp
7584 && expr->expr_type != EXPR_VARIABLE)
7586 se.expr = gfc_evaluate_now (se.expr, &block);
7587 dealloc = gfc_deallocate_alloc_comp (cm->ts.u.derived, se.expr,
7588 expr->rank);
7590 gfc_add_modify (&block, dest,
7591 fold_convert (TREE_TYPE (dest), se.expr));
7592 if (cm->ts.u.derived->attr.alloc_comp
7593 && expr->expr_type != EXPR_NULL)
7595 // TODO: Fix caf_mode
7596 tmp = gfc_copy_alloc_comp (cm->ts.u.derived, se.expr,
7597 dest, expr->rank, 0);
7598 gfc_add_expr_to_block (&block, tmp);
7599 if (dealloc != NULL_TREE)
7600 gfc_add_expr_to_block (&block, dealloc);
7602 gfc_add_block_to_block (&block, &se.post);
7604 else
7606 /* Nested constructors. */
7607 tmp = gfc_trans_structure_assign (dest, expr, expr->symtree != NULL);
7608 gfc_add_expr_to_block (&block, tmp);
7611 else if (gfc_deferred_strlen (cm, &tmp))
7613 tree strlen;
7614 strlen = tmp;
7615 gcc_assert (strlen);
7616 strlen = fold_build3_loc (input_location, COMPONENT_REF,
7617 TREE_TYPE (strlen),
7618 TREE_OPERAND (dest, 0),
7619 strlen, NULL_TREE);
7621 if (expr->expr_type == EXPR_NULL)
7623 tmp = build_int_cst (TREE_TYPE (cm->backend_decl), 0);
7624 gfc_add_modify (&block, dest, tmp);
7625 tmp = build_int_cst (TREE_TYPE (strlen), 0);
7626 gfc_add_modify (&block, strlen, tmp);
7628 else
7630 tree size;
7631 gfc_init_se (&se, NULL);
7632 gfc_conv_expr (&se, expr);
7633 size = size_of_string_in_bytes (cm->ts.kind, se.string_length);
7634 tmp = build_call_expr_loc (input_location,
7635 builtin_decl_explicit (BUILT_IN_MALLOC),
7636 1, size);
7637 gfc_add_modify (&block, dest,
7638 fold_convert (TREE_TYPE (dest), tmp));
7639 gfc_add_modify (&block, strlen,
7640 fold_convert (TREE_TYPE (strlen), se.string_length));
7641 tmp = gfc_build_memcpy_call (dest, se.expr, size);
7642 gfc_add_expr_to_block (&block, tmp);
7645 else if (!cm->attr.artificial)
7647 /* Scalar component (excluding deferred parameters). */
7648 gfc_init_se (&se, NULL);
7649 gfc_init_se (&lse, NULL);
7651 gfc_conv_expr (&se, expr);
7652 if (cm->ts.type == BT_CHARACTER)
7653 lse.string_length = cm->ts.u.cl->backend_decl;
7654 lse.expr = dest;
7655 tmp = gfc_trans_scalar_assign (&lse, &se, cm->ts, false, false);
7656 gfc_add_expr_to_block (&block, tmp);
7658 return gfc_finish_block (&block);
7661 /* Assign a derived type constructor to a variable. */
7663 tree
7664 gfc_trans_structure_assign (tree dest, gfc_expr * expr, bool init, bool coarray)
7666 gfc_constructor *c;
7667 gfc_component *cm;
7668 stmtblock_t block;
7669 tree field;
7670 tree tmp;
7671 gfc_se se;
7673 gfc_start_block (&block);
7674 cm = expr->ts.u.derived->components;
7676 if (expr->ts.u.derived->from_intmod == INTMOD_ISO_C_BINDING
7677 && (expr->ts.u.derived->intmod_sym_id == ISOCBINDING_PTR
7678 || expr->ts.u.derived->intmod_sym_id == ISOCBINDING_FUNPTR))
7680 gfc_se lse;
7682 gfc_init_se (&se, NULL);
7683 gfc_init_se (&lse, NULL);
7684 gfc_conv_expr (&se, gfc_constructor_first (expr->value.constructor)->expr);
7685 lse.expr = dest;
7686 gfc_add_modify (&block, lse.expr,
7687 fold_convert (TREE_TYPE (lse.expr), se.expr));
7689 return gfc_finish_block (&block);
7692 if (coarray)
7693 gfc_init_se (&se, NULL);
7695 for (c = gfc_constructor_first (expr->value.constructor);
7696 c; c = gfc_constructor_next (c), cm = cm->next)
7698 /* Skip absent members in default initializers. */
7699 if (!c->expr && !cm->attr.allocatable)
7700 continue;
7702 /* Register the component with the caf-lib before it is initialized.
7703 Register only allocatable components, that are not coarray'ed
7704 components (%comp[*]). Only register when the constructor is not the
7705 null-expression. */
7706 if (coarray && !cm->attr.codimension
7707 && (cm->attr.allocatable || cm->attr.pointer)
7708 && (!c->expr || c->expr->expr_type == EXPR_NULL))
7710 tree token, desc, size;
7711 bool is_array = cm->ts.type == BT_CLASS
7712 ? CLASS_DATA (cm)->attr.dimension : cm->attr.dimension;
7714 field = cm->backend_decl;
7715 field = fold_build3_loc (input_location, COMPONENT_REF,
7716 TREE_TYPE (field), dest, field, NULL_TREE);
7717 if (cm->ts.type == BT_CLASS)
7718 field = gfc_class_data_get (field);
7720 token = is_array ? gfc_conv_descriptor_token (field)
7721 : fold_build3_loc (input_location, COMPONENT_REF,
7722 TREE_TYPE (cm->caf_token), dest,
7723 cm->caf_token, NULL_TREE);
7725 if (is_array)
7727 /* The _caf_register routine looks at the rank of the array
7728 descriptor to decide whether the data registered is an array
7729 or not. */
7730 int rank = cm->ts.type == BT_CLASS ? CLASS_DATA (cm)->as->rank
7731 : cm->as->rank;
7732 /* When the rank is not known just set a positive rank, which
7733 suffices to recognize the data as array. */
7734 if (rank < 0)
7735 rank = 1;
7736 size = build_zero_cst (size_type_node);
7737 desc = field;
7738 gfc_add_modify (&block, gfc_conv_descriptor_rank (desc),
7739 build_int_cst (signed_char_type_node, rank));
7741 else
7743 desc = gfc_conv_scalar_to_descriptor (&se, field,
7744 cm->ts.type == BT_CLASS
7745 ? CLASS_DATA (cm)->attr
7746 : cm->attr);
7747 size = TYPE_SIZE_UNIT (TREE_TYPE (field));
7749 gfc_add_block_to_block (&block, &se.pre);
7750 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_register,
7751 7, size, build_int_cst (
7752 integer_type_node,
7753 GFC_CAF_COARRAY_ALLOC_REGISTER_ONLY),
7754 gfc_build_addr_expr (pvoid_type_node,
7755 token),
7756 gfc_build_addr_expr (NULL_TREE, desc),
7757 null_pointer_node, null_pointer_node,
7758 integer_zero_node);
7759 gfc_add_expr_to_block (&block, tmp);
7761 field = cm->backend_decl;
7762 tmp = fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field),
7763 dest, field, NULL_TREE);
7764 if (!c->expr)
7766 gfc_expr *e = gfc_get_null_expr (NULL);
7767 tmp = gfc_trans_subcomponent_assign (tmp, cm, e, expr->ts.u.derived,
7768 init);
7769 gfc_free_expr (e);
7771 else
7772 tmp = gfc_trans_subcomponent_assign (tmp, cm, c->expr,
7773 expr->ts.u.derived, init);
7774 gfc_add_expr_to_block (&block, tmp);
7776 return gfc_finish_block (&block);
7779 void
7780 gfc_conv_union_initializer (vec<constructor_elt, va_gc> *v,
7781 gfc_component *un, gfc_expr *init)
7783 gfc_constructor *ctor;
7785 if (un->ts.type != BT_UNION || un == NULL || init == NULL)
7786 return;
7788 ctor = gfc_constructor_first (init->value.constructor);
7790 if (ctor == NULL || ctor->expr == NULL)
7791 return;
7793 gcc_assert (init->expr_type == EXPR_STRUCTURE);
7795 /* If we have an 'initialize all' constructor, do it first. */
7796 if (ctor->expr->expr_type == EXPR_NULL)
7798 tree union_type = TREE_TYPE (un->backend_decl);
7799 tree val = build_constructor (union_type, NULL);
7800 CONSTRUCTOR_APPEND_ELT (v, un->backend_decl, val);
7801 ctor = gfc_constructor_next (ctor);
7804 /* Add the map initializer on top. */
7805 if (ctor != NULL && ctor->expr != NULL)
7807 gcc_assert (ctor->expr->expr_type == EXPR_STRUCTURE);
7808 tree val = gfc_conv_initializer (ctor->expr, &un->ts,
7809 TREE_TYPE (un->backend_decl),
7810 un->attr.dimension, un->attr.pointer,
7811 un->attr.proc_pointer);
7812 CONSTRUCTOR_APPEND_ELT (v, un->backend_decl, val);
7816 /* Build an expression for a constructor. If init is nonzero then
7817 this is part of a static variable initializer. */
7819 void
7820 gfc_conv_structure (gfc_se * se, gfc_expr * expr, int init)
7822 gfc_constructor *c;
7823 gfc_component *cm;
7824 tree val;
7825 tree type;
7826 tree tmp;
7827 vec<constructor_elt, va_gc> *v = NULL;
7829 gcc_assert (se->ss == NULL);
7830 gcc_assert (expr->expr_type == EXPR_STRUCTURE);
7831 type = gfc_typenode_for_spec (&expr->ts);
7833 if (!init)
7835 /* Create a temporary variable and fill it in. */
7836 se->expr = gfc_create_var (type, expr->ts.u.derived->name);
7837 /* The symtree in expr is NULL, if the code to generate is for
7838 initializing the static members only. */
7839 tmp = gfc_trans_structure_assign (se->expr, expr, expr->symtree != NULL,
7840 se->want_coarray);
7841 gfc_add_expr_to_block (&se->pre, tmp);
7842 return;
7845 cm = expr->ts.u.derived->components;
7847 for (c = gfc_constructor_first (expr->value.constructor);
7848 c; c = gfc_constructor_next (c), cm = cm->next)
7850 /* Skip absent members in default initializers and allocatable
7851 components. Although the latter have a default initializer
7852 of EXPR_NULL,... by default, the static nullify is not needed
7853 since this is done every time we come into scope. */
7854 if (!c->expr || (cm->attr.allocatable && cm->attr.flavor != FL_PROCEDURE))
7855 continue;
7857 if (cm->initializer && cm->initializer->expr_type != EXPR_NULL
7858 && strcmp (cm->name, "_extends") == 0
7859 && cm->initializer->symtree)
7861 tree vtab;
7862 gfc_symbol *vtabs;
7863 vtabs = cm->initializer->symtree->n.sym;
7864 vtab = gfc_build_addr_expr (NULL_TREE, gfc_get_symbol_decl (vtabs));
7865 vtab = unshare_expr_without_location (vtab);
7866 CONSTRUCTOR_APPEND_ELT (v, cm->backend_decl, vtab);
7868 else if (cm->ts.u.derived && strcmp (cm->name, "_size") == 0)
7870 val = TYPE_SIZE_UNIT (gfc_get_derived_type (cm->ts.u.derived));
7871 CONSTRUCTOR_APPEND_ELT (v, cm->backend_decl,
7872 fold_convert (TREE_TYPE (cm->backend_decl),
7873 val));
7875 else if (cm->ts.type == BT_INTEGER && strcmp (cm->name, "_len") == 0)
7876 CONSTRUCTOR_APPEND_ELT (v, cm->backend_decl,
7877 fold_convert (TREE_TYPE (cm->backend_decl),
7878 integer_zero_node));
7879 else if (cm->ts.type == BT_UNION)
7880 gfc_conv_union_initializer (v, cm, c->expr);
7881 else
7883 val = gfc_conv_initializer (c->expr, &cm->ts,
7884 TREE_TYPE (cm->backend_decl),
7885 cm->attr.dimension, cm->attr.pointer,
7886 cm->attr.proc_pointer);
7887 val = unshare_expr_without_location (val);
7889 /* Append it to the constructor list. */
7890 CONSTRUCTOR_APPEND_ELT (v, cm->backend_decl, val);
7894 se->expr = build_constructor (type, v);
7895 if (init)
7896 TREE_CONSTANT (se->expr) = 1;
7900 /* Translate a substring expression. */
7902 static void
7903 gfc_conv_substring_expr (gfc_se * se, gfc_expr * expr)
7905 gfc_ref *ref;
7907 ref = expr->ref;
7909 gcc_assert (ref == NULL || ref->type == REF_SUBSTRING);
7911 se->expr = gfc_build_wide_string_const (expr->ts.kind,
7912 expr->value.character.length,
7913 expr->value.character.string);
7915 se->string_length = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (se->expr)));
7916 TYPE_STRING_FLAG (TREE_TYPE (se->expr)) = 1;
7918 if (ref)
7919 gfc_conv_substring (se, ref, expr->ts.kind, NULL, &expr->where);
7923 /* Entry point for expression translation. Evaluates a scalar quantity.
7924 EXPR is the expression to be translated, and SE is the state structure if
7925 called from within the scalarized. */
7927 void
7928 gfc_conv_expr (gfc_se * se, gfc_expr * expr)
7930 gfc_ss *ss;
7932 ss = se->ss;
7933 if (ss && ss->info->expr == expr
7934 && (ss->info->type == GFC_SS_SCALAR
7935 || ss->info->type == GFC_SS_REFERENCE))
7937 gfc_ss_info *ss_info;
7939 ss_info = ss->info;
7940 /* Substitute a scalar expression evaluated outside the scalarization
7941 loop. */
7942 se->expr = ss_info->data.scalar.value;
7943 if (gfc_scalar_elemental_arg_saved_as_reference (ss_info))
7944 se->expr = build_fold_indirect_ref_loc (input_location, se->expr);
7946 se->string_length = ss_info->string_length;
7947 gfc_advance_se_ss_chain (se);
7948 return;
7951 /* We need to convert the expressions for the iso_c_binding derived types.
7952 C_NULL_PTR and C_NULL_FUNPTR will be made EXPR_NULL, which evaluates to
7953 null_pointer_node. C_PTR and C_FUNPTR are converted to match the
7954 typespec for the C_PTR and C_FUNPTR symbols, which has already been
7955 updated to be an integer with a kind equal to the size of a (void *). */
7956 if (expr->ts.type == BT_DERIVED && expr->ts.u.derived->ts.f90_type == BT_VOID
7957 && expr->ts.u.derived->attr.is_bind_c)
7959 if (expr->expr_type == EXPR_VARIABLE
7960 && (expr->symtree->n.sym->intmod_sym_id == ISOCBINDING_NULL_PTR
7961 || expr->symtree->n.sym->intmod_sym_id
7962 == ISOCBINDING_NULL_FUNPTR))
7964 /* Set expr_type to EXPR_NULL, which will result in
7965 null_pointer_node being used below. */
7966 expr->expr_type = EXPR_NULL;
7968 else
7970 /* Update the type/kind of the expression to be what the new
7971 type/kind are for the updated symbols of C_PTR/C_FUNPTR. */
7972 expr->ts.type = BT_INTEGER;
7973 expr->ts.f90_type = BT_VOID;
7974 expr->ts.kind = gfc_index_integer_kind;
7978 gfc_fix_class_refs (expr);
7980 switch (expr->expr_type)
7982 case EXPR_OP:
7983 gfc_conv_expr_op (se, expr);
7984 break;
7986 case EXPR_FUNCTION:
7987 gfc_conv_function_expr (se, expr);
7988 break;
7990 case EXPR_CONSTANT:
7991 gfc_conv_constant (se, expr);
7992 break;
7994 case EXPR_VARIABLE:
7995 gfc_conv_variable (se, expr);
7996 break;
7998 case EXPR_NULL:
7999 se->expr = null_pointer_node;
8000 break;
8002 case EXPR_SUBSTRING:
8003 gfc_conv_substring_expr (se, expr);
8004 break;
8006 case EXPR_STRUCTURE:
8007 gfc_conv_structure (se, expr, 0);
8008 break;
8010 case EXPR_ARRAY:
8011 gfc_conv_array_constructor_expr (se, expr);
8012 break;
8014 default:
8015 gcc_unreachable ();
8016 break;
8020 /* Like gfc_conv_expr_val, but the value is also suitable for use in the lhs
8021 of an assignment. */
8022 void
8023 gfc_conv_expr_lhs (gfc_se * se, gfc_expr * expr)
8025 gfc_conv_expr (se, expr);
8026 /* All numeric lvalues should have empty post chains. If not we need to
8027 figure out a way of rewriting an lvalue so that it has no post chain. */
8028 gcc_assert (expr->ts.type == BT_CHARACTER || !se->post.head);
8031 /* Like gfc_conv_expr, but the POST block is guaranteed to be empty for
8032 numeric expressions. Used for scalar values where inserting cleanup code
8033 is inconvenient. */
8034 void
8035 gfc_conv_expr_val (gfc_se * se, gfc_expr * expr)
8037 tree val;
8039 gcc_assert (expr->ts.type != BT_CHARACTER);
8040 gfc_conv_expr (se, expr);
8041 if (se->post.head)
8043 val = gfc_create_var (TREE_TYPE (se->expr), NULL);
8044 gfc_add_modify (&se->pre, val, se->expr);
8045 se->expr = val;
8046 gfc_add_block_to_block (&se->pre, &se->post);
8050 /* Helper to translate an expression and convert it to a particular type. */
8051 void
8052 gfc_conv_expr_type (gfc_se * se, gfc_expr * expr, tree type)
8054 gfc_conv_expr_val (se, expr);
8055 se->expr = convert (type, se->expr);
8059 /* Converts an expression so that it can be passed by reference. Scalar
8060 values only. */
8062 void
8063 gfc_conv_expr_reference (gfc_se * se, gfc_expr * expr)
8065 gfc_ss *ss;
8066 tree var;
8068 ss = se->ss;
8069 if (ss && ss->info->expr == expr
8070 && ss->info->type == GFC_SS_REFERENCE)
8072 /* Returns a reference to the scalar evaluated outside the loop
8073 for this case. */
8074 gfc_conv_expr (se, expr);
8076 if (expr->ts.type == BT_CHARACTER
8077 && expr->expr_type != EXPR_FUNCTION)
8078 gfc_conv_string_parameter (se);
8079 else
8080 se->expr = gfc_build_addr_expr (NULL_TREE, se->expr);
8082 return;
8085 if (expr->ts.type == BT_CHARACTER)
8087 gfc_conv_expr (se, expr);
8088 gfc_conv_string_parameter (se);
8089 return;
8092 if (expr->expr_type == EXPR_VARIABLE)
8094 se->want_pointer = 1;
8095 gfc_conv_expr (se, expr);
8096 if (se->post.head)
8098 var = gfc_create_var (TREE_TYPE (se->expr), NULL);
8099 gfc_add_modify (&se->pre, var, se->expr);
8100 gfc_add_block_to_block (&se->pre, &se->post);
8101 se->expr = var;
8103 return;
8106 if (expr->expr_type == EXPR_FUNCTION
8107 && ((expr->value.function.esym
8108 && expr->value.function.esym->result->attr.pointer
8109 && !expr->value.function.esym->result->attr.dimension)
8110 || (!expr->value.function.esym && !expr->ref
8111 && expr->symtree->n.sym->attr.pointer
8112 && !expr->symtree->n.sym->attr.dimension)))
8114 se->want_pointer = 1;
8115 gfc_conv_expr (se, expr);
8116 var = gfc_create_var (TREE_TYPE (se->expr), NULL);
8117 gfc_add_modify (&se->pre, var, se->expr);
8118 se->expr = var;
8119 return;
8122 gfc_conv_expr (se, expr);
8124 /* Create a temporary var to hold the value. */
8125 if (TREE_CONSTANT (se->expr))
8127 tree tmp = se->expr;
8128 STRIP_TYPE_NOPS (tmp);
8129 var = build_decl (input_location,
8130 CONST_DECL, NULL, TREE_TYPE (tmp));
8131 DECL_INITIAL (var) = tmp;
8132 TREE_STATIC (var) = 1;
8133 pushdecl (var);
8135 else
8137 var = gfc_create_var (TREE_TYPE (se->expr), NULL);
8138 gfc_add_modify (&se->pre, var, se->expr);
8141 if (!expr->must_finalize)
8142 gfc_add_block_to_block (&se->pre, &se->post);
8144 /* Take the address of that value. */
8145 se->expr = gfc_build_addr_expr (NULL_TREE, var);
8149 /* Get the _len component for an unlimited polymorphic expression. */
8151 static tree
8152 trans_get_upoly_len (stmtblock_t *block, gfc_expr *expr)
8154 gfc_se se;
8155 gfc_ref *ref = expr->ref;
8157 gfc_init_se (&se, NULL);
8158 while (ref && ref->next)
8159 ref = ref->next;
8160 gfc_add_len_component (expr);
8161 gfc_conv_expr (&se, expr);
8162 gfc_add_block_to_block (block, &se.pre);
8163 gcc_assert (se.post.head == NULL_TREE);
8164 if (ref)
8166 gfc_free_ref_list (ref->next);
8167 ref->next = NULL;
8169 else
8171 gfc_free_ref_list (expr->ref);
8172 expr->ref = NULL;
8174 return se.expr;
8178 /* Assign _vptr and _len components as appropriate. BLOCK should be a
8179 statement-list outside of the scalarizer-loop. When code is generated, that
8180 depends on the scalarized expression, it is added to RSE.PRE.
8181 Returns le's _vptr tree and when set the len expressions in to_lenp and
8182 from_lenp to form a le%_vptr%_copy (re, le, [from_lenp, to_lenp])
8183 expression. */
8185 static tree
8186 trans_class_vptr_len_assignment (stmtblock_t *block, gfc_expr * le,
8187 gfc_expr * re, gfc_se *rse,
8188 tree * to_lenp, tree * from_lenp)
8190 gfc_se se;
8191 gfc_expr * vptr_expr;
8192 tree tmp, to_len = NULL_TREE, from_len = NULL_TREE, lhs_vptr;
8193 bool set_vptr = false, temp_rhs = false;
8194 stmtblock_t *pre = block;
8196 /* Create a temporary for complicated expressions. */
8197 if (re->expr_type != EXPR_VARIABLE && re->expr_type != EXPR_NULL
8198 && rse->expr != NULL_TREE && !DECL_P (rse->expr))
8200 tmp = gfc_create_var (TREE_TYPE (rse->expr), "rhs");
8201 pre = &rse->pre;
8202 gfc_add_modify (&rse->pre, tmp, rse->expr);
8203 rse->expr = tmp;
8204 temp_rhs = true;
8207 /* Get the _vptr for the left-hand side expression. */
8208 gfc_init_se (&se, NULL);
8209 vptr_expr = gfc_find_and_cut_at_last_class_ref (le);
8210 if (vptr_expr != NULL && gfc_expr_attr (vptr_expr).class_ok)
8212 /* Care about _len for unlimited polymorphic entities. */
8213 if (UNLIMITED_POLY (vptr_expr)
8214 || (vptr_expr->ts.type == BT_DERIVED
8215 && vptr_expr->ts.u.derived->attr.unlimited_polymorphic))
8216 to_len = trans_get_upoly_len (block, vptr_expr);
8217 gfc_add_vptr_component (vptr_expr);
8218 set_vptr = true;
8220 else
8221 vptr_expr = gfc_lval_expr_from_sym (gfc_find_vtab (&le->ts));
8222 se.want_pointer = 1;
8223 gfc_conv_expr (&se, vptr_expr);
8224 gfc_free_expr (vptr_expr);
8225 gfc_add_block_to_block (block, &se.pre);
8226 gcc_assert (se.post.head == NULL_TREE);
8227 lhs_vptr = se.expr;
8228 STRIP_NOPS (lhs_vptr);
8230 /* Set the _vptr only when the left-hand side of the assignment is a
8231 class-object. */
8232 if (set_vptr)
8234 /* Get the vptr from the rhs expression only, when it is variable.
8235 Functions are expected to be assigned to a temporary beforehand. */
8236 vptr_expr = (re->expr_type == EXPR_VARIABLE && re->ts.type == BT_CLASS)
8237 ? gfc_find_and_cut_at_last_class_ref (re)
8238 : NULL;
8239 if (vptr_expr != NULL && vptr_expr->ts.type == BT_CLASS)
8241 if (to_len != NULL_TREE)
8243 /* Get the _len information from the rhs. */
8244 if (UNLIMITED_POLY (vptr_expr)
8245 || (vptr_expr->ts.type == BT_DERIVED
8246 && vptr_expr->ts.u.derived->attr.unlimited_polymorphic))
8247 from_len = trans_get_upoly_len (block, vptr_expr);
8249 gfc_add_vptr_component (vptr_expr);
8251 else
8253 if (re->expr_type == EXPR_VARIABLE
8254 && DECL_P (re->symtree->n.sym->backend_decl)
8255 && DECL_LANG_SPECIFIC (re->symtree->n.sym->backend_decl)
8256 && GFC_DECL_SAVED_DESCRIPTOR (re->symtree->n.sym->backend_decl)
8257 && GFC_CLASS_TYPE_P (TREE_TYPE (GFC_DECL_SAVED_DESCRIPTOR (
8258 re->symtree->n.sym->backend_decl))))
8260 vptr_expr = NULL;
8261 se.expr = gfc_class_vptr_get (GFC_DECL_SAVED_DESCRIPTOR (
8262 re->symtree->n.sym->backend_decl));
8263 if (to_len)
8264 from_len = gfc_class_len_get (GFC_DECL_SAVED_DESCRIPTOR (
8265 re->symtree->n.sym->backend_decl));
8267 else if (temp_rhs && re->ts.type == BT_CLASS)
8269 vptr_expr = NULL;
8270 se.expr = gfc_class_vptr_get (rse->expr);
8271 if (UNLIMITED_POLY (re))
8272 from_len = gfc_class_len_get (rse->expr);
8274 else if (re->expr_type != EXPR_NULL)
8275 /* Only when rhs is non-NULL use its declared type for vptr
8276 initialisation. */
8277 vptr_expr = gfc_lval_expr_from_sym (gfc_find_vtab (&re->ts));
8278 else
8279 /* When the rhs is NULL use the vtab of lhs' declared type. */
8280 vptr_expr = gfc_lval_expr_from_sym (gfc_find_vtab (&le->ts));
8283 if (vptr_expr)
8285 gfc_init_se (&se, NULL);
8286 se.want_pointer = 1;
8287 gfc_conv_expr (&se, vptr_expr);
8288 gfc_free_expr (vptr_expr);
8289 gfc_add_block_to_block (block, &se.pre);
8290 gcc_assert (se.post.head == NULL_TREE);
8292 gfc_add_modify (pre, lhs_vptr, fold_convert (TREE_TYPE (lhs_vptr),
8293 se.expr));
8295 if (to_len != NULL_TREE)
8297 /* The _len component needs to be set. Figure how to get the
8298 value of the right-hand side. */
8299 if (from_len == NULL_TREE)
8301 if (rse->string_length != NULL_TREE)
8302 from_len = rse->string_length;
8303 else if (re->ts.type == BT_CHARACTER && re->ts.u.cl->length)
8305 from_len = gfc_get_expr_charlen (re);
8306 gfc_init_se (&se, NULL);
8307 gfc_conv_expr (&se, re->ts.u.cl->length);
8308 gfc_add_block_to_block (block, &se.pre);
8309 gcc_assert (se.post.head == NULL_TREE);
8310 from_len = gfc_evaluate_now (se.expr, block);
8312 else
8313 from_len = build_zero_cst (gfc_charlen_type_node);
8315 gfc_add_modify (pre, to_len, fold_convert (TREE_TYPE (to_len),
8316 from_len));
8320 /* Return the _len trees only, when requested. */
8321 if (to_lenp)
8322 *to_lenp = to_len;
8323 if (from_lenp)
8324 *from_lenp = from_len;
8325 return lhs_vptr;
8329 /* Assign tokens for pointer components. */
8331 static void
8332 trans_caf_token_assign (gfc_se *lse, gfc_se *rse, gfc_expr *expr1,
8333 gfc_expr *expr2)
8335 symbol_attribute lhs_attr, rhs_attr;
8336 tree tmp, lhs_tok, rhs_tok;
8337 /* Flag to indicated component refs on the rhs. */
8338 bool rhs_cr;
8340 lhs_attr = gfc_caf_attr (expr1);
8341 if (expr2->expr_type != EXPR_NULL)
8343 rhs_attr = gfc_caf_attr (expr2, false, &rhs_cr);
8344 if (lhs_attr.codimension && rhs_attr.codimension)
8346 lhs_tok = gfc_get_ultimate_alloc_ptr_comps_caf_token (lse, expr1);
8347 lhs_tok = build_fold_indirect_ref (lhs_tok);
8349 if (rhs_cr)
8350 rhs_tok = gfc_get_ultimate_alloc_ptr_comps_caf_token (rse, expr2);
8351 else
8353 tree caf_decl;
8354 caf_decl = gfc_get_tree_for_caf_expr (expr2);
8355 gfc_get_caf_token_offset (rse, &rhs_tok, NULL, caf_decl,
8356 NULL_TREE, NULL);
8358 tmp = build2_loc (input_location, MODIFY_EXPR, void_type_node,
8359 lhs_tok,
8360 fold_convert (TREE_TYPE (lhs_tok), rhs_tok));
8361 gfc_prepend_expr_to_block (&lse->post, tmp);
8364 else if (lhs_attr.codimension)
8366 lhs_tok = gfc_get_ultimate_alloc_ptr_comps_caf_token (lse, expr1);
8367 lhs_tok = build_fold_indirect_ref (lhs_tok);
8368 tmp = build2_loc (input_location, MODIFY_EXPR, void_type_node,
8369 lhs_tok, null_pointer_node);
8370 gfc_prepend_expr_to_block (&lse->post, tmp);
8374 /* Indentify class valued proc_pointer assignments. */
8376 static bool
8377 pointer_assignment_is_proc_pointer (gfc_expr * expr1, gfc_expr * expr2)
8379 gfc_ref * ref;
8381 ref = expr1->ref;
8382 while (ref && ref->next)
8383 ref = ref->next;
8385 return ref && ref->type == REF_COMPONENT
8386 && ref->u.c.component->attr.proc_pointer
8387 && expr2->expr_type == EXPR_VARIABLE
8388 && expr2->symtree->n.sym->attr.flavor == FL_PROCEDURE;
8392 /* Do everything that is needed for a CLASS function expr2. */
8394 static tree
8395 trans_class_pointer_fcn (stmtblock_t *block, gfc_se *lse, gfc_se *rse,
8396 gfc_expr *expr1, gfc_expr *expr2)
8398 tree expr1_vptr = NULL_TREE;
8399 tree tmp;
8401 gfc_conv_function_expr (rse, expr2);
8402 rse->expr = gfc_evaluate_now (rse->expr, &rse->pre);
8404 if (expr1->ts.type != BT_CLASS)
8405 rse->expr = gfc_class_data_get (rse->expr);
8406 else
8408 expr1_vptr = trans_class_vptr_len_assignment (block, expr1,
8409 expr2, rse,
8410 NULL, NULL);
8411 gfc_add_block_to_block (block, &rse->pre);
8412 tmp = gfc_create_var (TREE_TYPE (rse->expr), "ptrtemp");
8413 gfc_add_modify (&lse->pre, tmp, rse->expr);
8415 gfc_add_modify (&lse->pre, expr1_vptr,
8416 fold_convert (TREE_TYPE (expr1_vptr),
8417 gfc_class_vptr_get (tmp)));
8418 rse->expr = gfc_class_data_get (tmp);
8421 return expr1_vptr;
8425 tree
8426 gfc_trans_pointer_assign (gfc_code * code)
8428 return gfc_trans_pointer_assignment (code->expr1, code->expr2);
8432 /* Generate code for a pointer assignment. */
8434 tree
8435 gfc_trans_pointer_assignment (gfc_expr * expr1, gfc_expr * expr2)
8437 gfc_se lse;
8438 gfc_se rse;
8439 stmtblock_t block;
8440 tree desc;
8441 tree tmp;
8442 tree expr1_vptr = NULL_TREE;
8443 bool scalar, non_proc_pointer_assign;
8444 gfc_ss *ss;
8446 gfc_start_block (&block);
8448 gfc_init_se (&lse, NULL);
8450 /* Usually testing whether this is not a proc pointer assignment. */
8451 non_proc_pointer_assign = !pointer_assignment_is_proc_pointer (expr1, expr2);
8453 /* Check whether the expression is a scalar or not; we cannot use
8454 expr1->rank as it can be nonzero for proc pointers. */
8455 ss = gfc_walk_expr (expr1);
8456 scalar = ss == gfc_ss_terminator;
8457 if (!scalar)
8458 gfc_free_ss_chain (ss);
8460 if (expr1->ts.type == BT_DERIVED && expr2->ts.type == BT_CLASS
8461 && expr2->expr_type != EXPR_FUNCTION && non_proc_pointer_assign)
8463 gfc_add_data_component (expr2);
8464 /* The following is required as gfc_add_data_component doesn't
8465 update ts.type if there is a tailing REF_ARRAY. */
8466 expr2->ts.type = BT_DERIVED;
8469 if (scalar)
8471 /* Scalar pointers. */
8472 lse.want_pointer = 1;
8473 gfc_conv_expr (&lse, expr1);
8474 gfc_init_se (&rse, NULL);
8475 rse.want_pointer = 1;
8476 if (expr2->expr_type == EXPR_FUNCTION && expr2->ts.type == BT_CLASS)
8477 trans_class_pointer_fcn (&block, &lse, &rse, expr1, expr2);
8478 else
8479 gfc_conv_expr (&rse, expr2);
8481 if (non_proc_pointer_assign && expr1->ts.type == BT_CLASS)
8483 trans_class_vptr_len_assignment (&block, expr1, expr2, &rse, NULL,
8484 NULL);
8485 lse.expr = gfc_class_data_get (lse.expr);
8488 if (expr1->symtree->n.sym->attr.proc_pointer
8489 && expr1->symtree->n.sym->attr.dummy)
8490 lse.expr = build_fold_indirect_ref_loc (input_location,
8491 lse.expr);
8493 if (expr2->symtree && expr2->symtree->n.sym->attr.proc_pointer
8494 && expr2->symtree->n.sym->attr.dummy)
8495 rse.expr = build_fold_indirect_ref_loc (input_location,
8496 rse.expr);
8498 gfc_add_block_to_block (&block, &lse.pre);
8499 gfc_add_block_to_block (&block, &rse.pre);
8501 /* Check character lengths if character expression. The test is only
8502 really added if -fbounds-check is enabled. Exclude deferred
8503 character length lefthand sides. */
8504 if (expr1->ts.type == BT_CHARACTER && expr2->expr_type != EXPR_NULL
8505 && !expr1->ts.deferred
8506 && !expr1->symtree->n.sym->attr.proc_pointer
8507 && !gfc_is_proc_ptr_comp (expr1))
8509 gcc_assert (expr2->ts.type == BT_CHARACTER);
8510 gcc_assert (lse.string_length && rse.string_length);
8511 gfc_trans_same_strlen_check ("pointer assignment", &expr1->where,
8512 lse.string_length, rse.string_length,
8513 &block);
8516 /* The assignment to an deferred character length sets the string
8517 length to that of the rhs. */
8518 if (expr1->ts.deferred)
8520 if (expr2->expr_type != EXPR_NULL && lse.string_length != NULL)
8521 gfc_add_modify (&block, lse.string_length,
8522 fold_convert (TREE_TYPE (lse.string_length),
8523 rse.string_length));
8524 else if (lse.string_length != NULL)
8525 gfc_add_modify (&block, lse.string_length,
8526 build_zero_cst (TREE_TYPE (lse.string_length)));
8529 gfc_add_modify (&block, lse.expr,
8530 fold_convert (TREE_TYPE (lse.expr), rse.expr));
8532 /* Also set the tokens for pointer components in derived typed
8533 coarrays. */
8534 if (flag_coarray == GFC_FCOARRAY_LIB)
8535 trans_caf_token_assign (&lse, &rse, expr1, expr2);
8537 gfc_add_block_to_block (&block, &rse.post);
8538 gfc_add_block_to_block (&block, &lse.post);
8540 else
8542 gfc_ref* remap;
8543 bool rank_remap;
8544 tree strlen_lhs;
8545 tree strlen_rhs = NULL_TREE;
8547 /* Array pointer. Find the last reference on the LHS and if it is an
8548 array section ref, we're dealing with bounds remapping. In this case,
8549 set it to AR_FULL so that gfc_conv_expr_descriptor does
8550 not see it and process the bounds remapping afterwards explicitly. */
8551 for (remap = expr1->ref; remap; remap = remap->next)
8552 if (!remap->next && remap->type == REF_ARRAY
8553 && remap->u.ar.type == AR_SECTION)
8554 break;
8555 rank_remap = (remap && remap->u.ar.end[0]);
8557 gfc_init_se (&lse, NULL);
8558 if (remap)
8559 lse.descriptor_only = 1;
8560 gfc_conv_expr_descriptor (&lse, expr1);
8561 strlen_lhs = lse.string_length;
8562 desc = lse.expr;
8564 if (expr2->expr_type == EXPR_NULL)
8566 /* Just set the data pointer to null. */
8567 gfc_conv_descriptor_data_set (&lse.pre, lse.expr, null_pointer_node);
8569 else if (rank_remap)
8571 /* If we are rank-remapping, just get the RHS's descriptor and
8572 process this later on. */
8573 gfc_init_se (&rse, NULL);
8574 rse.direct_byref = 1;
8575 rse.byref_noassign = 1;
8577 if (expr2->expr_type == EXPR_FUNCTION && expr2->ts.type == BT_CLASS)
8578 expr1_vptr = trans_class_pointer_fcn (&block, &lse, &rse,
8579 expr1, expr2);
8580 else if (expr2->expr_type == EXPR_FUNCTION)
8582 tree bound[GFC_MAX_DIMENSIONS];
8583 int i;
8585 for (i = 0; i < expr2->rank; i++)
8586 bound[i] = NULL_TREE;
8587 tmp = gfc_typenode_for_spec (&expr2->ts);
8588 tmp = gfc_get_array_type_bounds (tmp, expr2->rank, 0,
8589 bound, bound, 0,
8590 GFC_ARRAY_POINTER_CONT, false);
8591 tmp = gfc_create_var (tmp, "ptrtemp");
8592 rse.descriptor_only = 0;
8593 rse.expr = tmp;
8594 rse.direct_byref = 1;
8595 gfc_conv_expr_descriptor (&rse, expr2);
8596 strlen_rhs = rse.string_length;
8597 rse.expr = tmp;
8599 else
8601 gfc_conv_expr_descriptor (&rse, expr2);
8602 strlen_rhs = rse.string_length;
8603 if (expr1->ts.type == BT_CLASS)
8604 expr1_vptr = trans_class_vptr_len_assignment (&block, expr1,
8605 expr2, &rse,
8606 NULL, NULL);
8609 else if (expr2->expr_type == EXPR_VARIABLE)
8611 /* Assign directly to the LHS's descriptor. */
8612 lse.descriptor_only = 0;
8613 lse.direct_byref = 1;
8614 gfc_conv_expr_descriptor (&lse, expr2);
8615 strlen_rhs = lse.string_length;
8617 if (expr1->ts.type == BT_CLASS)
8619 rse.expr = NULL_TREE;
8620 rse.string_length = NULL_TREE;
8621 trans_class_vptr_len_assignment (&block, expr1, expr2, &rse,
8622 NULL, NULL);
8625 if (remap == NULL)
8627 /* If the target is not a whole array, use the target array
8628 reference for remap. */
8629 for (remap = expr2->ref; remap; remap = remap->next)
8630 if (remap->type == REF_ARRAY
8631 && remap->u.ar.type == AR_FULL
8632 && remap->next)
8633 break;
8636 else if (expr2->expr_type == EXPR_FUNCTION && expr2->ts.type == BT_CLASS)
8638 gfc_init_se (&rse, NULL);
8639 rse.want_pointer = 1;
8640 gfc_conv_function_expr (&rse, expr2);
8641 if (expr1->ts.type != BT_CLASS)
8643 rse.expr = gfc_class_data_get (rse.expr);
8644 gfc_add_modify (&lse.pre, desc, rse.expr);
8645 /* Set the lhs span. */
8646 tmp = TREE_TYPE (rse.expr);
8647 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (tmp));
8648 tmp = fold_convert (gfc_array_index_type, tmp);
8649 gfc_conv_descriptor_span_set (&lse.pre, desc, tmp);
8651 else
8653 expr1_vptr = trans_class_vptr_len_assignment (&block, expr1,
8654 expr2, &rse, NULL,
8655 NULL);
8656 gfc_add_block_to_block (&block, &rse.pre);
8657 tmp = gfc_create_var (TREE_TYPE (rse.expr), "ptrtemp");
8658 gfc_add_modify (&lse.pre, tmp, rse.expr);
8660 gfc_add_modify (&lse.pre, expr1_vptr,
8661 fold_convert (TREE_TYPE (expr1_vptr),
8662 gfc_class_vptr_get (tmp)));
8663 rse.expr = gfc_class_data_get (tmp);
8664 gfc_add_modify (&lse.pre, desc, rse.expr);
8667 else
8669 /* Assign to a temporary descriptor and then copy that
8670 temporary to the pointer. */
8671 tmp = gfc_create_var (TREE_TYPE (desc), "ptrtemp");
8672 lse.descriptor_only = 0;
8673 lse.expr = tmp;
8674 lse.direct_byref = 1;
8675 gfc_conv_expr_descriptor (&lse, expr2);
8676 strlen_rhs = lse.string_length;
8677 gfc_add_modify (&lse.pre, desc, tmp);
8680 gfc_add_block_to_block (&block, &lse.pre);
8681 if (rank_remap)
8682 gfc_add_block_to_block (&block, &rse.pre);
8684 /* If we do bounds remapping, update LHS descriptor accordingly. */
8685 if (remap)
8687 int dim;
8688 gcc_assert (remap->u.ar.dimen == expr1->rank);
8690 if (rank_remap)
8692 /* Do rank remapping. We already have the RHS's descriptor
8693 converted in rse and now have to build the correct LHS
8694 descriptor for it. */
8696 tree dtype, data, span;
8697 tree offs, stride;
8698 tree lbound, ubound;
8700 /* Set dtype. */
8701 dtype = gfc_conv_descriptor_dtype (desc);
8702 tmp = gfc_get_dtype (TREE_TYPE (desc));
8703 gfc_add_modify (&block, dtype, tmp);
8705 /* Copy data pointer. */
8706 data = gfc_conv_descriptor_data_get (rse.expr);
8707 gfc_conv_descriptor_data_set (&block, desc, data);
8709 /* Copy the span. */
8710 if (TREE_CODE (rse.expr) == VAR_DECL
8711 && GFC_DECL_PTR_ARRAY_P (rse.expr))
8712 span = gfc_conv_descriptor_span_get (rse.expr);
8713 else
8715 tmp = TREE_TYPE (rse.expr);
8716 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (tmp));
8717 span = fold_convert (gfc_array_index_type, tmp);
8719 gfc_conv_descriptor_span_set (&block, desc, span);
8721 /* Copy offset but adjust it such that it would correspond
8722 to a lbound of zero. */
8723 offs = gfc_conv_descriptor_offset_get (rse.expr);
8724 for (dim = 0; dim < expr2->rank; ++dim)
8726 stride = gfc_conv_descriptor_stride_get (rse.expr,
8727 gfc_rank_cst[dim]);
8728 lbound = gfc_conv_descriptor_lbound_get (rse.expr,
8729 gfc_rank_cst[dim]);
8730 tmp = fold_build2_loc (input_location, MULT_EXPR,
8731 gfc_array_index_type, stride, lbound);
8732 offs = fold_build2_loc (input_location, PLUS_EXPR,
8733 gfc_array_index_type, offs, tmp);
8735 gfc_conv_descriptor_offset_set (&block, desc, offs);
8737 /* Set the bounds as declared for the LHS and calculate strides as
8738 well as another offset update accordingly. */
8739 stride = gfc_conv_descriptor_stride_get (rse.expr,
8740 gfc_rank_cst[0]);
8741 for (dim = 0; dim < expr1->rank; ++dim)
8743 gfc_se lower_se;
8744 gfc_se upper_se;
8746 gcc_assert (remap->u.ar.start[dim] && remap->u.ar.end[dim]);
8748 /* Convert declared bounds. */
8749 gfc_init_se (&lower_se, NULL);
8750 gfc_init_se (&upper_se, NULL);
8751 gfc_conv_expr (&lower_se, remap->u.ar.start[dim]);
8752 gfc_conv_expr (&upper_se, remap->u.ar.end[dim]);
8754 gfc_add_block_to_block (&block, &lower_se.pre);
8755 gfc_add_block_to_block (&block, &upper_se.pre);
8757 lbound = fold_convert (gfc_array_index_type, lower_se.expr);
8758 ubound = fold_convert (gfc_array_index_type, upper_se.expr);
8760 lbound = gfc_evaluate_now (lbound, &block);
8761 ubound = gfc_evaluate_now (ubound, &block);
8763 gfc_add_block_to_block (&block, &lower_se.post);
8764 gfc_add_block_to_block (&block, &upper_se.post);
8766 /* Set bounds in descriptor. */
8767 gfc_conv_descriptor_lbound_set (&block, desc,
8768 gfc_rank_cst[dim], lbound);
8769 gfc_conv_descriptor_ubound_set (&block, desc,
8770 gfc_rank_cst[dim], ubound);
8772 /* Set stride. */
8773 stride = gfc_evaluate_now (stride, &block);
8774 gfc_conv_descriptor_stride_set (&block, desc,
8775 gfc_rank_cst[dim], stride);
8777 /* Update offset. */
8778 offs = gfc_conv_descriptor_offset_get (desc);
8779 tmp = fold_build2_loc (input_location, MULT_EXPR,
8780 gfc_array_index_type, lbound, stride);
8781 offs = fold_build2_loc (input_location, MINUS_EXPR,
8782 gfc_array_index_type, offs, tmp);
8783 offs = gfc_evaluate_now (offs, &block);
8784 gfc_conv_descriptor_offset_set (&block, desc, offs);
8786 /* Update stride. */
8787 tmp = gfc_conv_array_extent_dim (lbound, ubound, NULL);
8788 stride = fold_build2_loc (input_location, MULT_EXPR,
8789 gfc_array_index_type, stride, tmp);
8792 else
8794 /* Bounds remapping. Just shift the lower bounds. */
8796 gcc_assert (expr1->rank == expr2->rank);
8798 for (dim = 0; dim < remap->u.ar.dimen; ++dim)
8800 gfc_se lbound_se;
8802 gcc_assert (!remap->u.ar.end[dim]);
8803 gfc_init_se (&lbound_se, NULL);
8804 if (remap->u.ar.start[dim])
8806 gfc_conv_expr (&lbound_se, remap->u.ar.start[dim]);
8807 gfc_add_block_to_block (&block, &lbound_se.pre);
8809 else
8810 /* This remap arises from a target that is not a whole
8811 array. The start expressions will be NULL but we need
8812 the lbounds to be one. */
8813 lbound_se.expr = gfc_index_one_node;
8814 gfc_conv_shift_descriptor_lbound (&block, desc,
8815 dim, lbound_se.expr);
8816 gfc_add_block_to_block (&block, &lbound_se.post);
8821 /* Check string lengths if applicable. The check is only really added
8822 to the output code if -fbounds-check is enabled. */
8823 if (expr1->ts.type == BT_CHARACTER && expr2->expr_type != EXPR_NULL)
8825 gcc_assert (expr2->ts.type == BT_CHARACTER);
8826 gcc_assert (strlen_lhs && strlen_rhs);
8827 gfc_trans_same_strlen_check ("pointer assignment", &expr1->where,
8828 strlen_lhs, strlen_rhs, &block);
8831 /* If rank remapping was done, check with -fcheck=bounds that
8832 the target is at least as large as the pointer. */
8833 if (rank_remap && (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS))
8835 tree lsize, rsize;
8836 tree fault;
8837 const char* msg;
8839 lsize = gfc_conv_descriptor_size (lse.expr, expr1->rank);
8840 rsize = gfc_conv_descriptor_size (rse.expr, expr2->rank);
8842 lsize = gfc_evaluate_now (lsize, &block);
8843 rsize = gfc_evaluate_now (rsize, &block);
8844 fault = fold_build2_loc (input_location, LT_EXPR, logical_type_node,
8845 rsize, lsize);
8847 msg = _("Target of rank remapping is too small (%ld < %ld)");
8848 gfc_trans_runtime_check (true, false, fault, &block, &expr2->where,
8849 msg, rsize, lsize);
8852 gfc_add_block_to_block (&block, &lse.post);
8853 if (rank_remap)
8854 gfc_add_block_to_block (&block, &rse.post);
8857 return gfc_finish_block (&block);
8861 /* Makes sure se is suitable for passing as a function string parameter. */
8862 /* TODO: Need to check all callers of this function. It may be abused. */
8864 void
8865 gfc_conv_string_parameter (gfc_se * se)
8867 tree type;
8869 if (TREE_CODE (se->expr) == STRING_CST)
8871 type = TREE_TYPE (TREE_TYPE (se->expr));
8872 se->expr = gfc_build_addr_expr (build_pointer_type (type), se->expr);
8873 return;
8876 if (TYPE_STRING_FLAG (TREE_TYPE (se->expr)))
8878 if (TREE_CODE (se->expr) != INDIRECT_REF)
8880 type = TREE_TYPE (se->expr);
8881 se->expr = gfc_build_addr_expr (build_pointer_type (type), se->expr);
8883 else
8885 type = gfc_get_character_type_len (gfc_default_character_kind,
8886 se->string_length);
8887 type = build_pointer_type (type);
8888 se->expr = gfc_build_addr_expr (type, se->expr);
8892 gcc_assert (POINTER_TYPE_P (TREE_TYPE (se->expr)));
8896 /* Generate code for assignment of scalar variables. Includes character
8897 strings and derived types with allocatable components.
8898 If you know that the LHS has no allocations, set dealloc to false.
8900 DEEP_COPY has no effect if the typespec TS is not a derived type with
8901 allocatable components. Otherwise, if it is set, an explicit copy of each
8902 allocatable component is made. This is necessary as a simple copy of the
8903 whole object would copy array descriptors as is, so that the lhs's
8904 allocatable components would point to the rhs's after the assignment.
8905 Typically, setting DEEP_COPY is necessary if the rhs is a variable, and not
8906 necessary if the rhs is a non-pointer function, as the allocatable components
8907 are not accessible by other means than the function's result after the
8908 function has returned. It is even more subtle when temporaries are involved,
8909 as the two following examples show:
8910 1. When we evaluate an array constructor, a temporary is created. Thus
8911 there is theoretically no alias possible. However, no deep copy is
8912 made for this temporary, so that if the constructor is made of one or
8913 more variable with allocatable components, those components still point
8914 to the variable's: DEEP_COPY should be set for the assignment from the
8915 temporary to the lhs in that case.
8916 2. When assigning a scalar to an array, we evaluate the scalar value out
8917 of the loop, store it into a temporary variable, and assign from that.
8918 In that case, deep copying when assigning to the temporary would be a
8919 waste of resources; however deep copies should happen when assigning from
8920 the temporary to each array element: again DEEP_COPY should be set for
8921 the assignment from the temporary to the lhs. */
8923 tree
8924 gfc_trans_scalar_assign (gfc_se * lse, gfc_se * rse, gfc_typespec ts,
8925 bool deep_copy, bool dealloc, bool in_coarray)
8927 stmtblock_t block;
8928 tree tmp;
8929 tree cond;
8931 gfc_init_block (&block);
8933 if (ts.type == BT_CHARACTER)
8935 tree rlen = NULL;
8936 tree llen = NULL;
8938 if (lse->string_length != NULL_TREE)
8940 gfc_conv_string_parameter (lse);
8941 gfc_add_block_to_block (&block, &lse->pre);
8942 llen = lse->string_length;
8945 if (rse->string_length != NULL_TREE)
8947 gfc_conv_string_parameter (rse);
8948 gfc_add_block_to_block (&block, &rse->pre);
8949 rlen = rse->string_length;
8952 gfc_trans_string_copy (&block, llen, lse->expr, ts.kind, rlen,
8953 rse->expr, ts.kind);
8955 else if (gfc_bt_struct (ts.type)
8956 && (ts.u.derived->attr.alloc_comp
8957 || (deep_copy && ts.u.derived->attr.pdt_type)))
8959 tree tmp_var = NULL_TREE;
8960 cond = NULL_TREE;
8962 /* Are the rhs and the lhs the same? */
8963 if (deep_copy)
8965 cond = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
8966 gfc_build_addr_expr (NULL_TREE, lse->expr),
8967 gfc_build_addr_expr (NULL_TREE, rse->expr));
8968 cond = gfc_evaluate_now (cond, &lse->pre);
8971 /* Deallocate the lhs allocated components as long as it is not
8972 the same as the rhs. This must be done following the assignment
8973 to prevent deallocating data that could be used in the rhs
8974 expression. */
8975 if (dealloc)
8977 tmp_var = gfc_evaluate_now (lse->expr, &lse->pre);
8978 tmp = gfc_deallocate_alloc_comp_no_caf (ts.u.derived, tmp_var, 0);
8979 if (deep_copy)
8980 tmp = build3_v (COND_EXPR, cond, build_empty_stmt (input_location),
8981 tmp);
8982 gfc_add_expr_to_block (&lse->post, tmp);
8985 gfc_add_block_to_block (&block, &rse->pre);
8986 gfc_add_block_to_block (&block, &lse->pre);
8988 gfc_add_modify (&block, lse->expr,
8989 fold_convert (TREE_TYPE (lse->expr), rse->expr));
8991 /* Restore pointer address of coarray components. */
8992 if (ts.u.derived->attr.coarray_comp && deep_copy && tmp_var != NULL_TREE)
8994 tmp = gfc_reassign_alloc_comp_caf (ts.u.derived, tmp_var, lse->expr);
8995 tmp = build3_v (COND_EXPR, cond, build_empty_stmt (input_location),
8996 tmp);
8997 gfc_add_expr_to_block (&block, tmp);
9000 /* Do a deep copy if the rhs is a variable, if it is not the
9001 same as the lhs. */
9002 if (deep_copy)
9004 int caf_mode = in_coarray ? (GFC_STRUCTURE_CAF_MODE_ENABLE_COARRAY
9005 | GFC_STRUCTURE_CAF_MODE_IN_COARRAY) : 0;
9006 tmp = gfc_copy_alloc_comp (ts.u.derived, rse->expr, lse->expr, 0,
9007 caf_mode);
9008 tmp = build3_v (COND_EXPR, cond, build_empty_stmt (input_location),
9009 tmp);
9010 gfc_add_expr_to_block (&block, tmp);
9013 else if (gfc_bt_struct (ts.type) || ts.type == BT_CLASS)
9015 gfc_add_block_to_block (&block, &lse->pre);
9016 gfc_add_block_to_block (&block, &rse->pre);
9017 tmp = fold_build1_loc (input_location, VIEW_CONVERT_EXPR,
9018 TREE_TYPE (lse->expr), rse->expr);
9019 gfc_add_modify (&block, lse->expr, tmp);
9021 else
9023 gfc_add_block_to_block (&block, &lse->pre);
9024 gfc_add_block_to_block (&block, &rse->pre);
9026 gfc_add_modify (&block, lse->expr,
9027 fold_convert (TREE_TYPE (lse->expr), rse->expr));
9030 gfc_add_block_to_block (&block, &lse->post);
9031 gfc_add_block_to_block (&block, &rse->post);
9033 return gfc_finish_block (&block);
9037 /* There are quite a lot of restrictions on the optimisation in using an
9038 array function assign without a temporary. */
9040 static bool
9041 arrayfunc_assign_needs_temporary (gfc_expr * expr1, gfc_expr * expr2)
9043 gfc_ref * ref;
9044 bool seen_array_ref;
9045 bool c = false;
9046 gfc_symbol *sym = expr1->symtree->n.sym;
9048 /* Play it safe with class functions assigned to a derived type. */
9049 if (gfc_is_class_array_function (expr2)
9050 && expr1->ts.type == BT_DERIVED)
9051 return true;
9053 /* The caller has already checked rank>0 and expr_type == EXPR_FUNCTION. */
9054 if (expr2->value.function.isym && !gfc_is_intrinsic_libcall (expr2))
9055 return true;
9057 /* Elemental functions are scalarized so that they don't need a
9058 temporary in gfc_trans_assignment_1, so return a true. Otherwise,
9059 they would need special treatment in gfc_trans_arrayfunc_assign. */
9060 if (expr2->value.function.esym != NULL
9061 && expr2->value.function.esym->attr.elemental)
9062 return true;
9064 /* Need a temporary if rhs is not FULL or a contiguous section. */
9065 if (expr1->ref && !(gfc_full_array_ref_p (expr1->ref, &c) || c))
9066 return true;
9068 /* Need a temporary if EXPR1 can't be expressed as a descriptor. */
9069 if (gfc_ref_needs_temporary_p (expr1->ref))
9070 return true;
9072 /* Functions returning pointers or allocatables need temporaries. */
9073 c = expr2->value.function.esym
9074 ? (expr2->value.function.esym->attr.pointer
9075 || expr2->value.function.esym->attr.allocatable)
9076 : (expr2->symtree->n.sym->attr.pointer
9077 || expr2->symtree->n.sym->attr.allocatable);
9078 if (c)
9079 return true;
9081 /* Character array functions need temporaries unless the
9082 character lengths are the same. */
9083 if (expr2->ts.type == BT_CHARACTER && expr2->rank > 0)
9085 if (expr1->ts.u.cl->length == NULL
9086 || expr1->ts.u.cl->length->expr_type != EXPR_CONSTANT)
9087 return true;
9089 if (expr2->ts.u.cl->length == NULL
9090 || expr2->ts.u.cl->length->expr_type != EXPR_CONSTANT)
9091 return true;
9093 if (mpz_cmp (expr1->ts.u.cl->length->value.integer,
9094 expr2->ts.u.cl->length->value.integer) != 0)
9095 return true;
9098 /* Check that no LHS component references appear during an array
9099 reference. This is needed because we do not have the means to
9100 span any arbitrary stride with an array descriptor. This check
9101 is not needed for the rhs because the function result has to be
9102 a complete type. */
9103 seen_array_ref = false;
9104 for (ref = expr1->ref; ref; ref = ref->next)
9106 if (ref->type == REF_ARRAY)
9107 seen_array_ref= true;
9108 else if (ref->type == REF_COMPONENT && seen_array_ref)
9109 return true;
9112 /* Check for a dependency. */
9113 if (gfc_check_fncall_dependency (expr1, INTENT_OUT,
9114 expr2->value.function.esym,
9115 expr2->value.function.actual,
9116 NOT_ELEMENTAL))
9117 return true;
9119 /* If we have reached here with an intrinsic function, we do not
9120 need a temporary except in the particular case that reallocation
9121 on assignment is active and the lhs is allocatable and a target. */
9122 if (expr2->value.function.isym)
9123 return (flag_realloc_lhs && sym->attr.allocatable && sym->attr.target);
9125 /* If the LHS is a dummy, we need a temporary if it is not
9126 INTENT(OUT). */
9127 if (sym->attr.dummy && sym->attr.intent != INTENT_OUT)
9128 return true;
9130 /* If the lhs has been host_associated, is in common, a pointer or is
9131 a target and the function is not using a RESULT variable, aliasing
9132 can occur and a temporary is needed. */
9133 if ((sym->attr.host_assoc
9134 || sym->attr.in_common
9135 || sym->attr.pointer
9136 || sym->attr.cray_pointee
9137 || sym->attr.target)
9138 && expr2->symtree != NULL
9139 && expr2->symtree->n.sym == expr2->symtree->n.sym->result)
9140 return true;
9142 /* A PURE function can unconditionally be called without a temporary. */
9143 if (expr2->value.function.esym != NULL
9144 && expr2->value.function.esym->attr.pure)
9145 return false;
9147 /* Implicit_pure functions are those which could legally be declared
9148 to be PURE. */
9149 if (expr2->value.function.esym != NULL
9150 && expr2->value.function.esym->attr.implicit_pure)
9151 return false;
9153 if (!sym->attr.use_assoc
9154 && !sym->attr.in_common
9155 && !sym->attr.pointer
9156 && !sym->attr.target
9157 && !sym->attr.cray_pointee
9158 && expr2->value.function.esym)
9160 /* A temporary is not needed if the function is not contained and
9161 the variable is local or host associated and not a pointer or
9162 a target. */
9163 if (!expr2->value.function.esym->attr.contained)
9164 return false;
9166 /* A temporary is not needed if the lhs has never been host
9167 associated and the procedure is contained. */
9168 else if (!sym->attr.host_assoc)
9169 return false;
9171 /* A temporary is not needed if the variable is local and not
9172 a pointer, a target or a result. */
9173 if (sym->ns->parent
9174 && expr2->value.function.esym->ns == sym->ns->parent)
9175 return false;
9178 /* Default to temporary use. */
9179 return true;
9183 /* Provide the loop info so that the lhs descriptor can be built for
9184 reallocatable assignments from extrinsic function calls. */
9186 static void
9187 realloc_lhs_loop_for_fcn_call (gfc_se *se, locus *where, gfc_ss **ss,
9188 gfc_loopinfo *loop)
9190 /* Signal that the function call should not be made by
9191 gfc_conv_loop_setup. */
9192 se->ss->is_alloc_lhs = 1;
9193 gfc_init_loopinfo (loop);
9194 gfc_add_ss_to_loop (loop, *ss);
9195 gfc_add_ss_to_loop (loop, se->ss);
9196 gfc_conv_ss_startstride (loop);
9197 gfc_conv_loop_setup (loop, where);
9198 gfc_copy_loopinfo_to_se (se, loop);
9199 gfc_add_block_to_block (&se->pre, &loop->pre);
9200 gfc_add_block_to_block (&se->pre, &loop->post);
9201 se->ss->is_alloc_lhs = 0;
9205 /* For assignment to a reallocatable lhs from intrinsic functions,
9206 replace the se.expr (ie. the result) with a temporary descriptor.
9207 Null the data field so that the library allocates space for the
9208 result. Free the data of the original descriptor after the function,
9209 in case it appears in an argument expression and transfer the
9210 result to the original descriptor. */
9212 static void
9213 fcncall_realloc_result (gfc_se *se, int rank)
9215 tree desc;
9216 tree res_desc;
9217 tree tmp;
9218 tree offset;
9219 tree zero_cond;
9220 int n;
9222 /* Use the allocation done by the library. Substitute the lhs
9223 descriptor with a copy, whose data field is nulled.*/
9224 desc = build_fold_indirect_ref_loc (input_location, se->expr);
9225 if (POINTER_TYPE_P (TREE_TYPE (desc)))
9226 desc = build_fold_indirect_ref_loc (input_location, desc);
9228 /* Unallocated, the descriptor does not have a dtype. */
9229 tmp = gfc_conv_descriptor_dtype (desc);
9230 gfc_add_modify (&se->pre, tmp, gfc_get_dtype (TREE_TYPE (desc)));
9232 res_desc = gfc_evaluate_now (desc, &se->pre);
9233 gfc_conv_descriptor_data_set (&se->pre, res_desc, null_pointer_node);
9234 se->expr = gfc_build_addr_expr (NULL_TREE, res_desc);
9236 /* Free the lhs after the function call and copy the result data to
9237 the lhs descriptor. */
9238 tmp = gfc_conv_descriptor_data_get (desc);
9239 zero_cond = fold_build2_loc (input_location, EQ_EXPR,
9240 logical_type_node, tmp,
9241 build_int_cst (TREE_TYPE (tmp), 0));
9242 zero_cond = gfc_evaluate_now (zero_cond, &se->post);
9243 tmp = gfc_call_free (tmp);
9244 gfc_add_expr_to_block (&se->post, tmp);
9246 tmp = gfc_conv_descriptor_data_get (res_desc);
9247 gfc_conv_descriptor_data_set (&se->post, desc, tmp);
9249 /* Check that the shapes are the same between lhs and expression. */
9250 for (n = 0 ; n < rank; n++)
9252 tree tmp1;
9253 tmp = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[n]);
9254 tmp1 = gfc_conv_descriptor_lbound_get (res_desc, gfc_rank_cst[n]);
9255 tmp = fold_build2_loc (input_location, MINUS_EXPR,
9256 gfc_array_index_type, tmp, tmp1);
9257 tmp1 = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[n]);
9258 tmp = fold_build2_loc (input_location, MINUS_EXPR,
9259 gfc_array_index_type, tmp, tmp1);
9260 tmp1 = gfc_conv_descriptor_ubound_get (res_desc, gfc_rank_cst[n]);
9261 tmp = fold_build2_loc (input_location, PLUS_EXPR,
9262 gfc_array_index_type, tmp, tmp1);
9263 tmp = fold_build2_loc (input_location, NE_EXPR,
9264 logical_type_node, tmp,
9265 gfc_index_zero_node);
9266 tmp = gfc_evaluate_now (tmp, &se->post);
9267 zero_cond = fold_build2_loc (input_location, TRUTH_OR_EXPR,
9268 logical_type_node, tmp,
9269 zero_cond);
9272 /* 'zero_cond' being true is equal to lhs not being allocated or the
9273 shapes being different. */
9274 zero_cond = gfc_evaluate_now (zero_cond, &se->post);
9276 /* Now reset the bounds returned from the function call to bounds based
9277 on the lhs lbounds, except where the lhs is not allocated or the shapes
9278 of 'variable and 'expr' are different. Set the offset accordingly. */
9279 offset = gfc_index_zero_node;
9280 for (n = 0 ; n < rank; n++)
9282 tree lbound;
9284 lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[n]);
9285 lbound = fold_build3_loc (input_location, COND_EXPR,
9286 gfc_array_index_type, zero_cond,
9287 gfc_index_one_node, lbound);
9288 lbound = gfc_evaluate_now (lbound, &se->post);
9290 tmp = gfc_conv_descriptor_ubound_get (res_desc, gfc_rank_cst[n]);
9291 tmp = fold_build2_loc (input_location, PLUS_EXPR,
9292 gfc_array_index_type, tmp, lbound);
9293 gfc_conv_descriptor_lbound_set (&se->post, desc,
9294 gfc_rank_cst[n], lbound);
9295 gfc_conv_descriptor_ubound_set (&se->post, desc,
9296 gfc_rank_cst[n], tmp);
9298 /* Set stride and accumulate the offset. */
9299 tmp = gfc_conv_descriptor_stride_get (res_desc, gfc_rank_cst[n]);
9300 gfc_conv_descriptor_stride_set (&se->post, desc,
9301 gfc_rank_cst[n], tmp);
9302 tmp = fold_build2_loc (input_location, MULT_EXPR,
9303 gfc_array_index_type, lbound, tmp);
9304 offset = fold_build2_loc (input_location, MINUS_EXPR,
9305 gfc_array_index_type, offset, tmp);
9306 offset = gfc_evaluate_now (offset, &se->post);
9309 gfc_conv_descriptor_offset_set (&se->post, desc, offset);
9314 /* Try to translate array(:) = func (...), where func is a transformational
9315 array function, without using a temporary. Returns NULL if this isn't the
9316 case. */
9318 static tree
9319 gfc_trans_arrayfunc_assign (gfc_expr * expr1, gfc_expr * expr2)
9321 gfc_se se;
9322 gfc_ss *ss = NULL;
9323 gfc_component *comp = NULL;
9324 gfc_loopinfo loop;
9326 if (arrayfunc_assign_needs_temporary (expr1, expr2))
9327 return NULL;
9329 /* The frontend doesn't seem to bother filling in expr->symtree for intrinsic
9330 functions. */
9331 comp = gfc_get_proc_ptr_comp (expr2);
9333 if (!(expr2->value.function.isym
9334 || (comp && comp->attr.dimension)
9335 || (!comp && gfc_return_by_reference (expr2->value.function.esym)
9336 && expr2->value.function.esym->result->attr.dimension)))
9337 return NULL;
9339 gfc_init_se (&se, NULL);
9340 gfc_start_block (&se.pre);
9341 se.want_pointer = 1;
9343 gfc_conv_array_parameter (&se, expr1, false, NULL, NULL, NULL);
9345 if (expr1->ts.type == BT_DERIVED
9346 && expr1->ts.u.derived->attr.alloc_comp)
9348 tree tmp;
9349 tmp = gfc_deallocate_alloc_comp_no_caf (expr1->ts.u.derived, se.expr,
9350 expr1->rank);
9351 gfc_add_expr_to_block (&se.pre, tmp);
9354 se.direct_byref = 1;
9355 se.ss = gfc_walk_expr (expr2);
9356 gcc_assert (se.ss != gfc_ss_terminator);
9358 /* Reallocate on assignment needs the loopinfo for extrinsic functions.
9359 This is signalled to gfc_conv_procedure_call by setting is_alloc_lhs.
9360 Clearly, this cannot be done for an allocatable function result, since
9361 the shape of the result is unknown and, in any case, the function must
9362 correctly take care of the reallocation internally. For intrinsic
9363 calls, the array data is freed and the library takes care of allocation.
9364 TODO: Add logic of trans-array.c: gfc_alloc_allocatable_for_assignment
9365 to the library. */
9366 if (flag_realloc_lhs
9367 && gfc_is_reallocatable_lhs (expr1)
9368 && !gfc_expr_attr (expr1).codimension
9369 && !gfc_is_coindexed (expr1)
9370 && !(expr2->value.function.esym
9371 && expr2->value.function.esym->result->attr.allocatable))
9373 realloc_lhs_warning (expr1->ts.type, true, &expr1->where);
9375 if (!expr2->value.function.isym)
9377 ss = gfc_walk_expr (expr1);
9378 gcc_assert (ss != gfc_ss_terminator);
9380 realloc_lhs_loop_for_fcn_call (&se, &expr1->where, &ss, &loop);
9381 ss->is_alloc_lhs = 1;
9383 else
9384 fcncall_realloc_result (&se, expr1->rank);
9387 gfc_conv_function_expr (&se, expr2);
9388 gfc_add_block_to_block (&se.pre, &se.post);
9390 if (ss)
9391 gfc_cleanup_loop (&loop);
9392 else
9393 gfc_free_ss_chain (se.ss);
9395 return gfc_finish_block (&se.pre);
9399 /* Try to efficiently translate array(:) = 0. Return NULL if this
9400 can't be done. */
9402 static tree
9403 gfc_trans_zero_assign (gfc_expr * expr)
9405 tree dest, len, type;
9406 tree tmp;
9407 gfc_symbol *sym;
9409 sym = expr->symtree->n.sym;
9410 dest = gfc_get_symbol_decl (sym);
9412 type = TREE_TYPE (dest);
9413 if (POINTER_TYPE_P (type))
9414 type = TREE_TYPE (type);
9415 if (!GFC_ARRAY_TYPE_P (type))
9416 return NULL_TREE;
9418 /* Determine the length of the array. */
9419 len = GFC_TYPE_ARRAY_SIZE (type);
9420 if (!len || TREE_CODE (len) != INTEGER_CST)
9421 return NULL_TREE;
9423 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type));
9424 len = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type, len,
9425 fold_convert (gfc_array_index_type, tmp));
9427 /* If we are zeroing a local array avoid taking its address by emitting
9428 a = {} instead. */
9429 if (!POINTER_TYPE_P (TREE_TYPE (dest)))
9430 return build2_loc (input_location, MODIFY_EXPR, void_type_node,
9431 dest, build_constructor (TREE_TYPE (dest),
9432 NULL));
9434 /* Convert arguments to the correct types. */
9435 dest = fold_convert (pvoid_type_node, dest);
9436 len = fold_convert (size_type_node, len);
9438 /* Construct call to __builtin_memset. */
9439 tmp = build_call_expr_loc (input_location,
9440 builtin_decl_explicit (BUILT_IN_MEMSET),
9441 3, dest, integer_zero_node, len);
9442 return fold_convert (void_type_node, tmp);
9446 /* Helper for gfc_trans_array_copy and gfc_trans_array_constructor_copy
9447 that constructs the call to __builtin_memcpy. */
9449 tree
9450 gfc_build_memcpy_call (tree dst, tree src, tree len)
9452 tree tmp;
9454 /* Convert arguments to the correct types. */
9455 if (!POINTER_TYPE_P (TREE_TYPE (dst)))
9456 dst = gfc_build_addr_expr (pvoid_type_node, dst);
9457 else
9458 dst = fold_convert (pvoid_type_node, dst);
9460 if (!POINTER_TYPE_P (TREE_TYPE (src)))
9461 src = gfc_build_addr_expr (pvoid_type_node, src);
9462 else
9463 src = fold_convert (pvoid_type_node, src);
9465 len = fold_convert (size_type_node, len);
9467 /* Construct call to __builtin_memcpy. */
9468 tmp = build_call_expr_loc (input_location,
9469 builtin_decl_explicit (BUILT_IN_MEMCPY),
9470 3, dst, src, len);
9471 return fold_convert (void_type_node, tmp);
9475 /* Try to efficiently translate dst(:) = src(:). Return NULL if this
9476 can't be done. EXPR1 is the destination/lhs and EXPR2 is the
9477 source/rhs, both are gfc_full_array_ref_p which have been checked for
9478 dependencies. */
9480 static tree
9481 gfc_trans_array_copy (gfc_expr * expr1, gfc_expr * expr2)
9483 tree dst, dlen, dtype;
9484 tree src, slen, stype;
9485 tree tmp;
9487 dst = gfc_get_symbol_decl (expr1->symtree->n.sym);
9488 src = gfc_get_symbol_decl (expr2->symtree->n.sym);
9490 dtype = TREE_TYPE (dst);
9491 if (POINTER_TYPE_P (dtype))
9492 dtype = TREE_TYPE (dtype);
9493 stype = TREE_TYPE (src);
9494 if (POINTER_TYPE_P (stype))
9495 stype = TREE_TYPE (stype);
9497 if (!GFC_ARRAY_TYPE_P (dtype) || !GFC_ARRAY_TYPE_P (stype))
9498 return NULL_TREE;
9500 /* Determine the lengths of the arrays. */
9501 dlen = GFC_TYPE_ARRAY_SIZE (dtype);
9502 if (!dlen || TREE_CODE (dlen) != INTEGER_CST)
9503 return NULL_TREE;
9504 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (dtype));
9505 dlen = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
9506 dlen, fold_convert (gfc_array_index_type, tmp));
9508 slen = GFC_TYPE_ARRAY_SIZE (stype);
9509 if (!slen || TREE_CODE (slen) != INTEGER_CST)
9510 return NULL_TREE;
9511 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (stype));
9512 slen = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
9513 slen, fold_convert (gfc_array_index_type, tmp));
9515 /* Sanity check that they are the same. This should always be
9516 the case, as we should already have checked for conformance. */
9517 if (!tree_int_cst_equal (slen, dlen))
9518 return NULL_TREE;
9520 return gfc_build_memcpy_call (dst, src, dlen);
9524 /* Try to efficiently translate array(:) = (/ ... /). Return NULL if
9525 this can't be done. EXPR1 is the destination/lhs for which
9526 gfc_full_array_ref_p is true, and EXPR2 is the source/rhs. */
9528 static tree
9529 gfc_trans_array_constructor_copy (gfc_expr * expr1, gfc_expr * expr2)
9531 unsigned HOST_WIDE_INT nelem;
9532 tree dst, dtype;
9533 tree src, stype;
9534 tree len;
9535 tree tmp;
9537 nelem = gfc_constant_array_constructor_p (expr2->value.constructor);
9538 if (nelem == 0)
9539 return NULL_TREE;
9541 dst = gfc_get_symbol_decl (expr1->symtree->n.sym);
9542 dtype = TREE_TYPE (dst);
9543 if (POINTER_TYPE_P (dtype))
9544 dtype = TREE_TYPE (dtype);
9545 if (!GFC_ARRAY_TYPE_P (dtype))
9546 return NULL_TREE;
9548 /* Determine the lengths of the array. */
9549 len = GFC_TYPE_ARRAY_SIZE (dtype);
9550 if (!len || TREE_CODE (len) != INTEGER_CST)
9551 return NULL_TREE;
9553 /* Confirm that the constructor is the same size. */
9554 if (compare_tree_int (len, nelem) != 0)
9555 return NULL_TREE;
9557 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (dtype));
9558 len = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type, len,
9559 fold_convert (gfc_array_index_type, tmp));
9561 stype = gfc_typenode_for_spec (&expr2->ts);
9562 src = gfc_build_constant_array_constructor (expr2, stype);
9564 stype = TREE_TYPE (src);
9565 if (POINTER_TYPE_P (stype))
9566 stype = TREE_TYPE (stype);
9568 return gfc_build_memcpy_call (dst, src, len);
9572 /* Tells whether the expression is to be treated as a variable reference. */
9574 bool
9575 gfc_expr_is_variable (gfc_expr *expr)
9577 gfc_expr *arg;
9578 gfc_component *comp;
9579 gfc_symbol *func_ifc;
9581 if (expr->expr_type == EXPR_VARIABLE)
9582 return true;
9584 arg = gfc_get_noncopying_intrinsic_argument (expr);
9585 if (arg)
9587 gcc_assert (expr->value.function.isym->id == GFC_ISYM_TRANSPOSE);
9588 return gfc_expr_is_variable (arg);
9591 /* A data-pointer-returning function should be considered as a variable
9592 too. */
9593 if (expr->expr_type == EXPR_FUNCTION
9594 && expr->ref == NULL)
9596 if (expr->value.function.isym != NULL)
9597 return false;
9599 if (expr->value.function.esym != NULL)
9601 func_ifc = expr->value.function.esym;
9602 goto found_ifc;
9604 else
9606 gcc_assert (expr->symtree);
9607 func_ifc = expr->symtree->n.sym;
9608 goto found_ifc;
9611 gcc_unreachable ();
9614 comp = gfc_get_proc_ptr_comp (expr);
9615 if ((expr->expr_type == EXPR_PPC || expr->expr_type == EXPR_FUNCTION)
9616 && comp)
9618 func_ifc = comp->ts.interface;
9619 goto found_ifc;
9622 if (expr->expr_type == EXPR_COMPCALL)
9624 gcc_assert (!expr->value.compcall.tbp->is_generic);
9625 func_ifc = expr->value.compcall.tbp->u.specific->n.sym;
9626 goto found_ifc;
9629 return false;
9631 found_ifc:
9632 gcc_assert (func_ifc->attr.function
9633 && func_ifc->result != NULL);
9634 return func_ifc->result->attr.pointer;
9638 /* Is the lhs OK for automatic reallocation? */
9640 static bool
9641 is_scalar_reallocatable_lhs (gfc_expr *expr)
9643 gfc_ref * ref;
9645 /* An allocatable variable with no reference. */
9646 if (expr->symtree->n.sym->attr.allocatable
9647 && !expr->ref)
9648 return true;
9650 /* All that can be left are allocatable components. However, we do
9651 not check for allocatable components here because the expression
9652 could be an allocatable component of a pointer component. */
9653 if (expr->symtree->n.sym->ts.type != BT_DERIVED
9654 && expr->symtree->n.sym->ts.type != BT_CLASS)
9655 return false;
9657 /* Find an allocatable component ref last. */
9658 for (ref = expr->ref; ref; ref = ref->next)
9659 if (ref->type == REF_COMPONENT
9660 && !ref->next
9661 && ref->u.c.component->attr.allocatable)
9662 return true;
9664 return false;
9668 /* Allocate or reallocate scalar lhs, as necessary. */
9670 static void
9671 alloc_scalar_allocatable_for_assignment (stmtblock_t *block,
9672 tree string_length,
9673 gfc_expr *expr1,
9674 gfc_expr *expr2)
9677 tree cond;
9678 tree tmp;
9679 tree size;
9680 tree size_in_bytes;
9681 tree jump_label1;
9682 tree jump_label2;
9683 gfc_se lse;
9684 gfc_ref *ref;
9686 if (!expr1 || expr1->rank)
9687 return;
9689 if (!expr2 || expr2->rank)
9690 return;
9692 for (ref = expr1->ref; ref; ref = ref->next)
9693 if (ref->type == REF_SUBSTRING)
9694 return;
9696 realloc_lhs_warning (expr2->ts.type, false, &expr2->where);
9698 /* Since this is a scalar lhs, we can afford to do this. That is,
9699 there is no risk of side effects being repeated. */
9700 gfc_init_se (&lse, NULL);
9701 lse.want_pointer = 1;
9702 gfc_conv_expr (&lse, expr1);
9704 jump_label1 = gfc_build_label_decl (NULL_TREE);
9705 jump_label2 = gfc_build_label_decl (NULL_TREE);
9707 /* Do the allocation if the lhs is NULL. Otherwise go to label 1. */
9708 tmp = build_int_cst (TREE_TYPE (lse.expr), 0);
9709 cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
9710 lse.expr, tmp);
9711 tmp = build3_v (COND_EXPR, cond,
9712 build1_v (GOTO_EXPR, jump_label1),
9713 build_empty_stmt (input_location));
9714 gfc_add_expr_to_block (block, tmp);
9716 if (expr1->ts.type == BT_CHARACTER && expr1->ts.deferred)
9718 /* Use the rhs string length and the lhs element size. */
9719 size = string_length;
9720 tmp = TREE_TYPE (gfc_typenode_for_spec (&expr1->ts));
9721 tmp = TYPE_SIZE_UNIT (tmp);
9722 size_in_bytes = fold_build2_loc (input_location, MULT_EXPR,
9723 TREE_TYPE (tmp), tmp,
9724 fold_convert (TREE_TYPE (tmp), size));
9726 else
9728 /* Otherwise use the length in bytes of the rhs. */
9729 size = TYPE_SIZE_UNIT (gfc_typenode_for_spec (&expr1->ts));
9730 size_in_bytes = size;
9733 size_in_bytes = fold_build2_loc (input_location, MAX_EXPR, size_type_node,
9734 size_in_bytes, size_one_node);
9736 if (gfc_caf_attr (expr1).codimension && flag_coarray == GFC_FCOARRAY_LIB)
9738 tree caf_decl, token;
9739 gfc_se caf_se;
9740 symbol_attribute attr;
9742 gfc_clear_attr (&attr);
9743 gfc_init_se (&caf_se, NULL);
9745 caf_decl = gfc_get_tree_for_caf_expr (expr1);
9746 gfc_get_caf_token_offset (&caf_se, &token, NULL, caf_decl, NULL_TREE,
9747 NULL);
9748 gfc_add_block_to_block (block, &caf_se.pre);
9749 gfc_allocate_allocatable (block, lse.expr, size_in_bytes,
9750 gfc_build_addr_expr (NULL_TREE, token),
9751 NULL_TREE, NULL_TREE, NULL_TREE, jump_label1,
9752 expr1, 1);
9754 else if (expr1->ts.type == BT_DERIVED && expr1->ts.u.derived->attr.alloc_comp)
9756 tmp = build_call_expr_loc (input_location,
9757 builtin_decl_explicit (BUILT_IN_CALLOC),
9758 2, build_one_cst (size_type_node),
9759 size_in_bytes);
9760 tmp = fold_convert (TREE_TYPE (lse.expr), tmp);
9761 gfc_add_modify (block, lse.expr, tmp);
9763 else
9765 tmp = build_call_expr_loc (input_location,
9766 builtin_decl_explicit (BUILT_IN_MALLOC),
9767 1, size_in_bytes);
9768 tmp = fold_convert (TREE_TYPE (lse.expr), tmp);
9769 gfc_add_modify (block, lse.expr, tmp);
9772 if (expr1->ts.type == BT_CHARACTER && expr1->ts.deferred)
9774 /* Deferred characters need checking for lhs and rhs string
9775 length. Other deferred parameter variables will have to
9776 come here too. */
9777 tmp = build1_v (GOTO_EXPR, jump_label2);
9778 gfc_add_expr_to_block (block, tmp);
9780 tmp = build1_v (LABEL_EXPR, jump_label1);
9781 gfc_add_expr_to_block (block, tmp);
9783 /* For a deferred length character, reallocate if lengths of lhs and
9784 rhs are different. */
9785 if (expr1->ts.type == BT_CHARACTER && expr1->ts.deferred)
9787 cond = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
9788 lse.string_length,
9789 fold_convert (TREE_TYPE (lse.string_length),
9790 size));
9791 /* Jump past the realloc if the lengths are the same. */
9792 tmp = build3_v (COND_EXPR, cond,
9793 build1_v (GOTO_EXPR, jump_label2),
9794 build_empty_stmt (input_location));
9795 gfc_add_expr_to_block (block, tmp);
9796 tmp = build_call_expr_loc (input_location,
9797 builtin_decl_explicit (BUILT_IN_REALLOC),
9798 2, fold_convert (pvoid_type_node, lse.expr),
9799 size_in_bytes);
9800 tmp = fold_convert (TREE_TYPE (lse.expr), tmp);
9801 gfc_add_modify (block, lse.expr, tmp);
9802 tmp = build1_v (LABEL_EXPR, jump_label2);
9803 gfc_add_expr_to_block (block, tmp);
9805 /* Update the lhs character length. */
9806 size = string_length;
9807 gfc_add_modify (block, lse.string_length,
9808 fold_convert (TREE_TYPE (lse.string_length), size));
9812 /* Check for assignments of the type
9814 a = a + 4
9816 to make sure we do not check for reallocation unneccessarily. */
9819 static bool
9820 is_runtime_conformable (gfc_expr *expr1, gfc_expr *expr2)
9822 gfc_actual_arglist *a;
9823 gfc_expr *e1, *e2;
9825 switch (expr2->expr_type)
9827 case EXPR_VARIABLE:
9828 return gfc_dep_compare_expr (expr1, expr2) == 0;
9830 case EXPR_FUNCTION:
9831 if (expr2->value.function.esym
9832 && expr2->value.function.esym->attr.elemental)
9834 for (a = expr2->value.function.actual; a != NULL; a = a->next)
9836 e1 = a->expr;
9837 if (e1 && e1->rank > 0 && !is_runtime_conformable (expr1, e1))
9838 return false;
9840 return true;
9842 else if (expr2->value.function.isym
9843 && expr2->value.function.isym->elemental)
9845 for (a = expr2->value.function.actual; a != NULL; a = a->next)
9847 e1 = a->expr;
9848 if (e1 && e1->rank > 0 && !is_runtime_conformable (expr1, e1))
9849 return false;
9851 return true;
9854 break;
9856 case EXPR_OP:
9857 switch (expr2->value.op.op)
9859 case INTRINSIC_NOT:
9860 case INTRINSIC_UPLUS:
9861 case INTRINSIC_UMINUS:
9862 case INTRINSIC_PARENTHESES:
9863 return is_runtime_conformable (expr1, expr2->value.op.op1);
9865 case INTRINSIC_PLUS:
9866 case INTRINSIC_MINUS:
9867 case INTRINSIC_TIMES:
9868 case INTRINSIC_DIVIDE:
9869 case INTRINSIC_POWER:
9870 case INTRINSIC_AND:
9871 case INTRINSIC_OR:
9872 case INTRINSIC_EQV:
9873 case INTRINSIC_NEQV:
9874 case INTRINSIC_EQ:
9875 case INTRINSIC_NE:
9876 case INTRINSIC_GT:
9877 case INTRINSIC_GE:
9878 case INTRINSIC_LT:
9879 case INTRINSIC_LE:
9880 case INTRINSIC_EQ_OS:
9881 case INTRINSIC_NE_OS:
9882 case INTRINSIC_GT_OS:
9883 case INTRINSIC_GE_OS:
9884 case INTRINSIC_LT_OS:
9885 case INTRINSIC_LE_OS:
9887 e1 = expr2->value.op.op1;
9888 e2 = expr2->value.op.op2;
9890 if (e1->rank == 0 && e2->rank > 0)
9891 return is_runtime_conformable (expr1, e2);
9892 else if (e1->rank > 0 && e2->rank == 0)
9893 return is_runtime_conformable (expr1, e1);
9894 else if (e1->rank > 0 && e2->rank > 0)
9895 return is_runtime_conformable (expr1, e1)
9896 && is_runtime_conformable (expr1, e2);
9897 break;
9899 default:
9900 break;
9904 break;
9906 default:
9907 break;
9909 return false;
9913 static tree
9914 trans_class_assignment (stmtblock_t *block, gfc_expr *lhs, gfc_expr *rhs,
9915 gfc_se *lse, gfc_se *rse, bool use_vptr_copy,
9916 bool class_realloc)
9918 tree tmp, fcn, stdcopy, to_len, from_len, vptr;
9919 vec<tree, va_gc> *args = NULL;
9921 vptr = trans_class_vptr_len_assignment (block, lhs, rhs, rse, &to_len,
9922 &from_len);
9924 /* Generate allocation of the lhs. */
9925 if (class_realloc)
9927 stmtblock_t alloc;
9928 tree class_han;
9930 tmp = gfc_vptr_size_get (vptr);
9931 class_han = GFC_CLASS_TYPE_P (TREE_TYPE (lse->expr))
9932 ? gfc_class_data_get (lse->expr) : lse->expr;
9933 gfc_init_block (&alloc);
9934 gfc_allocate_using_malloc (&alloc, class_han, tmp, NULL_TREE);
9935 tmp = fold_build2_loc (input_location, EQ_EXPR,
9936 logical_type_node, class_han,
9937 build_int_cst (prvoid_type_node, 0));
9938 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
9939 gfc_unlikely (tmp,
9940 PRED_FORTRAN_FAIL_ALLOC),
9941 gfc_finish_block (&alloc),
9942 build_empty_stmt (input_location));
9943 gfc_add_expr_to_block (&lse->pre, tmp);
9946 fcn = gfc_vptr_copy_get (vptr);
9948 tmp = GFC_CLASS_TYPE_P (TREE_TYPE (rse->expr))
9949 ? gfc_class_data_get (rse->expr) : rse->expr;
9950 if (use_vptr_copy)
9952 if (!POINTER_TYPE_P (TREE_TYPE (tmp))
9953 || INDIRECT_REF_P (tmp)
9954 || (rhs->ts.type == BT_DERIVED
9955 && rhs->ts.u.derived->attr.unlimited_polymorphic
9956 && !rhs->ts.u.derived->attr.pointer
9957 && !rhs->ts.u.derived->attr.allocatable)
9958 || (UNLIMITED_POLY (rhs)
9959 && !CLASS_DATA (rhs)->attr.pointer
9960 && !CLASS_DATA (rhs)->attr.allocatable))
9961 vec_safe_push (args, gfc_build_addr_expr (NULL_TREE, tmp));
9962 else
9963 vec_safe_push (args, tmp);
9964 tmp = GFC_CLASS_TYPE_P (TREE_TYPE (lse->expr))
9965 ? gfc_class_data_get (lse->expr) : lse->expr;
9966 if (!POINTER_TYPE_P (TREE_TYPE (tmp))
9967 || INDIRECT_REF_P (tmp)
9968 || (lhs->ts.type == BT_DERIVED
9969 && lhs->ts.u.derived->attr.unlimited_polymorphic
9970 && !lhs->ts.u.derived->attr.pointer
9971 && !lhs->ts.u.derived->attr.allocatable)
9972 || (UNLIMITED_POLY (lhs)
9973 && !CLASS_DATA (lhs)->attr.pointer
9974 && !CLASS_DATA (lhs)->attr.allocatable))
9975 vec_safe_push (args, gfc_build_addr_expr (NULL_TREE, tmp));
9976 else
9977 vec_safe_push (args, tmp);
9979 stdcopy = build_call_vec (TREE_TYPE (TREE_TYPE (fcn)), fcn, args);
9981 if (to_len != NULL_TREE && !integer_zerop (from_len))
9983 tree extcopy;
9984 vec_safe_push (args, from_len);
9985 vec_safe_push (args, to_len);
9986 extcopy = build_call_vec (TREE_TYPE (TREE_TYPE (fcn)), fcn, args);
9988 tmp = fold_build2_loc (input_location, GT_EXPR,
9989 logical_type_node, from_len,
9990 build_zero_cst (TREE_TYPE (from_len)));
9991 return fold_build3_loc (input_location, COND_EXPR,
9992 void_type_node, tmp,
9993 extcopy, stdcopy);
9995 else
9996 return stdcopy;
9998 else
10000 tree rhst = GFC_CLASS_TYPE_P (TREE_TYPE (lse->expr))
10001 ? gfc_class_data_get (lse->expr) : lse->expr;
10002 stmtblock_t tblock;
10003 gfc_init_block (&tblock);
10004 if (!POINTER_TYPE_P (TREE_TYPE (tmp)))
10005 tmp = gfc_build_addr_expr (NULL_TREE, tmp);
10006 if (!POINTER_TYPE_P (TREE_TYPE (rhst)))
10007 rhst = gfc_build_addr_expr (NULL_TREE, rhst);
10008 /* When coming from a ptr_copy lhs and rhs are swapped. */
10009 gfc_add_modify_loc (input_location, &tblock, rhst,
10010 fold_convert (TREE_TYPE (rhst), tmp));
10011 return gfc_finish_block (&tblock);
10015 /* Subroutine of gfc_trans_assignment that actually scalarizes the
10016 assignment. EXPR1 is the destination/LHS and EXPR2 is the source/RHS.
10017 init_flag indicates initialization expressions and dealloc that no
10018 deallocate prior assignment is needed (if in doubt, set true).
10019 When PTR_COPY is set and expr1 is a class type, then use the _vptr-copy
10020 routine instead of a pointer assignment. Alias resolution is only done,
10021 when MAY_ALIAS is set (the default). This flag is used by ALLOCATE()
10022 where it is known, that newly allocated memory on the lhs can never be
10023 an alias of the rhs. */
10025 static tree
10026 gfc_trans_assignment_1 (gfc_expr * expr1, gfc_expr * expr2, bool init_flag,
10027 bool dealloc, bool use_vptr_copy, bool may_alias)
10029 gfc_se lse;
10030 gfc_se rse;
10031 gfc_ss *lss;
10032 gfc_ss *lss_section;
10033 gfc_ss *rss;
10034 gfc_loopinfo loop;
10035 tree tmp;
10036 stmtblock_t block;
10037 stmtblock_t body;
10038 bool l_is_temp;
10039 bool scalar_to_array;
10040 tree string_length;
10041 int n;
10042 bool maybe_workshare = false, lhs_refs_comp = false, rhs_refs_comp = false;
10043 symbol_attribute lhs_caf_attr, rhs_caf_attr, lhs_attr;
10044 bool is_poly_assign;
10046 /* Assignment of the form lhs = rhs. */
10047 gfc_start_block (&block);
10049 gfc_init_se (&lse, NULL);
10050 gfc_init_se (&rse, NULL);
10052 /* Walk the lhs. */
10053 lss = gfc_walk_expr (expr1);
10054 if (gfc_is_reallocatable_lhs (expr1))
10056 lss->no_bounds_check = 1;
10057 if (!(expr2->expr_type == EXPR_FUNCTION
10058 && expr2->value.function.isym != NULL
10059 && !(expr2->value.function.isym->elemental
10060 || expr2->value.function.isym->conversion)))
10061 lss->is_alloc_lhs = 1;
10063 else
10064 lss->no_bounds_check = expr1->no_bounds_check;
10066 rss = NULL;
10068 if ((expr1->ts.type == BT_DERIVED)
10069 && (gfc_is_class_array_function (expr2)
10070 || gfc_is_alloc_class_scalar_function (expr2)))
10071 expr2->must_finalize = 1;
10073 /* Checking whether a class assignment is desired is quite complicated and
10074 needed at two locations, so do it once only before the information is
10075 needed. */
10076 lhs_attr = gfc_expr_attr (expr1);
10077 is_poly_assign = (use_vptr_copy || lhs_attr.pointer
10078 || (lhs_attr.allocatable && !lhs_attr.dimension))
10079 && (expr1->ts.type == BT_CLASS
10080 || gfc_is_class_array_ref (expr1, NULL)
10081 || gfc_is_class_scalar_expr (expr1)
10082 || gfc_is_class_array_ref (expr2, NULL)
10083 || gfc_is_class_scalar_expr (expr2));
10086 /* Only analyze the expressions for coarray properties, when in coarray-lib
10087 mode. */
10088 if (flag_coarray == GFC_FCOARRAY_LIB)
10090 lhs_caf_attr = gfc_caf_attr (expr1, false, &lhs_refs_comp);
10091 rhs_caf_attr = gfc_caf_attr (expr2, false, &rhs_refs_comp);
10094 if (lss != gfc_ss_terminator)
10096 /* The assignment needs scalarization. */
10097 lss_section = lss;
10099 /* Find a non-scalar SS from the lhs. */
10100 while (lss_section != gfc_ss_terminator
10101 && lss_section->info->type != GFC_SS_SECTION)
10102 lss_section = lss_section->next;
10104 gcc_assert (lss_section != gfc_ss_terminator);
10106 /* Initialize the scalarizer. */
10107 gfc_init_loopinfo (&loop);
10109 /* Walk the rhs. */
10110 rss = gfc_walk_expr (expr2);
10111 if (rss == gfc_ss_terminator)
10112 /* The rhs is scalar. Add a ss for the expression. */
10113 rss = gfc_get_scalar_ss (gfc_ss_terminator, expr2);
10114 /* When doing a class assign, then the handle to the rhs needs to be a
10115 pointer to allow for polymorphism. */
10116 if (is_poly_assign && expr2->rank == 0 && !UNLIMITED_POLY (expr2))
10117 rss->info->type = GFC_SS_REFERENCE;
10119 rss->no_bounds_check = expr2->no_bounds_check;
10120 /* Associate the SS with the loop. */
10121 gfc_add_ss_to_loop (&loop, lss);
10122 gfc_add_ss_to_loop (&loop, rss);
10124 /* Calculate the bounds of the scalarization. */
10125 gfc_conv_ss_startstride (&loop);
10126 /* Enable loop reversal. */
10127 for (n = 0; n < GFC_MAX_DIMENSIONS; n++)
10128 loop.reverse[n] = GFC_ENABLE_REVERSE;
10129 /* Resolve any data dependencies in the statement. */
10130 if (may_alias)
10131 gfc_conv_resolve_dependencies (&loop, lss, rss);
10132 /* Setup the scalarizing loops. */
10133 gfc_conv_loop_setup (&loop, &expr2->where);
10135 /* Setup the gfc_se structures. */
10136 gfc_copy_loopinfo_to_se (&lse, &loop);
10137 gfc_copy_loopinfo_to_se (&rse, &loop);
10139 rse.ss = rss;
10140 gfc_mark_ss_chain_used (rss, 1);
10141 if (loop.temp_ss == NULL)
10143 lse.ss = lss;
10144 gfc_mark_ss_chain_used (lss, 1);
10146 else
10148 lse.ss = loop.temp_ss;
10149 gfc_mark_ss_chain_used (lss, 3);
10150 gfc_mark_ss_chain_used (loop.temp_ss, 3);
10153 /* Allow the scalarizer to workshare array assignments. */
10154 if ((ompws_flags & (OMPWS_WORKSHARE_FLAG | OMPWS_SCALARIZER_BODY))
10155 == OMPWS_WORKSHARE_FLAG
10156 && loop.temp_ss == NULL)
10158 maybe_workshare = true;
10159 ompws_flags |= OMPWS_SCALARIZER_WS | OMPWS_SCALARIZER_BODY;
10162 /* Start the scalarized loop body. */
10163 gfc_start_scalarized_body (&loop, &body);
10165 else
10166 gfc_init_block (&body);
10168 l_is_temp = (lss != gfc_ss_terminator && loop.temp_ss != NULL);
10170 /* Translate the expression. */
10171 rse.want_coarray = flag_coarray == GFC_FCOARRAY_LIB && init_flag
10172 && lhs_caf_attr.codimension;
10173 gfc_conv_expr (&rse, expr2);
10175 /* Deal with the case of a scalar class function assigned to a derived type. */
10176 if (gfc_is_alloc_class_scalar_function (expr2)
10177 && expr1->ts.type == BT_DERIVED)
10179 rse.expr = gfc_class_data_get (rse.expr);
10180 rse.expr = build_fold_indirect_ref_loc (input_location, rse.expr);
10183 /* Stabilize a string length for temporaries. */
10184 if (expr2->ts.type == BT_CHARACTER && !expr1->ts.deferred
10185 && !(VAR_P (rse.string_length)
10186 || TREE_CODE (rse.string_length) == PARM_DECL
10187 || TREE_CODE (rse.string_length) == INDIRECT_REF))
10188 string_length = gfc_evaluate_now (rse.string_length, &rse.pre);
10189 else if (expr2->ts.type == BT_CHARACTER)
10190 string_length = rse.string_length;
10191 else
10192 string_length = NULL_TREE;
10194 if (l_is_temp)
10196 gfc_conv_tmp_array_ref (&lse);
10197 if (expr2->ts.type == BT_CHARACTER)
10198 lse.string_length = string_length;
10200 else
10202 gfc_conv_expr (&lse, expr1);
10203 if (gfc_option.rtcheck & GFC_RTCHECK_MEM
10204 && !init_flag
10205 && gfc_expr_attr (expr1).allocatable
10206 && expr1->rank
10207 && !expr2->rank)
10209 tree cond;
10210 const char* msg;
10212 tmp = INDIRECT_REF_P (lse.expr)
10213 ? gfc_build_addr_expr (NULL_TREE, lse.expr) : lse.expr;
10215 /* We should only get array references here. */
10216 gcc_assert (TREE_CODE (tmp) == POINTER_PLUS_EXPR
10217 || TREE_CODE (tmp) == ARRAY_REF);
10219 /* 'tmp' is either the pointer to the array(POINTER_PLUS_EXPR)
10220 or the array itself(ARRAY_REF). */
10221 tmp = TREE_OPERAND (tmp, 0);
10223 /* Provide the address of the array. */
10224 if (TREE_CODE (lse.expr) == ARRAY_REF)
10225 tmp = gfc_build_addr_expr (NULL_TREE, tmp);
10227 cond = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
10228 tmp, build_int_cst (TREE_TYPE (tmp), 0));
10229 msg = _("Assignment of scalar to unallocated array");
10230 gfc_trans_runtime_check (true, false, cond, &loop.pre,
10231 &expr1->where, msg);
10234 /* Deallocate the lhs parameterized components if required. */
10235 if (dealloc && expr2->expr_type == EXPR_FUNCTION
10236 && !expr1->symtree->n.sym->attr.associate_var)
10238 if (expr1->ts.type == BT_DERIVED
10239 && expr1->ts.u.derived
10240 && expr1->ts.u.derived->attr.pdt_type)
10242 tmp = gfc_deallocate_pdt_comp (expr1->ts.u.derived, lse.expr,
10243 expr1->rank);
10244 gfc_add_expr_to_block (&lse.pre, tmp);
10246 else if (expr1->ts.type == BT_CLASS
10247 && CLASS_DATA (expr1)->ts.u.derived
10248 && CLASS_DATA (expr1)->ts.u.derived->attr.pdt_type)
10250 tmp = gfc_class_data_get (lse.expr);
10251 tmp = gfc_deallocate_pdt_comp (CLASS_DATA (expr1)->ts.u.derived,
10252 tmp, expr1->rank);
10253 gfc_add_expr_to_block (&lse.pre, tmp);
10258 /* Assignments of scalar derived types with allocatable components
10259 to arrays must be done with a deep copy and the rhs temporary
10260 must have its components deallocated afterwards. */
10261 scalar_to_array = (expr2->ts.type == BT_DERIVED
10262 && expr2->ts.u.derived->attr.alloc_comp
10263 && !gfc_expr_is_variable (expr2)
10264 && expr1->rank && !expr2->rank);
10265 scalar_to_array |= (expr1->ts.type == BT_DERIVED
10266 && expr1->rank
10267 && expr1->ts.u.derived->attr.alloc_comp
10268 && gfc_is_alloc_class_scalar_function (expr2));
10269 if (scalar_to_array && dealloc)
10271 tmp = gfc_deallocate_alloc_comp_no_caf (expr2->ts.u.derived, rse.expr, 0);
10272 gfc_prepend_expr_to_block (&loop.post, tmp);
10275 /* When assigning a character function result to a deferred-length variable,
10276 the function call must happen before the (re)allocation of the lhs -
10277 otherwise the character length of the result is not known.
10278 NOTE: This relies on having the exact dependence of the length type
10279 parameter available to the caller; gfortran saves it in the .mod files.
10280 NOTE ALSO: The concatenation operation generates a temporary pointer,
10281 whose allocation must go to the innermost loop.
10282 NOTE ALSO (2): Elemental functions may generate a temporary, too. */
10283 if (flag_realloc_lhs
10284 && expr2->ts.type == BT_CHARACTER && expr1->ts.deferred
10285 && !(lss != gfc_ss_terminator
10286 && rss != gfc_ss_terminator
10287 && ((expr2->expr_type == EXPR_FUNCTION
10288 && expr2->value.function.esym != NULL
10289 && expr2->value.function.esym->attr.elemental)
10290 || (expr2->expr_type == EXPR_FUNCTION
10291 && expr2->value.function.isym != NULL
10292 && expr2->value.function.isym->elemental)
10293 || (expr2->expr_type == EXPR_OP
10294 && expr2->value.op.op == INTRINSIC_CONCAT))))
10295 gfc_add_block_to_block (&block, &rse.pre);
10297 /* Nullify the allocatable components corresponding to those of the lhs
10298 derived type, so that the finalization of the function result does not
10299 affect the lhs of the assignment. Prepend is used to ensure that the
10300 nullification occurs before the call to the finalizer. In the case of
10301 a scalar to array assignment, this is done in gfc_trans_scalar_assign
10302 as part of the deep copy. */
10303 if (!scalar_to_array && expr1->ts.type == BT_DERIVED
10304 && (gfc_is_class_array_function (expr2)
10305 || gfc_is_alloc_class_scalar_function (expr2)))
10307 tmp = rse.expr;
10308 tmp = gfc_nullify_alloc_comp (expr1->ts.u.derived, rse.expr, 0);
10309 gfc_prepend_expr_to_block (&rse.post, tmp);
10310 if (lss != gfc_ss_terminator && rss == gfc_ss_terminator)
10311 gfc_add_block_to_block (&loop.post, &rse.post);
10314 tmp = NULL_TREE;
10316 if (is_poly_assign)
10317 tmp = trans_class_assignment (&body, expr1, expr2, &lse, &rse,
10318 use_vptr_copy || (lhs_attr.allocatable
10319 && !lhs_attr.dimension),
10320 flag_realloc_lhs && !lhs_attr.pointer);
10321 else if (flag_coarray == GFC_FCOARRAY_LIB
10322 && lhs_caf_attr.codimension && rhs_caf_attr.codimension
10323 && ((lhs_caf_attr.allocatable && lhs_refs_comp)
10324 || (rhs_caf_attr.allocatable && rhs_refs_comp)))
10326 /* Only detour to caf_send[get][_by_ref] () when the lhs or rhs is an
10327 allocatable component, because those need to be accessed via the
10328 caf-runtime. No need to check for coindexes here, because resolve
10329 has rewritten those already. */
10330 gfc_code code;
10331 gfc_actual_arglist a1, a2;
10332 /* Clear the structures to prevent accessing garbage. */
10333 memset (&code, '\0', sizeof (gfc_code));
10334 memset (&a1, '\0', sizeof (gfc_actual_arglist));
10335 memset (&a2, '\0', sizeof (gfc_actual_arglist));
10336 a1.expr = expr1;
10337 a1.next = &a2;
10338 a2.expr = expr2;
10339 a2.next = NULL;
10340 code.ext.actual = &a1;
10341 code.resolved_isym = gfc_intrinsic_subroutine_by_id (GFC_ISYM_CAF_SEND);
10342 tmp = gfc_conv_intrinsic_subroutine (&code);
10344 else if (!is_poly_assign && expr2->must_finalize
10345 && expr1->ts.type == BT_CLASS
10346 && expr2->ts.type == BT_CLASS)
10348 /* This case comes about when the scalarizer provides array element
10349 references. Use the vptr copy function, since this does a deep
10350 copy of allocatable components, without which the finalizer call */
10351 tmp = gfc_get_vptr_from_expr (rse.expr);
10352 if (tmp != NULL_TREE)
10354 tree fcn = gfc_vptr_copy_get (tmp);
10355 if (POINTER_TYPE_P (TREE_TYPE (fcn)))
10356 fcn = build_fold_indirect_ref_loc (input_location, fcn);
10357 tmp = build_call_expr_loc (input_location,
10358 fcn, 2,
10359 gfc_build_addr_expr (NULL, rse.expr),
10360 gfc_build_addr_expr (NULL, lse.expr));
10364 /* If nothing else works, do it the old fashioned way! */
10365 if (tmp == NULL_TREE)
10366 tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts,
10367 gfc_expr_is_variable (expr2)
10368 || scalar_to_array
10369 || expr2->expr_type == EXPR_ARRAY,
10370 !(l_is_temp || init_flag) && dealloc,
10371 expr1->symtree->n.sym->attr.codimension);
10373 /* Add the pre blocks to the body. */
10374 gfc_add_block_to_block (&body, &rse.pre);
10375 gfc_add_block_to_block (&body, &lse.pre);
10376 gfc_add_expr_to_block (&body, tmp);
10377 /* Add the post blocks to the body. */
10378 gfc_add_block_to_block (&body, &rse.post);
10379 gfc_add_block_to_block (&body, &lse.post);
10381 if (lss == gfc_ss_terminator)
10383 /* F2003: Add the code for reallocation on assignment. */
10384 if (flag_realloc_lhs && is_scalar_reallocatable_lhs (expr1)
10385 && !is_poly_assign)
10386 alloc_scalar_allocatable_for_assignment (&block, string_length,
10387 expr1, expr2);
10389 /* Use the scalar assignment as is. */
10390 gfc_add_block_to_block (&block, &body);
10392 else
10394 gcc_assert (lse.ss == gfc_ss_terminator
10395 && rse.ss == gfc_ss_terminator);
10397 if (l_is_temp)
10399 gfc_trans_scalarized_loop_boundary (&loop, &body);
10401 /* We need to copy the temporary to the actual lhs. */
10402 gfc_init_se (&lse, NULL);
10403 gfc_init_se (&rse, NULL);
10404 gfc_copy_loopinfo_to_se (&lse, &loop);
10405 gfc_copy_loopinfo_to_se (&rse, &loop);
10407 rse.ss = loop.temp_ss;
10408 lse.ss = lss;
10410 gfc_conv_tmp_array_ref (&rse);
10411 gfc_conv_expr (&lse, expr1);
10413 gcc_assert (lse.ss == gfc_ss_terminator
10414 && rse.ss == gfc_ss_terminator);
10416 if (expr2->ts.type == BT_CHARACTER)
10417 rse.string_length = string_length;
10419 tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts,
10420 false, dealloc);
10421 gfc_add_expr_to_block (&body, tmp);
10424 /* F2003: Allocate or reallocate lhs of allocatable array. */
10425 if (flag_realloc_lhs
10426 && gfc_is_reallocatable_lhs (expr1)
10427 && expr2->rank
10428 && !is_runtime_conformable (expr1, expr2))
10430 realloc_lhs_warning (expr1->ts.type, true, &expr1->where);
10431 ompws_flags &= ~OMPWS_SCALARIZER_WS;
10432 tmp = gfc_alloc_allocatable_for_assignment (&loop, expr1, expr2);
10433 if (tmp != NULL_TREE)
10434 gfc_add_expr_to_block (&loop.code[expr1->rank - 1], tmp);
10437 if (maybe_workshare)
10438 ompws_flags &= ~OMPWS_SCALARIZER_BODY;
10440 /* Generate the copying loops. */
10441 gfc_trans_scalarizing_loops (&loop, &body);
10443 /* Wrap the whole thing up. */
10444 gfc_add_block_to_block (&block, &loop.pre);
10445 gfc_add_block_to_block (&block, &loop.post);
10447 gfc_cleanup_loop (&loop);
10450 return gfc_finish_block (&block);
10454 /* Check whether EXPR is a copyable array. */
10456 static bool
10457 copyable_array_p (gfc_expr * expr)
10459 if (expr->expr_type != EXPR_VARIABLE)
10460 return false;
10462 /* First check it's an array. */
10463 if (expr->rank < 1 || !expr->ref || expr->ref->next)
10464 return false;
10466 if (!gfc_full_array_ref_p (expr->ref, NULL))
10467 return false;
10469 /* Next check that it's of a simple enough type. */
10470 switch (expr->ts.type)
10472 case BT_INTEGER:
10473 case BT_REAL:
10474 case BT_COMPLEX:
10475 case BT_LOGICAL:
10476 return true;
10478 case BT_CHARACTER:
10479 return false;
10481 case_bt_struct:
10482 return !expr->ts.u.derived->attr.alloc_comp;
10484 default:
10485 break;
10488 return false;
10491 /* Translate an assignment. */
10493 tree
10494 gfc_trans_assignment (gfc_expr * expr1, gfc_expr * expr2, bool init_flag,
10495 bool dealloc, bool use_vptr_copy, bool may_alias)
10497 tree tmp;
10499 /* Special case a single function returning an array. */
10500 if (expr2->expr_type == EXPR_FUNCTION && expr2->rank > 0)
10502 tmp = gfc_trans_arrayfunc_assign (expr1, expr2);
10503 if (tmp)
10504 return tmp;
10507 /* Special case assigning an array to zero. */
10508 if (copyable_array_p (expr1)
10509 && is_zero_initializer_p (expr2))
10511 tmp = gfc_trans_zero_assign (expr1);
10512 if (tmp)
10513 return tmp;
10516 /* Special case copying one array to another. */
10517 if (copyable_array_p (expr1)
10518 && copyable_array_p (expr2)
10519 && gfc_compare_types (&expr1->ts, &expr2->ts)
10520 && !gfc_check_dependency (expr1, expr2, 0))
10522 tmp = gfc_trans_array_copy (expr1, expr2);
10523 if (tmp)
10524 return tmp;
10527 /* Special case initializing an array from a constant array constructor. */
10528 if (copyable_array_p (expr1)
10529 && expr2->expr_type == EXPR_ARRAY
10530 && gfc_compare_types (&expr1->ts, &expr2->ts))
10532 tmp = gfc_trans_array_constructor_copy (expr1, expr2);
10533 if (tmp)
10534 return tmp;
10537 if (UNLIMITED_POLY (expr1) && expr1->rank
10538 && expr2->ts.type != BT_CLASS)
10539 use_vptr_copy = true;
10541 /* Fallback to the scalarizer to generate explicit loops. */
10542 return gfc_trans_assignment_1 (expr1, expr2, init_flag, dealloc,
10543 use_vptr_copy, may_alias);
10546 tree
10547 gfc_trans_init_assign (gfc_code * code)
10549 return gfc_trans_assignment (code->expr1, code->expr2, true, false, true);
10552 tree
10553 gfc_trans_assign (gfc_code * code)
10555 return gfc_trans_assignment (code->expr1, code->expr2, false, true);