* g++.dg/cpp0x/constexpr-53094-2.C: Ignore non-standard ABI
[official-gcc.git] / gcc / fortran / trans-expr.c
blob2c3ff1fc3cd608021b65b6d94ec59609c0fac90b
1 /* Expression translation
2 Copyright (C) 2002-2013 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 "tree.h"
28 #include "diagnostic-core.h" /* For fatal_error. */
29 #include "langhooks.h"
30 #include "flags.h"
31 #include "gfortran.h"
32 #include "arith.h"
33 #include "constructor.h"
34 #include "trans.h"
35 #include "trans-const.h"
36 #include "trans-types.h"
37 #include "trans-array.h"
38 /* Only for gfc_trans_assign and gfc_trans_pointer_assign. */
39 #include "trans-stmt.h"
40 #include "dependency.h"
43 /* Convert a scalar to an array descriptor. To be used for assumed-rank
44 arrays. */
46 static tree
47 get_scalar_to_descriptor_type (tree scalar, symbol_attribute attr)
49 enum gfc_array_kind akind;
51 if (attr.pointer)
52 akind = GFC_ARRAY_POINTER_CONT;
53 else if (attr.allocatable)
54 akind = GFC_ARRAY_ALLOCATABLE;
55 else
56 akind = GFC_ARRAY_ASSUMED_SHAPE_CONT;
58 return gfc_get_array_type_bounds (TREE_TYPE (scalar), 0, 0, NULL, NULL, 1,
59 akind, !(attr.pointer || attr.target));
62 tree
63 gfc_conv_scalar_to_descriptor (gfc_se *se, tree scalar, symbol_attribute attr)
65 tree desc, type;
67 type = get_scalar_to_descriptor_type (scalar, attr);
68 desc = gfc_create_var (type, "desc");
69 DECL_ARTIFICIAL (desc) = 1;
70 gfc_add_modify (&se->pre, gfc_conv_descriptor_dtype (desc),
71 gfc_get_dtype (type));
72 gfc_conv_descriptor_data_set (&se->pre, desc, scalar);
74 /* Copy pointer address back - but only if it could have changed and
75 if the actual argument is a pointer and not, e.g., NULL(). */
76 if ((attr.pointer || attr.allocatable)
77 && attr.intent != INTENT_IN && POINTER_TYPE_P (TREE_TYPE (scalar)))
78 gfc_add_modify (&se->post, scalar,
79 fold_convert (TREE_TYPE (scalar),
80 gfc_conv_descriptor_data_get (desc)));
81 return desc;
85 /* This is the seed for an eventual trans-class.c
87 The following parameters should not be used directly since they might
88 in future implementations. Use the corresponding APIs. */
89 #define CLASS_DATA_FIELD 0
90 #define CLASS_VPTR_FIELD 1
91 #define VTABLE_HASH_FIELD 0
92 #define VTABLE_SIZE_FIELD 1
93 #define VTABLE_EXTENDS_FIELD 2
94 #define VTABLE_DEF_INIT_FIELD 3
95 #define VTABLE_COPY_FIELD 4
96 #define VTABLE_FINAL_FIELD 5
99 tree
100 gfc_class_data_get (tree decl)
102 tree data;
103 if (POINTER_TYPE_P (TREE_TYPE (decl)))
104 decl = build_fold_indirect_ref_loc (input_location, decl);
105 data = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (decl)),
106 CLASS_DATA_FIELD);
107 return fold_build3_loc (input_location, COMPONENT_REF,
108 TREE_TYPE (data), decl, data,
109 NULL_TREE);
113 tree
114 gfc_class_vptr_get (tree decl)
116 tree vptr;
117 if (POINTER_TYPE_P (TREE_TYPE (decl)))
118 decl = build_fold_indirect_ref_loc (input_location, decl);
119 vptr = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (decl)),
120 CLASS_VPTR_FIELD);
121 return fold_build3_loc (input_location, COMPONENT_REF,
122 TREE_TYPE (vptr), decl, vptr,
123 NULL_TREE);
127 static tree
128 gfc_vtable_field_get (tree decl, int field)
130 tree size;
131 tree vptr;
132 vptr = gfc_class_vptr_get (decl);
133 vptr = build_fold_indirect_ref_loc (input_location, vptr);
134 size = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (vptr)),
135 field);
136 size = fold_build3_loc (input_location, COMPONENT_REF,
137 TREE_TYPE (size), vptr, size,
138 NULL_TREE);
139 /* Always return size as an array index type. */
140 if (field == VTABLE_SIZE_FIELD)
141 size = fold_convert (gfc_array_index_type, size);
142 gcc_assert (size);
143 return size;
147 tree
148 gfc_vtable_hash_get (tree decl)
150 return gfc_vtable_field_get (decl, VTABLE_HASH_FIELD);
154 tree
155 gfc_vtable_size_get (tree decl)
157 return gfc_vtable_field_get (decl, VTABLE_SIZE_FIELD);
161 tree
162 gfc_vtable_extends_get (tree decl)
164 return gfc_vtable_field_get (decl, VTABLE_EXTENDS_FIELD);
168 tree
169 gfc_vtable_def_init_get (tree decl)
171 return gfc_vtable_field_get (decl, VTABLE_DEF_INIT_FIELD);
175 tree
176 gfc_vtable_copy_get (tree decl)
178 return gfc_vtable_field_get (decl, VTABLE_COPY_FIELD);
182 tree
183 gfc_vtable_final_get (tree decl)
185 return gfc_vtable_field_get (decl, VTABLE_FINAL_FIELD);
189 #undef CLASS_DATA_FIELD
190 #undef CLASS_VPTR_FIELD
191 #undef VTABLE_HASH_FIELD
192 #undef VTABLE_SIZE_FIELD
193 #undef VTABLE_EXTENDS_FIELD
194 #undef VTABLE_DEF_INIT_FIELD
195 #undef VTABLE_COPY_FIELD
196 #undef VTABLE_FINAL_FIELD
199 /* Obtain the vptr of the last class reference in an expression.
200 Return NULL_TREE if no class reference is found. */
202 tree
203 gfc_get_vptr_from_expr (tree expr)
205 tree tmp;
206 tree type;
208 for (tmp = expr; tmp; tmp = TREE_OPERAND (tmp, 0))
210 type = TREE_TYPE (tmp);
211 while (type)
213 if (GFC_CLASS_TYPE_P (type))
214 return gfc_class_vptr_get (tmp);
215 if (type != TYPE_CANONICAL (type))
216 type = TYPE_CANONICAL (type);
217 else
218 type = NULL_TREE;
220 if (TREE_CODE (tmp) == VAR_DECL)
221 break;
223 return NULL_TREE;
227 static void
228 class_array_data_assign (stmtblock_t *block, tree lhs_desc, tree rhs_desc,
229 bool lhs_type)
231 tree tmp, tmp2, type;
233 gfc_conv_descriptor_data_set (block, lhs_desc,
234 gfc_conv_descriptor_data_get (rhs_desc));
235 gfc_conv_descriptor_offset_set (block, lhs_desc,
236 gfc_conv_descriptor_offset_get (rhs_desc));
238 gfc_add_modify (block, gfc_conv_descriptor_dtype (lhs_desc),
239 gfc_conv_descriptor_dtype (rhs_desc));
241 /* Assign the dimension as range-ref. */
242 tmp = gfc_get_descriptor_dimension (lhs_desc);
243 tmp2 = gfc_get_descriptor_dimension (rhs_desc);
245 type = lhs_type ? TREE_TYPE (tmp) : TREE_TYPE (tmp2);
246 tmp = build4_loc (input_location, ARRAY_RANGE_REF, type, tmp,
247 gfc_index_zero_node, NULL_TREE, NULL_TREE);
248 tmp2 = build4_loc (input_location, ARRAY_RANGE_REF, type, tmp2,
249 gfc_index_zero_node, NULL_TREE, NULL_TREE);
250 gfc_add_modify (block, tmp, tmp2);
254 /* Takes a derived type expression and returns the address of a temporary
255 class object of the 'declared' type. If vptr is not NULL, this is
256 used for the temporary class object.
257 optional_alloc_ptr is false when the dummy is neither allocatable
258 nor a pointer; that's only relevant for the optional handling. */
259 void
260 gfc_conv_derived_to_class (gfc_se *parmse, gfc_expr *e,
261 gfc_typespec class_ts, tree vptr, bool optional,
262 bool optional_alloc_ptr)
264 gfc_symbol *vtab;
265 tree cond_optional = NULL_TREE;
266 gfc_ss *ss;
267 tree ctree;
268 tree var;
269 tree tmp;
271 /* The derived type needs to be converted to a temporary
272 CLASS object. */
273 tmp = gfc_typenode_for_spec (&class_ts);
274 var = gfc_create_var (tmp, "class");
276 /* Set the vptr. */
277 ctree = gfc_class_vptr_get (var);
279 if (vptr != NULL_TREE)
281 /* Use the dynamic vptr. */
282 tmp = vptr;
284 else
286 /* In this case the vtab corresponds to the derived type and the
287 vptr must point to it. */
288 vtab = gfc_find_derived_vtab (e->ts.u.derived);
289 gcc_assert (vtab);
290 tmp = gfc_build_addr_expr (NULL_TREE, gfc_get_symbol_decl (vtab));
292 gfc_add_modify (&parmse->pre, ctree,
293 fold_convert (TREE_TYPE (ctree), tmp));
295 /* Now set the data field. */
296 ctree = gfc_class_data_get (var);
298 if (optional)
299 cond_optional = gfc_conv_expr_present (e->symtree->n.sym);
301 if (parmse->ss && parmse->ss->info->useflags)
303 /* For an array reference in an elemental procedure call we need
304 to retain the ss to provide the scalarized array reference. */
305 gfc_conv_expr_reference (parmse, e);
306 tmp = fold_convert (TREE_TYPE (ctree), parmse->expr);
307 if (optional)
308 tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp),
309 cond_optional, tmp,
310 fold_convert (TREE_TYPE (tmp), null_pointer_node));
311 gfc_add_modify (&parmse->pre, ctree, tmp);
314 else
316 ss = gfc_walk_expr (e);
317 if (ss == gfc_ss_terminator)
319 parmse->ss = NULL;
320 gfc_conv_expr_reference (parmse, e);
322 /* Scalar to an assumed-rank array. */
323 if (class_ts.u.derived->components->as)
325 tree type;
326 type = get_scalar_to_descriptor_type (parmse->expr,
327 gfc_expr_attr (e));
328 gfc_add_modify (&parmse->pre, gfc_conv_descriptor_dtype (ctree),
329 gfc_get_dtype (type));
330 if (optional)
331 parmse->expr = build3_loc (input_location, COND_EXPR,
332 TREE_TYPE (parmse->expr),
333 cond_optional, parmse->expr,
334 fold_convert (TREE_TYPE (parmse->expr),
335 null_pointer_node));
336 gfc_conv_descriptor_data_set (&parmse->pre, ctree, parmse->expr);
338 else
340 tmp = fold_convert (TREE_TYPE (ctree), parmse->expr);
341 if (optional)
342 tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp),
343 cond_optional, tmp,
344 fold_convert (TREE_TYPE (tmp),
345 null_pointer_node));
346 gfc_add_modify (&parmse->pre, ctree, tmp);
349 else
351 stmtblock_t block;
352 gfc_init_block (&block);
354 parmse->ss = ss;
355 gfc_conv_expr_descriptor (parmse, e);
357 if (e->rank != class_ts.u.derived->components->as->rank)
358 class_array_data_assign (&block, ctree, parmse->expr, true);
359 else
361 if (gfc_expr_attr (e).codimension)
362 parmse->expr = fold_build1_loc (input_location,
363 VIEW_CONVERT_EXPR,
364 TREE_TYPE (ctree),
365 parmse->expr);
366 gfc_add_modify (&block, ctree, parmse->expr);
369 if (optional)
371 tmp = gfc_finish_block (&block);
373 gfc_init_block (&block);
374 gfc_conv_descriptor_data_set (&block, ctree, null_pointer_node);
376 tmp = build3_v (COND_EXPR, cond_optional, tmp,
377 gfc_finish_block (&block));
378 gfc_add_expr_to_block (&parmse->pre, tmp);
380 else
381 gfc_add_block_to_block (&parmse->pre, &block);
385 /* Pass the address of the class object. */
386 parmse->expr = gfc_build_addr_expr (NULL_TREE, var);
388 if (optional && optional_alloc_ptr)
389 parmse->expr = build3_loc (input_location, COND_EXPR,
390 TREE_TYPE (parmse->expr),
391 cond_optional, parmse->expr,
392 fold_convert (TREE_TYPE (parmse->expr),
393 null_pointer_node));
397 /* Create a new class container, which is required as scalar coarrays
398 have an array descriptor while normal scalars haven't. Optionally,
399 NULL pointer checks are added if the argument is OPTIONAL. */
401 static void
402 class_scalar_coarray_to_class (gfc_se *parmse, gfc_expr *e,
403 gfc_typespec class_ts, bool optional)
405 tree var, ctree, tmp;
406 stmtblock_t block;
407 gfc_ref *ref;
408 gfc_ref *class_ref;
410 gfc_init_block (&block);
412 class_ref = NULL;
413 for (ref = e->ref; ref; ref = ref->next)
415 if (ref->type == REF_COMPONENT
416 && ref->u.c.component->ts.type == BT_CLASS)
417 class_ref = ref;
420 if (class_ref == NULL
421 && e->symtree && e->symtree->n.sym->ts.type == BT_CLASS)
422 tmp = e->symtree->n.sym->backend_decl;
423 else
425 /* Remove everything after the last class reference, convert the
426 expression and then recover its tailend once more. */
427 gfc_se tmpse;
428 ref = class_ref->next;
429 class_ref->next = NULL;
430 gfc_init_se (&tmpse, NULL);
431 gfc_conv_expr (&tmpse, e);
432 class_ref->next = ref;
433 tmp = tmpse.expr;
436 var = gfc_typenode_for_spec (&class_ts);
437 var = gfc_create_var (var, "class");
439 ctree = gfc_class_vptr_get (var);
440 gfc_add_modify (&block, ctree,
441 fold_convert (TREE_TYPE (ctree), gfc_class_vptr_get (tmp)));
443 ctree = gfc_class_data_get (var);
444 tmp = gfc_conv_descriptor_data_get (gfc_class_data_get (tmp));
445 gfc_add_modify (&block, ctree, fold_convert (TREE_TYPE (ctree), tmp));
447 /* Pass the address of the class object. */
448 parmse->expr = gfc_build_addr_expr (NULL_TREE, var);
450 if (optional)
452 tree cond = gfc_conv_expr_present (e->symtree->n.sym);
453 tree tmp2;
455 tmp = gfc_finish_block (&block);
457 gfc_init_block (&block);
458 tmp2 = gfc_class_data_get (var);
459 gfc_add_modify (&block, tmp2, fold_convert (TREE_TYPE (tmp2),
460 null_pointer_node));
461 tmp2 = gfc_finish_block (&block);
463 tmp = build3_loc (input_location, COND_EXPR, void_type_node,
464 cond, tmp, tmp2);
465 gfc_add_expr_to_block (&parmse->pre, tmp);
467 else
468 gfc_add_block_to_block (&parmse->pre, &block);
472 /* Takes an intrinsic type expression and returns the address of a temporary
473 class object of the 'declared' type. */
474 void
475 gfc_conv_intrinsic_to_class (gfc_se *parmse, gfc_expr *e,
476 gfc_typespec class_ts)
478 gfc_symbol *vtab;
479 gfc_ss *ss;
480 tree ctree;
481 tree var;
482 tree tmp;
484 /* The intrinsic type needs to be converted to a temporary
485 CLASS object. */
486 tmp = gfc_typenode_for_spec (&class_ts);
487 var = gfc_create_var (tmp, "class");
489 /* Set the vptr. */
490 ctree = gfc_class_vptr_get (var);
492 vtab = gfc_find_intrinsic_vtab (&e->ts);
493 gcc_assert (vtab);
494 tmp = gfc_build_addr_expr (NULL_TREE, gfc_get_symbol_decl (vtab));
495 gfc_add_modify (&parmse->pre, ctree,
496 fold_convert (TREE_TYPE (ctree), tmp));
498 /* Now set the data field. */
499 ctree = gfc_class_data_get (var);
500 if (parmse->ss && parmse->ss->info->useflags)
502 /* For an array reference in an elemental procedure call we need
503 to retain the ss to provide the scalarized array reference. */
504 gfc_conv_expr_reference (parmse, e);
505 tmp = fold_convert (TREE_TYPE (ctree), parmse->expr);
506 gfc_add_modify (&parmse->pre, ctree, tmp);
508 else
510 ss = gfc_walk_expr (e);
511 if (ss == gfc_ss_terminator)
513 parmse->ss = NULL;
514 gfc_conv_expr_reference (parmse, e);
515 tmp = fold_convert (TREE_TYPE (ctree), parmse->expr);
516 gfc_add_modify (&parmse->pre, ctree, tmp);
518 else
520 parmse->ss = ss;
521 gfc_conv_expr_descriptor (parmse, e);
522 gfc_add_modify (&parmse->pre, ctree, parmse->expr);
526 /* Pass the address of the class object. */
527 parmse->expr = gfc_build_addr_expr (NULL_TREE, var);
531 /* Takes a scalarized class array expression and returns the
532 address of a temporary scalar class object of the 'declared'
533 type.
534 OOP-TODO: This could be improved by adding code that branched on
535 the dynamic type being the same as the declared type. In this case
536 the original class expression can be passed directly.
537 optional_alloc_ptr is false when the dummy is neither allocatable
538 nor a pointer; that's relevant for the optional handling.
539 Set copyback to true if class container's _data and _vtab pointers
540 might get modified. */
542 void
543 gfc_conv_class_to_class (gfc_se *parmse, gfc_expr *e, gfc_typespec class_ts,
544 bool elemental, bool copyback, bool optional,
545 bool optional_alloc_ptr)
547 tree ctree;
548 tree var;
549 tree tmp;
550 tree vptr;
551 tree cond = NULL_TREE;
552 gfc_ref *ref;
553 gfc_ref *class_ref;
554 stmtblock_t block;
555 bool full_array = false;
557 gfc_init_block (&block);
559 class_ref = NULL;
560 for (ref = e->ref; ref; ref = ref->next)
562 if (ref->type == REF_COMPONENT
563 && ref->u.c.component->ts.type == BT_CLASS)
564 class_ref = ref;
566 if (ref->next == NULL)
567 break;
570 if ((ref == NULL || class_ref == ref)
571 && (!class_ts.u.derived->components->as
572 || class_ts.u.derived->components->as->rank != -1))
573 return;
575 /* Test for FULL_ARRAY. */
576 if (e->rank == 0 && gfc_expr_attr (e).codimension
577 && gfc_expr_attr (e).dimension)
578 full_array = true;
579 else
580 gfc_is_class_array_ref (e, &full_array);
582 /* The derived type needs to be converted to a temporary
583 CLASS object. */
584 tmp = gfc_typenode_for_spec (&class_ts);
585 var = gfc_create_var (tmp, "class");
587 /* Set the data. */
588 ctree = gfc_class_data_get (var);
589 if (class_ts.u.derived->components->as
590 && e->rank != class_ts.u.derived->components->as->rank)
592 if (e->rank == 0)
594 tree type = get_scalar_to_descriptor_type (parmse->expr,
595 gfc_expr_attr (e));
596 gfc_add_modify (&block, gfc_conv_descriptor_dtype (ctree),
597 gfc_get_dtype (type));
599 tmp = gfc_class_data_get (parmse->expr);
600 if (!POINTER_TYPE_P (TREE_TYPE (tmp)))
601 tmp = gfc_build_addr_expr (NULL_TREE, tmp);
603 gfc_conv_descriptor_data_set (&block, ctree, tmp);
605 else
606 class_array_data_assign (&block, ctree, parmse->expr, false);
608 else
610 if (TREE_TYPE (parmse->expr) != TREE_TYPE (ctree))
611 parmse->expr = fold_build1_loc (input_location, VIEW_CONVERT_EXPR,
612 TREE_TYPE (ctree), parmse->expr);
613 gfc_add_modify (&block, ctree, parmse->expr);
616 /* Return the data component, except in the case of scalarized array
617 references, where nullification of the cannot occur and so there
618 is no need. */
619 if (!elemental && full_array && copyback)
621 if (class_ts.u.derived->components->as
622 && e->rank != class_ts.u.derived->components->as->rank)
624 if (e->rank == 0)
625 gfc_add_modify (&parmse->post, gfc_class_data_get (parmse->expr),
626 gfc_conv_descriptor_data_get (ctree));
627 else
628 class_array_data_assign (&parmse->post, parmse->expr, ctree, true);
630 else
631 gfc_add_modify (&parmse->post, parmse->expr, ctree);
634 /* Set the vptr. */
635 ctree = gfc_class_vptr_get (var);
637 /* The vptr is the second field of the actual argument.
638 First we have to find the corresponding class reference. */
640 tmp = NULL_TREE;
641 if (class_ref == NULL
642 && e->symtree && e->symtree->n.sym->ts.type == BT_CLASS)
643 tmp = e->symtree->n.sym->backend_decl;
644 else
646 /* Remove everything after the last class reference, convert the
647 expression and then recover its tailend once more. */
648 gfc_se tmpse;
649 ref = class_ref->next;
650 class_ref->next = NULL;
651 gfc_init_se (&tmpse, NULL);
652 gfc_conv_expr (&tmpse, e);
653 class_ref->next = ref;
654 tmp = tmpse.expr;
657 gcc_assert (tmp != NULL_TREE);
659 /* Dereference if needs be. */
660 if (TREE_CODE (TREE_TYPE (tmp)) == REFERENCE_TYPE)
661 tmp = build_fold_indirect_ref_loc (input_location, tmp);
663 vptr = gfc_class_vptr_get (tmp);
664 gfc_add_modify (&block, ctree,
665 fold_convert (TREE_TYPE (ctree), vptr));
667 /* Return the vptr component, except in the case of scalarized array
668 references, where the dynamic type cannot change. */
669 if (!elemental && full_array && copyback)
670 gfc_add_modify (&parmse->post, vptr,
671 fold_convert (TREE_TYPE (vptr), ctree));
673 gcc_assert (!optional || (optional && !copyback));
674 if (optional)
676 tree tmp2;
678 cond = gfc_conv_expr_present (e->symtree->n.sym);
679 tmp = gfc_finish_block (&block);
681 if (optional_alloc_ptr)
682 tmp2 = build_empty_stmt (input_location);
683 else
685 gfc_init_block (&block);
687 tmp2 = gfc_conv_descriptor_data_get (gfc_class_data_get (var));
688 gfc_add_modify (&block, tmp2, fold_convert (TREE_TYPE (tmp2),
689 null_pointer_node));
690 tmp2 = gfc_finish_block (&block);
693 tmp = build3_loc (input_location, COND_EXPR, void_type_node,
694 cond, tmp, tmp2);
695 gfc_add_expr_to_block (&parmse->pre, tmp);
697 else
698 gfc_add_block_to_block (&parmse->pre, &block);
700 /* Pass the address of the class object. */
701 parmse->expr = gfc_build_addr_expr (NULL_TREE, var);
703 if (optional && optional_alloc_ptr)
704 parmse->expr = build3_loc (input_location, COND_EXPR,
705 TREE_TYPE (parmse->expr),
706 cond, parmse->expr,
707 fold_convert (TREE_TYPE (parmse->expr),
708 null_pointer_node));
712 /* Given a class array declaration and an index, returns the address
713 of the referenced element. */
715 tree
716 gfc_get_class_array_ref (tree index, tree class_decl)
718 tree data = gfc_class_data_get (class_decl);
719 tree size = gfc_vtable_size_get (class_decl);
720 tree offset = fold_build2_loc (input_location, MULT_EXPR,
721 gfc_array_index_type,
722 index, size);
723 tree ptr;
724 data = gfc_conv_descriptor_data_get (data);
725 ptr = fold_convert (pvoid_type_node, data);
726 ptr = fold_build_pointer_plus_loc (input_location, ptr, offset);
727 return fold_convert (TREE_TYPE (data), ptr);
731 /* Copies one class expression to another, assuming that if either
732 'to' or 'from' are arrays they are packed. Should 'from' be
733 NULL_TREE, the initialization expression for 'to' is used, assuming
734 that the _vptr is set. */
736 tree
737 gfc_copy_class_to_class (tree from, tree to, tree nelems)
739 tree fcn;
740 tree fcn_type;
741 tree from_data;
742 tree to_data;
743 tree to_ref;
744 tree from_ref;
745 vec<tree, va_gc> *args;
746 tree tmp;
747 tree index;
748 stmtblock_t loopbody;
749 stmtblock_t body;
750 gfc_loopinfo loop;
752 args = NULL;
754 if (from != NULL_TREE)
755 fcn = gfc_vtable_copy_get (from);
756 else
757 fcn = gfc_vtable_copy_get (to);
759 fcn_type = TREE_TYPE (TREE_TYPE (fcn));
761 if (from != NULL_TREE)
762 from_data = gfc_class_data_get (from);
763 else
764 from_data = gfc_vtable_def_init_get (to);
766 to_data = gfc_class_data_get (to);
768 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (to_data)))
770 gfc_init_block (&body);
771 tmp = fold_build2_loc (input_location, MINUS_EXPR,
772 gfc_array_index_type, nelems,
773 gfc_index_one_node);
774 nelems = gfc_evaluate_now (tmp, &body);
775 index = gfc_create_var (gfc_array_index_type, "S");
777 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (from_data)))
779 from_ref = gfc_get_class_array_ref (index, from);
780 vec_safe_push (args, from_ref);
782 else
783 vec_safe_push (args, from_data);
785 to_ref = gfc_get_class_array_ref (index, to);
786 vec_safe_push (args, to_ref);
788 tmp = build_call_vec (fcn_type, fcn, args);
790 /* Build the body of the loop. */
791 gfc_init_block (&loopbody);
792 gfc_add_expr_to_block (&loopbody, tmp);
794 /* Build the loop and return. */
795 gfc_init_loopinfo (&loop);
796 loop.dimen = 1;
797 loop.from[0] = gfc_index_zero_node;
798 loop.loopvar[0] = index;
799 loop.to[0] = nelems;
800 gfc_trans_scalarizing_loops (&loop, &loopbody);
801 gfc_add_block_to_block (&body, &loop.pre);
802 tmp = gfc_finish_block (&body);
803 gfc_cleanup_loop (&loop);
805 else
807 gcc_assert (!GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (from_data)));
808 vec_safe_push (args, from_data);
809 vec_safe_push (args, to_data);
810 tmp = build_call_vec (fcn_type, fcn, args);
813 return tmp;
816 static tree
817 gfc_trans_class_array_init_assign (gfc_expr *rhs, gfc_expr *lhs, gfc_expr *obj)
819 gfc_actual_arglist *actual;
820 gfc_expr *ppc;
821 gfc_code *ppc_code;
822 tree res;
824 actual = gfc_get_actual_arglist ();
825 actual->expr = gfc_copy_expr (rhs);
826 actual->next = gfc_get_actual_arglist ();
827 actual->next->expr = gfc_copy_expr (lhs);
828 ppc = gfc_copy_expr (obj);
829 gfc_add_vptr_component (ppc);
830 gfc_add_component_ref (ppc, "_copy");
831 ppc_code = gfc_get_code ();
832 ppc_code->resolved_sym = ppc->symtree->n.sym;
833 /* Although '_copy' is set to be elemental in class.c, it is
834 not staying that way. Find out why, sometime.... */
835 ppc_code->resolved_sym->attr.elemental = 1;
836 ppc_code->ext.actual = actual;
837 ppc_code->expr1 = ppc;
838 ppc_code->op = EXEC_CALL;
839 /* Since '_copy' is elemental, the scalarizer will take care
840 of arrays in gfc_trans_call. */
841 res = gfc_trans_call (ppc_code, false, NULL, NULL, false);
842 gfc_free_statements (ppc_code);
843 return res;
846 /* Special case for initializing a polymorphic dummy with INTENT(OUT).
847 A MEMCPY is needed to copy the full data from the default initializer
848 of the dynamic type. */
850 tree
851 gfc_trans_class_init_assign (gfc_code *code)
853 stmtblock_t block;
854 tree tmp;
855 gfc_se dst,src,memsz;
856 gfc_expr *lhs, *rhs, *sz;
858 gfc_start_block (&block);
860 lhs = gfc_copy_expr (code->expr1);
861 gfc_add_data_component (lhs);
863 rhs = gfc_copy_expr (code->expr1);
864 gfc_add_vptr_component (rhs);
866 /* Make sure that the component backend_decls have been built, which
867 will not have happened if the derived types concerned have not
868 been referenced. */
869 gfc_get_derived_type (rhs->ts.u.derived);
870 gfc_add_def_init_component (rhs);
872 if (code->expr1->ts.type == BT_CLASS
873 && CLASS_DATA (code->expr1)->attr.dimension)
874 tmp = gfc_trans_class_array_init_assign (rhs, lhs, code->expr1);
875 else
877 sz = gfc_copy_expr (code->expr1);
878 gfc_add_vptr_component (sz);
879 gfc_add_size_component (sz);
881 gfc_init_se (&dst, NULL);
882 gfc_init_se (&src, NULL);
883 gfc_init_se (&memsz, NULL);
884 gfc_conv_expr (&dst, lhs);
885 gfc_conv_expr (&src, rhs);
886 gfc_conv_expr (&memsz, sz);
887 gfc_add_block_to_block (&block, &src.pre);
888 src.expr = gfc_build_addr_expr (NULL_TREE, src.expr);
890 tmp = gfc_build_memcpy_call (dst.expr, src.expr, memsz.expr);
893 if (code->expr1->symtree->n.sym->attr.optional
894 || code->expr1->symtree->n.sym->ns->proc_name->attr.entry_master)
896 tree present = gfc_conv_expr_present (code->expr1->symtree->n.sym);
897 tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp),
898 present, tmp,
899 build_empty_stmt (input_location));
902 gfc_add_expr_to_block (&block, tmp);
904 return gfc_finish_block (&block);
908 /* Translate an assignment to a CLASS object
909 (pointer or ordinary assignment). */
911 tree
912 gfc_trans_class_assign (gfc_expr *expr1, gfc_expr *expr2, gfc_exec_op op)
914 stmtblock_t block;
915 tree tmp;
916 gfc_expr *lhs;
917 gfc_expr *rhs;
918 gfc_ref *ref;
920 gfc_start_block (&block);
922 ref = expr1->ref;
923 while (ref && ref->next)
924 ref = ref->next;
926 /* Class valued proc_pointer assignments do not need any further
927 preparation. */
928 if (ref && ref->type == REF_COMPONENT
929 && ref->u.c.component->attr.proc_pointer
930 && expr2->expr_type == EXPR_VARIABLE
931 && expr2->symtree->n.sym->attr.flavor == FL_PROCEDURE
932 && op == EXEC_POINTER_ASSIGN)
933 goto assign;
935 if (expr2->ts.type != BT_CLASS)
937 /* Insert an additional assignment which sets the '_vptr' field. */
938 gfc_symbol *vtab = NULL;
939 gfc_symtree *st;
941 lhs = gfc_copy_expr (expr1);
942 gfc_add_vptr_component (lhs);
944 if (UNLIMITED_POLY (expr1)
945 && expr2->expr_type == EXPR_NULL && expr2->ts.type == BT_UNKNOWN)
947 rhs = gfc_get_null_expr (&expr2->where);
948 goto assign_vptr;
951 if (expr2->ts.type == BT_DERIVED)
952 vtab = gfc_find_derived_vtab (expr2->ts.u.derived);
953 else if (expr2->expr_type == EXPR_NULL)
954 vtab = gfc_find_derived_vtab (expr1->ts.u.derived);
955 else
956 vtab = gfc_find_intrinsic_vtab (&expr2->ts);
957 gcc_assert (vtab);
959 rhs = gfc_get_expr ();
960 rhs->expr_type = EXPR_VARIABLE;
961 gfc_find_sym_tree (vtab->name, vtab->ns, 1, &st);
962 rhs->symtree = st;
963 rhs->ts = vtab->ts;
964 assign_vptr:
965 tmp = gfc_trans_pointer_assignment (lhs, rhs);
966 gfc_add_expr_to_block (&block, tmp);
968 gfc_free_expr (lhs);
969 gfc_free_expr (rhs);
971 else if (expr1->ts.type == BT_DERIVED && UNLIMITED_POLY (expr2))
973 /* F2003:C717 only sequence and bind-C types can come here. */
974 gcc_assert (expr1->ts.u.derived->attr.sequence
975 || expr1->ts.u.derived->attr.is_bind_c);
976 gfc_add_data_component (expr2);
977 goto assign;
979 else if (CLASS_DATA (expr2)->attr.dimension)
981 /* Insert an additional assignment which sets the '_vptr' field. */
982 lhs = gfc_copy_expr (expr1);
983 gfc_add_vptr_component (lhs);
985 rhs = gfc_copy_expr (expr2);
986 gfc_add_vptr_component (rhs);
988 tmp = gfc_trans_pointer_assignment (lhs, rhs);
989 gfc_add_expr_to_block (&block, tmp);
991 gfc_free_expr (lhs);
992 gfc_free_expr (rhs);
995 /* Do the actual CLASS assignment. */
996 if (expr2->ts.type == BT_CLASS
997 && !CLASS_DATA (expr2)->attr.dimension)
998 op = EXEC_ASSIGN;
999 else
1000 gfc_add_data_component (expr1);
1002 assign:
1004 if (op == EXEC_ASSIGN)
1005 tmp = gfc_trans_assignment (expr1, expr2, false, true);
1006 else if (op == EXEC_POINTER_ASSIGN)
1007 tmp = gfc_trans_pointer_assignment (expr1, expr2);
1008 else
1009 gcc_unreachable();
1011 gfc_add_expr_to_block (&block, tmp);
1013 return gfc_finish_block (&block);
1017 /* End of prototype trans-class.c */
1020 static void
1021 realloc_lhs_warning (bt type, bool array, locus *where)
1023 if (array && type != BT_CLASS && type != BT_DERIVED
1024 && gfc_option.warn_realloc_lhs)
1025 gfc_warning ("Code for reallocating the allocatable array at %L will "
1026 "be added", where);
1027 else if (gfc_option.warn_realloc_lhs_all)
1028 gfc_warning ("Code for reallocating the allocatable variable at %L "
1029 "will be added", where);
1033 static tree gfc_trans_structure_assign (tree dest, gfc_expr * expr);
1034 static void gfc_apply_interface_mapping_to_expr (gfc_interface_mapping *,
1035 gfc_expr *);
1037 /* Copy the scalarization loop variables. */
1039 static void
1040 gfc_copy_se_loopvars (gfc_se * dest, gfc_se * src)
1042 dest->ss = src->ss;
1043 dest->loop = src->loop;
1047 /* Initialize a simple expression holder.
1049 Care must be taken when multiple se are created with the same parent.
1050 The child se must be kept in sync. The easiest way is to delay creation
1051 of a child se until after after the previous se has been translated. */
1053 void
1054 gfc_init_se (gfc_se * se, gfc_se * parent)
1056 memset (se, 0, sizeof (gfc_se));
1057 gfc_init_block (&se->pre);
1058 gfc_init_block (&se->post);
1060 se->parent = parent;
1062 if (parent)
1063 gfc_copy_se_loopvars (se, parent);
1067 /* Advances to the next SS in the chain. Use this rather than setting
1068 se->ss = se->ss->next because all the parents needs to be kept in sync.
1069 See gfc_init_se. */
1071 void
1072 gfc_advance_se_ss_chain (gfc_se * se)
1074 gfc_se *p;
1075 gfc_ss *ss;
1077 gcc_assert (se != NULL && se->ss != NULL && se->ss != gfc_ss_terminator);
1079 p = se;
1080 /* Walk down the parent chain. */
1081 while (p != NULL)
1083 /* Simple consistency check. */
1084 gcc_assert (p->parent == NULL || p->parent->ss == p->ss
1085 || p->parent->ss->nested_ss == p->ss);
1087 /* If we were in a nested loop, the next scalarized expression can be
1088 on the parent ss' next pointer. Thus we should not take the next
1089 pointer blindly, but rather go up one nest level as long as next
1090 is the end of chain. */
1091 ss = p->ss;
1092 while (ss->next == gfc_ss_terminator && ss->parent != NULL)
1093 ss = ss->parent;
1095 p->ss = ss->next;
1097 p = p->parent;
1102 /* Ensures the result of the expression as either a temporary variable
1103 or a constant so that it can be used repeatedly. */
1105 void
1106 gfc_make_safe_expr (gfc_se * se)
1108 tree var;
1110 if (CONSTANT_CLASS_P (se->expr))
1111 return;
1113 /* We need a temporary for this result. */
1114 var = gfc_create_var (TREE_TYPE (se->expr), NULL);
1115 gfc_add_modify (&se->pre, var, se->expr);
1116 se->expr = var;
1120 /* Return an expression which determines if a dummy parameter is present.
1121 Also used for arguments to procedures with multiple entry points. */
1123 tree
1124 gfc_conv_expr_present (gfc_symbol * sym)
1126 tree decl, cond;
1128 gcc_assert (sym->attr.dummy);
1130 decl = gfc_get_symbol_decl (sym);
1131 if (TREE_CODE (decl) != PARM_DECL)
1133 /* Array parameters use a temporary descriptor, we want the real
1134 parameter. */
1135 gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl))
1136 || GFC_ARRAY_TYPE_P (TREE_TYPE (decl)));
1137 decl = GFC_DECL_SAVED_DESCRIPTOR (decl);
1140 cond = fold_build2_loc (input_location, NE_EXPR, boolean_type_node, decl,
1141 fold_convert (TREE_TYPE (decl), null_pointer_node));
1143 /* Fortran 2008 allows to pass null pointers and non-associated pointers
1144 as actual argument to denote absent dummies. For array descriptors,
1145 we thus also need to check the array descriptor. For BT_CLASS, it
1146 can also occur for scalars and F2003 due to type->class wrapping and
1147 class->class wrapping. Note futher that BT_CLASS always uses an
1148 array descriptor for arrays, also for explicit-shape/assumed-size. */
1150 if (!sym->attr.allocatable
1151 && ((sym->ts.type != BT_CLASS && !sym->attr.pointer)
1152 || (sym->ts.type == BT_CLASS
1153 && !CLASS_DATA (sym)->attr.allocatable
1154 && !CLASS_DATA (sym)->attr.class_pointer))
1155 && ((gfc_option.allow_std & GFC_STD_F2008) != 0
1156 || sym->ts.type == BT_CLASS))
1158 tree tmp;
1160 if ((sym->as && (sym->as->type == AS_ASSUMED_SHAPE
1161 || sym->as->type == AS_ASSUMED_RANK
1162 || sym->attr.codimension))
1163 || (sym->ts.type == BT_CLASS && CLASS_DATA (sym)->as))
1165 tmp = build_fold_indirect_ref_loc (input_location, decl);
1166 if (sym->ts.type == BT_CLASS)
1167 tmp = gfc_class_data_get (tmp);
1168 tmp = gfc_conv_array_data (tmp);
1170 else if (sym->ts.type == BT_CLASS)
1171 tmp = gfc_class_data_get (decl);
1172 else
1173 tmp = NULL_TREE;
1175 if (tmp != NULL_TREE)
1177 tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node, tmp,
1178 fold_convert (TREE_TYPE (tmp), null_pointer_node));
1179 cond = fold_build2_loc (input_location, TRUTH_ANDIF_EXPR,
1180 boolean_type_node, cond, tmp);
1184 return cond;
1188 /* Converts a missing, dummy argument into a null or zero. */
1190 void
1191 gfc_conv_missing_dummy (gfc_se * se, gfc_expr * arg, gfc_typespec ts, int kind)
1193 tree present;
1194 tree tmp;
1196 present = gfc_conv_expr_present (arg->symtree->n.sym);
1198 if (kind > 0)
1200 /* Create a temporary and convert it to the correct type. */
1201 tmp = gfc_get_int_type (kind);
1202 tmp = fold_convert (tmp, build_fold_indirect_ref_loc (input_location,
1203 se->expr));
1205 /* Test for a NULL value. */
1206 tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp), present,
1207 tmp, fold_convert (TREE_TYPE (tmp), integer_one_node));
1208 tmp = gfc_evaluate_now (tmp, &se->pre);
1209 se->expr = gfc_build_addr_expr (NULL_TREE, tmp);
1211 else
1213 tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (se->expr),
1214 present, se->expr,
1215 build_zero_cst (TREE_TYPE (se->expr)));
1216 tmp = gfc_evaluate_now (tmp, &se->pre);
1217 se->expr = tmp;
1220 if (ts.type == BT_CHARACTER)
1222 tmp = build_int_cst (gfc_charlen_type_node, 0);
1223 tmp = fold_build3_loc (input_location, COND_EXPR, gfc_charlen_type_node,
1224 present, se->string_length, tmp);
1225 tmp = gfc_evaluate_now (tmp, &se->pre);
1226 se->string_length = tmp;
1228 return;
1232 /* Get the character length of an expression, looking through gfc_refs
1233 if necessary. */
1235 tree
1236 gfc_get_expr_charlen (gfc_expr *e)
1238 gfc_ref *r;
1239 tree length;
1241 gcc_assert (e->expr_type == EXPR_VARIABLE
1242 && e->ts.type == BT_CHARACTER);
1244 length = NULL; /* To silence compiler warning. */
1246 if (is_subref_array (e) && e->ts.u.cl->length)
1248 gfc_se tmpse;
1249 gfc_init_se (&tmpse, NULL);
1250 gfc_conv_expr_type (&tmpse, e->ts.u.cl->length, gfc_charlen_type_node);
1251 e->ts.u.cl->backend_decl = tmpse.expr;
1252 return tmpse.expr;
1255 /* First candidate: if the variable is of type CHARACTER, the
1256 expression's length could be the length of the character
1257 variable. */
1258 if (e->symtree->n.sym->ts.type == BT_CHARACTER)
1259 length = e->symtree->n.sym->ts.u.cl->backend_decl;
1261 /* Look through the reference chain for component references. */
1262 for (r = e->ref; r; r = r->next)
1264 switch (r->type)
1266 case REF_COMPONENT:
1267 if (r->u.c.component->ts.type == BT_CHARACTER)
1268 length = r->u.c.component->ts.u.cl->backend_decl;
1269 break;
1271 case REF_ARRAY:
1272 /* Do nothing. */
1273 break;
1275 default:
1276 /* We should never got substring references here. These will be
1277 broken down by the scalarizer. */
1278 gcc_unreachable ();
1279 break;
1283 gcc_assert (length != NULL);
1284 return length;
1288 /* Return for an expression the backend decl of the coarray. */
1290 static tree
1291 get_tree_for_caf_expr (gfc_expr *expr)
1293 tree caf_decl = NULL_TREE;
1294 gfc_ref *ref;
1296 gcc_assert (expr && expr->expr_type == EXPR_VARIABLE);
1297 if (expr->symtree->n.sym->attr.codimension)
1298 caf_decl = expr->symtree->n.sym->backend_decl;
1300 for (ref = expr->ref; ref; ref = ref->next)
1301 if (ref->type == REF_COMPONENT)
1303 gfc_component *comp = ref->u.c.component;
1304 if (comp->attr.pointer || comp->attr.allocatable)
1305 caf_decl = NULL_TREE;
1306 if (comp->attr.codimension)
1307 caf_decl = comp->backend_decl;
1310 gcc_assert (caf_decl != NULL_TREE);
1311 return caf_decl;
1315 /* For each character array constructor subexpression without a ts.u.cl->length,
1316 replace it by its first element (if there aren't any elements, the length
1317 should already be set to zero). */
1319 static void
1320 flatten_array_ctors_without_strlen (gfc_expr* e)
1322 gfc_actual_arglist* arg;
1323 gfc_constructor* c;
1325 if (!e)
1326 return;
1328 switch (e->expr_type)
1331 case EXPR_OP:
1332 flatten_array_ctors_without_strlen (e->value.op.op1);
1333 flatten_array_ctors_without_strlen (e->value.op.op2);
1334 break;
1336 case EXPR_COMPCALL:
1337 /* TODO: Implement as with EXPR_FUNCTION when needed. */
1338 gcc_unreachable ();
1340 case EXPR_FUNCTION:
1341 for (arg = e->value.function.actual; arg; arg = arg->next)
1342 flatten_array_ctors_without_strlen (arg->expr);
1343 break;
1345 case EXPR_ARRAY:
1347 /* We've found what we're looking for. */
1348 if (e->ts.type == BT_CHARACTER && !e->ts.u.cl->length)
1350 gfc_constructor *c;
1351 gfc_expr* new_expr;
1353 gcc_assert (e->value.constructor);
1355 c = gfc_constructor_first (e->value.constructor);
1356 new_expr = c->expr;
1357 c->expr = NULL;
1359 flatten_array_ctors_without_strlen (new_expr);
1360 gfc_replace_expr (e, new_expr);
1361 break;
1364 /* Otherwise, fall through to handle constructor elements. */
1365 case EXPR_STRUCTURE:
1366 for (c = gfc_constructor_first (e->value.constructor);
1367 c; c = gfc_constructor_next (c))
1368 flatten_array_ctors_without_strlen (c->expr);
1369 break;
1371 default:
1372 break;
1378 /* Generate code to initialize a string length variable. Returns the
1379 value. For array constructors, cl->length might be NULL and in this case,
1380 the first element of the constructor is needed. expr is the original
1381 expression so we can access it but can be NULL if this is not needed. */
1383 void
1384 gfc_conv_string_length (gfc_charlen * cl, gfc_expr * expr, stmtblock_t * pblock)
1386 gfc_se se;
1388 gfc_init_se (&se, NULL);
1390 if (!cl->length
1391 && cl->backend_decl
1392 && TREE_CODE (cl->backend_decl) == VAR_DECL)
1393 return;
1395 /* If cl->length is NULL, use gfc_conv_expr to obtain the string length but
1396 "flatten" array constructors by taking their first element; all elements
1397 should be the same length or a cl->length should be present. */
1398 if (!cl->length)
1400 gfc_expr* expr_flat;
1401 gcc_assert (expr);
1402 expr_flat = gfc_copy_expr (expr);
1403 flatten_array_ctors_without_strlen (expr_flat);
1404 gfc_resolve_expr (expr_flat);
1406 gfc_conv_expr (&se, expr_flat);
1407 gfc_add_block_to_block (pblock, &se.pre);
1408 cl->backend_decl = convert (gfc_charlen_type_node, se.string_length);
1410 gfc_free_expr (expr_flat);
1411 return;
1414 /* Convert cl->length. */
1416 gcc_assert (cl->length);
1418 gfc_conv_expr_type (&se, cl->length, gfc_charlen_type_node);
1419 se.expr = fold_build2_loc (input_location, MAX_EXPR, gfc_charlen_type_node,
1420 se.expr, build_int_cst (gfc_charlen_type_node, 0));
1421 gfc_add_block_to_block (pblock, &se.pre);
1423 if (cl->backend_decl)
1424 gfc_add_modify (pblock, cl->backend_decl, se.expr);
1425 else
1426 cl->backend_decl = gfc_evaluate_now (se.expr, pblock);
1430 static void
1431 gfc_conv_substring (gfc_se * se, gfc_ref * ref, int kind,
1432 const char *name, locus *where)
1434 tree tmp;
1435 tree type;
1436 tree fault;
1437 gfc_se start;
1438 gfc_se end;
1439 char *msg;
1441 type = gfc_get_character_type (kind, ref->u.ss.length);
1442 type = build_pointer_type (type);
1444 gfc_init_se (&start, se);
1445 gfc_conv_expr_type (&start, ref->u.ss.start, gfc_charlen_type_node);
1446 gfc_add_block_to_block (&se->pre, &start.pre);
1448 if (integer_onep (start.expr))
1449 gfc_conv_string_parameter (se);
1450 else
1452 tmp = start.expr;
1453 STRIP_NOPS (tmp);
1454 /* Avoid multiple evaluation of substring start. */
1455 if (!CONSTANT_CLASS_P (tmp) && !DECL_P (tmp))
1456 start.expr = gfc_evaluate_now (start.expr, &se->pre);
1458 /* Change the start of the string. */
1459 if (TYPE_STRING_FLAG (TREE_TYPE (se->expr)))
1460 tmp = se->expr;
1461 else
1462 tmp = build_fold_indirect_ref_loc (input_location,
1463 se->expr);
1464 tmp = gfc_build_array_ref (tmp, start.expr, NULL);
1465 se->expr = gfc_build_addr_expr (type, tmp);
1468 /* Length = end + 1 - start. */
1469 gfc_init_se (&end, se);
1470 if (ref->u.ss.end == NULL)
1471 end.expr = se->string_length;
1472 else
1474 gfc_conv_expr_type (&end, ref->u.ss.end, gfc_charlen_type_node);
1475 gfc_add_block_to_block (&se->pre, &end.pre);
1477 tmp = end.expr;
1478 STRIP_NOPS (tmp);
1479 if (!CONSTANT_CLASS_P (tmp) && !DECL_P (tmp))
1480 end.expr = gfc_evaluate_now (end.expr, &se->pre);
1482 if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
1484 tree nonempty = fold_build2_loc (input_location, LE_EXPR,
1485 boolean_type_node, start.expr,
1486 end.expr);
1488 /* Check lower bound. */
1489 fault = fold_build2_loc (input_location, LT_EXPR, boolean_type_node,
1490 start.expr,
1491 build_int_cst (gfc_charlen_type_node, 1));
1492 fault = fold_build2_loc (input_location, TRUTH_ANDIF_EXPR,
1493 boolean_type_node, nonempty, fault);
1494 if (name)
1495 asprintf (&msg, "Substring out of bounds: lower bound (%%ld) of '%s' "
1496 "is less than one", name);
1497 else
1498 asprintf (&msg, "Substring out of bounds: lower bound (%%ld)"
1499 "is less than one");
1500 gfc_trans_runtime_check (true, false, fault, &se->pre, where, msg,
1501 fold_convert (long_integer_type_node,
1502 start.expr));
1503 free (msg);
1505 /* Check upper bound. */
1506 fault = fold_build2_loc (input_location, GT_EXPR, boolean_type_node,
1507 end.expr, se->string_length);
1508 fault = fold_build2_loc (input_location, TRUTH_ANDIF_EXPR,
1509 boolean_type_node, nonempty, fault);
1510 if (name)
1511 asprintf (&msg, "Substring out of bounds: upper bound (%%ld) of '%s' "
1512 "exceeds string length (%%ld)", name);
1513 else
1514 asprintf (&msg, "Substring out of bounds: upper bound (%%ld) "
1515 "exceeds string length (%%ld)");
1516 gfc_trans_runtime_check (true, false, fault, &se->pre, where, msg,
1517 fold_convert (long_integer_type_node, end.expr),
1518 fold_convert (long_integer_type_node,
1519 se->string_length));
1520 free (msg);
1523 /* If the start and end expressions are equal, the length is one. */
1524 if (ref->u.ss.end
1525 && gfc_dep_compare_expr (ref->u.ss.start, ref->u.ss.end) == 0)
1526 tmp = build_int_cst (gfc_charlen_type_node, 1);
1527 else
1529 tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_charlen_type_node,
1530 end.expr, start.expr);
1531 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_charlen_type_node,
1532 build_int_cst (gfc_charlen_type_node, 1), tmp);
1533 tmp = fold_build2_loc (input_location, MAX_EXPR, gfc_charlen_type_node,
1534 tmp, build_int_cst (gfc_charlen_type_node, 0));
1537 se->string_length = tmp;
1541 /* Convert a derived type component reference. */
1543 static void
1544 gfc_conv_component_ref (gfc_se * se, gfc_ref * ref)
1546 gfc_component *c;
1547 tree tmp;
1548 tree decl;
1549 tree field;
1551 c = ref->u.c.component;
1553 gcc_assert (c->backend_decl);
1555 field = c->backend_decl;
1556 gcc_assert (TREE_CODE (field) == FIELD_DECL);
1557 decl = se->expr;
1559 /* Components can correspond to fields of different containing
1560 types, as components are created without context, whereas
1561 a concrete use of a component has the type of decl as context.
1562 So, if the type doesn't match, we search the corresponding
1563 FIELD_DECL in the parent type. To not waste too much time
1564 we cache this result in norestrict_decl. */
1566 if (DECL_FIELD_CONTEXT (field) != TREE_TYPE (decl))
1568 tree f2 = c->norestrict_decl;
1569 if (!f2 || DECL_FIELD_CONTEXT (f2) != TREE_TYPE (decl))
1570 for (f2 = TYPE_FIELDS (TREE_TYPE (decl)); f2; f2 = DECL_CHAIN (f2))
1571 if (TREE_CODE (f2) == FIELD_DECL
1572 && DECL_NAME (f2) == DECL_NAME (field))
1573 break;
1574 gcc_assert (f2);
1575 c->norestrict_decl = f2;
1576 field = f2;
1579 tmp = fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field),
1580 decl, field, NULL_TREE);
1582 se->expr = tmp;
1584 if (c->ts.type == BT_CHARACTER && !c->attr.proc_pointer)
1586 tmp = c->ts.u.cl->backend_decl;
1587 /* Components must always be constant length. */
1588 gcc_assert (tmp && INTEGER_CST_P (tmp));
1589 se->string_length = tmp;
1592 if (((c->attr.pointer || c->attr.allocatable)
1593 && (!c->attr.dimension && !c->attr.codimension)
1594 && c->ts.type != BT_CHARACTER)
1595 || c->attr.proc_pointer)
1596 se->expr = build_fold_indirect_ref_loc (input_location,
1597 se->expr);
1601 /* This function deals with component references to components of the
1602 parent type for derived type extensions. */
1603 static void
1604 conv_parent_component_references (gfc_se * se, gfc_ref * ref)
1606 gfc_component *c;
1607 gfc_component *cmp;
1608 gfc_symbol *dt;
1609 gfc_ref parent;
1611 dt = ref->u.c.sym;
1612 c = ref->u.c.component;
1614 /* Return if the component is in the parent type. */
1615 for (cmp = dt->components; cmp; cmp = cmp->next)
1616 if (strcmp (c->name, cmp->name) == 0)
1617 return;
1619 /* Build a gfc_ref to recursively call gfc_conv_component_ref. */
1620 parent.type = REF_COMPONENT;
1621 parent.next = NULL;
1622 parent.u.c.sym = dt;
1623 parent.u.c.component = dt->components;
1625 if (dt->backend_decl == NULL)
1626 gfc_get_derived_type (dt);
1628 /* Build the reference and call self. */
1629 gfc_conv_component_ref (se, &parent);
1630 parent.u.c.sym = dt->components->ts.u.derived;
1631 parent.u.c.component = c;
1632 conv_parent_component_references (se, &parent);
1635 /* Return the contents of a variable. Also handles reference/pointer
1636 variables (all Fortran pointer references are implicit). */
1638 static void
1639 gfc_conv_variable (gfc_se * se, gfc_expr * expr)
1641 gfc_ss *ss;
1642 gfc_ref *ref;
1643 gfc_symbol *sym;
1644 tree parent_decl = NULL_TREE;
1645 int parent_flag;
1646 bool return_value;
1647 bool alternate_entry;
1648 bool entry_master;
1650 sym = expr->symtree->n.sym;
1651 ss = se->ss;
1652 if (ss != NULL)
1654 gfc_ss_info *ss_info = ss->info;
1656 /* Check that something hasn't gone horribly wrong. */
1657 gcc_assert (ss != gfc_ss_terminator);
1658 gcc_assert (ss_info->expr == expr);
1660 /* A scalarized term. We already know the descriptor. */
1661 se->expr = ss_info->data.array.descriptor;
1662 se->string_length = ss_info->string_length;
1663 for (ref = ss_info->data.array.ref; ref; ref = ref->next)
1664 if (ref->type == REF_ARRAY && ref->u.ar.type != AR_ELEMENT)
1665 break;
1667 else
1669 tree se_expr = NULL_TREE;
1671 se->expr = gfc_get_symbol_decl (sym);
1673 /* Deal with references to a parent results or entries by storing
1674 the current_function_decl and moving to the parent_decl. */
1675 return_value = sym->attr.function && sym->result == sym;
1676 alternate_entry = sym->attr.function && sym->attr.entry
1677 && sym->result == sym;
1678 entry_master = sym->attr.result
1679 && sym->ns->proc_name->attr.entry_master
1680 && !gfc_return_by_reference (sym->ns->proc_name);
1681 if (current_function_decl)
1682 parent_decl = DECL_CONTEXT (current_function_decl);
1684 if ((se->expr == parent_decl && return_value)
1685 || (sym->ns && sym->ns->proc_name
1686 && parent_decl
1687 && sym->ns->proc_name->backend_decl == parent_decl
1688 && (alternate_entry || entry_master)))
1689 parent_flag = 1;
1690 else
1691 parent_flag = 0;
1693 /* Special case for assigning the return value of a function.
1694 Self recursive functions must have an explicit return value. */
1695 if (return_value && (se->expr == current_function_decl || parent_flag))
1696 se_expr = gfc_get_fake_result_decl (sym, parent_flag);
1698 /* Similarly for alternate entry points. */
1699 else if (alternate_entry
1700 && (sym->ns->proc_name->backend_decl == current_function_decl
1701 || parent_flag))
1703 gfc_entry_list *el = NULL;
1705 for (el = sym->ns->entries; el; el = el->next)
1706 if (sym == el->sym)
1708 se_expr = gfc_get_fake_result_decl (sym, parent_flag);
1709 break;
1713 else if (entry_master
1714 && (sym->ns->proc_name->backend_decl == current_function_decl
1715 || parent_flag))
1716 se_expr = gfc_get_fake_result_decl (sym, parent_flag);
1718 if (se_expr)
1719 se->expr = se_expr;
1721 /* Procedure actual arguments. */
1722 else if (sym->attr.flavor == FL_PROCEDURE
1723 && se->expr != current_function_decl)
1725 if (!sym->attr.dummy && !sym->attr.proc_pointer)
1727 gcc_assert (TREE_CODE (se->expr) == FUNCTION_DECL);
1728 se->expr = gfc_build_addr_expr (NULL_TREE, se->expr);
1730 return;
1734 /* Dereference the expression, where needed. Since characters
1735 are entirely different from other types, they are treated
1736 separately. */
1737 if (sym->ts.type == BT_CHARACTER)
1739 /* Dereference character pointer dummy arguments
1740 or results. */
1741 if ((sym->attr.pointer || sym->attr.allocatable)
1742 && (sym->attr.dummy
1743 || sym->attr.function
1744 || sym->attr.result))
1745 se->expr = build_fold_indirect_ref_loc (input_location,
1746 se->expr);
1749 else if (!sym->attr.value)
1751 /* Dereference non-character scalar dummy arguments. */
1752 if (sym->attr.dummy && !sym->attr.dimension
1753 && !(sym->attr.codimension && sym->attr.allocatable))
1754 se->expr = build_fold_indirect_ref_loc (input_location,
1755 se->expr);
1757 /* Dereference scalar hidden result. */
1758 if (gfc_option.flag_f2c && sym->ts.type == BT_COMPLEX
1759 && (sym->attr.function || sym->attr.result)
1760 && !sym->attr.dimension && !sym->attr.pointer
1761 && !sym->attr.always_explicit)
1762 se->expr = build_fold_indirect_ref_loc (input_location,
1763 se->expr);
1765 /* Dereference non-character pointer variables.
1766 These must be dummies, results, or scalars. */
1767 if ((sym->attr.pointer || sym->attr.allocatable
1768 || gfc_is_associate_pointer (sym)
1769 || (sym->as && sym->as->type == AS_ASSUMED_RANK))
1770 && (sym->attr.dummy
1771 || sym->attr.function
1772 || sym->attr.result
1773 || (!sym->attr.dimension
1774 && (!sym->attr.codimension || !sym->attr.allocatable))))
1775 se->expr = build_fold_indirect_ref_loc (input_location,
1776 se->expr);
1779 ref = expr->ref;
1782 /* For character variables, also get the length. */
1783 if (sym->ts.type == BT_CHARACTER)
1785 /* If the character length of an entry isn't set, get the length from
1786 the master function instead. */
1787 if (sym->attr.entry && !sym->ts.u.cl->backend_decl)
1788 se->string_length = sym->ns->proc_name->ts.u.cl->backend_decl;
1789 else
1790 se->string_length = sym->ts.u.cl->backend_decl;
1791 gcc_assert (se->string_length);
1794 while (ref)
1796 switch (ref->type)
1798 case REF_ARRAY:
1799 /* Return the descriptor if that's what we want and this is an array
1800 section reference. */
1801 if (se->descriptor_only && ref->u.ar.type != AR_ELEMENT)
1802 return;
1803 /* TODO: Pointers to single elements of array sections, eg elemental subs. */
1804 /* Return the descriptor for array pointers and allocations. */
1805 if (se->want_pointer
1806 && ref->next == NULL && (se->descriptor_only))
1807 return;
1809 gfc_conv_array_ref (se, &ref->u.ar, sym, &expr->where);
1810 /* Return a pointer to an element. */
1811 break;
1813 case REF_COMPONENT:
1814 if (ref->u.c.sym->attr.extension)
1815 conv_parent_component_references (se, ref);
1817 gfc_conv_component_ref (se, ref);
1818 if (!ref->next && ref->u.c.sym->attr.codimension
1819 && se->want_pointer && se->descriptor_only)
1820 return;
1822 break;
1824 case REF_SUBSTRING:
1825 gfc_conv_substring (se, ref, expr->ts.kind,
1826 expr->symtree->name, &expr->where);
1827 break;
1829 default:
1830 gcc_unreachable ();
1831 break;
1833 ref = ref->next;
1835 /* Pointer assignment, allocation or pass by reference. Arrays are handled
1836 separately. */
1837 if (se->want_pointer)
1839 if (expr->ts.type == BT_CHARACTER && !gfc_is_proc_ptr_comp (expr))
1840 gfc_conv_string_parameter (se);
1841 else
1842 se->expr = gfc_build_addr_expr (NULL_TREE, se->expr);
1847 /* Unary ops are easy... Or they would be if ! was a valid op. */
1849 static void
1850 gfc_conv_unary_op (enum tree_code code, gfc_se * se, gfc_expr * expr)
1852 gfc_se operand;
1853 tree type;
1855 gcc_assert (expr->ts.type != BT_CHARACTER);
1856 /* Initialize the operand. */
1857 gfc_init_se (&operand, se);
1858 gfc_conv_expr_val (&operand, expr->value.op.op1);
1859 gfc_add_block_to_block (&se->pre, &operand.pre);
1861 type = gfc_typenode_for_spec (&expr->ts);
1863 /* TRUTH_NOT_EXPR is not a "true" unary operator in GCC.
1864 We must convert it to a compare to 0 (e.g. EQ_EXPR (op1, 0)).
1865 All other unary operators have an equivalent GIMPLE unary operator. */
1866 if (code == TRUTH_NOT_EXPR)
1867 se->expr = fold_build2_loc (input_location, EQ_EXPR, type, operand.expr,
1868 build_int_cst (type, 0));
1869 else
1870 se->expr = fold_build1_loc (input_location, code, type, operand.expr);
1874 /* Expand power operator to optimal multiplications when a value is raised
1875 to a constant integer n. See section 4.6.3, "Evaluation of Powers" of
1876 Donald E. Knuth, "Seminumerical Algorithms", Vol. 2, "The Art of Computer
1877 Programming", 3rd Edition, 1998. */
1879 /* This code is mostly duplicated from expand_powi in the backend.
1880 We establish the "optimal power tree" lookup table with the defined size.
1881 The items in the table are the exponents used to calculate the index
1882 exponents. Any integer n less than the value can get an "addition chain",
1883 with the first node being one. */
1884 #define POWI_TABLE_SIZE 256
1886 /* The table is from builtins.c. */
1887 static const unsigned char powi_table[POWI_TABLE_SIZE] =
1889 0, 1, 1, 2, 2, 3, 3, 4, /* 0 - 7 */
1890 4, 6, 5, 6, 6, 10, 7, 9, /* 8 - 15 */
1891 8, 16, 9, 16, 10, 12, 11, 13, /* 16 - 23 */
1892 12, 17, 13, 18, 14, 24, 15, 26, /* 24 - 31 */
1893 16, 17, 17, 19, 18, 33, 19, 26, /* 32 - 39 */
1894 20, 25, 21, 40, 22, 27, 23, 44, /* 40 - 47 */
1895 24, 32, 25, 34, 26, 29, 27, 44, /* 48 - 55 */
1896 28, 31, 29, 34, 30, 60, 31, 36, /* 56 - 63 */
1897 32, 64, 33, 34, 34, 46, 35, 37, /* 64 - 71 */
1898 36, 65, 37, 50, 38, 48, 39, 69, /* 72 - 79 */
1899 40, 49, 41, 43, 42, 51, 43, 58, /* 80 - 87 */
1900 44, 64, 45, 47, 46, 59, 47, 76, /* 88 - 95 */
1901 48, 65, 49, 66, 50, 67, 51, 66, /* 96 - 103 */
1902 52, 70, 53, 74, 54, 104, 55, 74, /* 104 - 111 */
1903 56, 64, 57, 69, 58, 78, 59, 68, /* 112 - 119 */
1904 60, 61, 61, 80, 62, 75, 63, 68, /* 120 - 127 */
1905 64, 65, 65, 128, 66, 129, 67, 90, /* 128 - 135 */
1906 68, 73, 69, 131, 70, 94, 71, 88, /* 136 - 143 */
1907 72, 128, 73, 98, 74, 132, 75, 121, /* 144 - 151 */
1908 76, 102, 77, 124, 78, 132, 79, 106, /* 152 - 159 */
1909 80, 97, 81, 160, 82, 99, 83, 134, /* 160 - 167 */
1910 84, 86, 85, 95, 86, 160, 87, 100, /* 168 - 175 */
1911 88, 113, 89, 98, 90, 107, 91, 122, /* 176 - 183 */
1912 92, 111, 93, 102, 94, 126, 95, 150, /* 184 - 191 */
1913 96, 128, 97, 130, 98, 133, 99, 195, /* 192 - 199 */
1914 100, 128, 101, 123, 102, 164, 103, 138, /* 200 - 207 */
1915 104, 145, 105, 146, 106, 109, 107, 149, /* 208 - 215 */
1916 108, 200, 109, 146, 110, 170, 111, 157, /* 216 - 223 */
1917 112, 128, 113, 130, 114, 182, 115, 132, /* 224 - 231 */
1918 116, 200, 117, 132, 118, 158, 119, 206, /* 232 - 239 */
1919 120, 240, 121, 162, 122, 147, 123, 152, /* 240 - 247 */
1920 124, 166, 125, 214, 126, 138, 127, 153, /* 248 - 255 */
1923 /* If n is larger than lookup table's max index, we use the "window
1924 method". */
1925 #define POWI_WINDOW_SIZE 3
1927 /* Recursive function to expand the power operator. The temporary
1928 values are put in tmpvar. The function returns tmpvar[1] ** n. */
1929 static tree
1930 gfc_conv_powi (gfc_se * se, unsigned HOST_WIDE_INT n, tree * tmpvar)
1932 tree op0;
1933 tree op1;
1934 tree tmp;
1935 int digit;
1937 if (n < POWI_TABLE_SIZE)
1939 if (tmpvar[n])
1940 return tmpvar[n];
1942 op0 = gfc_conv_powi (se, n - powi_table[n], tmpvar);
1943 op1 = gfc_conv_powi (se, powi_table[n], tmpvar);
1945 else if (n & 1)
1947 digit = n & ((1 << POWI_WINDOW_SIZE) - 1);
1948 op0 = gfc_conv_powi (se, n - digit, tmpvar);
1949 op1 = gfc_conv_powi (se, digit, tmpvar);
1951 else
1953 op0 = gfc_conv_powi (se, n >> 1, tmpvar);
1954 op1 = op0;
1957 tmp = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (op0), op0, op1);
1958 tmp = gfc_evaluate_now (tmp, &se->pre);
1960 if (n < POWI_TABLE_SIZE)
1961 tmpvar[n] = tmp;
1963 return tmp;
1967 /* Expand lhs ** rhs. rhs is a constant integer. If it expands successfully,
1968 return 1. Else return 0 and a call to runtime library functions
1969 will have to be built. */
1970 static int
1971 gfc_conv_cst_int_power (gfc_se * se, tree lhs, tree rhs)
1973 tree cond;
1974 tree tmp;
1975 tree type;
1976 tree vartmp[POWI_TABLE_SIZE];
1977 HOST_WIDE_INT m;
1978 unsigned HOST_WIDE_INT n;
1979 int sgn;
1981 /* If exponent is too large, we won't expand it anyway, so don't bother
1982 with large integer values. */
1983 if (!TREE_INT_CST (rhs).fits_shwi ())
1984 return 0;
1986 m = TREE_INT_CST (rhs).to_shwi ();
1987 /* There's no ABS for HOST_WIDE_INT, so here we go. It also takes care
1988 of the asymmetric range of the integer type. */
1989 n = (unsigned HOST_WIDE_INT) (m < 0 ? -m : m);
1991 type = TREE_TYPE (lhs);
1992 sgn = tree_int_cst_sgn (rhs);
1994 if (((FLOAT_TYPE_P (type) && !flag_unsafe_math_optimizations)
1995 || optimize_size) && (m > 2 || m < -1))
1996 return 0;
1998 /* rhs == 0 */
1999 if (sgn == 0)
2001 se->expr = gfc_build_const (type, integer_one_node);
2002 return 1;
2005 /* If rhs < 0 and lhs is an integer, the result is -1, 0 or 1. */
2006 if ((sgn == -1) && (TREE_CODE (type) == INTEGER_TYPE))
2008 tmp = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
2009 lhs, build_int_cst (TREE_TYPE (lhs), -1));
2010 cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
2011 lhs, build_int_cst (TREE_TYPE (lhs), 1));
2013 /* If rhs is even,
2014 result = (lhs == 1 || lhs == -1) ? 1 : 0. */
2015 if ((n & 1) == 0)
2017 tmp = fold_build2_loc (input_location, TRUTH_OR_EXPR,
2018 boolean_type_node, tmp, cond);
2019 se->expr = fold_build3_loc (input_location, COND_EXPR, type,
2020 tmp, build_int_cst (type, 1),
2021 build_int_cst (type, 0));
2022 return 1;
2024 /* If rhs is odd,
2025 result = (lhs == 1) ? 1 : (lhs == -1) ? -1 : 0. */
2026 tmp = fold_build3_loc (input_location, COND_EXPR, type, tmp,
2027 build_int_cst (type, -1),
2028 build_int_cst (type, 0));
2029 se->expr = fold_build3_loc (input_location, COND_EXPR, type,
2030 cond, build_int_cst (type, 1), tmp);
2031 return 1;
2034 memset (vartmp, 0, sizeof (vartmp));
2035 vartmp[1] = lhs;
2036 if (sgn == -1)
2038 tmp = gfc_build_const (type, integer_one_node);
2039 vartmp[1] = fold_build2_loc (input_location, RDIV_EXPR, type, tmp,
2040 vartmp[1]);
2043 se->expr = gfc_conv_powi (se, n, vartmp);
2045 return 1;
2049 /* Power op (**). Constant integer exponent has special handling. */
2051 static void
2052 gfc_conv_power_op (gfc_se * se, gfc_expr * expr)
2054 tree gfc_int4_type_node;
2055 int kind;
2056 int ikind;
2057 int res_ikind_1, res_ikind_2;
2058 gfc_se lse;
2059 gfc_se rse;
2060 tree fndecl = NULL;
2062 gfc_init_se (&lse, se);
2063 gfc_conv_expr_val (&lse, expr->value.op.op1);
2064 lse.expr = gfc_evaluate_now (lse.expr, &lse.pre);
2065 gfc_add_block_to_block (&se->pre, &lse.pre);
2067 gfc_init_se (&rse, se);
2068 gfc_conv_expr_val (&rse, expr->value.op.op2);
2069 gfc_add_block_to_block (&se->pre, &rse.pre);
2071 if (expr->value.op.op2->ts.type == BT_INTEGER
2072 && expr->value.op.op2->expr_type == EXPR_CONSTANT)
2073 if (gfc_conv_cst_int_power (se, lse.expr, rse.expr))
2074 return;
2076 gfc_int4_type_node = gfc_get_int_type (4);
2078 /* In case of integer operands with kinds 1 or 2, we call the integer kind 4
2079 library routine. But in the end, we have to convert the result back
2080 if this case applies -- with res_ikind_K, we keep track whether operand K
2081 falls into this case. */
2082 res_ikind_1 = -1;
2083 res_ikind_2 = -1;
2085 kind = expr->value.op.op1->ts.kind;
2086 switch (expr->value.op.op2->ts.type)
2088 case BT_INTEGER:
2089 ikind = expr->value.op.op2->ts.kind;
2090 switch (ikind)
2092 case 1:
2093 case 2:
2094 rse.expr = convert (gfc_int4_type_node, rse.expr);
2095 res_ikind_2 = ikind;
2096 /* Fall through. */
2098 case 4:
2099 ikind = 0;
2100 break;
2102 case 8:
2103 ikind = 1;
2104 break;
2106 case 16:
2107 ikind = 2;
2108 break;
2110 default:
2111 gcc_unreachable ();
2113 switch (kind)
2115 case 1:
2116 case 2:
2117 if (expr->value.op.op1->ts.type == BT_INTEGER)
2119 lse.expr = convert (gfc_int4_type_node, lse.expr);
2120 res_ikind_1 = kind;
2122 else
2123 gcc_unreachable ();
2124 /* Fall through. */
2126 case 4:
2127 kind = 0;
2128 break;
2130 case 8:
2131 kind = 1;
2132 break;
2134 case 10:
2135 kind = 2;
2136 break;
2138 case 16:
2139 kind = 3;
2140 break;
2142 default:
2143 gcc_unreachable ();
2146 switch (expr->value.op.op1->ts.type)
2148 case BT_INTEGER:
2149 if (kind == 3) /* Case 16 was not handled properly above. */
2150 kind = 2;
2151 fndecl = gfor_fndecl_math_powi[kind][ikind].integer;
2152 break;
2154 case BT_REAL:
2155 /* Use builtins for real ** int4. */
2156 if (ikind == 0)
2158 switch (kind)
2160 case 0:
2161 fndecl = builtin_decl_explicit (BUILT_IN_POWIF);
2162 break;
2164 case 1:
2165 fndecl = builtin_decl_explicit (BUILT_IN_POWI);
2166 break;
2168 case 2:
2169 fndecl = builtin_decl_explicit (BUILT_IN_POWIL);
2170 break;
2172 case 3:
2173 /* Use the __builtin_powil() only if real(kind=16) is
2174 actually the C long double type. */
2175 if (!gfc_real16_is_float128)
2176 fndecl = builtin_decl_explicit (BUILT_IN_POWIL);
2177 break;
2179 default:
2180 gcc_unreachable ();
2184 /* If we don't have a good builtin for this, go for the
2185 library function. */
2186 if (!fndecl)
2187 fndecl = gfor_fndecl_math_powi[kind][ikind].real;
2188 break;
2190 case BT_COMPLEX:
2191 fndecl = gfor_fndecl_math_powi[kind][ikind].cmplx;
2192 break;
2194 default:
2195 gcc_unreachable ();
2197 break;
2199 case BT_REAL:
2200 fndecl = gfc_builtin_decl_for_float_kind (BUILT_IN_POW, kind);
2201 break;
2203 case BT_COMPLEX:
2204 fndecl = gfc_builtin_decl_for_float_kind (BUILT_IN_CPOW, kind);
2205 break;
2207 default:
2208 gcc_unreachable ();
2209 break;
2212 se->expr = build_call_expr_loc (input_location,
2213 fndecl, 2, lse.expr, rse.expr);
2215 /* Convert the result back if it is of wrong integer kind. */
2216 if (res_ikind_1 != -1 && res_ikind_2 != -1)
2218 /* We want the maximum of both operand kinds as result. */
2219 if (res_ikind_1 < res_ikind_2)
2220 res_ikind_1 = res_ikind_2;
2221 se->expr = convert (gfc_get_int_type (res_ikind_1), se->expr);
2226 /* Generate code to allocate a string temporary. */
2228 tree
2229 gfc_conv_string_tmp (gfc_se * se, tree type, tree len)
2231 tree var;
2232 tree tmp;
2234 if (gfc_can_put_var_on_stack (len))
2236 /* Create a temporary variable to hold the result. */
2237 tmp = fold_build2_loc (input_location, MINUS_EXPR,
2238 gfc_charlen_type_node, len,
2239 build_int_cst (gfc_charlen_type_node, 1));
2240 tmp = build_range_type (gfc_array_index_type, gfc_index_zero_node, tmp);
2242 if (TREE_CODE (TREE_TYPE (type)) == ARRAY_TYPE)
2243 tmp = build_array_type (TREE_TYPE (TREE_TYPE (type)), tmp);
2244 else
2245 tmp = build_array_type (TREE_TYPE (type), tmp);
2247 var = gfc_create_var (tmp, "str");
2248 var = gfc_build_addr_expr (type, var);
2250 else
2252 /* Allocate a temporary to hold the result. */
2253 var = gfc_create_var (type, "pstr");
2254 tmp = gfc_call_malloc (&se->pre, type,
2255 fold_build2_loc (input_location, MULT_EXPR,
2256 TREE_TYPE (len), len,
2257 fold_convert (TREE_TYPE (len),
2258 TYPE_SIZE (type))));
2259 gfc_add_modify (&se->pre, var, tmp);
2261 /* Free the temporary afterwards. */
2262 tmp = gfc_call_free (convert (pvoid_type_node, var));
2263 gfc_add_expr_to_block (&se->post, tmp);
2266 return var;
2270 /* Handle a string concatenation operation. A temporary will be allocated to
2271 hold the result. */
2273 static void
2274 gfc_conv_concat_op (gfc_se * se, gfc_expr * expr)
2276 gfc_se lse, rse;
2277 tree len, type, var, tmp, fndecl;
2279 gcc_assert (expr->value.op.op1->ts.type == BT_CHARACTER
2280 && expr->value.op.op2->ts.type == BT_CHARACTER);
2281 gcc_assert (expr->value.op.op1->ts.kind == expr->value.op.op2->ts.kind);
2283 gfc_init_se (&lse, se);
2284 gfc_conv_expr (&lse, expr->value.op.op1);
2285 gfc_conv_string_parameter (&lse);
2286 gfc_init_se (&rse, se);
2287 gfc_conv_expr (&rse, expr->value.op.op2);
2288 gfc_conv_string_parameter (&rse);
2290 gfc_add_block_to_block (&se->pre, &lse.pre);
2291 gfc_add_block_to_block (&se->pre, &rse.pre);
2293 type = gfc_get_character_type (expr->ts.kind, expr->ts.u.cl);
2294 len = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
2295 if (len == NULL_TREE)
2297 len = fold_build2_loc (input_location, PLUS_EXPR,
2298 TREE_TYPE (lse.string_length),
2299 lse.string_length, rse.string_length);
2302 type = build_pointer_type (type);
2304 var = gfc_conv_string_tmp (se, type, len);
2306 /* Do the actual concatenation. */
2307 if (expr->ts.kind == 1)
2308 fndecl = gfor_fndecl_concat_string;
2309 else if (expr->ts.kind == 4)
2310 fndecl = gfor_fndecl_concat_string_char4;
2311 else
2312 gcc_unreachable ();
2314 tmp = build_call_expr_loc (input_location,
2315 fndecl, 6, len, var, lse.string_length, lse.expr,
2316 rse.string_length, rse.expr);
2317 gfc_add_expr_to_block (&se->pre, tmp);
2319 /* Add the cleanup for the operands. */
2320 gfc_add_block_to_block (&se->pre, &rse.post);
2321 gfc_add_block_to_block (&se->pre, &lse.post);
2323 se->expr = var;
2324 se->string_length = len;
2327 /* Translates an op expression. Common (binary) cases are handled by this
2328 function, others are passed on. Recursion is used in either case.
2329 We use the fact that (op1.ts == op2.ts) (except for the power
2330 operator **).
2331 Operators need no special handling for scalarized expressions as long as
2332 they call gfc_conv_simple_val to get their operands.
2333 Character strings get special handling. */
2335 static void
2336 gfc_conv_expr_op (gfc_se * se, gfc_expr * expr)
2338 enum tree_code code;
2339 gfc_se lse;
2340 gfc_se rse;
2341 tree tmp, type;
2342 int lop;
2343 int checkstring;
2345 checkstring = 0;
2346 lop = 0;
2347 switch (expr->value.op.op)
2349 case INTRINSIC_PARENTHESES:
2350 if ((expr->ts.type == BT_REAL
2351 || expr->ts.type == BT_COMPLEX)
2352 && gfc_option.flag_protect_parens)
2354 gfc_conv_unary_op (PAREN_EXPR, se, expr);
2355 gcc_assert (FLOAT_TYPE_P (TREE_TYPE (se->expr)));
2356 return;
2359 /* Fallthrough. */
2360 case INTRINSIC_UPLUS:
2361 gfc_conv_expr (se, expr->value.op.op1);
2362 return;
2364 case INTRINSIC_UMINUS:
2365 gfc_conv_unary_op (NEGATE_EXPR, se, expr);
2366 return;
2368 case INTRINSIC_NOT:
2369 gfc_conv_unary_op (TRUTH_NOT_EXPR, se, expr);
2370 return;
2372 case INTRINSIC_PLUS:
2373 code = PLUS_EXPR;
2374 break;
2376 case INTRINSIC_MINUS:
2377 code = MINUS_EXPR;
2378 break;
2380 case INTRINSIC_TIMES:
2381 code = MULT_EXPR;
2382 break;
2384 case INTRINSIC_DIVIDE:
2385 /* If expr is a real or complex expr, use an RDIV_EXPR. If op1 is
2386 an integer, we must round towards zero, so we use a
2387 TRUNC_DIV_EXPR. */
2388 if (expr->ts.type == BT_INTEGER)
2389 code = TRUNC_DIV_EXPR;
2390 else
2391 code = RDIV_EXPR;
2392 break;
2394 case INTRINSIC_POWER:
2395 gfc_conv_power_op (se, expr);
2396 return;
2398 case INTRINSIC_CONCAT:
2399 gfc_conv_concat_op (se, expr);
2400 return;
2402 case INTRINSIC_AND:
2403 code = TRUTH_ANDIF_EXPR;
2404 lop = 1;
2405 break;
2407 case INTRINSIC_OR:
2408 code = TRUTH_ORIF_EXPR;
2409 lop = 1;
2410 break;
2412 /* EQV and NEQV only work on logicals, but since we represent them
2413 as integers, we can use EQ_EXPR and NE_EXPR for them in GIMPLE. */
2414 case INTRINSIC_EQ:
2415 case INTRINSIC_EQ_OS:
2416 case INTRINSIC_EQV:
2417 code = EQ_EXPR;
2418 checkstring = 1;
2419 lop = 1;
2420 break;
2422 case INTRINSIC_NE:
2423 case INTRINSIC_NE_OS:
2424 case INTRINSIC_NEQV:
2425 code = NE_EXPR;
2426 checkstring = 1;
2427 lop = 1;
2428 break;
2430 case INTRINSIC_GT:
2431 case INTRINSIC_GT_OS:
2432 code = GT_EXPR;
2433 checkstring = 1;
2434 lop = 1;
2435 break;
2437 case INTRINSIC_GE:
2438 case INTRINSIC_GE_OS:
2439 code = GE_EXPR;
2440 checkstring = 1;
2441 lop = 1;
2442 break;
2444 case INTRINSIC_LT:
2445 case INTRINSIC_LT_OS:
2446 code = LT_EXPR;
2447 checkstring = 1;
2448 lop = 1;
2449 break;
2451 case INTRINSIC_LE:
2452 case INTRINSIC_LE_OS:
2453 code = LE_EXPR;
2454 checkstring = 1;
2455 lop = 1;
2456 break;
2458 case INTRINSIC_USER:
2459 case INTRINSIC_ASSIGN:
2460 /* These should be converted into function calls by the frontend. */
2461 gcc_unreachable ();
2463 default:
2464 fatal_error ("Unknown intrinsic op");
2465 return;
2468 /* The only exception to this is **, which is handled separately anyway. */
2469 gcc_assert (expr->value.op.op1->ts.type == expr->value.op.op2->ts.type);
2471 if (checkstring && expr->value.op.op1->ts.type != BT_CHARACTER)
2472 checkstring = 0;
2474 /* lhs */
2475 gfc_init_se (&lse, se);
2476 gfc_conv_expr (&lse, expr->value.op.op1);
2477 gfc_add_block_to_block (&se->pre, &lse.pre);
2479 /* rhs */
2480 gfc_init_se (&rse, se);
2481 gfc_conv_expr (&rse, expr->value.op.op2);
2482 gfc_add_block_to_block (&se->pre, &rse.pre);
2484 if (checkstring)
2486 gfc_conv_string_parameter (&lse);
2487 gfc_conv_string_parameter (&rse);
2489 lse.expr = gfc_build_compare_string (lse.string_length, lse.expr,
2490 rse.string_length, rse.expr,
2491 expr->value.op.op1->ts.kind,
2492 code);
2493 rse.expr = build_int_cst (TREE_TYPE (lse.expr), 0);
2494 gfc_add_block_to_block (&lse.post, &rse.post);
2497 type = gfc_typenode_for_spec (&expr->ts);
2499 if (lop)
2501 /* The result of logical ops is always boolean_type_node. */
2502 tmp = fold_build2_loc (input_location, code, boolean_type_node,
2503 lse.expr, rse.expr);
2504 se->expr = convert (type, tmp);
2506 else
2507 se->expr = fold_build2_loc (input_location, code, type, lse.expr, rse.expr);
2509 /* Add the post blocks. */
2510 gfc_add_block_to_block (&se->post, &rse.post);
2511 gfc_add_block_to_block (&se->post, &lse.post);
2514 /* If a string's length is one, we convert it to a single character. */
2516 tree
2517 gfc_string_to_single_character (tree len, tree str, int kind)
2520 if (len == NULL
2521 || !INTEGER_CST_P (len) || TREE_INT_CST_HIGH (len) != 0
2522 || !POINTER_TYPE_P (TREE_TYPE (str)))
2523 return NULL_TREE;
2525 if (TREE_INT_CST_LOW (len) == 1)
2527 str = fold_convert (gfc_get_pchar_type (kind), str);
2528 return build_fold_indirect_ref_loc (input_location, str);
2531 if (kind == 1
2532 && TREE_CODE (str) == ADDR_EXPR
2533 && TREE_CODE (TREE_OPERAND (str, 0)) == ARRAY_REF
2534 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (str, 0), 0)) == STRING_CST
2535 && array_ref_low_bound (TREE_OPERAND (str, 0))
2536 == TREE_OPERAND (TREE_OPERAND (str, 0), 1)
2537 && TREE_INT_CST_LOW (len) > 1
2538 && TREE_INT_CST_LOW (len)
2539 == (unsigned HOST_WIDE_INT)
2540 TREE_STRING_LENGTH (TREE_OPERAND (TREE_OPERAND (str, 0), 0)))
2542 tree ret = fold_convert (gfc_get_pchar_type (kind), str);
2543 ret = build_fold_indirect_ref_loc (input_location, ret);
2544 if (TREE_CODE (ret) == INTEGER_CST)
2546 tree string_cst = TREE_OPERAND (TREE_OPERAND (str, 0), 0);
2547 int i, length = TREE_STRING_LENGTH (string_cst);
2548 const char *ptr = TREE_STRING_POINTER (string_cst);
2550 for (i = 1; i < length; i++)
2551 if (ptr[i] != ' ')
2552 return NULL_TREE;
2554 return ret;
2558 return NULL_TREE;
2562 void
2563 gfc_conv_scalar_char_value (gfc_symbol *sym, gfc_se *se, gfc_expr **expr)
2566 if (sym->backend_decl)
2568 /* This becomes the nominal_type in
2569 function.c:assign_parm_find_data_types. */
2570 TREE_TYPE (sym->backend_decl) = unsigned_char_type_node;
2571 /* This becomes the passed_type in
2572 function.c:assign_parm_find_data_types. C promotes char to
2573 integer for argument passing. */
2574 DECL_ARG_TYPE (sym->backend_decl) = unsigned_type_node;
2576 DECL_BY_REFERENCE (sym->backend_decl) = 0;
2579 if (expr != NULL)
2581 /* If we have a constant character expression, make it into an
2582 integer. */
2583 if ((*expr)->expr_type == EXPR_CONSTANT)
2585 gfc_typespec ts;
2586 gfc_clear_ts (&ts);
2588 *expr = gfc_get_int_expr (gfc_default_integer_kind, NULL,
2589 (int)(*expr)->value.character.string[0]);
2590 if ((*expr)->ts.kind != gfc_c_int_kind)
2592 /* The expr needs to be compatible with a C int. If the
2593 conversion fails, then the 2 causes an ICE. */
2594 ts.type = BT_INTEGER;
2595 ts.kind = gfc_c_int_kind;
2596 gfc_convert_type (*expr, &ts, 2);
2599 else if (se != NULL && (*expr)->expr_type == EXPR_VARIABLE)
2601 if ((*expr)->ref == NULL)
2603 se->expr = gfc_string_to_single_character
2604 (build_int_cst (integer_type_node, 1),
2605 gfc_build_addr_expr (gfc_get_pchar_type ((*expr)->ts.kind),
2606 gfc_get_symbol_decl
2607 ((*expr)->symtree->n.sym)),
2608 (*expr)->ts.kind);
2610 else
2612 gfc_conv_variable (se, *expr);
2613 se->expr = gfc_string_to_single_character
2614 (build_int_cst (integer_type_node, 1),
2615 gfc_build_addr_expr (gfc_get_pchar_type ((*expr)->ts.kind),
2616 se->expr),
2617 (*expr)->ts.kind);
2623 /* Helper function for gfc_build_compare_string. Return LEN_TRIM value
2624 if STR is a string literal, otherwise return -1. */
2626 static int
2627 gfc_optimize_len_trim (tree len, tree str, int kind)
2629 if (kind == 1
2630 && TREE_CODE (str) == ADDR_EXPR
2631 && TREE_CODE (TREE_OPERAND (str, 0)) == ARRAY_REF
2632 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (str, 0), 0)) == STRING_CST
2633 && array_ref_low_bound (TREE_OPERAND (str, 0))
2634 == TREE_OPERAND (TREE_OPERAND (str, 0), 1)
2635 && TREE_INT_CST_LOW (len) >= 1
2636 && TREE_INT_CST_LOW (len)
2637 == (unsigned HOST_WIDE_INT)
2638 TREE_STRING_LENGTH (TREE_OPERAND (TREE_OPERAND (str, 0), 0)))
2640 tree folded = fold_convert (gfc_get_pchar_type (kind), str);
2641 folded = build_fold_indirect_ref_loc (input_location, folded);
2642 if (TREE_CODE (folded) == INTEGER_CST)
2644 tree string_cst = TREE_OPERAND (TREE_OPERAND (str, 0), 0);
2645 int length = TREE_STRING_LENGTH (string_cst);
2646 const char *ptr = TREE_STRING_POINTER (string_cst);
2648 for (; length > 0; length--)
2649 if (ptr[length - 1] != ' ')
2650 break;
2652 return length;
2655 return -1;
2658 /* Compare two strings. If they are all single characters, the result is the
2659 subtraction of them. Otherwise, we build a library call. */
2661 tree
2662 gfc_build_compare_string (tree len1, tree str1, tree len2, tree str2, int kind,
2663 enum tree_code code)
2665 tree sc1;
2666 tree sc2;
2667 tree fndecl;
2669 gcc_assert (POINTER_TYPE_P (TREE_TYPE (str1)));
2670 gcc_assert (POINTER_TYPE_P (TREE_TYPE (str2)));
2672 sc1 = gfc_string_to_single_character (len1, str1, kind);
2673 sc2 = gfc_string_to_single_character (len2, str2, kind);
2675 if (sc1 != NULL_TREE && sc2 != NULL_TREE)
2677 /* Deal with single character specially. */
2678 sc1 = fold_convert (integer_type_node, sc1);
2679 sc2 = fold_convert (integer_type_node, sc2);
2680 return fold_build2_loc (input_location, MINUS_EXPR, integer_type_node,
2681 sc1, sc2);
2684 if ((code == EQ_EXPR || code == NE_EXPR)
2685 && optimize
2686 && INTEGER_CST_P (len1) && INTEGER_CST_P (len2))
2688 /* If one string is a string literal with LEN_TRIM longer
2689 than the length of the second string, the strings
2690 compare unequal. */
2691 int len = gfc_optimize_len_trim (len1, str1, kind);
2692 if (len > 0 && compare_tree_int (len2, len) < 0)
2693 return integer_one_node;
2694 len = gfc_optimize_len_trim (len2, str2, kind);
2695 if (len > 0 && compare_tree_int (len1, len) < 0)
2696 return integer_one_node;
2699 /* Build a call for the comparison. */
2700 if (kind == 1)
2701 fndecl = gfor_fndecl_compare_string;
2702 else if (kind == 4)
2703 fndecl = gfor_fndecl_compare_string_char4;
2704 else
2705 gcc_unreachable ();
2707 return build_call_expr_loc (input_location, fndecl, 4,
2708 len1, str1, len2, str2);
2712 /* Return the backend_decl for a procedure pointer component. */
2714 static tree
2715 get_proc_ptr_comp (gfc_expr *e)
2717 gfc_se comp_se;
2718 gfc_expr *e2;
2719 expr_t old_type;
2721 gfc_init_se (&comp_se, NULL);
2722 e2 = gfc_copy_expr (e);
2723 /* We have to restore the expr type later so that gfc_free_expr frees
2724 the exact same thing that was allocated.
2725 TODO: This is ugly. */
2726 old_type = e2->expr_type;
2727 e2->expr_type = EXPR_VARIABLE;
2728 gfc_conv_expr (&comp_se, e2);
2729 e2->expr_type = old_type;
2730 gfc_free_expr (e2);
2731 return build_fold_addr_expr_loc (input_location, comp_se.expr);
2735 /* Convert a typebound function reference from a class object. */
2736 static void
2737 conv_base_obj_fcn_val (gfc_se * se, tree base_object, gfc_expr * expr)
2739 gfc_ref *ref;
2740 tree var;
2742 if (TREE_CODE (base_object) != VAR_DECL)
2744 var = gfc_create_var (TREE_TYPE (base_object), NULL);
2745 gfc_add_modify (&se->pre, var, base_object);
2747 se->expr = gfc_class_vptr_get (base_object);
2748 se->expr = build_fold_indirect_ref_loc (input_location, se->expr);
2749 ref = expr->ref;
2750 while (ref && ref->next)
2751 ref = ref->next;
2752 gcc_assert (ref && ref->type == REF_COMPONENT);
2753 if (ref->u.c.sym->attr.extension)
2754 conv_parent_component_references (se, ref);
2755 gfc_conv_component_ref (se, ref);
2756 se->expr = build_fold_addr_expr_loc (input_location, se->expr);
2760 static void
2761 conv_function_val (gfc_se * se, gfc_symbol * sym, gfc_expr * expr)
2763 tree tmp;
2765 if (gfc_is_proc_ptr_comp (expr))
2766 tmp = get_proc_ptr_comp (expr);
2767 else if (sym->attr.dummy)
2769 tmp = gfc_get_symbol_decl (sym);
2770 if (sym->attr.proc_pointer)
2771 tmp = build_fold_indirect_ref_loc (input_location,
2772 tmp);
2773 gcc_assert (TREE_CODE (TREE_TYPE (tmp)) == POINTER_TYPE
2774 && TREE_CODE (TREE_TYPE (TREE_TYPE (tmp))) == FUNCTION_TYPE);
2776 else
2778 if (!sym->backend_decl)
2779 sym->backend_decl = gfc_get_extern_function_decl (sym);
2781 TREE_USED (sym->backend_decl) = 1;
2783 tmp = sym->backend_decl;
2785 if (sym->attr.cray_pointee)
2787 /* TODO - make the cray pointee a pointer to a procedure,
2788 assign the pointer to it and use it for the call. This
2789 will do for now! */
2790 tmp = convert (build_pointer_type (TREE_TYPE (tmp)),
2791 gfc_get_symbol_decl (sym->cp_pointer));
2792 tmp = gfc_evaluate_now (tmp, &se->pre);
2795 if (!POINTER_TYPE_P (TREE_TYPE (tmp)))
2797 gcc_assert (TREE_CODE (tmp) == FUNCTION_DECL);
2798 tmp = gfc_build_addr_expr (NULL_TREE, tmp);
2801 se->expr = tmp;
2805 /* Initialize MAPPING. */
2807 void
2808 gfc_init_interface_mapping (gfc_interface_mapping * mapping)
2810 mapping->syms = NULL;
2811 mapping->charlens = NULL;
2815 /* Free all memory held by MAPPING (but not MAPPING itself). */
2817 void
2818 gfc_free_interface_mapping (gfc_interface_mapping * mapping)
2820 gfc_interface_sym_mapping *sym;
2821 gfc_interface_sym_mapping *nextsym;
2822 gfc_charlen *cl;
2823 gfc_charlen *nextcl;
2825 for (sym = mapping->syms; sym; sym = nextsym)
2827 nextsym = sym->next;
2828 sym->new_sym->n.sym->formal = NULL;
2829 gfc_free_symbol (sym->new_sym->n.sym);
2830 gfc_free_expr (sym->expr);
2831 free (sym->new_sym);
2832 free (sym);
2834 for (cl = mapping->charlens; cl; cl = nextcl)
2836 nextcl = cl->next;
2837 gfc_free_expr (cl->length);
2838 free (cl);
2843 /* Return a copy of gfc_charlen CL. Add the returned structure to
2844 MAPPING so that it will be freed by gfc_free_interface_mapping. */
2846 static gfc_charlen *
2847 gfc_get_interface_mapping_charlen (gfc_interface_mapping * mapping,
2848 gfc_charlen * cl)
2850 gfc_charlen *new_charlen;
2852 new_charlen = gfc_get_charlen ();
2853 new_charlen->next = mapping->charlens;
2854 new_charlen->length = gfc_copy_expr (cl->length);
2856 mapping->charlens = new_charlen;
2857 return new_charlen;
2861 /* A subroutine of gfc_add_interface_mapping. Return a descriptorless
2862 array variable that can be used as the actual argument for dummy
2863 argument SYM. Add any initialization code to BLOCK. PACKED is as
2864 for gfc_get_nodesc_array_type and DATA points to the first element
2865 in the passed array. */
2867 static tree
2868 gfc_get_interface_mapping_array (stmtblock_t * block, gfc_symbol * sym,
2869 gfc_packed packed, tree data)
2871 tree type;
2872 tree var;
2874 type = gfc_typenode_for_spec (&sym->ts);
2875 type = gfc_get_nodesc_array_type (type, sym->as, packed,
2876 !sym->attr.target && !sym->attr.pointer
2877 && !sym->attr.proc_pointer);
2879 var = gfc_create_var (type, "ifm");
2880 gfc_add_modify (block, var, fold_convert (type, data));
2882 return var;
2886 /* A subroutine of gfc_add_interface_mapping. Set the stride, upper bounds
2887 and offset of descriptorless array type TYPE given that it has the same
2888 size as DESC. Add any set-up code to BLOCK. */
2890 static void
2891 gfc_set_interface_mapping_bounds (stmtblock_t * block, tree type, tree desc)
2893 int n;
2894 tree dim;
2895 tree offset;
2896 tree tmp;
2898 offset = gfc_index_zero_node;
2899 for (n = 0; n < GFC_TYPE_ARRAY_RANK (type); n++)
2901 dim = gfc_rank_cst[n];
2902 GFC_TYPE_ARRAY_STRIDE (type, n) = gfc_conv_array_stride (desc, n);
2903 if (GFC_TYPE_ARRAY_LBOUND (type, n) == NULL_TREE)
2905 GFC_TYPE_ARRAY_LBOUND (type, n)
2906 = gfc_conv_descriptor_lbound_get (desc, dim);
2907 GFC_TYPE_ARRAY_UBOUND (type, n)
2908 = gfc_conv_descriptor_ubound_get (desc, dim);
2910 else if (GFC_TYPE_ARRAY_UBOUND (type, n) == NULL_TREE)
2912 tmp = fold_build2_loc (input_location, MINUS_EXPR,
2913 gfc_array_index_type,
2914 gfc_conv_descriptor_ubound_get (desc, dim),
2915 gfc_conv_descriptor_lbound_get (desc, dim));
2916 tmp = fold_build2_loc (input_location, PLUS_EXPR,
2917 gfc_array_index_type,
2918 GFC_TYPE_ARRAY_LBOUND (type, n), tmp);
2919 tmp = gfc_evaluate_now (tmp, block);
2920 GFC_TYPE_ARRAY_UBOUND (type, n) = tmp;
2922 tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
2923 GFC_TYPE_ARRAY_LBOUND (type, n),
2924 GFC_TYPE_ARRAY_STRIDE (type, n));
2925 offset = fold_build2_loc (input_location, MINUS_EXPR,
2926 gfc_array_index_type, offset, tmp);
2928 offset = gfc_evaluate_now (offset, block);
2929 GFC_TYPE_ARRAY_OFFSET (type) = offset;
2933 /* Extend MAPPING so that it maps dummy argument SYM to the value stored
2934 in SE. The caller may still use se->expr and se->string_length after
2935 calling this function. */
2937 void
2938 gfc_add_interface_mapping (gfc_interface_mapping * mapping,
2939 gfc_symbol * sym, gfc_se * se,
2940 gfc_expr *expr)
2942 gfc_interface_sym_mapping *sm;
2943 tree desc;
2944 tree tmp;
2945 tree value;
2946 gfc_symbol *new_sym;
2947 gfc_symtree *root;
2948 gfc_symtree *new_symtree;
2950 /* Create a new symbol to represent the actual argument. */
2951 new_sym = gfc_new_symbol (sym->name, NULL);
2952 new_sym->ts = sym->ts;
2953 new_sym->as = gfc_copy_array_spec (sym->as);
2954 new_sym->attr.referenced = 1;
2955 new_sym->attr.dimension = sym->attr.dimension;
2956 new_sym->attr.contiguous = sym->attr.contiguous;
2957 new_sym->attr.codimension = sym->attr.codimension;
2958 new_sym->attr.pointer = sym->attr.pointer;
2959 new_sym->attr.allocatable = sym->attr.allocatable;
2960 new_sym->attr.flavor = sym->attr.flavor;
2961 new_sym->attr.function = sym->attr.function;
2963 /* Ensure that the interface is available and that
2964 descriptors are passed for array actual arguments. */
2965 if (sym->attr.flavor == FL_PROCEDURE)
2967 new_sym->formal = expr->symtree->n.sym->formal;
2968 new_sym->attr.always_explicit
2969 = expr->symtree->n.sym->attr.always_explicit;
2972 /* Create a fake symtree for it. */
2973 root = NULL;
2974 new_symtree = gfc_new_symtree (&root, sym->name);
2975 new_symtree->n.sym = new_sym;
2976 gcc_assert (new_symtree == root);
2978 /* Create a dummy->actual mapping. */
2979 sm = XCNEW (gfc_interface_sym_mapping);
2980 sm->next = mapping->syms;
2981 sm->old = sym;
2982 sm->new_sym = new_symtree;
2983 sm->expr = gfc_copy_expr (expr);
2984 mapping->syms = sm;
2986 /* Stabilize the argument's value. */
2987 if (!sym->attr.function && se)
2988 se->expr = gfc_evaluate_now (se->expr, &se->pre);
2990 if (sym->ts.type == BT_CHARACTER)
2992 /* Create a copy of the dummy argument's length. */
2993 new_sym->ts.u.cl = gfc_get_interface_mapping_charlen (mapping, sym->ts.u.cl);
2994 sm->expr->ts.u.cl = new_sym->ts.u.cl;
2996 /* If the length is specified as "*", record the length that
2997 the caller is passing. We should use the callee's length
2998 in all other cases. */
2999 if (!new_sym->ts.u.cl->length && se)
3001 se->string_length = gfc_evaluate_now (se->string_length, &se->pre);
3002 new_sym->ts.u.cl->backend_decl = se->string_length;
3006 if (!se)
3007 return;
3009 /* Use the passed value as-is if the argument is a function. */
3010 if (sym->attr.flavor == FL_PROCEDURE)
3011 value = se->expr;
3013 /* If the argument is either a string or a pointer to a string,
3014 convert it to a boundless character type. */
3015 else if (!sym->attr.dimension && sym->ts.type == BT_CHARACTER)
3017 tmp = gfc_get_character_type_len (sym->ts.kind, NULL);
3018 tmp = build_pointer_type (tmp);
3019 if (sym->attr.pointer)
3020 value = build_fold_indirect_ref_loc (input_location,
3021 se->expr);
3022 else
3023 value = se->expr;
3024 value = fold_convert (tmp, value);
3027 /* If the argument is a scalar, a pointer to an array or an allocatable,
3028 dereference it. */
3029 else if (!sym->attr.dimension || sym->attr.pointer || sym->attr.allocatable)
3030 value = build_fold_indirect_ref_loc (input_location,
3031 se->expr);
3033 /* For character(*), use the actual argument's descriptor. */
3034 else if (sym->ts.type == BT_CHARACTER && !new_sym->ts.u.cl->length)
3035 value = build_fold_indirect_ref_loc (input_location,
3036 se->expr);
3038 /* If the argument is an array descriptor, use it to determine
3039 information about the actual argument's shape. */
3040 else if (POINTER_TYPE_P (TREE_TYPE (se->expr))
3041 && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (TREE_TYPE (se->expr))))
3043 /* Get the actual argument's descriptor. */
3044 desc = build_fold_indirect_ref_loc (input_location,
3045 se->expr);
3047 /* Create the replacement variable. */
3048 tmp = gfc_conv_descriptor_data_get (desc);
3049 value = gfc_get_interface_mapping_array (&se->pre, sym,
3050 PACKED_NO, tmp);
3052 /* Use DESC to work out the upper bounds, strides and offset. */
3053 gfc_set_interface_mapping_bounds (&se->pre, TREE_TYPE (value), desc);
3055 else
3056 /* Otherwise we have a packed array. */
3057 value = gfc_get_interface_mapping_array (&se->pre, sym,
3058 PACKED_FULL, se->expr);
3060 new_sym->backend_decl = value;
3064 /* Called once all dummy argument mappings have been added to MAPPING,
3065 but before the mapping is used to evaluate expressions. Pre-evaluate
3066 the length of each argument, adding any initialization code to PRE and
3067 any finalization code to POST. */
3069 void
3070 gfc_finish_interface_mapping (gfc_interface_mapping * mapping,
3071 stmtblock_t * pre, stmtblock_t * post)
3073 gfc_interface_sym_mapping *sym;
3074 gfc_expr *expr;
3075 gfc_se se;
3077 for (sym = mapping->syms; sym; sym = sym->next)
3078 if (sym->new_sym->n.sym->ts.type == BT_CHARACTER
3079 && !sym->new_sym->n.sym->ts.u.cl->backend_decl)
3081 expr = sym->new_sym->n.sym->ts.u.cl->length;
3082 gfc_apply_interface_mapping_to_expr (mapping, expr);
3083 gfc_init_se (&se, NULL);
3084 gfc_conv_expr (&se, expr);
3085 se.expr = fold_convert (gfc_charlen_type_node, se.expr);
3086 se.expr = gfc_evaluate_now (se.expr, &se.pre);
3087 gfc_add_block_to_block (pre, &se.pre);
3088 gfc_add_block_to_block (post, &se.post);
3090 sym->new_sym->n.sym->ts.u.cl->backend_decl = se.expr;
3095 /* Like gfc_apply_interface_mapping_to_expr, but applied to
3096 constructor C. */
3098 static void
3099 gfc_apply_interface_mapping_to_cons (gfc_interface_mapping * mapping,
3100 gfc_constructor_base base)
3102 gfc_constructor *c;
3103 for (c = gfc_constructor_first (base); c; c = gfc_constructor_next (c))
3105 gfc_apply_interface_mapping_to_expr (mapping, c->expr);
3106 if (c->iterator)
3108 gfc_apply_interface_mapping_to_expr (mapping, c->iterator->start);
3109 gfc_apply_interface_mapping_to_expr (mapping, c->iterator->end);
3110 gfc_apply_interface_mapping_to_expr (mapping, c->iterator->step);
3116 /* Like gfc_apply_interface_mapping_to_expr, but applied to
3117 reference REF. */
3119 static void
3120 gfc_apply_interface_mapping_to_ref (gfc_interface_mapping * mapping,
3121 gfc_ref * ref)
3123 int n;
3125 for (; ref; ref = ref->next)
3126 switch (ref->type)
3128 case REF_ARRAY:
3129 for (n = 0; n < ref->u.ar.dimen; n++)
3131 gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.start[n]);
3132 gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.end[n]);
3133 gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.stride[n]);
3135 break;
3137 case REF_COMPONENT:
3138 break;
3140 case REF_SUBSTRING:
3141 gfc_apply_interface_mapping_to_expr (mapping, ref->u.ss.start);
3142 gfc_apply_interface_mapping_to_expr (mapping, ref->u.ss.end);
3143 break;
3148 /* Convert intrinsic function calls into result expressions. */
3150 static bool
3151 gfc_map_intrinsic_function (gfc_expr *expr, gfc_interface_mapping *mapping)
3153 gfc_symbol *sym;
3154 gfc_expr *new_expr;
3155 gfc_expr *arg1;
3156 gfc_expr *arg2;
3157 int d, dup;
3159 arg1 = expr->value.function.actual->expr;
3160 if (expr->value.function.actual->next)
3161 arg2 = expr->value.function.actual->next->expr;
3162 else
3163 arg2 = NULL;
3165 sym = arg1->symtree->n.sym;
3167 if (sym->attr.dummy)
3168 return false;
3170 new_expr = NULL;
3172 switch (expr->value.function.isym->id)
3174 case GFC_ISYM_LEN:
3175 /* TODO figure out why this condition is necessary. */
3176 if (sym->attr.function
3177 && (arg1->ts.u.cl->length == NULL
3178 || (arg1->ts.u.cl->length->expr_type != EXPR_CONSTANT
3179 && arg1->ts.u.cl->length->expr_type != EXPR_VARIABLE)))
3180 return false;
3182 new_expr = gfc_copy_expr (arg1->ts.u.cl->length);
3183 break;
3185 case GFC_ISYM_SIZE:
3186 if (!sym->as || sym->as->rank == 0)
3187 return false;
3189 if (arg2 && arg2->expr_type == EXPR_CONSTANT)
3191 dup = mpz_get_si (arg2->value.integer);
3192 d = dup - 1;
3194 else
3196 dup = sym->as->rank;
3197 d = 0;
3200 for (; d < dup; d++)
3202 gfc_expr *tmp;
3204 if (!sym->as->upper[d] || !sym->as->lower[d])
3206 gfc_free_expr (new_expr);
3207 return false;
3210 tmp = gfc_add (gfc_copy_expr (sym->as->upper[d]),
3211 gfc_get_int_expr (gfc_default_integer_kind,
3212 NULL, 1));
3213 tmp = gfc_subtract (tmp, gfc_copy_expr (sym->as->lower[d]));
3214 if (new_expr)
3215 new_expr = gfc_multiply (new_expr, tmp);
3216 else
3217 new_expr = tmp;
3219 break;
3221 case GFC_ISYM_LBOUND:
3222 case GFC_ISYM_UBOUND:
3223 /* TODO These implementations of lbound and ubound do not limit if
3224 the size < 0, according to F95's 13.14.53 and 13.14.113. */
3226 if (!sym->as || sym->as->rank == 0)
3227 return false;
3229 if (arg2 && arg2->expr_type == EXPR_CONSTANT)
3230 d = mpz_get_si (arg2->value.integer) - 1;
3231 else
3232 /* TODO: If the need arises, this could produce an array of
3233 ubound/lbounds. */
3234 gcc_unreachable ();
3236 if (expr->value.function.isym->id == GFC_ISYM_LBOUND)
3238 if (sym->as->lower[d])
3239 new_expr = gfc_copy_expr (sym->as->lower[d]);
3241 else
3243 if (sym->as->upper[d])
3244 new_expr = gfc_copy_expr (sym->as->upper[d]);
3246 break;
3248 default:
3249 break;
3252 gfc_apply_interface_mapping_to_expr (mapping, new_expr);
3253 if (!new_expr)
3254 return false;
3256 gfc_replace_expr (expr, new_expr);
3257 return true;
3261 static void
3262 gfc_map_fcn_formal_to_actual (gfc_expr *expr, gfc_expr *map_expr,
3263 gfc_interface_mapping * mapping)
3265 gfc_formal_arglist *f;
3266 gfc_actual_arglist *actual;
3268 actual = expr->value.function.actual;
3269 f = gfc_sym_get_dummy_args (map_expr->symtree->n.sym);
3271 for (; f && actual; f = f->next, actual = actual->next)
3273 if (!actual->expr)
3274 continue;
3276 gfc_add_interface_mapping (mapping, f->sym, NULL, actual->expr);
3279 if (map_expr->symtree->n.sym->attr.dimension)
3281 int d;
3282 gfc_array_spec *as;
3284 as = gfc_copy_array_spec (map_expr->symtree->n.sym->as);
3286 for (d = 0; d < as->rank; d++)
3288 gfc_apply_interface_mapping_to_expr (mapping, as->lower[d]);
3289 gfc_apply_interface_mapping_to_expr (mapping, as->upper[d]);
3292 expr->value.function.esym->as = as;
3295 if (map_expr->symtree->n.sym->ts.type == BT_CHARACTER)
3297 expr->value.function.esym->ts.u.cl->length
3298 = gfc_copy_expr (map_expr->symtree->n.sym->ts.u.cl->length);
3300 gfc_apply_interface_mapping_to_expr (mapping,
3301 expr->value.function.esym->ts.u.cl->length);
3306 /* EXPR is a copy of an expression that appeared in the interface
3307 associated with MAPPING. Walk it recursively looking for references to
3308 dummy arguments that MAPPING maps to actual arguments. Replace each such
3309 reference with a reference to the associated actual argument. */
3311 static void
3312 gfc_apply_interface_mapping_to_expr (gfc_interface_mapping * mapping,
3313 gfc_expr * expr)
3315 gfc_interface_sym_mapping *sym;
3316 gfc_actual_arglist *actual;
3318 if (!expr)
3319 return;
3321 /* Copying an expression does not copy its length, so do that here. */
3322 if (expr->ts.type == BT_CHARACTER && expr->ts.u.cl)
3324 expr->ts.u.cl = gfc_get_interface_mapping_charlen (mapping, expr->ts.u.cl);
3325 gfc_apply_interface_mapping_to_expr (mapping, expr->ts.u.cl->length);
3328 /* Apply the mapping to any references. */
3329 gfc_apply_interface_mapping_to_ref (mapping, expr->ref);
3331 /* ...and to the expression's symbol, if it has one. */
3332 /* TODO Find out why the condition on expr->symtree had to be moved into
3333 the loop rather than being outside it, as originally. */
3334 for (sym = mapping->syms; sym; sym = sym->next)
3335 if (expr->symtree && sym->old == expr->symtree->n.sym)
3337 if (sym->new_sym->n.sym->backend_decl)
3338 expr->symtree = sym->new_sym;
3339 else if (sym->expr)
3340 gfc_replace_expr (expr, gfc_copy_expr (sym->expr));
3341 /* Replace base type for polymorphic arguments. */
3342 if (expr->ref && expr->ref->type == REF_COMPONENT
3343 && sym->expr && sym->expr->ts.type == BT_CLASS)
3344 expr->ref->u.c.sym = sym->expr->ts.u.derived;
3347 /* ...and to subexpressions in expr->value. */
3348 switch (expr->expr_type)
3350 case EXPR_VARIABLE:
3351 case EXPR_CONSTANT:
3352 case EXPR_NULL:
3353 case EXPR_SUBSTRING:
3354 break;
3356 case EXPR_OP:
3357 gfc_apply_interface_mapping_to_expr (mapping, expr->value.op.op1);
3358 gfc_apply_interface_mapping_to_expr (mapping, expr->value.op.op2);
3359 break;
3361 case EXPR_FUNCTION:
3362 for (actual = expr->value.function.actual; actual; actual = actual->next)
3363 gfc_apply_interface_mapping_to_expr (mapping, actual->expr);
3365 if (expr->value.function.esym == NULL
3366 && expr->value.function.isym != NULL
3367 && expr->value.function.actual->expr->symtree
3368 && gfc_map_intrinsic_function (expr, mapping))
3369 break;
3371 for (sym = mapping->syms; sym; sym = sym->next)
3372 if (sym->old == expr->value.function.esym)
3374 expr->value.function.esym = sym->new_sym->n.sym;
3375 gfc_map_fcn_formal_to_actual (expr, sym->expr, mapping);
3376 expr->value.function.esym->result = sym->new_sym->n.sym;
3378 break;
3380 case EXPR_ARRAY:
3381 case EXPR_STRUCTURE:
3382 gfc_apply_interface_mapping_to_cons (mapping, expr->value.constructor);
3383 break;
3385 case EXPR_COMPCALL:
3386 case EXPR_PPC:
3387 gcc_unreachable ();
3388 break;
3391 return;
3395 /* Evaluate interface expression EXPR using MAPPING. Store the result
3396 in SE. */
3398 void
3399 gfc_apply_interface_mapping (gfc_interface_mapping * mapping,
3400 gfc_se * se, gfc_expr * expr)
3402 expr = gfc_copy_expr (expr);
3403 gfc_apply_interface_mapping_to_expr (mapping, expr);
3404 gfc_conv_expr (se, expr);
3405 se->expr = gfc_evaluate_now (se->expr, &se->pre);
3406 gfc_free_expr (expr);
3410 /* Returns a reference to a temporary array into which a component of
3411 an actual argument derived type array is copied and then returned
3412 after the function call. */
3413 void
3414 gfc_conv_subref_array_arg (gfc_se * parmse, gfc_expr * expr, int g77,
3415 sym_intent intent, bool formal_ptr)
3417 gfc_se lse;
3418 gfc_se rse;
3419 gfc_ss *lss;
3420 gfc_ss *rss;
3421 gfc_loopinfo loop;
3422 gfc_loopinfo loop2;
3423 gfc_array_info *info;
3424 tree offset;
3425 tree tmp_index;
3426 tree tmp;
3427 tree base_type;
3428 tree size;
3429 stmtblock_t body;
3430 int n;
3431 int dimen;
3433 gcc_assert (expr->expr_type == EXPR_VARIABLE);
3435 gfc_init_se (&lse, NULL);
3436 gfc_init_se (&rse, NULL);
3438 /* Walk the argument expression. */
3439 rss = gfc_walk_expr (expr);
3441 gcc_assert (rss != gfc_ss_terminator);
3443 /* Initialize the scalarizer. */
3444 gfc_init_loopinfo (&loop);
3445 gfc_add_ss_to_loop (&loop, rss);
3447 /* Calculate the bounds of the scalarization. */
3448 gfc_conv_ss_startstride (&loop);
3450 /* Build an ss for the temporary. */
3451 if (expr->ts.type == BT_CHARACTER && !expr->ts.u.cl->backend_decl)
3452 gfc_conv_string_length (expr->ts.u.cl, expr, &parmse->pre);
3454 base_type = gfc_typenode_for_spec (&expr->ts);
3455 if (GFC_ARRAY_TYPE_P (base_type)
3456 || GFC_DESCRIPTOR_TYPE_P (base_type))
3457 base_type = gfc_get_element_type (base_type);
3459 if (expr->ts.type == BT_CLASS)
3460 base_type = gfc_typenode_for_spec (&CLASS_DATA (expr)->ts);
3462 loop.temp_ss = gfc_get_temp_ss (base_type, ((expr->ts.type == BT_CHARACTER)
3463 ? expr->ts.u.cl->backend_decl
3464 : NULL),
3465 loop.dimen);
3467 parmse->string_length = loop.temp_ss->info->string_length;
3469 /* Associate the SS with the loop. */
3470 gfc_add_ss_to_loop (&loop, loop.temp_ss);
3472 /* Setup the scalarizing loops. */
3473 gfc_conv_loop_setup (&loop, &expr->where);
3475 /* Pass the temporary descriptor back to the caller. */
3476 info = &loop.temp_ss->info->data.array;
3477 parmse->expr = info->descriptor;
3479 /* Setup the gfc_se structures. */
3480 gfc_copy_loopinfo_to_se (&lse, &loop);
3481 gfc_copy_loopinfo_to_se (&rse, &loop);
3483 rse.ss = rss;
3484 lse.ss = loop.temp_ss;
3485 gfc_mark_ss_chain_used (rss, 1);
3486 gfc_mark_ss_chain_used (loop.temp_ss, 1);
3488 /* Start the scalarized loop body. */
3489 gfc_start_scalarized_body (&loop, &body);
3491 /* Translate the expression. */
3492 gfc_conv_expr (&rse, expr);
3494 gfc_conv_tmp_array_ref (&lse);
3496 if (intent != INTENT_OUT)
3498 tmp = gfc_trans_scalar_assign (&lse, &rse, expr->ts, true, false, true);
3499 gfc_add_expr_to_block (&body, tmp);
3500 gcc_assert (rse.ss == gfc_ss_terminator);
3501 gfc_trans_scalarizing_loops (&loop, &body);
3503 else
3505 /* Make sure that the temporary declaration survives by merging
3506 all the loop declarations into the current context. */
3507 for (n = 0; n < loop.dimen; n++)
3509 gfc_merge_block_scope (&body);
3510 body = loop.code[loop.order[n]];
3512 gfc_merge_block_scope (&body);
3515 /* Add the post block after the second loop, so that any
3516 freeing of allocated memory is done at the right time. */
3517 gfc_add_block_to_block (&parmse->pre, &loop.pre);
3519 /**********Copy the temporary back again.*********/
3521 gfc_init_se (&lse, NULL);
3522 gfc_init_se (&rse, NULL);
3524 /* Walk the argument expression. */
3525 lss = gfc_walk_expr (expr);
3526 rse.ss = loop.temp_ss;
3527 lse.ss = lss;
3529 /* Initialize the scalarizer. */
3530 gfc_init_loopinfo (&loop2);
3531 gfc_add_ss_to_loop (&loop2, lss);
3533 /* Calculate the bounds of the scalarization. */
3534 gfc_conv_ss_startstride (&loop2);
3536 /* Setup the scalarizing loops. */
3537 gfc_conv_loop_setup (&loop2, &expr->where);
3539 gfc_copy_loopinfo_to_se (&lse, &loop2);
3540 gfc_copy_loopinfo_to_se (&rse, &loop2);
3542 gfc_mark_ss_chain_used (lss, 1);
3543 gfc_mark_ss_chain_used (loop.temp_ss, 1);
3545 /* Declare the variable to hold the temporary offset and start the
3546 scalarized loop body. */
3547 offset = gfc_create_var (gfc_array_index_type, NULL);
3548 gfc_start_scalarized_body (&loop2, &body);
3550 /* Build the offsets for the temporary from the loop variables. The
3551 temporary array has lbounds of zero and strides of one in all
3552 dimensions, so this is very simple. The offset is only computed
3553 outside the innermost loop, so the overall transfer could be
3554 optimized further. */
3555 info = &rse.ss->info->data.array;
3556 dimen = rse.ss->dimen;
3558 tmp_index = gfc_index_zero_node;
3559 for (n = dimen - 1; n > 0; n--)
3561 tree tmp_str;
3562 tmp = rse.loop->loopvar[n];
3563 tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
3564 tmp, rse.loop->from[n]);
3565 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
3566 tmp, tmp_index);
3568 tmp_str = fold_build2_loc (input_location, MINUS_EXPR,
3569 gfc_array_index_type,
3570 rse.loop->to[n-1], rse.loop->from[n-1]);
3571 tmp_str = fold_build2_loc (input_location, PLUS_EXPR,
3572 gfc_array_index_type,
3573 tmp_str, gfc_index_one_node);
3575 tmp_index = fold_build2_loc (input_location, MULT_EXPR,
3576 gfc_array_index_type, tmp, tmp_str);
3579 tmp_index = fold_build2_loc (input_location, MINUS_EXPR,
3580 gfc_array_index_type,
3581 tmp_index, rse.loop->from[0]);
3582 gfc_add_modify (&rse.loop->code[0], offset, tmp_index);
3584 tmp_index = fold_build2_loc (input_location, PLUS_EXPR,
3585 gfc_array_index_type,
3586 rse.loop->loopvar[0], offset);
3588 /* Now use the offset for the reference. */
3589 tmp = build_fold_indirect_ref_loc (input_location,
3590 info->data);
3591 rse.expr = gfc_build_array_ref (tmp, tmp_index, NULL);
3593 if (expr->ts.type == BT_CHARACTER)
3594 rse.string_length = expr->ts.u.cl->backend_decl;
3596 gfc_conv_expr (&lse, expr);
3598 gcc_assert (lse.ss == gfc_ss_terminator);
3600 tmp = gfc_trans_scalar_assign (&lse, &rse, expr->ts, false, false, true);
3601 gfc_add_expr_to_block (&body, tmp);
3603 /* Generate the copying loops. */
3604 gfc_trans_scalarizing_loops (&loop2, &body);
3606 /* Wrap the whole thing up by adding the second loop to the post-block
3607 and following it by the post-block of the first loop. In this way,
3608 if the temporary needs freeing, it is done after use! */
3609 if (intent != INTENT_IN)
3611 gfc_add_block_to_block (&parmse->post, &loop2.pre);
3612 gfc_add_block_to_block (&parmse->post, &loop2.post);
3615 gfc_add_block_to_block (&parmse->post, &loop.post);
3617 gfc_cleanup_loop (&loop);
3618 gfc_cleanup_loop (&loop2);
3620 /* Pass the string length to the argument expression. */
3621 if (expr->ts.type == BT_CHARACTER)
3622 parmse->string_length = expr->ts.u.cl->backend_decl;
3624 /* Determine the offset for pointer formal arguments and set the
3625 lbounds to one. */
3626 if (formal_ptr)
3628 size = gfc_index_one_node;
3629 offset = gfc_index_zero_node;
3630 for (n = 0; n < dimen; n++)
3632 tmp = gfc_conv_descriptor_ubound_get (parmse->expr,
3633 gfc_rank_cst[n]);
3634 tmp = fold_build2_loc (input_location, PLUS_EXPR,
3635 gfc_array_index_type, tmp,
3636 gfc_index_one_node);
3637 gfc_conv_descriptor_ubound_set (&parmse->pre,
3638 parmse->expr,
3639 gfc_rank_cst[n],
3640 tmp);
3641 gfc_conv_descriptor_lbound_set (&parmse->pre,
3642 parmse->expr,
3643 gfc_rank_cst[n],
3644 gfc_index_one_node);
3645 size = gfc_evaluate_now (size, &parmse->pre);
3646 offset = fold_build2_loc (input_location, MINUS_EXPR,
3647 gfc_array_index_type,
3648 offset, size);
3649 offset = gfc_evaluate_now (offset, &parmse->pre);
3650 tmp = fold_build2_loc (input_location, MINUS_EXPR,
3651 gfc_array_index_type,
3652 rse.loop->to[n], rse.loop->from[n]);
3653 tmp = fold_build2_loc (input_location, PLUS_EXPR,
3654 gfc_array_index_type,
3655 tmp, gfc_index_one_node);
3656 size = fold_build2_loc (input_location, MULT_EXPR,
3657 gfc_array_index_type, size, tmp);
3660 gfc_conv_descriptor_offset_set (&parmse->pre, parmse->expr,
3661 offset);
3664 /* We want either the address for the data or the address of the descriptor,
3665 depending on the mode of passing array arguments. */
3666 if (g77)
3667 parmse->expr = gfc_conv_descriptor_data_get (parmse->expr);
3668 else
3669 parmse->expr = gfc_build_addr_expr (NULL_TREE, parmse->expr);
3671 return;
3675 /* Generate the code for argument list functions. */
3677 static void
3678 conv_arglist_function (gfc_se *se, gfc_expr *expr, const char *name)
3680 /* Pass by value for g77 %VAL(arg), pass the address
3681 indirectly for %LOC, else by reference. Thus %REF
3682 is a "do-nothing" and %LOC is the same as an F95
3683 pointer. */
3684 if (strncmp (name, "%VAL", 4) == 0)
3685 gfc_conv_expr (se, expr);
3686 else if (strncmp (name, "%LOC", 4) == 0)
3688 gfc_conv_expr_reference (se, expr);
3689 se->expr = gfc_build_addr_expr (NULL, se->expr);
3691 else if (strncmp (name, "%REF", 4) == 0)
3692 gfc_conv_expr_reference (se, expr);
3693 else
3694 gfc_error ("Unknown argument list function at %L", &expr->where);
3698 /* The following routine generates code for the intrinsic
3699 procedures from the ISO_C_BINDING module:
3700 * C_LOC (function)
3701 * C_FUNLOC (function)
3702 * C_F_POINTER (subroutine)
3703 * C_F_PROCPOINTER (subroutine)
3704 * C_ASSOCIATED (function)
3705 One exception which is not handled here is C_F_POINTER with non-scalar
3706 arguments. Returns 1 if the call was replaced by inline code (else: 0). */
3708 static int
3709 conv_isocbinding_procedure (gfc_se * se, gfc_symbol * sym,
3710 gfc_actual_arglist * arg)
3712 gfc_symbol *fsym;
3714 if (sym->intmod_sym_id == ISOCBINDING_LOC)
3716 if (arg->expr->rank == 0)
3717 gfc_conv_expr_reference (se, arg->expr);
3718 else
3720 int f;
3721 /* This is really the actual arg because no formal arglist is
3722 created for C_LOC. */
3723 fsym = arg->expr->symtree->n.sym;
3725 /* We should want it to do g77 calling convention. */
3726 f = (fsym != NULL)
3727 && !(fsym->attr.pointer || fsym->attr.allocatable)
3728 && fsym->as->type != AS_ASSUMED_SHAPE;
3729 f = f || !sym->attr.always_explicit;
3731 gfc_conv_array_parameter (se, arg->expr, f, NULL, NULL, NULL);
3734 /* TODO -- the following two lines shouldn't be necessary, but if
3735 they're removed, a bug is exposed later in the code path.
3736 This workaround was thus introduced, but will have to be
3737 removed; please see PR 35150 for details about the issue. */
3738 se->expr = convert (pvoid_type_node, se->expr);
3739 se->expr = gfc_evaluate_now (se->expr, &se->pre);
3741 return 1;
3743 else if (sym->intmod_sym_id == ISOCBINDING_FUNLOC)
3745 arg->expr->ts.type = sym->ts.u.derived->ts.type;
3746 arg->expr->ts.f90_type = sym->ts.u.derived->ts.f90_type;
3747 arg->expr->ts.kind = sym->ts.u.derived->ts.kind;
3748 gfc_conv_expr_reference (se, arg->expr);
3750 return 1;
3752 else if (sym->intmod_sym_id == ISOCBINDING_F_POINTER
3753 || sym->intmod_sym_id == ISOCBINDING_F_PROCPOINTER)
3755 /* Convert c_f_pointer and c_f_procpointer. */
3756 gfc_se cptrse;
3757 gfc_se fptrse;
3758 gfc_se shapese;
3759 gfc_ss *shape_ss;
3760 tree desc, dim, tmp, stride, offset;
3761 stmtblock_t body, block;
3762 gfc_loopinfo loop;
3764 gfc_init_se (&cptrse, NULL);
3765 gfc_conv_expr (&cptrse, arg->expr);
3766 gfc_add_block_to_block (&se->pre, &cptrse.pre);
3767 gfc_add_block_to_block (&se->post, &cptrse.post);
3769 gfc_init_se (&fptrse, NULL);
3770 if (arg->next->expr->rank == 0)
3772 if (sym->intmod_sym_id == ISOCBINDING_F_POINTER
3773 || gfc_is_proc_ptr_comp (arg->next->expr))
3774 fptrse.want_pointer = 1;
3776 gfc_conv_expr (&fptrse, arg->next->expr);
3777 gfc_add_block_to_block (&se->pre, &fptrse.pre);
3778 gfc_add_block_to_block (&se->post, &fptrse.post);
3779 if (arg->next->expr->symtree->n.sym->attr.proc_pointer
3780 && arg->next->expr->symtree->n.sym->attr.dummy)
3781 fptrse.expr = build_fold_indirect_ref_loc (input_location,
3782 fptrse.expr);
3783 se->expr = fold_build2_loc (input_location, MODIFY_EXPR,
3784 TREE_TYPE (fptrse.expr),
3785 fptrse.expr,
3786 fold_convert (TREE_TYPE (fptrse.expr),
3787 cptrse.expr));
3788 return 1;
3791 gfc_start_block (&block);
3793 /* Get the descriptor of the Fortran pointer. */
3794 fptrse.descriptor_only = 1;
3795 gfc_conv_expr_descriptor (&fptrse, arg->next->expr);
3796 gfc_add_block_to_block (&block, &fptrse.pre);
3797 desc = fptrse.expr;
3799 /* Set data value, dtype, and offset. */
3800 tmp = GFC_TYPE_ARRAY_DATAPTR_TYPE (TREE_TYPE (desc));
3801 gfc_conv_descriptor_data_set (&block, desc,
3802 fold_convert (tmp, cptrse.expr));
3803 gfc_add_modify (&block, gfc_conv_descriptor_dtype (desc),
3804 gfc_get_dtype (TREE_TYPE (desc)));
3806 /* Start scalarization of the bounds, using the shape argument. */
3808 shape_ss = gfc_walk_expr (arg->next->next->expr);
3809 gcc_assert (shape_ss != gfc_ss_terminator);
3810 gfc_init_se (&shapese, NULL);
3812 gfc_init_loopinfo (&loop);
3813 gfc_add_ss_to_loop (&loop, shape_ss);
3814 gfc_conv_ss_startstride (&loop);
3815 gfc_conv_loop_setup (&loop, &arg->next->expr->where);
3816 gfc_mark_ss_chain_used (shape_ss, 1);
3818 gfc_copy_loopinfo_to_se (&shapese, &loop);
3819 shapese.ss = shape_ss;
3821 stride = gfc_create_var (gfc_array_index_type, "stride");
3822 offset = gfc_create_var (gfc_array_index_type, "offset");
3823 gfc_add_modify (&block, stride, gfc_index_one_node);
3824 gfc_add_modify (&block, offset, gfc_index_zero_node);
3826 /* Loop body. */
3827 gfc_start_scalarized_body (&loop, &body);
3829 dim = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
3830 loop.loopvar[0], loop.from[0]);
3832 /* Set bounds and stride. */
3833 gfc_conv_descriptor_lbound_set (&body, desc, dim, gfc_index_one_node);
3834 gfc_conv_descriptor_stride_set (&body, desc, dim, stride);
3836 gfc_conv_expr (&shapese, arg->next->next->expr);
3837 gfc_add_block_to_block (&body, &shapese.pre);
3838 gfc_conv_descriptor_ubound_set (&body, desc, dim, shapese.expr);
3839 gfc_add_block_to_block (&body, &shapese.post);
3841 /* Calculate offset. */
3842 gfc_add_modify (&body, offset,
3843 fold_build2_loc (input_location, PLUS_EXPR,
3844 gfc_array_index_type, offset, stride));
3845 /* Update stride. */
3846 gfc_add_modify (&body, stride,
3847 fold_build2_loc (input_location, MULT_EXPR,
3848 gfc_array_index_type, stride,
3849 fold_convert (gfc_array_index_type,
3850 shapese.expr)));
3851 /* Finish scalarization loop. */
3852 gfc_trans_scalarizing_loops (&loop, &body);
3853 gfc_add_block_to_block (&block, &loop.pre);
3854 gfc_add_block_to_block (&block, &loop.post);
3855 gfc_add_block_to_block (&block, &fptrse.post);
3856 gfc_cleanup_loop (&loop);
3858 gfc_add_modify (&block, offset,
3859 fold_build1_loc (input_location, NEGATE_EXPR,
3860 gfc_array_index_type, offset));
3861 gfc_conv_descriptor_offset_set (&block, desc, offset);
3863 se->expr = gfc_finish_block (&block);
3864 return 1;
3866 else if (sym->intmod_sym_id == ISOCBINDING_ASSOCIATED)
3868 gfc_se arg1se;
3869 gfc_se arg2se;
3871 /* Build the addr_expr for the first argument. The argument is
3872 already an *address* so we don't need to set want_pointer in
3873 the gfc_se. */
3874 gfc_init_se (&arg1se, NULL);
3875 gfc_conv_expr (&arg1se, arg->expr);
3876 gfc_add_block_to_block (&se->pre, &arg1se.pre);
3877 gfc_add_block_to_block (&se->post, &arg1se.post);
3879 /* See if we were given two arguments. */
3880 if (arg->next == NULL)
3881 /* Only given one arg so generate a null and do a
3882 not-equal comparison against the first arg. */
3883 se->expr = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
3884 arg1se.expr,
3885 fold_convert (TREE_TYPE (arg1se.expr),
3886 null_pointer_node));
3887 else
3889 tree eq_expr;
3890 tree not_null_expr;
3892 /* Given two arguments so build the arg2se from second arg. */
3893 gfc_init_se (&arg2se, NULL);
3894 gfc_conv_expr (&arg2se, arg->next->expr);
3895 gfc_add_block_to_block (&se->pre, &arg2se.pre);
3896 gfc_add_block_to_block (&se->post, &arg2se.post);
3898 /* Generate test to compare that the two args are equal. */
3899 eq_expr = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
3900 arg1se.expr, arg2se.expr);
3901 /* Generate test to ensure that the first arg is not null. */
3902 not_null_expr = fold_build2_loc (input_location, NE_EXPR,
3903 boolean_type_node,
3904 arg1se.expr, null_pointer_node);
3906 /* Finally, the generated test must check that both arg1 is not
3907 NULL and that it is equal to the second arg. */
3908 se->expr = fold_build2_loc (input_location, TRUTH_AND_EXPR,
3909 boolean_type_node,
3910 not_null_expr, eq_expr);
3913 return 1;
3916 /* Nothing was done. */
3917 return 0;
3921 /* Generate code for a procedure call. Note can return se->post != NULL.
3922 If se->direct_byref is set then se->expr contains the return parameter.
3923 Return nonzero, if the call has alternate specifiers.
3924 'expr' is only needed for procedure pointer components. */
3927 gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
3928 gfc_actual_arglist * args, gfc_expr * expr,
3929 vec<tree, va_gc> *append_args)
3931 gfc_interface_mapping mapping;
3932 vec<tree, va_gc> *arglist;
3933 vec<tree, va_gc> *retargs;
3934 tree tmp;
3935 tree fntype;
3936 gfc_se parmse;
3937 gfc_array_info *info;
3938 int byref;
3939 int parm_kind;
3940 tree type;
3941 tree var;
3942 tree len;
3943 tree base_object;
3944 vec<tree, va_gc> *stringargs;
3945 tree result = NULL;
3946 gfc_formal_arglist *formal;
3947 gfc_actual_arglist *arg;
3948 int has_alternate_specifier = 0;
3949 bool need_interface_mapping;
3950 bool callee_alloc;
3951 gfc_typespec ts;
3952 gfc_charlen cl;
3953 gfc_expr *e;
3954 gfc_symbol *fsym;
3955 stmtblock_t post;
3956 enum {MISSING = 0, ELEMENTAL, SCALAR, SCALAR_POINTER, ARRAY};
3957 gfc_component *comp = NULL;
3958 int arglen;
3960 arglist = NULL;
3961 retargs = NULL;
3962 stringargs = NULL;
3963 var = NULL_TREE;
3964 len = NULL_TREE;
3965 gfc_clear_ts (&ts);
3967 if (sym->from_intmod == INTMOD_ISO_C_BINDING
3968 && conv_isocbinding_procedure (se, sym, args))
3969 return 0;
3971 comp = gfc_get_proc_ptr_comp (expr);
3973 if (se->ss != NULL)
3975 if (!sym->attr.elemental && !(comp && comp->attr.elemental))
3977 gcc_assert (se->ss->info->type == GFC_SS_FUNCTION);
3978 if (se->ss->info->useflags)
3980 gcc_assert ((!comp && gfc_return_by_reference (sym)
3981 && sym->result->attr.dimension)
3982 || (comp && comp->attr.dimension));
3983 gcc_assert (se->loop != NULL);
3985 /* Access the previously obtained result. */
3986 gfc_conv_tmp_array_ref (se);
3987 return 0;
3990 info = &se->ss->info->data.array;
3992 else
3993 info = NULL;
3995 gfc_init_block (&post);
3996 gfc_init_interface_mapping (&mapping);
3997 if (!comp)
3999 formal = gfc_sym_get_dummy_args (sym);
4000 need_interface_mapping = sym->attr.dimension ||
4001 (sym->ts.type == BT_CHARACTER
4002 && sym->ts.u.cl->length
4003 && sym->ts.u.cl->length->expr_type
4004 != EXPR_CONSTANT);
4006 else
4008 formal = comp->ts.interface ? comp->ts.interface->formal : NULL;
4009 need_interface_mapping = comp->attr.dimension ||
4010 (comp->ts.type == BT_CHARACTER
4011 && comp->ts.u.cl->length
4012 && comp->ts.u.cl->length->expr_type
4013 != EXPR_CONSTANT);
4016 base_object = NULL_TREE;
4018 /* Evaluate the arguments. */
4019 for (arg = args; arg != NULL;
4020 arg = arg->next, formal = formal ? formal->next : NULL)
4022 e = arg->expr;
4023 fsym = formal ? formal->sym : NULL;
4024 parm_kind = MISSING;
4026 /* Class array expressions are sometimes coming completely unadorned
4027 with either arrayspec or _data component. Correct that here.
4028 OOP-TODO: Move this to the frontend. */
4029 if (e && e->expr_type == EXPR_VARIABLE
4030 && !e->ref
4031 && e->ts.type == BT_CLASS
4032 && (CLASS_DATA (e)->attr.codimension
4033 || CLASS_DATA (e)->attr.dimension))
4035 gfc_typespec temp_ts = e->ts;
4036 gfc_add_class_array_ref (e);
4037 e->ts = temp_ts;
4040 if (e == NULL)
4042 if (se->ignore_optional)
4044 /* Some intrinsics have already been resolved to the correct
4045 parameters. */
4046 continue;
4048 else if (arg->label)
4050 has_alternate_specifier = 1;
4051 continue;
4053 else
4055 /* Pass a NULL pointer for an absent arg. */
4056 gfc_init_se (&parmse, NULL);
4057 parmse.expr = null_pointer_node;
4058 if (arg->missing_arg_type == BT_CHARACTER)
4059 parmse.string_length = build_int_cst (gfc_charlen_type_node, 0);
4062 else if (arg->expr->expr_type == EXPR_NULL
4063 && fsym && !fsym->attr.pointer
4064 && (fsym->ts.type != BT_CLASS
4065 || !CLASS_DATA (fsym)->attr.class_pointer))
4067 /* Pass a NULL pointer to denote an absent arg. */
4068 gcc_assert (fsym->attr.optional && !fsym->attr.allocatable
4069 && (fsym->ts.type != BT_CLASS
4070 || !CLASS_DATA (fsym)->attr.allocatable));
4071 gfc_init_se (&parmse, NULL);
4072 parmse.expr = null_pointer_node;
4073 if (arg->missing_arg_type == BT_CHARACTER)
4074 parmse.string_length = build_int_cst (gfc_charlen_type_node, 0);
4076 else if (fsym && fsym->ts.type == BT_CLASS
4077 && e->ts.type == BT_DERIVED)
4079 /* The derived type needs to be converted to a temporary
4080 CLASS object. */
4081 gfc_init_se (&parmse, se);
4082 gfc_conv_derived_to_class (&parmse, e, fsym->ts, NULL,
4083 fsym->attr.optional
4084 && e->expr_type == EXPR_VARIABLE
4085 && e->symtree->n.sym->attr.optional,
4086 CLASS_DATA (fsym)->attr.class_pointer
4087 || CLASS_DATA (fsym)->attr.allocatable);
4089 else if (UNLIMITED_POLY (fsym) && e->ts.type != BT_CLASS)
4091 /* The intrinsic type needs to be converted to a temporary
4092 CLASS object for the unlimited polymorphic formal. */
4093 gfc_init_se (&parmse, se);
4094 gfc_conv_intrinsic_to_class (&parmse, e, fsym->ts);
4096 else if (se->ss && se->ss->info->useflags)
4098 gfc_ss *ss;
4100 ss = se->ss;
4102 /* An elemental function inside a scalarized loop. */
4103 gfc_init_se (&parmse, se);
4104 parm_kind = ELEMENTAL;
4106 if (ss->dimen > 0 && e->expr_type == EXPR_VARIABLE
4107 && ss->info->data.array.ref == NULL)
4109 gfc_conv_tmp_array_ref (&parmse);
4110 if (e->ts.type == BT_CHARACTER)
4111 gfc_conv_string_parameter (&parmse);
4112 else
4113 parmse.expr = gfc_build_addr_expr (NULL_TREE, parmse.expr);
4115 else
4117 gfc_conv_expr_reference (&parmse, e);
4118 if (e->ts.type == BT_CHARACTER && !e->rank
4119 && e->expr_type == EXPR_FUNCTION)
4120 parmse.expr = build_fold_indirect_ref_loc (input_location,
4121 parmse.expr);
4124 if (fsym && fsym->ts.type == BT_DERIVED
4125 && gfc_is_class_container_ref (e))
4127 parmse.expr = gfc_class_data_get (parmse.expr);
4129 if (fsym->attr.optional && e->expr_type == EXPR_VARIABLE
4130 && e->symtree->n.sym->attr.optional)
4132 tree cond = gfc_conv_expr_present (e->symtree->n.sym);
4133 parmse.expr = build3_loc (input_location, COND_EXPR,
4134 TREE_TYPE (parmse.expr),
4135 cond, parmse.expr,
4136 fold_convert (TREE_TYPE (parmse.expr),
4137 null_pointer_node));
4141 /* If we are passing an absent array as optional dummy to an
4142 elemental procedure, make sure that we pass NULL when the data
4143 pointer is NULL. We need this extra conditional because of
4144 scalarization which passes arrays elements to the procedure,
4145 ignoring the fact that the array can be absent/unallocated/... */
4146 if (ss->info->can_be_null_ref && ss->info->type != GFC_SS_REFERENCE)
4148 tree descriptor_data;
4150 descriptor_data = ss->info->data.array.data;
4151 tmp = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
4152 descriptor_data,
4153 fold_convert (TREE_TYPE (descriptor_data),
4154 null_pointer_node));
4155 parmse.expr
4156 = fold_build3_loc (input_location, COND_EXPR,
4157 TREE_TYPE (parmse.expr),
4158 gfc_unlikely (tmp),
4159 fold_convert (TREE_TYPE (parmse.expr),
4160 null_pointer_node),
4161 parmse.expr);
4164 /* The scalarizer does not repackage the reference to a class
4165 array - instead it returns a pointer to the data element. */
4166 if (fsym && fsym->ts.type == BT_CLASS && e->ts.type == BT_CLASS)
4167 gfc_conv_class_to_class (&parmse, e, fsym->ts, true,
4168 fsym->attr.intent != INTENT_IN
4169 && (CLASS_DATA (fsym)->attr.class_pointer
4170 || CLASS_DATA (fsym)->attr.allocatable),
4171 fsym->attr.optional
4172 && e->expr_type == EXPR_VARIABLE
4173 && e->symtree->n.sym->attr.optional,
4174 CLASS_DATA (fsym)->attr.class_pointer
4175 || CLASS_DATA (fsym)->attr.allocatable);
4177 else
4179 bool scalar;
4180 gfc_ss *argss;
4182 gfc_init_se (&parmse, NULL);
4184 /* Check whether the expression is a scalar or not; we cannot use
4185 e->rank as it can be nonzero for functions arguments. */
4186 argss = gfc_walk_expr (e);
4187 scalar = argss == gfc_ss_terminator;
4188 if (!scalar)
4189 gfc_free_ss_chain (argss);
4191 /* Special handling for passing scalar polymorphic coarrays;
4192 otherwise one passes "class->_data.data" instead of "&class". */
4193 if (e->rank == 0 && e->ts.type == BT_CLASS
4194 && fsym && fsym->ts.type == BT_CLASS
4195 && CLASS_DATA (fsym)->attr.codimension
4196 && !CLASS_DATA (fsym)->attr.dimension)
4198 gfc_add_class_array_ref (e);
4199 parmse.want_coarray = 1;
4200 scalar = false;
4203 /* A scalar or transformational function. */
4204 if (scalar)
4206 if (e->expr_type == EXPR_VARIABLE
4207 && e->symtree->n.sym->attr.cray_pointee
4208 && fsym && fsym->attr.flavor == FL_PROCEDURE)
4210 /* The Cray pointer needs to be converted to a pointer to
4211 a type given by the expression. */
4212 gfc_conv_expr (&parmse, e);
4213 type = build_pointer_type (TREE_TYPE (parmse.expr));
4214 tmp = gfc_get_symbol_decl (e->symtree->n.sym->cp_pointer);
4215 parmse.expr = convert (type, tmp);
4217 else if (fsym && fsym->attr.value)
4219 if (fsym->ts.type == BT_CHARACTER
4220 && fsym->ts.is_c_interop
4221 && fsym->ns->proc_name != NULL
4222 && fsym->ns->proc_name->attr.is_bind_c)
4224 parmse.expr = NULL;
4225 gfc_conv_scalar_char_value (fsym, &parmse, &e);
4226 if (parmse.expr == NULL)
4227 gfc_conv_expr (&parmse, e);
4229 else
4230 gfc_conv_expr (&parmse, e);
4232 else if (arg->name && arg->name[0] == '%')
4233 /* Argument list functions %VAL, %LOC and %REF are signalled
4234 through arg->name. */
4235 conv_arglist_function (&parmse, arg->expr, arg->name);
4236 else if ((e->expr_type == EXPR_FUNCTION)
4237 && ((e->value.function.esym
4238 && e->value.function.esym->result->attr.pointer)
4239 || (!e->value.function.esym
4240 && e->symtree->n.sym->attr.pointer))
4241 && fsym && fsym->attr.target)
4243 gfc_conv_expr (&parmse, e);
4244 parmse.expr = gfc_build_addr_expr (NULL_TREE, parmse.expr);
4246 else if (e->expr_type == EXPR_FUNCTION
4247 && e->symtree->n.sym->result
4248 && e->symtree->n.sym->result != e->symtree->n.sym
4249 && e->symtree->n.sym->result->attr.proc_pointer)
4251 /* Functions returning procedure pointers. */
4252 gfc_conv_expr (&parmse, e);
4253 if (fsym && fsym->attr.proc_pointer)
4254 parmse.expr = gfc_build_addr_expr (NULL_TREE, parmse.expr);
4256 else
4258 if (e->ts.type == BT_CLASS && fsym
4259 && fsym->ts.type == BT_CLASS
4260 && (!CLASS_DATA (fsym)->as
4261 || CLASS_DATA (fsym)->as->type != AS_ASSUMED_RANK)
4262 && CLASS_DATA (e)->attr.codimension)
4264 gcc_assert (!CLASS_DATA (fsym)->attr.codimension);
4265 gcc_assert (!CLASS_DATA (fsym)->as);
4266 gfc_add_class_array_ref (e);
4267 parmse.want_coarray = 1;
4268 gfc_conv_expr_reference (&parmse, e);
4269 class_scalar_coarray_to_class (&parmse, e, fsym->ts,
4270 fsym->attr.optional
4271 && e->expr_type == EXPR_VARIABLE);
4273 else
4274 gfc_conv_expr_reference (&parmse, e);
4276 /* Catch base objects that are not variables. */
4277 if (e->ts.type == BT_CLASS
4278 && e->expr_type != EXPR_VARIABLE
4279 && expr && e == expr->base_expr)
4280 base_object = build_fold_indirect_ref_loc (input_location,
4281 parmse.expr);
4283 /* A class array element needs converting back to be a
4284 class object, if the formal argument is a class object. */
4285 if (fsym && fsym->ts.type == BT_CLASS
4286 && e->ts.type == BT_CLASS
4287 && ((CLASS_DATA (fsym)->as
4288 && CLASS_DATA (fsym)->as->type == AS_ASSUMED_RANK)
4289 || CLASS_DATA (e)->attr.dimension))
4290 gfc_conv_class_to_class (&parmse, e, fsym->ts, false,
4291 fsym->attr.intent != INTENT_IN
4292 && (CLASS_DATA (fsym)->attr.class_pointer
4293 || CLASS_DATA (fsym)->attr.allocatable),
4294 fsym->attr.optional
4295 && e->expr_type == EXPR_VARIABLE
4296 && e->symtree->n.sym->attr.optional,
4297 CLASS_DATA (fsym)->attr.class_pointer
4298 || CLASS_DATA (fsym)->attr.allocatable);
4300 /* If an ALLOCATABLE dummy argument has INTENT(OUT) and is
4301 allocated on entry, it must be deallocated. */
4302 if (fsym && fsym->attr.intent == INTENT_OUT
4303 && (fsym->attr.allocatable
4304 || (fsym->ts.type == BT_CLASS
4305 && CLASS_DATA (fsym)->attr.allocatable)))
4307 stmtblock_t block;
4308 tree ptr;
4310 gfc_init_block (&block);
4311 ptr = parmse.expr;
4312 if (e->ts.type == BT_CLASS)
4313 ptr = gfc_class_data_get (ptr);
4315 tmp = gfc_deallocate_with_status (ptr, NULL_TREE,
4316 NULL_TREE, NULL_TREE,
4317 NULL_TREE, true, NULL,
4318 false);
4319 gfc_add_expr_to_block (&block, tmp);
4320 tmp = fold_build2_loc (input_location, MODIFY_EXPR,
4321 void_type_node, ptr,
4322 null_pointer_node);
4323 gfc_add_expr_to_block (&block, tmp);
4325 if (fsym->ts.type == BT_CLASS && UNLIMITED_POLY (fsym))
4327 gfc_add_modify (&block, ptr,
4328 fold_convert (TREE_TYPE (ptr),
4329 null_pointer_node));
4330 gfc_add_expr_to_block (&block, tmp);
4332 else if (fsym->ts.type == BT_CLASS)
4334 gfc_symbol *vtab;
4335 vtab = gfc_find_derived_vtab (fsym->ts.u.derived);
4336 tmp = gfc_get_symbol_decl (vtab);
4337 tmp = gfc_build_addr_expr (NULL_TREE, tmp);
4338 ptr = gfc_class_vptr_get (parmse.expr);
4339 gfc_add_modify (&block, ptr,
4340 fold_convert (TREE_TYPE (ptr), tmp));
4341 gfc_add_expr_to_block (&block, tmp);
4344 if (fsym->attr.optional
4345 && e->expr_type == EXPR_VARIABLE
4346 && e->symtree->n.sym->attr.optional)
4348 tmp = fold_build3_loc (input_location, COND_EXPR,
4349 void_type_node,
4350 gfc_conv_expr_present (e->symtree->n.sym),
4351 gfc_finish_block (&block),
4352 build_empty_stmt (input_location));
4354 else
4355 tmp = gfc_finish_block (&block);
4357 gfc_add_expr_to_block (&se->pre, tmp);
4360 if (fsym && (fsym->ts.type == BT_DERIVED
4361 || fsym->ts.type == BT_ASSUMED)
4362 && e->ts.type == BT_CLASS
4363 && !CLASS_DATA (e)->attr.dimension
4364 && !CLASS_DATA (e)->attr.codimension)
4365 parmse.expr = gfc_class_data_get (parmse.expr);
4367 /* Wrap scalar variable in a descriptor. We need to convert
4368 the address of a pointer back to the pointer itself before,
4369 we can assign it to the data field. */
4371 if (fsym && fsym->as && fsym->as->type == AS_ASSUMED_RANK
4372 && fsym->ts.type != BT_CLASS && e->expr_type != EXPR_NULL)
4374 tmp = parmse.expr;
4375 if (TREE_CODE (tmp) == ADDR_EXPR
4376 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (tmp, 0))))
4377 tmp = TREE_OPERAND (tmp, 0);
4378 parmse.expr = gfc_conv_scalar_to_descriptor (&parmse, tmp,
4379 fsym->attr);
4380 parmse.expr = gfc_build_addr_expr (NULL_TREE,
4381 parmse.expr);
4383 else if (fsym && e->expr_type != EXPR_NULL
4384 && ((fsym->attr.pointer
4385 && fsym->attr.flavor != FL_PROCEDURE)
4386 || (fsym->attr.proc_pointer
4387 && !(e->expr_type == EXPR_VARIABLE
4388 && e->symtree->n.sym->attr.dummy))
4389 || (fsym->attr.proc_pointer
4390 && e->expr_type == EXPR_VARIABLE
4391 && gfc_is_proc_ptr_comp (e))
4392 || (fsym->attr.allocatable
4393 && fsym->attr.flavor != FL_PROCEDURE)))
4395 /* Scalar pointer dummy args require an extra level of
4396 indirection. The null pointer already contains
4397 this level of indirection. */
4398 parm_kind = SCALAR_POINTER;
4399 parmse.expr = gfc_build_addr_expr (NULL_TREE, parmse.expr);
4403 else if (e->ts.type == BT_CLASS
4404 && fsym && fsym->ts.type == BT_CLASS
4405 && (CLASS_DATA (fsym)->attr.dimension
4406 || CLASS_DATA (fsym)->attr.codimension))
4408 /* Pass a class array. */
4409 gfc_conv_expr_descriptor (&parmse, e);
4410 /* The conversion does not repackage the reference to a class
4411 array - _data descriptor. */
4412 gfc_conv_class_to_class (&parmse, e, fsym->ts, false,
4413 fsym->attr.intent != INTENT_IN
4414 && (CLASS_DATA (fsym)->attr.class_pointer
4415 || CLASS_DATA (fsym)->attr.allocatable),
4416 fsym->attr.optional
4417 && e->expr_type == EXPR_VARIABLE
4418 && e->symtree->n.sym->attr.optional,
4419 CLASS_DATA (fsym)->attr.class_pointer
4420 || CLASS_DATA (fsym)->attr.allocatable);
4422 else
4424 /* If the procedure requires an explicit interface, the actual
4425 argument is passed according to the corresponding formal
4426 argument. If the corresponding formal argument is a POINTER,
4427 ALLOCATABLE or assumed shape, we do not use g77's calling
4428 convention, and pass the address of the array descriptor
4429 instead. Otherwise we use g77's calling convention. */
4430 bool f;
4431 f = (fsym != NULL)
4432 && !(fsym->attr.pointer || fsym->attr.allocatable)
4433 && fsym->as && fsym->as->type != AS_ASSUMED_SHAPE
4434 && fsym->as->type != AS_ASSUMED_RANK;
4435 if (comp)
4436 f = f || !comp->attr.always_explicit;
4437 else
4438 f = f || !sym->attr.always_explicit;
4440 /* If the argument is a function call that may not create
4441 a temporary for the result, we have to check that we
4442 can do it, i.e. that there is no alias between this
4443 argument and another one. */
4444 if (gfc_get_noncopying_intrinsic_argument (e) != NULL)
4446 gfc_expr *iarg;
4447 sym_intent intent;
4449 if (fsym != NULL)
4450 intent = fsym->attr.intent;
4451 else
4452 intent = INTENT_UNKNOWN;
4454 if (gfc_check_fncall_dependency (e, intent, sym, args,
4455 NOT_ELEMENTAL))
4456 parmse.force_tmp = 1;
4458 iarg = e->value.function.actual->expr;
4460 /* Temporary needed if aliasing due to host association. */
4461 if (sym->attr.contained
4462 && !sym->attr.pure
4463 && !sym->attr.implicit_pure
4464 && !sym->attr.use_assoc
4465 && iarg->expr_type == EXPR_VARIABLE
4466 && sym->ns == iarg->symtree->n.sym->ns)
4467 parmse.force_tmp = 1;
4469 /* Ditto within module. */
4470 if (sym->attr.use_assoc
4471 && !sym->attr.pure
4472 && !sym->attr.implicit_pure
4473 && iarg->expr_type == EXPR_VARIABLE
4474 && sym->module == iarg->symtree->n.sym->module)
4475 parmse.force_tmp = 1;
4478 if (e->expr_type == EXPR_VARIABLE
4479 && is_subref_array (e))
4480 /* The actual argument is a component reference to an
4481 array of derived types. In this case, the argument
4482 is converted to a temporary, which is passed and then
4483 written back after the procedure call. */
4484 gfc_conv_subref_array_arg (&parmse, e, f,
4485 fsym ? fsym->attr.intent : INTENT_INOUT,
4486 fsym && fsym->attr.pointer);
4487 else if (gfc_is_class_array_ref (e, NULL)
4488 && fsym && fsym->ts.type == BT_DERIVED)
4489 /* The actual argument is a component reference to an
4490 array of derived types. In this case, the argument
4491 is converted to a temporary, which is passed and then
4492 written back after the procedure call.
4493 OOP-TODO: Insert code so that if the dynamic type is
4494 the same as the declared type, copy-in/copy-out does
4495 not occur. */
4496 gfc_conv_subref_array_arg (&parmse, e, f,
4497 fsym ? fsym->attr.intent : INTENT_INOUT,
4498 fsym && fsym->attr.pointer);
4499 else
4500 gfc_conv_array_parameter (&parmse, e, f, fsym, sym->name, NULL);
4502 /* If an ALLOCATABLE dummy argument has INTENT(OUT) and is
4503 allocated on entry, it must be deallocated. */
4504 if (fsym && fsym->attr.allocatable
4505 && fsym->attr.intent == INTENT_OUT)
4507 tmp = build_fold_indirect_ref_loc (input_location,
4508 parmse.expr);
4509 tmp = gfc_trans_dealloc_allocated (tmp, false);
4510 if (fsym->attr.optional
4511 && e->expr_type == EXPR_VARIABLE
4512 && e->symtree->n.sym->attr.optional)
4513 tmp = fold_build3_loc (input_location, COND_EXPR,
4514 void_type_node,
4515 gfc_conv_expr_present (e->symtree->n.sym),
4516 tmp, build_empty_stmt (input_location));
4517 gfc_add_expr_to_block (&se->pre, tmp);
4522 /* The case with fsym->attr.optional is that of a user subroutine
4523 with an interface indicating an optional argument. When we call
4524 an intrinsic subroutine, however, fsym is NULL, but we might still
4525 have an optional argument, so we proceed to the substitution
4526 just in case. */
4527 if (e && (fsym == NULL || fsym->attr.optional))
4529 /* If an optional argument is itself an optional dummy argument,
4530 check its presence and substitute a null if absent. This is
4531 only needed when passing an array to an elemental procedure
4532 as then array elements are accessed - or no NULL pointer is
4533 allowed and a "1" or "0" should be passed if not present.
4534 When passing a non-array-descriptor full array to a
4535 non-array-descriptor dummy, no check is needed. For
4536 array-descriptor actual to array-descriptor dummy, see
4537 PR 41911 for why a check has to be inserted.
4538 fsym == NULL is checked as intrinsics required the descriptor
4539 but do not always set fsym. */
4540 if (e->expr_type == EXPR_VARIABLE
4541 && e->symtree->n.sym->attr.optional
4542 && ((e->rank != 0 && sym->attr.elemental)
4543 || e->representation.length || e->ts.type == BT_CHARACTER
4544 || (e->rank != 0
4545 && (fsym == NULL
4546 || (fsym-> as
4547 && (fsym->as->type == AS_ASSUMED_SHAPE
4548 || fsym->as->type == AS_ASSUMED_RANK
4549 || fsym->as->type == AS_DEFERRED))))))
4550 gfc_conv_missing_dummy (&parmse, e, fsym ? fsym->ts : e->ts,
4551 e->representation.length);
4554 if (fsym && e)
4556 /* Obtain the character length of an assumed character length
4557 length procedure from the typespec. */
4558 if (fsym->ts.type == BT_CHARACTER
4559 && parmse.string_length == NULL_TREE
4560 && e->ts.type == BT_PROCEDURE
4561 && e->symtree->n.sym->ts.type == BT_CHARACTER
4562 && e->symtree->n.sym->ts.u.cl->length != NULL
4563 && e->symtree->n.sym->ts.u.cl->length->expr_type == EXPR_CONSTANT)
4565 gfc_conv_const_charlen (e->symtree->n.sym->ts.u.cl);
4566 parmse.string_length = e->symtree->n.sym->ts.u.cl->backend_decl;
4570 if (fsym && need_interface_mapping && e)
4571 gfc_add_interface_mapping (&mapping, fsym, &parmse, e);
4573 gfc_add_block_to_block (&se->pre, &parmse.pre);
4574 gfc_add_block_to_block (&post, &parmse.post);
4576 /* Allocated allocatable components of derived types must be
4577 deallocated for non-variable scalars. Non-variable arrays are
4578 dealt with in trans-array.c(gfc_conv_array_parameter). */
4579 if (e && (e->ts.type == BT_DERIVED || e->ts.type == BT_CLASS)
4580 && e->ts.u.derived->attr.alloc_comp
4581 && !(e->symtree && e->symtree->n.sym->attr.pointer)
4582 && (e->expr_type != EXPR_VARIABLE && !e->rank))
4584 int parm_rank;
4585 tmp = build_fold_indirect_ref_loc (input_location,
4586 parmse.expr);
4587 parm_rank = e->rank;
4588 switch (parm_kind)
4590 case (ELEMENTAL):
4591 case (SCALAR):
4592 parm_rank = 0;
4593 break;
4595 case (SCALAR_POINTER):
4596 tmp = build_fold_indirect_ref_loc (input_location,
4597 tmp);
4598 break;
4601 if (e->expr_type == EXPR_OP
4602 && e->value.op.op == INTRINSIC_PARENTHESES
4603 && e->value.op.op1->expr_type == EXPR_VARIABLE)
4605 tree local_tmp;
4606 local_tmp = gfc_evaluate_now (tmp, &se->pre);
4607 local_tmp = gfc_copy_alloc_comp (e->ts.u.derived, local_tmp, tmp, parm_rank);
4608 gfc_add_expr_to_block (&se->post, local_tmp);
4611 if (e->ts.type == BT_DERIVED && fsym && fsym->ts.type == BT_CLASS)
4613 /* The derived type is passed to gfc_deallocate_alloc_comp.
4614 Therefore, class actuals can handled correctly but derived
4615 types passed to class formals need the _data component. */
4616 tmp = gfc_class_data_get (tmp);
4617 if (!CLASS_DATA (fsym)->attr.dimension)
4618 tmp = build_fold_indirect_ref_loc (input_location, tmp);
4621 tmp = gfc_deallocate_alloc_comp (e->ts.u.derived, tmp, parm_rank);
4623 gfc_add_expr_to_block (&se->post, tmp);
4626 /* Add argument checking of passing an unallocated/NULL actual to
4627 a nonallocatable/nonpointer dummy. */
4629 if (gfc_option.rtcheck & GFC_RTCHECK_POINTER && e != NULL)
4631 symbol_attribute attr;
4632 char *msg;
4633 tree cond;
4635 if (e->expr_type == EXPR_VARIABLE || e->expr_type == EXPR_FUNCTION)
4636 attr = gfc_expr_attr (e);
4637 else
4638 goto end_pointer_check;
4640 /* In Fortran 2008 it's allowed to pass a NULL pointer/nonallocated
4641 allocatable to an optional dummy, cf. 12.5.2.12. */
4642 if (fsym != NULL && fsym->attr.optional && !attr.proc_pointer
4643 && (gfc_option.allow_std & GFC_STD_F2008) != 0)
4644 goto end_pointer_check;
4646 if (attr.optional)
4648 /* If the actual argument is an optional pointer/allocatable and
4649 the formal argument takes an nonpointer optional value,
4650 it is invalid to pass a non-present argument on, even
4651 though there is no technical reason for this in gfortran.
4652 See Fortran 2003, Section 12.4.1.6 item (7)+(8). */
4653 tree present, null_ptr, type;
4655 if (attr.allocatable
4656 && (fsym == NULL || !fsym->attr.allocatable))
4657 asprintf (&msg, "Allocatable actual argument '%s' is not "
4658 "allocated or not present", e->symtree->n.sym->name);
4659 else if (attr.pointer
4660 && (fsym == NULL || !fsym->attr.pointer))
4661 asprintf (&msg, "Pointer actual argument '%s' is not "
4662 "associated or not present",
4663 e->symtree->n.sym->name);
4664 else if (attr.proc_pointer
4665 && (fsym == NULL || !fsym->attr.proc_pointer))
4666 asprintf (&msg, "Proc-pointer actual argument '%s' is not "
4667 "associated or not present",
4668 e->symtree->n.sym->name);
4669 else
4670 goto end_pointer_check;
4672 present = gfc_conv_expr_present (e->symtree->n.sym);
4673 type = TREE_TYPE (present);
4674 present = fold_build2_loc (input_location, EQ_EXPR,
4675 boolean_type_node, present,
4676 fold_convert (type,
4677 null_pointer_node));
4678 type = TREE_TYPE (parmse.expr);
4679 null_ptr = fold_build2_loc (input_location, EQ_EXPR,
4680 boolean_type_node, parmse.expr,
4681 fold_convert (type,
4682 null_pointer_node));
4683 cond = fold_build2_loc (input_location, TRUTH_ORIF_EXPR,
4684 boolean_type_node, present, null_ptr);
4686 else
4688 if (attr.allocatable
4689 && (fsym == NULL || !fsym->attr.allocatable))
4690 asprintf (&msg, "Allocatable actual argument '%s' is not "
4691 "allocated", e->symtree->n.sym->name);
4692 else if (attr.pointer
4693 && (fsym == NULL || !fsym->attr.pointer))
4694 asprintf (&msg, "Pointer actual argument '%s' is not "
4695 "associated", e->symtree->n.sym->name);
4696 else if (attr.proc_pointer
4697 && (fsym == NULL || !fsym->attr.proc_pointer))
4698 asprintf (&msg, "Proc-pointer actual argument '%s' is not "
4699 "associated", e->symtree->n.sym->name);
4700 else
4701 goto end_pointer_check;
4703 tmp = parmse.expr;
4705 /* If the argument is passed by value, we need to strip the
4706 INDIRECT_REF. */
4707 if (!POINTER_TYPE_P (TREE_TYPE (parmse.expr)))
4708 tmp = gfc_build_addr_expr (NULL_TREE, tmp);
4710 cond = fold_build2_loc (input_location, EQ_EXPR,
4711 boolean_type_node, tmp,
4712 fold_convert (TREE_TYPE (tmp),
4713 null_pointer_node));
4716 gfc_trans_runtime_check (true, false, cond, &se->pre, &e->where,
4717 msg);
4718 free (msg);
4720 end_pointer_check:
4722 /* Deferred length dummies pass the character length by reference
4723 so that the value can be returned. */
4724 if (parmse.string_length && fsym && fsym->ts.deferred)
4726 tmp = parmse.string_length;
4727 if (TREE_CODE (tmp) != VAR_DECL)
4728 tmp = gfc_evaluate_now (parmse.string_length, &se->pre);
4729 parmse.string_length = gfc_build_addr_expr (NULL_TREE, tmp);
4732 /* Character strings are passed as two parameters, a length and a
4733 pointer - except for Bind(c) which only passes the pointer.
4734 An unlimited polymorphic formal argument likewise does not
4735 need the length. */
4736 if (parmse.string_length != NULL_TREE
4737 && !sym->attr.is_bind_c
4738 && !(fsym && UNLIMITED_POLY (fsym)))
4739 vec_safe_push (stringargs, parmse.string_length);
4741 /* When calling __copy for character expressions to unlimited
4742 polymorphic entities, the dst argument needs a string length. */
4743 if (sym->name[0] == '_' && e && e->ts.type == BT_CHARACTER
4744 && strncmp (sym->name, "__vtab_CHARACTER", 16) == 0
4745 && arg->next && arg->next->expr
4746 && arg->next->expr->ts.type == BT_DERIVED
4747 && arg->next->expr->ts.u.derived->attr.unlimited_polymorphic)
4748 vec_safe_push (stringargs, parmse.string_length);
4750 /* For descriptorless coarrays and assumed-shape coarray dummies, we
4751 pass the token and the offset as additional arguments. */
4752 if (fsym && fsym->attr.codimension
4753 && gfc_option.coarray == GFC_FCOARRAY_LIB
4754 && !fsym->attr.allocatable
4755 && e == NULL)
4757 /* Token and offset. */
4758 vec_safe_push (stringargs, null_pointer_node);
4759 vec_safe_push (stringargs, build_int_cst (gfc_array_index_type, 0));
4760 gcc_assert (fsym->attr.optional);
4762 else if (fsym && fsym->attr.codimension
4763 && !fsym->attr.allocatable
4764 && gfc_option.coarray == GFC_FCOARRAY_LIB)
4766 tree caf_decl, caf_type;
4767 tree offset, tmp2;
4769 caf_decl = get_tree_for_caf_expr (e);
4770 caf_type = TREE_TYPE (caf_decl);
4772 if (GFC_DESCRIPTOR_TYPE_P (caf_type)
4773 && GFC_TYPE_ARRAY_AKIND (caf_type) == GFC_ARRAY_ALLOCATABLE)
4774 tmp = gfc_conv_descriptor_token (caf_decl);
4775 else if (DECL_LANG_SPECIFIC (caf_decl)
4776 && GFC_DECL_TOKEN (caf_decl) != NULL_TREE)
4777 tmp = GFC_DECL_TOKEN (caf_decl);
4778 else
4780 gcc_assert (GFC_ARRAY_TYPE_P (caf_type)
4781 && GFC_TYPE_ARRAY_CAF_TOKEN (caf_type) != NULL_TREE);
4782 tmp = GFC_TYPE_ARRAY_CAF_TOKEN (caf_type);
4785 vec_safe_push (stringargs, tmp);
4787 if (GFC_DESCRIPTOR_TYPE_P (caf_type)
4788 && GFC_TYPE_ARRAY_AKIND (caf_type) == GFC_ARRAY_ALLOCATABLE)
4789 offset = build_int_cst (gfc_array_index_type, 0);
4790 else if (DECL_LANG_SPECIFIC (caf_decl)
4791 && GFC_DECL_CAF_OFFSET (caf_decl) != NULL_TREE)
4792 offset = GFC_DECL_CAF_OFFSET (caf_decl);
4793 else if (GFC_TYPE_ARRAY_CAF_OFFSET (caf_type) != NULL_TREE)
4794 offset = GFC_TYPE_ARRAY_CAF_OFFSET (caf_type);
4795 else
4796 offset = build_int_cst (gfc_array_index_type, 0);
4798 if (GFC_DESCRIPTOR_TYPE_P (caf_type))
4799 tmp = gfc_conv_descriptor_data_get (caf_decl);
4800 else
4802 gcc_assert (POINTER_TYPE_P (caf_type));
4803 tmp = caf_decl;
4806 if (fsym->as->type == AS_ASSUMED_SHAPE
4807 || (fsym->as->type == AS_ASSUMED_RANK && !fsym->attr.pointer
4808 && !fsym->attr.allocatable))
4810 gcc_assert (POINTER_TYPE_P (TREE_TYPE (parmse.expr)));
4811 gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE
4812 (TREE_TYPE (parmse.expr))));
4813 tmp2 = build_fold_indirect_ref_loc (input_location, parmse.expr);
4814 tmp2 = gfc_conv_descriptor_data_get (tmp2);
4816 else if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (parmse.expr)))
4817 tmp2 = gfc_conv_descriptor_data_get (parmse.expr);
4818 else
4820 gcc_assert (POINTER_TYPE_P (TREE_TYPE (parmse.expr)));
4821 tmp2 = parmse.expr;
4824 tmp = fold_build2_loc (input_location, MINUS_EXPR,
4825 gfc_array_index_type,
4826 fold_convert (gfc_array_index_type, tmp2),
4827 fold_convert (gfc_array_index_type, tmp));
4828 offset = fold_build2_loc (input_location, PLUS_EXPR,
4829 gfc_array_index_type, offset, tmp);
4831 vec_safe_push (stringargs, offset);
4834 vec_safe_push (arglist, parmse.expr);
4836 gfc_finish_interface_mapping (&mapping, &se->pre, &se->post);
4838 if (comp)
4839 ts = comp->ts;
4840 else
4841 ts = sym->ts;
4843 if (ts.type == BT_CHARACTER && sym->attr.is_bind_c)
4844 se->string_length = build_int_cst (gfc_charlen_type_node, 1);
4845 else if (ts.type == BT_CHARACTER)
4847 if (ts.u.cl->length == NULL)
4849 /* Assumed character length results are not allowed by 5.1.1.5 of the
4850 standard and are trapped in resolve.c; except in the case of SPREAD
4851 (and other intrinsics?) and dummy functions. In the case of SPREAD,
4852 we take the character length of the first argument for the result.
4853 For dummies, we have to look through the formal argument list for
4854 this function and use the character length found there.*/
4855 if (ts.deferred)
4856 cl.backend_decl = gfc_create_var (gfc_charlen_type_node, "slen");
4857 else if (!sym->attr.dummy)
4858 cl.backend_decl = (*stringargs)[0];
4859 else
4861 formal = gfc_sym_get_dummy_args (sym->ns->proc_name);
4862 for (; formal; formal = formal->next)
4863 if (strcmp (formal->sym->name, sym->name) == 0)
4864 cl.backend_decl = formal->sym->ts.u.cl->backend_decl;
4866 len = cl.backend_decl;
4868 else
4870 tree tmp;
4872 /* Calculate the length of the returned string. */
4873 gfc_init_se (&parmse, NULL);
4874 if (need_interface_mapping)
4875 gfc_apply_interface_mapping (&mapping, &parmse, ts.u.cl->length);
4876 else
4877 gfc_conv_expr (&parmse, ts.u.cl->length);
4878 gfc_add_block_to_block (&se->pre, &parmse.pre);
4879 gfc_add_block_to_block (&se->post, &parmse.post);
4881 tmp = fold_convert (gfc_charlen_type_node, parmse.expr);
4882 tmp = fold_build2_loc (input_location, MAX_EXPR,
4883 gfc_charlen_type_node, tmp,
4884 build_int_cst (gfc_charlen_type_node, 0));
4885 cl.backend_decl = tmp;
4888 /* Set up a charlen structure for it. */
4889 cl.next = NULL;
4890 cl.length = NULL;
4891 ts.u.cl = &cl;
4893 len = cl.backend_decl;
4896 byref = (comp && (comp->attr.dimension || comp->ts.type == BT_CHARACTER))
4897 || (!comp && gfc_return_by_reference (sym));
4898 if (byref)
4900 if (se->direct_byref)
4902 /* Sometimes, too much indirection can be applied; e.g. for
4903 function_result = array_valued_recursive_function. */
4904 if (TREE_TYPE (TREE_TYPE (se->expr))
4905 && TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr)))
4906 && GFC_DESCRIPTOR_TYPE_P
4907 (TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr)))))
4908 se->expr = build_fold_indirect_ref_loc (input_location,
4909 se->expr);
4911 /* If the lhs of an assignment x = f(..) is allocatable and
4912 f2003 is allowed, we must do the automatic reallocation.
4913 TODO - deal with intrinsics, without using a temporary. */
4914 if (gfc_option.flag_realloc_lhs
4915 && se->ss && se->ss->loop_chain
4916 && se->ss->loop_chain->is_alloc_lhs
4917 && !expr->value.function.isym
4918 && sym->result->as != NULL)
4920 /* Evaluate the bounds of the result, if known. */
4921 gfc_set_loop_bounds_from_array_spec (&mapping, se,
4922 sym->result->as);
4924 /* Perform the automatic reallocation. */
4925 tmp = gfc_alloc_allocatable_for_assignment (se->loop,
4926 expr, NULL);
4927 gfc_add_expr_to_block (&se->pre, tmp);
4929 /* Pass the temporary as the first argument. */
4930 result = info->descriptor;
4932 else
4933 result = build_fold_indirect_ref_loc (input_location,
4934 se->expr);
4935 vec_safe_push (retargs, se->expr);
4937 else if (comp && comp->attr.dimension)
4939 gcc_assert (se->loop && info);
4941 /* Set the type of the array. */
4942 tmp = gfc_typenode_for_spec (&comp->ts);
4943 gcc_assert (se->ss->dimen == se->loop->dimen);
4945 /* Evaluate the bounds of the result, if known. */
4946 gfc_set_loop_bounds_from_array_spec (&mapping, se, comp->as);
4948 /* If the lhs of an assignment x = f(..) is allocatable and
4949 f2003 is allowed, we must not generate the function call
4950 here but should just send back the results of the mapping.
4951 This is signalled by the function ss being flagged. */
4952 if (gfc_option.flag_realloc_lhs
4953 && se->ss && se->ss->is_alloc_lhs)
4955 gfc_free_interface_mapping (&mapping);
4956 return has_alternate_specifier;
4959 /* Create a temporary to store the result. In case the function
4960 returns a pointer, the temporary will be a shallow copy and
4961 mustn't be deallocated. */
4962 callee_alloc = comp->attr.allocatable || comp->attr.pointer;
4963 gfc_trans_create_temp_array (&se->pre, &se->post, se->ss,
4964 tmp, NULL_TREE, false,
4965 !comp->attr.pointer, callee_alloc,
4966 &se->ss->info->expr->where);
4968 /* Pass the temporary as the first argument. */
4969 result = info->descriptor;
4970 tmp = gfc_build_addr_expr (NULL_TREE, result);
4971 vec_safe_push (retargs, tmp);
4973 else if (!comp && sym->result->attr.dimension)
4975 gcc_assert (se->loop && info);
4977 /* Set the type of the array. */
4978 tmp = gfc_typenode_for_spec (&ts);
4979 gcc_assert (se->ss->dimen == se->loop->dimen);
4981 /* Evaluate the bounds of the result, if known. */
4982 gfc_set_loop_bounds_from_array_spec (&mapping, se, sym->result->as);
4984 /* If the lhs of an assignment x = f(..) is allocatable and
4985 f2003 is allowed, we must not generate the function call
4986 here but should just send back the results of the mapping.
4987 This is signalled by the function ss being flagged. */
4988 if (gfc_option.flag_realloc_lhs
4989 && se->ss && se->ss->is_alloc_lhs)
4991 gfc_free_interface_mapping (&mapping);
4992 return has_alternate_specifier;
4995 /* Create a temporary to store the result. In case the function
4996 returns a pointer, the temporary will be a shallow copy and
4997 mustn't be deallocated. */
4998 callee_alloc = sym->attr.allocatable || sym->attr.pointer;
4999 gfc_trans_create_temp_array (&se->pre, &se->post, se->ss,
5000 tmp, NULL_TREE, false,
5001 !sym->attr.pointer, callee_alloc,
5002 &se->ss->info->expr->where);
5004 /* Pass the temporary as the first argument. */
5005 result = info->descriptor;
5006 tmp = gfc_build_addr_expr (NULL_TREE, result);
5007 vec_safe_push (retargs, tmp);
5009 else if (ts.type == BT_CHARACTER)
5011 /* Pass the string length. */
5012 type = gfc_get_character_type (ts.kind, ts.u.cl);
5013 type = build_pointer_type (type);
5015 /* Return an address to a char[0:len-1]* temporary for
5016 character pointers. */
5017 if ((!comp && (sym->attr.pointer || sym->attr.allocatable))
5018 || (comp && (comp->attr.pointer || comp->attr.allocatable)))
5020 var = gfc_create_var (type, "pstr");
5022 if ((!comp && sym->attr.allocatable)
5023 || (comp && comp->attr.allocatable))
5025 gfc_add_modify (&se->pre, var,
5026 fold_convert (TREE_TYPE (var),
5027 null_pointer_node));
5028 tmp = gfc_call_free (convert (pvoid_type_node, var));
5029 gfc_add_expr_to_block (&se->post, tmp);
5032 /* Provide an address expression for the function arguments. */
5033 var = gfc_build_addr_expr (NULL_TREE, var);
5035 else
5036 var = gfc_conv_string_tmp (se, type, len);
5038 vec_safe_push (retargs, var);
5040 else
5042 gcc_assert (gfc_option.flag_f2c && ts.type == BT_COMPLEX);
5044 type = gfc_get_complex_type (ts.kind);
5045 var = gfc_build_addr_expr (NULL_TREE, gfc_create_var (type, "cmplx"));
5046 vec_safe_push (retargs, var);
5049 /* Add the string length to the argument list. */
5050 if (ts.type == BT_CHARACTER && ts.deferred)
5052 tmp = len;
5053 if (TREE_CODE (tmp) != VAR_DECL)
5054 tmp = gfc_evaluate_now (len, &se->pre);
5055 tmp = gfc_build_addr_expr (NULL_TREE, tmp);
5056 vec_safe_push (retargs, tmp);
5058 else if (ts.type == BT_CHARACTER)
5059 vec_safe_push (retargs, len);
5061 gfc_free_interface_mapping (&mapping);
5063 /* We need to glom RETARGS + ARGLIST + STRINGARGS + APPEND_ARGS. */
5064 arglen = (vec_safe_length (arglist) + vec_safe_length (stringargs)
5065 + vec_safe_length (append_args));
5066 vec_safe_reserve (retargs, arglen);
5068 /* Add the return arguments. */
5069 retargs->splice (arglist);
5071 /* Add the hidden string length parameters to the arguments. */
5072 retargs->splice (stringargs);
5074 /* We may want to append extra arguments here. This is used e.g. for
5075 calls to libgfortran_matmul_??, which need extra information. */
5076 if (!vec_safe_is_empty (append_args))
5077 retargs->splice (append_args);
5078 arglist = retargs;
5080 /* Generate the actual call. */
5081 if (base_object == NULL_TREE)
5082 conv_function_val (se, sym, expr);
5083 else
5084 conv_base_obj_fcn_val (se, base_object, expr);
5086 /* If there are alternate return labels, function type should be
5087 integer. Can't modify the type in place though, since it can be shared
5088 with other functions. For dummy arguments, the typing is done to
5089 this result, even if it has to be repeated for each call. */
5090 if (has_alternate_specifier
5091 && TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr))) != integer_type_node)
5093 if (!sym->attr.dummy)
5095 TREE_TYPE (sym->backend_decl)
5096 = build_function_type (integer_type_node,
5097 TYPE_ARG_TYPES (TREE_TYPE (sym->backend_decl)));
5098 se->expr = gfc_build_addr_expr (NULL_TREE, sym->backend_decl);
5100 else
5101 TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr))) = integer_type_node;
5104 fntype = TREE_TYPE (TREE_TYPE (se->expr));
5105 se->expr = build_call_vec (TREE_TYPE (fntype), se->expr, arglist);
5107 /* If we have a pointer function, but we don't want a pointer, e.g.
5108 something like
5109 x = f()
5110 where f is pointer valued, we have to dereference the result. */
5111 if (!se->want_pointer && !byref
5112 && ((!comp && (sym->attr.pointer || sym->attr.allocatable))
5113 || (comp && (comp->attr.pointer || comp->attr.allocatable))))
5114 se->expr = build_fold_indirect_ref_loc (input_location, se->expr);
5116 /* f2c calling conventions require a scalar default real function to
5117 return a double precision result. Convert this back to default
5118 real. We only care about the cases that can happen in Fortran 77.
5120 if (gfc_option.flag_f2c && sym->ts.type == BT_REAL
5121 && sym->ts.kind == gfc_default_real_kind
5122 && !sym->attr.always_explicit)
5123 se->expr = fold_convert (gfc_get_real_type (sym->ts.kind), se->expr);
5125 /* A pure function may still have side-effects - it may modify its
5126 parameters. */
5127 TREE_SIDE_EFFECTS (se->expr) = 1;
5128 #if 0
5129 if (!sym->attr.pure)
5130 TREE_SIDE_EFFECTS (se->expr) = 1;
5131 #endif
5133 if (byref)
5135 /* Add the function call to the pre chain. There is no expression. */
5136 gfc_add_expr_to_block (&se->pre, se->expr);
5137 se->expr = NULL_TREE;
5139 if (!se->direct_byref)
5141 if ((sym->attr.dimension && !comp) || (comp && comp->attr.dimension))
5143 if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
5145 /* Check the data pointer hasn't been modified. This would
5146 happen in a function returning a pointer. */
5147 tmp = gfc_conv_descriptor_data_get (info->descriptor);
5148 tmp = fold_build2_loc (input_location, NE_EXPR,
5149 boolean_type_node,
5150 tmp, info->data);
5151 gfc_trans_runtime_check (true, false, tmp, &se->pre, NULL,
5152 gfc_msg_fault);
5154 se->expr = info->descriptor;
5155 /* Bundle in the string length. */
5156 se->string_length = len;
5158 else if (ts.type == BT_CHARACTER)
5160 /* Dereference for character pointer results. */
5161 if ((!comp && (sym->attr.pointer || sym->attr.allocatable))
5162 || (comp && (comp->attr.pointer || comp->attr.allocatable)))
5163 se->expr = build_fold_indirect_ref_loc (input_location, var);
5164 else
5165 se->expr = var;
5167 se->string_length = len;
5169 else
5171 gcc_assert (ts.type == BT_COMPLEX && gfc_option.flag_f2c);
5172 se->expr = build_fold_indirect_ref_loc (input_location, var);
5177 /* Follow the function call with the argument post block. */
5178 if (byref)
5180 gfc_add_block_to_block (&se->pre, &post);
5182 /* Transformational functions of derived types with allocatable
5183 components must have the result allocatable components copied. */
5184 arg = expr->value.function.actual;
5185 if (result && arg && expr->rank
5186 && expr->value.function.isym
5187 && expr->value.function.isym->transformational
5188 && arg->expr->ts.type == BT_DERIVED
5189 && arg->expr->ts.u.derived->attr.alloc_comp)
5191 tree tmp2;
5192 /* Copy the allocatable components. We have to use a
5193 temporary here to prevent source allocatable components
5194 from being corrupted. */
5195 tmp2 = gfc_evaluate_now (result, &se->pre);
5196 tmp = gfc_copy_alloc_comp (arg->expr->ts.u.derived,
5197 result, tmp2, expr->rank);
5198 gfc_add_expr_to_block (&se->pre, tmp);
5199 tmp = gfc_copy_allocatable_data (result, tmp2, TREE_TYPE(tmp2),
5200 expr->rank);
5201 gfc_add_expr_to_block (&se->pre, tmp);
5203 /* Finally free the temporary's data field. */
5204 tmp = gfc_conv_descriptor_data_get (tmp2);
5205 tmp = gfc_deallocate_with_status (tmp, NULL_TREE, NULL_TREE,
5206 NULL_TREE, NULL_TREE, true,
5207 NULL, false);
5208 gfc_add_expr_to_block (&se->pre, tmp);
5211 else
5212 gfc_add_block_to_block (&se->post, &post);
5214 return has_alternate_specifier;
5218 /* Fill a character string with spaces. */
5220 static tree
5221 fill_with_spaces (tree start, tree type, tree size)
5223 stmtblock_t block, loop;
5224 tree i, el, exit_label, cond, tmp;
5226 /* For a simple char type, we can call memset(). */
5227 if (compare_tree_int (TYPE_SIZE_UNIT (type), 1) == 0)
5228 return build_call_expr_loc (input_location,
5229 builtin_decl_explicit (BUILT_IN_MEMSET),
5230 3, start,
5231 build_int_cst (gfc_get_int_type (gfc_c_int_kind),
5232 lang_hooks.to_target_charset (' ')),
5233 size);
5235 /* Otherwise, we use a loop:
5236 for (el = start, i = size; i > 0; el--, i+= TYPE_SIZE_UNIT (type))
5237 *el = (type) ' ';
5240 /* Initialize variables. */
5241 gfc_init_block (&block);
5242 i = gfc_create_var (sizetype, "i");
5243 gfc_add_modify (&block, i, fold_convert (sizetype, size));
5244 el = gfc_create_var (build_pointer_type (type), "el");
5245 gfc_add_modify (&block, el, fold_convert (TREE_TYPE (el), start));
5246 exit_label = gfc_build_label_decl (NULL_TREE);
5247 TREE_USED (exit_label) = 1;
5250 /* Loop body. */
5251 gfc_init_block (&loop);
5253 /* Exit condition. */
5254 cond = fold_build2_loc (input_location, LE_EXPR, boolean_type_node, i,
5255 build_zero_cst (sizetype));
5256 tmp = build1_v (GOTO_EXPR, exit_label);
5257 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond, tmp,
5258 build_empty_stmt (input_location));
5259 gfc_add_expr_to_block (&loop, tmp);
5261 /* Assignment. */
5262 gfc_add_modify (&loop,
5263 fold_build1_loc (input_location, INDIRECT_REF, type, el),
5264 build_int_cst (type, lang_hooks.to_target_charset (' ')));
5266 /* Increment loop variables. */
5267 gfc_add_modify (&loop, i,
5268 fold_build2_loc (input_location, MINUS_EXPR, sizetype, i,
5269 TYPE_SIZE_UNIT (type)));
5270 gfc_add_modify (&loop, el,
5271 fold_build_pointer_plus_loc (input_location,
5272 el, TYPE_SIZE_UNIT (type)));
5274 /* Making the loop... actually loop! */
5275 tmp = gfc_finish_block (&loop);
5276 tmp = build1_v (LOOP_EXPR, tmp);
5277 gfc_add_expr_to_block (&block, tmp);
5279 /* The exit label. */
5280 tmp = build1_v (LABEL_EXPR, exit_label);
5281 gfc_add_expr_to_block (&block, tmp);
5284 return gfc_finish_block (&block);
5288 /* Generate code to copy a string. */
5290 void
5291 gfc_trans_string_copy (stmtblock_t * block, tree dlength, tree dest,
5292 int dkind, tree slength, tree src, int skind)
5294 tree tmp, dlen, slen;
5295 tree dsc;
5296 tree ssc;
5297 tree cond;
5298 tree cond2;
5299 tree tmp2;
5300 tree tmp3;
5301 tree tmp4;
5302 tree chartype;
5303 stmtblock_t tempblock;
5305 gcc_assert (dkind == skind);
5307 if (slength != NULL_TREE)
5309 slen = fold_convert (size_type_node, gfc_evaluate_now (slength, block));
5310 ssc = gfc_string_to_single_character (slen, src, skind);
5312 else
5314 slen = build_int_cst (size_type_node, 1);
5315 ssc = src;
5318 if (dlength != NULL_TREE)
5320 dlen = fold_convert (size_type_node, gfc_evaluate_now (dlength, block));
5321 dsc = gfc_string_to_single_character (dlen, dest, dkind);
5323 else
5325 dlen = build_int_cst (size_type_node, 1);
5326 dsc = dest;
5329 /* Assign directly if the types are compatible. */
5330 if (dsc != NULL_TREE && ssc != NULL_TREE
5331 && TREE_TYPE (dsc) == TREE_TYPE (ssc))
5333 gfc_add_modify (block, dsc, ssc);
5334 return;
5337 /* Do nothing if the destination length is zero. */
5338 cond = fold_build2_loc (input_location, GT_EXPR, boolean_type_node, dlen,
5339 build_int_cst (size_type_node, 0));
5341 /* The following code was previously in _gfortran_copy_string:
5343 // The two strings may overlap so we use memmove.
5344 void
5345 copy_string (GFC_INTEGER_4 destlen, char * dest,
5346 GFC_INTEGER_4 srclen, const char * src)
5348 if (srclen >= destlen)
5350 // This will truncate if too long.
5351 memmove (dest, src, destlen);
5353 else
5355 memmove (dest, src, srclen);
5356 // Pad with spaces.
5357 memset (&dest[srclen], ' ', destlen - srclen);
5361 We're now doing it here for better optimization, but the logic
5362 is the same. */
5364 /* For non-default character kinds, we have to multiply the string
5365 length by the base type size. */
5366 chartype = gfc_get_char_type (dkind);
5367 slen = fold_build2_loc (input_location, MULT_EXPR, size_type_node,
5368 fold_convert (size_type_node, slen),
5369 fold_convert (size_type_node,
5370 TYPE_SIZE_UNIT (chartype)));
5371 dlen = fold_build2_loc (input_location, MULT_EXPR, size_type_node,
5372 fold_convert (size_type_node, dlen),
5373 fold_convert (size_type_node,
5374 TYPE_SIZE_UNIT (chartype)));
5376 if (dlength && POINTER_TYPE_P (TREE_TYPE (dest)))
5377 dest = fold_convert (pvoid_type_node, dest);
5378 else
5379 dest = gfc_build_addr_expr (pvoid_type_node, dest);
5381 if (slength && POINTER_TYPE_P (TREE_TYPE (src)))
5382 src = fold_convert (pvoid_type_node, src);
5383 else
5384 src = gfc_build_addr_expr (pvoid_type_node, src);
5386 /* Truncate string if source is too long. */
5387 cond2 = fold_build2_loc (input_location, GE_EXPR, boolean_type_node, slen,
5388 dlen);
5389 tmp2 = build_call_expr_loc (input_location,
5390 builtin_decl_explicit (BUILT_IN_MEMMOVE),
5391 3, dest, src, dlen);
5393 /* Else copy and pad with spaces. */
5394 tmp3 = build_call_expr_loc (input_location,
5395 builtin_decl_explicit (BUILT_IN_MEMMOVE),
5396 3, dest, src, slen);
5398 tmp4 = fold_build_pointer_plus_loc (input_location, dest, slen);
5399 tmp4 = fill_with_spaces (tmp4, chartype,
5400 fold_build2_loc (input_location, MINUS_EXPR,
5401 TREE_TYPE(dlen), dlen, slen));
5403 gfc_init_block (&tempblock);
5404 gfc_add_expr_to_block (&tempblock, tmp3);
5405 gfc_add_expr_to_block (&tempblock, tmp4);
5406 tmp3 = gfc_finish_block (&tempblock);
5408 /* The whole copy_string function is there. */
5409 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond2,
5410 tmp2, tmp3);
5411 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond, tmp,
5412 build_empty_stmt (input_location));
5413 gfc_add_expr_to_block (block, tmp);
5417 /* Translate a statement function.
5418 The value of a statement function reference is obtained by evaluating the
5419 expression using the values of the actual arguments for the values of the
5420 corresponding dummy arguments. */
5422 static void
5423 gfc_conv_statement_function (gfc_se * se, gfc_expr * expr)
5425 gfc_symbol *sym;
5426 gfc_symbol *fsym;
5427 gfc_formal_arglist *fargs;
5428 gfc_actual_arglist *args;
5429 gfc_se lse;
5430 gfc_se rse;
5431 gfc_saved_var *saved_vars;
5432 tree *temp_vars;
5433 tree type;
5434 tree tmp;
5435 int n;
5437 sym = expr->symtree->n.sym;
5438 args = expr->value.function.actual;
5439 gfc_init_se (&lse, NULL);
5440 gfc_init_se (&rse, NULL);
5442 n = 0;
5443 for (fargs = gfc_sym_get_dummy_args (sym); fargs; fargs = fargs->next)
5444 n++;
5445 saved_vars = XCNEWVEC (gfc_saved_var, n);
5446 temp_vars = XCNEWVEC (tree, n);
5448 for (fargs = gfc_sym_get_dummy_args (sym), n = 0; fargs;
5449 fargs = fargs->next, n++)
5451 /* Each dummy shall be specified, explicitly or implicitly, to be
5452 scalar. */
5453 gcc_assert (fargs->sym->attr.dimension == 0);
5454 fsym = fargs->sym;
5456 if (fsym->ts.type == BT_CHARACTER)
5458 /* Copy string arguments. */
5459 tree arglen;
5461 gcc_assert (fsym->ts.u.cl && fsym->ts.u.cl->length
5462 && fsym->ts.u.cl->length->expr_type == EXPR_CONSTANT);
5464 /* Create a temporary to hold the value. */
5465 if (fsym->ts.u.cl->backend_decl == NULL_TREE)
5466 fsym->ts.u.cl->backend_decl
5467 = gfc_conv_constant_to_tree (fsym->ts.u.cl->length);
5469 type = gfc_get_character_type (fsym->ts.kind, fsym->ts.u.cl);
5470 temp_vars[n] = gfc_create_var (type, fsym->name);
5472 arglen = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
5474 gfc_conv_expr (&rse, args->expr);
5475 gfc_conv_string_parameter (&rse);
5476 gfc_add_block_to_block (&se->pre, &lse.pre);
5477 gfc_add_block_to_block (&se->pre, &rse.pre);
5479 gfc_trans_string_copy (&se->pre, arglen, temp_vars[n], fsym->ts.kind,
5480 rse.string_length, rse.expr, fsym->ts.kind);
5481 gfc_add_block_to_block (&se->pre, &lse.post);
5482 gfc_add_block_to_block (&se->pre, &rse.post);
5484 else
5486 /* For everything else, just evaluate the expression. */
5488 /* Create a temporary to hold the value. */
5489 type = gfc_typenode_for_spec (&fsym->ts);
5490 temp_vars[n] = gfc_create_var (type, fsym->name);
5492 gfc_conv_expr (&lse, args->expr);
5494 gfc_add_block_to_block (&se->pre, &lse.pre);
5495 gfc_add_modify (&se->pre, temp_vars[n], lse.expr);
5496 gfc_add_block_to_block (&se->pre, &lse.post);
5499 args = args->next;
5502 /* Use the temporary variables in place of the real ones. */
5503 for (fargs = gfc_sym_get_dummy_args (sym), n = 0; fargs;
5504 fargs = fargs->next, n++)
5505 gfc_shadow_sym (fargs->sym, temp_vars[n], &saved_vars[n]);
5507 gfc_conv_expr (se, sym->value);
5509 if (sym->ts.type == BT_CHARACTER)
5511 gfc_conv_const_charlen (sym->ts.u.cl);
5513 /* Force the expression to the correct length. */
5514 if (!INTEGER_CST_P (se->string_length)
5515 || tree_int_cst_lt (se->string_length,
5516 sym->ts.u.cl->backend_decl))
5518 type = gfc_get_character_type (sym->ts.kind, sym->ts.u.cl);
5519 tmp = gfc_create_var (type, sym->name);
5520 tmp = gfc_build_addr_expr (build_pointer_type (type), tmp);
5521 gfc_trans_string_copy (&se->pre, sym->ts.u.cl->backend_decl, tmp,
5522 sym->ts.kind, se->string_length, se->expr,
5523 sym->ts.kind);
5524 se->expr = tmp;
5526 se->string_length = sym->ts.u.cl->backend_decl;
5529 /* Restore the original variables. */
5530 for (fargs = gfc_sym_get_dummy_args (sym), n = 0; fargs;
5531 fargs = fargs->next, n++)
5532 gfc_restore_sym (fargs->sym, &saved_vars[n]);
5533 free (temp_vars);
5534 free (saved_vars);
5538 /* Translate a function expression. */
5540 static void
5541 gfc_conv_function_expr (gfc_se * se, gfc_expr * expr)
5543 gfc_symbol *sym;
5545 if (expr->value.function.isym)
5547 gfc_conv_intrinsic_function (se, expr);
5548 return;
5551 /* expr.value.function.esym is the resolved (specific) function symbol for
5552 most functions. However this isn't set for dummy procedures. */
5553 sym = expr->value.function.esym;
5554 if (!sym)
5555 sym = expr->symtree->n.sym;
5557 /* We distinguish statement functions from general functions to improve
5558 runtime performance. */
5559 if (sym->attr.proc == PROC_ST_FUNCTION)
5561 gfc_conv_statement_function (se, expr);
5562 return;
5565 gfc_conv_procedure_call (se, sym, expr->value.function.actual, expr,
5566 NULL);
5570 /* Determine whether the given EXPR_CONSTANT is a zero initializer. */
5572 static bool
5573 is_zero_initializer_p (gfc_expr * expr)
5575 if (expr->expr_type != EXPR_CONSTANT)
5576 return false;
5578 /* We ignore constants with prescribed memory representations for now. */
5579 if (expr->representation.string)
5580 return false;
5582 switch (expr->ts.type)
5584 case BT_INTEGER:
5585 return mpz_cmp_si (expr->value.integer, 0) == 0;
5587 case BT_REAL:
5588 return mpfr_zero_p (expr->value.real)
5589 && MPFR_SIGN (expr->value.real) >= 0;
5591 case BT_LOGICAL:
5592 return expr->value.logical == 0;
5594 case BT_COMPLEX:
5595 return mpfr_zero_p (mpc_realref (expr->value.complex))
5596 && MPFR_SIGN (mpc_realref (expr->value.complex)) >= 0
5597 && mpfr_zero_p (mpc_imagref (expr->value.complex))
5598 && MPFR_SIGN (mpc_imagref (expr->value.complex)) >= 0;
5600 default:
5601 break;
5603 return false;
5607 static void
5608 gfc_conv_array_constructor_expr (gfc_se * se, gfc_expr * expr)
5610 gfc_ss *ss;
5612 ss = se->ss;
5613 gcc_assert (ss != NULL && ss != gfc_ss_terminator);
5614 gcc_assert (ss->info->expr == expr && ss->info->type == GFC_SS_CONSTRUCTOR);
5616 gfc_conv_tmp_array_ref (se);
5620 /* Build a static initializer. EXPR is the expression for the initial value.
5621 The other parameters describe the variable of the component being
5622 initialized. EXPR may be null. */
5624 tree
5625 gfc_conv_initializer (gfc_expr * expr, gfc_typespec * ts, tree type,
5626 bool array, bool pointer, bool procptr)
5628 gfc_se se;
5630 if (!(expr || pointer || procptr))
5631 return NULL_TREE;
5633 /* Check if we have ISOCBINDING_NULL_PTR or ISOCBINDING_NULL_FUNPTR
5634 (these are the only two iso_c_binding derived types that can be
5635 used as initialization expressions). If so, we need to modify
5636 the 'expr' to be that for a (void *). */
5637 if (expr != NULL && expr->ts.type == BT_DERIVED
5638 && expr->ts.is_iso_c && expr->ts.u.derived)
5640 gfc_symbol *derived = expr->ts.u.derived;
5642 /* The derived symbol has already been converted to a (void *). Use
5643 its kind. */
5644 expr = gfc_get_int_expr (derived->ts.kind, NULL, 0);
5645 expr->ts.f90_type = derived->ts.f90_type;
5647 gfc_init_se (&se, NULL);
5648 gfc_conv_constant (&se, expr);
5649 gcc_assert (TREE_CODE (se.expr) != CONSTRUCTOR);
5650 return se.expr;
5653 if (array && !procptr)
5655 tree ctor;
5656 /* Arrays need special handling. */
5657 if (pointer)
5658 ctor = gfc_build_null_descriptor (type);
5659 /* Special case assigning an array to zero. */
5660 else if (is_zero_initializer_p (expr))
5661 ctor = build_constructor (type, NULL);
5662 else
5663 ctor = gfc_conv_array_initializer (type, expr);
5664 TREE_STATIC (ctor) = 1;
5665 return ctor;
5667 else if (pointer || procptr)
5669 if (!expr || expr->expr_type == EXPR_NULL)
5670 return fold_convert (type, null_pointer_node);
5671 else
5673 gfc_init_se (&se, NULL);
5674 se.want_pointer = 1;
5675 gfc_conv_expr (&se, expr);
5676 gcc_assert (TREE_CODE (se.expr) != CONSTRUCTOR);
5677 return se.expr;
5680 else
5682 switch (ts->type)
5684 case BT_DERIVED:
5685 case BT_CLASS:
5686 gfc_init_se (&se, NULL);
5687 if (ts->type == BT_CLASS && expr->expr_type == EXPR_NULL)
5688 gfc_conv_structure (&se, gfc_class_null_initializer(ts, expr), 1);
5689 else
5690 gfc_conv_structure (&se, expr, 1);
5691 gcc_assert (TREE_CODE (se.expr) == CONSTRUCTOR);
5692 TREE_STATIC (se.expr) = 1;
5693 return se.expr;
5695 case BT_CHARACTER:
5697 tree ctor = gfc_conv_string_init (ts->u.cl->backend_decl,expr);
5698 TREE_STATIC (ctor) = 1;
5699 return ctor;
5702 default:
5703 gfc_init_se (&se, NULL);
5704 gfc_conv_constant (&se, expr);
5705 gcc_assert (TREE_CODE (se.expr) != CONSTRUCTOR);
5706 return se.expr;
5711 static tree
5712 gfc_trans_subarray_assign (tree dest, gfc_component * cm, gfc_expr * expr)
5714 gfc_se rse;
5715 gfc_se lse;
5716 gfc_ss *rss;
5717 gfc_ss *lss;
5718 gfc_array_info *lss_array;
5719 stmtblock_t body;
5720 stmtblock_t block;
5721 gfc_loopinfo loop;
5722 int n;
5723 tree tmp;
5725 gfc_start_block (&block);
5727 /* Initialize the scalarizer. */
5728 gfc_init_loopinfo (&loop);
5730 gfc_init_se (&lse, NULL);
5731 gfc_init_se (&rse, NULL);
5733 /* Walk the rhs. */
5734 rss = gfc_walk_expr (expr);
5735 if (rss == gfc_ss_terminator)
5736 /* The rhs is scalar. Add a ss for the expression. */
5737 rss = gfc_get_scalar_ss (gfc_ss_terminator, expr);
5739 /* Create a SS for the destination. */
5740 lss = gfc_get_array_ss (gfc_ss_terminator, NULL, cm->as->rank,
5741 GFC_SS_COMPONENT);
5742 lss_array = &lss->info->data.array;
5743 lss_array->shape = gfc_get_shape (cm->as->rank);
5744 lss_array->descriptor = dest;
5745 lss_array->data = gfc_conv_array_data (dest);
5746 lss_array->offset = gfc_conv_array_offset (dest);
5747 for (n = 0; n < cm->as->rank; n++)
5749 lss_array->start[n] = gfc_conv_array_lbound (dest, n);
5750 lss_array->stride[n] = gfc_index_one_node;
5752 mpz_init (lss_array->shape[n]);
5753 mpz_sub (lss_array->shape[n], cm->as->upper[n]->value.integer,
5754 cm->as->lower[n]->value.integer);
5755 mpz_add_ui (lss_array->shape[n], lss_array->shape[n], 1);
5758 /* Associate the SS with the loop. */
5759 gfc_add_ss_to_loop (&loop, lss);
5760 gfc_add_ss_to_loop (&loop, rss);
5762 /* Calculate the bounds of the scalarization. */
5763 gfc_conv_ss_startstride (&loop);
5765 /* Setup the scalarizing loops. */
5766 gfc_conv_loop_setup (&loop, &expr->where);
5768 /* Setup the gfc_se structures. */
5769 gfc_copy_loopinfo_to_se (&lse, &loop);
5770 gfc_copy_loopinfo_to_se (&rse, &loop);
5772 rse.ss = rss;
5773 gfc_mark_ss_chain_used (rss, 1);
5774 lse.ss = lss;
5775 gfc_mark_ss_chain_used (lss, 1);
5777 /* Start the scalarized loop body. */
5778 gfc_start_scalarized_body (&loop, &body);
5780 gfc_conv_tmp_array_ref (&lse);
5781 if (cm->ts.type == BT_CHARACTER)
5782 lse.string_length = cm->ts.u.cl->backend_decl;
5784 gfc_conv_expr (&rse, expr);
5786 tmp = gfc_trans_scalar_assign (&lse, &rse, cm->ts, true, false, true);
5787 gfc_add_expr_to_block (&body, tmp);
5789 gcc_assert (rse.ss == gfc_ss_terminator);
5791 /* Generate the copying loops. */
5792 gfc_trans_scalarizing_loops (&loop, &body);
5794 /* Wrap the whole thing up. */
5795 gfc_add_block_to_block (&block, &loop.pre);
5796 gfc_add_block_to_block (&block, &loop.post);
5798 gcc_assert (lss_array->shape != NULL);
5799 gfc_free_shape (&lss_array->shape, cm->as->rank);
5800 gfc_cleanup_loop (&loop);
5802 return gfc_finish_block (&block);
5806 static tree
5807 gfc_trans_alloc_subarray_assign (tree dest, gfc_component * cm,
5808 gfc_expr * expr)
5810 gfc_se se;
5811 stmtblock_t block;
5812 tree offset;
5813 int n;
5814 tree tmp;
5815 tree tmp2;
5816 gfc_array_spec *as;
5817 gfc_expr *arg = NULL;
5819 gfc_start_block (&block);
5820 gfc_init_se (&se, NULL);
5822 /* Get the descriptor for the expressions. */
5823 se.want_pointer = 0;
5824 gfc_conv_expr_descriptor (&se, expr);
5825 gfc_add_block_to_block (&block, &se.pre);
5826 gfc_add_modify (&block, dest, se.expr);
5828 /* Deal with arrays of derived types with allocatable components. */
5829 if (cm->ts.type == BT_DERIVED
5830 && cm->ts.u.derived->attr.alloc_comp)
5831 tmp = gfc_copy_alloc_comp (cm->ts.u.derived,
5832 se.expr, dest,
5833 cm->as->rank);
5834 else
5835 tmp = gfc_duplicate_allocatable (dest, se.expr,
5836 TREE_TYPE(cm->backend_decl),
5837 cm->as->rank);
5839 gfc_add_expr_to_block (&block, tmp);
5840 gfc_add_block_to_block (&block, &se.post);
5842 if (expr->expr_type != EXPR_VARIABLE)
5843 gfc_conv_descriptor_data_set (&block, se.expr,
5844 null_pointer_node);
5846 /* We need to know if the argument of a conversion function is a
5847 variable, so that the correct lower bound can be used. */
5848 if (expr->expr_type == EXPR_FUNCTION
5849 && expr->value.function.isym
5850 && expr->value.function.isym->conversion
5851 && expr->value.function.actual->expr
5852 && expr->value.function.actual->expr->expr_type == EXPR_VARIABLE)
5853 arg = expr->value.function.actual->expr;
5855 /* Obtain the array spec of full array references. */
5856 if (arg)
5857 as = gfc_get_full_arrayspec_from_expr (arg);
5858 else
5859 as = gfc_get_full_arrayspec_from_expr (expr);
5861 /* Shift the lbound and ubound of temporaries to being unity,
5862 rather than zero, based. Always calculate the offset. */
5863 offset = gfc_conv_descriptor_offset_get (dest);
5864 gfc_add_modify (&block, offset, gfc_index_zero_node);
5865 tmp2 =gfc_create_var (gfc_array_index_type, NULL);
5867 for (n = 0; n < expr->rank; n++)
5869 tree span;
5870 tree lbound;
5872 /* Obtain the correct lbound - ISO/IEC TR 15581:2001 page 9.
5873 TODO It looks as if gfc_conv_expr_descriptor should return
5874 the correct bounds and that the following should not be
5875 necessary. This would simplify gfc_conv_intrinsic_bound
5876 as well. */
5877 if (as && as->lower[n])
5879 gfc_se lbse;
5880 gfc_init_se (&lbse, NULL);
5881 gfc_conv_expr (&lbse, as->lower[n]);
5882 gfc_add_block_to_block (&block, &lbse.pre);
5883 lbound = gfc_evaluate_now (lbse.expr, &block);
5885 else if (as && arg)
5887 tmp = gfc_get_symbol_decl (arg->symtree->n.sym);
5888 lbound = gfc_conv_descriptor_lbound_get (tmp,
5889 gfc_rank_cst[n]);
5891 else if (as)
5892 lbound = gfc_conv_descriptor_lbound_get (dest,
5893 gfc_rank_cst[n]);
5894 else
5895 lbound = gfc_index_one_node;
5897 lbound = fold_convert (gfc_array_index_type, lbound);
5899 /* Shift the bounds and set the offset accordingly. */
5900 tmp = gfc_conv_descriptor_ubound_get (dest, gfc_rank_cst[n]);
5901 span = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
5902 tmp, gfc_conv_descriptor_lbound_get (dest, gfc_rank_cst[n]));
5903 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
5904 span, lbound);
5905 gfc_conv_descriptor_ubound_set (&block, dest,
5906 gfc_rank_cst[n], tmp);
5907 gfc_conv_descriptor_lbound_set (&block, dest,
5908 gfc_rank_cst[n], lbound);
5910 tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
5911 gfc_conv_descriptor_lbound_get (dest,
5912 gfc_rank_cst[n]),
5913 gfc_conv_descriptor_stride_get (dest,
5914 gfc_rank_cst[n]));
5915 gfc_add_modify (&block, tmp2, tmp);
5916 tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
5917 offset, tmp2);
5918 gfc_conv_descriptor_offset_set (&block, dest, tmp);
5921 if (arg)
5923 /* If a conversion expression has a null data pointer
5924 argument, nullify the allocatable component. */
5925 tree non_null_expr;
5926 tree null_expr;
5928 if (arg->symtree->n.sym->attr.allocatable
5929 || arg->symtree->n.sym->attr.pointer)
5931 non_null_expr = gfc_finish_block (&block);
5932 gfc_start_block (&block);
5933 gfc_conv_descriptor_data_set (&block, dest,
5934 null_pointer_node);
5935 null_expr = gfc_finish_block (&block);
5936 tmp = gfc_conv_descriptor_data_get (arg->symtree->n.sym->backend_decl);
5937 tmp = build2_loc (input_location, EQ_EXPR, boolean_type_node, tmp,
5938 fold_convert (TREE_TYPE (tmp), null_pointer_node));
5939 return build3_v (COND_EXPR, tmp,
5940 null_expr, non_null_expr);
5944 return gfc_finish_block (&block);
5948 /* Assign a single component of a derived type constructor. */
5950 static tree
5951 gfc_trans_subcomponent_assign (tree dest, gfc_component * cm, gfc_expr * expr)
5953 gfc_se se;
5954 gfc_se lse;
5955 stmtblock_t block;
5956 tree tmp;
5958 gfc_start_block (&block);
5960 if (cm->attr.pointer || cm->attr.proc_pointer)
5962 gfc_init_se (&se, NULL);
5963 /* Pointer component. */
5964 if (cm->attr.dimension && !cm->attr.proc_pointer)
5966 /* Array pointer. */
5967 if (expr->expr_type == EXPR_NULL)
5968 gfc_conv_descriptor_data_set (&block, dest, null_pointer_node);
5969 else
5971 se.direct_byref = 1;
5972 se.expr = dest;
5973 gfc_conv_expr_descriptor (&se, expr);
5974 gfc_add_block_to_block (&block, &se.pre);
5975 gfc_add_block_to_block (&block, &se.post);
5978 else
5980 /* Scalar pointers. */
5981 se.want_pointer = 1;
5982 gfc_conv_expr (&se, expr);
5983 gfc_add_block_to_block (&block, &se.pre);
5985 if (expr->symtree && expr->symtree->n.sym->attr.proc_pointer
5986 && expr->symtree->n.sym->attr.dummy)
5987 se.expr = build_fold_indirect_ref_loc (input_location, se.expr);
5989 gfc_add_modify (&block, dest,
5990 fold_convert (TREE_TYPE (dest), se.expr));
5991 gfc_add_block_to_block (&block, &se.post);
5994 else if (cm->ts.type == BT_CLASS && expr->expr_type == EXPR_NULL)
5996 /* NULL initialization for CLASS components. */
5997 tmp = gfc_trans_structure_assign (dest,
5998 gfc_class_null_initializer (&cm->ts, expr));
5999 gfc_add_expr_to_block (&block, tmp);
6001 else if (cm->attr.dimension && !cm->attr.proc_pointer)
6003 if (cm->attr.allocatable && expr->expr_type == EXPR_NULL)
6004 gfc_conv_descriptor_data_set (&block, dest, null_pointer_node);
6005 else if (cm->attr.allocatable)
6007 tmp = gfc_trans_alloc_subarray_assign (dest, cm, expr);
6008 gfc_add_expr_to_block (&block, tmp);
6010 else
6012 tmp = gfc_trans_subarray_assign (dest, cm, expr);
6013 gfc_add_expr_to_block (&block, tmp);
6016 else if (expr->ts.type == BT_DERIVED)
6018 if (expr->expr_type != EXPR_STRUCTURE)
6020 gfc_init_se (&se, NULL);
6021 gfc_conv_expr (&se, expr);
6022 gfc_add_block_to_block (&block, &se.pre);
6023 gfc_add_modify (&block, dest,
6024 fold_convert (TREE_TYPE (dest), se.expr));
6025 gfc_add_block_to_block (&block, &se.post);
6027 else
6029 /* Nested constructors. */
6030 tmp = gfc_trans_structure_assign (dest, expr);
6031 gfc_add_expr_to_block (&block, tmp);
6034 else
6036 /* Scalar component. */
6037 gfc_init_se (&se, NULL);
6038 gfc_init_se (&lse, NULL);
6040 gfc_conv_expr (&se, expr);
6041 if (cm->ts.type == BT_CHARACTER)
6042 lse.string_length = cm->ts.u.cl->backend_decl;
6043 lse.expr = dest;
6044 tmp = gfc_trans_scalar_assign (&lse, &se, cm->ts, true, false, true);
6045 gfc_add_expr_to_block (&block, tmp);
6047 return gfc_finish_block (&block);
6050 /* Assign a derived type constructor to a variable. */
6052 static tree
6053 gfc_trans_structure_assign (tree dest, gfc_expr * expr)
6055 gfc_constructor *c;
6056 gfc_component *cm;
6057 stmtblock_t block;
6058 tree field;
6059 tree tmp;
6061 gfc_start_block (&block);
6062 cm = expr->ts.u.derived->components;
6064 if (expr->ts.u.derived->from_intmod == INTMOD_ISO_C_BINDING
6065 && (expr->ts.u.derived->intmod_sym_id == ISOCBINDING_PTR
6066 || expr->ts.u.derived->intmod_sym_id == ISOCBINDING_FUNPTR))
6068 gfc_se se, lse;
6070 gcc_assert (cm->backend_decl == NULL);
6071 gfc_init_se (&se, NULL);
6072 gfc_init_se (&lse, NULL);
6073 gfc_conv_expr (&se, gfc_constructor_first (expr->value.constructor)->expr);
6074 lse.expr = dest;
6075 gfc_add_modify (&block, lse.expr,
6076 fold_convert (TREE_TYPE (lse.expr), se.expr));
6078 return gfc_finish_block (&block);
6081 for (c = gfc_constructor_first (expr->value.constructor);
6082 c; c = gfc_constructor_next (c), cm = cm->next)
6084 /* Skip absent members in default initializers. */
6085 if (!c->expr)
6086 continue;
6088 field = cm->backend_decl;
6089 tmp = fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field),
6090 dest, field, NULL_TREE);
6091 tmp = gfc_trans_subcomponent_assign (tmp, cm, c->expr);
6092 gfc_add_expr_to_block (&block, tmp);
6094 return gfc_finish_block (&block);
6097 /* Build an expression for a constructor. If init is nonzero then
6098 this is part of a static variable initializer. */
6100 void
6101 gfc_conv_structure (gfc_se * se, gfc_expr * expr, int init)
6103 gfc_constructor *c;
6104 gfc_component *cm;
6105 tree val;
6106 tree type;
6107 tree tmp;
6108 vec<constructor_elt, va_gc> *v = NULL;
6110 gcc_assert (se->ss == NULL);
6111 gcc_assert (expr->expr_type == EXPR_STRUCTURE);
6112 type = gfc_typenode_for_spec (&expr->ts);
6114 if (!init)
6116 /* Create a temporary variable and fill it in. */
6117 se->expr = gfc_create_var (type, expr->ts.u.derived->name);
6118 tmp = gfc_trans_structure_assign (se->expr, expr);
6119 gfc_add_expr_to_block (&se->pre, tmp);
6120 return;
6123 cm = expr->ts.u.derived->components;
6125 for (c = gfc_constructor_first (expr->value.constructor);
6126 c; c = gfc_constructor_next (c), cm = cm->next)
6128 /* Skip absent members in default initializers and allocatable
6129 components. Although the latter have a default initializer
6130 of EXPR_NULL,... by default, the static nullify is not needed
6131 since this is done every time we come into scope. */
6132 if (!c->expr || (cm->attr.allocatable && cm->attr.flavor != FL_PROCEDURE))
6133 continue;
6135 if (cm->initializer && cm->initializer->expr_type != EXPR_NULL
6136 && strcmp (cm->name, "_extends") == 0
6137 && cm->initializer->symtree)
6139 tree vtab;
6140 gfc_symbol *vtabs;
6141 vtabs = cm->initializer->symtree->n.sym;
6142 vtab = gfc_build_addr_expr (NULL_TREE, gfc_get_symbol_decl (vtabs));
6143 vtab = unshare_expr_without_location (vtab);
6144 CONSTRUCTOR_APPEND_ELT (v, cm->backend_decl, vtab);
6146 else if (cm->ts.u.derived && strcmp (cm->name, "_size") == 0)
6148 val = TYPE_SIZE_UNIT (gfc_get_derived_type (cm->ts.u.derived));
6149 CONSTRUCTOR_APPEND_ELT (v, cm->backend_decl, val);
6151 else
6153 val = gfc_conv_initializer (c->expr, &cm->ts,
6154 TREE_TYPE (cm->backend_decl),
6155 cm->attr.dimension, cm->attr.pointer,
6156 cm->attr.proc_pointer);
6157 val = unshare_expr_without_location (val);
6159 /* Append it to the constructor list. */
6160 CONSTRUCTOR_APPEND_ELT (v, cm->backend_decl, val);
6163 se->expr = build_constructor (type, v);
6164 if (init)
6165 TREE_CONSTANT (se->expr) = 1;
6169 /* Translate a substring expression. */
6171 static void
6172 gfc_conv_substring_expr (gfc_se * se, gfc_expr * expr)
6174 gfc_ref *ref;
6176 ref = expr->ref;
6178 gcc_assert (ref == NULL || ref->type == REF_SUBSTRING);
6180 se->expr = gfc_build_wide_string_const (expr->ts.kind,
6181 expr->value.character.length,
6182 expr->value.character.string);
6184 se->string_length = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (se->expr)));
6185 TYPE_STRING_FLAG (TREE_TYPE (se->expr)) = 1;
6187 if (ref)
6188 gfc_conv_substring (se, ref, expr->ts.kind, NULL, &expr->where);
6192 /* Entry point for expression translation. Evaluates a scalar quantity.
6193 EXPR is the expression to be translated, and SE is the state structure if
6194 called from within the scalarized. */
6196 void
6197 gfc_conv_expr (gfc_se * se, gfc_expr * expr)
6199 gfc_ss *ss;
6201 ss = se->ss;
6202 if (ss && ss->info->expr == expr
6203 && (ss->info->type == GFC_SS_SCALAR
6204 || ss->info->type == GFC_SS_REFERENCE))
6206 gfc_ss_info *ss_info;
6208 ss_info = ss->info;
6209 /* Substitute a scalar expression evaluated outside the scalarization
6210 loop. */
6211 se->expr = ss_info->data.scalar.value;
6212 /* If the reference can be NULL, the value field contains the reference,
6213 not the value the reference points to (see gfc_add_loop_ss_code). */
6214 if (ss_info->can_be_null_ref)
6215 se->expr = build_fold_indirect_ref_loc (input_location, se->expr);
6217 se->string_length = ss_info->string_length;
6218 gfc_advance_se_ss_chain (se);
6219 return;
6222 /* We need to convert the expressions for the iso_c_binding derived types.
6223 C_NULL_PTR and C_NULL_FUNPTR will be made EXPR_NULL, which evaluates to
6224 null_pointer_node. C_PTR and C_FUNPTR are converted to match the
6225 typespec for the C_PTR and C_FUNPTR symbols, which has already been
6226 updated to be an integer with a kind equal to the size of a (void *). */
6227 if (expr->ts.type == BT_DERIVED && expr->ts.u.derived
6228 && expr->ts.u.derived->attr.is_iso_c)
6230 if (expr->expr_type == EXPR_VARIABLE
6231 && (expr->symtree->n.sym->intmod_sym_id == ISOCBINDING_NULL_PTR
6232 || expr->symtree->n.sym->intmod_sym_id
6233 == ISOCBINDING_NULL_FUNPTR))
6235 /* Set expr_type to EXPR_NULL, which will result in
6236 null_pointer_node being used below. */
6237 expr->expr_type = EXPR_NULL;
6239 else
6241 /* Update the type/kind of the expression to be what the new
6242 type/kind are for the updated symbols of C_PTR/C_FUNPTR. */
6243 expr->ts.type = expr->ts.u.derived->ts.type;
6244 expr->ts.f90_type = expr->ts.u.derived->ts.f90_type;
6245 expr->ts.kind = expr->ts.u.derived->ts.kind;
6249 gfc_fix_class_refs (expr);
6251 switch (expr->expr_type)
6253 case EXPR_OP:
6254 gfc_conv_expr_op (se, expr);
6255 break;
6257 case EXPR_FUNCTION:
6258 gfc_conv_function_expr (se, expr);
6259 break;
6261 case EXPR_CONSTANT:
6262 gfc_conv_constant (se, expr);
6263 break;
6265 case EXPR_VARIABLE:
6266 gfc_conv_variable (se, expr);
6267 break;
6269 case EXPR_NULL:
6270 se->expr = null_pointer_node;
6271 break;
6273 case EXPR_SUBSTRING:
6274 gfc_conv_substring_expr (se, expr);
6275 break;
6277 case EXPR_STRUCTURE:
6278 gfc_conv_structure (se, expr, 0);
6279 break;
6281 case EXPR_ARRAY:
6282 gfc_conv_array_constructor_expr (se, expr);
6283 break;
6285 default:
6286 gcc_unreachable ();
6287 break;
6291 /* Like gfc_conv_expr_val, but the value is also suitable for use in the lhs
6292 of an assignment. */
6293 void
6294 gfc_conv_expr_lhs (gfc_se * se, gfc_expr * expr)
6296 gfc_conv_expr (se, expr);
6297 /* All numeric lvalues should have empty post chains. If not we need to
6298 figure out a way of rewriting an lvalue so that it has no post chain. */
6299 gcc_assert (expr->ts.type == BT_CHARACTER || !se->post.head);
6302 /* Like gfc_conv_expr, but the POST block is guaranteed to be empty for
6303 numeric expressions. Used for scalar values where inserting cleanup code
6304 is inconvenient. */
6305 void
6306 gfc_conv_expr_val (gfc_se * se, gfc_expr * expr)
6308 tree val;
6310 gcc_assert (expr->ts.type != BT_CHARACTER);
6311 gfc_conv_expr (se, expr);
6312 if (se->post.head)
6314 val = gfc_create_var (TREE_TYPE (se->expr), NULL);
6315 gfc_add_modify (&se->pre, val, se->expr);
6316 se->expr = val;
6317 gfc_add_block_to_block (&se->pre, &se->post);
6321 /* Helper to translate an expression and convert it to a particular type. */
6322 void
6323 gfc_conv_expr_type (gfc_se * se, gfc_expr * expr, tree type)
6325 gfc_conv_expr_val (se, expr);
6326 se->expr = convert (type, se->expr);
6330 /* Converts an expression so that it can be passed by reference. Scalar
6331 values only. */
6333 void
6334 gfc_conv_expr_reference (gfc_se * se, gfc_expr * expr)
6336 gfc_ss *ss;
6337 tree var;
6339 ss = se->ss;
6340 if (ss && ss->info->expr == expr
6341 && ss->info->type == GFC_SS_REFERENCE)
6343 /* Returns a reference to the scalar evaluated outside the loop
6344 for this case. */
6345 gfc_conv_expr (se, expr);
6346 se->expr = gfc_build_addr_expr (NULL_TREE, se->expr);
6347 return;
6350 if (expr->ts.type == BT_CHARACTER)
6352 gfc_conv_expr (se, expr);
6353 gfc_conv_string_parameter (se);
6354 return;
6357 if (expr->expr_type == EXPR_VARIABLE)
6359 se->want_pointer = 1;
6360 gfc_conv_expr (se, expr);
6361 if (se->post.head)
6363 var = gfc_create_var (TREE_TYPE (se->expr), NULL);
6364 gfc_add_modify (&se->pre, var, se->expr);
6365 gfc_add_block_to_block (&se->pre, &se->post);
6366 se->expr = var;
6368 return;
6371 if (expr->expr_type == EXPR_FUNCTION
6372 && ((expr->value.function.esym
6373 && expr->value.function.esym->result->attr.pointer
6374 && !expr->value.function.esym->result->attr.dimension)
6375 || (!expr->value.function.esym && !expr->ref
6376 && expr->symtree->n.sym->attr.pointer
6377 && !expr->symtree->n.sym->attr.dimension)))
6379 se->want_pointer = 1;
6380 gfc_conv_expr (se, expr);
6381 var = gfc_create_var (TREE_TYPE (se->expr), NULL);
6382 gfc_add_modify (&se->pre, var, se->expr);
6383 se->expr = var;
6384 return;
6387 gfc_conv_expr (se, expr);
6389 /* Create a temporary var to hold the value. */
6390 if (TREE_CONSTANT (se->expr))
6392 tree tmp = se->expr;
6393 STRIP_TYPE_NOPS (tmp);
6394 var = build_decl (input_location,
6395 CONST_DECL, NULL, TREE_TYPE (tmp));
6396 DECL_INITIAL (var) = tmp;
6397 TREE_STATIC (var) = 1;
6398 pushdecl (var);
6400 else
6402 var = gfc_create_var (TREE_TYPE (se->expr), NULL);
6403 gfc_add_modify (&se->pre, var, se->expr);
6405 gfc_add_block_to_block (&se->pre, &se->post);
6407 /* Take the address of that value. */
6408 se->expr = gfc_build_addr_expr (NULL_TREE, var);
6412 tree
6413 gfc_trans_pointer_assign (gfc_code * code)
6415 return gfc_trans_pointer_assignment (code->expr1, code->expr2);
6419 /* Generate code for a pointer assignment. */
6421 tree
6422 gfc_trans_pointer_assignment (gfc_expr * expr1, gfc_expr * expr2)
6424 gfc_se lse;
6425 gfc_se rse;
6426 stmtblock_t block;
6427 tree desc;
6428 tree tmp;
6429 tree decl;
6430 bool scalar;
6431 gfc_ss *ss;
6433 gfc_start_block (&block);
6435 gfc_init_se (&lse, NULL);
6437 /* Check whether the expression is a scalar or not; we cannot use
6438 expr1->rank as it can be nonzero for proc pointers. */
6439 ss = gfc_walk_expr (expr1);
6440 scalar = ss == gfc_ss_terminator;
6441 if (!scalar)
6442 gfc_free_ss_chain (ss);
6444 if (scalar)
6446 /* Scalar pointers. */
6447 lse.want_pointer = 1;
6448 gfc_conv_expr (&lse, expr1);
6449 gfc_init_se (&rse, NULL);
6450 rse.want_pointer = 1;
6451 gfc_conv_expr (&rse, expr2);
6453 if (expr1->symtree->n.sym->attr.proc_pointer
6454 && expr1->symtree->n.sym->attr.dummy)
6455 lse.expr = build_fold_indirect_ref_loc (input_location,
6456 lse.expr);
6458 if (expr2->symtree && expr2->symtree->n.sym->attr.proc_pointer
6459 && expr2->symtree->n.sym->attr.dummy)
6460 rse.expr = build_fold_indirect_ref_loc (input_location,
6461 rse.expr);
6463 gfc_add_block_to_block (&block, &lse.pre);
6464 gfc_add_block_to_block (&block, &rse.pre);
6466 /* Check character lengths if character expression. The test is only
6467 really added if -fbounds-check is enabled. Exclude deferred
6468 character length lefthand sides. */
6469 if (expr1->ts.type == BT_CHARACTER && expr2->expr_type != EXPR_NULL
6470 && !expr1->ts.deferred
6471 && !expr1->symtree->n.sym->attr.proc_pointer
6472 && !gfc_is_proc_ptr_comp (expr1))
6474 gcc_assert (expr2->ts.type == BT_CHARACTER);
6475 gcc_assert (lse.string_length && rse.string_length);
6476 gfc_trans_same_strlen_check ("pointer assignment", &expr1->where,
6477 lse.string_length, rse.string_length,
6478 &block);
6481 /* The assignment to an deferred character length sets the string
6482 length to that of the rhs. */
6483 if (expr1->ts.deferred)
6485 if (expr2->expr_type != EXPR_NULL && lse.string_length != NULL)
6486 gfc_add_modify (&block, lse.string_length, rse.string_length);
6487 else if (lse.string_length != NULL)
6488 gfc_add_modify (&block, lse.string_length,
6489 build_int_cst (gfc_charlen_type_node, 0));
6492 gfc_add_modify (&block, lse.expr,
6493 fold_convert (TREE_TYPE (lse.expr), rse.expr));
6495 gfc_add_block_to_block (&block, &rse.post);
6496 gfc_add_block_to_block (&block, &lse.post);
6498 else
6500 gfc_ref* remap;
6501 bool rank_remap;
6502 tree strlen_lhs;
6503 tree strlen_rhs = NULL_TREE;
6505 /* Array pointer. Find the last reference on the LHS and if it is an
6506 array section ref, we're dealing with bounds remapping. In this case,
6507 set it to AR_FULL so that gfc_conv_expr_descriptor does
6508 not see it and process the bounds remapping afterwards explicitly. */
6509 for (remap = expr1->ref; remap; remap = remap->next)
6510 if (!remap->next && remap->type == REF_ARRAY
6511 && remap->u.ar.type == AR_SECTION)
6512 break;
6513 rank_remap = (remap && remap->u.ar.end[0]);
6515 if (remap)
6516 lse.descriptor_only = 1;
6517 gfc_conv_expr_descriptor (&lse, expr1);
6518 strlen_lhs = lse.string_length;
6519 desc = lse.expr;
6521 if (expr2->expr_type == EXPR_NULL)
6523 /* Just set the data pointer to null. */
6524 gfc_conv_descriptor_data_set (&lse.pre, lse.expr, null_pointer_node);
6526 else if (rank_remap)
6528 /* If we are rank-remapping, just get the RHS's descriptor and
6529 process this later on. */
6530 gfc_init_se (&rse, NULL);
6531 rse.direct_byref = 1;
6532 rse.byref_noassign = 1;
6533 gfc_conv_expr_descriptor (&rse, expr2);
6534 strlen_rhs = rse.string_length;
6536 else if (expr2->expr_type == EXPR_VARIABLE)
6538 /* Assign directly to the LHS's descriptor. */
6539 lse.direct_byref = 1;
6540 gfc_conv_expr_descriptor (&lse, expr2);
6541 strlen_rhs = lse.string_length;
6543 /* If this is a subreference array pointer assignment, use the rhs
6544 descriptor element size for the lhs span. */
6545 if (expr1->symtree->n.sym->attr.subref_array_pointer)
6547 decl = expr1->symtree->n.sym->backend_decl;
6548 gfc_init_se (&rse, NULL);
6549 rse.descriptor_only = 1;
6550 gfc_conv_expr (&rse, expr2);
6551 tmp = gfc_get_element_type (TREE_TYPE (rse.expr));
6552 tmp = fold_convert (gfc_array_index_type, size_in_bytes (tmp));
6553 if (!INTEGER_CST_P (tmp))
6554 gfc_add_block_to_block (&lse.post, &rse.pre);
6555 gfc_add_modify (&lse.post, GFC_DECL_SPAN(decl), tmp);
6558 else
6560 /* Assign to a temporary descriptor and then copy that
6561 temporary to the pointer. */
6562 tmp = gfc_create_var (TREE_TYPE (desc), "ptrtemp");
6564 lse.expr = tmp;
6565 lse.direct_byref = 1;
6566 gfc_conv_expr_descriptor (&lse, expr2);
6567 strlen_rhs = lse.string_length;
6568 gfc_add_modify (&lse.pre, desc, tmp);
6571 gfc_add_block_to_block (&block, &lse.pre);
6572 if (rank_remap)
6573 gfc_add_block_to_block (&block, &rse.pre);
6575 /* If we do bounds remapping, update LHS descriptor accordingly. */
6576 if (remap)
6578 int dim;
6579 gcc_assert (remap->u.ar.dimen == expr1->rank);
6581 if (rank_remap)
6583 /* Do rank remapping. We already have the RHS's descriptor
6584 converted in rse and now have to build the correct LHS
6585 descriptor for it. */
6587 tree dtype, data;
6588 tree offs, stride;
6589 tree lbound, ubound;
6591 /* Set dtype. */
6592 dtype = gfc_conv_descriptor_dtype (desc);
6593 tmp = gfc_get_dtype (TREE_TYPE (desc));
6594 gfc_add_modify (&block, dtype, tmp);
6596 /* Copy data pointer. */
6597 data = gfc_conv_descriptor_data_get (rse.expr);
6598 gfc_conv_descriptor_data_set (&block, desc, data);
6600 /* Copy offset but adjust it such that it would correspond
6601 to a lbound of zero. */
6602 offs = gfc_conv_descriptor_offset_get (rse.expr);
6603 for (dim = 0; dim < expr2->rank; ++dim)
6605 stride = gfc_conv_descriptor_stride_get (rse.expr,
6606 gfc_rank_cst[dim]);
6607 lbound = gfc_conv_descriptor_lbound_get (rse.expr,
6608 gfc_rank_cst[dim]);
6609 tmp = fold_build2_loc (input_location, MULT_EXPR,
6610 gfc_array_index_type, stride, lbound);
6611 offs = fold_build2_loc (input_location, PLUS_EXPR,
6612 gfc_array_index_type, offs, tmp);
6614 gfc_conv_descriptor_offset_set (&block, desc, offs);
6616 /* Set the bounds as declared for the LHS and calculate strides as
6617 well as another offset update accordingly. */
6618 stride = gfc_conv_descriptor_stride_get (rse.expr,
6619 gfc_rank_cst[0]);
6620 for (dim = 0; dim < expr1->rank; ++dim)
6622 gfc_se lower_se;
6623 gfc_se upper_se;
6625 gcc_assert (remap->u.ar.start[dim] && remap->u.ar.end[dim]);
6627 /* Convert declared bounds. */
6628 gfc_init_se (&lower_se, NULL);
6629 gfc_init_se (&upper_se, NULL);
6630 gfc_conv_expr (&lower_se, remap->u.ar.start[dim]);
6631 gfc_conv_expr (&upper_se, remap->u.ar.end[dim]);
6633 gfc_add_block_to_block (&block, &lower_se.pre);
6634 gfc_add_block_to_block (&block, &upper_se.pre);
6636 lbound = fold_convert (gfc_array_index_type, lower_se.expr);
6637 ubound = fold_convert (gfc_array_index_type, upper_se.expr);
6639 lbound = gfc_evaluate_now (lbound, &block);
6640 ubound = gfc_evaluate_now (ubound, &block);
6642 gfc_add_block_to_block (&block, &lower_se.post);
6643 gfc_add_block_to_block (&block, &upper_se.post);
6645 /* Set bounds in descriptor. */
6646 gfc_conv_descriptor_lbound_set (&block, desc,
6647 gfc_rank_cst[dim], lbound);
6648 gfc_conv_descriptor_ubound_set (&block, desc,
6649 gfc_rank_cst[dim], ubound);
6651 /* Set stride. */
6652 stride = gfc_evaluate_now (stride, &block);
6653 gfc_conv_descriptor_stride_set (&block, desc,
6654 gfc_rank_cst[dim], stride);
6656 /* Update offset. */
6657 offs = gfc_conv_descriptor_offset_get (desc);
6658 tmp = fold_build2_loc (input_location, MULT_EXPR,
6659 gfc_array_index_type, lbound, stride);
6660 offs = fold_build2_loc (input_location, MINUS_EXPR,
6661 gfc_array_index_type, offs, tmp);
6662 offs = gfc_evaluate_now (offs, &block);
6663 gfc_conv_descriptor_offset_set (&block, desc, offs);
6665 /* Update stride. */
6666 tmp = gfc_conv_array_extent_dim (lbound, ubound, NULL);
6667 stride = fold_build2_loc (input_location, MULT_EXPR,
6668 gfc_array_index_type, stride, tmp);
6671 else
6673 /* Bounds remapping. Just shift the lower bounds. */
6675 gcc_assert (expr1->rank == expr2->rank);
6677 for (dim = 0; dim < remap->u.ar.dimen; ++dim)
6679 gfc_se lbound_se;
6681 gcc_assert (remap->u.ar.start[dim]);
6682 gcc_assert (!remap->u.ar.end[dim]);
6683 gfc_init_se (&lbound_se, NULL);
6684 gfc_conv_expr (&lbound_se, remap->u.ar.start[dim]);
6686 gfc_add_block_to_block (&block, &lbound_se.pre);
6687 gfc_conv_shift_descriptor_lbound (&block, desc,
6688 dim, lbound_se.expr);
6689 gfc_add_block_to_block (&block, &lbound_se.post);
6694 /* Check string lengths if applicable. The check is only really added
6695 to the output code if -fbounds-check is enabled. */
6696 if (expr1->ts.type == BT_CHARACTER && expr2->expr_type != EXPR_NULL)
6698 gcc_assert (expr2->ts.type == BT_CHARACTER);
6699 gcc_assert (strlen_lhs && strlen_rhs);
6700 gfc_trans_same_strlen_check ("pointer assignment", &expr1->where,
6701 strlen_lhs, strlen_rhs, &block);
6704 /* If rank remapping was done, check with -fcheck=bounds that
6705 the target is at least as large as the pointer. */
6706 if (rank_remap && (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS))
6708 tree lsize, rsize;
6709 tree fault;
6710 const char* msg;
6712 lsize = gfc_conv_descriptor_size (lse.expr, expr1->rank);
6713 rsize = gfc_conv_descriptor_size (rse.expr, expr2->rank);
6715 lsize = gfc_evaluate_now (lsize, &block);
6716 rsize = gfc_evaluate_now (rsize, &block);
6717 fault = fold_build2_loc (input_location, LT_EXPR, boolean_type_node,
6718 rsize, lsize);
6720 msg = _("Target of rank remapping is too small (%ld < %ld)");
6721 gfc_trans_runtime_check (true, false, fault, &block, &expr2->where,
6722 msg, rsize, lsize);
6725 gfc_add_block_to_block (&block, &lse.post);
6726 if (rank_remap)
6727 gfc_add_block_to_block (&block, &rse.post);
6730 return gfc_finish_block (&block);
6734 /* Makes sure se is suitable for passing as a function string parameter. */
6735 /* TODO: Need to check all callers of this function. It may be abused. */
6737 void
6738 gfc_conv_string_parameter (gfc_se * se)
6740 tree type;
6742 if (TREE_CODE (se->expr) == STRING_CST)
6744 type = TREE_TYPE (TREE_TYPE (se->expr));
6745 se->expr = gfc_build_addr_expr (build_pointer_type (type), se->expr);
6746 return;
6749 if (TYPE_STRING_FLAG (TREE_TYPE (se->expr)))
6751 if (TREE_CODE (se->expr) != INDIRECT_REF)
6753 type = TREE_TYPE (se->expr);
6754 se->expr = gfc_build_addr_expr (build_pointer_type (type), se->expr);
6756 else
6758 type = gfc_get_character_type_len (gfc_default_character_kind,
6759 se->string_length);
6760 type = build_pointer_type (type);
6761 se->expr = gfc_build_addr_expr (type, se->expr);
6765 gcc_assert (POINTER_TYPE_P (TREE_TYPE (se->expr)));
6769 /* Generate code for assignment of scalar variables. Includes character
6770 strings and derived types with allocatable components.
6771 If you know that the LHS has no allocations, set dealloc to false.
6773 DEEP_COPY has no effect if the typespec TS is not a derived type with
6774 allocatable components. Otherwise, if it is set, an explicit copy of each
6775 allocatable component is made. This is necessary as a simple copy of the
6776 whole object would copy array descriptors as is, so that the lhs's
6777 allocatable components would point to the rhs's after the assignment.
6778 Typically, setting DEEP_COPY is necessary if the rhs is a variable, and not
6779 necessary if the rhs is a non-pointer function, as the allocatable components
6780 are not accessible by other means than the function's result after the
6781 function has returned. It is even more subtle when temporaries are involved,
6782 as the two following examples show:
6783 1. When we evaluate an array constructor, a temporary is created. Thus
6784 there is theoretically no alias possible. However, no deep copy is
6785 made for this temporary, so that if the constructor is made of one or
6786 more variable with allocatable components, those components still point
6787 to the variable's: DEEP_COPY should be set for the assignment from the
6788 temporary to the lhs in that case.
6789 2. When assigning a scalar to an array, we evaluate the scalar value out
6790 of the loop, store it into a temporary variable, and assign from that.
6791 In that case, deep copying when assigning to the temporary would be a
6792 waste of resources; however deep copies should happen when assigning from
6793 the temporary to each array element: again DEEP_COPY should be set for
6794 the assignment from the temporary to the lhs. */
6796 tree
6797 gfc_trans_scalar_assign (gfc_se * lse, gfc_se * rse, gfc_typespec ts,
6798 bool l_is_temp, bool deep_copy, bool dealloc)
6800 stmtblock_t block;
6801 tree tmp;
6802 tree cond;
6804 gfc_init_block (&block);
6806 if (ts.type == BT_CHARACTER)
6808 tree rlen = NULL;
6809 tree llen = NULL;
6811 if (lse->string_length != NULL_TREE)
6813 gfc_conv_string_parameter (lse);
6814 gfc_add_block_to_block (&block, &lse->pre);
6815 llen = lse->string_length;
6818 if (rse->string_length != NULL_TREE)
6820 gcc_assert (rse->string_length != NULL_TREE);
6821 gfc_conv_string_parameter (rse);
6822 gfc_add_block_to_block (&block, &rse->pre);
6823 rlen = rse->string_length;
6826 gfc_trans_string_copy (&block, llen, lse->expr, ts.kind, rlen,
6827 rse->expr, ts.kind);
6829 else if (ts.type == BT_DERIVED && ts.u.derived->attr.alloc_comp)
6831 cond = NULL_TREE;
6833 /* Are the rhs and the lhs the same? */
6834 if (deep_copy)
6836 cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
6837 gfc_build_addr_expr (NULL_TREE, lse->expr),
6838 gfc_build_addr_expr (NULL_TREE, rse->expr));
6839 cond = gfc_evaluate_now (cond, &lse->pre);
6842 /* Deallocate the lhs allocated components as long as it is not
6843 the same as the rhs. This must be done following the assignment
6844 to prevent deallocating data that could be used in the rhs
6845 expression. */
6846 if (!l_is_temp && dealloc)
6848 tmp = gfc_evaluate_now (lse->expr, &lse->pre);
6849 tmp = gfc_deallocate_alloc_comp (ts.u.derived, tmp, 0);
6850 if (deep_copy)
6851 tmp = build3_v (COND_EXPR, cond, build_empty_stmt (input_location),
6852 tmp);
6853 gfc_add_expr_to_block (&lse->post, tmp);
6856 gfc_add_block_to_block (&block, &rse->pre);
6857 gfc_add_block_to_block (&block, &lse->pre);
6859 gfc_add_modify (&block, lse->expr,
6860 fold_convert (TREE_TYPE (lse->expr), rse->expr));
6862 /* Do a deep copy if the rhs is a variable, if it is not the
6863 same as the lhs. */
6864 if (deep_copy)
6866 tmp = gfc_copy_alloc_comp (ts.u.derived, rse->expr, lse->expr, 0);
6867 tmp = build3_v (COND_EXPR, cond, build_empty_stmt (input_location),
6868 tmp);
6869 gfc_add_expr_to_block (&block, tmp);
6872 else if (ts.type == BT_DERIVED || ts.type == BT_CLASS)
6874 gfc_add_block_to_block (&block, &lse->pre);
6875 gfc_add_block_to_block (&block, &rse->pre);
6876 tmp = fold_build1_loc (input_location, VIEW_CONVERT_EXPR,
6877 TREE_TYPE (lse->expr), rse->expr);
6878 gfc_add_modify (&block, lse->expr, tmp);
6880 else
6882 gfc_add_block_to_block (&block, &lse->pre);
6883 gfc_add_block_to_block (&block, &rse->pre);
6885 gfc_add_modify (&block, lse->expr,
6886 fold_convert (TREE_TYPE (lse->expr), rse->expr));
6889 gfc_add_block_to_block (&block, &lse->post);
6890 gfc_add_block_to_block (&block, &rse->post);
6892 return gfc_finish_block (&block);
6896 /* There are quite a lot of restrictions on the optimisation in using an
6897 array function assign without a temporary. */
6899 static bool
6900 arrayfunc_assign_needs_temporary (gfc_expr * expr1, gfc_expr * expr2)
6902 gfc_ref * ref;
6903 bool seen_array_ref;
6904 bool c = false;
6905 gfc_symbol *sym = expr1->symtree->n.sym;
6907 /* The caller has already checked rank>0 and expr_type == EXPR_FUNCTION. */
6908 if (expr2->value.function.isym && !gfc_is_intrinsic_libcall (expr2))
6909 return true;
6911 /* Elemental functions are scalarized so that they don't need a
6912 temporary in gfc_trans_assignment_1, so return a true. Otherwise,
6913 they would need special treatment in gfc_trans_arrayfunc_assign. */
6914 if (expr2->value.function.esym != NULL
6915 && expr2->value.function.esym->attr.elemental)
6916 return true;
6918 /* Need a temporary if rhs is not FULL or a contiguous section. */
6919 if (expr1->ref && !(gfc_full_array_ref_p (expr1->ref, &c) || c))
6920 return true;
6922 /* Need a temporary if EXPR1 can't be expressed as a descriptor. */
6923 if (gfc_ref_needs_temporary_p (expr1->ref))
6924 return true;
6926 /* Functions returning pointers or allocatables need temporaries. */
6927 c = expr2->value.function.esym
6928 ? (expr2->value.function.esym->attr.pointer
6929 || expr2->value.function.esym->attr.allocatable)
6930 : (expr2->symtree->n.sym->attr.pointer
6931 || expr2->symtree->n.sym->attr.allocatable);
6932 if (c)
6933 return true;
6935 /* Character array functions need temporaries unless the
6936 character lengths are the same. */
6937 if (expr2->ts.type == BT_CHARACTER && expr2->rank > 0)
6939 if (expr1->ts.u.cl->length == NULL
6940 || expr1->ts.u.cl->length->expr_type != EXPR_CONSTANT)
6941 return true;
6943 if (expr2->ts.u.cl->length == NULL
6944 || expr2->ts.u.cl->length->expr_type != EXPR_CONSTANT)
6945 return true;
6947 if (mpz_cmp (expr1->ts.u.cl->length->value.integer,
6948 expr2->ts.u.cl->length->value.integer) != 0)
6949 return true;
6952 /* Check that no LHS component references appear during an array
6953 reference. This is needed because we do not have the means to
6954 span any arbitrary stride with an array descriptor. This check
6955 is not needed for the rhs because the function result has to be
6956 a complete type. */
6957 seen_array_ref = false;
6958 for (ref = expr1->ref; ref; ref = ref->next)
6960 if (ref->type == REF_ARRAY)
6961 seen_array_ref= true;
6962 else if (ref->type == REF_COMPONENT && seen_array_ref)
6963 return true;
6966 /* Check for a dependency. */
6967 if (gfc_check_fncall_dependency (expr1, INTENT_OUT,
6968 expr2->value.function.esym,
6969 expr2->value.function.actual,
6970 NOT_ELEMENTAL))
6971 return true;
6973 /* If we have reached here with an intrinsic function, we do not
6974 need a temporary except in the particular case that reallocation
6975 on assignment is active and the lhs is allocatable and a target. */
6976 if (expr2->value.function.isym)
6977 return (gfc_option.flag_realloc_lhs
6978 && sym->attr.allocatable
6979 && sym->attr.target);
6981 /* If the LHS is a dummy, we need a temporary if it is not
6982 INTENT(OUT). */
6983 if (sym->attr.dummy && sym->attr.intent != INTENT_OUT)
6984 return true;
6986 /* If the lhs has been host_associated, is in common, a pointer or is
6987 a target and the function is not using a RESULT variable, aliasing
6988 can occur and a temporary is needed. */
6989 if ((sym->attr.host_assoc
6990 || sym->attr.in_common
6991 || sym->attr.pointer
6992 || sym->attr.cray_pointee
6993 || sym->attr.target)
6994 && expr2->symtree != NULL
6995 && expr2->symtree->n.sym == expr2->symtree->n.sym->result)
6996 return true;
6998 /* A PURE function can unconditionally be called without a temporary. */
6999 if (expr2->value.function.esym != NULL
7000 && expr2->value.function.esym->attr.pure)
7001 return false;
7003 /* Implicit_pure functions are those which could legally be declared
7004 to be PURE. */
7005 if (expr2->value.function.esym != NULL
7006 && expr2->value.function.esym->attr.implicit_pure)
7007 return false;
7009 if (!sym->attr.use_assoc
7010 && !sym->attr.in_common
7011 && !sym->attr.pointer
7012 && !sym->attr.target
7013 && !sym->attr.cray_pointee
7014 && expr2->value.function.esym)
7016 /* A temporary is not needed if the function is not contained and
7017 the variable is local or host associated and not a pointer or
7018 a target. */
7019 if (!expr2->value.function.esym->attr.contained)
7020 return false;
7022 /* A temporary is not needed if the lhs has never been host
7023 associated and the procedure is contained. */
7024 else if (!sym->attr.host_assoc)
7025 return false;
7027 /* A temporary is not needed if the variable is local and not
7028 a pointer, a target or a result. */
7029 if (sym->ns->parent
7030 && expr2->value.function.esym->ns == sym->ns->parent)
7031 return false;
7034 /* Default to temporary use. */
7035 return true;
7039 /* Provide the loop info so that the lhs descriptor can be built for
7040 reallocatable assignments from extrinsic function calls. */
7042 static void
7043 realloc_lhs_loop_for_fcn_call (gfc_se *se, locus *where, gfc_ss **ss,
7044 gfc_loopinfo *loop)
7046 /* Signal that the function call should not be made by
7047 gfc_conv_loop_setup. */
7048 se->ss->is_alloc_lhs = 1;
7049 gfc_init_loopinfo (loop);
7050 gfc_add_ss_to_loop (loop, *ss);
7051 gfc_add_ss_to_loop (loop, se->ss);
7052 gfc_conv_ss_startstride (loop);
7053 gfc_conv_loop_setup (loop, where);
7054 gfc_copy_loopinfo_to_se (se, loop);
7055 gfc_add_block_to_block (&se->pre, &loop->pre);
7056 gfc_add_block_to_block (&se->pre, &loop->post);
7057 se->ss->is_alloc_lhs = 0;
7061 /* For assignment to a reallocatable lhs from intrinsic functions,
7062 replace the se.expr (ie. the result) with a temporary descriptor.
7063 Null the data field so that the library allocates space for the
7064 result. Free the data of the original descriptor after the function,
7065 in case it appears in an argument expression and transfer the
7066 result to the original descriptor. */
7068 static void
7069 fcncall_realloc_result (gfc_se *se, int rank)
7071 tree desc;
7072 tree res_desc;
7073 tree tmp;
7074 tree offset;
7075 tree zero_cond;
7076 int n;
7078 /* Use the allocation done by the library. Substitute the lhs
7079 descriptor with a copy, whose data field is nulled.*/
7080 desc = build_fold_indirect_ref_loc (input_location, se->expr);
7081 if (POINTER_TYPE_P (TREE_TYPE (desc)))
7082 desc = build_fold_indirect_ref_loc (input_location, desc);
7084 /* Unallocated, the descriptor does not have a dtype. */
7085 tmp = gfc_conv_descriptor_dtype (desc);
7086 gfc_add_modify (&se->pre, tmp, gfc_get_dtype (TREE_TYPE (desc)));
7088 res_desc = gfc_evaluate_now (desc, &se->pre);
7089 gfc_conv_descriptor_data_set (&se->pre, res_desc, null_pointer_node);
7090 se->expr = gfc_build_addr_expr (TREE_TYPE (se->expr), res_desc);
7092 /* Free the lhs after the function call and copy the result data to
7093 the lhs descriptor. */
7094 tmp = gfc_conv_descriptor_data_get (desc);
7095 zero_cond = fold_build2_loc (input_location, EQ_EXPR,
7096 boolean_type_node, tmp,
7097 build_int_cst (TREE_TYPE (tmp), 0));
7098 zero_cond = gfc_evaluate_now (zero_cond, &se->post);
7099 tmp = gfc_call_free (fold_convert (pvoid_type_node, tmp));
7100 gfc_add_expr_to_block (&se->post, tmp);
7102 tmp = gfc_conv_descriptor_data_get (res_desc);
7103 gfc_conv_descriptor_data_set (&se->post, desc, tmp);
7105 /* Check that the shapes are the same between lhs and expression. */
7106 for (n = 0 ; n < rank; n++)
7108 tree tmp1;
7109 tmp = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[n]);
7110 tmp1 = gfc_conv_descriptor_lbound_get (res_desc, gfc_rank_cst[n]);
7111 tmp = fold_build2_loc (input_location, MINUS_EXPR,
7112 gfc_array_index_type, tmp, tmp1);
7113 tmp1 = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[n]);
7114 tmp = fold_build2_loc (input_location, MINUS_EXPR,
7115 gfc_array_index_type, tmp, tmp1);
7116 tmp1 = gfc_conv_descriptor_ubound_get (res_desc, gfc_rank_cst[n]);
7117 tmp = fold_build2_loc (input_location, PLUS_EXPR,
7118 gfc_array_index_type, tmp, tmp1);
7119 tmp = fold_build2_loc (input_location, NE_EXPR,
7120 boolean_type_node, tmp,
7121 gfc_index_zero_node);
7122 tmp = gfc_evaluate_now (tmp, &se->post);
7123 zero_cond = fold_build2_loc (input_location, TRUTH_OR_EXPR,
7124 boolean_type_node, tmp,
7125 zero_cond);
7128 /* 'zero_cond' being true is equal to lhs not being allocated or the
7129 shapes being different. */
7130 zero_cond = gfc_evaluate_now (zero_cond, &se->post);
7132 /* Now reset the bounds returned from the function call to bounds based
7133 on the lhs lbounds, except where the lhs is not allocated or the shapes
7134 of 'variable and 'expr' are different. Set the offset accordingly. */
7135 offset = gfc_index_zero_node;
7136 for (n = 0 ; n < rank; n++)
7138 tree lbound;
7140 lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[n]);
7141 lbound = fold_build3_loc (input_location, COND_EXPR,
7142 gfc_array_index_type, zero_cond,
7143 gfc_index_one_node, lbound);
7144 lbound = gfc_evaluate_now (lbound, &se->post);
7146 tmp = gfc_conv_descriptor_ubound_get (res_desc, gfc_rank_cst[n]);
7147 tmp = fold_build2_loc (input_location, PLUS_EXPR,
7148 gfc_array_index_type, tmp, lbound);
7149 gfc_conv_descriptor_lbound_set (&se->post, desc,
7150 gfc_rank_cst[n], lbound);
7151 gfc_conv_descriptor_ubound_set (&se->post, desc,
7152 gfc_rank_cst[n], tmp);
7154 /* Set stride and accumulate the offset. */
7155 tmp = gfc_conv_descriptor_stride_get (res_desc, gfc_rank_cst[n]);
7156 gfc_conv_descriptor_stride_set (&se->post, desc,
7157 gfc_rank_cst[n], tmp);
7158 tmp = fold_build2_loc (input_location, MULT_EXPR,
7159 gfc_array_index_type, lbound, tmp);
7160 offset = fold_build2_loc (input_location, MINUS_EXPR,
7161 gfc_array_index_type, offset, tmp);
7162 offset = gfc_evaluate_now (offset, &se->post);
7165 gfc_conv_descriptor_offset_set (&se->post, desc, offset);
7170 /* Try to translate array(:) = func (...), where func is a transformational
7171 array function, without using a temporary. Returns NULL if this isn't the
7172 case. */
7174 static tree
7175 gfc_trans_arrayfunc_assign (gfc_expr * expr1, gfc_expr * expr2)
7177 gfc_se se;
7178 gfc_ss *ss = NULL;
7179 gfc_component *comp = NULL;
7180 gfc_loopinfo loop;
7182 if (arrayfunc_assign_needs_temporary (expr1, expr2))
7183 return NULL;
7185 /* The frontend doesn't seem to bother filling in expr->symtree for intrinsic
7186 functions. */
7187 comp = gfc_get_proc_ptr_comp (expr2);
7188 gcc_assert (expr2->value.function.isym
7189 || (comp && comp->attr.dimension)
7190 || (!comp && gfc_return_by_reference (expr2->value.function.esym)
7191 && expr2->value.function.esym->result->attr.dimension));
7193 gfc_init_se (&se, NULL);
7194 gfc_start_block (&se.pre);
7195 se.want_pointer = 1;
7197 gfc_conv_array_parameter (&se, expr1, false, NULL, NULL, NULL);
7199 if (expr1->ts.type == BT_DERIVED
7200 && expr1->ts.u.derived->attr.alloc_comp)
7202 tree tmp;
7203 tmp = gfc_deallocate_alloc_comp (expr1->ts.u.derived, se.expr,
7204 expr1->rank);
7205 gfc_add_expr_to_block (&se.pre, tmp);
7208 se.direct_byref = 1;
7209 se.ss = gfc_walk_expr (expr2);
7210 gcc_assert (se.ss != gfc_ss_terminator);
7212 /* Reallocate on assignment needs the loopinfo for extrinsic functions.
7213 This is signalled to gfc_conv_procedure_call by setting is_alloc_lhs.
7214 Clearly, this cannot be done for an allocatable function result, since
7215 the shape of the result is unknown and, in any case, the function must
7216 correctly take care of the reallocation internally. For intrinsic
7217 calls, the array data is freed and the library takes care of allocation.
7218 TODO: Add logic of trans-array.c: gfc_alloc_allocatable_for_assignment
7219 to the library. */
7220 if (gfc_option.flag_realloc_lhs
7221 && gfc_is_reallocatable_lhs (expr1)
7222 && !gfc_expr_attr (expr1).codimension
7223 && !gfc_is_coindexed (expr1)
7224 && !(expr2->value.function.esym
7225 && expr2->value.function.esym->result->attr.allocatable))
7227 realloc_lhs_warning (expr1->ts.type, true, &expr1->where);
7229 if (!expr2->value.function.isym)
7231 ss = gfc_walk_expr (expr1);
7232 gcc_assert (ss != gfc_ss_terminator);
7234 realloc_lhs_loop_for_fcn_call (&se, &expr1->where, &ss, &loop);
7235 ss->is_alloc_lhs = 1;
7237 else
7238 fcncall_realloc_result (&se, expr1->rank);
7241 gfc_conv_function_expr (&se, expr2);
7242 gfc_add_block_to_block (&se.pre, &se.post);
7244 if (ss)
7245 gfc_cleanup_loop (&loop);
7246 else
7247 gfc_free_ss_chain (se.ss);
7249 return gfc_finish_block (&se.pre);
7253 /* Try to efficiently translate array(:) = 0. Return NULL if this
7254 can't be done. */
7256 static tree
7257 gfc_trans_zero_assign (gfc_expr * expr)
7259 tree dest, len, type;
7260 tree tmp;
7261 gfc_symbol *sym;
7263 sym = expr->symtree->n.sym;
7264 dest = gfc_get_symbol_decl (sym);
7266 type = TREE_TYPE (dest);
7267 if (POINTER_TYPE_P (type))
7268 type = TREE_TYPE (type);
7269 if (!GFC_ARRAY_TYPE_P (type))
7270 return NULL_TREE;
7272 /* Determine the length of the array. */
7273 len = GFC_TYPE_ARRAY_SIZE (type);
7274 if (!len || TREE_CODE (len) != INTEGER_CST)
7275 return NULL_TREE;
7277 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type));
7278 len = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type, len,
7279 fold_convert (gfc_array_index_type, tmp));
7281 /* If we are zeroing a local array avoid taking its address by emitting
7282 a = {} instead. */
7283 if (!POINTER_TYPE_P (TREE_TYPE (dest)))
7284 return build2_loc (input_location, MODIFY_EXPR, void_type_node,
7285 dest, build_constructor (TREE_TYPE (dest),
7286 NULL));
7288 /* Convert arguments to the correct types. */
7289 dest = fold_convert (pvoid_type_node, dest);
7290 len = fold_convert (size_type_node, len);
7292 /* Construct call to __builtin_memset. */
7293 tmp = build_call_expr_loc (input_location,
7294 builtin_decl_explicit (BUILT_IN_MEMSET),
7295 3, dest, integer_zero_node, len);
7296 return fold_convert (void_type_node, tmp);
7300 /* Helper for gfc_trans_array_copy and gfc_trans_array_constructor_copy
7301 that constructs the call to __builtin_memcpy. */
7303 tree
7304 gfc_build_memcpy_call (tree dst, tree src, tree len)
7306 tree tmp;
7308 /* Convert arguments to the correct types. */
7309 if (!POINTER_TYPE_P (TREE_TYPE (dst)))
7310 dst = gfc_build_addr_expr (pvoid_type_node, dst);
7311 else
7312 dst = fold_convert (pvoid_type_node, dst);
7314 if (!POINTER_TYPE_P (TREE_TYPE (src)))
7315 src = gfc_build_addr_expr (pvoid_type_node, src);
7316 else
7317 src = fold_convert (pvoid_type_node, src);
7319 len = fold_convert (size_type_node, len);
7321 /* Construct call to __builtin_memcpy. */
7322 tmp = build_call_expr_loc (input_location,
7323 builtin_decl_explicit (BUILT_IN_MEMCPY),
7324 3, dst, src, len);
7325 return fold_convert (void_type_node, tmp);
7329 /* Try to efficiently translate dst(:) = src(:). Return NULL if this
7330 can't be done. EXPR1 is the destination/lhs and EXPR2 is the
7331 source/rhs, both are gfc_full_array_ref_p which have been checked for
7332 dependencies. */
7334 static tree
7335 gfc_trans_array_copy (gfc_expr * expr1, gfc_expr * expr2)
7337 tree dst, dlen, dtype;
7338 tree src, slen, stype;
7339 tree tmp;
7341 dst = gfc_get_symbol_decl (expr1->symtree->n.sym);
7342 src = gfc_get_symbol_decl (expr2->symtree->n.sym);
7344 dtype = TREE_TYPE (dst);
7345 if (POINTER_TYPE_P (dtype))
7346 dtype = TREE_TYPE (dtype);
7347 stype = TREE_TYPE (src);
7348 if (POINTER_TYPE_P (stype))
7349 stype = TREE_TYPE (stype);
7351 if (!GFC_ARRAY_TYPE_P (dtype) || !GFC_ARRAY_TYPE_P (stype))
7352 return NULL_TREE;
7354 /* Determine the lengths of the arrays. */
7355 dlen = GFC_TYPE_ARRAY_SIZE (dtype);
7356 if (!dlen || TREE_CODE (dlen) != INTEGER_CST)
7357 return NULL_TREE;
7358 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (dtype));
7359 dlen = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
7360 dlen, fold_convert (gfc_array_index_type, tmp));
7362 slen = GFC_TYPE_ARRAY_SIZE (stype);
7363 if (!slen || TREE_CODE (slen) != INTEGER_CST)
7364 return NULL_TREE;
7365 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (stype));
7366 slen = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
7367 slen, fold_convert (gfc_array_index_type, tmp));
7369 /* Sanity check that they are the same. This should always be
7370 the case, as we should already have checked for conformance. */
7371 if (!tree_int_cst_equal (slen, dlen))
7372 return NULL_TREE;
7374 return gfc_build_memcpy_call (dst, src, dlen);
7378 /* Try to efficiently translate array(:) = (/ ... /). Return NULL if
7379 this can't be done. EXPR1 is the destination/lhs for which
7380 gfc_full_array_ref_p is true, and EXPR2 is the source/rhs. */
7382 static tree
7383 gfc_trans_array_constructor_copy (gfc_expr * expr1, gfc_expr * expr2)
7385 unsigned HOST_WIDE_INT nelem;
7386 tree dst, dtype;
7387 tree src, stype;
7388 tree len;
7389 tree tmp;
7391 nelem = gfc_constant_array_constructor_p (expr2->value.constructor);
7392 if (nelem == 0)
7393 return NULL_TREE;
7395 dst = gfc_get_symbol_decl (expr1->symtree->n.sym);
7396 dtype = TREE_TYPE (dst);
7397 if (POINTER_TYPE_P (dtype))
7398 dtype = TREE_TYPE (dtype);
7399 if (!GFC_ARRAY_TYPE_P (dtype))
7400 return NULL_TREE;
7402 /* Determine the lengths of the array. */
7403 len = GFC_TYPE_ARRAY_SIZE (dtype);
7404 if (!len || TREE_CODE (len) != INTEGER_CST)
7405 return NULL_TREE;
7407 /* Confirm that the constructor is the same size. */
7408 if (compare_tree_int (len, nelem) != 0)
7409 return NULL_TREE;
7411 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (dtype));
7412 len = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type, len,
7413 fold_convert (gfc_array_index_type, tmp));
7415 stype = gfc_typenode_for_spec (&expr2->ts);
7416 src = gfc_build_constant_array_constructor (expr2, stype);
7418 stype = TREE_TYPE (src);
7419 if (POINTER_TYPE_P (stype))
7420 stype = TREE_TYPE (stype);
7422 return gfc_build_memcpy_call (dst, src, len);
7426 /* Tells whether the expression is to be treated as a variable reference. */
7428 static bool
7429 expr_is_variable (gfc_expr *expr)
7431 gfc_expr *arg;
7432 gfc_component *comp;
7433 gfc_symbol *func_ifc;
7435 if (expr->expr_type == EXPR_VARIABLE)
7436 return true;
7438 arg = gfc_get_noncopying_intrinsic_argument (expr);
7439 if (arg)
7441 gcc_assert (expr->value.function.isym->id == GFC_ISYM_TRANSPOSE);
7442 return expr_is_variable (arg);
7445 /* A data-pointer-returning function should be considered as a variable
7446 too. */
7447 if (expr->expr_type == EXPR_FUNCTION
7448 && expr->ref == NULL)
7450 if (expr->value.function.isym != NULL)
7451 return false;
7453 if (expr->value.function.esym != NULL)
7455 func_ifc = expr->value.function.esym;
7456 goto found_ifc;
7458 else
7460 gcc_assert (expr->symtree);
7461 func_ifc = expr->symtree->n.sym;
7462 goto found_ifc;
7465 gcc_unreachable ();
7468 comp = gfc_get_proc_ptr_comp (expr);
7469 if ((expr->expr_type == EXPR_PPC || expr->expr_type == EXPR_FUNCTION)
7470 && comp)
7472 func_ifc = comp->ts.interface;
7473 goto found_ifc;
7476 if (expr->expr_type == EXPR_COMPCALL)
7478 gcc_assert (!expr->value.compcall.tbp->is_generic);
7479 func_ifc = expr->value.compcall.tbp->u.specific->n.sym;
7480 goto found_ifc;
7483 return false;
7485 found_ifc:
7486 gcc_assert (func_ifc->attr.function
7487 && func_ifc->result != NULL);
7488 return func_ifc->result->attr.pointer;
7492 /* Is the lhs OK for automatic reallocation? */
7494 static bool
7495 is_scalar_reallocatable_lhs (gfc_expr *expr)
7497 gfc_ref * ref;
7499 /* An allocatable variable with no reference. */
7500 if (expr->symtree->n.sym->attr.allocatable
7501 && !expr->ref)
7502 return true;
7504 /* All that can be left are allocatable components. */
7505 if ((expr->symtree->n.sym->ts.type != BT_DERIVED
7506 && expr->symtree->n.sym->ts.type != BT_CLASS)
7507 || !expr->symtree->n.sym->ts.u.derived->attr.alloc_comp)
7508 return false;
7510 /* Find an allocatable component ref last. */
7511 for (ref = expr->ref; ref; ref = ref->next)
7512 if (ref->type == REF_COMPONENT
7513 && !ref->next
7514 && ref->u.c.component->attr.allocatable)
7515 return true;
7517 return false;
7521 /* Allocate or reallocate scalar lhs, as necessary. */
7523 static void
7524 alloc_scalar_allocatable_for_assignment (stmtblock_t *block,
7525 tree string_length,
7526 gfc_expr *expr1,
7527 gfc_expr *expr2)
7530 tree cond;
7531 tree tmp;
7532 tree size;
7533 tree size_in_bytes;
7534 tree jump_label1;
7535 tree jump_label2;
7536 gfc_se lse;
7538 if (!expr1 || expr1->rank)
7539 return;
7541 if (!expr2 || expr2->rank)
7542 return;
7544 realloc_lhs_warning (expr2->ts.type, false, &expr2->where);
7546 /* Since this is a scalar lhs, we can afford to do this. That is,
7547 there is no risk of side effects being repeated. */
7548 gfc_init_se (&lse, NULL);
7549 lse.want_pointer = 1;
7550 gfc_conv_expr (&lse, expr1);
7552 jump_label1 = gfc_build_label_decl (NULL_TREE);
7553 jump_label2 = gfc_build_label_decl (NULL_TREE);
7555 /* Do the allocation if the lhs is NULL. Otherwise go to label 1. */
7556 tmp = build_int_cst (TREE_TYPE (lse.expr), 0);
7557 cond = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
7558 lse.expr, tmp);
7559 tmp = build3_v (COND_EXPR, cond,
7560 build1_v (GOTO_EXPR, jump_label1),
7561 build_empty_stmt (input_location));
7562 gfc_add_expr_to_block (block, tmp);
7564 if (expr1->ts.type == BT_CHARACTER && expr1->ts.deferred)
7566 /* Use the rhs string length and the lhs element size. */
7567 size = string_length;
7568 tmp = TREE_TYPE (gfc_typenode_for_spec (&expr1->ts));
7569 tmp = TYPE_SIZE_UNIT (tmp);
7570 size_in_bytes = fold_build2_loc (input_location, MULT_EXPR,
7571 TREE_TYPE (tmp), tmp,
7572 fold_convert (TREE_TYPE (tmp), size));
7574 else
7576 /* Otherwise use the length in bytes of the rhs. */
7577 size = TYPE_SIZE_UNIT (gfc_typenode_for_spec (&expr1->ts));
7578 size_in_bytes = size;
7581 if (expr1->ts.type == BT_DERIVED && expr1->ts.u.derived->attr.alloc_comp)
7583 tmp = build_call_expr_loc (input_location,
7584 builtin_decl_explicit (BUILT_IN_CALLOC),
7585 2, build_one_cst (size_type_node),
7586 size_in_bytes);
7587 tmp = fold_convert (TREE_TYPE (lse.expr), tmp);
7588 gfc_add_modify (block, lse.expr, tmp);
7590 else
7592 tmp = build_call_expr_loc (input_location,
7593 builtin_decl_explicit (BUILT_IN_MALLOC),
7594 1, size_in_bytes);
7595 tmp = fold_convert (TREE_TYPE (lse.expr), tmp);
7596 gfc_add_modify (block, lse.expr, tmp);
7599 if (expr1->ts.type == BT_CHARACTER && expr1->ts.deferred)
7601 /* Deferred characters need checking for lhs and rhs string
7602 length. Other deferred parameter variables will have to
7603 come here too. */
7604 tmp = build1_v (GOTO_EXPR, jump_label2);
7605 gfc_add_expr_to_block (block, tmp);
7607 tmp = build1_v (LABEL_EXPR, jump_label1);
7608 gfc_add_expr_to_block (block, tmp);
7610 /* For a deferred length character, reallocate if lengths of lhs and
7611 rhs are different. */
7612 if (expr1->ts.type == BT_CHARACTER && expr1->ts.deferred)
7614 cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
7615 expr1->ts.u.cl->backend_decl, size);
7616 /* Jump past the realloc if the lengths are the same. */
7617 tmp = build3_v (COND_EXPR, cond,
7618 build1_v (GOTO_EXPR, jump_label2),
7619 build_empty_stmt (input_location));
7620 gfc_add_expr_to_block (block, tmp);
7621 tmp = build_call_expr_loc (input_location,
7622 builtin_decl_explicit (BUILT_IN_REALLOC),
7623 2, fold_convert (pvoid_type_node, lse.expr),
7624 size_in_bytes);
7625 tmp = fold_convert (TREE_TYPE (lse.expr), tmp);
7626 gfc_add_modify (block, lse.expr, tmp);
7627 tmp = build1_v (LABEL_EXPR, jump_label2);
7628 gfc_add_expr_to_block (block, tmp);
7630 /* Update the lhs character length. */
7631 size = string_length;
7632 gfc_add_modify (block, expr1->ts.u.cl->backend_decl, size);
7637 /* Subroutine of gfc_trans_assignment that actually scalarizes the
7638 assignment. EXPR1 is the destination/LHS and EXPR2 is the source/RHS.
7639 init_flag indicates initialization expressions and dealloc that no
7640 deallocate prior assignment is needed (if in doubt, set true). */
7642 static tree
7643 gfc_trans_assignment_1 (gfc_expr * expr1, gfc_expr * expr2, bool init_flag,
7644 bool dealloc)
7646 gfc_se lse;
7647 gfc_se rse;
7648 gfc_ss *lss;
7649 gfc_ss *lss_section;
7650 gfc_ss *rss;
7651 gfc_loopinfo loop;
7652 tree tmp;
7653 stmtblock_t block;
7654 stmtblock_t body;
7655 bool l_is_temp;
7656 bool scalar_to_array;
7657 tree string_length;
7658 int n;
7660 /* Assignment of the form lhs = rhs. */
7661 gfc_start_block (&block);
7663 gfc_init_se (&lse, NULL);
7664 gfc_init_se (&rse, NULL);
7666 /* Walk the lhs. */
7667 lss = gfc_walk_expr (expr1);
7668 if (gfc_is_reallocatable_lhs (expr1)
7669 && !(expr2->expr_type == EXPR_FUNCTION
7670 && expr2->value.function.isym != NULL))
7671 lss->is_alloc_lhs = 1;
7672 rss = NULL;
7673 if (lss != gfc_ss_terminator)
7675 /* The assignment needs scalarization. */
7676 lss_section = lss;
7678 /* Find a non-scalar SS from the lhs. */
7679 while (lss_section != gfc_ss_terminator
7680 && lss_section->info->type != GFC_SS_SECTION)
7681 lss_section = lss_section->next;
7683 gcc_assert (lss_section != gfc_ss_terminator);
7685 /* Initialize the scalarizer. */
7686 gfc_init_loopinfo (&loop);
7688 /* Walk the rhs. */
7689 rss = gfc_walk_expr (expr2);
7690 if (rss == gfc_ss_terminator)
7691 /* The rhs is scalar. Add a ss for the expression. */
7692 rss = gfc_get_scalar_ss (gfc_ss_terminator, expr2);
7694 /* Associate the SS with the loop. */
7695 gfc_add_ss_to_loop (&loop, lss);
7696 gfc_add_ss_to_loop (&loop, rss);
7698 /* Calculate the bounds of the scalarization. */
7699 gfc_conv_ss_startstride (&loop);
7700 /* Enable loop reversal. */
7701 for (n = 0; n < GFC_MAX_DIMENSIONS; n++)
7702 loop.reverse[n] = GFC_ENABLE_REVERSE;
7703 /* Resolve any data dependencies in the statement. */
7704 gfc_conv_resolve_dependencies (&loop, lss, rss);
7705 /* Setup the scalarizing loops. */
7706 gfc_conv_loop_setup (&loop, &expr2->where);
7708 /* Setup the gfc_se structures. */
7709 gfc_copy_loopinfo_to_se (&lse, &loop);
7710 gfc_copy_loopinfo_to_se (&rse, &loop);
7712 rse.ss = rss;
7713 gfc_mark_ss_chain_used (rss, 1);
7714 if (loop.temp_ss == NULL)
7716 lse.ss = lss;
7717 gfc_mark_ss_chain_used (lss, 1);
7719 else
7721 lse.ss = loop.temp_ss;
7722 gfc_mark_ss_chain_used (lss, 3);
7723 gfc_mark_ss_chain_used (loop.temp_ss, 3);
7726 /* Allow the scalarizer to workshare array assignments. */
7727 if ((ompws_flags & OMPWS_WORKSHARE_FLAG) && loop.temp_ss == NULL)
7728 ompws_flags |= OMPWS_SCALARIZER_WS;
7730 /* Start the scalarized loop body. */
7731 gfc_start_scalarized_body (&loop, &body);
7733 else
7734 gfc_init_block (&body);
7736 l_is_temp = (lss != gfc_ss_terminator && loop.temp_ss != NULL);
7738 /* Translate the expression. */
7739 gfc_conv_expr (&rse, expr2);
7741 /* Stabilize a string length for temporaries. */
7742 if (expr2->ts.type == BT_CHARACTER)
7743 string_length = gfc_evaluate_now (rse.string_length, &rse.pre);
7744 else
7745 string_length = NULL_TREE;
7747 if (l_is_temp)
7749 gfc_conv_tmp_array_ref (&lse);
7750 if (expr2->ts.type == BT_CHARACTER)
7751 lse.string_length = string_length;
7753 else
7754 gfc_conv_expr (&lse, expr1);
7756 /* Assignments of scalar derived types with allocatable components
7757 to arrays must be done with a deep copy and the rhs temporary
7758 must have its components deallocated afterwards. */
7759 scalar_to_array = (expr2->ts.type == BT_DERIVED
7760 && expr2->ts.u.derived->attr.alloc_comp
7761 && !expr_is_variable (expr2)
7762 && !gfc_is_constant_expr (expr2)
7763 && expr1->rank && !expr2->rank);
7764 if (scalar_to_array && dealloc)
7766 tmp = gfc_deallocate_alloc_comp (expr2->ts.u.derived, rse.expr, 0);
7767 gfc_add_expr_to_block (&loop.post, tmp);
7770 /* When assigning a character function result to a deferred-length variable,
7771 the function call must happen before the (re)allocation of the lhs -
7772 otherwise the character length of the result is not known.
7773 NOTE: This relies on having the exact dependence of the length type
7774 parameter available to the caller; gfortran saves it in the .mod files. */
7775 if (gfc_option.flag_realloc_lhs && expr2->ts.type == BT_CHARACTER
7776 && expr1->ts.deferred)
7777 gfc_add_block_to_block (&block, &rse.pre);
7779 tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts,
7780 l_is_temp || init_flag,
7781 expr_is_variable (expr2) || scalar_to_array
7782 || expr2->expr_type == EXPR_ARRAY, dealloc);
7783 gfc_add_expr_to_block (&body, tmp);
7785 if (lss == gfc_ss_terminator)
7787 /* F2003: Add the code for reallocation on assignment. */
7788 if (gfc_option.flag_realloc_lhs
7789 && is_scalar_reallocatable_lhs (expr1))
7790 alloc_scalar_allocatable_for_assignment (&block, rse.string_length,
7791 expr1, expr2);
7793 /* Use the scalar assignment as is. */
7794 gfc_add_block_to_block (&block, &body);
7796 else
7798 gcc_assert (lse.ss == gfc_ss_terminator
7799 && rse.ss == gfc_ss_terminator);
7801 if (l_is_temp)
7803 gfc_trans_scalarized_loop_boundary (&loop, &body);
7805 /* We need to copy the temporary to the actual lhs. */
7806 gfc_init_se (&lse, NULL);
7807 gfc_init_se (&rse, NULL);
7808 gfc_copy_loopinfo_to_se (&lse, &loop);
7809 gfc_copy_loopinfo_to_se (&rse, &loop);
7811 rse.ss = loop.temp_ss;
7812 lse.ss = lss;
7814 gfc_conv_tmp_array_ref (&rse);
7815 gfc_conv_expr (&lse, expr1);
7817 gcc_assert (lse.ss == gfc_ss_terminator
7818 && rse.ss == gfc_ss_terminator);
7820 if (expr2->ts.type == BT_CHARACTER)
7821 rse.string_length = string_length;
7823 tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts,
7824 false, false, dealloc);
7825 gfc_add_expr_to_block (&body, tmp);
7828 /* F2003: Allocate or reallocate lhs of allocatable array. */
7829 if (gfc_option.flag_realloc_lhs
7830 && gfc_is_reallocatable_lhs (expr1)
7831 && !gfc_expr_attr (expr1).codimension
7832 && !gfc_is_coindexed (expr1)
7833 && expr2->rank)
7835 realloc_lhs_warning (expr1->ts.type, true, &expr1->where);
7836 ompws_flags &= ~OMPWS_SCALARIZER_WS;
7837 tmp = gfc_alloc_allocatable_for_assignment (&loop, expr1, expr2);
7838 if (tmp != NULL_TREE)
7839 gfc_add_expr_to_block (&loop.code[expr1->rank - 1], tmp);
7842 /* Generate the copying loops. */
7843 gfc_trans_scalarizing_loops (&loop, &body);
7845 /* Wrap the whole thing up. */
7846 gfc_add_block_to_block (&block, &loop.pre);
7847 gfc_add_block_to_block (&block, &loop.post);
7849 gfc_cleanup_loop (&loop);
7852 return gfc_finish_block (&block);
7856 /* Check whether EXPR is a copyable array. */
7858 static bool
7859 copyable_array_p (gfc_expr * expr)
7861 if (expr->expr_type != EXPR_VARIABLE)
7862 return false;
7864 /* First check it's an array. */
7865 if (expr->rank < 1 || !expr->ref || expr->ref->next)
7866 return false;
7868 if (!gfc_full_array_ref_p (expr->ref, NULL))
7869 return false;
7871 /* Next check that it's of a simple enough type. */
7872 switch (expr->ts.type)
7874 case BT_INTEGER:
7875 case BT_REAL:
7876 case BT_COMPLEX:
7877 case BT_LOGICAL:
7878 return true;
7880 case BT_CHARACTER:
7881 return false;
7883 case BT_DERIVED:
7884 return !expr->ts.u.derived->attr.alloc_comp;
7886 default:
7887 break;
7890 return false;
7893 /* Translate an assignment. */
7895 tree
7896 gfc_trans_assignment (gfc_expr * expr1, gfc_expr * expr2, bool init_flag,
7897 bool dealloc)
7899 tree tmp;
7901 /* Special case a single function returning an array. */
7902 if (expr2->expr_type == EXPR_FUNCTION && expr2->rank > 0)
7904 tmp = gfc_trans_arrayfunc_assign (expr1, expr2);
7905 if (tmp)
7906 return tmp;
7909 /* Special case assigning an array to zero. */
7910 if (copyable_array_p (expr1)
7911 && is_zero_initializer_p (expr2))
7913 tmp = gfc_trans_zero_assign (expr1);
7914 if (tmp)
7915 return tmp;
7918 /* Special case copying one array to another. */
7919 if (copyable_array_p (expr1)
7920 && copyable_array_p (expr2)
7921 && gfc_compare_types (&expr1->ts, &expr2->ts)
7922 && !gfc_check_dependency (expr1, expr2, 0))
7924 tmp = gfc_trans_array_copy (expr1, expr2);
7925 if (tmp)
7926 return tmp;
7929 /* Special case initializing an array from a constant array constructor. */
7930 if (copyable_array_p (expr1)
7931 && expr2->expr_type == EXPR_ARRAY
7932 && gfc_compare_types (&expr1->ts, &expr2->ts))
7934 tmp = gfc_trans_array_constructor_copy (expr1, expr2);
7935 if (tmp)
7936 return tmp;
7939 /* Fallback to the scalarizer to generate explicit loops. */
7940 return gfc_trans_assignment_1 (expr1, expr2, init_flag, dealloc);
7943 tree
7944 gfc_trans_init_assign (gfc_code * code)
7946 return gfc_trans_assignment (code->expr1, code->expr2, true, false);
7949 tree
7950 gfc_trans_assign (gfc_code * code)
7952 return gfc_trans_assignment (code->expr1, code->expr2, false, true);