fortran/
[official-gcc.git] / gcc / fortran / trans-expr.c
blob12a75d0d156a47f5eb66c940919d4625fbe8d3a8
1 /* Expression translation
2 Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
3 2011, 2012
4 Free Software Foundation, Inc.
5 Contributed by Paul Brook <paul@nowt.org>
6 and Steven Bosscher <s.bosscher@student.tudelft.nl>
8 This file is part of GCC.
10 GCC is free software; you can redistribute it and/or modify it under
11 the terms of the GNU General Public License as published by the Free
12 Software Foundation; either version 3, or (at your option) any later
13 version.
15 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
16 WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 for more details.
20 You should have received a copy of the GNU General Public License
21 along with GCC; see the file COPYING3. If not see
22 <http://www.gnu.org/licenses/>. */
24 /* trans-expr.c-- generate GENERIC trees for gfc_expr. */
26 #include "config.h"
27 #include "system.h"
28 #include "coretypes.h"
29 #include "tree.h"
30 #include "diagnostic-core.h" /* For fatal_error. */
31 #include "langhooks.h"
32 #include "flags.h"
33 #include "gfortran.h"
34 #include "arith.h"
35 #include "constructor.h"
36 #include "trans.h"
37 #include "trans-const.h"
38 #include "trans-types.h"
39 #include "trans-array.h"
40 /* Only for gfc_trans_assign and gfc_trans_pointer_assign. */
41 #include "trans-stmt.h"
42 #include "dependency.h"
45 /* Convert a scalar to an array descriptor. To be used for assumed-rank
46 arrays. */
48 static tree
49 get_scalar_to_descriptor_type (tree scalar, symbol_attribute attr)
51 enum gfc_array_kind akind;
53 if (attr.pointer)
54 akind = GFC_ARRAY_POINTER_CONT;
55 else if (attr.allocatable)
56 akind = GFC_ARRAY_ALLOCATABLE;
57 else
58 akind = GFC_ARRAY_ASSUMED_SHAPE_CONT;
60 return gfc_get_array_type_bounds (TREE_TYPE (scalar), 0, 0, NULL, NULL, 1,
61 akind, !(attr.pointer || attr.target));
64 static tree
65 conv_scalar_to_descriptor (gfc_se *se, tree scalar, symbol_attribute attr)
67 tree desc, type;
69 type = get_scalar_to_descriptor_type (scalar, attr);
70 desc = gfc_create_var (type, "desc");
71 DECL_ARTIFICIAL (desc) = 1;
72 gfc_add_modify (&se->pre, gfc_conv_descriptor_dtype (desc),
73 gfc_get_dtype (type));
74 gfc_conv_descriptor_data_set (&se->pre, desc, scalar);
76 /* Copy pointer address back - but only if it could have changed and
77 if the actual argument is a pointer and not, e.g., NULL(). */
78 if ((attr.pointer || attr.allocatable)
79 && attr.intent != INTENT_IN && POINTER_TYPE_P (TREE_TYPE (scalar)))
80 gfc_add_modify (&se->post, scalar,
81 fold_convert (TREE_TYPE (scalar),
82 gfc_conv_descriptor_data_get (desc)));
83 return desc;
87 /* This is the seed for an eventual trans-class.c
89 The following parameters should not be used directly since they might
90 in future implementations. Use the corresponding APIs. */
91 #define CLASS_DATA_FIELD 0
92 #define CLASS_VPTR_FIELD 1
93 #define VTABLE_HASH_FIELD 0
94 #define VTABLE_SIZE_FIELD 1
95 #define VTABLE_EXTENDS_FIELD 2
96 #define VTABLE_DEF_INIT_FIELD 3
97 #define VTABLE_COPY_FIELD 4
100 tree
101 gfc_class_data_get (tree decl)
103 tree data;
104 if (POINTER_TYPE_P (TREE_TYPE (decl)))
105 decl = build_fold_indirect_ref_loc (input_location, decl);
106 data = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (decl)),
107 CLASS_DATA_FIELD);
108 return fold_build3_loc (input_location, COMPONENT_REF,
109 TREE_TYPE (data), decl, data,
110 NULL_TREE);
114 tree
115 gfc_class_vptr_get (tree decl)
117 tree vptr;
118 if (POINTER_TYPE_P (TREE_TYPE (decl)))
119 decl = build_fold_indirect_ref_loc (input_location, decl);
120 vptr = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (decl)),
121 CLASS_VPTR_FIELD);
122 return fold_build3_loc (input_location, COMPONENT_REF,
123 TREE_TYPE (vptr), decl, vptr,
124 NULL_TREE);
128 static tree
129 gfc_vtable_field_get (tree decl, int field)
131 tree size;
132 tree vptr;
133 vptr = gfc_class_vptr_get (decl);
134 vptr = build_fold_indirect_ref_loc (input_location, vptr);
135 size = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (vptr)),
136 field);
137 size = fold_build3_loc (input_location, COMPONENT_REF,
138 TREE_TYPE (size), vptr, size,
139 NULL_TREE);
140 /* Always return size as an array index type. */
141 if (field == VTABLE_SIZE_FIELD)
142 size = fold_convert (gfc_array_index_type, size);
143 gcc_assert (size);
144 return size;
148 tree
149 gfc_vtable_hash_get (tree decl)
151 return gfc_vtable_field_get (decl, VTABLE_HASH_FIELD);
155 tree
156 gfc_vtable_size_get (tree decl)
158 return gfc_vtable_field_get (decl, VTABLE_SIZE_FIELD);
162 tree
163 gfc_vtable_extends_get (tree decl)
165 return gfc_vtable_field_get (decl, VTABLE_EXTENDS_FIELD);
169 tree
170 gfc_vtable_def_init_get (tree decl)
172 return gfc_vtable_field_get (decl, VTABLE_DEF_INIT_FIELD);
176 tree
177 gfc_vtable_copy_get (tree decl)
179 return gfc_vtable_field_get (decl, VTABLE_COPY_FIELD);
183 #undef CLASS_DATA_FIELD
184 #undef CLASS_VPTR_FIELD
185 #undef VTABLE_HASH_FIELD
186 #undef VTABLE_SIZE_FIELD
187 #undef VTABLE_EXTENDS_FIELD
188 #undef VTABLE_DEF_INIT_FIELD
189 #undef VTABLE_COPY_FIELD
192 /* Obtain the vptr of the last class reference in an expression. */
194 tree
195 gfc_get_vptr_from_expr (tree expr)
197 tree tmp = expr;
198 while (tmp && !GFC_CLASS_TYPE_P (TREE_TYPE (tmp)))
199 tmp = TREE_OPERAND (tmp, 0);
200 tmp = gfc_class_vptr_get (tmp);
201 return tmp;
205 static void
206 class_array_data_assign (stmtblock_t *block, tree lhs_desc, tree rhs_desc,
207 bool lhs_type)
209 tree tmp, tmp2, type;
211 gfc_conv_descriptor_data_set (block, lhs_desc,
212 gfc_conv_descriptor_data_get (rhs_desc));
213 gfc_conv_descriptor_offset_set (block, lhs_desc,
214 gfc_conv_descriptor_offset_get (rhs_desc));
216 gfc_add_modify (block, gfc_conv_descriptor_dtype (lhs_desc),
217 gfc_conv_descriptor_dtype (rhs_desc));
219 /* Assign the dimension as range-ref. */
220 tmp = gfc_get_descriptor_dimension (lhs_desc);
221 tmp2 = gfc_get_descriptor_dimension (rhs_desc);
223 type = lhs_type ? TREE_TYPE (tmp) : TREE_TYPE (tmp2);
224 tmp = build4_loc (input_location, ARRAY_RANGE_REF, type, tmp,
225 gfc_index_zero_node, NULL_TREE, NULL_TREE);
226 tmp2 = build4_loc (input_location, ARRAY_RANGE_REF, type, tmp2,
227 gfc_index_zero_node, NULL_TREE, NULL_TREE);
228 gfc_add_modify (block, tmp, tmp2);
232 /* Takes a derived type expression and returns the address of a temporary
233 class object of the 'declared' type. If vptr is not NULL, this is
234 used for the temporary class object. */
235 void
236 gfc_conv_derived_to_class (gfc_se *parmse, gfc_expr *e,
237 gfc_typespec class_ts, tree vptr)
239 gfc_symbol *vtab;
240 gfc_ss *ss;
241 tree ctree;
242 tree var;
243 tree tmp;
245 /* The derived type needs to be converted to a temporary
246 CLASS object. */
247 tmp = gfc_typenode_for_spec (&class_ts);
248 var = gfc_create_var (tmp, "class");
250 /* Set the vptr. */
251 ctree = gfc_class_vptr_get (var);
253 if (vptr != NULL_TREE)
255 /* Use the dynamic vptr. */
256 tmp = vptr;
258 else
260 /* In this case the vtab corresponds to the derived type and the
261 vptr must point to it. */
262 vtab = gfc_find_derived_vtab (e->ts.u.derived);
263 gcc_assert (vtab);
264 tmp = gfc_build_addr_expr (NULL_TREE, gfc_get_symbol_decl (vtab));
266 gfc_add_modify (&parmse->pre, ctree,
267 fold_convert (TREE_TYPE (ctree), tmp));
269 /* Now set the data field. */
270 ctree = gfc_class_data_get (var);
272 if (parmse->ss && parmse->ss->info->useflags)
274 /* For an array reference in an elemental procedure call we need
275 to retain the ss to provide the scalarized array reference. */
276 gfc_conv_expr_reference (parmse, e);
277 tmp = fold_convert (TREE_TYPE (ctree), parmse->expr);
278 gfc_add_modify (&parmse->pre, ctree, tmp);
280 else
282 ss = gfc_walk_expr (e);
283 if (ss == gfc_ss_terminator)
285 parmse->ss = NULL;
286 gfc_conv_expr_reference (parmse, e);
288 /* Scalar to an assumed-rank array. */
289 if (class_ts.u.derived->components->as)
291 tree type;
292 type = get_scalar_to_descriptor_type (parmse->expr,
293 gfc_expr_attr (e));
294 gfc_add_modify (&parmse->pre, gfc_conv_descriptor_dtype (ctree),
295 gfc_get_dtype (type));
296 gfc_conv_descriptor_data_set (&parmse->pre, ctree, parmse->expr);
298 else
300 tmp = fold_convert (TREE_TYPE (ctree), parmse->expr);
301 gfc_add_modify (&parmse->pre, ctree, tmp);
304 else
306 parmse->ss = ss;
307 gfc_conv_expr_descriptor (parmse, e, ss);
309 if (e->rank != class_ts.u.derived->components->as->rank)
310 class_array_data_assign (&parmse->pre, ctree, parmse->expr, true);
311 else
312 gfc_add_modify (&parmse->pre, ctree, parmse->expr);
316 /* Pass the address of the class object. */
317 parmse->expr = gfc_build_addr_expr (NULL_TREE, var);
321 /* Takes a scalarized class array expression and returns the
322 address of a temporary scalar class object of the 'declared'
323 type.
324 OOP-TODO: This could be improved by adding code that branched on
325 the dynamic type being the same as the declared type. In this case
326 the original class expression can be passed directly. */
327 void
328 gfc_conv_class_to_class (gfc_se *parmse, gfc_expr *e,
329 gfc_typespec class_ts, bool elemental)
331 tree ctree;
332 tree var;
333 tree tmp;
334 tree vptr;
335 gfc_ref *ref;
336 gfc_ref *class_ref;
337 bool full_array = false;
339 class_ref = NULL;
340 for (ref = e->ref; ref; ref = ref->next)
342 if (ref->type == REF_COMPONENT
343 && ref->u.c.component->ts.type == BT_CLASS)
344 class_ref = ref;
346 if (ref->next == NULL)
347 break;
350 if ((ref == NULL || class_ref == ref)
351 && (!class_ts.u.derived->components->as
352 || class_ts.u.derived->components->as->rank != -1))
353 return;
355 /* Test for FULL_ARRAY. */
356 gfc_is_class_array_ref (e, &full_array);
358 /* The derived type needs to be converted to a temporary
359 CLASS object. */
360 tmp = gfc_typenode_for_spec (&class_ts);
361 var = gfc_create_var (tmp, "class");
363 /* Set the data. */
364 ctree = gfc_class_data_get (var);
365 if (class_ts.u.derived->components->as
366 && e->rank != class_ts.u.derived->components->as->rank)
368 if (e->rank == 0)
370 tree type = get_scalar_to_descriptor_type (parmse->expr,
371 gfc_expr_attr (e));
372 gfc_add_modify (&parmse->pre, gfc_conv_descriptor_dtype (ctree),
373 gfc_get_dtype (type));
374 gfc_conv_descriptor_data_set (&parmse->pre, ctree,
375 gfc_class_data_get (parmse->expr));
378 else
379 class_array_data_assign (&parmse->pre, ctree, parmse->expr, false);
381 else
382 gfc_add_modify (&parmse->pre, ctree, parmse->expr);
384 /* Return the data component, except in the case of scalarized array
385 references, where nullification of the cannot occur and so there
386 is no need. */
387 if (!elemental && full_array)
389 if (class_ts.u.derived->components->as
390 && e->rank != class_ts.u.derived->components->as->rank)
392 if (e->rank == 0)
393 gfc_add_modify (&parmse->post, gfc_class_data_get (parmse->expr),
394 gfc_conv_descriptor_data_get (ctree));
395 else
396 class_array_data_assign (&parmse->post, parmse->expr, ctree, true);
398 else
399 gfc_add_modify (&parmse->post, parmse->expr, ctree);
402 /* Set the vptr. */
403 ctree = gfc_class_vptr_get (var);
405 /* The vptr is the second field of the actual argument.
406 First we have to find the corresponding class reference. */
408 tmp = NULL_TREE;
409 if (class_ref == NULL
410 && e->symtree && e->symtree->n.sym->ts.type == BT_CLASS)
411 tmp = e->symtree->n.sym->backend_decl;
412 else
414 /* Remove everything after the last class reference, convert the
415 expression and then recover its tailend once more. */
416 gfc_se tmpse;
417 ref = class_ref->next;
418 class_ref->next = NULL;
419 gfc_init_se (&tmpse, NULL);
420 gfc_conv_expr (&tmpse, e);
421 class_ref->next = ref;
422 tmp = tmpse.expr;
425 gcc_assert (tmp != NULL_TREE);
427 /* Dereference if needs be. */
428 if (TREE_CODE (TREE_TYPE (tmp)) == REFERENCE_TYPE)
429 tmp = build_fold_indirect_ref_loc (input_location, tmp);
431 vptr = gfc_class_vptr_get (tmp);
432 gfc_add_modify (&parmse->pre, ctree,
433 fold_convert (TREE_TYPE (ctree), vptr));
435 /* Return the vptr component, except in the case of scalarized array
436 references, where the dynamic type cannot change. */
437 if (!elemental && full_array)
438 gfc_add_modify (&parmse->post, vptr,
439 fold_convert (TREE_TYPE (vptr), ctree));
441 /* Pass the address of the class object. */
442 parmse->expr = gfc_build_addr_expr (NULL_TREE, var);
446 /* Given a class array declaration and an index, returns the address
447 of the referenced element. */
449 tree
450 gfc_get_class_array_ref (tree index, tree class_decl)
452 tree data = gfc_class_data_get (class_decl);
453 tree size = gfc_vtable_size_get (class_decl);
454 tree offset = fold_build2_loc (input_location, MULT_EXPR,
455 gfc_array_index_type,
456 index, size);
457 tree ptr;
458 data = gfc_conv_descriptor_data_get (data);
459 ptr = fold_convert (pvoid_type_node, data);
460 ptr = fold_build_pointer_plus_loc (input_location, ptr, offset);
461 return fold_convert (TREE_TYPE (data), ptr);
465 /* Copies one class expression to another, assuming that if either
466 'to' or 'from' are arrays they are packed. Should 'from' be
467 NULL_TREE, the initialization expression for 'to' is used, assuming
468 that the _vptr is set. */
470 tree
471 gfc_copy_class_to_class (tree from, tree to, tree nelems)
473 tree fcn;
474 tree fcn_type;
475 tree from_data;
476 tree to_data;
477 tree to_ref;
478 tree from_ref;
479 VEC(tree,gc) *args;
480 tree tmp;
481 tree index;
482 stmtblock_t loopbody;
483 stmtblock_t body;
484 gfc_loopinfo loop;
486 args = NULL;
488 if (from != NULL_TREE)
489 fcn = gfc_vtable_copy_get (from);
490 else
491 fcn = gfc_vtable_copy_get (to);
493 fcn_type = TREE_TYPE (TREE_TYPE (fcn));
495 if (from != NULL_TREE)
496 from_data = gfc_class_data_get (from);
497 else
498 from_data = gfc_vtable_def_init_get (to);
500 to_data = gfc_class_data_get (to);
502 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (to_data)))
504 gfc_init_block (&body);
505 tmp = fold_build2_loc (input_location, MINUS_EXPR,
506 gfc_array_index_type, nelems,
507 gfc_index_one_node);
508 nelems = gfc_evaluate_now (tmp, &body);
509 index = gfc_create_var (gfc_array_index_type, "S");
511 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (from_data)))
513 from_ref = gfc_get_class_array_ref (index, from);
514 VEC_safe_push (tree, gc, args, from_ref);
516 else
517 VEC_safe_push (tree, gc, args, from_data);
519 to_ref = gfc_get_class_array_ref (index, to);
520 VEC_safe_push (tree, gc, args, to_ref);
522 tmp = build_call_vec (fcn_type, fcn, args);
524 /* Build the body of the loop. */
525 gfc_init_block (&loopbody);
526 gfc_add_expr_to_block (&loopbody, tmp);
528 /* Build the loop and return. */
529 gfc_init_loopinfo (&loop);
530 loop.dimen = 1;
531 loop.from[0] = gfc_index_zero_node;
532 loop.loopvar[0] = index;
533 loop.to[0] = nelems;
534 gfc_trans_scalarizing_loops (&loop, &loopbody);
535 gfc_add_block_to_block (&body, &loop.pre);
536 tmp = gfc_finish_block (&body);
538 else
540 gcc_assert (!GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (from_data)));
541 VEC_safe_push (tree, gc, args, from_data);
542 VEC_safe_push (tree, gc, args, to_data);
543 tmp = build_call_vec (fcn_type, fcn, args);
546 return tmp;
549 static tree
550 gfc_trans_class_array_init_assign (gfc_expr *rhs, gfc_expr *lhs, gfc_expr *obj)
552 gfc_actual_arglist *actual;
553 gfc_expr *ppc;
554 gfc_code *ppc_code;
555 tree res;
557 actual = gfc_get_actual_arglist ();
558 actual->expr = gfc_copy_expr (rhs);
559 actual->next = gfc_get_actual_arglist ();
560 actual->next->expr = gfc_copy_expr (lhs);
561 ppc = gfc_copy_expr (obj);
562 gfc_add_vptr_component (ppc);
563 gfc_add_component_ref (ppc, "_copy");
564 ppc_code = gfc_get_code ();
565 ppc_code->resolved_sym = ppc->symtree->n.sym;
566 /* Although '_copy' is set to be elemental in class.c, it is
567 not staying that way. Find out why, sometime.... */
568 ppc_code->resolved_sym->attr.elemental = 1;
569 ppc_code->ext.actual = actual;
570 ppc_code->expr1 = ppc;
571 ppc_code->op = EXEC_CALL;
572 /* Since '_copy' is elemental, the scalarizer will take care
573 of arrays in gfc_trans_call. */
574 res = gfc_trans_call (ppc_code, false, NULL, NULL, false);
575 gfc_free_statements (ppc_code);
576 return res;
579 /* Special case for initializing a polymorphic dummy with INTENT(OUT).
580 A MEMCPY is needed to copy the full data from the default initializer
581 of the dynamic type. */
583 tree
584 gfc_trans_class_init_assign (gfc_code *code)
586 stmtblock_t block;
587 tree tmp;
588 gfc_se dst,src,memsz;
589 gfc_expr *lhs, *rhs, *sz;
591 gfc_start_block (&block);
593 lhs = gfc_copy_expr (code->expr1);
594 gfc_add_data_component (lhs);
596 rhs = gfc_copy_expr (code->expr1);
597 gfc_add_vptr_component (rhs);
599 /* Make sure that the component backend_decls have been built, which
600 will not have happened if the derived types concerned have not
601 been referenced. */
602 gfc_get_derived_type (rhs->ts.u.derived);
603 gfc_add_def_init_component (rhs);
605 if (code->expr1->ts.type == BT_CLASS
606 && CLASS_DATA (code->expr1)->attr.dimension)
607 tmp = gfc_trans_class_array_init_assign (rhs, lhs, code->expr1);
608 else
610 sz = gfc_copy_expr (code->expr1);
611 gfc_add_vptr_component (sz);
612 gfc_add_size_component (sz);
614 gfc_init_se (&dst, NULL);
615 gfc_init_se (&src, NULL);
616 gfc_init_se (&memsz, NULL);
617 gfc_conv_expr (&dst, lhs);
618 gfc_conv_expr (&src, rhs);
619 gfc_conv_expr (&memsz, sz);
620 gfc_add_block_to_block (&block, &src.pre);
621 tmp = gfc_build_memcpy_call (dst.expr, src.expr, memsz.expr);
623 gfc_add_expr_to_block (&block, tmp);
625 return gfc_finish_block (&block);
629 /* Translate an assignment to a CLASS object
630 (pointer or ordinary assignment). */
632 tree
633 gfc_trans_class_assign (gfc_expr *expr1, gfc_expr *expr2, gfc_exec_op op)
635 stmtblock_t block;
636 tree tmp;
637 gfc_expr *lhs;
638 gfc_expr *rhs;
639 gfc_ref *ref;
641 gfc_start_block (&block);
643 ref = expr1->ref;
644 while (ref && ref->next)
645 ref = ref->next;
647 /* Class valued proc_pointer assignments do not need any further
648 preparation. */
649 if (ref && ref->type == REF_COMPONENT
650 && ref->u.c.component->attr.proc_pointer
651 && expr2->expr_type == EXPR_VARIABLE
652 && expr2->symtree->n.sym->attr.flavor == FL_PROCEDURE
653 && op == EXEC_POINTER_ASSIGN)
654 goto assign;
656 if (expr2->ts.type != BT_CLASS)
658 /* Insert an additional assignment which sets the '_vptr' field. */
659 gfc_symbol *vtab = NULL;
660 gfc_symtree *st;
662 lhs = gfc_copy_expr (expr1);
663 gfc_add_vptr_component (lhs);
665 if (expr2->ts.type == BT_DERIVED)
666 vtab = gfc_find_derived_vtab (expr2->ts.u.derived);
667 else if (expr2->expr_type == EXPR_NULL)
668 vtab = gfc_find_derived_vtab (expr1->ts.u.derived);
669 gcc_assert (vtab);
671 rhs = gfc_get_expr ();
672 rhs->expr_type = EXPR_VARIABLE;
673 gfc_find_sym_tree (vtab->name, vtab->ns, 1, &st);
674 rhs->symtree = st;
675 rhs->ts = vtab->ts;
677 tmp = gfc_trans_pointer_assignment (lhs, rhs);
678 gfc_add_expr_to_block (&block, tmp);
680 gfc_free_expr (lhs);
681 gfc_free_expr (rhs);
683 else if (CLASS_DATA (expr2)->attr.dimension)
685 /* Insert an additional assignment which sets the '_vptr' field. */
686 lhs = gfc_copy_expr (expr1);
687 gfc_add_vptr_component (lhs);
689 rhs = gfc_copy_expr (expr2);
690 gfc_add_vptr_component (rhs);
692 tmp = gfc_trans_pointer_assignment (lhs, rhs);
693 gfc_add_expr_to_block (&block, tmp);
695 gfc_free_expr (lhs);
696 gfc_free_expr (rhs);
699 /* Do the actual CLASS assignment. */
700 if (expr2->ts.type == BT_CLASS
701 && !CLASS_DATA (expr2)->attr.dimension)
702 op = EXEC_ASSIGN;
703 else
704 gfc_add_data_component (expr1);
706 assign:
708 if (op == EXEC_ASSIGN)
709 tmp = gfc_trans_assignment (expr1, expr2, false, true);
710 else if (op == EXEC_POINTER_ASSIGN)
711 tmp = gfc_trans_pointer_assignment (expr1, expr2);
712 else
713 gcc_unreachable();
715 gfc_add_expr_to_block (&block, tmp);
717 return gfc_finish_block (&block);
721 /* End of prototype trans-class.c */
724 static void
725 realloc_lhs_warning (bt type, bool array, locus *where)
727 if (array && type != BT_CLASS && type != BT_DERIVED
728 && gfc_option.warn_realloc_lhs)
729 gfc_warning ("Code for reallocating the allocatable array at %L will "
730 "be added", where);
731 else if (gfc_option.warn_realloc_lhs_all)
732 gfc_warning ("Code for reallocating the allocatable variable at %L "
733 "will be added", where);
737 static tree gfc_trans_structure_assign (tree dest, gfc_expr * expr);
738 static void gfc_apply_interface_mapping_to_expr (gfc_interface_mapping *,
739 gfc_expr *);
741 /* Copy the scalarization loop variables. */
743 static void
744 gfc_copy_se_loopvars (gfc_se * dest, gfc_se * src)
746 dest->ss = src->ss;
747 dest->loop = src->loop;
751 /* Initialize a simple expression holder.
753 Care must be taken when multiple se are created with the same parent.
754 The child se must be kept in sync. The easiest way is to delay creation
755 of a child se until after after the previous se has been translated. */
757 void
758 gfc_init_se (gfc_se * se, gfc_se * parent)
760 memset (se, 0, sizeof (gfc_se));
761 gfc_init_block (&se->pre);
762 gfc_init_block (&se->post);
764 se->parent = parent;
766 if (parent)
767 gfc_copy_se_loopvars (se, parent);
771 /* Advances to the next SS in the chain. Use this rather than setting
772 se->ss = se->ss->next because all the parents needs to be kept in sync.
773 See gfc_init_se. */
775 void
776 gfc_advance_se_ss_chain (gfc_se * se)
778 gfc_se *p;
779 gfc_ss *ss;
781 gcc_assert (se != NULL && se->ss != NULL && se->ss != gfc_ss_terminator);
783 p = se;
784 /* Walk down the parent chain. */
785 while (p != NULL)
787 /* Simple consistency check. */
788 gcc_assert (p->parent == NULL || p->parent->ss == p->ss
789 || p->parent->ss->nested_ss == p->ss);
791 /* If we were in a nested loop, the next scalarized expression can be
792 on the parent ss' next pointer. Thus we should not take the next
793 pointer blindly, but rather go up one nest level as long as next
794 is the end of chain. */
795 ss = p->ss;
796 while (ss->next == gfc_ss_terminator && ss->parent != NULL)
797 ss = ss->parent;
799 p->ss = ss->next;
801 p = p->parent;
806 /* Ensures the result of the expression as either a temporary variable
807 or a constant so that it can be used repeatedly. */
809 void
810 gfc_make_safe_expr (gfc_se * se)
812 tree var;
814 if (CONSTANT_CLASS_P (se->expr))
815 return;
817 /* We need a temporary for this result. */
818 var = gfc_create_var (TREE_TYPE (se->expr), NULL);
819 gfc_add_modify (&se->pre, var, se->expr);
820 se->expr = var;
824 /* Return an expression which determines if a dummy parameter is present.
825 Also used for arguments to procedures with multiple entry points. */
827 tree
828 gfc_conv_expr_present (gfc_symbol * sym)
830 tree decl, cond;
832 gcc_assert (sym->attr.dummy);
834 decl = gfc_get_symbol_decl (sym);
835 if (TREE_CODE (decl) != PARM_DECL)
837 /* Array parameters use a temporary descriptor, we want the real
838 parameter. */
839 gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl))
840 || GFC_ARRAY_TYPE_P (TREE_TYPE (decl)));
841 decl = GFC_DECL_SAVED_DESCRIPTOR (decl);
844 cond = fold_build2_loc (input_location, NE_EXPR, boolean_type_node, decl,
845 fold_convert (TREE_TYPE (decl), null_pointer_node));
847 /* Fortran 2008 allows to pass null pointers and non-associated pointers
848 as actual argument to denote absent dummies. For array descriptors,
849 we thus also need to check the array descriptor. */
850 if (!sym->attr.pointer && !sym->attr.allocatable
851 && sym->as && (sym->as->type == AS_ASSUMED_SHAPE
852 || sym->as->type == AS_ASSUMED_RANK)
853 && (gfc_option.allow_std & GFC_STD_F2008) != 0)
855 tree tmp;
856 tmp = build_fold_indirect_ref_loc (input_location, decl);
857 tmp = gfc_conv_array_data (tmp);
858 tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node, tmp,
859 fold_convert (TREE_TYPE (tmp), null_pointer_node));
860 cond = fold_build2_loc (input_location, TRUTH_ANDIF_EXPR,
861 boolean_type_node, cond, tmp);
864 return cond;
868 /* Converts a missing, dummy argument into a null or zero. */
870 void
871 gfc_conv_missing_dummy (gfc_se * se, gfc_expr * arg, gfc_typespec ts, int kind)
873 tree present;
874 tree tmp;
876 present = gfc_conv_expr_present (arg->symtree->n.sym);
878 if (kind > 0)
880 /* Create a temporary and convert it to the correct type. */
881 tmp = gfc_get_int_type (kind);
882 tmp = fold_convert (tmp, build_fold_indirect_ref_loc (input_location,
883 se->expr));
885 /* Test for a NULL value. */
886 tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp), present,
887 tmp, fold_convert (TREE_TYPE (tmp), integer_one_node));
888 tmp = gfc_evaluate_now (tmp, &se->pre);
889 se->expr = gfc_build_addr_expr (NULL_TREE, tmp);
891 else
893 tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (se->expr),
894 present, se->expr,
895 build_zero_cst (TREE_TYPE (se->expr)));
896 tmp = gfc_evaluate_now (tmp, &se->pre);
897 se->expr = tmp;
900 if (ts.type == BT_CHARACTER)
902 tmp = build_int_cst (gfc_charlen_type_node, 0);
903 tmp = fold_build3_loc (input_location, COND_EXPR, gfc_charlen_type_node,
904 present, se->string_length, tmp);
905 tmp = gfc_evaluate_now (tmp, &se->pre);
906 se->string_length = tmp;
908 return;
912 /* Get the character length of an expression, looking through gfc_refs
913 if necessary. */
915 tree
916 gfc_get_expr_charlen (gfc_expr *e)
918 gfc_ref *r;
919 tree length;
921 gcc_assert (e->expr_type == EXPR_VARIABLE
922 && e->ts.type == BT_CHARACTER);
924 length = NULL; /* To silence compiler warning. */
926 if (is_subref_array (e) && e->ts.u.cl->length)
928 gfc_se tmpse;
929 gfc_init_se (&tmpse, NULL);
930 gfc_conv_expr_type (&tmpse, e->ts.u.cl->length, gfc_charlen_type_node);
931 e->ts.u.cl->backend_decl = tmpse.expr;
932 return tmpse.expr;
935 /* First candidate: if the variable is of type CHARACTER, the
936 expression's length could be the length of the character
937 variable. */
938 if (e->symtree->n.sym->ts.type == BT_CHARACTER)
939 length = e->symtree->n.sym->ts.u.cl->backend_decl;
941 /* Look through the reference chain for component references. */
942 for (r = e->ref; r; r = r->next)
944 switch (r->type)
946 case REF_COMPONENT:
947 if (r->u.c.component->ts.type == BT_CHARACTER)
948 length = r->u.c.component->ts.u.cl->backend_decl;
949 break;
951 case REF_ARRAY:
952 /* Do nothing. */
953 break;
955 default:
956 /* We should never got substring references here. These will be
957 broken down by the scalarizer. */
958 gcc_unreachable ();
959 break;
963 gcc_assert (length != NULL);
964 return length;
968 /* Return for an expression the backend decl of the coarray. */
970 static tree
971 get_tree_for_caf_expr (gfc_expr *expr)
973 tree caf_decl = NULL_TREE;
974 gfc_ref *ref;
976 gcc_assert (expr && expr->expr_type == EXPR_VARIABLE);
977 if (expr->symtree->n.sym->attr.codimension)
978 caf_decl = expr->symtree->n.sym->backend_decl;
980 for (ref = expr->ref; ref; ref = ref->next)
981 if (ref->type == REF_COMPONENT)
983 gfc_component *comp = ref->u.c.component;
984 if (comp->attr.pointer || comp->attr.allocatable)
985 caf_decl = NULL_TREE;
986 if (comp->attr.codimension)
987 caf_decl = comp->backend_decl;
990 gcc_assert (caf_decl != NULL_TREE);
991 return caf_decl;
995 /* For each character array constructor subexpression without a ts.u.cl->length,
996 replace it by its first element (if there aren't any elements, the length
997 should already be set to zero). */
999 static void
1000 flatten_array_ctors_without_strlen (gfc_expr* e)
1002 gfc_actual_arglist* arg;
1003 gfc_constructor* c;
1005 if (!e)
1006 return;
1008 switch (e->expr_type)
1011 case EXPR_OP:
1012 flatten_array_ctors_without_strlen (e->value.op.op1);
1013 flatten_array_ctors_without_strlen (e->value.op.op2);
1014 break;
1016 case EXPR_COMPCALL:
1017 /* TODO: Implement as with EXPR_FUNCTION when needed. */
1018 gcc_unreachable ();
1020 case EXPR_FUNCTION:
1021 for (arg = e->value.function.actual; arg; arg = arg->next)
1022 flatten_array_ctors_without_strlen (arg->expr);
1023 break;
1025 case EXPR_ARRAY:
1027 /* We've found what we're looking for. */
1028 if (e->ts.type == BT_CHARACTER && !e->ts.u.cl->length)
1030 gfc_constructor *c;
1031 gfc_expr* new_expr;
1033 gcc_assert (e->value.constructor);
1035 c = gfc_constructor_first (e->value.constructor);
1036 new_expr = c->expr;
1037 c->expr = NULL;
1039 flatten_array_ctors_without_strlen (new_expr);
1040 gfc_replace_expr (e, new_expr);
1041 break;
1044 /* Otherwise, fall through to handle constructor elements. */
1045 case EXPR_STRUCTURE:
1046 for (c = gfc_constructor_first (e->value.constructor);
1047 c; c = gfc_constructor_next (c))
1048 flatten_array_ctors_without_strlen (c->expr);
1049 break;
1051 default:
1052 break;
1058 /* Generate code to initialize a string length variable. Returns the
1059 value. For array constructors, cl->length might be NULL and in this case,
1060 the first element of the constructor is needed. expr is the original
1061 expression so we can access it but can be NULL if this is not needed. */
1063 void
1064 gfc_conv_string_length (gfc_charlen * cl, gfc_expr * expr, stmtblock_t * pblock)
1066 gfc_se se;
1068 gfc_init_se (&se, NULL);
1070 if (!cl->length
1071 && cl->backend_decl
1072 && TREE_CODE (cl->backend_decl) == VAR_DECL)
1073 return;
1075 /* If cl->length is NULL, use gfc_conv_expr to obtain the string length but
1076 "flatten" array constructors by taking their first element; all elements
1077 should be the same length or a cl->length should be present. */
1078 if (!cl->length)
1080 gfc_expr* expr_flat;
1081 gcc_assert (expr);
1082 expr_flat = gfc_copy_expr (expr);
1083 flatten_array_ctors_without_strlen (expr_flat);
1084 gfc_resolve_expr (expr_flat);
1086 gfc_conv_expr (&se, expr_flat);
1087 gfc_add_block_to_block (pblock, &se.pre);
1088 cl->backend_decl = convert (gfc_charlen_type_node, se.string_length);
1090 gfc_free_expr (expr_flat);
1091 return;
1094 /* Convert cl->length. */
1096 gcc_assert (cl->length);
1098 gfc_conv_expr_type (&se, cl->length, gfc_charlen_type_node);
1099 se.expr = fold_build2_loc (input_location, MAX_EXPR, gfc_charlen_type_node,
1100 se.expr, build_int_cst (gfc_charlen_type_node, 0));
1101 gfc_add_block_to_block (pblock, &se.pre);
1103 if (cl->backend_decl)
1104 gfc_add_modify (pblock, cl->backend_decl, se.expr);
1105 else
1106 cl->backend_decl = gfc_evaluate_now (se.expr, pblock);
1110 static void
1111 gfc_conv_substring (gfc_se * se, gfc_ref * ref, int kind,
1112 const char *name, locus *where)
1114 tree tmp;
1115 tree type;
1116 tree fault;
1117 gfc_se start;
1118 gfc_se end;
1119 char *msg;
1121 type = gfc_get_character_type (kind, ref->u.ss.length);
1122 type = build_pointer_type (type);
1124 gfc_init_se (&start, se);
1125 gfc_conv_expr_type (&start, ref->u.ss.start, gfc_charlen_type_node);
1126 gfc_add_block_to_block (&se->pre, &start.pre);
1128 if (integer_onep (start.expr))
1129 gfc_conv_string_parameter (se);
1130 else
1132 tmp = start.expr;
1133 STRIP_NOPS (tmp);
1134 /* Avoid multiple evaluation of substring start. */
1135 if (!CONSTANT_CLASS_P (tmp) && !DECL_P (tmp))
1136 start.expr = gfc_evaluate_now (start.expr, &se->pre);
1138 /* Change the start of the string. */
1139 if (TYPE_STRING_FLAG (TREE_TYPE (se->expr)))
1140 tmp = se->expr;
1141 else
1142 tmp = build_fold_indirect_ref_loc (input_location,
1143 se->expr);
1144 tmp = gfc_build_array_ref (tmp, start.expr, NULL);
1145 se->expr = gfc_build_addr_expr (type, tmp);
1148 /* Length = end + 1 - start. */
1149 gfc_init_se (&end, se);
1150 if (ref->u.ss.end == NULL)
1151 end.expr = se->string_length;
1152 else
1154 gfc_conv_expr_type (&end, ref->u.ss.end, gfc_charlen_type_node);
1155 gfc_add_block_to_block (&se->pre, &end.pre);
1157 tmp = end.expr;
1158 STRIP_NOPS (tmp);
1159 if (!CONSTANT_CLASS_P (tmp) && !DECL_P (tmp))
1160 end.expr = gfc_evaluate_now (end.expr, &se->pre);
1162 if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
1164 tree nonempty = fold_build2_loc (input_location, LE_EXPR,
1165 boolean_type_node, start.expr,
1166 end.expr);
1168 /* Check lower bound. */
1169 fault = fold_build2_loc (input_location, LT_EXPR, boolean_type_node,
1170 start.expr,
1171 build_int_cst (gfc_charlen_type_node, 1));
1172 fault = fold_build2_loc (input_location, TRUTH_ANDIF_EXPR,
1173 boolean_type_node, nonempty, fault);
1174 if (name)
1175 asprintf (&msg, "Substring out of bounds: lower bound (%%ld) of '%s' "
1176 "is less than one", name);
1177 else
1178 asprintf (&msg, "Substring out of bounds: lower bound (%%ld)"
1179 "is less than one");
1180 gfc_trans_runtime_check (true, false, fault, &se->pre, where, msg,
1181 fold_convert (long_integer_type_node,
1182 start.expr));
1183 free (msg);
1185 /* Check upper bound. */
1186 fault = fold_build2_loc (input_location, GT_EXPR, boolean_type_node,
1187 end.expr, se->string_length);
1188 fault = fold_build2_loc (input_location, TRUTH_ANDIF_EXPR,
1189 boolean_type_node, nonempty, fault);
1190 if (name)
1191 asprintf (&msg, "Substring out of bounds: upper bound (%%ld) of '%s' "
1192 "exceeds string length (%%ld)", name);
1193 else
1194 asprintf (&msg, "Substring out of bounds: upper bound (%%ld) "
1195 "exceeds string length (%%ld)");
1196 gfc_trans_runtime_check (true, false, fault, &se->pre, where, msg,
1197 fold_convert (long_integer_type_node, end.expr),
1198 fold_convert (long_integer_type_node,
1199 se->string_length));
1200 free (msg);
1203 /* If the start and end expressions are equal, the length is one. */
1204 if (ref->u.ss.end
1205 && gfc_dep_compare_expr (ref->u.ss.start, ref->u.ss.end) == 0)
1206 tmp = build_int_cst (gfc_charlen_type_node, 1);
1207 else
1209 tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_charlen_type_node,
1210 end.expr, start.expr);
1211 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_charlen_type_node,
1212 build_int_cst (gfc_charlen_type_node, 1), tmp);
1213 tmp = fold_build2_loc (input_location, MAX_EXPR, gfc_charlen_type_node,
1214 tmp, build_int_cst (gfc_charlen_type_node, 0));
1217 se->string_length = tmp;
1221 /* Convert a derived type component reference. */
1223 static void
1224 gfc_conv_component_ref (gfc_se * se, gfc_ref * ref)
1226 gfc_component *c;
1227 tree tmp;
1228 tree decl;
1229 tree field;
1231 c = ref->u.c.component;
1233 gcc_assert (c->backend_decl);
1235 field = c->backend_decl;
1236 gcc_assert (TREE_CODE (field) == FIELD_DECL);
1237 decl = se->expr;
1239 /* Components can correspond to fields of different containing
1240 types, as components are created without context, whereas
1241 a concrete use of a component has the type of decl as context.
1242 So, if the type doesn't match, we search the corresponding
1243 FIELD_DECL in the parent type. To not waste too much time
1244 we cache this result in norestrict_decl. */
1246 if (DECL_FIELD_CONTEXT (field) != TREE_TYPE (decl))
1248 tree f2 = c->norestrict_decl;
1249 if (!f2 || DECL_FIELD_CONTEXT (f2) != TREE_TYPE (decl))
1250 for (f2 = TYPE_FIELDS (TREE_TYPE (decl)); f2; f2 = DECL_CHAIN (f2))
1251 if (TREE_CODE (f2) == FIELD_DECL
1252 && DECL_NAME (f2) == DECL_NAME (field))
1253 break;
1254 gcc_assert (f2);
1255 c->norestrict_decl = f2;
1256 field = f2;
1258 tmp = fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field),
1259 decl, field, NULL_TREE);
1261 se->expr = tmp;
1263 if (c->ts.type == BT_CHARACTER && !c->attr.proc_pointer)
1265 tmp = c->ts.u.cl->backend_decl;
1266 /* Components must always be constant length. */
1267 gcc_assert (tmp && INTEGER_CST_P (tmp));
1268 se->string_length = tmp;
1271 if (((c->attr.pointer || c->attr.allocatable)
1272 && (!c->attr.dimension && !c->attr.codimension)
1273 && c->ts.type != BT_CHARACTER)
1274 || c->attr.proc_pointer)
1275 se->expr = build_fold_indirect_ref_loc (input_location,
1276 se->expr);
1280 /* This function deals with component references to components of the
1281 parent type for derived type extensions. */
1282 static void
1283 conv_parent_component_references (gfc_se * se, gfc_ref * ref)
1285 gfc_component *c;
1286 gfc_component *cmp;
1287 gfc_symbol *dt;
1288 gfc_ref parent;
1290 dt = ref->u.c.sym;
1291 c = ref->u.c.component;
1293 /* Return if the component is not in the parent type. */
1294 for (cmp = dt->components; cmp; cmp = cmp->next)
1295 if (strcmp (c->name, cmp->name) == 0)
1296 return;
1298 /* Build a gfc_ref to recursively call gfc_conv_component_ref. */
1299 parent.type = REF_COMPONENT;
1300 parent.next = NULL;
1301 parent.u.c.sym = dt;
1302 parent.u.c.component = dt->components;
1304 if (dt->backend_decl == NULL)
1305 gfc_get_derived_type (dt);
1307 /* Build the reference and call self. */
1308 gfc_conv_component_ref (se, &parent);
1309 parent.u.c.sym = dt->components->ts.u.derived;
1310 parent.u.c.component = c;
1311 conv_parent_component_references (se, &parent);
1314 /* Return the contents of a variable. Also handles reference/pointer
1315 variables (all Fortran pointer references are implicit). */
1317 static void
1318 gfc_conv_variable (gfc_se * se, gfc_expr * expr)
1320 gfc_ss *ss;
1321 gfc_ref *ref;
1322 gfc_symbol *sym;
1323 tree parent_decl = NULL_TREE;
1324 int parent_flag;
1325 bool return_value;
1326 bool alternate_entry;
1327 bool entry_master;
1329 sym = expr->symtree->n.sym;
1330 ss = se->ss;
1331 if (ss != NULL)
1333 gfc_ss_info *ss_info = ss->info;
1335 /* Check that something hasn't gone horribly wrong. */
1336 gcc_assert (ss != gfc_ss_terminator);
1337 gcc_assert (ss_info->expr == expr);
1339 /* A scalarized term. We already know the descriptor. */
1340 se->expr = ss_info->data.array.descriptor;
1341 se->string_length = ss_info->string_length;
1342 for (ref = ss_info->data.array.ref; ref; ref = ref->next)
1343 if (ref->type == REF_ARRAY && ref->u.ar.type != AR_ELEMENT)
1344 break;
1346 else
1348 tree se_expr = NULL_TREE;
1350 se->expr = gfc_get_symbol_decl (sym);
1352 /* Deal with references to a parent results or entries by storing
1353 the current_function_decl and moving to the parent_decl. */
1354 return_value = sym->attr.function && sym->result == sym;
1355 alternate_entry = sym->attr.function && sym->attr.entry
1356 && sym->result == sym;
1357 entry_master = sym->attr.result
1358 && sym->ns->proc_name->attr.entry_master
1359 && !gfc_return_by_reference (sym->ns->proc_name);
1360 if (current_function_decl)
1361 parent_decl = DECL_CONTEXT (current_function_decl);
1363 if ((se->expr == parent_decl && return_value)
1364 || (sym->ns && sym->ns->proc_name
1365 && parent_decl
1366 && sym->ns->proc_name->backend_decl == parent_decl
1367 && (alternate_entry || entry_master)))
1368 parent_flag = 1;
1369 else
1370 parent_flag = 0;
1372 /* Special case for assigning the return value of a function.
1373 Self recursive functions must have an explicit return value. */
1374 if (return_value && (se->expr == current_function_decl || parent_flag))
1375 se_expr = gfc_get_fake_result_decl (sym, parent_flag);
1377 /* Similarly for alternate entry points. */
1378 else if (alternate_entry
1379 && (sym->ns->proc_name->backend_decl == current_function_decl
1380 || parent_flag))
1382 gfc_entry_list *el = NULL;
1384 for (el = sym->ns->entries; el; el = el->next)
1385 if (sym == el->sym)
1387 se_expr = gfc_get_fake_result_decl (sym, parent_flag);
1388 break;
1392 else if (entry_master
1393 && (sym->ns->proc_name->backend_decl == current_function_decl
1394 || parent_flag))
1395 se_expr = gfc_get_fake_result_decl (sym, parent_flag);
1397 if (se_expr)
1398 se->expr = se_expr;
1400 /* Procedure actual arguments. */
1401 else if (sym->attr.flavor == FL_PROCEDURE
1402 && se->expr != current_function_decl)
1404 if (!sym->attr.dummy && !sym->attr.proc_pointer)
1406 gcc_assert (TREE_CODE (se->expr) == FUNCTION_DECL);
1407 se->expr = gfc_build_addr_expr (NULL_TREE, se->expr);
1409 return;
1413 /* Dereference the expression, where needed. Since characters
1414 are entirely different from other types, they are treated
1415 separately. */
1416 if (sym->ts.type == BT_CHARACTER)
1418 /* Dereference character pointer dummy arguments
1419 or results. */
1420 if ((sym->attr.pointer || sym->attr.allocatable)
1421 && (sym->attr.dummy
1422 || sym->attr.function
1423 || sym->attr.result))
1424 se->expr = build_fold_indirect_ref_loc (input_location,
1425 se->expr);
1428 else if (!sym->attr.value)
1430 /* Dereference non-character scalar dummy arguments. */
1431 if (sym->attr.dummy && !sym->attr.dimension
1432 && !(sym->attr.codimension && sym->attr.allocatable))
1433 se->expr = build_fold_indirect_ref_loc (input_location,
1434 se->expr);
1436 /* Dereference scalar hidden result. */
1437 if (gfc_option.flag_f2c && sym->ts.type == BT_COMPLEX
1438 && (sym->attr.function || sym->attr.result)
1439 && !sym->attr.dimension && !sym->attr.pointer
1440 && !sym->attr.always_explicit)
1441 se->expr = build_fold_indirect_ref_loc (input_location,
1442 se->expr);
1444 /* Dereference non-character pointer variables.
1445 These must be dummies, results, or scalars. */
1446 if ((sym->attr.pointer || sym->attr.allocatable
1447 || gfc_is_associate_pointer (sym)
1448 || (sym->as && sym->as->type == AS_ASSUMED_RANK))
1449 && (sym->attr.dummy
1450 || sym->attr.function
1451 || sym->attr.result
1452 || (!sym->attr.dimension
1453 && (!sym->attr.codimension || !sym->attr.allocatable))))
1454 se->expr = build_fold_indirect_ref_loc (input_location,
1455 se->expr);
1458 ref = expr->ref;
1461 /* For character variables, also get the length. */
1462 if (sym->ts.type == BT_CHARACTER)
1464 /* If the character length of an entry isn't set, get the length from
1465 the master function instead. */
1466 if (sym->attr.entry && !sym->ts.u.cl->backend_decl)
1467 se->string_length = sym->ns->proc_name->ts.u.cl->backend_decl;
1468 else
1469 se->string_length = sym->ts.u.cl->backend_decl;
1470 gcc_assert (se->string_length);
1473 while (ref)
1475 switch (ref->type)
1477 case REF_ARRAY:
1478 /* Return the descriptor if that's what we want and this is an array
1479 section reference. */
1480 if (se->descriptor_only && ref->u.ar.type != AR_ELEMENT)
1481 return;
1482 /* TODO: Pointers to single elements of array sections, eg elemental subs. */
1483 /* Return the descriptor for array pointers and allocations. */
1484 if (se->want_pointer
1485 && ref->next == NULL && (se->descriptor_only))
1486 return;
1488 gfc_conv_array_ref (se, &ref->u.ar, sym, &expr->where);
1489 /* Return a pointer to an element. */
1490 break;
1492 case REF_COMPONENT:
1493 if (ref->u.c.sym->attr.extension)
1494 conv_parent_component_references (se, ref);
1496 gfc_conv_component_ref (se, ref);
1498 break;
1500 case REF_SUBSTRING:
1501 gfc_conv_substring (se, ref, expr->ts.kind,
1502 expr->symtree->name, &expr->where);
1503 break;
1505 default:
1506 gcc_unreachable ();
1507 break;
1509 ref = ref->next;
1511 /* Pointer assignment, allocation or pass by reference. Arrays are handled
1512 separately. */
1513 if (se->want_pointer)
1515 if (expr->ts.type == BT_CHARACTER && !gfc_is_proc_ptr_comp (expr))
1516 gfc_conv_string_parameter (se);
1517 else
1518 se->expr = gfc_build_addr_expr (NULL_TREE, se->expr);
1523 /* Unary ops are easy... Or they would be if ! was a valid op. */
1525 static void
1526 gfc_conv_unary_op (enum tree_code code, gfc_se * se, gfc_expr * expr)
1528 gfc_se operand;
1529 tree type;
1531 gcc_assert (expr->ts.type != BT_CHARACTER);
1532 /* Initialize the operand. */
1533 gfc_init_se (&operand, se);
1534 gfc_conv_expr_val (&operand, expr->value.op.op1);
1535 gfc_add_block_to_block (&se->pre, &operand.pre);
1537 type = gfc_typenode_for_spec (&expr->ts);
1539 /* TRUTH_NOT_EXPR is not a "true" unary operator in GCC.
1540 We must convert it to a compare to 0 (e.g. EQ_EXPR (op1, 0)).
1541 All other unary operators have an equivalent GIMPLE unary operator. */
1542 if (code == TRUTH_NOT_EXPR)
1543 se->expr = fold_build2_loc (input_location, EQ_EXPR, type, operand.expr,
1544 build_int_cst (type, 0));
1545 else
1546 se->expr = fold_build1_loc (input_location, code, type, operand.expr);
1550 /* Expand power operator to optimal multiplications when a value is raised
1551 to a constant integer n. See section 4.6.3, "Evaluation of Powers" of
1552 Donald E. Knuth, "Seminumerical Algorithms", Vol. 2, "The Art of Computer
1553 Programming", 3rd Edition, 1998. */
1555 /* This code is mostly duplicated from expand_powi in the backend.
1556 We establish the "optimal power tree" lookup table with the defined size.
1557 The items in the table are the exponents used to calculate the index
1558 exponents. Any integer n less than the value can get an "addition chain",
1559 with the first node being one. */
1560 #define POWI_TABLE_SIZE 256
1562 /* The table is from builtins.c. */
1563 static const unsigned char powi_table[POWI_TABLE_SIZE] =
1565 0, 1, 1, 2, 2, 3, 3, 4, /* 0 - 7 */
1566 4, 6, 5, 6, 6, 10, 7, 9, /* 8 - 15 */
1567 8, 16, 9, 16, 10, 12, 11, 13, /* 16 - 23 */
1568 12, 17, 13, 18, 14, 24, 15, 26, /* 24 - 31 */
1569 16, 17, 17, 19, 18, 33, 19, 26, /* 32 - 39 */
1570 20, 25, 21, 40, 22, 27, 23, 44, /* 40 - 47 */
1571 24, 32, 25, 34, 26, 29, 27, 44, /* 48 - 55 */
1572 28, 31, 29, 34, 30, 60, 31, 36, /* 56 - 63 */
1573 32, 64, 33, 34, 34, 46, 35, 37, /* 64 - 71 */
1574 36, 65, 37, 50, 38, 48, 39, 69, /* 72 - 79 */
1575 40, 49, 41, 43, 42, 51, 43, 58, /* 80 - 87 */
1576 44, 64, 45, 47, 46, 59, 47, 76, /* 88 - 95 */
1577 48, 65, 49, 66, 50, 67, 51, 66, /* 96 - 103 */
1578 52, 70, 53, 74, 54, 104, 55, 74, /* 104 - 111 */
1579 56, 64, 57, 69, 58, 78, 59, 68, /* 112 - 119 */
1580 60, 61, 61, 80, 62, 75, 63, 68, /* 120 - 127 */
1581 64, 65, 65, 128, 66, 129, 67, 90, /* 128 - 135 */
1582 68, 73, 69, 131, 70, 94, 71, 88, /* 136 - 143 */
1583 72, 128, 73, 98, 74, 132, 75, 121, /* 144 - 151 */
1584 76, 102, 77, 124, 78, 132, 79, 106, /* 152 - 159 */
1585 80, 97, 81, 160, 82, 99, 83, 134, /* 160 - 167 */
1586 84, 86, 85, 95, 86, 160, 87, 100, /* 168 - 175 */
1587 88, 113, 89, 98, 90, 107, 91, 122, /* 176 - 183 */
1588 92, 111, 93, 102, 94, 126, 95, 150, /* 184 - 191 */
1589 96, 128, 97, 130, 98, 133, 99, 195, /* 192 - 199 */
1590 100, 128, 101, 123, 102, 164, 103, 138, /* 200 - 207 */
1591 104, 145, 105, 146, 106, 109, 107, 149, /* 208 - 215 */
1592 108, 200, 109, 146, 110, 170, 111, 157, /* 216 - 223 */
1593 112, 128, 113, 130, 114, 182, 115, 132, /* 224 - 231 */
1594 116, 200, 117, 132, 118, 158, 119, 206, /* 232 - 239 */
1595 120, 240, 121, 162, 122, 147, 123, 152, /* 240 - 247 */
1596 124, 166, 125, 214, 126, 138, 127, 153, /* 248 - 255 */
1599 /* If n is larger than lookup table's max index, we use the "window
1600 method". */
1601 #define POWI_WINDOW_SIZE 3
1603 /* Recursive function to expand the power operator. The temporary
1604 values are put in tmpvar. The function returns tmpvar[1] ** n. */
1605 static tree
1606 gfc_conv_powi (gfc_se * se, unsigned HOST_WIDE_INT n, tree * tmpvar)
1608 tree op0;
1609 tree op1;
1610 tree tmp;
1611 int digit;
1613 if (n < POWI_TABLE_SIZE)
1615 if (tmpvar[n])
1616 return tmpvar[n];
1618 op0 = gfc_conv_powi (se, n - powi_table[n], tmpvar);
1619 op1 = gfc_conv_powi (se, powi_table[n], tmpvar);
1621 else if (n & 1)
1623 digit = n & ((1 << POWI_WINDOW_SIZE) - 1);
1624 op0 = gfc_conv_powi (se, n - digit, tmpvar);
1625 op1 = gfc_conv_powi (se, digit, tmpvar);
1627 else
1629 op0 = gfc_conv_powi (se, n >> 1, tmpvar);
1630 op1 = op0;
1633 tmp = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (op0), op0, op1);
1634 tmp = gfc_evaluate_now (tmp, &se->pre);
1636 if (n < POWI_TABLE_SIZE)
1637 tmpvar[n] = tmp;
1639 return tmp;
1643 /* Expand lhs ** rhs. rhs is a constant integer. If it expands successfully,
1644 return 1. Else return 0 and a call to runtime library functions
1645 will have to be built. */
1646 static int
1647 gfc_conv_cst_int_power (gfc_se * se, tree lhs, tree rhs)
1649 tree cond;
1650 tree tmp;
1651 tree type;
1652 tree vartmp[POWI_TABLE_SIZE];
1653 HOST_WIDE_INT m;
1654 unsigned HOST_WIDE_INT n;
1655 int sgn;
1657 /* If exponent is too large, we won't expand it anyway, so don't bother
1658 with large integer values. */
1659 if (!double_int_fits_in_shwi_p (TREE_INT_CST (rhs)))
1660 return 0;
1662 m = double_int_to_shwi (TREE_INT_CST (rhs));
1663 /* There's no ABS for HOST_WIDE_INT, so here we go. It also takes care
1664 of the asymmetric range of the integer type. */
1665 n = (unsigned HOST_WIDE_INT) (m < 0 ? -m : m);
1667 type = TREE_TYPE (lhs);
1668 sgn = tree_int_cst_sgn (rhs);
1670 if (((FLOAT_TYPE_P (type) && !flag_unsafe_math_optimizations)
1671 || optimize_size) && (m > 2 || m < -1))
1672 return 0;
1674 /* rhs == 0 */
1675 if (sgn == 0)
1677 se->expr = gfc_build_const (type, integer_one_node);
1678 return 1;
1681 /* If rhs < 0 and lhs is an integer, the result is -1, 0 or 1. */
1682 if ((sgn == -1) && (TREE_CODE (type) == INTEGER_TYPE))
1684 tmp = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
1685 lhs, build_int_cst (TREE_TYPE (lhs), -1));
1686 cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
1687 lhs, build_int_cst (TREE_TYPE (lhs), 1));
1689 /* If rhs is even,
1690 result = (lhs == 1 || lhs == -1) ? 1 : 0. */
1691 if ((n & 1) == 0)
1693 tmp = fold_build2_loc (input_location, TRUTH_OR_EXPR,
1694 boolean_type_node, tmp, cond);
1695 se->expr = fold_build3_loc (input_location, COND_EXPR, type,
1696 tmp, build_int_cst (type, 1),
1697 build_int_cst (type, 0));
1698 return 1;
1700 /* If rhs is odd,
1701 result = (lhs == 1) ? 1 : (lhs == -1) ? -1 : 0. */
1702 tmp = fold_build3_loc (input_location, COND_EXPR, type, tmp,
1703 build_int_cst (type, -1),
1704 build_int_cst (type, 0));
1705 se->expr = fold_build3_loc (input_location, COND_EXPR, type,
1706 cond, build_int_cst (type, 1), tmp);
1707 return 1;
1710 memset (vartmp, 0, sizeof (vartmp));
1711 vartmp[1] = lhs;
1712 if (sgn == -1)
1714 tmp = gfc_build_const (type, integer_one_node);
1715 vartmp[1] = fold_build2_loc (input_location, RDIV_EXPR, type, tmp,
1716 vartmp[1]);
1719 se->expr = gfc_conv_powi (se, n, vartmp);
1721 return 1;
1725 /* Power op (**). Constant integer exponent has special handling. */
1727 static void
1728 gfc_conv_power_op (gfc_se * se, gfc_expr * expr)
1730 tree gfc_int4_type_node;
1731 int kind;
1732 int ikind;
1733 int res_ikind_1, res_ikind_2;
1734 gfc_se lse;
1735 gfc_se rse;
1736 tree fndecl = NULL;
1738 gfc_init_se (&lse, se);
1739 gfc_conv_expr_val (&lse, expr->value.op.op1);
1740 lse.expr = gfc_evaluate_now (lse.expr, &lse.pre);
1741 gfc_add_block_to_block (&se->pre, &lse.pre);
1743 gfc_init_se (&rse, se);
1744 gfc_conv_expr_val (&rse, expr->value.op.op2);
1745 gfc_add_block_to_block (&se->pre, &rse.pre);
1747 if (expr->value.op.op2->ts.type == BT_INTEGER
1748 && expr->value.op.op2->expr_type == EXPR_CONSTANT)
1749 if (gfc_conv_cst_int_power (se, lse.expr, rse.expr))
1750 return;
1752 gfc_int4_type_node = gfc_get_int_type (4);
1754 /* In case of integer operands with kinds 1 or 2, we call the integer kind 4
1755 library routine. But in the end, we have to convert the result back
1756 if this case applies -- with res_ikind_K, we keep track whether operand K
1757 falls into this case. */
1758 res_ikind_1 = -1;
1759 res_ikind_2 = -1;
1761 kind = expr->value.op.op1->ts.kind;
1762 switch (expr->value.op.op2->ts.type)
1764 case BT_INTEGER:
1765 ikind = expr->value.op.op2->ts.kind;
1766 switch (ikind)
1768 case 1:
1769 case 2:
1770 rse.expr = convert (gfc_int4_type_node, rse.expr);
1771 res_ikind_2 = ikind;
1772 /* Fall through. */
1774 case 4:
1775 ikind = 0;
1776 break;
1778 case 8:
1779 ikind = 1;
1780 break;
1782 case 16:
1783 ikind = 2;
1784 break;
1786 default:
1787 gcc_unreachable ();
1789 switch (kind)
1791 case 1:
1792 case 2:
1793 if (expr->value.op.op1->ts.type == BT_INTEGER)
1795 lse.expr = convert (gfc_int4_type_node, lse.expr);
1796 res_ikind_1 = kind;
1798 else
1799 gcc_unreachable ();
1800 /* Fall through. */
1802 case 4:
1803 kind = 0;
1804 break;
1806 case 8:
1807 kind = 1;
1808 break;
1810 case 10:
1811 kind = 2;
1812 break;
1814 case 16:
1815 kind = 3;
1816 break;
1818 default:
1819 gcc_unreachable ();
1822 switch (expr->value.op.op1->ts.type)
1824 case BT_INTEGER:
1825 if (kind == 3) /* Case 16 was not handled properly above. */
1826 kind = 2;
1827 fndecl = gfor_fndecl_math_powi[kind][ikind].integer;
1828 break;
1830 case BT_REAL:
1831 /* Use builtins for real ** int4. */
1832 if (ikind == 0)
1834 switch (kind)
1836 case 0:
1837 fndecl = builtin_decl_explicit (BUILT_IN_POWIF);
1838 break;
1840 case 1:
1841 fndecl = builtin_decl_explicit (BUILT_IN_POWI);
1842 break;
1844 case 2:
1845 fndecl = builtin_decl_explicit (BUILT_IN_POWIL);
1846 break;
1848 case 3:
1849 /* Use the __builtin_powil() only if real(kind=16) is
1850 actually the C long double type. */
1851 if (!gfc_real16_is_float128)
1852 fndecl = builtin_decl_explicit (BUILT_IN_POWIL);
1853 break;
1855 default:
1856 gcc_unreachable ();
1860 /* If we don't have a good builtin for this, go for the
1861 library function. */
1862 if (!fndecl)
1863 fndecl = gfor_fndecl_math_powi[kind][ikind].real;
1864 break;
1866 case BT_COMPLEX:
1867 fndecl = gfor_fndecl_math_powi[kind][ikind].cmplx;
1868 break;
1870 default:
1871 gcc_unreachable ();
1873 break;
1875 case BT_REAL:
1876 fndecl = gfc_builtin_decl_for_float_kind (BUILT_IN_POW, kind);
1877 break;
1879 case BT_COMPLEX:
1880 fndecl = gfc_builtin_decl_for_float_kind (BUILT_IN_CPOW, kind);
1881 break;
1883 default:
1884 gcc_unreachable ();
1885 break;
1888 se->expr = build_call_expr_loc (input_location,
1889 fndecl, 2, lse.expr, rse.expr);
1891 /* Convert the result back if it is of wrong integer kind. */
1892 if (res_ikind_1 != -1 && res_ikind_2 != -1)
1894 /* We want the maximum of both operand kinds as result. */
1895 if (res_ikind_1 < res_ikind_2)
1896 res_ikind_1 = res_ikind_2;
1897 se->expr = convert (gfc_get_int_type (res_ikind_1), se->expr);
1902 /* Generate code to allocate a string temporary. */
1904 tree
1905 gfc_conv_string_tmp (gfc_se * se, tree type, tree len)
1907 tree var;
1908 tree tmp;
1910 if (gfc_can_put_var_on_stack (len))
1912 /* Create a temporary variable to hold the result. */
1913 tmp = fold_build2_loc (input_location, MINUS_EXPR,
1914 gfc_charlen_type_node, len,
1915 build_int_cst (gfc_charlen_type_node, 1));
1916 tmp = build_range_type (gfc_array_index_type, gfc_index_zero_node, tmp);
1918 if (TREE_CODE (TREE_TYPE (type)) == ARRAY_TYPE)
1919 tmp = build_array_type (TREE_TYPE (TREE_TYPE (type)), tmp);
1920 else
1921 tmp = build_array_type (TREE_TYPE (type), tmp);
1923 var = gfc_create_var (tmp, "str");
1924 var = gfc_build_addr_expr (type, var);
1926 else
1928 /* Allocate a temporary to hold the result. */
1929 var = gfc_create_var (type, "pstr");
1930 tmp = gfc_call_malloc (&se->pre, type,
1931 fold_build2_loc (input_location, MULT_EXPR,
1932 TREE_TYPE (len), len,
1933 fold_convert (TREE_TYPE (len),
1934 TYPE_SIZE (type))));
1935 gfc_add_modify (&se->pre, var, tmp);
1937 /* Free the temporary afterwards. */
1938 tmp = gfc_call_free (convert (pvoid_type_node, var));
1939 gfc_add_expr_to_block (&se->post, tmp);
1942 return var;
1946 /* Handle a string concatenation operation. A temporary will be allocated to
1947 hold the result. */
1949 static void
1950 gfc_conv_concat_op (gfc_se * se, gfc_expr * expr)
1952 gfc_se lse, rse;
1953 tree len, type, var, tmp, fndecl;
1955 gcc_assert (expr->value.op.op1->ts.type == BT_CHARACTER
1956 && expr->value.op.op2->ts.type == BT_CHARACTER);
1957 gcc_assert (expr->value.op.op1->ts.kind == expr->value.op.op2->ts.kind);
1959 gfc_init_se (&lse, se);
1960 gfc_conv_expr (&lse, expr->value.op.op1);
1961 gfc_conv_string_parameter (&lse);
1962 gfc_init_se (&rse, se);
1963 gfc_conv_expr (&rse, expr->value.op.op2);
1964 gfc_conv_string_parameter (&rse);
1966 gfc_add_block_to_block (&se->pre, &lse.pre);
1967 gfc_add_block_to_block (&se->pre, &rse.pre);
1969 type = gfc_get_character_type (expr->ts.kind, expr->ts.u.cl);
1970 len = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
1971 if (len == NULL_TREE)
1973 len = fold_build2_loc (input_location, PLUS_EXPR,
1974 TREE_TYPE (lse.string_length),
1975 lse.string_length, rse.string_length);
1978 type = build_pointer_type (type);
1980 var = gfc_conv_string_tmp (se, type, len);
1982 /* Do the actual concatenation. */
1983 if (expr->ts.kind == 1)
1984 fndecl = gfor_fndecl_concat_string;
1985 else if (expr->ts.kind == 4)
1986 fndecl = gfor_fndecl_concat_string_char4;
1987 else
1988 gcc_unreachable ();
1990 tmp = build_call_expr_loc (input_location,
1991 fndecl, 6, len, var, lse.string_length, lse.expr,
1992 rse.string_length, rse.expr);
1993 gfc_add_expr_to_block (&se->pre, tmp);
1995 /* Add the cleanup for the operands. */
1996 gfc_add_block_to_block (&se->pre, &rse.post);
1997 gfc_add_block_to_block (&se->pre, &lse.post);
1999 se->expr = var;
2000 se->string_length = len;
2003 /* Translates an op expression. Common (binary) cases are handled by this
2004 function, others are passed on. Recursion is used in either case.
2005 We use the fact that (op1.ts == op2.ts) (except for the power
2006 operator **).
2007 Operators need no special handling for scalarized expressions as long as
2008 they call gfc_conv_simple_val to get their operands.
2009 Character strings get special handling. */
2011 static void
2012 gfc_conv_expr_op (gfc_se * se, gfc_expr * expr)
2014 enum tree_code code;
2015 gfc_se lse;
2016 gfc_se rse;
2017 tree tmp, type;
2018 int lop;
2019 int checkstring;
2021 checkstring = 0;
2022 lop = 0;
2023 switch (expr->value.op.op)
2025 case INTRINSIC_PARENTHESES:
2026 if ((expr->ts.type == BT_REAL
2027 || expr->ts.type == BT_COMPLEX)
2028 && gfc_option.flag_protect_parens)
2030 gfc_conv_unary_op (PAREN_EXPR, se, expr);
2031 gcc_assert (FLOAT_TYPE_P (TREE_TYPE (se->expr)));
2032 return;
2035 /* Fallthrough. */
2036 case INTRINSIC_UPLUS:
2037 gfc_conv_expr (se, expr->value.op.op1);
2038 return;
2040 case INTRINSIC_UMINUS:
2041 gfc_conv_unary_op (NEGATE_EXPR, se, expr);
2042 return;
2044 case INTRINSIC_NOT:
2045 gfc_conv_unary_op (TRUTH_NOT_EXPR, se, expr);
2046 return;
2048 case INTRINSIC_PLUS:
2049 code = PLUS_EXPR;
2050 break;
2052 case INTRINSIC_MINUS:
2053 code = MINUS_EXPR;
2054 break;
2056 case INTRINSIC_TIMES:
2057 code = MULT_EXPR;
2058 break;
2060 case INTRINSIC_DIVIDE:
2061 /* If expr is a real or complex expr, use an RDIV_EXPR. If op1 is
2062 an integer, we must round towards zero, so we use a
2063 TRUNC_DIV_EXPR. */
2064 if (expr->ts.type == BT_INTEGER)
2065 code = TRUNC_DIV_EXPR;
2066 else
2067 code = RDIV_EXPR;
2068 break;
2070 case INTRINSIC_POWER:
2071 gfc_conv_power_op (se, expr);
2072 return;
2074 case INTRINSIC_CONCAT:
2075 gfc_conv_concat_op (se, expr);
2076 return;
2078 case INTRINSIC_AND:
2079 code = TRUTH_ANDIF_EXPR;
2080 lop = 1;
2081 break;
2083 case INTRINSIC_OR:
2084 code = TRUTH_ORIF_EXPR;
2085 lop = 1;
2086 break;
2088 /* EQV and NEQV only work on logicals, but since we represent them
2089 as integers, we can use EQ_EXPR and NE_EXPR for them in GIMPLE. */
2090 case INTRINSIC_EQ:
2091 case INTRINSIC_EQ_OS:
2092 case INTRINSIC_EQV:
2093 code = EQ_EXPR;
2094 checkstring = 1;
2095 lop = 1;
2096 break;
2098 case INTRINSIC_NE:
2099 case INTRINSIC_NE_OS:
2100 case INTRINSIC_NEQV:
2101 code = NE_EXPR;
2102 checkstring = 1;
2103 lop = 1;
2104 break;
2106 case INTRINSIC_GT:
2107 case INTRINSIC_GT_OS:
2108 code = GT_EXPR;
2109 checkstring = 1;
2110 lop = 1;
2111 break;
2113 case INTRINSIC_GE:
2114 case INTRINSIC_GE_OS:
2115 code = GE_EXPR;
2116 checkstring = 1;
2117 lop = 1;
2118 break;
2120 case INTRINSIC_LT:
2121 case INTRINSIC_LT_OS:
2122 code = LT_EXPR;
2123 checkstring = 1;
2124 lop = 1;
2125 break;
2127 case INTRINSIC_LE:
2128 case INTRINSIC_LE_OS:
2129 code = LE_EXPR;
2130 checkstring = 1;
2131 lop = 1;
2132 break;
2134 case INTRINSIC_USER:
2135 case INTRINSIC_ASSIGN:
2136 /* These should be converted into function calls by the frontend. */
2137 gcc_unreachable ();
2139 default:
2140 fatal_error ("Unknown intrinsic op");
2141 return;
2144 /* The only exception to this is **, which is handled separately anyway. */
2145 gcc_assert (expr->value.op.op1->ts.type == expr->value.op.op2->ts.type);
2147 if (checkstring && expr->value.op.op1->ts.type != BT_CHARACTER)
2148 checkstring = 0;
2150 /* lhs */
2151 gfc_init_se (&lse, se);
2152 gfc_conv_expr (&lse, expr->value.op.op1);
2153 gfc_add_block_to_block (&se->pre, &lse.pre);
2155 /* rhs */
2156 gfc_init_se (&rse, se);
2157 gfc_conv_expr (&rse, expr->value.op.op2);
2158 gfc_add_block_to_block (&se->pre, &rse.pre);
2160 if (checkstring)
2162 gfc_conv_string_parameter (&lse);
2163 gfc_conv_string_parameter (&rse);
2165 lse.expr = gfc_build_compare_string (lse.string_length, lse.expr,
2166 rse.string_length, rse.expr,
2167 expr->value.op.op1->ts.kind,
2168 code);
2169 rse.expr = build_int_cst (TREE_TYPE (lse.expr), 0);
2170 gfc_add_block_to_block (&lse.post, &rse.post);
2173 type = gfc_typenode_for_spec (&expr->ts);
2175 if (lop)
2177 /* The result of logical ops is always boolean_type_node. */
2178 tmp = fold_build2_loc (input_location, code, boolean_type_node,
2179 lse.expr, rse.expr);
2180 se->expr = convert (type, tmp);
2182 else
2183 se->expr = fold_build2_loc (input_location, code, type, lse.expr, rse.expr);
2185 /* Add the post blocks. */
2186 gfc_add_block_to_block (&se->post, &rse.post);
2187 gfc_add_block_to_block (&se->post, &lse.post);
2190 /* If a string's length is one, we convert it to a single character. */
2192 tree
2193 gfc_string_to_single_character (tree len, tree str, int kind)
2196 if (len == NULL
2197 || !INTEGER_CST_P (len) || TREE_INT_CST_HIGH (len) != 0
2198 || !POINTER_TYPE_P (TREE_TYPE (str)))
2199 return NULL_TREE;
2201 if (TREE_INT_CST_LOW (len) == 1)
2203 str = fold_convert (gfc_get_pchar_type (kind), str);
2204 return build_fold_indirect_ref_loc (input_location, str);
2207 if (kind == 1
2208 && TREE_CODE (str) == ADDR_EXPR
2209 && TREE_CODE (TREE_OPERAND (str, 0)) == ARRAY_REF
2210 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (str, 0), 0)) == STRING_CST
2211 && array_ref_low_bound (TREE_OPERAND (str, 0))
2212 == TREE_OPERAND (TREE_OPERAND (str, 0), 1)
2213 && TREE_INT_CST_LOW (len) > 1
2214 && TREE_INT_CST_LOW (len)
2215 == (unsigned HOST_WIDE_INT)
2216 TREE_STRING_LENGTH (TREE_OPERAND (TREE_OPERAND (str, 0), 0)))
2218 tree ret = fold_convert (gfc_get_pchar_type (kind), str);
2219 ret = build_fold_indirect_ref_loc (input_location, ret);
2220 if (TREE_CODE (ret) == INTEGER_CST)
2222 tree string_cst = TREE_OPERAND (TREE_OPERAND (str, 0), 0);
2223 int i, length = TREE_STRING_LENGTH (string_cst);
2224 const char *ptr = TREE_STRING_POINTER (string_cst);
2226 for (i = 1; i < length; i++)
2227 if (ptr[i] != ' ')
2228 return NULL_TREE;
2230 return ret;
2234 return NULL_TREE;
2238 void
2239 gfc_conv_scalar_char_value (gfc_symbol *sym, gfc_se *se, gfc_expr **expr)
2242 if (sym->backend_decl)
2244 /* This becomes the nominal_type in
2245 function.c:assign_parm_find_data_types. */
2246 TREE_TYPE (sym->backend_decl) = unsigned_char_type_node;
2247 /* This becomes the passed_type in
2248 function.c:assign_parm_find_data_types. C promotes char to
2249 integer for argument passing. */
2250 DECL_ARG_TYPE (sym->backend_decl) = unsigned_type_node;
2252 DECL_BY_REFERENCE (sym->backend_decl) = 0;
2255 if (expr != NULL)
2257 /* If we have a constant character expression, make it into an
2258 integer. */
2259 if ((*expr)->expr_type == EXPR_CONSTANT)
2261 gfc_typespec ts;
2262 gfc_clear_ts (&ts);
2264 *expr = gfc_get_int_expr (gfc_default_integer_kind, NULL,
2265 (int)(*expr)->value.character.string[0]);
2266 if ((*expr)->ts.kind != gfc_c_int_kind)
2268 /* The expr needs to be compatible with a C int. If the
2269 conversion fails, then the 2 causes an ICE. */
2270 ts.type = BT_INTEGER;
2271 ts.kind = gfc_c_int_kind;
2272 gfc_convert_type (*expr, &ts, 2);
2275 else if (se != NULL && (*expr)->expr_type == EXPR_VARIABLE)
2277 if ((*expr)->ref == NULL)
2279 se->expr = gfc_string_to_single_character
2280 (build_int_cst (integer_type_node, 1),
2281 gfc_build_addr_expr (gfc_get_pchar_type ((*expr)->ts.kind),
2282 gfc_get_symbol_decl
2283 ((*expr)->symtree->n.sym)),
2284 (*expr)->ts.kind);
2286 else
2288 gfc_conv_variable (se, *expr);
2289 se->expr = gfc_string_to_single_character
2290 (build_int_cst (integer_type_node, 1),
2291 gfc_build_addr_expr (gfc_get_pchar_type ((*expr)->ts.kind),
2292 se->expr),
2293 (*expr)->ts.kind);
2299 /* Helper function for gfc_build_compare_string. Return LEN_TRIM value
2300 if STR is a string literal, otherwise return -1. */
2302 static int
2303 gfc_optimize_len_trim (tree len, tree str, int kind)
2305 if (kind == 1
2306 && TREE_CODE (str) == ADDR_EXPR
2307 && TREE_CODE (TREE_OPERAND (str, 0)) == ARRAY_REF
2308 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (str, 0), 0)) == STRING_CST
2309 && array_ref_low_bound (TREE_OPERAND (str, 0))
2310 == TREE_OPERAND (TREE_OPERAND (str, 0), 1)
2311 && TREE_INT_CST_LOW (len) >= 1
2312 && TREE_INT_CST_LOW (len)
2313 == (unsigned HOST_WIDE_INT)
2314 TREE_STRING_LENGTH (TREE_OPERAND (TREE_OPERAND (str, 0), 0)))
2316 tree folded = fold_convert (gfc_get_pchar_type (kind), str);
2317 folded = build_fold_indirect_ref_loc (input_location, folded);
2318 if (TREE_CODE (folded) == INTEGER_CST)
2320 tree string_cst = TREE_OPERAND (TREE_OPERAND (str, 0), 0);
2321 int length = TREE_STRING_LENGTH (string_cst);
2322 const char *ptr = TREE_STRING_POINTER (string_cst);
2324 for (; length > 0; length--)
2325 if (ptr[length - 1] != ' ')
2326 break;
2328 return length;
2331 return -1;
2334 /* Compare two strings. If they are all single characters, the result is the
2335 subtraction of them. Otherwise, we build a library call. */
2337 tree
2338 gfc_build_compare_string (tree len1, tree str1, tree len2, tree str2, int kind,
2339 enum tree_code code)
2341 tree sc1;
2342 tree sc2;
2343 tree fndecl;
2345 gcc_assert (POINTER_TYPE_P (TREE_TYPE (str1)));
2346 gcc_assert (POINTER_TYPE_P (TREE_TYPE (str2)));
2348 sc1 = gfc_string_to_single_character (len1, str1, kind);
2349 sc2 = gfc_string_to_single_character (len2, str2, kind);
2351 if (sc1 != NULL_TREE && sc2 != NULL_TREE)
2353 /* Deal with single character specially. */
2354 sc1 = fold_convert (integer_type_node, sc1);
2355 sc2 = fold_convert (integer_type_node, sc2);
2356 return fold_build2_loc (input_location, MINUS_EXPR, integer_type_node,
2357 sc1, sc2);
2360 if ((code == EQ_EXPR || code == NE_EXPR)
2361 && optimize
2362 && INTEGER_CST_P (len1) && INTEGER_CST_P (len2))
2364 /* If one string is a string literal with LEN_TRIM longer
2365 than the length of the second string, the strings
2366 compare unequal. */
2367 int len = gfc_optimize_len_trim (len1, str1, kind);
2368 if (len > 0 && compare_tree_int (len2, len) < 0)
2369 return integer_one_node;
2370 len = gfc_optimize_len_trim (len2, str2, kind);
2371 if (len > 0 && compare_tree_int (len1, len) < 0)
2372 return integer_one_node;
2375 /* Build a call for the comparison. */
2376 if (kind == 1)
2377 fndecl = gfor_fndecl_compare_string;
2378 else if (kind == 4)
2379 fndecl = gfor_fndecl_compare_string_char4;
2380 else
2381 gcc_unreachable ();
2383 return build_call_expr_loc (input_location, fndecl, 4,
2384 len1, str1, len2, str2);
2388 /* Return the backend_decl for a procedure pointer component. */
2390 static tree
2391 get_proc_ptr_comp (gfc_expr *e)
2393 gfc_se comp_se;
2394 gfc_expr *e2;
2395 expr_t old_type;
2397 gfc_init_se (&comp_se, NULL);
2398 e2 = gfc_copy_expr (e);
2399 /* We have to restore the expr type later so that gfc_free_expr frees
2400 the exact same thing that was allocated.
2401 TODO: This is ugly. */
2402 old_type = e2->expr_type;
2403 e2->expr_type = EXPR_VARIABLE;
2404 gfc_conv_expr (&comp_se, e2);
2405 e2->expr_type = old_type;
2406 gfc_free_expr (e2);
2407 return build_fold_addr_expr_loc (input_location, comp_se.expr);
2411 /* Convert a typebound function reference from a class object. */
2412 static void
2413 conv_base_obj_fcn_val (gfc_se * se, tree base_object, gfc_expr * expr)
2415 gfc_ref *ref;
2416 tree var;
2418 if (TREE_CODE (base_object) != VAR_DECL)
2420 var = gfc_create_var (TREE_TYPE (base_object), NULL);
2421 gfc_add_modify (&se->pre, var, base_object);
2423 se->expr = gfc_class_vptr_get (base_object);
2424 se->expr = build_fold_indirect_ref_loc (input_location, se->expr);
2425 ref = expr->ref;
2426 while (ref && ref->next)
2427 ref = ref->next;
2428 gcc_assert (ref && ref->type == REF_COMPONENT);
2429 if (ref->u.c.sym->attr.extension)
2430 conv_parent_component_references (se, ref);
2431 gfc_conv_component_ref (se, ref);
2432 se->expr = build_fold_addr_expr_loc (input_location, se->expr);
2436 static void
2437 conv_function_val (gfc_se * se, gfc_symbol * sym, gfc_expr * expr)
2439 tree tmp;
2441 if (gfc_is_proc_ptr_comp (expr))
2442 tmp = get_proc_ptr_comp (expr);
2443 else if (sym->attr.dummy)
2445 tmp = gfc_get_symbol_decl (sym);
2446 if (sym->attr.proc_pointer)
2447 tmp = build_fold_indirect_ref_loc (input_location,
2448 tmp);
2449 gcc_assert (TREE_CODE (TREE_TYPE (tmp)) == POINTER_TYPE
2450 && TREE_CODE (TREE_TYPE (TREE_TYPE (tmp))) == FUNCTION_TYPE);
2452 else
2454 if (!sym->backend_decl)
2455 sym->backend_decl = gfc_get_extern_function_decl (sym);
2457 tmp = sym->backend_decl;
2459 if (sym->attr.cray_pointee)
2461 /* TODO - make the cray pointee a pointer to a procedure,
2462 assign the pointer to it and use it for the call. This
2463 will do for now! */
2464 tmp = convert (build_pointer_type (TREE_TYPE (tmp)),
2465 gfc_get_symbol_decl (sym->cp_pointer));
2466 tmp = gfc_evaluate_now (tmp, &se->pre);
2469 if (!POINTER_TYPE_P (TREE_TYPE (tmp)))
2471 gcc_assert (TREE_CODE (tmp) == FUNCTION_DECL);
2472 tmp = gfc_build_addr_expr (NULL_TREE, tmp);
2475 se->expr = tmp;
2479 /* Initialize MAPPING. */
2481 void
2482 gfc_init_interface_mapping (gfc_interface_mapping * mapping)
2484 mapping->syms = NULL;
2485 mapping->charlens = NULL;
2489 /* Free all memory held by MAPPING (but not MAPPING itself). */
2491 void
2492 gfc_free_interface_mapping (gfc_interface_mapping * mapping)
2494 gfc_interface_sym_mapping *sym;
2495 gfc_interface_sym_mapping *nextsym;
2496 gfc_charlen *cl;
2497 gfc_charlen *nextcl;
2499 for (sym = mapping->syms; sym; sym = nextsym)
2501 nextsym = sym->next;
2502 sym->new_sym->n.sym->formal = NULL;
2503 gfc_free_symbol (sym->new_sym->n.sym);
2504 gfc_free_expr (sym->expr);
2505 free (sym->new_sym);
2506 free (sym);
2508 for (cl = mapping->charlens; cl; cl = nextcl)
2510 nextcl = cl->next;
2511 gfc_free_expr (cl->length);
2512 free (cl);
2517 /* Return a copy of gfc_charlen CL. Add the returned structure to
2518 MAPPING so that it will be freed by gfc_free_interface_mapping. */
2520 static gfc_charlen *
2521 gfc_get_interface_mapping_charlen (gfc_interface_mapping * mapping,
2522 gfc_charlen * cl)
2524 gfc_charlen *new_charlen;
2526 new_charlen = gfc_get_charlen ();
2527 new_charlen->next = mapping->charlens;
2528 new_charlen->length = gfc_copy_expr (cl->length);
2530 mapping->charlens = new_charlen;
2531 return new_charlen;
2535 /* A subroutine of gfc_add_interface_mapping. Return a descriptorless
2536 array variable that can be used as the actual argument for dummy
2537 argument SYM. Add any initialization code to BLOCK. PACKED is as
2538 for gfc_get_nodesc_array_type and DATA points to the first element
2539 in the passed array. */
2541 static tree
2542 gfc_get_interface_mapping_array (stmtblock_t * block, gfc_symbol * sym,
2543 gfc_packed packed, tree data)
2545 tree type;
2546 tree var;
2548 type = gfc_typenode_for_spec (&sym->ts);
2549 type = gfc_get_nodesc_array_type (type, sym->as, packed,
2550 !sym->attr.target && !sym->attr.pointer
2551 && !sym->attr.proc_pointer);
2553 var = gfc_create_var (type, "ifm");
2554 gfc_add_modify (block, var, fold_convert (type, data));
2556 return var;
2560 /* A subroutine of gfc_add_interface_mapping. Set the stride, upper bounds
2561 and offset of descriptorless array type TYPE given that it has the same
2562 size as DESC. Add any set-up code to BLOCK. */
2564 static void
2565 gfc_set_interface_mapping_bounds (stmtblock_t * block, tree type, tree desc)
2567 int n;
2568 tree dim;
2569 tree offset;
2570 tree tmp;
2572 offset = gfc_index_zero_node;
2573 for (n = 0; n < GFC_TYPE_ARRAY_RANK (type); n++)
2575 dim = gfc_rank_cst[n];
2576 GFC_TYPE_ARRAY_STRIDE (type, n) = gfc_conv_array_stride (desc, n);
2577 if (GFC_TYPE_ARRAY_LBOUND (type, n) == NULL_TREE)
2579 GFC_TYPE_ARRAY_LBOUND (type, n)
2580 = gfc_conv_descriptor_lbound_get (desc, dim);
2581 GFC_TYPE_ARRAY_UBOUND (type, n)
2582 = gfc_conv_descriptor_ubound_get (desc, dim);
2584 else if (GFC_TYPE_ARRAY_UBOUND (type, n) == NULL_TREE)
2586 tmp = fold_build2_loc (input_location, MINUS_EXPR,
2587 gfc_array_index_type,
2588 gfc_conv_descriptor_ubound_get (desc, dim),
2589 gfc_conv_descriptor_lbound_get (desc, dim));
2590 tmp = fold_build2_loc (input_location, PLUS_EXPR,
2591 gfc_array_index_type,
2592 GFC_TYPE_ARRAY_LBOUND (type, n), tmp);
2593 tmp = gfc_evaluate_now (tmp, block);
2594 GFC_TYPE_ARRAY_UBOUND (type, n) = tmp;
2596 tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
2597 GFC_TYPE_ARRAY_LBOUND (type, n),
2598 GFC_TYPE_ARRAY_STRIDE (type, n));
2599 offset = fold_build2_loc (input_location, MINUS_EXPR,
2600 gfc_array_index_type, offset, tmp);
2602 offset = gfc_evaluate_now (offset, block);
2603 GFC_TYPE_ARRAY_OFFSET (type) = offset;
2607 /* Extend MAPPING so that it maps dummy argument SYM to the value stored
2608 in SE. The caller may still use se->expr and se->string_length after
2609 calling this function. */
2611 void
2612 gfc_add_interface_mapping (gfc_interface_mapping * mapping,
2613 gfc_symbol * sym, gfc_se * se,
2614 gfc_expr *expr)
2616 gfc_interface_sym_mapping *sm;
2617 tree desc;
2618 tree tmp;
2619 tree value;
2620 gfc_symbol *new_sym;
2621 gfc_symtree *root;
2622 gfc_symtree *new_symtree;
2624 /* Create a new symbol to represent the actual argument. */
2625 new_sym = gfc_new_symbol (sym->name, NULL);
2626 new_sym->ts = sym->ts;
2627 new_sym->as = gfc_copy_array_spec (sym->as);
2628 new_sym->attr.referenced = 1;
2629 new_sym->attr.dimension = sym->attr.dimension;
2630 new_sym->attr.contiguous = sym->attr.contiguous;
2631 new_sym->attr.codimension = sym->attr.codimension;
2632 new_sym->attr.pointer = sym->attr.pointer;
2633 new_sym->attr.allocatable = sym->attr.allocatable;
2634 new_sym->attr.flavor = sym->attr.flavor;
2635 new_sym->attr.function = sym->attr.function;
2637 /* Ensure that the interface is available and that
2638 descriptors are passed for array actual arguments. */
2639 if (sym->attr.flavor == FL_PROCEDURE)
2641 new_sym->formal = expr->symtree->n.sym->formal;
2642 new_sym->attr.always_explicit
2643 = expr->symtree->n.sym->attr.always_explicit;
2646 /* Create a fake symtree for it. */
2647 root = NULL;
2648 new_symtree = gfc_new_symtree (&root, sym->name);
2649 new_symtree->n.sym = new_sym;
2650 gcc_assert (new_symtree == root);
2652 /* Create a dummy->actual mapping. */
2653 sm = XCNEW (gfc_interface_sym_mapping);
2654 sm->next = mapping->syms;
2655 sm->old = sym;
2656 sm->new_sym = new_symtree;
2657 sm->expr = gfc_copy_expr (expr);
2658 mapping->syms = sm;
2660 /* Stabilize the argument's value. */
2661 if (!sym->attr.function && se)
2662 se->expr = gfc_evaluate_now (se->expr, &se->pre);
2664 if (sym->ts.type == BT_CHARACTER)
2666 /* Create a copy of the dummy argument's length. */
2667 new_sym->ts.u.cl = gfc_get_interface_mapping_charlen (mapping, sym->ts.u.cl);
2668 sm->expr->ts.u.cl = new_sym->ts.u.cl;
2670 /* If the length is specified as "*", record the length that
2671 the caller is passing. We should use the callee's length
2672 in all other cases. */
2673 if (!new_sym->ts.u.cl->length && se)
2675 se->string_length = gfc_evaluate_now (se->string_length, &se->pre);
2676 new_sym->ts.u.cl->backend_decl = se->string_length;
2680 if (!se)
2681 return;
2683 /* Use the passed value as-is if the argument is a function. */
2684 if (sym->attr.flavor == FL_PROCEDURE)
2685 value = se->expr;
2687 /* If the argument is either a string or a pointer to a string,
2688 convert it to a boundless character type. */
2689 else if (!sym->attr.dimension && sym->ts.type == BT_CHARACTER)
2691 tmp = gfc_get_character_type_len (sym->ts.kind, NULL);
2692 tmp = build_pointer_type (tmp);
2693 if (sym->attr.pointer)
2694 value = build_fold_indirect_ref_loc (input_location,
2695 se->expr);
2696 else
2697 value = se->expr;
2698 value = fold_convert (tmp, value);
2701 /* If the argument is a scalar, a pointer to an array or an allocatable,
2702 dereference it. */
2703 else if (!sym->attr.dimension || sym->attr.pointer || sym->attr.allocatable)
2704 value = build_fold_indirect_ref_loc (input_location,
2705 se->expr);
2707 /* For character(*), use the actual argument's descriptor. */
2708 else if (sym->ts.type == BT_CHARACTER && !new_sym->ts.u.cl->length)
2709 value = build_fold_indirect_ref_loc (input_location,
2710 se->expr);
2712 /* If the argument is an array descriptor, use it to determine
2713 information about the actual argument's shape. */
2714 else if (POINTER_TYPE_P (TREE_TYPE (se->expr))
2715 && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (TREE_TYPE (se->expr))))
2717 /* Get the actual argument's descriptor. */
2718 desc = build_fold_indirect_ref_loc (input_location,
2719 se->expr);
2721 /* Create the replacement variable. */
2722 tmp = gfc_conv_descriptor_data_get (desc);
2723 value = gfc_get_interface_mapping_array (&se->pre, sym,
2724 PACKED_NO, tmp);
2726 /* Use DESC to work out the upper bounds, strides and offset. */
2727 gfc_set_interface_mapping_bounds (&se->pre, TREE_TYPE (value), desc);
2729 else
2730 /* Otherwise we have a packed array. */
2731 value = gfc_get_interface_mapping_array (&se->pre, sym,
2732 PACKED_FULL, se->expr);
2734 new_sym->backend_decl = value;
2738 /* Called once all dummy argument mappings have been added to MAPPING,
2739 but before the mapping is used to evaluate expressions. Pre-evaluate
2740 the length of each argument, adding any initialization code to PRE and
2741 any finalization code to POST. */
2743 void
2744 gfc_finish_interface_mapping (gfc_interface_mapping * mapping,
2745 stmtblock_t * pre, stmtblock_t * post)
2747 gfc_interface_sym_mapping *sym;
2748 gfc_expr *expr;
2749 gfc_se se;
2751 for (sym = mapping->syms; sym; sym = sym->next)
2752 if (sym->new_sym->n.sym->ts.type == BT_CHARACTER
2753 && !sym->new_sym->n.sym->ts.u.cl->backend_decl)
2755 expr = sym->new_sym->n.sym->ts.u.cl->length;
2756 gfc_apply_interface_mapping_to_expr (mapping, expr);
2757 gfc_init_se (&se, NULL);
2758 gfc_conv_expr (&se, expr);
2759 se.expr = fold_convert (gfc_charlen_type_node, se.expr);
2760 se.expr = gfc_evaluate_now (se.expr, &se.pre);
2761 gfc_add_block_to_block (pre, &se.pre);
2762 gfc_add_block_to_block (post, &se.post);
2764 sym->new_sym->n.sym->ts.u.cl->backend_decl = se.expr;
2769 /* Like gfc_apply_interface_mapping_to_expr, but applied to
2770 constructor C. */
2772 static void
2773 gfc_apply_interface_mapping_to_cons (gfc_interface_mapping * mapping,
2774 gfc_constructor_base base)
2776 gfc_constructor *c;
2777 for (c = gfc_constructor_first (base); c; c = gfc_constructor_next (c))
2779 gfc_apply_interface_mapping_to_expr (mapping, c->expr);
2780 if (c->iterator)
2782 gfc_apply_interface_mapping_to_expr (mapping, c->iterator->start);
2783 gfc_apply_interface_mapping_to_expr (mapping, c->iterator->end);
2784 gfc_apply_interface_mapping_to_expr (mapping, c->iterator->step);
2790 /* Like gfc_apply_interface_mapping_to_expr, but applied to
2791 reference REF. */
2793 static void
2794 gfc_apply_interface_mapping_to_ref (gfc_interface_mapping * mapping,
2795 gfc_ref * ref)
2797 int n;
2799 for (; ref; ref = ref->next)
2800 switch (ref->type)
2802 case REF_ARRAY:
2803 for (n = 0; n < ref->u.ar.dimen; n++)
2805 gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.start[n]);
2806 gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.end[n]);
2807 gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.stride[n]);
2809 break;
2811 case REF_COMPONENT:
2812 break;
2814 case REF_SUBSTRING:
2815 gfc_apply_interface_mapping_to_expr (mapping, ref->u.ss.start);
2816 gfc_apply_interface_mapping_to_expr (mapping, ref->u.ss.end);
2817 break;
2822 /* Convert intrinsic function calls into result expressions. */
2824 static bool
2825 gfc_map_intrinsic_function (gfc_expr *expr, gfc_interface_mapping *mapping)
2827 gfc_symbol *sym;
2828 gfc_expr *new_expr;
2829 gfc_expr *arg1;
2830 gfc_expr *arg2;
2831 int d, dup;
2833 arg1 = expr->value.function.actual->expr;
2834 if (expr->value.function.actual->next)
2835 arg2 = expr->value.function.actual->next->expr;
2836 else
2837 arg2 = NULL;
2839 sym = arg1->symtree->n.sym;
2841 if (sym->attr.dummy)
2842 return false;
2844 new_expr = NULL;
2846 switch (expr->value.function.isym->id)
2848 case GFC_ISYM_LEN:
2849 /* TODO figure out why this condition is necessary. */
2850 if (sym->attr.function
2851 && (arg1->ts.u.cl->length == NULL
2852 || (arg1->ts.u.cl->length->expr_type != EXPR_CONSTANT
2853 && arg1->ts.u.cl->length->expr_type != EXPR_VARIABLE)))
2854 return false;
2856 new_expr = gfc_copy_expr (arg1->ts.u.cl->length);
2857 break;
2859 case GFC_ISYM_SIZE:
2860 if (!sym->as || sym->as->rank == 0)
2861 return false;
2863 if (arg2 && arg2->expr_type == EXPR_CONSTANT)
2865 dup = mpz_get_si (arg2->value.integer);
2866 d = dup - 1;
2868 else
2870 dup = sym->as->rank;
2871 d = 0;
2874 for (; d < dup; d++)
2876 gfc_expr *tmp;
2878 if (!sym->as->upper[d] || !sym->as->lower[d])
2880 gfc_free_expr (new_expr);
2881 return false;
2884 tmp = gfc_add (gfc_copy_expr (sym->as->upper[d]),
2885 gfc_get_int_expr (gfc_default_integer_kind,
2886 NULL, 1));
2887 tmp = gfc_subtract (tmp, gfc_copy_expr (sym->as->lower[d]));
2888 if (new_expr)
2889 new_expr = gfc_multiply (new_expr, tmp);
2890 else
2891 new_expr = tmp;
2893 break;
2895 case GFC_ISYM_LBOUND:
2896 case GFC_ISYM_UBOUND:
2897 /* TODO These implementations of lbound and ubound do not limit if
2898 the size < 0, according to F95's 13.14.53 and 13.14.113. */
2900 if (!sym->as || sym->as->rank == 0)
2901 return false;
2903 if (arg2 && arg2->expr_type == EXPR_CONSTANT)
2904 d = mpz_get_si (arg2->value.integer) - 1;
2905 else
2906 /* TODO: If the need arises, this could produce an array of
2907 ubound/lbounds. */
2908 gcc_unreachable ();
2910 if (expr->value.function.isym->id == GFC_ISYM_LBOUND)
2912 if (sym->as->lower[d])
2913 new_expr = gfc_copy_expr (sym->as->lower[d]);
2915 else
2917 if (sym->as->upper[d])
2918 new_expr = gfc_copy_expr (sym->as->upper[d]);
2920 break;
2922 default:
2923 break;
2926 gfc_apply_interface_mapping_to_expr (mapping, new_expr);
2927 if (!new_expr)
2928 return false;
2930 gfc_replace_expr (expr, new_expr);
2931 return true;
2935 static void
2936 gfc_map_fcn_formal_to_actual (gfc_expr *expr, gfc_expr *map_expr,
2937 gfc_interface_mapping * mapping)
2939 gfc_formal_arglist *f;
2940 gfc_actual_arglist *actual;
2942 actual = expr->value.function.actual;
2943 f = map_expr->symtree->n.sym->formal;
2945 for (; f && actual; f = f->next, actual = actual->next)
2947 if (!actual->expr)
2948 continue;
2950 gfc_add_interface_mapping (mapping, f->sym, NULL, actual->expr);
2953 if (map_expr->symtree->n.sym->attr.dimension)
2955 int d;
2956 gfc_array_spec *as;
2958 as = gfc_copy_array_spec (map_expr->symtree->n.sym->as);
2960 for (d = 0; d < as->rank; d++)
2962 gfc_apply_interface_mapping_to_expr (mapping, as->lower[d]);
2963 gfc_apply_interface_mapping_to_expr (mapping, as->upper[d]);
2966 expr->value.function.esym->as = as;
2969 if (map_expr->symtree->n.sym->ts.type == BT_CHARACTER)
2971 expr->value.function.esym->ts.u.cl->length
2972 = gfc_copy_expr (map_expr->symtree->n.sym->ts.u.cl->length);
2974 gfc_apply_interface_mapping_to_expr (mapping,
2975 expr->value.function.esym->ts.u.cl->length);
2980 /* EXPR is a copy of an expression that appeared in the interface
2981 associated with MAPPING. Walk it recursively looking for references to
2982 dummy arguments that MAPPING maps to actual arguments. Replace each such
2983 reference with a reference to the associated actual argument. */
2985 static void
2986 gfc_apply_interface_mapping_to_expr (gfc_interface_mapping * mapping,
2987 gfc_expr * expr)
2989 gfc_interface_sym_mapping *sym;
2990 gfc_actual_arglist *actual;
2992 if (!expr)
2993 return;
2995 /* Copying an expression does not copy its length, so do that here. */
2996 if (expr->ts.type == BT_CHARACTER && expr->ts.u.cl)
2998 expr->ts.u.cl = gfc_get_interface_mapping_charlen (mapping, expr->ts.u.cl);
2999 gfc_apply_interface_mapping_to_expr (mapping, expr->ts.u.cl->length);
3002 /* Apply the mapping to any references. */
3003 gfc_apply_interface_mapping_to_ref (mapping, expr->ref);
3005 /* ...and to the expression's symbol, if it has one. */
3006 /* TODO Find out why the condition on expr->symtree had to be moved into
3007 the loop rather than being outside it, as originally. */
3008 for (sym = mapping->syms; sym; sym = sym->next)
3009 if (expr->symtree && sym->old == expr->symtree->n.sym)
3011 if (sym->new_sym->n.sym->backend_decl)
3012 expr->symtree = sym->new_sym;
3013 else if (sym->expr)
3014 gfc_replace_expr (expr, gfc_copy_expr (sym->expr));
3015 /* Replace base type for polymorphic arguments. */
3016 if (expr->ref && expr->ref->type == REF_COMPONENT
3017 && sym->expr && sym->expr->ts.type == BT_CLASS)
3018 expr->ref->u.c.sym = sym->expr->ts.u.derived;
3021 /* ...and to subexpressions in expr->value. */
3022 switch (expr->expr_type)
3024 case EXPR_VARIABLE:
3025 case EXPR_CONSTANT:
3026 case EXPR_NULL:
3027 case EXPR_SUBSTRING:
3028 break;
3030 case EXPR_OP:
3031 gfc_apply_interface_mapping_to_expr (mapping, expr->value.op.op1);
3032 gfc_apply_interface_mapping_to_expr (mapping, expr->value.op.op2);
3033 break;
3035 case EXPR_FUNCTION:
3036 for (actual = expr->value.function.actual; actual; actual = actual->next)
3037 gfc_apply_interface_mapping_to_expr (mapping, actual->expr);
3039 if (expr->value.function.esym == NULL
3040 && expr->value.function.isym != NULL
3041 && expr->value.function.actual->expr->symtree
3042 && gfc_map_intrinsic_function (expr, mapping))
3043 break;
3045 for (sym = mapping->syms; sym; sym = sym->next)
3046 if (sym->old == expr->value.function.esym)
3048 expr->value.function.esym = sym->new_sym->n.sym;
3049 gfc_map_fcn_formal_to_actual (expr, sym->expr, mapping);
3050 expr->value.function.esym->result = sym->new_sym->n.sym;
3052 break;
3054 case EXPR_ARRAY:
3055 case EXPR_STRUCTURE:
3056 gfc_apply_interface_mapping_to_cons (mapping, expr->value.constructor);
3057 break;
3059 case EXPR_COMPCALL:
3060 case EXPR_PPC:
3061 gcc_unreachable ();
3062 break;
3065 return;
3069 /* Evaluate interface expression EXPR using MAPPING. Store the result
3070 in SE. */
3072 void
3073 gfc_apply_interface_mapping (gfc_interface_mapping * mapping,
3074 gfc_se * se, gfc_expr * expr)
3076 expr = gfc_copy_expr (expr);
3077 gfc_apply_interface_mapping_to_expr (mapping, expr);
3078 gfc_conv_expr (se, expr);
3079 se->expr = gfc_evaluate_now (se->expr, &se->pre);
3080 gfc_free_expr (expr);
3084 /* Returns a reference to a temporary array into which a component of
3085 an actual argument derived type array is copied and then returned
3086 after the function call. */
3087 void
3088 gfc_conv_subref_array_arg (gfc_se * parmse, gfc_expr * expr, int g77,
3089 sym_intent intent, bool formal_ptr)
3091 gfc_se lse;
3092 gfc_se rse;
3093 gfc_ss *lss;
3094 gfc_ss *rss;
3095 gfc_loopinfo loop;
3096 gfc_loopinfo loop2;
3097 gfc_array_info *info;
3098 tree offset;
3099 tree tmp_index;
3100 tree tmp;
3101 tree base_type;
3102 tree size;
3103 stmtblock_t body;
3104 int n;
3105 int dimen;
3107 gcc_assert (expr->expr_type == EXPR_VARIABLE);
3109 gfc_init_se (&lse, NULL);
3110 gfc_init_se (&rse, NULL);
3112 /* Walk the argument expression. */
3113 rss = gfc_walk_expr (expr);
3115 gcc_assert (rss != gfc_ss_terminator);
3117 /* Initialize the scalarizer. */
3118 gfc_init_loopinfo (&loop);
3119 gfc_add_ss_to_loop (&loop, rss);
3121 /* Calculate the bounds of the scalarization. */
3122 gfc_conv_ss_startstride (&loop);
3124 /* Build an ss for the temporary. */
3125 if (expr->ts.type == BT_CHARACTER && !expr->ts.u.cl->backend_decl)
3126 gfc_conv_string_length (expr->ts.u.cl, expr, &parmse->pre);
3128 base_type = gfc_typenode_for_spec (&expr->ts);
3129 if (GFC_ARRAY_TYPE_P (base_type)
3130 || GFC_DESCRIPTOR_TYPE_P (base_type))
3131 base_type = gfc_get_element_type (base_type);
3133 if (expr->ts.type == BT_CLASS)
3134 base_type = gfc_typenode_for_spec (&CLASS_DATA (expr)->ts);
3136 loop.temp_ss = gfc_get_temp_ss (base_type, ((expr->ts.type == BT_CHARACTER)
3137 ? expr->ts.u.cl->backend_decl
3138 : NULL),
3139 loop.dimen);
3141 parmse->string_length = loop.temp_ss->info->string_length;
3143 /* Associate the SS with the loop. */
3144 gfc_add_ss_to_loop (&loop, loop.temp_ss);
3146 /* Setup the scalarizing loops. */
3147 gfc_conv_loop_setup (&loop, &expr->where);
3149 /* Pass the temporary descriptor back to the caller. */
3150 info = &loop.temp_ss->info->data.array;
3151 parmse->expr = info->descriptor;
3153 /* Setup the gfc_se structures. */
3154 gfc_copy_loopinfo_to_se (&lse, &loop);
3155 gfc_copy_loopinfo_to_se (&rse, &loop);
3157 rse.ss = rss;
3158 lse.ss = loop.temp_ss;
3159 gfc_mark_ss_chain_used (rss, 1);
3160 gfc_mark_ss_chain_used (loop.temp_ss, 1);
3162 /* Start the scalarized loop body. */
3163 gfc_start_scalarized_body (&loop, &body);
3165 /* Translate the expression. */
3166 gfc_conv_expr (&rse, expr);
3168 gfc_conv_tmp_array_ref (&lse);
3170 if (intent != INTENT_OUT)
3172 tmp = gfc_trans_scalar_assign (&lse, &rse, expr->ts, true, false, true);
3173 gfc_add_expr_to_block (&body, tmp);
3174 gcc_assert (rse.ss == gfc_ss_terminator);
3175 gfc_trans_scalarizing_loops (&loop, &body);
3177 else
3179 /* Make sure that the temporary declaration survives by merging
3180 all the loop declarations into the current context. */
3181 for (n = 0; n < loop.dimen; n++)
3183 gfc_merge_block_scope (&body);
3184 body = loop.code[loop.order[n]];
3186 gfc_merge_block_scope (&body);
3189 /* Add the post block after the second loop, so that any
3190 freeing of allocated memory is done at the right time. */
3191 gfc_add_block_to_block (&parmse->pre, &loop.pre);
3193 /**********Copy the temporary back again.*********/
3195 gfc_init_se (&lse, NULL);
3196 gfc_init_se (&rse, NULL);
3198 /* Walk the argument expression. */
3199 lss = gfc_walk_expr (expr);
3200 rse.ss = loop.temp_ss;
3201 lse.ss = lss;
3203 /* Initialize the scalarizer. */
3204 gfc_init_loopinfo (&loop2);
3205 gfc_add_ss_to_loop (&loop2, lss);
3207 /* Calculate the bounds of the scalarization. */
3208 gfc_conv_ss_startstride (&loop2);
3210 /* Setup the scalarizing loops. */
3211 gfc_conv_loop_setup (&loop2, &expr->where);
3213 gfc_copy_loopinfo_to_se (&lse, &loop2);
3214 gfc_copy_loopinfo_to_se (&rse, &loop2);
3216 gfc_mark_ss_chain_used (lss, 1);
3217 gfc_mark_ss_chain_used (loop.temp_ss, 1);
3219 /* Declare the variable to hold the temporary offset and start the
3220 scalarized loop body. */
3221 offset = gfc_create_var (gfc_array_index_type, NULL);
3222 gfc_start_scalarized_body (&loop2, &body);
3224 /* Build the offsets for the temporary from the loop variables. The
3225 temporary array has lbounds of zero and strides of one in all
3226 dimensions, so this is very simple. The offset is only computed
3227 outside the innermost loop, so the overall transfer could be
3228 optimized further. */
3229 info = &rse.ss->info->data.array;
3230 dimen = rse.ss->dimen;
3232 tmp_index = gfc_index_zero_node;
3233 for (n = dimen - 1; n > 0; n--)
3235 tree tmp_str;
3236 tmp = rse.loop->loopvar[n];
3237 tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
3238 tmp, rse.loop->from[n]);
3239 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
3240 tmp, tmp_index);
3242 tmp_str = fold_build2_loc (input_location, MINUS_EXPR,
3243 gfc_array_index_type,
3244 rse.loop->to[n-1], rse.loop->from[n-1]);
3245 tmp_str = fold_build2_loc (input_location, PLUS_EXPR,
3246 gfc_array_index_type,
3247 tmp_str, gfc_index_one_node);
3249 tmp_index = fold_build2_loc (input_location, MULT_EXPR,
3250 gfc_array_index_type, tmp, tmp_str);
3253 tmp_index = fold_build2_loc (input_location, MINUS_EXPR,
3254 gfc_array_index_type,
3255 tmp_index, rse.loop->from[0]);
3256 gfc_add_modify (&rse.loop->code[0], offset, tmp_index);
3258 tmp_index = fold_build2_loc (input_location, PLUS_EXPR,
3259 gfc_array_index_type,
3260 rse.loop->loopvar[0], offset);
3262 /* Now use the offset for the reference. */
3263 tmp = build_fold_indirect_ref_loc (input_location,
3264 info->data);
3265 rse.expr = gfc_build_array_ref (tmp, tmp_index, NULL);
3267 if (expr->ts.type == BT_CHARACTER)
3268 rse.string_length = expr->ts.u.cl->backend_decl;
3270 gfc_conv_expr (&lse, expr);
3272 gcc_assert (lse.ss == gfc_ss_terminator);
3274 tmp = gfc_trans_scalar_assign (&lse, &rse, expr->ts, false, false, true);
3275 gfc_add_expr_to_block (&body, tmp);
3277 /* Generate the copying loops. */
3278 gfc_trans_scalarizing_loops (&loop2, &body);
3280 /* Wrap the whole thing up by adding the second loop to the post-block
3281 and following it by the post-block of the first loop. In this way,
3282 if the temporary needs freeing, it is done after use! */
3283 if (intent != INTENT_IN)
3285 gfc_add_block_to_block (&parmse->post, &loop2.pre);
3286 gfc_add_block_to_block (&parmse->post, &loop2.post);
3289 gfc_add_block_to_block (&parmse->post, &loop.post);
3291 gfc_cleanup_loop (&loop);
3292 gfc_cleanup_loop (&loop2);
3294 /* Pass the string length to the argument expression. */
3295 if (expr->ts.type == BT_CHARACTER)
3296 parmse->string_length = expr->ts.u.cl->backend_decl;
3298 /* Determine the offset for pointer formal arguments and set the
3299 lbounds to one. */
3300 if (formal_ptr)
3302 size = gfc_index_one_node;
3303 offset = gfc_index_zero_node;
3304 for (n = 0; n < dimen; n++)
3306 tmp = gfc_conv_descriptor_ubound_get (parmse->expr,
3307 gfc_rank_cst[n]);
3308 tmp = fold_build2_loc (input_location, PLUS_EXPR,
3309 gfc_array_index_type, tmp,
3310 gfc_index_one_node);
3311 gfc_conv_descriptor_ubound_set (&parmse->pre,
3312 parmse->expr,
3313 gfc_rank_cst[n],
3314 tmp);
3315 gfc_conv_descriptor_lbound_set (&parmse->pre,
3316 parmse->expr,
3317 gfc_rank_cst[n],
3318 gfc_index_one_node);
3319 size = gfc_evaluate_now (size, &parmse->pre);
3320 offset = fold_build2_loc (input_location, MINUS_EXPR,
3321 gfc_array_index_type,
3322 offset, size);
3323 offset = gfc_evaluate_now (offset, &parmse->pre);
3324 tmp = fold_build2_loc (input_location, MINUS_EXPR,
3325 gfc_array_index_type,
3326 rse.loop->to[n], rse.loop->from[n]);
3327 tmp = fold_build2_loc (input_location, PLUS_EXPR,
3328 gfc_array_index_type,
3329 tmp, gfc_index_one_node);
3330 size = fold_build2_loc (input_location, MULT_EXPR,
3331 gfc_array_index_type, size, tmp);
3334 gfc_conv_descriptor_offset_set (&parmse->pre, parmse->expr,
3335 offset);
3338 /* We want either the address for the data or the address of the descriptor,
3339 depending on the mode of passing array arguments. */
3340 if (g77)
3341 parmse->expr = gfc_conv_descriptor_data_get (parmse->expr);
3342 else
3343 parmse->expr = gfc_build_addr_expr (NULL_TREE, parmse->expr);
3345 return;
3349 /* Generate the code for argument list functions. */
3351 static void
3352 conv_arglist_function (gfc_se *se, gfc_expr *expr, const char *name)
3354 /* Pass by value for g77 %VAL(arg), pass the address
3355 indirectly for %LOC, else by reference. Thus %REF
3356 is a "do-nothing" and %LOC is the same as an F95
3357 pointer. */
3358 if (strncmp (name, "%VAL", 4) == 0)
3359 gfc_conv_expr (se, expr);
3360 else if (strncmp (name, "%LOC", 4) == 0)
3362 gfc_conv_expr_reference (se, expr);
3363 se->expr = gfc_build_addr_expr (NULL, se->expr);
3365 else if (strncmp (name, "%REF", 4) == 0)
3366 gfc_conv_expr_reference (se, expr);
3367 else
3368 gfc_error ("Unknown argument list function at %L", &expr->where);
3372 /* The following routine generates code for the intrinsic
3373 procedures from the ISO_C_BINDING module:
3374 * C_LOC (function)
3375 * C_FUNLOC (function)
3376 * C_F_POINTER (subroutine)
3377 * C_F_PROCPOINTER (subroutine)
3378 * C_ASSOCIATED (function)
3379 One exception which is not handled here is C_F_POINTER with non-scalar
3380 arguments. Returns 1 if the call was replaced by inline code (else: 0). */
3382 static int
3383 conv_isocbinding_procedure (gfc_se * se, gfc_symbol * sym,
3384 gfc_actual_arglist * arg)
3386 gfc_symbol *fsym;
3387 gfc_ss *argss;
3389 if (sym->intmod_sym_id == ISOCBINDING_LOC)
3391 if (arg->expr->rank == 0)
3392 gfc_conv_expr_reference (se, arg->expr);
3393 else
3395 int f;
3396 /* This is really the actual arg because no formal arglist is
3397 created for C_LOC. */
3398 fsym = arg->expr->symtree->n.sym;
3400 /* We should want it to do g77 calling convention. */
3401 f = (fsym != NULL)
3402 && !(fsym->attr.pointer || fsym->attr.allocatable)
3403 && fsym->as->type != AS_ASSUMED_SHAPE;
3404 f = f || !sym->attr.always_explicit;
3406 argss = gfc_walk_expr (arg->expr);
3407 gfc_conv_array_parameter (se, arg->expr, argss, f,
3408 NULL, NULL, NULL);
3411 /* TODO -- the following two lines shouldn't be necessary, but if
3412 they're removed, a bug is exposed later in the code path.
3413 This workaround was thus introduced, but will have to be
3414 removed; please see PR 35150 for details about the issue. */
3415 se->expr = convert (pvoid_type_node, se->expr);
3416 se->expr = gfc_evaluate_now (se->expr, &se->pre);
3418 return 1;
3420 else if (sym->intmod_sym_id == ISOCBINDING_FUNLOC)
3422 arg->expr->ts.type = sym->ts.u.derived->ts.type;
3423 arg->expr->ts.f90_type = sym->ts.u.derived->ts.f90_type;
3424 arg->expr->ts.kind = sym->ts.u.derived->ts.kind;
3425 gfc_conv_expr_reference (se, arg->expr);
3427 return 1;
3429 else if (sym->intmod_sym_id == ISOCBINDING_F_POINTER
3430 || sym->intmod_sym_id == ISOCBINDING_F_PROCPOINTER)
3432 /* Convert c_f_pointer and c_f_procpointer. */
3433 gfc_se cptrse;
3434 gfc_se fptrse;
3435 gfc_se shapese;
3436 gfc_ss *ss, *shape_ss;
3437 tree desc, dim, tmp, stride, offset;
3438 stmtblock_t body, block;
3439 gfc_loopinfo loop;
3441 gfc_init_se (&cptrse, NULL);
3442 gfc_conv_expr (&cptrse, arg->expr);
3443 gfc_add_block_to_block (&se->pre, &cptrse.pre);
3444 gfc_add_block_to_block (&se->post, &cptrse.post);
3446 gfc_init_se (&fptrse, NULL);
3447 if (arg->next->expr->rank == 0)
3449 if (sym->intmod_sym_id == ISOCBINDING_F_POINTER
3450 || gfc_is_proc_ptr_comp (arg->next->expr))
3451 fptrse.want_pointer = 1;
3453 gfc_conv_expr (&fptrse, arg->next->expr);
3454 gfc_add_block_to_block (&se->pre, &fptrse.pre);
3455 gfc_add_block_to_block (&se->post, &fptrse.post);
3456 if (arg->next->expr->symtree->n.sym->attr.proc_pointer
3457 && arg->next->expr->symtree->n.sym->attr.dummy)
3458 fptrse.expr = build_fold_indirect_ref_loc (input_location,
3459 fptrse.expr);
3460 se->expr = fold_build2_loc (input_location, MODIFY_EXPR,
3461 TREE_TYPE (fptrse.expr),
3462 fptrse.expr,
3463 fold_convert (TREE_TYPE (fptrse.expr),
3464 cptrse.expr));
3465 return 1;
3468 gfc_start_block (&block);
3470 /* Get the descriptor of the Fortran pointer. */
3471 ss = gfc_walk_expr (arg->next->expr);
3472 gcc_assert (ss != gfc_ss_terminator);
3473 fptrse.descriptor_only = 1;
3474 gfc_conv_expr_descriptor (&fptrse, arg->next->expr, ss);
3475 gfc_add_block_to_block (&block, &fptrse.pre);
3476 desc = fptrse.expr;
3478 /* Set data value, dtype, and offset. */
3479 tmp = GFC_TYPE_ARRAY_DATAPTR_TYPE (TREE_TYPE (desc));
3480 gfc_conv_descriptor_data_set (&block, desc,
3481 fold_convert (tmp, cptrse.expr));
3482 gfc_add_modify (&block, gfc_conv_descriptor_dtype (desc),
3483 gfc_get_dtype (TREE_TYPE (desc)));
3485 /* Start scalarization of the bounds, using the shape argument. */
3487 shape_ss = gfc_walk_expr (arg->next->next->expr);
3488 gcc_assert (shape_ss != gfc_ss_terminator);
3489 gfc_init_se (&shapese, NULL);
3491 gfc_init_loopinfo (&loop);
3492 gfc_add_ss_to_loop (&loop, shape_ss);
3493 gfc_conv_ss_startstride (&loop);
3494 gfc_conv_loop_setup (&loop, &arg->next->expr->where);
3495 gfc_mark_ss_chain_used (shape_ss, 1);
3497 gfc_copy_loopinfo_to_se (&shapese, &loop);
3498 shapese.ss = shape_ss;
3500 stride = gfc_create_var (gfc_array_index_type, "stride");
3501 offset = gfc_create_var (gfc_array_index_type, "offset");
3502 gfc_add_modify (&block, stride, gfc_index_one_node);
3503 gfc_add_modify (&block, offset, gfc_index_zero_node);
3505 /* Loop body. */
3506 gfc_start_scalarized_body (&loop, &body);
3508 dim = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
3509 loop.loopvar[0], loop.from[0]);
3511 /* Set bounds and stride. */
3512 gfc_conv_descriptor_lbound_set (&body, desc, dim, gfc_index_one_node);
3513 gfc_conv_descriptor_stride_set (&body, desc, dim, stride);
3515 gfc_conv_expr (&shapese, arg->next->next->expr);
3516 gfc_add_block_to_block (&body, &shapese.pre);
3517 gfc_conv_descriptor_ubound_set (&body, desc, dim, shapese.expr);
3518 gfc_add_block_to_block (&body, &shapese.post);
3520 /* Calculate offset. */
3521 gfc_add_modify (&body, offset,
3522 fold_build2_loc (input_location, PLUS_EXPR,
3523 gfc_array_index_type, offset, stride));
3524 /* Update stride. */
3525 gfc_add_modify (&body, stride,
3526 fold_build2_loc (input_location, MULT_EXPR,
3527 gfc_array_index_type, stride,
3528 fold_convert (gfc_array_index_type,
3529 shapese.expr)));
3530 /* Finish scalarization loop. */
3531 gfc_trans_scalarizing_loops (&loop, &body);
3532 gfc_add_block_to_block (&block, &loop.pre);
3533 gfc_add_block_to_block (&block, &loop.post);
3534 gfc_add_block_to_block (&block, &fptrse.post);
3535 gfc_cleanup_loop (&loop);
3536 gfc_free_ss (ss);
3538 gfc_add_modify (&block, offset,
3539 fold_build1_loc (input_location, NEGATE_EXPR,
3540 gfc_array_index_type, offset));
3541 gfc_conv_descriptor_offset_set (&block, desc, offset);
3543 se->expr = gfc_finish_block (&block);
3544 return 1;
3546 else if (sym->intmod_sym_id == ISOCBINDING_ASSOCIATED)
3548 gfc_se arg1se;
3549 gfc_se arg2se;
3551 /* Build the addr_expr for the first argument. The argument is
3552 already an *address* so we don't need to set want_pointer in
3553 the gfc_se. */
3554 gfc_init_se (&arg1se, NULL);
3555 gfc_conv_expr (&arg1se, arg->expr);
3556 gfc_add_block_to_block (&se->pre, &arg1se.pre);
3557 gfc_add_block_to_block (&se->post, &arg1se.post);
3559 /* See if we were given two arguments. */
3560 if (arg->next == NULL)
3561 /* Only given one arg so generate a null and do a
3562 not-equal comparison against the first arg. */
3563 se->expr = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
3564 arg1se.expr,
3565 fold_convert (TREE_TYPE (arg1se.expr),
3566 null_pointer_node));
3567 else
3569 tree eq_expr;
3570 tree not_null_expr;
3572 /* Given two arguments so build the arg2se from second arg. */
3573 gfc_init_se (&arg2se, NULL);
3574 gfc_conv_expr (&arg2se, arg->next->expr);
3575 gfc_add_block_to_block (&se->pre, &arg2se.pre);
3576 gfc_add_block_to_block (&se->post, &arg2se.post);
3578 /* Generate test to compare that the two args are equal. */
3579 eq_expr = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
3580 arg1se.expr, arg2se.expr);
3581 /* Generate test to ensure that the first arg is not null. */
3582 not_null_expr = fold_build2_loc (input_location, NE_EXPR,
3583 boolean_type_node,
3584 arg1se.expr, null_pointer_node);
3586 /* Finally, the generated test must check that both arg1 is not
3587 NULL and that it is equal to the second arg. */
3588 se->expr = fold_build2_loc (input_location, TRUTH_AND_EXPR,
3589 boolean_type_node,
3590 not_null_expr, eq_expr);
3593 return 1;
3596 /* Nothing was done. */
3597 return 0;
3601 /* Generate code for a procedure call. Note can return se->post != NULL.
3602 If se->direct_byref is set then se->expr contains the return parameter.
3603 Return nonzero, if the call has alternate specifiers.
3604 'expr' is only needed for procedure pointer components. */
3607 gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
3608 gfc_actual_arglist * args, gfc_expr * expr,
3609 VEC(tree,gc) *append_args)
3611 gfc_interface_mapping mapping;
3612 VEC(tree,gc) *arglist;
3613 VEC(tree,gc) *retargs;
3614 tree tmp;
3615 tree fntype;
3616 gfc_se parmse;
3617 gfc_ss *argss;
3618 gfc_array_info *info;
3619 int byref;
3620 int parm_kind;
3621 tree type;
3622 tree var;
3623 tree len;
3624 tree base_object;
3625 VEC(tree,gc) *stringargs;
3626 tree result = NULL;
3627 gfc_formal_arglist *formal;
3628 gfc_actual_arglist *arg;
3629 int has_alternate_specifier = 0;
3630 bool need_interface_mapping;
3631 bool callee_alloc;
3632 gfc_typespec ts;
3633 gfc_charlen cl;
3634 gfc_expr *e;
3635 gfc_symbol *fsym;
3636 stmtblock_t post;
3637 enum {MISSING = 0, ELEMENTAL, SCALAR, SCALAR_POINTER, ARRAY};
3638 gfc_component *comp = NULL;
3639 int arglen;
3641 arglist = NULL;
3642 retargs = NULL;
3643 stringargs = NULL;
3644 var = NULL_TREE;
3645 len = NULL_TREE;
3646 gfc_clear_ts (&ts);
3648 if (sym->from_intmod == INTMOD_ISO_C_BINDING
3649 && conv_isocbinding_procedure (se, sym, args))
3650 return 0;
3652 comp = gfc_get_proc_ptr_comp (expr);
3654 if (se->ss != NULL)
3656 if (!sym->attr.elemental && !(comp && comp->attr.elemental))
3658 gcc_assert (se->ss->info->type == GFC_SS_FUNCTION);
3659 if (se->ss->info->useflags)
3661 gcc_assert ((!comp && gfc_return_by_reference (sym)
3662 && sym->result->attr.dimension)
3663 || (comp && comp->attr.dimension));
3664 gcc_assert (se->loop != NULL);
3666 /* Access the previously obtained result. */
3667 gfc_conv_tmp_array_ref (se);
3668 return 0;
3671 info = &se->ss->info->data.array;
3673 else
3674 info = NULL;
3676 gfc_init_block (&post);
3677 gfc_init_interface_mapping (&mapping);
3678 if (!comp)
3680 formal = sym->formal;
3681 need_interface_mapping = sym->attr.dimension ||
3682 (sym->ts.type == BT_CHARACTER
3683 && sym->ts.u.cl->length
3684 && sym->ts.u.cl->length->expr_type
3685 != EXPR_CONSTANT);
3687 else
3689 formal = comp->formal;
3690 need_interface_mapping = comp->attr.dimension ||
3691 (comp->ts.type == BT_CHARACTER
3692 && comp->ts.u.cl->length
3693 && comp->ts.u.cl->length->expr_type
3694 != EXPR_CONSTANT);
3697 base_object = NULL_TREE;
3699 /* Evaluate the arguments. */
3700 for (arg = args; arg != NULL;
3701 arg = arg->next, formal = formal ? formal->next : NULL)
3703 e = arg->expr;
3704 fsym = formal ? formal->sym : NULL;
3705 parm_kind = MISSING;
3707 /* Class array expressions are sometimes coming completely unadorned
3708 with either arrayspec or _data component. Correct that here.
3709 OOP-TODO: Move this to the frontend. */
3710 if (e && e->expr_type == EXPR_VARIABLE
3711 && !e->ref
3712 && e->ts.type == BT_CLASS
3713 && CLASS_DATA (e)->attr.dimension)
3715 gfc_typespec temp_ts = e->ts;
3716 gfc_add_class_array_ref (e);
3717 e->ts = temp_ts;
3720 if (e == NULL)
3722 if (se->ignore_optional)
3724 /* Some intrinsics have already been resolved to the correct
3725 parameters. */
3726 continue;
3728 else if (arg->label)
3730 has_alternate_specifier = 1;
3731 continue;
3733 else
3735 /* Pass a NULL pointer for an absent arg. */
3736 gfc_init_se (&parmse, NULL);
3737 parmse.expr = null_pointer_node;
3738 if (arg->missing_arg_type == BT_CHARACTER)
3739 parmse.string_length = build_int_cst (gfc_charlen_type_node, 0);
3742 else if (arg->expr->expr_type == EXPR_NULL
3743 && fsym && !fsym->attr.pointer
3744 && (fsym->ts.type != BT_CLASS
3745 || !CLASS_DATA (fsym)->attr.class_pointer))
3747 /* Pass a NULL pointer to denote an absent arg. */
3748 gcc_assert (fsym->attr.optional && !fsym->attr.allocatable
3749 && (fsym->ts.type != BT_CLASS
3750 || !CLASS_DATA (fsym)->attr.allocatable));
3751 gfc_init_se (&parmse, NULL);
3752 parmse.expr = null_pointer_node;
3753 if (arg->missing_arg_type == BT_CHARACTER)
3754 parmse.string_length = build_int_cst (gfc_charlen_type_node, 0);
3756 else if (fsym && fsym->ts.type == BT_CLASS
3757 && e->ts.type == BT_DERIVED)
3759 /* The derived type needs to be converted to a temporary
3760 CLASS object. */
3761 gfc_init_se (&parmse, se);
3762 gfc_conv_derived_to_class (&parmse, e, fsym->ts, NULL);
3764 else if (se->ss && se->ss->info->useflags)
3766 gfc_ss *ss;
3768 ss = se->ss;
3770 /* An elemental function inside a scalarized loop. */
3771 gfc_init_se (&parmse, se);
3772 parm_kind = ELEMENTAL;
3774 if (ss->dimen > 0 && e->expr_type == EXPR_VARIABLE
3775 && ss->info->data.array.ref == NULL)
3777 gfc_conv_tmp_array_ref (&parmse);
3778 if (e->ts.type == BT_CHARACTER)
3779 gfc_conv_string_parameter (&parmse);
3780 else
3781 parmse.expr = gfc_build_addr_expr (NULL_TREE, parmse.expr);
3783 else
3784 gfc_conv_expr_reference (&parmse, e);
3786 if (fsym && fsym->ts.type == BT_DERIVED
3787 && gfc_is_class_container_ref (e))
3788 parmse.expr = gfc_class_data_get (parmse.expr);
3790 /* If we are passing an absent array as optional dummy to an
3791 elemental procedure, make sure that we pass NULL when the data
3792 pointer is NULL. We need this extra conditional because of
3793 scalarization which passes arrays elements to the procedure,
3794 ignoring the fact that the array can be absent/unallocated/... */
3795 if (ss->info->can_be_null_ref && ss->info->type != GFC_SS_REFERENCE)
3797 tree descriptor_data;
3799 descriptor_data = ss->info->data.array.data;
3800 tmp = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
3801 descriptor_data,
3802 fold_convert (TREE_TYPE (descriptor_data),
3803 null_pointer_node));
3804 parmse.expr
3805 = fold_build3_loc (input_location, COND_EXPR,
3806 TREE_TYPE (parmse.expr),
3807 gfc_unlikely (tmp),
3808 fold_convert (TREE_TYPE (parmse.expr),
3809 null_pointer_node),
3810 parmse.expr);
3813 /* The scalarizer does not repackage the reference to a class
3814 array - instead it returns a pointer to the data element. */
3815 if (fsym && fsym->ts.type == BT_CLASS && e->ts.type == BT_CLASS)
3816 gfc_conv_class_to_class (&parmse, e, fsym->ts, true);
3818 else
3820 /* A scalar or transformational function. */
3821 gfc_init_se (&parmse, NULL);
3822 argss = gfc_walk_expr (e);
3824 if (argss == gfc_ss_terminator)
3826 if (e->expr_type == EXPR_VARIABLE
3827 && e->symtree->n.sym->attr.cray_pointee
3828 && fsym && fsym->attr.flavor == FL_PROCEDURE)
3830 /* The Cray pointer needs to be converted to a pointer to
3831 a type given by the expression. */
3832 gfc_conv_expr (&parmse, e);
3833 type = build_pointer_type (TREE_TYPE (parmse.expr));
3834 tmp = gfc_get_symbol_decl (e->symtree->n.sym->cp_pointer);
3835 parmse.expr = convert (type, tmp);
3837 else if (fsym && fsym->attr.value)
3839 if (fsym->ts.type == BT_CHARACTER
3840 && fsym->ts.is_c_interop
3841 && fsym->ns->proc_name != NULL
3842 && fsym->ns->proc_name->attr.is_bind_c)
3844 parmse.expr = NULL;
3845 gfc_conv_scalar_char_value (fsym, &parmse, &e);
3846 if (parmse.expr == NULL)
3847 gfc_conv_expr (&parmse, e);
3849 else
3850 gfc_conv_expr (&parmse, e);
3852 else if (arg->name && arg->name[0] == '%')
3853 /* Argument list functions %VAL, %LOC and %REF are signalled
3854 through arg->name. */
3855 conv_arglist_function (&parmse, arg->expr, arg->name);
3856 else if ((e->expr_type == EXPR_FUNCTION)
3857 && ((e->value.function.esym
3858 && e->value.function.esym->result->attr.pointer)
3859 || (!e->value.function.esym
3860 && e->symtree->n.sym->attr.pointer))
3861 && fsym && fsym->attr.target)
3863 gfc_conv_expr (&parmse, e);
3864 parmse.expr = gfc_build_addr_expr (NULL_TREE, parmse.expr);
3866 else if (e->expr_type == EXPR_FUNCTION
3867 && e->symtree->n.sym->result
3868 && e->symtree->n.sym->result != e->symtree->n.sym
3869 && e->symtree->n.sym->result->attr.proc_pointer)
3871 /* Functions returning procedure pointers. */
3872 gfc_conv_expr (&parmse, e);
3873 if (fsym && fsym->attr.proc_pointer)
3874 parmse.expr = gfc_build_addr_expr (NULL_TREE, parmse.expr);
3876 else
3878 gfc_conv_expr_reference (&parmse, e);
3880 /* Catch base objects that are not variables. */
3881 if (e->ts.type == BT_CLASS
3882 && e->expr_type != EXPR_VARIABLE
3883 && expr && e == expr->base_expr)
3884 base_object = build_fold_indirect_ref_loc (input_location,
3885 parmse.expr);
3887 /* A class array element needs converting back to be a
3888 class object, if the formal argument is a class object. */
3889 if (fsym && fsym->ts.type == BT_CLASS
3890 && e->ts.type == BT_CLASS
3891 && ((CLASS_DATA (fsym)->as
3892 && CLASS_DATA (fsym)->as->type == AS_ASSUMED_RANK)
3893 || CLASS_DATA (e)->attr.dimension))
3894 gfc_conv_class_to_class (&parmse, e, fsym->ts, false);
3896 if (fsym && (fsym->ts.type == BT_DERIVED
3897 || fsym->ts.type == BT_ASSUMED)
3898 && e->ts.type == BT_CLASS
3899 && !CLASS_DATA (e)->attr.dimension
3900 && !CLASS_DATA (e)->attr.codimension)
3901 parmse.expr = gfc_class_data_get (parmse.expr);
3903 /* If an ALLOCATABLE dummy argument has INTENT(OUT) and is
3904 allocated on entry, it must be deallocated. */
3905 if (fsym && fsym->attr.allocatable
3906 && fsym->attr.intent == INTENT_OUT)
3908 stmtblock_t block;
3910 gfc_init_block (&block);
3911 tmp = gfc_deallocate_with_status (parmse.expr, NULL_TREE,
3912 NULL_TREE, NULL_TREE,
3913 NULL_TREE, true, NULL,
3914 false);
3915 gfc_add_expr_to_block (&block, tmp);
3916 tmp = fold_build2_loc (input_location, MODIFY_EXPR,
3917 void_type_node, parmse.expr,
3918 null_pointer_node);
3919 gfc_add_expr_to_block (&block, tmp);
3921 if (fsym->attr.optional
3922 && e->expr_type == EXPR_VARIABLE
3923 && e->symtree->n.sym->attr.optional)
3925 tmp = fold_build3_loc (input_location, COND_EXPR,
3926 void_type_node,
3927 gfc_conv_expr_present (e->symtree->n.sym),
3928 gfc_finish_block (&block),
3929 build_empty_stmt (input_location));
3931 else
3932 tmp = gfc_finish_block (&block);
3934 gfc_add_expr_to_block (&se->pre, tmp);
3937 /* Wrap scalar variable in a descriptor. We need to convert
3938 the address of a pointer back to the pointer itself before,
3939 we can assign it to the data field. */
3941 if (fsym && fsym->as && fsym->as->type == AS_ASSUMED_RANK
3942 && fsym->ts.type != BT_CLASS && e->expr_type != EXPR_NULL)
3944 tmp = parmse.expr;
3945 if (TREE_CODE (tmp) == ADDR_EXPR
3946 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (tmp, 0))))
3947 tmp = TREE_OPERAND (tmp, 0);
3948 parmse.expr = conv_scalar_to_descriptor (&parmse, tmp,
3949 fsym->attr);
3950 parmse.expr = gfc_build_addr_expr (NULL_TREE,
3951 parmse.expr);
3953 else if (fsym && e->expr_type != EXPR_NULL
3954 && ((fsym->attr.pointer
3955 && fsym->attr.flavor != FL_PROCEDURE)
3956 || (fsym->attr.proc_pointer
3957 && !(e->expr_type == EXPR_VARIABLE
3958 && e->symtree->n.sym->attr.dummy))
3959 || (fsym->attr.proc_pointer
3960 && e->expr_type == EXPR_VARIABLE
3961 && gfc_is_proc_ptr_comp (e))
3962 || (fsym->attr.allocatable
3963 && fsym->attr.flavor != FL_PROCEDURE)))
3965 /* Scalar pointer dummy args require an extra level of
3966 indirection. The null pointer already contains
3967 this level of indirection. */
3968 parm_kind = SCALAR_POINTER;
3969 parmse.expr = gfc_build_addr_expr (NULL_TREE, parmse.expr);
3973 else if (e->ts.type == BT_CLASS
3974 && fsym && fsym->ts.type == BT_CLASS
3975 && CLASS_DATA (fsym)->attr.dimension)
3977 /* Pass a class array. */
3978 gfc_init_se (&parmse, se);
3979 gfc_conv_expr_descriptor (&parmse, e, argss);
3980 /* The conversion does not repackage the reference to a class
3981 array - _data descriptor. */
3982 gfc_conv_class_to_class (&parmse, e, fsym->ts, false);
3984 else
3986 /* If the procedure requires an explicit interface, the actual
3987 argument is passed according to the corresponding formal
3988 argument. If the corresponding formal argument is a POINTER,
3989 ALLOCATABLE or assumed shape, we do not use g77's calling
3990 convention, and pass the address of the array descriptor
3991 instead. Otherwise we use g77's calling convention. */
3992 bool f;
3993 f = (fsym != NULL)
3994 && !(fsym->attr.pointer || fsym->attr.allocatable)
3995 && fsym->as && fsym->as->type != AS_ASSUMED_SHAPE
3996 && fsym->as->type != AS_ASSUMED_RANK;
3997 if (comp)
3998 f = f || !comp->attr.always_explicit;
3999 else
4000 f = f || !sym->attr.always_explicit;
4002 /* If the argument is a function call that may not create
4003 a temporary for the result, we have to check that we
4004 can do it, i.e. that there is no alias between this
4005 argument and another one. */
4006 if (gfc_get_noncopying_intrinsic_argument (e) != NULL)
4008 gfc_expr *iarg;
4009 sym_intent intent;
4011 if (fsym != NULL)
4012 intent = fsym->attr.intent;
4013 else
4014 intent = INTENT_UNKNOWN;
4016 if (gfc_check_fncall_dependency (e, intent, sym, args,
4017 NOT_ELEMENTAL))
4018 parmse.force_tmp = 1;
4020 iarg = e->value.function.actual->expr;
4022 /* Temporary needed if aliasing due to host association. */
4023 if (sym->attr.contained
4024 && !sym->attr.pure
4025 && !sym->attr.implicit_pure
4026 && !sym->attr.use_assoc
4027 && iarg->expr_type == EXPR_VARIABLE
4028 && sym->ns == iarg->symtree->n.sym->ns)
4029 parmse.force_tmp = 1;
4031 /* Ditto within module. */
4032 if (sym->attr.use_assoc
4033 && !sym->attr.pure
4034 && !sym->attr.implicit_pure
4035 && iarg->expr_type == EXPR_VARIABLE
4036 && sym->module == iarg->symtree->n.sym->module)
4037 parmse.force_tmp = 1;
4040 if (e->expr_type == EXPR_VARIABLE
4041 && is_subref_array (e))
4042 /* The actual argument is a component reference to an
4043 array of derived types. In this case, the argument
4044 is converted to a temporary, which is passed and then
4045 written back after the procedure call. */
4046 gfc_conv_subref_array_arg (&parmse, e, f,
4047 fsym ? fsym->attr.intent : INTENT_INOUT,
4048 fsym && fsym->attr.pointer);
4049 else if (gfc_is_class_array_ref (e, NULL)
4050 && fsym && fsym->ts.type == BT_DERIVED)
4051 /* The actual argument is a component reference to an
4052 array of derived types. In this case, the argument
4053 is converted to a temporary, which is passed and then
4054 written back after the procedure call.
4055 OOP-TODO: Insert code so that if the dynamic type is
4056 the same as the declared type, copy-in/copy-out does
4057 not occur. */
4058 gfc_conv_subref_array_arg (&parmse, e, f,
4059 fsym ? fsym->attr.intent : INTENT_INOUT,
4060 fsym && fsym->attr.pointer);
4061 else
4062 gfc_conv_array_parameter (&parmse, e, argss, f, fsym,
4063 sym->name, NULL);
4065 /* If an ALLOCATABLE dummy argument has INTENT(OUT) and is
4066 allocated on entry, it must be deallocated. */
4067 if (fsym && fsym->attr.allocatable
4068 && fsym->attr.intent == INTENT_OUT)
4070 tmp = build_fold_indirect_ref_loc (input_location,
4071 parmse.expr);
4072 tmp = gfc_trans_dealloc_allocated (tmp, false);
4073 if (fsym->attr.optional
4074 && e->expr_type == EXPR_VARIABLE
4075 && e->symtree->n.sym->attr.optional)
4076 tmp = fold_build3_loc (input_location, COND_EXPR,
4077 void_type_node,
4078 gfc_conv_expr_present (e->symtree->n.sym),
4079 tmp, build_empty_stmt (input_location));
4080 gfc_add_expr_to_block (&se->pre, tmp);
4085 /* The case with fsym->attr.optional is that of a user subroutine
4086 with an interface indicating an optional argument. When we call
4087 an intrinsic subroutine, however, fsym is NULL, but we might still
4088 have an optional argument, so we proceed to the substitution
4089 just in case. */
4090 if (e && (fsym == NULL || fsym->attr.optional))
4092 /* If an optional argument is itself an optional dummy argument,
4093 check its presence and substitute a null if absent. This is
4094 only needed when passing an array to an elemental procedure
4095 as then array elements are accessed - or no NULL pointer is
4096 allowed and a "1" or "0" should be passed if not present.
4097 When passing a non-array-descriptor full array to a
4098 non-array-descriptor dummy, no check is needed. For
4099 array-descriptor actual to array-descriptor dummy, see
4100 PR 41911 for why a check has to be inserted.
4101 fsym == NULL is checked as intrinsics required the descriptor
4102 but do not always set fsym. */
4103 if (e->expr_type == EXPR_VARIABLE
4104 && e->symtree->n.sym->attr.optional
4105 && ((e->rank != 0 && sym->attr.elemental)
4106 || e->representation.length || e->ts.type == BT_CHARACTER
4107 || (e->rank != 0
4108 && (fsym == NULL
4109 || (fsym-> as
4110 && (fsym->as->type == AS_ASSUMED_SHAPE
4111 || fsym->as->type == AS_ASSUMED_RANK
4112 || fsym->as->type == AS_DEFERRED))))))
4113 gfc_conv_missing_dummy (&parmse, e, fsym ? fsym->ts : e->ts,
4114 e->representation.length);
4117 if (fsym && e)
4119 /* Obtain the character length of an assumed character length
4120 length procedure from the typespec. */
4121 if (fsym->ts.type == BT_CHARACTER
4122 && parmse.string_length == NULL_TREE
4123 && e->ts.type == BT_PROCEDURE
4124 && e->symtree->n.sym->ts.type == BT_CHARACTER
4125 && e->symtree->n.sym->ts.u.cl->length != NULL
4126 && e->symtree->n.sym->ts.u.cl->length->expr_type == EXPR_CONSTANT)
4128 gfc_conv_const_charlen (e->symtree->n.sym->ts.u.cl);
4129 parmse.string_length = e->symtree->n.sym->ts.u.cl->backend_decl;
4133 if (fsym && need_interface_mapping && e)
4134 gfc_add_interface_mapping (&mapping, fsym, &parmse, e);
4136 gfc_add_block_to_block (&se->pre, &parmse.pre);
4137 gfc_add_block_to_block (&post, &parmse.post);
4139 /* Allocated allocatable components of derived types must be
4140 deallocated for non-variable scalars. Non-variable arrays are
4141 dealt with in trans-array.c(gfc_conv_array_parameter). */
4142 if (e && (e->ts.type == BT_DERIVED || e->ts.type == BT_CLASS)
4143 && e->ts.u.derived->attr.alloc_comp
4144 && !(e->symtree && e->symtree->n.sym->attr.pointer)
4145 && (e->expr_type != EXPR_VARIABLE && !e->rank))
4147 int parm_rank;
4148 tmp = build_fold_indirect_ref_loc (input_location,
4149 parmse.expr);
4150 parm_rank = e->rank;
4151 switch (parm_kind)
4153 case (ELEMENTAL):
4154 case (SCALAR):
4155 parm_rank = 0;
4156 break;
4158 case (SCALAR_POINTER):
4159 tmp = build_fold_indirect_ref_loc (input_location,
4160 tmp);
4161 break;
4164 if (e->expr_type == EXPR_OP
4165 && e->value.op.op == INTRINSIC_PARENTHESES
4166 && e->value.op.op1->expr_type == EXPR_VARIABLE)
4168 tree local_tmp;
4169 local_tmp = gfc_evaluate_now (tmp, &se->pre);
4170 local_tmp = gfc_copy_alloc_comp (e->ts.u.derived, local_tmp, tmp, parm_rank);
4171 gfc_add_expr_to_block (&se->post, local_tmp);
4174 if (e->ts.type == BT_DERIVED && fsym && fsym->ts.type == BT_CLASS)
4176 /* The derived type is passed to gfc_deallocate_alloc_comp.
4177 Therefore, class actuals can handled correctly but derived
4178 types passed to class formals need the _data component. */
4179 tmp = gfc_class_data_get (tmp);
4180 if (!CLASS_DATA (fsym)->attr.dimension)
4181 tmp = build_fold_indirect_ref_loc (input_location, tmp);
4184 tmp = gfc_deallocate_alloc_comp (e->ts.u.derived, tmp, parm_rank);
4186 gfc_add_expr_to_block (&se->post, tmp);
4189 /* Add argument checking of passing an unallocated/NULL actual to
4190 a nonallocatable/nonpointer dummy. */
4192 if (gfc_option.rtcheck & GFC_RTCHECK_POINTER && e != NULL)
4194 symbol_attribute attr;
4195 char *msg;
4196 tree cond;
4198 if (e->expr_type == EXPR_VARIABLE || e->expr_type == EXPR_FUNCTION)
4199 attr = gfc_expr_attr (e);
4200 else
4201 goto end_pointer_check;
4203 /* In Fortran 2008 it's allowed to pass a NULL pointer/nonallocated
4204 allocatable to an optional dummy, cf. 12.5.2.12. */
4205 if (fsym != NULL && fsym->attr.optional && !attr.proc_pointer
4206 && (gfc_option.allow_std & GFC_STD_F2008) != 0)
4207 goto end_pointer_check;
4209 if (attr.optional)
4211 /* If the actual argument is an optional pointer/allocatable and
4212 the formal argument takes an nonpointer optional value,
4213 it is invalid to pass a non-present argument on, even
4214 though there is no technical reason for this in gfortran.
4215 See Fortran 2003, Section 12.4.1.6 item (7)+(8). */
4216 tree present, null_ptr, type;
4218 if (attr.allocatable
4219 && (fsym == NULL || !fsym->attr.allocatable))
4220 asprintf (&msg, "Allocatable actual argument '%s' is not "
4221 "allocated or not present", e->symtree->n.sym->name);
4222 else if (attr.pointer
4223 && (fsym == NULL || !fsym->attr.pointer))
4224 asprintf (&msg, "Pointer actual argument '%s' is not "
4225 "associated or not present",
4226 e->symtree->n.sym->name);
4227 else if (attr.proc_pointer
4228 && (fsym == NULL || !fsym->attr.proc_pointer))
4229 asprintf (&msg, "Proc-pointer actual argument '%s' is not "
4230 "associated or not present",
4231 e->symtree->n.sym->name);
4232 else
4233 goto end_pointer_check;
4235 present = gfc_conv_expr_present (e->symtree->n.sym);
4236 type = TREE_TYPE (present);
4237 present = fold_build2_loc (input_location, EQ_EXPR,
4238 boolean_type_node, present,
4239 fold_convert (type,
4240 null_pointer_node));
4241 type = TREE_TYPE (parmse.expr);
4242 null_ptr = fold_build2_loc (input_location, EQ_EXPR,
4243 boolean_type_node, parmse.expr,
4244 fold_convert (type,
4245 null_pointer_node));
4246 cond = fold_build2_loc (input_location, TRUTH_ORIF_EXPR,
4247 boolean_type_node, present, null_ptr);
4249 else
4251 if (attr.allocatable
4252 && (fsym == NULL || !fsym->attr.allocatable))
4253 asprintf (&msg, "Allocatable actual argument '%s' is not "
4254 "allocated", e->symtree->n.sym->name);
4255 else if (attr.pointer
4256 && (fsym == NULL || !fsym->attr.pointer))
4257 asprintf (&msg, "Pointer actual argument '%s' is not "
4258 "associated", e->symtree->n.sym->name);
4259 else if (attr.proc_pointer
4260 && (fsym == NULL || !fsym->attr.proc_pointer))
4261 asprintf (&msg, "Proc-pointer actual argument '%s' is not "
4262 "associated", e->symtree->n.sym->name);
4263 else
4264 goto end_pointer_check;
4266 tmp = parmse.expr;
4268 /* If the argument is passed by value, we need to strip the
4269 INDIRECT_REF. */
4270 if (!POINTER_TYPE_P (TREE_TYPE (parmse.expr)))
4271 tmp = gfc_build_addr_expr (NULL_TREE, tmp);
4273 cond = fold_build2_loc (input_location, EQ_EXPR,
4274 boolean_type_node, tmp,
4275 fold_convert (TREE_TYPE (tmp),
4276 null_pointer_node));
4279 gfc_trans_runtime_check (true, false, cond, &se->pre, &e->where,
4280 msg);
4281 free (msg);
4283 end_pointer_check:
4285 /* Deferred length dummies pass the character length by reference
4286 so that the value can be returned. */
4287 if (parmse.string_length && fsym && fsym->ts.deferred)
4289 tmp = parmse.string_length;
4290 if (TREE_CODE (tmp) != VAR_DECL)
4291 tmp = gfc_evaluate_now (parmse.string_length, &se->pre);
4292 parmse.string_length = gfc_build_addr_expr (NULL_TREE, tmp);
4295 /* Character strings are passed as two parameters, a length and a
4296 pointer - except for Bind(c) which only passes the pointer. */
4297 if (parmse.string_length != NULL_TREE && !sym->attr.is_bind_c)
4298 VEC_safe_push (tree, gc, stringargs, parmse.string_length);
4300 /* For descriptorless coarrays and assumed-shape coarray dummies, we
4301 pass the token and the offset as additional arguments. */
4302 if (fsym && fsym->attr.codimension
4303 && gfc_option.coarray == GFC_FCOARRAY_LIB
4304 && !fsym->attr.allocatable
4305 && e == NULL)
4307 /* Token and offset. */
4308 VEC_safe_push (tree, gc, stringargs, null_pointer_node);
4309 VEC_safe_push (tree, gc, stringargs,
4310 build_int_cst (gfc_array_index_type, 0));
4311 gcc_assert (fsym->attr.optional);
4313 else if (fsym && fsym->attr.codimension
4314 && !fsym->attr.allocatable
4315 && gfc_option.coarray == GFC_FCOARRAY_LIB)
4317 tree caf_decl, caf_type;
4318 tree offset, tmp2;
4320 caf_decl = get_tree_for_caf_expr (e);
4321 caf_type = TREE_TYPE (caf_decl);
4323 if (GFC_DESCRIPTOR_TYPE_P (caf_type)
4324 && GFC_TYPE_ARRAY_AKIND (caf_type) == GFC_ARRAY_ALLOCATABLE)
4325 tmp = gfc_conv_descriptor_token (caf_decl);
4326 else if (DECL_LANG_SPECIFIC (caf_decl)
4327 && GFC_DECL_TOKEN (caf_decl) != NULL_TREE)
4328 tmp = GFC_DECL_TOKEN (caf_decl);
4329 else
4331 gcc_assert (GFC_ARRAY_TYPE_P (caf_type)
4332 && GFC_TYPE_ARRAY_CAF_TOKEN (caf_type) != NULL_TREE);
4333 tmp = GFC_TYPE_ARRAY_CAF_TOKEN (caf_type);
4336 VEC_safe_push (tree, gc, stringargs, tmp);
4338 if (GFC_DESCRIPTOR_TYPE_P (caf_type)
4339 && GFC_TYPE_ARRAY_AKIND (caf_type) == GFC_ARRAY_ALLOCATABLE)
4340 offset = build_int_cst (gfc_array_index_type, 0);
4341 else if (DECL_LANG_SPECIFIC (caf_decl)
4342 && GFC_DECL_CAF_OFFSET (caf_decl) != NULL_TREE)
4343 offset = GFC_DECL_CAF_OFFSET (caf_decl);
4344 else if (GFC_TYPE_ARRAY_CAF_OFFSET (caf_type) != NULL_TREE)
4345 offset = GFC_TYPE_ARRAY_CAF_OFFSET (caf_type);
4346 else
4347 offset = build_int_cst (gfc_array_index_type, 0);
4349 if (GFC_DESCRIPTOR_TYPE_P (caf_type))
4350 tmp = gfc_conv_descriptor_data_get (caf_decl);
4351 else
4353 gcc_assert (POINTER_TYPE_P (caf_type));
4354 tmp = caf_decl;
4357 if (fsym->as->type == AS_ASSUMED_SHAPE
4358 || (fsym->as->type == AS_ASSUMED_RANK && !fsym->attr.pointer
4359 && !fsym->attr.allocatable))
4361 gcc_assert (POINTER_TYPE_P (TREE_TYPE (parmse.expr)));
4362 gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE
4363 (TREE_TYPE (parmse.expr))));
4364 tmp2 = build_fold_indirect_ref_loc (input_location, parmse.expr);
4365 tmp2 = gfc_conv_descriptor_data_get (tmp2);
4367 else if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (parmse.expr)))
4368 tmp2 = gfc_conv_descriptor_data_get (parmse.expr);
4369 else
4371 gcc_assert (POINTER_TYPE_P (TREE_TYPE (parmse.expr)));
4372 tmp2 = parmse.expr;
4375 tmp = fold_build2_loc (input_location, MINUS_EXPR,
4376 gfc_array_index_type,
4377 fold_convert (gfc_array_index_type, tmp2),
4378 fold_convert (gfc_array_index_type, tmp));
4379 offset = fold_build2_loc (input_location, PLUS_EXPR,
4380 gfc_array_index_type, offset, tmp);
4382 VEC_safe_push (tree, gc, stringargs, offset);
4385 VEC_safe_push (tree, gc, arglist, parmse.expr);
4387 gfc_finish_interface_mapping (&mapping, &se->pre, &se->post);
4389 if (comp)
4390 ts = comp->ts;
4391 else
4392 ts = sym->ts;
4394 if (ts.type == BT_CHARACTER && sym->attr.is_bind_c)
4395 se->string_length = build_int_cst (gfc_charlen_type_node, 1);
4396 else if (ts.type == BT_CHARACTER)
4398 if (ts.u.cl->length == NULL)
4400 /* Assumed character length results are not allowed by 5.1.1.5 of the
4401 standard and are trapped in resolve.c; except in the case of SPREAD
4402 (and other intrinsics?) and dummy functions. In the case of SPREAD,
4403 we take the character length of the first argument for the result.
4404 For dummies, we have to look through the formal argument list for
4405 this function and use the character length found there.*/
4406 if (ts.deferred)
4407 cl.backend_decl = gfc_create_var (gfc_charlen_type_node, "slen");
4408 else if (!sym->attr.dummy)
4409 cl.backend_decl = VEC_index (tree, stringargs, 0);
4410 else
4412 formal = sym->ns->proc_name->formal;
4413 for (; formal; formal = formal->next)
4414 if (strcmp (formal->sym->name, sym->name) == 0)
4415 cl.backend_decl = formal->sym->ts.u.cl->backend_decl;
4417 len = cl.backend_decl;
4419 else
4421 tree tmp;
4423 /* Calculate the length of the returned string. */
4424 gfc_init_se (&parmse, NULL);
4425 if (need_interface_mapping)
4426 gfc_apply_interface_mapping (&mapping, &parmse, ts.u.cl->length);
4427 else
4428 gfc_conv_expr (&parmse, ts.u.cl->length);
4429 gfc_add_block_to_block (&se->pre, &parmse.pre);
4430 gfc_add_block_to_block (&se->post, &parmse.post);
4432 tmp = fold_convert (gfc_charlen_type_node, parmse.expr);
4433 tmp = fold_build2_loc (input_location, MAX_EXPR,
4434 gfc_charlen_type_node, tmp,
4435 build_int_cst (gfc_charlen_type_node, 0));
4436 cl.backend_decl = tmp;
4439 /* Set up a charlen structure for it. */
4440 cl.next = NULL;
4441 cl.length = NULL;
4442 ts.u.cl = &cl;
4444 len = cl.backend_decl;
4447 byref = (comp && (comp->attr.dimension || comp->ts.type == BT_CHARACTER))
4448 || (!comp && gfc_return_by_reference (sym));
4449 if (byref)
4451 if (se->direct_byref)
4453 /* Sometimes, too much indirection can be applied; e.g. for
4454 function_result = array_valued_recursive_function. */
4455 if (TREE_TYPE (TREE_TYPE (se->expr))
4456 && TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr)))
4457 && GFC_DESCRIPTOR_TYPE_P
4458 (TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr)))))
4459 se->expr = build_fold_indirect_ref_loc (input_location,
4460 se->expr);
4462 /* If the lhs of an assignment x = f(..) is allocatable and
4463 f2003 is allowed, we must do the automatic reallocation.
4464 TODO - deal with intrinsics, without using a temporary. */
4465 if (gfc_option.flag_realloc_lhs
4466 && se->ss && se->ss->loop_chain
4467 && se->ss->loop_chain->is_alloc_lhs
4468 && !expr->value.function.isym
4469 && sym->result->as != NULL)
4471 /* Evaluate the bounds of the result, if known. */
4472 gfc_set_loop_bounds_from_array_spec (&mapping, se,
4473 sym->result->as);
4475 /* Perform the automatic reallocation. */
4476 tmp = gfc_alloc_allocatable_for_assignment (se->loop,
4477 expr, NULL);
4478 gfc_add_expr_to_block (&se->pre, tmp);
4480 /* Pass the temporary as the first argument. */
4481 result = info->descriptor;
4483 else
4484 result = build_fold_indirect_ref_loc (input_location,
4485 se->expr);
4486 VEC_safe_push (tree, gc, retargs, se->expr);
4488 else if (comp && comp->attr.dimension)
4490 gcc_assert (se->loop && info);
4492 /* Set the type of the array. */
4493 tmp = gfc_typenode_for_spec (&comp->ts);
4494 gcc_assert (se->ss->dimen == se->loop->dimen);
4496 /* Evaluate the bounds of the result, if known. */
4497 gfc_set_loop_bounds_from_array_spec (&mapping, se, comp->as);
4499 /* If the lhs of an assignment x = f(..) is allocatable and
4500 f2003 is allowed, we must not generate the function call
4501 here but should just send back the results of the mapping.
4502 This is signalled by the function ss being flagged. */
4503 if (gfc_option.flag_realloc_lhs
4504 && se->ss && se->ss->is_alloc_lhs)
4506 gfc_free_interface_mapping (&mapping);
4507 return has_alternate_specifier;
4510 /* Create a temporary to store the result. In case the function
4511 returns a pointer, the temporary will be a shallow copy and
4512 mustn't be deallocated. */
4513 callee_alloc = comp->attr.allocatable || comp->attr.pointer;
4514 gfc_trans_create_temp_array (&se->pre, &se->post, se->ss,
4515 tmp, NULL_TREE, false,
4516 !comp->attr.pointer, callee_alloc,
4517 &se->ss->info->expr->where);
4519 /* Pass the temporary as the first argument. */
4520 result = info->descriptor;
4521 tmp = gfc_build_addr_expr (NULL_TREE, result);
4522 VEC_safe_push (tree, gc, retargs, tmp);
4524 else if (!comp && sym->result->attr.dimension)
4526 gcc_assert (se->loop && info);
4528 /* Set the type of the array. */
4529 tmp = gfc_typenode_for_spec (&ts);
4530 gcc_assert (se->ss->dimen == se->loop->dimen);
4532 /* Evaluate the bounds of the result, if known. */
4533 gfc_set_loop_bounds_from_array_spec (&mapping, se, sym->result->as);
4535 /* If the lhs of an assignment x = f(..) is allocatable and
4536 f2003 is allowed, we must not generate the function call
4537 here but should just send back the results of the mapping.
4538 This is signalled by the function ss being flagged. */
4539 if (gfc_option.flag_realloc_lhs
4540 && se->ss && se->ss->is_alloc_lhs)
4542 gfc_free_interface_mapping (&mapping);
4543 return has_alternate_specifier;
4546 /* Create a temporary to store the result. In case the function
4547 returns a pointer, the temporary will be a shallow copy and
4548 mustn't be deallocated. */
4549 callee_alloc = sym->attr.allocatable || sym->attr.pointer;
4550 gfc_trans_create_temp_array (&se->pre, &se->post, se->ss,
4551 tmp, NULL_TREE, false,
4552 !sym->attr.pointer, callee_alloc,
4553 &se->ss->info->expr->where);
4555 /* Pass the temporary as the first argument. */
4556 result = info->descriptor;
4557 tmp = gfc_build_addr_expr (NULL_TREE, result);
4558 VEC_safe_push (tree, gc, retargs, tmp);
4560 else if (ts.type == BT_CHARACTER)
4562 /* Pass the string length. */
4563 type = gfc_get_character_type (ts.kind, ts.u.cl);
4564 type = build_pointer_type (type);
4566 /* Return an address to a char[0:len-1]* temporary for
4567 character pointers. */
4568 if ((!comp && (sym->attr.pointer || sym->attr.allocatable))
4569 || (comp && (comp->attr.pointer || comp->attr.allocatable)))
4571 var = gfc_create_var (type, "pstr");
4573 if ((!comp && sym->attr.allocatable)
4574 || (comp && comp->attr.allocatable))
4576 gfc_add_modify (&se->pre, var,
4577 fold_convert (TREE_TYPE (var),
4578 null_pointer_node));
4579 tmp = gfc_call_free (convert (pvoid_type_node, var));
4580 gfc_add_expr_to_block (&se->post, tmp);
4583 /* Provide an address expression for the function arguments. */
4584 var = gfc_build_addr_expr (NULL_TREE, var);
4586 else
4587 var = gfc_conv_string_tmp (se, type, len);
4589 VEC_safe_push (tree, gc, retargs, var);
4591 else
4593 gcc_assert (gfc_option.flag_f2c && ts.type == BT_COMPLEX);
4595 type = gfc_get_complex_type (ts.kind);
4596 var = gfc_build_addr_expr (NULL_TREE, gfc_create_var (type, "cmplx"));
4597 VEC_safe_push (tree, gc, retargs, var);
4600 /* Add the string length to the argument list. */
4601 if (ts.type == BT_CHARACTER && ts.deferred)
4603 tmp = len;
4604 if (TREE_CODE (tmp) != VAR_DECL)
4605 tmp = gfc_evaluate_now (len, &se->pre);
4606 tmp = gfc_build_addr_expr (NULL_TREE, tmp);
4607 VEC_safe_push (tree, gc, retargs, tmp);
4609 else if (ts.type == BT_CHARACTER)
4610 VEC_safe_push (tree, gc, retargs, len);
4612 gfc_free_interface_mapping (&mapping);
4614 /* We need to glom RETARGS + ARGLIST + STRINGARGS + APPEND_ARGS. */
4615 arglen = (VEC_length (tree, arglist)
4616 + VEC_length (tree, stringargs) + VEC_length (tree, append_args));
4617 VEC_reserve_exact (tree, gc, retargs, arglen);
4619 /* Add the return arguments. */
4620 VEC_splice (tree, retargs, arglist);
4622 /* Add the hidden string length parameters to the arguments. */
4623 VEC_splice (tree, retargs, stringargs);
4625 /* We may want to append extra arguments here. This is used e.g. for
4626 calls to libgfortran_matmul_??, which need extra information. */
4627 if (!VEC_empty (tree, append_args))
4628 VEC_splice (tree, retargs, append_args);
4629 arglist = retargs;
4631 /* Generate the actual call. */
4632 if (base_object == NULL_TREE)
4633 conv_function_val (se, sym, expr);
4634 else
4635 conv_base_obj_fcn_val (se, base_object, expr);
4637 /* If there are alternate return labels, function type should be
4638 integer. Can't modify the type in place though, since it can be shared
4639 with other functions. For dummy arguments, the typing is done to
4640 this result, even if it has to be repeated for each call. */
4641 if (has_alternate_specifier
4642 && TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr))) != integer_type_node)
4644 if (!sym->attr.dummy)
4646 TREE_TYPE (sym->backend_decl)
4647 = build_function_type (integer_type_node,
4648 TYPE_ARG_TYPES (TREE_TYPE (sym->backend_decl)));
4649 se->expr = gfc_build_addr_expr (NULL_TREE, sym->backend_decl);
4651 else
4652 TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr))) = integer_type_node;
4655 fntype = TREE_TYPE (TREE_TYPE (se->expr));
4656 se->expr = build_call_vec (TREE_TYPE (fntype), se->expr, arglist);
4658 /* If we have a pointer function, but we don't want a pointer, e.g.
4659 something like
4660 x = f()
4661 where f is pointer valued, we have to dereference the result. */
4662 if (!se->want_pointer && !byref
4663 && ((!comp && (sym->attr.pointer || sym->attr.allocatable))
4664 || (comp && (comp->attr.pointer || comp->attr.allocatable))))
4665 se->expr = build_fold_indirect_ref_loc (input_location, se->expr);
4667 /* f2c calling conventions require a scalar default real function to
4668 return a double precision result. Convert this back to default
4669 real. We only care about the cases that can happen in Fortran 77.
4671 if (gfc_option.flag_f2c && sym->ts.type == BT_REAL
4672 && sym->ts.kind == gfc_default_real_kind
4673 && !sym->attr.always_explicit)
4674 se->expr = fold_convert (gfc_get_real_type (sym->ts.kind), se->expr);
4676 /* A pure function may still have side-effects - it may modify its
4677 parameters. */
4678 TREE_SIDE_EFFECTS (se->expr) = 1;
4679 #if 0
4680 if (!sym->attr.pure)
4681 TREE_SIDE_EFFECTS (se->expr) = 1;
4682 #endif
4684 if (byref)
4686 /* Add the function call to the pre chain. There is no expression. */
4687 gfc_add_expr_to_block (&se->pre, se->expr);
4688 se->expr = NULL_TREE;
4690 if (!se->direct_byref)
4692 if ((sym->attr.dimension && !comp) || (comp && comp->attr.dimension))
4694 if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
4696 /* Check the data pointer hasn't been modified. This would
4697 happen in a function returning a pointer. */
4698 tmp = gfc_conv_descriptor_data_get (info->descriptor);
4699 tmp = fold_build2_loc (input_location, NE_EXPR,
4700 boolean_type_node,
4701 tmp, info->data);
4702 gfc_trans_runtime_check (true, false, tmp, &se->pre, NULL,
4703 gfc_msg_fault);
4705 se->expr = info->descriptor;
4706 /* Bundle in the string length. */
4707 se->string_length = len;
4709 else if (ts.type == BT_CHARACTER)
4711 /* Dereference for character pointer results. */
4712 if ((!comp && (sym->attr.pointer || sym->attr.allocatable))
4713 || (comp && (comp->attr.pointer || comp->attr.allocatable)))
4714 se->expr = build_fold_indirect_ref_loc (input_location, var);
4715 else
4716 se->expr = var;
4718 se->string_length = len;
4720 else
4722 gcc_assert (ts.type == BT_COMPLEX && gfc_option.flag_f2c);
4723 se->expr = build_fold_indirect_ref_loc (input_location, var);
4728 /* Follow the function call with the argument post block. */
4729 if (byref)
4731 gfc_add_block_to_block (&se->pre, &post);
4733 /* Transformational functions of derived types with allocatable
4734 components must have the result allocatable components copied. */
4735 arg = expr->value.function.actual;
4736 if (result && arg && expr->rank
4737 && expr->value.function.isym
4738 && expr->value.function.isym->transformational
4739 && arg->expr->ts.type == BT_DERIVED
4740 && arg->expr->ts.u.derived->attr.alloc_comp)
4742 tree tmp2;
4743 /* Copy the allocatable components. We have to use a
4744 temporary here to prevent source allocatable components
4745 from being corrupted. */
4746 tmp2 = gfc_evaluate_now (result, &se->pre);
4747 tmp = gfc_copy_alloc_comp (arg->expr->ts.u.derived,
4748 result, tmp2, expr->rank);
4749 gfc_add_expr_to_block (&se->pre, tmp);
4750 tmp = gfc_copy_allocatable_data (result, tmp2, TREE_TYPE(tmp2),
4751 expr->rank);
4752 gfc_add_expr_to_block (&se->pre, tmp);
4754 /* Finally free the temporary's data field. */
4755 tmp = gfc_conv_descriptor_data_get (tmp2);
4756 tmp = gfc_deallocate_with_status (tmp, NULL_TREE, NULL_TREE,
4757 NULL_TREE, NULL_TREE, true,
4758 NULL, false);
4759 gfc_add_expr_to_block (&se->pre, tmp);
4762 else
4763 gfc_add_block_to_block (&se->post, &post);
4765 return has_alternate_specifier;
4769 /* Fill a character string with spaces. */
4771 static tree
4772 fill_with_spaces (tree start, tree type, tree size)
4774 stmtblock_t block, loop;
4775 tree i, el, exit_label, cond, tmp;
4777 /* For a simple char type, we can call memset(). */
4778 if (compare_tree_int (TYPE_SIZE_UNIT (type), 1) == 0)
4779 return build_call_expr_loc (input_location,
4780 builtin_decl_explicit (BUILT_IN_MEMSET),
4781 3, start,
4782 build_int_cst (gfc_get_int_type (gfc_c_int_kind),
4783 lang_hooks.to_target_charset (' ')),
4784 size);
4786 /* Otherwise, we use a loop:
4787 for (el = start, i = size; i > 0; el--, i+= TYPE_SIZE_UNIT (type))
4788 *el = (type) ' ';
4791 /* Initialize variables. */
4792 gfc_init_block (&block);
4793 i = gfc_create_var (sizetype, "i");
4794 gfc_add_modify (&block, i, fold_convert (sizetype, size));
4795 el = gfc_create_var (build_pointer_type (type), "el");
4796 gfc_add_modify (&block, el, fold_convert (TREE_TYPE (el), start));
4797 exit_label = gfc_build_label_decl (NULL_TREE);
4798 TREE_USED (exit_label) = 1;
4801 /* Loop body. */
4802 gfc_init_block (&loop);
4804 /* Exit condition. */
4805 cond = fold_build2_loc (input_location, LE_EXPR, boolean_type_node, i,
4806 build_zero_cst (sizetype));
4807 tmp = build1_v (GOTO_EXPR, exit_label);
4808 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond, tmp,
4809 build_empty_stmt (input_location));
4810 gfc_add_expr_to_block (&loop, tmp);
4812 /* Assignment. */
4813 gfc_add_modify (&loop,
4814 fold_build1_loc (input_location, INDIRECT_REF, type, el),
4815 build_int_cst (type, lang_hooks.to_target_charset (' ')));
4817 /* Increment loop variables. */
4818 gfc_add_modify (&loop, i,
4819 fold_build2_loc (input_location, MINUS_EXPR, sizetype, i,
4820 TYPE_SIZE_UNIT (type)));
4821 gfc_add_modify (&loop, el,
4822 fold_build_pointer_plus_loc (input_location,
4823 el, TYPE_SIZE_UNIT (type)));
4825 /* Making the loop... actually loop! */
4826 tmp = gfc_finish_block (&loop);
4827 tmp = build1_v (LOOP_EXPR, tmp);
4828 gfc_add_expr_to_block (&block, tmp);
4830 /* The exit label. */
4831 tmp = build1_v (LABEL_EXPR, exit_label);
4832 gfc_add_expr_to_block (&block, tmp);
4835 return gfc_finish_block (&block);
4839 /* Generate code to copy a string. */
4841 void
4842 gfc_trans_string_copy (stmtblock_t * block, tree dlength, tree dest,
4843 int dkind, tree slength, tree src, int skind)
4845 tree tmp, dlen, slen;
4846 tree dsc;
4847 tree ssc;
4848 tree cond;
4849 tree cond2;
4850 tree tmp2;
4851 tree tmp3;
4852 tree tmp4;
4853 tree chartype;
4854 stmtblock_t tempblock;
4856 gcc_assert (dkind == skind);
4858 if (slength != NULL_TREE)
4860 slen = fold_convert (size_type_node, gfc_evaluate_now (slength, block));
4861 ssc = gfc_string_to_single_character (slen, src, skind);
4863 else
4865 slen = build_int_cst (size_type_node, 1);
4866 ssc = src;
4869 if (dlength != NULL_TREE)
4871 dlen = fold_convert (size_type_node, gfc_evaluate_now (dlength, block));
4872 dsc = gfc_string_to_single_character (dlen, dest, dkind);
4874 else
4876 dlen = build_int_cst (size_type_node, 1);
4877 dsc = dest;
4880 /* Assign directly if the types are compatible. */
4881 if (dsc != NULL_TREE && ssc != NULL_TREE
4882 && TREE_TYPE (dsc) == TREE_TYPE (ssc))
4884 gfc_add_modify (block, dsc, ssc);
4885 return;
4888 /* Do nothing if the destination length is zero. */
4889 cond = fold_build2_loc (input_location, GT_EXPR, boolean_type_node, dlen,
4890 build_int_cst (size_type_node, 0));
4892 /* The following code was previously in _gfortran_copy_string:
4894 // The two strings may overlap so we use memmove.
4895 void
4896 copy_string (GFC_INTEGER_4 destlen, char * dest,
4897 GFC_INTEGER_4 srclen, const char * src)
4899 if (srclen >= destlen)
4901 // This will truncate if too long.
4902 memmove (dest, src, destlen);
4904 else
4906 memmove (dest, src, srclen);
4907 // Pad with spaces.
4908 memset (&dest[srclen], ' ', destlen - srclen);
4912 We're now doing it here for better optimization, but the logic
4913 is the same. */
4915 /* For non-default character kinds, we have to multiply the string
4916 length by the base type size. */
4917 chartype = gfc_get_char_type (dkind);
4918 slen = fold_build2_loc (input_location, MULT_EXPR, size_type_node,
4919 fold_convert (size_type_node, slen),
4920 fold_convert (size_type_node,
4921 TYPE_SIZE_UNIT (chartype)));
4922 dlen = fold_build2_loc (input_location, MULT_EXPR, size_type_node,
4923 fold_convert (size_type_node, dlen),
4924 fold_convert (size_type_node,
4925 TYPE_SIZE_UNIT (chartype)));
4927 if (dlength && POINTER_TYPE_P (TREE_TYPE (dest)))
4928 dest = fold_convert (pvoid_type_node, dest);
4929 else
4930 dest = gfc_build_addr_expr (pvoid_type_node, dest);
4932 if (slength && POINTER_TYPE_P (TREE_TYPE (src)))
4933 src = fold_convert (pvoid_type_node, src);
4934 else
4935 src = gfc_build_addr_expr (pvoid_type_node, src);
4937 /* Truncate string if source is too long. */
4938 cond2 = fold_build2_loc (input_location, GE_EXPR, boolean_type_node, slen,
4939 dlen);
4940 tmp2 = build_call_expr_loc (input_location,
4941 builtin_decl_explicit (BUILT_IN_MEMMOVE),
4942 3, dest, src, dlen);
4944 /* Else copy and pad with spaces. */
4945 tmp3 = build_call_expr_loc (input_location,
4946 builtin_decl_explicit (BUILT_IN_MEMMOVE),
4947 3, dest, src, slen);
4949 tmp4 = fold_build_pointer_plus_loc (input_location, dest, slen);
4950 tmp4 = fill_with_spaces (tmp4, chartype,
4951 fold_build2_loc (input_location, MINUS_EXPR,
4952 TREE_TYPE(dlen), dlen, slen));
4954 gfc_init_block (&tempblock);
4955 gfc_add_expr_to_block (&tempblock, tmp3);
4956 gfc_add_expr_to_block (&tempblock, tmp4);
4957 tmp3 = gfc_finish_block (&tempblock);
4959 /* The whole copy_string function is there. */
4960 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond2,
4961 tmp2, tmp3);
4962 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond, tmp,
4963 build_empty_stmt (input_location));
4964 gfc_add_expr_to_block (block, tmp);
4968 /* Translate a statement function.
4969 The value of a statement function reference is obtained by evaluating the
4970 expression using the values of the actual arguments for the values of the
4971 corresponding dummy arguments. */
4973 static void
4974 gfc_conv_statement_function (gfc_se * se, gfc_expr * expr)
4976 gfc_symbol *sym;
4977 gfc_symbol *fsym;
4978 gfc_formal_arglist *fargs;
4979 gfc_actual_arglist *args;
4980 gfc_se lse;
4981 gfc_se rse;
4982 gfc_saved_var *saved_vars;
4983 tree *temp_vars;
4984 tree type;
4985 tree tmp;
4986 int n;
4988 sym = expr->symtree->n.sym;
4989 args = expr->value.function.actual;
4990 gfc_init_se (&lse, NULL);
4991 gfc_init_se (&rse, NULL);
4993 n = 0;
4994 for (fargs = sym->formal; fargs; fargs = fargs->next)
4995 n++;
4996 saved_vars = XCNEWVEC (gfc_saved_var, n);
4997 temp_vars = XCNEWVEC (tree, n);
4999 for (fargs = sym->formal, n = 0; fargs; fargs = fargs->next, n++)
5001 /* Each dummy shall be specified, explicitly or implicitly, to be
5002 scalar. */
5003 gcc_assert (fargs->sym->attr.dimension == 0);
5004 fsym = fargs->sym;
5006 if (fsym->ts.type == BT_CHARACTER)
5008 /* Copy string arguments. */
5009 tree arglen;
5011 gcc_assert (fsym->ts.u.cl && fsym->ts.u.cl->length
5012 && fsym->ts.u.cl->length->expr_type == EXPR_CONSTANT);
5014 /* Create a temporary to hold the value. */
5015 if (fsym->ts.u.cl->backend_decl == NULL_TREE)
5016 fsym->ts.u.cl->backend_decl
5017 = gfc_conv_constant_to_tree (fsym->ts.u.cl->length);
5019 type = gfc_get_character_type (fsym->ts.kind, fsym->ts.u.cl);
5020 temp_vars[n] = gfc_create_var (type, fsym->name);
5022 arglen = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
5024 gfc_conv_expr (&rse, args->expr);
5025 gfc_conv_string_parameter (&rse);
5026 gfc_add_block_to_block (&se->pre, &lse.pre);
5027 gfc_add_block_to_block (&se->pre, &rse.pre);
5029 gfc_trans_string_copy (&se->pre, arglen, temp_vars[n], fsym->ts.kind,
5030 rse.string_length, rse.expr, fsym->ts.kind);
5031 gfc_add_block_to_block (&se->pre, &lse.post);
5032 gfc_add_block_to_block (&se->pre, &rse.post);
5034 else
5036 /* For everything else, just evaluate the expression. */
5038 /* Create a temporary to hold the value. */
5039 type = gfc_typenode_for_spec (&fsym->ts);
5040 temp_vars[n] = gfc_create_var (type, fsym->name);
5042 gfc_conv_expr (&lse, args->expr);
5044 gfc_add_block_to_block (&se->pre, &lse.pre);
5045 gfc_add_modify (&se->pre, temp_vars[n], lse.expr);
5046 gfc_add_block_to_block (&se->pre, &lse.post);
5049 args = args->next;
5052 /* Use the temporary variables in place of the real ones. */
5053 for (fargs = sym->formal, n = 0; fargs; fargs = fargs->next, n++)
5054 gfc_shadow_sym (fargs->sym, temp_vars[n], &saved_vars[n]);
5056 gfc_conv_expr (se, sym->value);
5058 if (sym->ts.type == BT_CHARACTER)
5060 gfc_conv_const_charlen (sym->ts.u.cl);
5062 /* Force the expression to the correct length. */
5063 if (!INTEGER_CST_P (se->string_length)
5064 || tree_int_cst_lt (se->string_length,
5065 sym->ts.u.cl->backend_decl))
5067 type = gfc_get_character_type (sym->ts.kind, sym->ts.u.cl);
5068 tmp = gfc_create_var (type, sym->name);
5069 tmp = gfc_build_addr_expr (build_pointer_type (type), tmp);
5070 gfc_trans_string_copy (&se->pre, sym->ts.u.cl->backend_decl, tmp,
5071 sym->ts.kind, se->string_length, se->expr,
5072 sym->ts.kind);
5073 se->expr = tmp;
5075 se->string_length = sym->ts.u.cl->backend_decl;
5078 /* Restore the original variables. */
5079 for (fargs = sym->formal, n = 0; fargs; fargs = fargs->next, n++)
5080 gfc_restore_sym (fargs->sym, &saved_vars[n]);
5081 free (saved_vars);
5085 /* Translate a function expression. */
5087 static void
5088 gfc_conv_function_expr (gfc_se * se, gfc_expr * expr)
5090 gfc_symbol *sym;
5092 if (expr->value.function.isym)
5094 gfc_conv_intrinsic_function (se, expr);
5095 return;
5098 /* We distinguish statement functions from general functions to improve
5099 runtime performance. */
5100 if (expr->symtree->n.sym->attr.proc == PROC_ST_FUNCTION)
5102 gfc_conv_statement_function (se, expr);
5103 return;
5106 /* expr.value.function.esym is the resolved (specific) function symbol for
5107 most functions. However this isn't set for dummy procedures. */
5108 sym = expr->value.function.esym;
5109 if (!sym)
5110 sym = expr->symtree->n.sym;
5112 gfc_conv_procedure_call (se, sym, expr->value.function.actual, expr, NULL);
5116 /* Determine whether the given EXPR_CONSTANT is a zero initializer. */
5118 static bool
5119 is_zero_initializer_p (gfc_expr * expr)
5121 if (expr->expr_type != EXPR_CONSTANT)
5122 return false;
5124 /* We ignore constants with prescribed memory representations for now. */
5125 if (expr->representation.string)
5126 return false;
5128 switch (expr->ts.type)
5130 case BT_INTEGER:
5131 return mpz_cmp_si (expr->value.integer, 0) == 0;
5133 case BT_REAL:
5134 return mpfr_zero_p (expr->value.real)
5135 && MPFR_SIGN (expr->value.real) >= 0;
5137 case BT_LOGICAL:
5138 return expr->value.logical == 0;
5140 case BT_COMPLEX:
5141 return mpfr_zero_p (mpc_realref (expr->value.complex))
5142 && MPFR_SIGN (mpc_realref (expr->value.complex)) >= 0
5143 && mpfr_zero_p (mpc_imagref (expr->value.complex))
5144 && MPFR_SIGN (mpc_imagref (expr->value.complex)) >= 0;
5146 default:
5147 break;
5149 return false;
5153 static void
5154 gfc_conv_array_constructor_expr (gfc_se * se, gfc_expr * expr)
5156 gfc_ss *ss;
5158 ss = se->ss;
5159 gcc_assert (ss != NULL && ss != gfc_ss_terminator);
5160 gcc_assert (ss->info->expr == expr && ss->info->type == GFC_SS_CONSTRUCTOR);
5162 gfc_conv_tmp_array_ref (se);
5166 /* Build a static initializer. EXPR is the expression for the initial value.
5167 The other parameters describe the variable of the component being
5168 initialized. EXPR may be null. */
5170 tree
5171 gfc_conv_initializer (gfc_expr * expr, gfc_typespec * ts, tree type,
5172 bool array, bool pointer, bool procptr)
5174 gfc_se se;
5176 if (!(expr || pointer || procptr))
5177 return NULL_TREE;
5179 /* Check if we have ISOCBINDING_NULL_PTR or ISOCBINDING_NULL_FUNPTR
5180 (these are the only two iso_c_binding derived types that can be
5181 used as initialization expressions). If so, we need to modify
5182 the 'expr' to be that for a (void *). */
5183 if (expr != NULL && expr->ts.type == BT_DERIVED
5184 && expr->ts.is_iso_c && expr->ts.u.derived)
5186 gfc_symbol *derived = expr->ts.u.derived;
5188 /* The derived symbol has already been converted to a (void *). Use
5189 its kind. */
5190 expr = gfc_get_int_expr (derived->ts.kind, NULL, 0);
5191 expr->ts.f90_type = derived->ts.f90_type;
5193 gfc_init_se (&se, NULL);
5194 gfc_conv_constant (&se, expr);
5195 gcc_assert (TREE_CODE (se.expr) != CONSTRUCTOR);
5196 return se.expr;
5199 if (array && !procptr)
5201 tree ctor;
5202 /* Arrays need special handling. */
5203 if (pointer)
5204 ctor = gfc_build_null_descriptor (type);
5205 /* Special case assigning an array to zero. */
5206 else if (is_zero_initializer_p (expr))
5207 ctor = build_constructor (type, NULL);
5208 else
5209 ctor = gfc_conv_array_initializer (type, expr);
5210 TREE_STATIC (ctor) = 1;
5211 return ctor;
5213 else if (pointer || procptr)
5215 if (!expr || expr->expr_type == EXPR_NULL)
5216 return fold_convert (type, null_pointer_node);
5217 else
5219 gfc_init_se (&se, NULL);
5220 se.want_pointer = 1;
5221 gfc_conv_expr (&se, expr);
5222 gcc_assert (TREE_CODE (se.expr) != CONSTRUCTOR);
5223 return se.expr;
5226 else
5228 switch (ts->type)
5230 case BT_DERIVED:
5231 case BT_CLASS:
5232 gfc_init_se (&se, NULL);
5233 if (ts->type == BT_CLASS && expr->expr_type == EXPR_NULL)
5234 gfc_conv_structure (&se, gfc_class_null_initializer(ts), 1);
5235 else
5236 gfc_conv_structure (&se, expr, 1);
5237 gcc_assert (TREE_CODE (se.expr) == CONSTRUCTOR);
5238 TREE_STATIC (se.expr) = 1;
5239 return se.expr;
5241 case BT_CHARACTER:
5243 tree ctor = gfc_conv_string_init (ts->u.cl->backend_decl,expr);
5244 TREE_STATIC (ctor) = 1;
5245 return ctor;
5248 default:
5249 gfc_init_se (&se, NULL);
5250 gfc_conv_constant (&se, expr);
5251 gcc_assert (TREE_CODE (se.expr) != CONSTRUCTOR);
5252 return se.expr;
5257 static tree
5258 gfc_trans_subarray_assign (tree dest, gfc_component * cm, gfc_expr * expr)
5260 gfc_se rse;
5261 gfc_se lse;
5262 gfc_ss *rss;
5263 gfc_ss *lss;
5264 gfc_array_info *lss_array;
5265 stmtblock_t body;
5266 stmtblock_t block;
5267 gfc_loopinfo loop;
5268 int n;
5269 tree tmp;
5271 gfc_start_block (&block);
5273 /* Initialize the scalarizer. */
5274 gfc_init_loopinfo (&loop);
5276 gfc_init_se (&lse, NULL);
5277 gfc_init_se (&rse, NULL);
5279 /* Walk the rhs. */
5280 rss = gfc_walk_expr (expr);
5281 if (rss == gfc_ss_terminator)
5282 /* The rhs is scalar. Add a ss for the expression. */
5283 rss = gfc_get_scalar_ss (gfc_ss_terminator, expr);
5285 /* Create a SS for the destination. */
5286 lss = gfc_get_array_ss (gfc_ss_terminator, NULL, cm->as->rank,
5287 GFC_SS_COMPONENT);
5288 lss_array = &lss->info->data.array;
5289 lss_array->shape = gfc_get_shape (cm->as->rank);
5290 lss_array->descriptor = dest;
5291 lss_array->data = gfc_conv_array_data (dest);
5292 lss_array->offset = gfc_conv_array_offset (dest);
5293 for (n = 0; n < cm->as->rank; n++)
5295 lss_array->start[n] = gfc_conv_array_lbound (dest, n);
5296 lss_array->stride[n] = gfc_index_one_node;
5298 mpz_init (lss_array->shape[n]);
5299 mpz_sub (lss_array->shape[n], cm->as->upper[n]->value.integer,
5300 cm->as->lower[n]->value.integer);
5301 mpz_add_ui (lss_array->shape[n], lss_array->shape[n], 1);
5304 /* Associate the SS with the loop. */
5305 gfc_add_ss_to_loop (&loop, lss);
5306 gfc_add_ss_to_loop (&loop, rss);
5308 /* Calculate the bounds of the scalarization. */
5309 gfc_conv_ss_startstride (&loop);
5311 /* Setup the scalarizing loops. */
5312 gfc_conv_loop_setup (&loop, &expr->where);
5314 /* Setup the gfc_se structures. */
5315 gfc_copy_loopinfo_to_se (&lse, &loop);
5316 gfc_copy_loopinfo_to_se (&rse, &loop);
5318 rse.ss = rss;
5319 gfc_mark_ss_chain_used (rss, 1);
5320 lse.ss = lss;
5321 gfc_mark_ss_chain_used (lss, 1);
5323 /* Start the scalarized loop body. */
5324 gfc_start_scalarized_body (&loop, &body);
5326 gfc_conv_tmp_array_ref (&lse);
5327 if (cm->ts.type == BT_CHARACTER)
5328 lse.string_length = cm->ts.u.cl->backend_decl;
5330 gfc_conv_expr (&rse, expr);
5332 tmp = gfc_trans_scalar_assign (&lse, &rse, cm->ts, true, false, true);
5333 gfc_add_expr_to_block (&body, tmp);
5335 gcc_assert (rse.ss == gfc_ss_terminator);
5337 /* Generate the copying loops. */
5338 gfc_trans_scalarizing_loops (&loop, &body);
5340 /* Wrap the whole thing up. */
5341 gfc_add_block_to_block (&block, &loop.pre);
5342 gfc_add_block_to_block (&block, &loop.post);
5344 gcc_assert (lss_array->shape != NULL);
5345 gfc_free_shape (&lss_array->shape, cm->as->rank);
5346 gfc_cleanup_loop (&loop);
5348 return gfc_finish_block (&block);
5352 static tree
5353 gfc_trans_alloc_subarray_assign (tree dest, gfc_component * cm,
5354 gfc_expr * expr)
5356 gfc_se se;
5357 gfc_ss *rss;
5358 stmtblock_t block;
5359 tree offset;
5360 int n;
5361 tree tmp;
5362 tree tmp2;
5363 gfc_array_spec *as;
5364 gfc_expr *arg = NULL;
5366 gfc_start_block (&block);
5367 gfc_init_se (&se, NULL);
5369 /* Get the descriptor for the expressions. */
5370 rss = gfc_walk_expr (expr);
5371 se.want_pointer = 0;
5372 gfc_conv_expr_descriptor (&se, expr, rss);
5373 gfc_add_block_to_block (&block, &se.pre);
5374 gfc_add_modify (&block, dest, se.expr);
5376 /* Deal with arrays of derived types with allocatable components. */
5377 if (cm->ts.type == BT_DERIVED
5378 && cm->ts.u.derived->attr.alloc_comp)
5379 tmp = gfc_copy_alloc_comp (cm->ts.u.derived,
5380 se.expr, dest,
5381 cm->as->rank);
5382 else
5383 tmp = gfc_duplicate_allocatable (dest, se.expr,
5384 TREE_TYPE(cm->backend_decl),
5385 cm->as->rank);
5387 gfc_add_expr_to_block (&block, tmp);
5388 gfc_add_block_to_block (&block, &se.post);
5390 if (expr->expr_type != EXPR_VARIABLE)
5391 gfc_conv_descriptor_data_set (&block, se.expr,
5392 null_pointer_node);
5394 /* We need to know if the argument of a conversion function is a
5395 variable, so that the correct lower bound can be used. */
5396 if (expr->expr_type == EXPR_FUNCTION
5397 && expr->value.function.isym
5398 && expr->value.function.isym->conversion
5399 && expr->value.function.actual->expr
5400 && expr->value.function.actual->expr->expr_type == EXPR_VARIABLE)
5401 arg = expr->value.function.actual->expr;
5403 /* Obtain the array spec of full array references. */
5404 if (arg)
5405 as = gfc_get_full_arrayspec_from_expr (arg);
5406 else
5407 as = gfc_get_full_arrayspec_from_expr (expr);
5409 /* Shift the lbound and ubound of temporaries to being unity,
5410 rather than zero, based. Always calculate the offset. */
5411 offset = gfc_conv_descriptor_offset_get (dest);
5412 gfc_add_modify (&block, offset, gfc_index_zero_node);
5413 tmp2 =gfc_create_var (gfc_array_index_type, NULL);
5415 for (n = 0; n < expr->rank; n++)
5417 tree span;
5418 tree lbound;
5420 /* Obtain the correct lbound - ISO/IEC TR 15581:2001 page 9.
5421 TODO It looks as if gfc_conv_expr_descriptor should return
5422 the correct bounds and that the following should not be
5423 necessary. This would simplify gfc_conv_intrinsic_bound
5424 as well. */
5425 if (as && as->lower[n])
5427 gfc_se lbse;
5428 gfc_init_se (&lbse, NULL);
5429 gfc_conv_expr (&lbse, as->lower[n]);
5430 gfc_add_block_to_block (&block, &lbse.pre);
5431 lbound = gfc_evaluate_now (lbse.expr, &block);
5433 else if (as && arg)
5435 tmp = gfc_get_symbol_decl (arg->symtree->n.sym);
5436 lbound = gfc_conv_descriptor_lbound_get (tmp,
5437 gfc_rank_cst[n]);
5439 else if (as)
5440 lbound = gfc_conv_descriptor_lbound_get (dest,
5441 gfc_rank_cst[n]);
5442 else
5443 lbound = gfc_index_one_node;
5445 lbound = fold_convert (gfc_array_index_type, lbound);
5447 /* Shift the bounds and set the offset accordingly. */
5448 tmp = gfc_conv_descriptor_ubound_get (dest, gfc_rank_cst[n]);
5449 span = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
5450 tmp, gfc_conv_descriptor_lbound_get (dest, gfc_rank_cst[n]));
5451 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
5452 span, lbound);
5453 gfc_conv_descriptor_ubound_set (&block, dest,
5454 gfc_rank_cst[n], tmp);
5455 gfc_conv_descriptor_lbound_set (&block, dest,
5456 gfc_rank_cst[n], lbound);
5458 tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
5459 gfc_conv_descriptor_lbound_get (dest,
5460 gfc_rank_cst[n]),
5461 gfc_conv_descriptor_stride_get (dest,
5462 gfc_rank_cst[n]));
5463 gfc_add_modify (&block, tmp2, tmp);
5464 tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
5465 offset, tmp2);
5466 gfc_conv_descriptor_offset_set (&block, dest, tmp);
5469 if (arg)
5471 /* If a conversion expression has a null data pointer
5472 argument, nullify the allocatable component. */
5473 tree non_null_expr;
5474 tree null_expr;
5476 if (arg->symtree->n.sym->attr.allocatable
5477 || arg->symtree->n.sym->attr.pointer)
5479 non_null_expr = gfc_finish_block (&block);
5480 gfc_start_block (&block);
5481 gfc_conv_descriptor_data_set (&block, dest,
5482 null_pointer_node);
5483 null_expr = gfc_finish_block (&block);
5484 tmp = gfc_conv_descriptor_data_get (arg->symtree->n.sym->backend_decl);
5485 tmp = build2_loc (input_location, EQ_EXPR, boolean_type_node, tmp,
5486 fold_convert (TREE_TYPE (tmp), null_pointer_node));
5487 return build3_v (COND_EXPR, tmp,
5488 null_expr, non_null_expr);
5492 return gfc_finish_block (&block);
5496 /* Assign a single component of a derived type constructor. */
5498 static tree
5499 gfc_trans_subcomponent_assign (tree dest, gfc_component * cm, gfc_expr * expr)
5501 gfc_se se;
5502 gfc_se lse;
5503 gfc_ss *rss;
5504 stmtblock_t block;
5505 tree tmp;
5507 gfc_start_block (&block);
5509 if (cm->attr.pointer)
5511 gfc_init_se (&se, NULL);
5512 /* Pointer component. */
5513 if (cm->attr.dimension)
5515 /* Array pointer. */
5516 if (expr->expr_type == EXPR_NULL)
5517 gfc_conv_descriptor_data_set (&block, dest, null_pointer_node);
5518 else
5520 rss = gfc_walk_expr (expr);
5521 se.direct_byref = 1;
5522 se.expr = dest;
5523 gfc_conv_expr_descriptor (&se, expr, rss);
5524 gfc_add_block_to_block (&block, &se.pre);
5525 gfc_add_block_to_block (&block, &se.post);
5528 else
5530 /* Scalar pointers. */
5531 se.want_pointer = 1;
5532 gfc_conv_expr (&se, expr);
5533 gfc_add_block_to_block (&block, &se.pre);
5534 gfc_add_modify (&block, dest,
5535 fold_convert (TREE_TYPE (dest), se.expr));
5536 gfc_add_block_to_block (&block, &se.post);
5539 else if (cm->ts.type == BT_CLASS && expr->expr_type == EXPR_NULL)
5541 /* NULL initialization for CLASS components. */
5542 tmp = gfc_trans_structure_assign (dest,
5543 gfc_class_null_initializer (&cm->ts));
5544 gfc_add_expr_to_block (&block, tmp);
5546 else if (cm->attr.dimension && !cm->attr.proc_pointer)
5548 if (cm->attr.allocatable && expr->expr_type == EXPR_NULL)
5549 gfc_conv_descriptor_data_set (&block, dest, null_pointer_node);
5550 else if (cm->attr.allocatable)
5552 tmp = gfc_trans_alloc_subarray_assign (dest, cm, expr);
5553 gfc_add_expr_to_block (&block, tmp);
5555 else
5557 tmp = gfc_trans_subarray_assign (dest, cm, expr);
5558 gfc_add_expr_to_block (&block, tmp);
5561 else if (expr->ts.type == BT_DERIVED)
5563 if (expr->expr_type != EXPR_STRUCTURE)
5565 gfc_init_se (&se, NULL);
5566 gfc_conv_expr (&se, expr);
5567 gfc_add_block_to_block (&block, &se.pre);
5568 gfc_add_modify (&block, dest,
5569 fold_convert (TREE_TYPE (dest), se.expr));
5570 gfc_add_block_to_block (&block, &se.post);
5572 else
5574 /* Nested constructors. */
5575 tmp = gfc_trans_structure_assign (dest, expr);
5576 gfc_add_expr_to_block (&block, tmp);
5579 else
5581 /* Scalar component. */
5582 gfc_init_se (&se, NULL);
5583 gfc_init_se (&lse, NULL);
5585 gfc_conv_expr (&se, expr);
5586 if (cm->ts.type == BT_CHARACTER)
5587 lse.string_length = cm->ts.u.cl->backend_decl;
5588 lse.expr = dest;
5589 tmp = gfc_trans_scalar_assign (&lse, &se, cm->ts, true, false, true);
5590 gfc_add_expr_to_block (&block, tmp);
5592 return gfc_finish_block (&block);
5595 /* Assign a derived type constructor to a variable. */
5597 static tree
5598 gfc_trans_structure_assign (tree dest, gfc_expr * expr)
5600 gfc_constructor *c;
5601 gfc_component *cm;
5602 stmtblock_t block;
5603 tree field;
5604 tree tmp;
5606 gfc_start_block (&block);
5607 cm = expr->ts.u.derived->components;
5609 if (expr->ts.u.derived->from_intmod == INTMOD_ISO_C_BINDING
5610 && (expr->ts.u.derived->intmod_sym_id == ISOCBINDING_PTR
5611 || expr->ts.u.derived->intmod_sym_id == ISOCBINDING_FUNPTR))
5613 gfc_se se, lse;
5615 gcc_assert (cm->backend_decl == NULL);
5616 gfc_init_se (&se, NULL);
5617 gfc_init_se (&lse, NULL);
5618 gfc_conv_expr (&se, gfc_constructor_first (expr->value.constructor)->expr);
5619 lse.expr = dest;
5620 gfc_add_modify (&block, lse.expr,
5621 fold_convert (TREE_TYPE (lse.expr), se.expr));
5623 return gfc_finish_block (&block);
5626 for (c = gfc_constructor_first (expr->value.constructor);
5627 c; c = gfc_constructor_next (c), cm = cm->next)
5629 /* Skip absent members in default initializers. */
5630 if (!c->expr)
5631 continue;
5633 field = cm->backend_decl;
5634 tmp = fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field),
5635 dest, field, NULL_TREE);
5636 tmp = gfc_trans_subcomponent_assign (tmp, cm, c->expr);
5637 gfc_add_expr_to_block (&block, tmp);
5639 return gfc_finish_block (&block);
5642 /* Build an expression for a constructor. If init is nonzero then
5643 this is part of a static variable initializer. */
5645 void
5646 gfc_conv_structure (gfc_se * se, gfc_expr * expr, int init)
5648 gfc_constructor *c;
5649 gfc_component *cm;
5650 tree val;
5651 tree type;
5652 tree tmp;
5653 VEC(constructor_elt,gc) *v = NULL;
5655 gcc_assert (se->ss == NULL);
5656 gcc_assert (expr->expr_type == EXPR_STRUCTURE);
5657 type = gfc_typenode_for_spec (&expr->ts);
5659 if (!init)
5661 /* Create a temporary variable and fill it in. */
5662 se->expr = gfc_create_var (type, expr->ts.u.derived->name);
5663 tmp = gfc_trans_structure_assign (se->expr, expr);
5664 gfc_add_expr_to_block (&se->pre, tmp);
5665 return;
5668 cm = expr->ts.u.derived->components;
5670 for (c = gfc_constructor_first (expr->value.constructor);
5671 c; c = gfc_constructor_next (c), cm = cm->next)
5673 /* Skip absent members in default initializers and allocatable
5674 components. Although the latter have a default initializer
5675 of EXPR_NULL,... by default, the static nullify is not needed
5676 since this is done every time we come into scope. */
5677 if (!c->expr || (cm->attr.allocatable && cm->attr.flavor != FL_PROCEDURE))
5678 continue;
5680 if (strcmp (cm->name, "_size") == 0)
5682 val = TYPE_SIZE_UNIT (gfc_get_derived_type (cm->ts.u.derived));
5683 CONSTRUCTOR_APPEND_ELT (v, cm->backend_decl, val);
5685 else if (cm->initializer && cm->initializer->expr_type != EXPR_NULL
5686 && strcmp (cm->name, "_extends") == 0)
5688 tree vtab;
5689 gfc_symbol *vtabs;
5690 vtabs = cm->initializer->symtree->n.sym;
5691 vtab = gfc_build_addr_expr (NULL_TREE, gfc_get_symbol_decl (vtabs));
5692 CONSTRUCTOR_APPEND_ELT (v, cm->backend_decl, vtab);
5694 else
5696 val = gfc_conv_initializer (c->expr, &cm->ts,
5697 TREE_TYPE (cm->backend_decl),
5698 cm->attr.dimension, cm->attr.pointer,
5699 cm->attr.proc_pointer);
5701 /* Append it to the constructor list. */
5702 CONSTRUCTOR_APPEND_ELT (v, cm->backend_decl, val);
5705 se->expr = build_constructor (type, v);
5706 if (init)
5707 TREE_CONSTANT (se->expr) = 1;
5711 /* Translate a substring expression. */
5713 static void
5714 gfc_conv_substring_expr (gfc_se * se, gfc_expr * expr)
5716 gfc_ref *ref;
5718 ref = expr->ref;
5720 gcc_assert (ref == NULL || ref->type == REF_SUBSTRING);
5722 se->expr = gfc_build_wide_string_const (expr->ts.kind,
5723 expr->value.character.length,
5724 expr->value.character.string);
5726 se->string_length = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (se->expr)));
5727 TYPE_STRING_FLAG (TREE_TYPE (se->expr)) = 1;
5729 if (ref)
5730 gfc_conv_substring (se, ref, expr->ts.kind, NULL, &expr->where);
5734 /* Entry point for expression translation. Evaluates a scalar quantity.
5735 EXPR is the expression to be translated, and SE is the state structure if
5736 called from within the scalarized. */
5738 void
5739 gfc_conv_expr (gfc_se * se, gfc_expr * expr)
5741 gfc_ss *ss;
5743 ss = se->ss;
5744 if (ss && ss->info->expr == expr
5745 && (ss->info->type == GFC_SS_SCALAR
5746 || ss->info->type == GFC_SS_REFERENCE))
5748 gfc_ss_info *ss_info;
5750 ss_info = ss->info;
5751 /* Substitute a scalar expression evaluated outside the scalarization
5752 loop. */
5753 se->expr = ss_info->data.scalar.value;
5754 /* If the reference can be NULL, the value field contains the reference,
5755 not the value the reference points to (see gfc_add_loop_ss_code). */
5756 if (ss_info->can_be_null_ref)
5757 se->expr = build_fold_indirect_ref_loc (input_location, se->expr);
5759 se->string_length = ss_info->string_length;
5760 gfc_advance_se_ss_chain (se);
5761 return;
5764 /* We need to convert the expressions for the iso_c_binding derived types.
5765 C_NULL_PTR and C_NULL_FUNPTR will be made EXPR_NULL, which evaluates to
5766 null_pointer_node. C_PTR and C_FUNPTR are converted to match the
5767 typespec for the C_PTR and C_FUNPTR symbols, which has already been
5768 updated to be an integer with a kind equal to the size of a (void *). */
5769 if (expr->ts.type == BT_DERIVED && expr->ts.u.derived
5770 && expr->ts.u.derived->attr.is_iso_c)
5772 if (expr->expr_type == EXPR_VARIABLE
5773 && (expr->symtree->n.sym->intmod_sym_id == ISOCBINDING_NULL_PTR
5774 || expr->symtree->n.sym->intmod_sym_id
5775 == ISOCBINDING_NULL_FUNPTR))
5777 /* Set expr_type to EXPR_NULL, which will result in
5778 null_pointer_node being used below. */
5779 expr->expr_type = EXPR_NULL;
5781 else
5783 /* Update the type/kind of the expression to be what the new
5784 type/kind are for the updated symbols of C_PTR/C_FUNPTR. */
5785 expr->ts.type = expr->ts.u.derived->ts.type;
5786 expr->ts.f90_type = expr->ts.u.derived->ts.f90_type;
5787 expr->ts.kind = expr->ts.u.derived->ts.kind;
5791 gfc_fix_class_refs (expr);
5793 switch (expr->expr_type)
5795 case EXPR_OP:
5796 gfc_conv_expr_op (se, expr);
5797 break;
5799 case EXPR_FUNCTION:
5800 gfc_conv_function_expr (se, expr);
5801 break;
5803 case EXPR_CONSTANT:
5804 gfc_conv_constant (se, expr);
5805 break;
5807 case EXPR_VARIABLE:
5808 gfc_conv_variable (se, expr);
5809 break;
5811 case EXPR_NULL:
5812 se->expr = null_pointer_node;
5813 break;
5815 case EXPR_SUBSTRING:
5816 gfc_conv_substring_expr (se, expr);
5817 break;
5819 case EXPR_STRUCTURE:
5820 gfc_conv_structure (se, expr, 0);
5821 break;
5823 case EXPR_ARRAY:
5824 gfc_conv_array_constructor_expr (se, expr);
5825 break;
5827 default:
5828 gcc_unreachable ();
5829 break;
5833 /* Like gfc_conv_expr_val, but the value is also suitable for use in the lhs
5834 of an assignment. */
5835 void
5836 gfc_conv_expr_lhs (gfc_se * se, gfc_expr * expr)
5838 gfc_conv_expr (se, expr);
5839 /* All numeric lvalues should have empty post chains. If not we need to
5840 figure out a way of rewriting an lvalue so that it has no post chain. */
5841 gcc_assert (expr->ts.type == BT_CHARACTER || !se->post.head);
5844 /* Like gfc_conv_expr, but the POST block is guaranteed to be empty for
5845 numeric expressions. Used for scalar values where inserting cleanup code
5846 is inconvenient. */
5847 void
5848 gfc_conv_expr_val (gfc_se * se, gfc_expr * expr)
5850 tree val;
5852 gcc_assert (expr->ts.type != BT_CHARACTER);
5853 gfc_conv_expr (se, expr);
5854 if (se->post.head)
5856 val = gfc_create_var (TREE_TYPE (se->expr), NULL);
5857 gfc_add_modify (&se->pre, val, se->expr);
5858 se->expr = val;
5859 gfc_add_block_to_block (&se->pre, &se->post);
5863 /* Helper to translate an expression and convert it to a particular type. */
5864 void
5865 gfc_conv_expr_type (gfc_se * se, gfc_expr * expr, tree type)
5867 gfc_conv_expr_val (se, expr);
5868 se->expr = convert (type, se->expr);
5872 /* Converts an expression so that it can be passed by reference. Scalar
5873 values only. */
5875 void
5876 gfc_conv_expr_reference (gfc_se * se, gfc_expr * expr)
5878 gfc_ss *ss;
5879 tree var;
5881 ss = se->ss;
5882 if (ss && ss->info->expr == expr
5883 && ss->info->type == GFC_SS_REFERENCE)
5885 /* Returns a reference to the scalar evaluated outside the loop
5886 for this case. */
5887 gfc_conv_expr (se, expr);
5888 se->expr = gfc_build_addr_expr (NULL_TREE, se->expr);
5889 return;
5892 if (expr->ts.type == BT_CHARACTER)
5894 gfc_conv_expr (se, expr);
5895 gfc_conv_string_parameter (se);
5896 return;
5899 if (expr->expr_type == EXPR_VARIABLE)
5901 se->want_pointer = 1;
5902 gfc_conv_expr (se, expr);
5903 if (se->post.head)
5905 var = gfc_create_var (TREE_TYPE (se->expr), NULL);
5906 gfc_add_modify (&se->pre, var, se->expr);
5907 gfc_add_block_to_block (&se->pre, &se->post);
5908 se->expr = var;
5910 return;
5913 if (expr->expr_type == EXPR_FUNCTION
5914 && ((expr->value.function.esym
5915 && expr->value.function.esym->result->attr.pointer
5916 && !expr->value.function.esym->result->attr.dimension)
5917 || (!expr->value.function.esym && !expr->ref
5918 && expr->symtree->n.sym->attr.pointer
5919 && !expr->symtree->n.sym->attr.dimension)))
5921 se->want_pointer = 1;
5922 gfc_conv_expr (se, expr);
5923 var = gfc_create_var (TREE_TYPE (se->expr), NULL);
5924 gfc_add_modify (&se->pre, var, se->expr);
5925 se->expr = var;
5926 return;
5929 gfc_conv_expr (se, expr);
5931 /* Create a temporary var to hold the value. */
5932 if (TREE_CONSTANT (se->expr))
5934 tree tmp = se->expr;
5935 STRIP_TYPE_NOPS (tmp);
5936 var = build_decl (input_location,
5937 CONST_DECL, NULL, TREE_TYPE (tmp));
5938 DECL_INITIAL (var) = tmp;
5939 TREE_STATIC (var) = 1;
5940 pushdecl (var);
5942 else
5944 var = gfc_create_var (TREE_TYPE (se->expr), NULL);
5945 gfc_add_modify (&se->pre, var, se->expr);
5947 gfc_add_block_to_block (&se->pre, &se->post);
5949 /* Take the address of that value. */
5950 se->expr = gfc_build_addr_expr (NULL_TREE, var);
5954 tree
5955 gfc_trans_pointer_assign (gfc_code * code)
5957 return gfc_trans_pointer_assignment (code->expr1, code->expr2);
5961 /* Generate code for a pointer assignment. */
5963 tree
5964 gfc_trans_pointer_assignment (gfc_expr * expr1, gfc_expr * expr2)
5966 gfc_se lse;
5967 gfc_se rse;
5968 gfc_ss *lss;
5969 gfc_ss *rss;
5970 stmtblock_t block;
5971 tree desc;
5972 tree tmp;
5973 tree decl;
5975 gfc_start_block (&block);
5977 gfc_init_se (&lse, NULL);
5979 lss = gfc_walk_expr (expr1);
5980 rss = gfc_walk_expr (expr2);
5981 if (lss == gfc_ss_terminator)
5983 /* Scalar pointers. */
5984 lse.want_pointer = 1;
5985 gfc_conv_expr (&lse, expr1);
5986 gcc_assert (rss == gfc_ss_terminator);
5987 gfc_init_se (&rse, NULL);
5988 rse.want_pointer = 1;
5989 gfc_conv_expr (&rse, expr2);
5991 if (expr1->symtree->n.sym->attr.proc_pointer
5992 && expr1->symtree->n.sym->attr.dummy)
5993 lse.expr = build_fold_indirect_ref_loc (input_location,
5994 lse.expr);
5996 if (expr2->symtree && expr2->symtree->n.sym->attr.proc_pointer
5997 && expr2->symtree->n.sym->attr.dummy)
5998 rse.expr = build_fold_indirect_ref_loc (input_location,
5999 rse.expr);
6001 gfc_add_block_to_block (&block, &lse.pre);
6002 gfc_add_block_to_block (&block, &rse.pre);
6004 /* Check character lengths if character expression. The test is only
6005 really added if -fbounds-check is enabled. Exclude deferred
6006 character length lefthand sides. */
6007 if (expr1->ts.type == BT_CHARACTER && expr2->expr_type != EXPR_NULL
6008 && !expr1->ts.deferred
6009 && !expr1->symtree->n.sym->attr.proc_pointer
6010 && !gfc_is_proc_ptr_comp (expr1))
6012 gcc_assert (expr2->ts.type == BT_CHARACTER);
6013 gcc_assert (lse.string_length && rse.string_length);
6014 gfc_trans_same_strlen_check ("pointer assignment", &expr1->where,
6015 lse.string_length, rse.string_length,
6016 &block);
6019 /* The assignment to an deferred character length sets the string
6020 length to that of the rhs. */
6021 if (expr1->ts.deferred)
6023 if (expr2->expr_type != EXPR_NULL && lse.string_length != NULL)
6024 gfc_add_modify (&block, lse.string_length, rse.string_length);
6025 else if (lse.string_length != NULL)
6026 gfc_add_modify (&block, lse.string_length,
6027 build_int_cst (gfc_charlen_type_node, 0));
6030 gfc_add_modify (&block, lse.expr,
6031 fold_convert (TREE_TYPE (lse.expr), rse.expr));
6033 gfc_add_block_to_block (&block, &rse.post);
6034 gfc_add_block_to_block (&block, &lse.post);
6036 else
6038 gfc_ref* remap;
6039 bool rank_remap;
6040 tree strlen_lhs;
6041 tree strlen_rhs = NULL_TREE;
6043 /* Array pointer. Find the last reference on the LHS and if it is an
6044 array section ref, we're dealing with bounds remapping. In this case,
6045 set it to AR_FULL so that gfc_conv_expr_descriptor does
6046 not see it and process the bounds remapping afterwards explicitly. */
6047 for (remap = expr1->ref; remap; remap = remap->next)
6048 if (!remap->next && remap->type == REF_ARRAY
6049 && remap->u.ar.type == AR_SECTION)
6051 remap->u.ar.type = AR_FULL;
6052 break;
6054 rank_remap = (remap && remap->u.ar.end[0]);
6056 gfc_conv_expr_descriptor (&lse, expr1, lss);
6057 strlen_lhs = lse.string_length;
6058 desc = lse.expr;
6060 if (expr2->expr_type == EXPR_NULL)
6062 /* Just set the data pointer to null. */
6063 gfc_conv_descriptor_data_set (&lse.pre, lse.expr, null_pointer_node);
6065 else if (rank_remap)
6067 /* If we are rank-remapping, just get the RHS's descriptor and
6068 process this later on. */
6069 gfc_init_se (&rse, NULL);
6070 rse.direct_byref = 1;
6071 rse.byref_noassign = 1;
6072 gfc_conv_expr_descriptor (&rse, expr2, rss);
6073 strlen_rhs = rse.string_length;
6075 else if (expr2->expr_type == EXPR_VARIABLE)
6077 /* Assign directly to the LHS's descriptor. */
6078 lse.direct_byref = 1;
6079 gfc_conv_expr_descriptor (&lse, expr2, rss);
6080 strlen_rhs = lse.string_length;
6082 /* If this is a subreference array pointer assignment, use the rhs
6083 descriptor element size for the lhs span. */
6084 if (expr1->symtree->n.sym->attr.subref_array_pointer)
6086 decl = expr1->symtree->n.sym->backend_decl;
6087 gfc_init_se (&rse, NULL);
6088 rse.descriptor_only = 1;
6089 gfc_conv_expr (&rse, expr2);
6090 tmp = gfc_get_element_type (TREE_TYPE (rse.expr));
6091 tmp = fold_convert (gfc_array_index_type, size_in_bytes (tmp));
6092 if (!INTEGER_CST_P (tmp))
6093 gfc_add_block_to_block (&lse.post, &rse.pre);
6094 gfc_add_modify (&lse.post, GFC_DECL_SPAN(decl), tmp);
6097 else
6099 /* Assign to a temporary descriptor and then copy that
6100 temporary to the pointer. */
6101 tmp = gfc_create_var (TREE_TYPE (desc), "ptrtemp");
6103 lse.expr = tmp;
6104 lse.direct_byref = 1;
6105 gfc_conv_expr_descriptor (&lse, expr2, rss);
6106 strlen_rhs = lse.string_length;
6107 gfc_add_modify (&lse.pre, desc, tmp);
6110 gfc_add_block_to_block (&block, &lse.pre);
6111 if (rank_remap)
6112 gfc_add_block_to_block (&block, &rse.pre);
6114 /* If we do bounds remapping, update LHS descriptor accordingly. */
6115 if (remap)
6117 int dim;
6118 gcc_assert (remap->u.ar.dimen == expr1->rank);
6120 if (rank_remap)
6122 /* Do rank remapping. We already have the RHS's descriptor
6123 converted in rse and now have to build the correct LHS
6124 descriptor for it. */
6126 tree dtype, data;
6127 tree offs, stride;
6128 tree lbound, ubound;
6130 /* Set dtype. */
6131 dtype = gfc_conv_descriptor_dtype (desc);
6132 tmp = gfc_get_dtype (TREE_TYPE (desc));
6133 gfc_add_modify (&block, dtype, tmp);
6135 /* Copy data pointer. */
6136 data = gfc_conv_descriptor_data_get (rse.expr);
6137 gfc_conv_descriptor_data_set (&block, desc, data);
6139 /* Copy offset but adjust it such that it would correspond
6140 to a lbound of zero. */
6141 offs = gfc_conv_descriptor_offset_get (rse.expr);
6142 for (dim = 0; dim < expr2->rank; ++dim)
6144 stride = gfc_conv_descriptor_stride_get (rse.expr,
6145 gfc_rank_cst[dim]);
6146 lbound = gfc_conv_descriptor_lbound_get (rse.expr,
6147 gfc_rank_cst[dim]);
6148 tmp = fold_build2_loc (input_location, MULT_EXPR,
6149 gfc_array_index_type, stride, lbound);
6150 offs = fold_build2_loc (input_location, PLUS_EXPR,
6151 gfc_array_index_type, offs, tmp);
6153 gfc_conv_descriptor_offset_set (&block, desc, offs);
6155 /* Set the bounds as declared for the LHS and calculate strides as
6156 well as another offset update accordingly. */
6157 stride = gfc_conv_descriptor_stride_get (rse.expr,
6158 gfc_rank_cst[0]);
6159 for (dim = 0; dim < expr1->rank; ++dim)
6161 gfc_se lower_se;
6162 gfc_se upper_se;
6164 gcc_assert (remap->u.ar.start[dim] && remap->u.ar.end[dim]);
6166 /* Convert declared bounds. */
6167 gfc_init_se (&lower_se, NULL);
6168 gfc_init_se (&upper_se, NULL);
6169 gfc_conv_expr (&lower_se, remap->u.ar.start[dim]);
6170 gfc_conv_expr (&upper_se, remap->u.ar.end[dim]);
6172 gfc_add_block_to_block (&block, &lower_se.pre);
6173 gfc_add_block_to_block (&block, &upper_se.pre);
6175 lbound = fold_convert (gfc_array_index_type, lower_se.expr);
6176 ubound = fold_convert (gfc_array_index_type, upper_se.expr);
6178 lbound = gfc_evaluate_now (lbound, &block);
6179 ubound = gfc_evaluate_now (ubound, &block);
6181 gfc_add_block_to_block (&block, &lower_se.post);
6182 gfc_add_block_to_block (&block, &upper_se.post);
6184 /* Set bounds in descriptor. */
6185 gfc_conv_descriptor_lbound_set (&block, desc,
6186 gfc_rank_cst[dim], lbound);
6187 gfc_conv_descriptor_ubound_set (&block, desc,
6188 gfc_rank_cst[dim], ubound);
6190 /* Set stride. */
6191 stride = gfc_evaluate_now (stride, &block);
6192 gfc_conv_descriptor_stride_set (&block, desc,
6193 gfc_rank_cst[dim], stride);
6195 /* Update offset. */
6196 offs = gfc_conv_descriptor_offset_get (desc);
6197 tmp = fold_build2_loc (input_location, MULT_EXPR,
6198 gfc_array_index_type, lbound, stride);
6199 offs = fold_build2_loc (input_location, MINUS_EXPR,
6200 gfc_array_index_type, offs, tmp);
6201 offs = gfc_evaluate_now (offs, &block);
6202 gfc_conv_descriptor_offset_set (&block, desc, offs);
6204 /* Update stride. */
6205 tmp = gfc_conv_array_extent_dim (lbound, ubound, NULL);
6206 stride = fold_build2_loc (input_location, MULT_EXPR,
6207 gfc_array_index_type, stride, tmp);
6210 else
6212 /* Bounds remapping. Just shift the lower bounds. */
6214 gcc_assert (expr1->rank == expr2->rank);
6216 for (dim = 0; dim < remap->u.ar.dimen; ++dim)
6218 gfc_se lbound_se;
6220 gcc_assert (remap->u.ar.start[dim]);
6221 gcc_assert (!remap->u.ar.end[dim]);
6222 gfc_init_se (&lbound_se, NULL);
6223 gfc_conv_expr (&lbound_se, remap->u.ar.start[dim]);
6225 gfc_add_block_to_block (&block, &lbound_se.pre);
6226 gfc_conv_shift_descriptor_lbound (&block, desc,
6227 dim, lbound_se.expr);
6228 gfc_add_block_to_block (&block, &lbound_se.post);
6233 /* Check string lengths if applicable. The check is only really added
6234 to the output code if -fbounds-check is enabled. */
6235 if (expr1->ts.type == BT_CHARACTER && expr2->expr_type != EXPR_NULL)
6237 gcc_assert (expr2->ts.type == BT_CHARACTER);
6238 gcc_assert (strlen_lhs && strlen_rhs);
6239 gfc_trans_same_strlen_check ("pointer assignment", &expr1->where,
6240 strlen_lhs, strlen_rhs, &block);
6243 /* If rank remapping was done, check with -fcheck=bounds that
6244 the target is at least as large as the pointer. */
6245 if (rank_remap && (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS))
6247 tree lsize, rsize;
6248 tree fault;
6249 const char* msg;
6251 lsize = gfc_conv_descriptor_size (lse.expr, expr1->rank);
6252 rsize = gfc_conv_descriptor_size (rse.expr, expr2->rank);
6254 lsize = gfc_evaluate_now (lsize, &block);
6255 rsize = gfc_evaluate_now (rsize, &block);
6256 fault = fold_build2_loc (input_location, LT_EXPR, boolean_type_node,
6257 rsize, lsize);
6259 msg = _("Target of rank remapping is too small (%ld < %ld)");
6260 gfc_trans_runtime_check (true, false, fault, &block, &expr2->where,
6261 msg, rsize, lsize);
6264 gfc_add_block_to_block (&block, &lse.post);
6265 if (rank_remap)
6266 gfc_add_block_to_block (&block, &rse.post);
6269 return gfc_finish_block (&block);
6273 /* Makes sure se is suitable for passing as a function string parameter. */
6274 /* TODO: Need to check all callers of this function. It may be abused. */
6276 void
6277 gfc_conv_string_parameter (gfc_se * se)
6279 tree type;
6281 if (TREE_CODE (se->expr) == STRING_CST)
6283 type = TREE_TYPE (TREE_TYPE (se->expr));
6284 se->expr = gfc_build_addr_expr (build_pointer_type (type), se->expr);
6285 return;
6288 if (TYPE_STRING_FLAG (TREE_TYPE (se->expr)))
6290 if (TREE_CODE (se->expr) != INDIRECT_REF)
6292 type = TREE_TYPE (se->expr);
6293 se->expr = gfc_build_addr_expr (build_pointer_type (type), se->expr);
6295 else
6297 type = gfc_get_character_type_len (gfc_default_character_kind,
6298 se->string_length);
6299 type = build_pointer_type (type);
6300 se->expr = gfc_build_addr_expr (type, se->expr);
6304 gcc_assert (POINTER_TYPE_P (TREE_TYPE (se->expr)));
6308 /* Generate code for assignment of scalar variables. Includes character
6309 strings and derived types with allocatable components.
6310 If you know that the LHS has no allocations, set dealloc to false. */
6312 tree
6313 gfc_trans_scalar_assign (gfc_se * lse, gfc_se * rse, gfc_typespec ts,
6314 bool l_is_temp, bool r_is_var, bool dealloc)
6316 stmtblock_t block;
6317 tree tmp;
6318 tree cond;
6320 gfc_init_block (&block);
6322 if (ts.type == BT_CHARACTER)
6324 tree rlen = NULL;
6325 tree llen = NULL;
6327 if (lse->string_length != NULL_TREE)
6329 gfc_conv_string_parameter (lse);
6330 gfc_add_block_to_block (&block, &lse->pre);
6331 llen = lse->string_length;
6334 if (rse->string_length != NULL_TREE)
6336 gcc_assert (rse->string_length != NULL_TREE);
6337 gfc_conv_string_parameter (rse);
6338 gfc_add_block_to_block (&block, &rse->pre);
6339 rlen = rse->string_length;
6342 gfc_trans_string_copy (&block, llen, lse->expr, ts.kind, rlen,
6343 rse->expr, ts.kind);
6345 else if (ts.type == BT_DERIVED && ts.u.derived->attr.alloc_comp)
6347 cond = NULL_TREE;
6349 /* Are the rhs and the lhs the same? */
6350 if (r_is_var)
6352 cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
6353 gfc_build_addr_expr (NULL_TREE, lse->expr),
6354 gfc_build_addr_expr (NULL_TREE, rse->expr));
6355 cond = gfc_evaluate_now (cond, &lse->pre);
6358 /* Deallocate the lhs allocated components as long as it is not
6359 the same as the rhs. This must be done following the assignment
6360 to prevent deallocating data that could be used in the rhs
6361 expression. */
6362 if (!l_is_temp && dealloc)
6364 tmp = gfc_evaluate_now (lse->expr, &lse->pre);
6365 tmp = gfc_deallocate_alloc_comp (ts.u.derived, tmp, 0);
6366 if (r_is_var)
6367 tmp = build3_v (COND_EXPR, cond, build_empty_stmt (input_location),
6368 tmp);
6369 gfc_add_expr_to_block (&lse->post, tmp);
6372 gfc_add_block_to_block (&block, &rse->pre);
6373 gfc_add_block_to_block (&block, &lse->pre);
6375 gfc_add_modify (&block, lse->expr,
6376 fold_convert (TREE_TYPE (lse->expr), rse->expr));
6378 /* Do a deep copy if the rhs is a variable, if it is not the
6379 same as the lhs. */
6380 if (r_is_var)
6382 tmp = gfc_copy_alloc_comp (ts.u.derived, rse->expr, lse->expr, 0);
6383 tmp = build3_v (COND_EXPR, cond, build_empty_stmt (input_location),
6384 tmp);
6385 gfc_add_expr_to_block (&block, tmp);
6388 else if (ts.type == BT_DERIVED || ts.type == BT_CLASS)
6390 gfc_add_block_to_block (&block, &lse->pre);
6391 gfc_add_block_to_block (&block, &rse->pre);
6392 tmp = fold_build1_loc (input_location, VIEW_CONVERT_EXPR,
6393 TREE_TYPE (lse->expr), rse->expr);
6394 gfc_add_modify (&block, lse->expr, tmp);
6396 else
6398 gfc_add_block_to_block (&block, &lse->pre);
6399 gfc_add_block_to_block (&block, &rse->pre);
6401 gfc_add_modify (&block, lse->expr,
6402 fold_convert (TREE_TYPE (lse->expr), rse->expr));
6405 gfc_add_block_to_block (&block, &lse->post);
6406 gfc_add_block_to_block (&block, &rse->post);
6408 return gfc_finish_block (&block);
6412 /* There are quite a lot of restrictions on the optimisation in using an
6413 array function assign without a temporary. */
6415 static bool
6416 arrayfunc_assign_needs_temporary (gfc_expr * expr1, gfc_expr * expr2)
6418 gfc_ref * ref;
6419 bool seen_array_ref;
6420 bool c = false;
6421 gfc_symbol *sym = expr1->symtree->n.sym;
6423 /* The caller has already checked rank>0 and expr_type == EXPR_FUNCTION. */
6424 if (expr2->value.function.isym && !gfc_is_intrinsic_libcall (expr2))
6425 return true;
6427 /* Elemental functions are scalarized so that they don't need a
6428 temporary in gfc_trans_assignment_1, so return a true. Otherwise,
6429 they would need special treatment in gfc_trans_arrayfunc_assign. */
6430 if (expr2->value.function.esym != NULL
6431 && expr2->value.function.esym->attr.elemental)
6432 return true;
6434 /* Need a temporary if rhs is not FULL or a contiguous section. */
6435 if (expr1->ref && !(gfc_full_array_ref_p (expr1->ref, &c) || c))
6436 return true;
6438 /* Need a temporary if EXPR1 can't be expressed as a descriptor. */
6439 if (gfc_ref_needs_temporary_p (expr1->ref))
6440 return true;
6442 /* Functions returning pointers or allocatables need temporaries. */
6443 c = expr2->value.function.esym
6444 ? (expr2->value.function.esym->attr.pointer
6445 || expr2->value.function.esym->attr.allocatable)
6446 : (expr2->symtree->n.sym->attr.pointer
6447 || expr2->symtree->n.sym->attr.allocatable);
6448 if (c)
6449 return true;
6451 /* Character array functions need temporaries unless the
6452 character lengths are the same. */
6453 if (expr2->ts.type == BT_CHARACTER && expr2->rank > 0)
6455 if (expr1->ts.u.cl->length == NULL
6456 || expr1->ts.u.cl->length->expr_type != EXPR_CONSTANT)
6457 return true;
6459 if (expr2->ts.u.cl->length == NULL
6460 || expr2->ts.u.cl->length->expr_type != EXPR_CONSTANT)
6461 return true;
6463 if (mpz_cmp (expr1->ts.u.cl->length->value.integer,
6464 expr2->ts.u.cl->length->value.integer) != 0)
6465 return true;
6468 /* Check that no LHS component references appear during an array
6469 reference. This is needed because we do not have the means to
6470 span any arbitrary stride with an array descriptor. This check
6471 is not needed for the rhs because the function result has to be
6472 a complete type. */
6473 seen_array_ref = false;
6474 for (ref = expr1->ref; ref; ref = ref->next)
6476 if (ref->type == REF_ARRAY)
6477 seen_array_ref= true;
6478 else if (ref->type == REF_COMPONENT && seen_array_ref)
6479 return true;
6482 /* Check for a dependency. */
6483 if (gfc_check_fncall_dependency (expr1, INTENT_OUT,
6484 expr2->value.function.esym,
6485 expr2->value.function.actual,
6486 NOT_ELEMENTAL))
6487 return true;
6489 /* If we have reached here with an intrinsic function, we do not
6490 need a temporary except in the particular case that reallocation
6491 on assignment is active and the lhs is allocatable and a target. */
6492 if (expr2->value.function.isym)
6493 return (gfc_option.flag_realloc_lhs
6494 && sym->attr.allocatable
6495 && sym->attr.target);
6497 /* If the LHS is a dummy, we need a temporary if it is not
6498 INTENT(OUT). */
6499 if (sym->attr.dummy && sym->attr.intent != INTENT_OUT)
6500 return true;
6502 /* If the lhs has been host_associated, is in common, a pointer or is
6503 a target and the function is not using a RESULT variable, aliasing
6504 can occur and a temporary is needed. */
6505 if ((sym->attr.host_assoc
6506 || sym->attr.in_common
6507 || sym->attr.pointer
6508 || sym->attr.cray_pointee
6509 || sym->attr.target)
6510 && expr2->symtree != NULL
6511 && expr2->symtree->n.sym == expr2->symtree->n.sym->result)
6512 return true;
6514 /* A PURE function can unconditionally be called without a temporary. */
6515 if (expr2->value.function.esym != NULL
6516 && expr2->value.function.esym->attr.pure)
6517 return false;
6519 /* Implicit_pure functions are those which could legally be declared
6520 to be PURE. */
6521 if (expr2->value.function.esym != NULL
6522 && expr2->value.function.esym->attr.implicit_pure)
6523 return false;
6525 if (!sym->attr.use_assoc
6526 && !sym->attr.in_common
6527 && !sym->attr.pointer
6528 && !sym->attr.target
6529 && !sym->attr.cray_pointee
6530 && expr2->value.function.esym)
6532 /* A temporary is not needed if the function is not contained and
6533 the variable is local or host associated and not a pointer or
6534 a target. */
6535 if (!expr2->value.function.esym->attr.contained)
6536 return false;
6538 /* A temporary is not needed if the lhs has never been host
6539 associated and the procedure is contained. */
6540 else if (!sym->attr.host_assoc)
6541 return false;
6543 /* A temporary is not needed if the variable is local and not
6544 a pointer, a target or a result. */
6545 if (sym->ns->parent
6546 && expr2->value.function.esym->ns == sym->ns->parent)
6547 return false;
6550 /* Default to temporary use. */
6551 return true;
6555 /* Provide the loop info so that the lhs descriptor can be built for
6556 reallocatable assignments from extrinsic function calls. */
6558 static void
6559 realloc_lhs_loop_for_fcn_call (gfc_se *se, locus *where, gfc_ss **ss,
6560 gfc_loopinfo *loop)
6562 /* Signal that the function call should not be made by
6563 gfc_conv_loop_setup. */
6564 se->ss->is_alloc_lhs = 1;
6565 gfc_init_loopinfo (loop);
6566 gfc_add_ss_to_loop (loop, *ss);
6567 gfc_add_ss_to_loop (loop, se->ss);
6568 gfc_conv_ss_startstride (loop);
6569 gfc_conv_loop_setup (loop, where);
6570 gfc_copy_loopinfo_to_se (se, loop);
6571 gfc_add_block_to_block (&se->pre, &loop->pre);
6572 gfc_add_block_to_block (&se->pre, &loop->post);
6573 se->ss->is_alloc_lhs = 0;
6577 /* For assignment to a reallocatable lhs from intrinsic functions,
6578 replace the se.expr (ie. the result) with a temporary descriptor.
6579 Null the data field so that the library allocates space for the
6580 result. Free the data of the original descriptor after the function,
6581 in case it appears in an argument expression and transfer the
6582 result to the original descriptor. */
6584 static void
6585 fcncall_realloc_result (gfc_se *se, int rank)
6587 tree desc;
6588 tree res_desc;
6589 tree tmp;
6590 tree offset;
6591 tree zero_cond;
6592 int n;
6594 /* Use the allocation done by the library. Substitute the lhs
6595 descriptor with a copy, whose data field is nulled.*/
6596 desc = build_fold_indirect_ref_loc (input_location, se->expr);
6597 if (POINTER_TYPE_P (TREE_TYPE (desc)))
6598 desc = build_fold_indirect_ref_loc (input_location, desc);
6600 /* Unallocated, the descriptor does not have a dtype. */
6601 tmp = gfc_conv_descriptor_dtype (desc);
6602 gfc_add_modify (&se->pre, tmp, gfc_get_dtype (TREE_TYPE (desc)));
6604 res_desc = gfc_evaluate_now (desc, &se->pre);
6605 gfc_conv_descriptor_data_set (&se->pre, res_desc, null_pointer_node);
6606 se->expr = gfc_build_addr_expr (TREE_TYPE (se->expr), res_desc);
6608 /* Free the lhs after the function call and copy the result data to
6609 the lhs descriptor. */
6610 tmp = gfc_conv_descriptor_data_get (desc);
6611 zero_cond = fold_build2_loc (input_location, EQ_EXPR,
6612 boolean_type_node, tmp,
6613 build_int_cst (TREE_TYPE (tmp), 0));
6614 zero_cond = gfc_evaluate_now (zero_cond, &se->post);
6615 tmp = gfc_call_free (fold_convert (pvoid_type_node, tmp));
6616 gfc_add_expr_to_block (&se->post, tmp);
6618 tmp = gfc_conv_descriptor_data_get (res_desc);
6619 gfc_conv_descriptor_data_set (&se->post, desc, tmp);
6621 /* Check that the shapes are the same between lhs and expression. */
6622 for (n = 0 ; n < rank; n++)
6624 tree tmp1;
6625 tmp = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[n]);
6626 tmp1 = gfc_conv_descriptor_lbound_get (res_desc, gfc_rank_cst[n]);
6627 tmp = fold_build2_loc (input_location, MINUS_EXPR,
6628 gfc_array_index_type, tmp, tmp1);
6629 tmp1 = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[n]);
6630 tmp = fold_build2_loc (input_location, MINUS_EXPR,
6631 gfc_array_index_type, tmp, tmp1);
6632 tmp1 = gfc_conv_descriptor_ubound_get (res_desc, gfc_rank_cst[n]);
6633 tmp = fold_build2_loc (input_location, PLUS_EXPR,
6634 gfc_array_index_type, tmp, tmp1);
6635 tmp = fold_build2_loc (input_location, NE_EXPR,
6636 boolean_type_node, tmp,
6637 gfc_index_zero_node);
6638 tmp = gfc_evaluate_now (tmp, &se->post);
6639 zero_cond = fold_build2_loc (input_location, TRUTH_OR_EXPR,
6640 boolean_type_node, tmp,
6641 zero_cond);
6644 /* 'zero_cond' being true is equal to lhs not being allocated or the
6645 shapes being different. */
6646 zero_cond = gfc_evaluate_now (zero_cond, &se->post);
6648 /* Now reset the bounds returned from the function call to bounds based
6649 on the lhs lbounds, except where the lhs is not allocated or the shapes
6650 of 'variable and 'expr' are different. Set the offset accordingly. */
6651 offset = gfc_index_zero_node;
6652 for (n = 0 ; n < rank; n++)
6654 tree lbound;
6656 lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[n]);
6657 lbound = fold_build3_loc (input_location, COND_EXPR,
6658 gfc_array_index_type, zero_cond,
6659 gfc_index_one_node, lbound);
6660 lbound = gfc_evaluate_now (lbound, &se->post);
6662 tmp = gfc_conv_descriptor_ubound_get (res_desc, gfc_rank_cst[n]);
6663 tmp = fold_build2_loc (input_location, PLUS_EXPR,
6664 gfc_array_index_type, tmp, lbound);
6665 gfc_conv_descriptor_lbound_set (&se->post, desc,
6666 gfc_rank_cst[n], lbound);
6667 gfc_conv_descriptor_ubound_set (&se->post, desc,
6668 gfc_rank_cst[n], tmp);
6670 /* Set stride and accumulate the offset. */
6671 tmp = gfc_conv_descriptor_stride_get (res_desc, gfc_rank_cst[n]);
6672 gfc_conv_descriptor_stride_set (&se->post, desc,
6673 gfc_rank_cst[n], tmp);
6674 tmp = fold_build2_loc (input_location, MULT_EXPR,
6675 gfc_array_index_type, lbound, tmp);
6676 offset = fold_build2_loc (input_location, MINUS_EXPR,
6677 gfc_array_index_type, offset, tmp);
6678 offset = gfc_evaluate_now (offset, &se->post);
6681 gfc_conv_descriptor_offset_set (&se->post, desc, offset);
6686 /* Try to translate array(:) = func (...), where func is a transformational
6687 array function, without using a temporary. Returns NULL if this isn't the
6688 case. */
6690 static tree
6691 gfc_trans_arrayfunc_assign (gfc_expr * expr1, gfc_expr * expr2)
6693 gfc_se se;
6694 gfc_ss *ss;
6695 gfc_component *comp = NULL;
6696 gfc_loopinfo loop;
6698 if (arrayfunc_assign_needs_temporary (expr1, expr2))
6699 return NULL;
6701 /* The frontend doesn't seem to bother filling in expr->symtree for intrinsic
6702 functions. */
6703 comp = gfc_get_proc_ptr_comp (expr2);
6704 gcc_assert (expr2->value.function.isym
6705 || (comp && comp->attr.dimension)
6706 || (!comp && gfc_return_by_reference (expr2->value.function.esym)
6707 && expr2->value.function.esym->result->attr.dimension));
6709 ss = gfc_walk_expr (expr1);
6710 gcc_assert (ss != gfc_ss_terminator);
6711 gfc_init_se (&se, NULL);
6712 gfc_start_block (&se.pre);
6713 se.want_pointer = 1;
6715 gfc_conv_array_parameter (&se, expr1, ss, false, NULL, NULL, NULL);
6717 if (expr1->ts.type == BT_DERIVED
6718 && expr1->ts.u.derived->attr.alloc_comp)
6720 tree tmp;
6721 tmp = gfc_deallocate_alloc_comp (expr1->ts.u.derived, se.expr,
6722 expr1->rank);
6723 gfc_add_expr_to_block (&se.pre, tmp);
6726 se.direct_byref = 1;
6727 se.ss = gfc_walk_expr (expr2);
6728 gcc_assert (se.ss != gfc_ss_terminator);
6730 /* Reallocate on assignment needs the loopinfo for extrinsic functions.
6731 This is signalled to gfc_conv_procedure_call by setting is_alloc_lhs.
6732 Clearly, this cannot be done for an allocatable function result, since
6733 the shape of the result is unknown and, in any case, the function must
6734 correctly take care of the reallocation internally. For intrinsic
6735 calls, the array data is freed and the library takes care of allocation.
6736 TODO: Add logic of trans-array.c: gfc_alloc_allocatable_for_assignment
6737 to the library. */
6738 if (gfc_option.flag_realloc_lhs
6739 && gfc_is_reallocatable_lhs (expr1)
6740 && !gfc_expr_attr (expr1).codimension
6741 && !gfc_is_coindexed (expr1)
6742 && !(expr2->value.function.esym
6743 && expr2->value.function.esym->result->attr.allocatable))
6745 realloc_lhs_warning (expr1->ts.type, true, &expr1->where);
6747 if (!expr2->value.function.isym)
6749 realloc_lhs_loop_for_fcn_call (&se, &expr1->where, &ss, &loop);
6750 ss->is_alloc_lhs = 1;
6752 else
6753 fcncall_realloc_result (&se, expr1->rank);
6756 gfc_conv_function_expr (&se, expr2);
6757 gfc_add_block_to_block (&se.pre, &se.post);
6759 return gfc_finish_block (&se.pre);
6763 /* Try to efficiently translate array(:) = 0. Return NULL if this
6764 can't be done. */
6766 static tree
6767 gfc_trans_zero_assign (gfc_expr * expr)
6769 tree dest, len, type;
6770 tree tmp;
6771 gfc_symbol *sym;
6773 sym = expr->symtree->n.sym;
6774 dest = gfc_get_symbol_decl (sym);
6776 type = TREE_TYPE (dest);
6777 if (POINTER_TYPE_P (type))
6778 type = TREE_TYPE (type);
6779 if (!GFC_ARRAY_TYPE_P (type))
6780 return NULL_TREE;
6782 /* Determine the length of the array. */
6783 len = GFC_TYPE_ARRAY_SIZE (type);
6784 if (!len || TREE_CODE (len) != INTEGER_CST)
6785 return NULL_TREE;
6787 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type));
6788 len = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type, len,
6789 fold_convert (gfc_array_index_type, tmp));
6791 /* If we are zeroing a local array avoid taking its address by emitting
6792 a = {} instead. */
6793 if (!POINTER_TYPE_P (TREE_TYPE (dest)))
6794 return build2_loc (input_location, MODIFY_EXPR, void_type_node,
6795 dest, build_constructor (TREE_TYPE (dest), NULL));
6797 /* Convert arguments to the correct types. */
6798 dest = fold_convert (pvoid_type_node, dest);
6799 len = fold_convert (size_type_node, len);
6801 /* Construct call to __builtin_memset. */
6802 tmp = build_call_expr_loc (input_location,
6803 builtin_decl_explicit (BUILT_IN_MEMSET),
6804 3, dest, integer_zero_node, len);
6805 return fold_convert (void_type_node, tmp);
6809 /* Helper for gfc_trans_array_copy and gfc_trans_array_constructor_copy
6810 that constructs the call to __builtin_memcpy. */
6812 tree
6813 gfc_build_memcpy_call (tree dst, tree src, tree len)
6815 tree tmp;
6817 /* Convert arguments to the correct types. */
6818 if (!POINTER_TYPE_P (TREE_TYPE (dst)))
6819 dst = gfc_build_addr_expr (pvoid_type_node, dst);
6820 else
6821 dst = fold_convert (pvoid_type_node, dst);
6823 if (!POINTER_TYPE_P (TREE_TYPE (src)))
6824 src = gfc_build_addr_expr (pvoid_type_node, src);
6825 else
6826 src = fold_convert (pvoid_type_node, src);
6828 len = fold_convert (size_type_node, len);
6830 /* Construct call to __builtin_memcpy. */
6831 tmp = build_call_expr_loc (input_location,
6832 builtin_decl_explicit (BUILT_IN_MEMCPY),
6833 3, dst, src, len);
6834 return fold_convert (void_type_node, tmp);
6838 /* Try to efficiently translate dst(:) = src(:). Return NULL if this
6839 can't be done. EXPR1 is the destination/lhs and EXPR2 is the
6840 source/rhs, both are gfc_full_array_ref_p which have been checked for
6841 dependencies. */
6843 static tree
6844 gfc_trans_array_copy (gfc_expr * expr1, gfc_expr * expr2)
6846 tree dst, dlen, dtype;
6847 tree src, slen, stype;
6848 tree tmp;
6850 dst = gfc_get_symbol_decl (expr1->symtree->n.sym);
6851 src = gfc_get_symbol_decl (expr2->symtree->n.sym);
6853 dtype = TREE_TYPE (dst);
6854 if (POINTER_TYPE_P (dtype))
6855 dtype = TREE_TYPE (dtype);
6856 stype = TREE_TYPE (src);
6857 if (POINTER_TYPE_P (stype))
6858 stype = TREE_TYPE (stype);
6860 if (!GFC_ARRAY_TYPE_P (dtype) || !GFC_ARRAY_TYPE_P (stype))
6861 return NULL_TREE;
6863 /* Determine the lengths of the arrays. */
6864 dlen = GFC_TYPE_ARRAY_SIZE (dtype);
6865 if (!dlen || TREE_CODE (dlen) != INTEGER_CST)
6866 return NULL_TREE;
6867 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (dtype));
6868 dlen = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
6869 dlen, fold_convert (gfc_array_index_type, tmp));
6871 slen = GFC_TYPE_ARRAY_SIZE (stype);
6872 if (!slen || TREE_CODE (slen) != INTEGER_CST)
6873 return NULL_TREE;
6874 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (stype));
6875 slen = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
6876 slen, fold_convert (gfc_array_index_type, tmp));
6878 /* Sanity check that they are the same. This should always be
6879 the case, as we should already have checked for conformance. */
6880 if (!tree_int_cst_equal (slen, dlen))
6881 return NULL_TREE;
6883 return gfc_build_memcpy_call (dst, src, dlen);
6887 /* Try to efficiently translate array(:) = (/ ... /). Return NULL if
6888 this can't be done. EXPR1 is the destination/lhs for which
6889 gfc_full_array_ref_p is true, and EXPR2 is the source/rhs. */
6891 static tree
6892 gfc_trans_array_constructor_copy (gfc_expr * expr1, gfc_expr * expr2)
6894 unsigned HOST_WIDE_INT nelem;
6895 tree dst, dtype;
6896 tree src, stype;
6897 tree len;
6898 tree tmp;
6900 nelem = gfc_constant_array_constructor_p (expr2->value.constructor);
6901 if (nelem == 0)
6902 return NULL_TREE;
6904 dst = gfc_get_symbol_decl (expr1->symtree->n.sym);
6905 dtype = TREE_TYPE (dst);
6906 if (POINTER_TYPE_P (dtype))
6907 dtype = TREE_TYPE (dtype);
6908 if (!GFC_ARRAY_TYPE_P (dtype))
6909 return NULL_TREE;
6911 /* Determine the lengths of the array. */
6912 len = GFC_TYPE_ARRAY_SIZE (dtype);
6913 if (!len || TREE_CODE (len) != INTEGER_CST)
6914 return NULL_TREE;
6916 /* Confirm that the constructor is the same size. */
6917 if (compare_tree_int (len, nelem) != 0)
6918 return NULL_TREE;
6920 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (dtype));
6921 len = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type, len,
6922 fold_convert (gfc_array_index_type, tmp));
6924 stype = gfc_typenode_for_spec (&expr2->ts);
6925 src = gfc_build_constant_array_constructor (expr2, stype);
6927 stype = TREE_TYPE (src);
6928 if (POINTER_TYPE_P (stype))
6929 stype = TREE_TYPE (stype);
6931 return gfc_build_memcpy_call (dst, src, len);
6935 /* Tells whether the expression is to be treated as a variable reference. */
6937 static bool
6938 expr_is_variable (gfc_expr *expr)
6940 gfc_expr *arg;
6942 if (expr->expr_type == EXPR_VARIABLE)
6943 return true;
6945 arg = gfc_get_noncopying_intrinsic_argument (expr);
6946 if (arg)
6948 gcc_assert (expr->value.function.isym->id == GFC_ISYM_TRANSPOSE);
6949 return expr_is_variable (arg);
6952 return false;
6956 /* Is the lhs OK for automatic reallocation? */
6958 static bool
6959 is_scalar_reallocatable_lhs (gfc_expr *expr)
6961 gfc_ref * ref;
6963 /* An allocatable variable with no reference. */
6964 if (expr->symtree->n.sym->attr.allocatable
6965 && !expr->ref)
6966 return true;
6968 /* All that can be left are allocatable components. */
6969 if ((expr->symtree->n.sym->ts.type != BT_DERIVED
6970 && expr->symtree->n.sym->ts.type != BT_CLASS)
6971 || !expr->symtree->n.sym->ts.u.derived->attr.alloc_comp)
6972 return false;
6974 /* Find an allocatable component ref last. */
6975 for (ref = expr->ref; ref; ref = ref->next)
6976 if (ref->type == REF_COMPONENT
6977 && !ref->next
6978 && ref->u.c.component->attr.allocatable)
6979 return true;
6981 return false;
6985 /* Allocate or reallocate scalar lhs, as necessary. */
6987 static void
6988 alloc_scalar_allocatable_for_assignment (stmtblock_t *block,
6989 tree string_length,
6990 gfc_expr *expr1,
6991 gfc_expr *expr2)
6994 tree cond;
6995 tree tmp;
6996 tree size;
6997 tree size_in_bytes;
6998 tree jump_label1;
6999 tree jump_label2;
7000 gfc_se lse;
7002 if (!expr1 || expr1->rank)
7003 return;
7005 if (!expr2 || expr2->rank)
7006 return;
7008 realloc_lhs_warning (expr2->ts.type, false, &expr2->where);
7010 /* Since this is a scalar lhs, we can afford to do this. That is,
7011 there is no risk of side effects being repeated. */
7012 gfc_init_se (&lse, NULL);
7013 lse.want_pointer = 1;
7014 gfc_conv_expr (&lse, expr1);
7016 jump_label1 = gfc_build_label_decl (NULL_TREE);
7017 jump_label2 = gfc_build_label_decl (NULL_TREE);
7019 /* Do the allocation if the lhs is NULL. Otherwise go to label 1. */
7020 tmp = build_int_cst (TREE_TYPE (lse.expr), 0);
7021 cond = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
7022 lse.expr, tmp);
7023 tmp = build3_v (COND_EXPR, cond,
7024 build1_v (GOTO_EXPR, jump_label1),
7025 build_empty_stmt (input_location));
7026 gfc_add_expr_to_block (block, tmp);
7028 if (expr1->ts.type == BT_CHARACTER && expr1->ts.deferred)
7030 /* Use the rhs string length and the lhs element size. */
7031 size = string_length;
7032 tmp = TREE_TYPE (gfc_typenode_for_spec (&expr1->ts));
7033 tmp = TYPE_SIZE_UNIT (tmp);
7034 size_in_bytes = fold_build2_loc (input_location, MULT_EXPR,
7035 TREE_TYPE (tmp), tmp,
7036 fold_convert (TREE_TYPE (tmp), size));
7038 else
7040 /* Otherwise use the length in bytes of the rhs. */
7041 size = TYPE_SIZE_UNIT (gfc_typenode_for_spec (&expr1->ts));
7042 size_in_bytes = size;
7045 if (expr1->ts.type == BT_DERIVED && expr1->ts.u.derived->attr.alloc_comp)
7047 tmp = build_call_expr_loc (input_location,
7048 builtin_decl_explicit (BUILT_IN_CALLOC),
7049 2, build_one_cst (size_type_node),
7050 size_in_bytes);
7051 tmp = fold_convert (TREE_TYPE (lse.expr), tmp);
7052 gfc_add_modify (block, lse.expr, tmp);
7054 else
7056 tmp = build_call_expr_loc (input_location,
7057 builtin_decl_explicit (BUILT_IN_MALLOC),
7058 1, size_in_bytes);
7059 tmp = fold_convert (TREE_TYPE (lse.expr), tmp);
7060 gfc_add_modify (block, lse.expr, tmp);
7063 if (expr1->ts.type == BT_CHARACTER && expr1->ts.deferred)
7065 /* Deferred characters need checking for lhs and rhs string
7066 length. Other deferred parameter variables will have to
7067 come here too. */
7068 tmp = build1_v (GOTO_EXPR, jump_label2);
7069 gfc_add_expr_to_block (block, tmp);
7071 tmp = build1_v (LABEL_EXPR, jump_label1);
7072 gfc_add_expr_to_block (block, tmp);
7074 /* For a deferred length character, reallocate if lengths of lhs and
7075 rhs are different. */
7076 if (expr1->ts.type == BT_CHARACTER && expr1->ts.deferred)
7078 cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
7079 expr1->ts.u.cl->backend_decl, size);
7080 /* Jump past the realloc if the lengths are the same. */
7081 tmp = build3_v (COND_EXPR, cond,
7082 build1_v (GOTO_EXPR, jump_label2),
7083 build_empty_stmt (input_location));
7084 gfc_add_expr_to_block (block, tmp);
7085 tmp = build_call_expr_loc (input_location,
7086 builtin_decl_explicit (BUILT_IN_REALLOC),
7087 2, fold_convert (pvoid_type_node, lse.expr),
7088 size_in_bytes);
7089 tmp = fold_convert (TREE_TYPE (lse.expr), tmp);
7090 gfc_add_modify (block, lse.expr, tmp);
7091 tmp = build1_v (LABEL_EXPR, jump_label2);
7092 gfc_add_expr_to_block (block, tmp);
7094 /* Update the lhs character length. */
7095 size = string_length;
7096 gfc_add_modify (block, expr1->ts.u.cl->backend_decl, size);
7101 /* Subroutine of gfc_trans_assignment that actually scalarizes the
7102 assignment. EXPR1 is the destination/LHS and EXPR2 is the source/RHS.
7103 init_flag indicates initialization expressions and dealloc that no
7104 deallocate prior assignment is needed (if in doubt, set true). */
7106 static tree
7107 gfc_trans_assignment_1 (gfc_expr * expr1, gfc_expr * expr2, bool init_flag,
7108 bool dealloc)
7110 gfc_se lse;
7111 gfc_se rse;
7112 gfc_ss *lss;
7113 gfc_ss *lss_section;
7114 gfc_ss *rss;
7115 gfc_loopinfo loop;
7116 tree tmp;
7117 stmtblock_t block;
7118 stmtblock_t body;
7119 bool l_is_temp;
7120 bool scalar_to_array;
7121 tree string_length;
7122 int n;
7124 /* Assignment of the form lhs = rhs. */
7125 gfc_start_block (&block);
7127 gfc_init_se (&lse, NULL);
7128 gfc_init_se (&rse, NULL);
7130 /* Walk the lhs. */
7131 lss = gfc_walk_expr (expr1);
7132 if (gfc_is_reallocatable_lhs (expr1)
7133 && !(expr2->expr_type == EXPR_FUNCTION
7134 && expr2->value.function.isym != NULL))
7135 lss->is_alloc_lhs = 1;
7136 rss = NULL;
7137 if (lss != gfc_ss_terminator)
7139 /* The assignment needs scalarization. */
7140 lss_section = lss;
7142 /* Find a non-scalar SS from the lhs. */
7143 while (lss_section != gfc_ss_terminator
7144 && lss_section->info->type != GFC_SS_SECTION)
7145 lss_section = lss_section->next;
7147 gcc_assert (lss_section != gfc_ss_terminator);
7149 /* Initialize the scalarizer. */
7150 gfc_init_loopinfo (&loop);
7152 /* Walk the rhs. */
7153 rss = gfc_walk_expr (expr2);
7154 if (rss == gfc_ss_terminator)
7155 /* The rhs is scalar. Add a ss for the expression. */
7156 rss = gfc_get_scalar_ss (gfc_ss_terminator, expr2);
7158 /* Associate the SS with the loop. */
7159 gfc_add_ss_to_loop (&loop, lss);
7160 gfc_add_ss_to_loop (&loop, rss);
7162 /* Calculate the bounds of the scalarization. */
7163 gfc_conv_ss_startstride (&loop);
7164 /* Enable loop reversal. */
7165 for (n = 0; n < GFC_MAX_DIMENSIONS; n++)
7166 loop.reverse[n] = GFC_ENABLE_REVERSE;
7167 /* Resolve any data dependencies in the statement. */
7168 gfc_conv_resolve_dependencies (&loop, lss, rss);
7169 /* Setup the scalarizing loops. */
7170 gfc_conv_loop_setup (&loop, &expr2->where);
7172 /* Setup the gfc_se structures. */
7173 gfc_copy_loopinfo_to_se (&lse, &loop);
7174 gfc_copy_loopinfo_to_se (&rse, &loop);
7176 rse.ss = rss;
7177 gfc_mark_ss_chain_used (rss, 1);
7178 if (loop.temp_ss == NULL)
7180 lse.ss = lss;
7181 gfc_mark_ss_chain_used (lss, 1);
7183 else
7185 lse.ss = loop.temp_ss;
7186 gfc_mark_ss_chain_used (lss, 3);
7187 gfc_mark_ss_chain_used (loop.temp_ss, 3);
7190 /* Allow the scalarizer to workshare array assignments. */
7191 if ((ompws_flags & OMPWS_WORKSHARE_FLAG) && loop.temp_ss == NULL)
7192 ompws_flags |= OMPWS_SCALARIZER_WS;
7194 /* Start the scalarized loop body. */
7195 gfc_start_scalarized_body (&loop, &body);
7197 else
7198 gfc_init_block (&body);
7200 l_is_temp = (lss != gfc_ss_terminator && loop.temp_ss != NULL);
7202 /* Translate the expression. */
7203 gfc_conv_expr (&rse, expr2);
7205 /* Stabilize a string length for temporaries. */
7206 if (expr2->ts.type == BT_CHARACTER)
7207 string_length = gfc_evaluate_now (rse.string_length, &rse.pre);
7208 else
7209 string_length = NULL_TREE;
7211 if (l_is_temp)
7213 gfc_conv_tmp_array_ref (&lse);
7214 if (expr2->ts.type == BT_CHARACTER)
7215 lse.string_length = string_length;
7217 else
7218 gfc_conv_expr (&lse, expr1);
7220 /* Assignments of scalar derived types with allocatable components
7221 to arrays must be done with a deep copy and the rhs temporary
7222 must have its components deallocated afterwards. */
7223 scalar_to_array = (expr2->ts.type == BT_DERIVED
7224 && expr2->ts.u.derived->attr.alloc_comp
7225 && !expr_is_variable (expr2)
7226 && !gfc_is_constant_expr (expr2)
7227 && expr1->rank && !expr2->rank);
7228 if (scalar_to_array && dealloc)
7230 tmp = gfc_deallocate_alloc_comp (expr2->ts.u.derived, rse.expr, 0);
7231 gfc_add_expr_to_block (&loop.post, tmp);
7234 /* When assigning a character function result to a deferred-length variable,
7235 the function call must happen before the (re)allocation of the lhs -
7236 otherwise the character length of the result is not known.
7237 NOTE: This relies on having the exact dependence of the length type
7238 parameter available to the caller; gfortran saves it in the .mod files. */
7239 if (gfc_option.flag_realloc_lhs && expr2->ts.type == BT_CHARACTER
7240 && expr1->ts.deferred)
7241 gfc_add_block_to_block (&block, &rse.pre);
7243 tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts,
7244 l_is_temp || init_flag,
7245 expr_is_variable (expr2) || scalar_to_array
7246 || expr2->expr_type == EXPR_ARRAY, dealloc);
7247 gfc_add_expr_to_block (&body, tmp);
7249 if (lss == gfc_ss_terminator)
7251 /* F2003: Add the code for reallocation on assignment. */
7252 if (gfc_option.flag_realloc_lhs
7253 && is_scalar_reallocatable_lhs (expr1))
7254 alloc_scalar_allocatable_for_assignment (&block, rse.string_length,
7255 expr1, expr2);
7257 /* Use the scalar assignment as is. */
7258 gfc_add_block_to_block (&block, &body);
7260 else
7262 gcc_assert (lse.ss == gfc_ss_terminator
7263 && rse.ss == gfc_ss_terminator);
7265 if (l_is_temp)
7267 gfc_trans_scalarized_loop_boundary (&loop, &body);
7269 /* We need to copy the temporary to the actual lhs. */
7270 gfc_init_se (&lse, NULL);
7271 gfc_init_se (&rse, NULL);
7272 gfc_copy_loopinfo_to_se (&lse, &loop);
7273 gfc_copy_loopinfo_to_se (&rse, &loop);
7275 rse.ss = loop.temp_ss;
7276 lse.ss = lss;
7278 gfc_conv_tmp_array_ref (&rse);
7279 gfc_conv_expr (&lse, expr1);
7281 gcc_assert (lse.ss == gfc_ss_terminator
7282 && rse.ss == gfc_ss_terminator);
7284 if (expr2->ts.type == BT_CHARACTER)
7285 rse.string_length = string_length;
7287 tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts,
7288 false, false, dealloc);
7289 gfc_add_expr_to_block (&body, tmp);
7292 /* F2003: Allocate or reallocate lhs of allocatable array. */
7293 if (gfc_option.flag_realloc_lhs
7294 && gfc_is_reallocatable_lhs (expr1)
7295 && !gfc_expr_attr (expr1).codimension
7296 && !gfc_is_coindexed (expr1)
7297 && expr2->rank)
7299 realloc_lhs_warning (expr1->ts.type, true, &expr1->where);
7300 ompws_flags &= ~OMPWS_SCALARIZER_WS;
7301 tmp = gfc_alloc_allocatable_for_assignment (&loop, expr1, expr2);
7302 if (tmp != NULL_TREE)
7303 gfc_add_expr_to_block (&loop.code[expr1->rank - 1], tmp);
7306 /* Generate the copying loops. */
7307 gfc_trans_scalarizing_loops (&loop, &body);
7309 /* Wrap the whole thing up. */
7310 gfc_add_block_to_block (&block, &loop.pre);
7311 gfc_add_block_to_block (&block, &loop.post);
7313 gfc_cleanup_loop (&loop);
7316 return gfc_finish_block (&block);
7320 /* Check whether EXPR is a copyable array. */
7322 static bool
7323 copyable_array_p (gfc_expr * expr)
7325 if (expr->expr_type != EXPR_VARIABLE)
7326 return false;
7328 /* First check it's an array. */
7329 if (expr->rank < 1 || !expr->ref || expr->ref->next)
7330 return false;
7332 if (!gfc_full_array_ref_p (expr->ref, NULL))
7333 return false;
7335 /* Next check that it's of a simple enough type. */
7336 switch (expr->ts.type)
7338 case BT_INTEGER:
7339 case BT_REAL:
7340 case BT_COMPLEX:
7341 case BT_LOGICAL:
7342 return true;
7344 case BT_CHARACTER:
7345 return false;
7347 case BT_DERIVED:
7348 return !expr->ts.u.derived->attr.alloc_comp;
7350 default:
7351 break;
7354 return false;
7357 /* Translate an assignment. */
7359 tree
7360 gfc_trans_assignment (gfc_expr * expr1, gfc_expr * expr2, bool init_flag,
7361 bool dealloc)
7363 tree tmp;
7365 /* Special case a single function returning an array. */
7366 if (expr2->expr_type == EXPR_FUNCTION && expr2->rank > 0)
7368 tmp = gfc_trans_arrayfunc_assign (expr1, expr2);
7369 if (tmp)
7370 return tmp;
7373 /* Special case assigning an array to zero. */
7374 if (copyable_array_p (expr1)
7375 && is_zero_initializer_p (expr2))
7377 tmp = gfc_trans_zero_assign (expr1);
7378 if (tmp)
7379 return tmp;
7382 /* Special case copying one array to another. */
7383 if (copyable_array_p (expr1)
7384 && copyable_array_p (expr2)
7385 && gfc_compare_types (&expr1->ts, &expr2->ts)
7386 && !gfc_check_dependency (expr1, expr2, 0))
7388 tmp = gfc_trans_array_copy (expr1, expr2);
7389 if (tmp)
7390 return tmp;
7393 /* Special case initializing an array from a constant array constructor. */
7394 if (copyable_array_p (expr1)
7395 && expr2->expr_type == EXPR_ARRAY
7396 && gfc_compare_types (&expr1->ts, &expr2->ts))
7398 tmp = gfc_trans_array_constructor_copy (expr1, expr2);
7399 if (tmp)
7400 return tmp;
7403 /* Fallback to the scalarizer to generate explicit loops. */
7404 return gfc_trans_assignment_1 (expr1, expr2, init_flag, dealloc);
7407 tree
7408 gfc_trans_init_assign (gfc_code * code)
7410 return gfc_trans_assignment (code->expr1, code->expr2, true, false);
7413 tree
7414 gfc_trans_assign (gfc_code * code)
7416 return gfc_trans_assignment (code->expr1, code->expr2, false, true);