Add support for C++0x nullptr.
[official-gcc/constexpr.git] / gcc / fortran / trans-expr.c
blob47883e258bb022d5b14917a1ccf75612f433f379
1 /* Expression translation
2 Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
3 Free Software Foundation, Inc.
4 Contributed by Paul Brook <paul@nowt.org>
5 and Steven Bosscher <s.bosscher@student.tudelft.nl>
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 3, or (at your option) any later
12 version.
14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 for more details.
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3. If not see
21 <http://www.gnu.org/licenses/>. */
23 /* trans-expr.c-- generate GENERIC trees for gfc_expr. */
25 #include "config.h"
26 #include "system.h"
27 #include "coretypes.h"
28 #include "tree.h"
29 #include "convert.h"
30 #include "ggc.h"
31 #include "toplev.h"
32 #include "real.h"
33 #include "gimple.h"
34 #include "langhooks.h"
35 #include "flags.h"
36 #include "gfortran.h"
37 #include "arith.h"
38 #include "constructor.h"
39 #include "trans.h"
40 #include "trans-const.h"
41 #include "trans-types.h"
42 #include "trans-array.h"
43 /* Only for gfc_trans_assign and gfc_trans_pointer_assign. */
44 #include "trans-stmt.h"
45 #include "dependency.h"
47 static tree gfc_trans_structure_assign (tree dest, gfc_expr * expr);
48 static void gfc_apply_interface_mapping_to_expr (gfc_interface_mapping *,
49 gfc_expr *);
51 /* Copy the scalarization loop variables. */
53 static void
54 gfc_copy_se_loopvars (gfc_se * dest, gfc_se * src)
56 dest->ss = src->ss;
57 dest->loop = src->loop;
61 /* Initialize a simple expression holder.
63 Care must be taken when multiple se are created with the same parent.
64 The child se must be kept in sync. The easiest way is to delay creation
65 of a child se until after after the previous se has been translated. */
67 void
68 gfc_init_se (gfc_se * se, gfc_se * parent)
70 memset (se, 0, sizeof (gfc_se));
71 gfc_init_block (&se->pre);
72 gfc_init_block (&se->post);
74 se->parent = parent;
76 if (parent)
77 gfc_copy_se_loopvars (se, parent);
81 /* Advances to the next SS in the chain. Use this rather than setting
82 se->ss = se->ss->next because all the parents needs to be kept in sync.
83 See gfc_init_se. */
85 void
86 gfc_advance_se_ss_chain (gfc_se * se)
88 gfc_se *p;
90 gcc_assert (se != NULL && se->ss != NULL && se->ss != gfc_ss_terminator);
92 p = se;
93 /* Walk down the parent chain. */
94 while (p != NULL)
96 /* Simple consistency check. */
97 gcc_assert (p->parent == NULL || p->parent->ss == p->ss);
99 p->ss = p->ss->next;
101 p = p->parent;
106 /* Ensures the result of the expression as either a temporary variable
107 or a constant so that it can be used repeatedly. */
109 void
110 gfc_make_safe_expr (gfc_se * se)
112 tree var;
114 if (CONSTANT_CLASS_P (se->expr))
115 return;
117 /* We need a temporary for this result. */
118 var = gfc_create_var (TREE_TYPE (se->expr), NULL);
119 gfc_add_modify (&se->pre, var, se->expr);
120 se->expr = var;
124 /* Return an expression which determines if a dummy parameter is present.
125 Also used for arguments to procedures with multiple entry points. */
127 tree
128 gfc_conv_expr_present (gfc_symbol * sym)
130 tree decl;
132 gcc_assert (sym->attr.dummy);
134 decl = gfc_get_symbol_decl (sym);
135 if (TREE_CODE (decl) != PARM_DECL)
137 /* Array parameters use a temporary descriptor, we want the real
138 parameter. */
139 gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl))
140 || GFC_ARRAY_TYPE_P (TREE_TYPE (decl)));
141 decl = GFC_DECL_SAVED_DESCRIPTOR (decl);
143 return fold_build2 (NE_EXPR, boolean_type_node, decl,
144 fold_convert (TREE_TYPE (decl), null_pointer_node));
148 /* Converts a missing, dummy argument into a null or zero. */
150 void
151 gfc_conv_missing_dummy (gfc_se * se, gfc_expr * arg, gfc_typespec ts, int kind)
153 tree present;
154 tree tmp;
156 present = gfc_conv_expr_present (arg->symtree->n.sym);
158 if (kind > 0)
160 /* Create a temporary and convert it to the correct type. */
161 tmp = gfc_get_int_type (kind);
162 tmp = fold_convert (tmp, build_fold_indirect_ref_loc (input_location,
163 se->expr));
165 /* Test for a NULL value. */
166 tmp = build3 (COND_EXPR, TREE_TYPE (tmp), present, tmp,
167 fold_convert (TREE_TYPE (tmp), integer_one_node));
168 tmp = gfc_evaluate_now (tmp, &se->pre);
169 se->expr = gfc_build_addr_expr (NULL_TREE, tmp);
171 else
173 tmp = build3 (COND_EXPR, TREE_TYPE (se->expr), present, se->expr,
174 fold_convert (TREE_TYPE (se->expr), integer_zero_node));
175 tmp = gfc_evaluate_now (tmp, &se->pre);
176 se->expr = tmp;
179 if (ts.type == BT_CHARACTER)
181 tmp = build_int_cst (gfc_charlen_type_node, 0);
182 tmp = fold_build3 (COND_EXPR, gfc_charlen_type_node,
183 present, se->string_length, tmp);
184 tmp = gfc_evaluate_now (tmp, &se->pre);
185 se->string_length = tmp;
187 return;
191 /* Get the character length of an expression, looking through gfc_refs
192 if necessary. */
194 tree
195 gfc_get_expr_charlen (gfc_expr *e)
197 gfc_ref *r;
198 tree length;
200 gcc_assert (e->expr_type == EXPR_VARIABLE
201 && e->ts.type == BT_CHARACTER);
203 length = NULL; /* To silence compiler warning. */
205 if (is_subref_array (e) && e->ts.u.cl->length)
207 gfc_se tmpse;
208 gfc_init_se (&tmpse, NULL);
209 gfc_conv_expr_type (&tmpse, e->ts.u.cl->length, gfc_charlen_type_node);
210 e->ts.u.cl->backend_decl = tmpse.expr;
211 return tmpse.expr;
214 /* First candidate: if the variable is of type CHARACTER, the
215 expression's length could be the length of the character
216 variable. */
217 if (e->symtree->n.sym->ts.type == BT_CHARACTER)
218 length = e->symtree->n.sym->ts.u.cl->backend_decl;
220 /* Look through the reference chain for component references. */
221 for (r = e->ref; r; r = r->next)
223 switch (r->type)
225 case REF_COMPONENT:
226 if (r->u.c.component->ts.type == BT_CHARACTER)
227 length = r->u.c.component->ts.u.cl->backend_decl;
228 break;
230 case REF_ARRAY:
231 /* Do nothing. */
232 break;
234 default:
235 /* We should never got substring references here. These will be
236 broken down by the scalarizer. */
237 gcc_unreachable ();
238 break;
242 gcc_assert (length != NULL);
243 return length;
247 /* For each character array constructor subexpression without a ts.u.cl->length,
248 replace it by its first element (if there aren't any elements, the length
249 should already be set to zero). */
251 static void
252 flatten_array_ctors_without_strlen (gfc_expr* e)
254 gfc_actual_arglist* arg;
255 gfc_constructor* c;
257 if (!e)
258 return;
260 switch (e->expr_type)
263 case EXPR_OP:
264 flatten_array_ctors_without_strlen (e->value.op.op1);
265 flatten_array_ctors_without_strlen (e->value.op.op2);
266 break;
268 case EXPR_COMPCALL:
269 /* TODO: Implement as with EXPR_FUNCTION when needed. */
270 gcc_unreachable ();
272 case EXPR_FUNCTION:
273 for (arg = e->value.function.actual; arg; arg = arg->next)
274 flatten_array_ctors_without_strlen (arg->expr);
275 break;
277 case EXPR_ARRAY:
279 /* We've found what we're looking for. */
280 if (e->ts.type == BT_CHARACTER && !e->ts.u.cl->length)
282 gfc_constructor *c;
283 gfc_expr* new_expr;
285 gcc_assert (e->value.constructor);
287 c = gfc_constructor_first (e->value.constructor);
288 new_expr = c->expr;
289 c->expr = NULL;
291 flatten_array_ctors_without_strlen (new_expr);
292 gfc_replace_expr (e, new_expr);
293 break;
296 /* Otherwise, fall through to handle constructor elements. */
297 case EXPR_STRUCTURE:
298 for (c = gfc_constructor_first (e->value.constructor);
299 c; c = gfc_constructor_next (c))
300 flatten_array_ctors_without_strlen (c->expr);
301 break;
303 default:
304 break;
310 /* Generate code to initialize a string length variable. Returns the
311 value. For array constructors, cl->length might be NULL and in this case,
312 the first element of the constructor is needed. expr is the original
313 expression so we can access it but can be NULL if this is not needed. */
315 void
316 gfc_conv_string_length (gfc_charlen * cl, gfc_expr * expr, stmtblock_t * pblock)
318 gfc_se se;
320 gfc_init_se (&se, NULL);
322 /* If cl->length is NULL, use gfc_conv_expr to obtain the string length but
323 "flatten" array constructors by taking their first element; all elements
324 should be the same length or a cl->length should be present. */
325 if (!cl->length)
327 gfc_expr* expr_flat;
328 gcc_assert (expr);
330 expr_flat = gfc_copy_expr (expr);
331 flatten_array_ctors_without_strlen (expr_flat);
332 gfc_resolve_expr (expr_flat);
334 gfc_conv_expr (&se, expr_flat);
335 gfc_add_block_to_block (pblock, &se.pre);
336 cl->backend_decl = convert (gfc_charlen_type_node, se.string_length);
338 gfc_free_expr (expr_flat);
339 return;
342 /* Convert cl->length. */
344 gcc_assert (cl->length);
346 gfc_conv_expr_type (&se, cl->length, gfc_charlen_type_node);
347 se.expr = fold_build2 (MAX_EXPR, gfc_charlen_type_node, se.expr,
348 build_int_cst (gfc_charlen_type_node, 0));
349 gfc_add_block_to_block (pblock, &se.pre);
351 if (cl->backend_decl)
352 gfc_add_modify (pblock, cl->backend_decl, se.expr);
353 else
354 cl->backend_decl = gfc_evaluate_now (se.expr, pblock);
358 static void
359 gfc_conv_substring (gfc_se * se, gfc_ref * ref, int kind,
360 const char *name, locus *where)
362 tree tmp;
363 tree type;
364 tree fault;
365 gfc_se start;
366 gfc_se end;
367 char *msg;
369 type = gfc_get_character_type (kind, ref->u.ss.length);
370 type = build_pointer_type (type);
372 gfc_init_se (&start, se);
373 gfc_conv_expr_type (&start, ref->u.ss.start, gfc_charlen_type_node);
374 gfc_add_block_to_block (&se->pre, &start.pre);
376 if (integer_onep (start.expr))
377 gfc_conv_string_parameter (se);
378 else
380 tmp = start.expr;
381 STRIP_NOPS (tmp);
382 /* Avoid multiple evaluation of substring start. */
383 if (!CONSTANT_CLASS_P (tmp) && !DECL_P (tmp))
384 start.expr = gfc_evaluate_now (start.expr, &se->pre);
386 /* Change the start of the string. */
387 if (TYPE_STRING_FLAG (TREE_TYPE (se->expr)))
388 tmp = se->expr;
389 else
390 tmp = build_fold_indirect_ref_loc (input_location,
391 se->expr);
392 tmp = gfc_build_array_ref (tmp, start.expr, NULL);
393 se->expr = gfc_build_addr_expr (type, tmp);
396 /* Length = end + 1 - start. */
397 gfc_init_se (&end, se);
398 if (ref->u.ss.end == NULL)
399 end.expr = se->string_length;
400 else
402 gfc_conv_expr_type (&end, ref->u.ss.end, gfc_charlen_type_node);
403 gfc_add_block_to_block (&se->pre, &end.pre);
405 tmp = end.expr;
406 STRIP_NOPS (tmp);
407 if (!CONSTANT_CLASS_P (tmp) && !DECL_P (tmp))
408 end.expr = gfc_evaluate_now (end.expr, &se->pre);
410 if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
412 tree nonempty = fold_build2 (LE_EXPR, boolean_type_node,
413 start.expr, end.expr);
415 /* Check lower bound. */
416 fault = fold_build2 (LT_EXPR, boolean_type_node, start.expr,
417 build_int_cst (gfc_charlen_type_node, 1));
418 fault = fold_build2 (TRUTH_ANDIF_EXPR, boolean_type_node,
419 nonempty, fault);
420 if (name)
421 asprintf (&msg, "Substring out of bounds: lower bound (%%ld) of '%s' "
422 "is less than one", name);
423 else
424 asprintf (&msg, "Substring out of bounds: lower bound (%%ld)"
425 "is less than one");
426 gfc_trans_runtime_check (true, false, fault, &se->pre, where, msg,
427 fold_convert (long_integer_type_node,
428 start.expr));
429 gfc_free (msg);
431 /* Check upper bound. */
432 fault = fold_build2 (GT_EXPR, boolean_type_node, end.expr,
433 se->string_length);
434 fault = fold_build2 (TRUTH_ANDIF_EXPR, boolean_type_node,
435 nonempty, fault);
436 if (name)
437 asprintf (&msg, "Substring out of bounds: upper bound (%%ld) of '%s' "
438 "exceeds string length (%%ld)", name);
439 else
440 asprintf (&msg, "Substring out of bounds: upper bound (%%ld) "
441 "exceeds string length (%%ld)");
442 gfc_trans_runtime_check (true, false, fault, &se->pre, where, msg,
443 fold_convert (long_integer_type_node, end.expr),
444 fold_convert (long_integer_type_node,
445 se->string_length));
446 gfc_free (msg);
449 tmp = fold_build2 (MINUS_EXPR, gfc_charlen_type_node,
450 end.expr, start.expr);
451 tmp = fold_build2 (PLUS_EXPR, gfc_charlen_type_node,
452 build_int_cst (gfc_charlen_type_node, 1), tmp);
453 tmp = fold_build2 (MAX_EXPR, gfc_charlen_type_node, tmp,
454 build_int_cst (gfc_charlen_type_node, 0));
455 se->string_length = tmp;
459 /* Convert a derived type component reference. */
461 static void
462 gfc_conv_component_ref (gfc_se * se, gfc_ref * ref)
464 gfc_component *c;
465 tree tmp;
466 tree decl;
467 tree field;
469 c = ref->u.c.component;
471 gcc_assert (c->backend_decl);
473 field = c->backend_decl;
474 gcc_assert (TREE_CODE (field) == FIELD_DECL);
475 decl = se->expr;
476 tmp = fold_build3 (COMPONENT_REF, TREE_TYPE (field), decl, field, NULL_TREE);
478 se->expr = tmp;
480 if (c->ts.type == BT_CHARACTER && !c->attr.proc_pointer)
482 tmp = c->ts.u.cl->backend_decl;
483 /* Components must always be constant length. */
484 gcc_assert (tmp && INTEGER_CST_P (tmp));
485 se->string_length = tmp;
488 if (((c->attr.pointer || c->attr.allocatable) && c->attr.dimension == 0
489 && c->ts.type != BT_CHARACTER)
490 || c->attr.proc_pointer)
491 se->expr = build_fold_indirect_ref_loc (input_location,
492 se->expr);
496 /* This function deals with component references to components of the
497 parent type for derived type extensons. */
498 static void
499 conv_parent_component_references (gfc_se * se, gfc_ref * ref)
501 gfc_component *c;
502 gfc_component *cmp;
503 gfc_symbol *dt;
504 gfc_ref parent;
506 dt = ref->u.c.sym;
507 c = ref->u.c.component;
509 /* Build a gfc_ref to recursively call gfc_conv_component_ref. */
510 parent.type = REF_COMPONENT;
511 parent.next = NULL;
512 parent.u.c.sym = dt;
513 parent.u.c.component = dt->components;
515 if (dt->backend_decl == NULL)
516 gfc_get_derived_type (dt);
518 if (dt->attr.extension && dt->components)
520 if (dt->attr.is_class)
521 cmp = dt->components;
522 else
523 cmp = dt->components->next;
524 /* Return if the component is not in the parent type. */
525 for (; cmp; cmp = cmp->next)
526 if (strcmp (c->name, cmp->name) == 0)
527 return;
529 /* Otherwise build the reference and call self. */
530 gfc_conv_component_ref (se, &parent);
531 parent.u.c.sym = dt->components->ts.u.derived;
532 parent.u.c.component = c;
533 conv_parent_component_references (se, &parent);
537 /* Return the contents of a variable. Also handles reference/pointer
538 variables (all Fortran pointer references are implicit). */
540 static void
541 gfc_conv_variable (gfc_se * se, gfc_expr * expr)
543 gfc_ref *ref;
544 gfc_symbol *sym;
545 tree parent_decl;
546 int parent_flag;
547 bool return_value;
548 bool alternate_entry;
549 bool entry_master;
551 sym = expr->symtree->n.sym;
552 if (se->ss != NULL)
554 /* Check that something hasn't gone horribly wrong. */
555 gcc_assert (se->ss != gfc_ss_terminator);
556 gcc_assert (se->ss->expr == expr);
558 /* A scalarized term. We already know the descriptor. */
559 se->expr = se->ss->data.info.descriptor;
560 se->string_length = se->ss->string_length;
561 for (ref = se->ss->data.info.ref; ref; ref = ref->next)
562 if (ref->type == REF_ARRAY && ref->u.ar.type != AR_ELEMENT)
563 break;
565 else
567 tree se_expr = NULL_TREE;
569 se->expr = gfc_get_symbol_decl (sym);
571 /* Deal with references to a parent results or entries by storing
572 the current_function_decl and moving to the parent_decl. */
573 return_value = sym->attr.function && sym->result == sym;
574 alternate_entry = sym->attr.function && sym->attr.entry
575 && sym->result == sym;
576 entry_master = sym->attr.result
577 && sym->ns->proc_name->attr.entry_master
578 && !gfc_return_by_reference (sym->ns->proc_name);
579 parent_decl = DECL_CONTEXT (current_function_decl);
581 if ((se->expr == parent_decl && return_value)
582 || (sym->ns && sym->ns->proc_name
583 && parent_decl
584 && sym->ns->proc_name->backend_decl == parent_decl
585 && (alternate_entry || entry_master)))
586 parent_flag = 1;
587 else
588 parent_flag = 0;
590 /* Special case for assigning the return value of a function.
591 Self recursive functions must have an explicit return value. */
592 if (return_value && (se->expr == current_function_decl || parent_flag))
593 se_expr = gfc_get_fake_result_decl (sym, parent_flag);
595 /* Similarly for alternate entry points. */
596 else if (alternate_entry
597 && (sym->ns->proc_name->backend_decl == current_function_decl
598 || parent_flag))
600 gfc_entry_list *el = NULL;
602 for (el = sym->ns->entries; el; el = el->next)
603 if (sym == el->sym)
605 se_expr = gfc_get_fake_result_decl (sym, parent_flag);
606 break;
610 else if (entry_master
611 && (sym->ns->proc_name->backend_decl == current_function_decl
612 || parent_flag))
613 se_expr = gfc_get_fake_result_decl (sym, parent_flag);
615 if (se_expr)
616 se->expr = se_expr;
618 /* Procedure actual arguments. */
619 else if (sym->attr.flavor == FL_PROCEDURE
620 && se->expr != current_function_decl)
622 if (!sym->attr.dummy && !sym->attr.proc_pointer)
624 gcc_assert (TREE_CODE (se->expr) == FUNCTION_DECL);
625 se->expr = gfc_build_addr_expr (NULL_TREE, se->expr);
627 return;
631 /* Dereference the expression, where needed. Since characters
632 are entirely different from other types, they are treated
633 separately. */
634 if (sym->ts.type == BT_CHARACTER)
636 /* Dereference character pointer dummy arguments
637 or results. */
638 if ((sym->attr.pointer || sym->attr.allocatable)
639 && (sym->attr.dummy
640 || sym->attr.function
641 || sym->attr.result))
642 se->expr = build_fold_indirect_ref_loc (input_location,
643 se->expr);
646 else if (!sym->attr.value)
648 /* Dereference non-character scalar dummy arguments. */
649 if (sym->attr.dummy && !sym->attr.dimension)
650 se->expr = build_fold_indirect_ref_loc (input_location,
651 se->expr);
653 /* Dereference scalar hidden result. */
654 if (gfc_option.flag_f2c && sym->ts.type == BT_COMPLEX
655 && (sym->attr.function || sym->attr.result)
656 && !sym->attr.dimension && !sym->attr.pointer
657 && !sym->attr.always_explicit)
658 se->expr = build_fold_indirect_ref_loc (input_location,
659 se->expr);
661 /* Dereference non-character pointer variables.
662 These must be dummies, results, or scalars. */
663 if ((sym->attr.pointer || sym->attr.allocatable)
664 && (sym->attr.dummy
665 || sym->attr.function
666 || sym->attr.result
667 || !sym->attr.dimension))
668 se->expr = build_fold_indirect_ref_loc (input_location,
669 se->expr);
672 ref = expr->ref;
675 /* For character variables, also get the length. */
676 if (sym->ts.type == BT_CHARACTER)
678 /* If the character length of an entry isn't set, get the length from
679 the master function instead. */
680 if (sym->attr.entry && !sym->ts.u.cl->backend_decl)
681 se->string_length = sym->ns->proc_name->ts.u.cl->backend_decl;
682 else
683 se->string_length = sym->ts.u.cl->backend_decl;
684 gcc_assert (se->string_length);
687 while (ref)
689 switch (ref->type)
691 case REF_ARRAY:
692 /* Return the descriptor if that's what we want and this is an array
693 section reference. */
694 if (se->descriptor_only && ref->u.ar.type != AR_ELEMENT)
695 return;
696 /* TODO: Pointers to single elements of array sections, eg elemental subs. */
697 /* Return the descriptor for array pointers and allocations. */
698 if (se->want_pointer
699 && ref->next == NULL && (se->descriptor_only))
700 return;
702 gfc_conv_array_ref (se, &ref->u.ar, sym, &expr->where);
703 /* Return a pointer to an element. */
704 break;
706 case REF_COMPONENT:
707 if (ref->u.c.sym->attr.extension)
708 conv_parent_component_references (se, ref);
710 gfc_conv_component_ref (se, ref);
711 break;
713 case REF_SUBSTRING:
714 gfc_conv_substring (se, ref, expr->ts.kind,
715 expr->symtree->name, &expr->where);
716 break;
718 default:
719 gcc_unreachable ();
720 break;
722 ref = ref->next;
724 /* Pointer assignment, allocation or pass by reference. Arrays are handled
725 separately. */
726 if (se->want_pointer)
728 if (expr->ts.type == BT_CHARACTER && !gfc_is_proc_ptr_comp (expr, NULL))
729 gfc_conv_string_parameter (se);
730 else
731 se->expr = gfc_build_addr_expr (NULL_TREE, se->expr);
736 /* Unary ops are easy... Or they would be if ! was a valid op. */
738 static void
739 gfc_conv_unary_op (enum tree_code code, gfc_se * se, gfc_expr * expr)
741 gfc_se operand;
742 tree type;
744 gcc_assert (expr->ts.type != BT_CHARACTER);
745 /* Initialize the operand. */
746 gfc_init_se (&operand, se);
747 gfc_conv_expr_val (&operand, expr->value.op.op1);
748 gfc_add_block_to_block (&se->pre, &operand.pre);
750 type = gfc_typenode_for_spec (&expr->ts);
752 /* TRUTH_NOT_EXPR is not a "true" unary operator in GCC.
753 We must convert it to a compare to 0 (e.g. EQ_EXPR (op1, 0)).
754 All other unary operators have an equivalent GIMPLE unary operator. */
755 if (code == TRUTH_NOT_EXPR)
756 se->expr = fold_build2 (EQ_EXPR, type, operand.expr,
757 build_int_cst (type, 0));
758 else
759 se->expr = fold_build1 (code, type, operand.expr);
763 /* Expand power operator to optimal multiplications when a value is raised
764 to a constant integer n. See section 4.6.3, "Evaluation of Powers" of
765 Donald E. Knuth, "Seminumerical Algorithms", Vol. 2, "The Art of Computer
766 Programming", 3rd Edition, 1998. */
768 /* This code is mostly duplicated from expand_powi in the backend.
769 We establish the "optimal power tree" lookup table with the defined size.
770 The items in the table are the exponents used to calculate the index
771 exponents. Any integer n less than the value can get an "addition chain",
772 with the first node being one. */
773 #define POWI_TABLE_SIZE 256
775 /* The table is from builtins.c. */
776 static const unsigned char powi_table[POWI_TABLE_SIZE] =
778 0, 1, 1, 2, 2, 3, 3, 4, /* 0 - 7 */
779 4, 6, 5, 6, 6, 10, 7, 9, /* 8 - 15 */
780 8, 16, 9, 16, 10, 12, 11, 13, /* 16 - 23 */
781 12, 17, 13, 18, 14, 24, 15, 26, /* 24 - 31 */
782 16, 17, 17, 19, 18, 33, 19, 26, /* 32 - 39 */
783 20, 25, 21, 40, 22, 27, 23, 44, /* 40 - 47 */
784 24, 32, 25, 34, 26, 29, 27, 44, /* 48 - 55 */
785 28, 31, 29, 34, 30, 60, 31, 36, /* 56 - 63 */
786 32, 64, 33, 34, 34, 46, 35, 37, /* 64 - 71 */
787 36, 65, 37, 50, 38, 48, 39, 69, /* 72 - 79 */
788 40, 49, 41, 43, 42, 51, 43, 58, /* 80 - 87 */
789 44, 64, 45, 47, 46, 59, 47, 76, /* 88 - 95 */
790 48, 65, 49, 66, 50, 67, 51, 66, /* 96 - 103 */
791 52, 70, 53, 74, 54, 104, 55, 74, /* 104 - 111 */
792 56, 64, 57, 69, 58, 78, 59, 68, /* 112 - 119 */
793 60, 61, 61, 80, 62, 75, 63, 68, /* 120 - 127 */
794 64, 65, 65, 128, 66, 129, 67, 90, /* 128 - 135 */
795 68, 73, 69, 131, 70, 94, 71, 88, /* 136 - 143 */
796 72, 128, 73, 98, 74, 132, 75, 121, /* 144 - 151 */
797 76, 102, 77, 124, 78, 132, 79, 106, /* 152 - 159 */
798 80, 97, 81, 160, 82, 99, 83, 134, /* 160 - 167 */
799 84, 86, 85, 95, 86, 160, 87, 100, /* 168 - 175 */
800 88, 113, 89, 98, 90, 107, 91, 122, /* 176 - 183 */
801 92, 111, 93, 102, 94, 126, 95, 150, /* 184 - 191 */
802 96, 128, 97, 130, 98, 133, 99, 195, /* 192 - 199 */
803 100, 128, 101, 123, 102, 164, 103, 138, /* 200 - 207 */
804 104, 145, 105, 146, 106, 109, 107, 149, /* 208 - 215 */
805 108, 200, 109, 146, 110, 170, 111, 157, /* 216 - 223 */
806 112, 128, 113, 130, 114, 182, 115, 132, /* 224 - 231 */
807 116, 200, 117, 132, 118, 158, 119, 206, /* 232 - 239 */
808 120, 240, 121, 162, 122, 147, 123, 152, /* 240 - 247 */
809 124, 166, 125, 214, 126, 138, 127, 153, /* 248 - 255 */
812 /* If n is larger than lookup table's max index, we use the "window
813 method". */
814 #define POWI_WINDOW_SIZE 3
816 /* Recursive function to expand the power operator. The temporary
817 values are put in tmpvar. The function returns tmpvar[1] ** n. */
818 static tree
819 gfc_conv_powi (gfc_se * se, unsigned HOST_WIDE_INT n, tree * tmpvar)
821 tree op0;
822 tree op1;
823 tree tmp;
824 int digit;
826 if (n < POWI_TABLE_SIZE)
828 if (tmpvar[n])
829 return tmpvar[n];
831 op0 = gfc_conv_powi (se, n - powi_table[n], tmpvar);
832 op1 = gfc_conv_powi (se, powi_table[n], tmpvar);
834 else if (n & 1)
836 digit = n & ((1 << POWI_WINDOW_SIZE) - 1);
837 op0 = gfc_conv_powi (se, n - digit, tmpvar);
838 op1 = gfc_conv_powi (se, digit, tmpvar);
840 else
842 op0 = gfc_conv_powi (se, n >> 1, tmpvar);
843 op1 = op0;
846 tmp = fold_build2 (MULT_EXPR, TREE_TYPE (op0), op0, op1);
847 tmp = gfc_evaluate_now (tmp, &se->pre);
849 if (n < POWI_TABLE_SIZE)
850 tmpvar[n] = tmp;
852 return tmp;
856 /* Expand lhs ** rhs. rhs is a constant integer. If it expands successfully,
857 return 1. Else return 0 and a call to runtime library functions
858 will have to be built. */
859 static int
860 gfc_conv_cst_int_power (gfc_se * se, tree lhs, tree rhs)
862 tree cond;
863 tree tmp;
864 tree type;
865 tree vartmp[POWI_TABLE_SIZE];
866 HOST_WIDE_INT m;
867 unsigned HOST_WIDE_INT n;
868 int sgn;
870 /* If exponent is too large, we won't expand it anyway, so don't bother
871 with large integer values. */
872 if (!double_int_fits_in_shwi_p (TREE_INT_CST (rhs)))
873 return 0;
875 m = double_int_to_shwi (TREE_INT_CST (rhs));
876 /* There's no ABS for HOST_WIDE_INT, so here we go. It also takes care
877 of the asymmetric range of the integer type. */
878 n = (unsigned HOST_WIDE_INT) (m < 0 ? -m : m);
880 type = TREE_TYPE (lhs);
881 sgn = tree_int_cst_sgn (rhs);
883 if (((FLOAT_TYPE_P (type) && !flag_unsafe_math_optimizations)
884 || optimize_size) && (m > 2 || m < -1))
885 return 0;
887 /* rhs == 0 */
888 if (sgn == 0)
890 se->expr = gfc_build_const (type, integer_one_node);
891 return 1;
894 /* If rhs < 0 and lhs is an integer, the result is -1, 0 or 1. */
895 if ((sgn == -1) && (TREE_CODE (type) == INTEGER_TYPE))
897 tmp = fold_build2 (EQ_EXPR, boolean_type_node,
898 lhs, build_int_cst (TREE_TYPE (lhs), -1));
899 cond = fold_build2 (EQ_EXPR, boolean_type_node,
900 lhs, build_int_cst (TREE_TYPE (lhs), 1));
902 /* If rhs is even,
903 result = (lhs == 1 || lhs == -1) ? 1 : 0. */
904 if ((n & 1) == 0)
906 tmp = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, tmp, cond);
907 se->expr = fold_build3 (COND_EXPR, type,
908 tmp, build_int_cst (type, 1),
909 build_int_cst (type, 0));
910 return 1;
912 /* If rhs is odd,
913 result = (lhs == 1) ? 1 : (lhs == -1) ? -1 : 0. */
914 tmp = fold_build3 (COND_EXPR, type, tmp, build_int_cst (type, -1),
915 build_int_cst (type, 0));
916 se->expr = fold_build3 (COND_EXPR, type,
917 cond, build_int_cst (type, 1), tmp);
918 return 1;
921 memset (vartmp, 0, sizeof (vartmp));
922 vartmp[1] = lhs;
923 if (sgn == -1)
925 tmp = gfc_build_const (type, integer_one_node);
926 vartmp[1] = fold_build2 (RDIV_EXPR, type, tmp, vartmp[1]);
929 se->expr = gfc_conv_powi (se, n, vartmp);
931 return 1;
935 /* Power op (**). Constant integer exponent has special handling. */
937 static void
938 gfc_conv_power_op (gfc_se * se, gfc_expr * expr)
940 tree gfc_int4_type_node;
941 int kind;
942 int ikind;
943 gfc_se lse;
944 gfc_se rse;
945 tree fndecl;
947 gfc_init_se (&lse, se);
948 gfc_conv_expr_val (&lse, expr->value.op.op1);
949 lse.expr = gfc_evaluate_now (lse.expr, &lse.pre);
950 gfc_add_block_to_block (&se->pre, &lse.pre);
952 gfc_init_se (&rse, se);
953 gfc_conv_expr_val (&rse, expr->value.op.op2);
954 gfc_add_block_to_block (&se->pre, &rse.pre);
956 if (expr->value.op.op2->ts.type == BT_INTEGER
957 && expr->value.op.op2->expr_type == EXPR_CONSTANT)
958 if (gfc_conv_cst_int_power (se, lse.expr, rse.expr))
959 return;
961 gfc_int4_type_node = gfc_get_int_type (4);
963 kind = expr->value.op.op1->ts.kind;
964 switch (expr->value.op.op2->ts.type)
966 case BT_INTEGER:
967 ikind = expr->value.op.op2->ts.kind;
968 switch (ikind)
970 case 1:
971 case 2:
972 rse.expr = convert (gfc_int4_type_node, rse.expr);
973 /* Fall through. */
975 case 4:
976 ikind = 0;
977 break;
979 case 8:
980 ikind = 1;
981 break;
983 case 16:
984 ikind = 2;
985 break;
987 default:
988 gcc_unreachable ();
990 switch (kind)
992 case 1:
993 case 2:
994 if (expr->value.op.op1->ts.type == BT_INTEGER)
995 lse.expr = convert (gfc_int4_type_node, lse.expr);
996 else
997 gcc_unreachable ();
998 /* Fall through. */
1000 case 4:
1001 kind = 0;
1002 break;
1004 case 8:
1005 kind = 1;
1006 break;
1008 case 10:
1009 kind = 2;
1010 break;
1012 case 16:
1013 kind = 3;
1014 break;
1016 default:
1017 gcc_unreachable ();
1020 switch (expr->value.op.op1->ts.type)
1022 case BT_INTEGER:
1023 if (kind == 3) /* Case 16 was not handled properly above. */
1024 kind = 2;
1025 fndecl = gfor_fndecl_math_powi[kind][ikind].integer;
1026 break;
1028 case BT_REAL:
1029 /* Use builtins for real ** int4. */
1030 if (ikind == 0)
1032 switch (kind)
1034 case 0:
1035 fndecl = built_in_decls[BUILT_IN_POWIF];
1036 break;
1038 case 1:
1039 fndecl = built_in_decls[BUILT_IN_POWI];
1040 break;
1042 case 2:
1043 case 3:
1044 fndecl = built_in_decls[BUILT_IN_POWIL];
1045 break;
1047 default:
1048 gcc_unreachable ();
1051 else
1052 fndecl = gfor_fndecl_math_powi[kind][ikind].real;
1053 break;
1055 case BT_COMPLEX:
1056 fndecl = gfor_fndecl_math_powi[kind][ikind].cmplx;
1057 break;
1059 default:
1060 gcc_unreachable ();
1062 break;
1064 case BT_REAL:
1065 switch (kind)
1067 case 4:
1068 fndecl = built_in_decls[BUILT_IN_POWF];
1069 break;
1070 case 8:
1071 fndecl = built_in_decls[BUILT_IN_POW];
1072 break;
1073 case 10:
1074 case 16:
1075 fndecl = built_in_decls[BUILT_IN_POWL];
1076 break;
1077 default:
1078 gcc_unreachable ();
1080 break;
1082 case BT_COMPLEX:
1083 switch (kind)
1085 case 4:
1086 fndecl = built_in_decls[BUILT_IN_CPOWF];
1087 break;
1088 case 8:
1089 fndecl = built_in_decls[BUILT_IN_CPOW];
1090 break;
1091 case 10:
1092 case 16:
1093 fndecl = built_in_decls[BUILT_IN_CPOWL];
1094 break;
1095 default:
1096 gcc_unreachable ();
1098 break;
1100 default:
1101 gcc_unreachable ();
1102 break;
1105 se->expr = build_call_expr_loc (input_location,
1106 fndecl, 2, lse.expr, rse.expr);
1110 /* Generate code to allocate a string temporary. */
1112 tree
1113 gfc_conv_string_tmp (gfc_se * se, tree type, tree len)
1115 tree var;
1116 tree tmp;
1118 gcc_assert (types_compatible_p (TREE_TYPE (len), gfc_charlen_type_node));
1120 if (gfc_can_put_var_on_stack (len))
1122 /* Create a temporary variable to hold the result. */
1123 tmp = fold_build2 (MINUS_EXPR, gfc_charlen_type_node, len,
1124 build_int_cst (gfc_charlen_type_node, 1));
1125 tmp = build_range_type (gfc_array_index_type, gfc_index_zero_node, tmp);
1127 if (TREE_CODE (TREE_TYPE (type)) == ARRAY_TYPE)
1128 tmp = build_array_type (TREE_TYPE (TREE_TYPE (type)), tmp);
1129 else
1130 tmp = build_array_type (TREE_TYPE (type), tmp);
1132 var = gfc_create_var (tmp, "str");
1133 var = gfc_build_addr_expr (type, var);
1135 else
1137 /* Allocate a temporary to hold the result. */
1138 var = gfc_create_var (type, "pstr");
1139 tmp = gfc_call_malloc (&se->pre, type,
1140 fold_build2 (MULT_EXPR, TREE_TYPE (len), len,
1141 fold_convert (TREE_TYPE (len),
1142 TYPE_SIZE (type))));
1143 gfc_add_modify (&se->pre, var, tmp);
1145 /* Free the temporary afterwards. */
1146 tmp = gfc_call_free (convert (pvoid_type_node, var));
1147 gfc_add_expr_to_block (&se->post, tmp);
1150 return var;
1154 /* Handle a string concatenation operation. A temporary will be allocated to
1155 hold the result. */
1157 static void
1158 gfc_conv_concat_op (gfc_se * se, gfc_expr * expr)
1160 gfc_se lse, rse;
1161 tree len, type, var, tmp, fndecl;
1163 gcc_assert (expr->value.op.op1->ts.type == BT_CHARACTER
1164 && expr->value.op.op2->ts.type == BT_CHARACTER);
1165 gcc_assert (expr->value.op.op1->ts.kind == expr->value.op.op2->ts.kind);
1167 gfc_init_se (&lse, se);
1168 gfc_conv_expr (&lse, expr->value.op.op1);
1169 gfc_conv_string_parameter (&lse);
1170 gfc_init_se (&rse, se);
1171 gfc_conv_expr (&rse, expr->value.op.op2);
1172 gfc_conv_string_parameter (&rse);
1174 gfc_add_block_to_block (&se->pre, &lse.pre);
1175 gfc_add_block_to_block (&se->pre, &rse.pre);
1177 type = gfc_get_character_type (expr->ts.kind, expr->ts.u.cl);
1178 len = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
1179 if (len == NULL_TREE)
1181 len = fold_build2 (PLUS_EXPR, TREE_TYPE (lse.string_length),
1182 lse.string_length, rse.string_length);
1185 type = build_pointer_type (type);
1187 var = gfc_conv_string_tmp (se, type, len);
1189 /* Do the actual concatenation. */
1190 if (expr->ts.kind == 1)
1191 fndecl = gfor_fndecl_concat_string;
1192 else if (expr->ts.kind == 4)
1193 fndecl = gfor_fndecl_concat_string_char4;
1194 else
1195 gcc_unreachable ();
1197 tmp = build_call_expr_loc (input_location,
1198 fndecl, 6, len, var, lse.string_length, lse.expr,
1199 rse.string_length, rse.expr);
1200 gfc_add_expr_to_block (&se->pre, tmp);
1202 /* Add the cleanup for the operands. */
1203 gfc_add_block_to_block (&se->pre, &rse.post);
1204 gfc_add_block_to_block (&se->pre, &lse.post);
1206 se->expr = var;
1207 se->string_length = len;
1210 /* Translates an op expression. Common (binary) cases are handled by this
1211 function, others are passed on. Recursion is used in either case.
1212 We use the fact that (op1.ts == op2.ts) (except for the power
1213 operator **).
1214 Operators need no special handling for scalarized expressions as long as
1215 they call gfc_conv_simple_val to get their operands.
1216 Character strings get special handling. */
1218 static void
1219 gfc_conv_expr_op (gfc_se * se, gfc_expr * expr)
1221 enum tree_code code;
1222 gfc_se lse;
1223 gfc_se rse;
1224 tree tmp, type;
1225 int lop;
1226 int checkstring;
1228 checkstring = 0;
1229 lop = 0;
1230 switch (expr->value.op.op)
1232 case INTRINSIC_PARENTHESES:
1233 if ((expr->ts.type == BT_REAL
1234 || expr->ts.type == BT_COMPLEX)
1235 && gfc_option.flag_protect_parens)
1237 gfc_conv_unary_op (PAREN_EXPR, se, expr);
1238 gcc_assert (FLOAT_TYPE_P (TREE_TYPE (se->expr)));
1239 return;
1242 /* Fallthrough. */
1243 case INTRINSIC_UPLUS:
1244 gfc_conv_expr (se, expr->value.op.op1);
1245 return;
1247 case INTRINSIC_UMINUS:
1248 gfc_conv_unary_op (NEGATE_EXPR, se, expr);
1249 return;
1251 case INTRINSIC_NOT:
1252 gfc_conv_unary_op (TRUTH_NOT_EXPR, se, expr);
1253 return;
1255 case INTRINSIC_PLUS:
1256 code = PLUS_EXPR;
1257 break;
1259 case INTRINSIC_MINUS:
1260 code = MINUS_EXPR;
1261 break;
1263 case INTRINSIC_TIMES:
1264 code = MULT_EXPR;
1265 break;
1267 case INTRINSIC_DIVIDE:
1268 /* If expr is a real or complex expr, use an RDIV_EXPR. If op1 is
1269 an integer, we must round towards zero, so we use a
1270 TRUNC_DIV_EXPR. */
1271 if (expr->ts.type == BT_INTEGER)
1272 code = TRUNC_DIV_EXPR;
1273 else
1274 code = RDIV_EXPR;
1275 break;
1277 case INTRINSIC_POWER:
1278 gfc_conv_power_op (se, expr);
1279 return;
1281 case INTRINSIC_CONCAT:
1282 gfc_conv_concat_op (se, expr);
1283 return;
1285 case INTRINSIC_AND:
1286 code = TRUTH_ANDIF_EXPR;
1287 lop = 1;
1288 break;
1290 case INTRINSIC_OR:
1291 code = TRUTH_ORIF_EXPR;
1292 lop = 1;
1293 break;
1295 /* EQV and NEQV only work on logicals, but since we represent them
1296 as integers, we can use EQ_EXPR and NE_EXPR for them in GIMPLE. */
1297 case INTRINSIC_EQ:
1298 case INTRINSIC_EQ_OS:
1299 case INTRINSIC_EQV:
1300 code = EQ_EXPR;
1301 checkstring = 1;
1302 lop = 1;
1303 break;
1305 case INTRINSIC_NE:
1306 case INTRINSIC_NE_OS:
1307 case INTRINSIC_NEQV:
1308 code = NE_EXPR;
1309 checkstring = 1;
1310 lop = 1;
1311 break;
1313 case INTRINSIC_GT:
1314 case INTRINSIC_GT_OS:
1315 code = GT_EXPR;
1316 checkstring = 1;
1317 lop = 1;
1318 break;
1320 case INTRINSIC_GE:
1321 case INTRINSIC_GE_OS:
1322 code = GE_EXPR;
1323 checkstring = 1;
1324 lop = 1;
1325 break;
1327 case INTRINSIC_LT:
1328 case INTRINSIC_LT_OS:
1329 code = LT_EXPR;
1330 checkstring = 1;
1331 lop = 1;
1332 break;
1334 case INTRINSIC_LE:
1335 case INTRINSIC_LE_OS:
1336 code = LE_EXPR;
1337 checkstring = 1;
1338 lop = 1;
1339 break;
1341 case INTRINSIC_USER:
1342 case INTRINSIC_ASSIGN:
1343 /* These should be converted into function calls by the frontend. */
1344 gcc_unreachable ();
1346 default:
1347 fatal_error ("Unknown intrinsic op");
1348 return;
1351 /* The only exception to this is **, which is handled separately anyway. */
1352 gcc_assert (expr->value.op.op1->ts.type == expr->value.op.op2->ts.type);
1354 if (checkstring && expr->value.op.op1->ts.type != BT_CHARACTER)
1355 checkstring = 0;
1357 /* lhs */
1358 gfc_init_se (&lse, se);
1359 gfc_conv_expr (&lse, expr->value.op.op1);
1360 gfc_add_block_to_block (&se->pre, &lse.pre);
1362 /* rhs */
1363 gfc_init_se (&rse, se);
1364 gfc_conv_expr (&rse, expr->value.op.op2);
1365 gfc_add_block_to_block (&se->pre, &rse.pre);
1367 if (checkstring)
1369 gfc_conv_string_parameter (&lse);
1370 gfc_conv_string_parameter (&rse);
1372 lse.expr = gfc_build_compare_string (lse.string_length, lse.expr,
1373 rse.string_length, rse.expr,
1374 expr->value.op.op1->ts.kind);
1375 rse.expr = build_int_cst (TREE_TYPE (lse.expr), 0);
1376 gfc_add_block_to_block (&lse.post, &rse.post);
1379 type = gfc_typenode_for_spec (&expr->ts);
1381 if (lop)
1383 /* The result of logical ops is always boolean_type_node. */
1384 tmp = fold_build2 (code, boolean_type_node, lse.expr, rse.expr);
1385 se->expr = convert (type, tmp);
1387 else
1388 se->expr = fold_build2 (code, type, lse.expr, rse.expr);
1390 /* Add the post blocks. */
1391 gfc_add_block_to_block (&se->post, &rse.post);
1392 gfc_add_block_to_block (&se->post, &lse.post);
1395 /* If a string's length is one, we convert it to a single character. */
1397 static tree
1398 string_to_single_character (tree len, tree str, int kind)
1400 gcc_assert (POINTER_TYPE_P (TREE_TYPE (str)));
1402 if (INTEGER_CST_P (len) && TREE_INT_CST_LOW (len) == 1
1403 && TREE_INT_CST_HIGH (len) == 0)
1405 str = fold_convert (gfc_get_pchar_type (kind), str);
1406 return build_fold_indirect_ref_loc (input_location,
1407 str);
1410 return NULL_TREE;
1414 void
1415 gfc_conv_scalar_char_value (gfc_symbol *sym, gfc_se *se, gfc_expr **expr)
1418 if (sym->backend_decl)
1420 /* This becomes the nominal_type in
1421 function.c:assign_parm_find_data_types. */
1422 TREE_TYPE (sym->backend_decl) = unsigned_char_type_node;
1423 /* This becomes the passed_type in
1424 function.c:assign_parm_find_data_types. C promotes char to
1425 integer for argument passing. */
1426 DECL_ARG_TYPE (sym->backend_decl) = unsigned_type_node;
1428 DECL_BY_REFERENCE (sym->backend_decl) = 0;
1431 if (expr != NULL)
1433 /* If we have a constant character expression, make it into an
1434 integer. */
1435 if ((*expr)->expr_type == EXPR_CONSTANT)
1437 gfc_typespec ts;
1438 gfc_clear_ts (&ts);
1440 *expr = gfc_get_int_expr (gfc_default_integer_kind, NULL,
1441 (int)(*expr)->value.character.string[0]);
1442 if ((*expr)->ts.kind != gfc_c_int_kind)
1444 /* The expr needs to be compatible with a C int. If the
1445 conversion fails, then the 2 causes an ICE. */
1446 ts.type = BT_INTEGER;
1447 ts.kind = gfc_c_int_kind;
1448 gfc_convert_type (*expr, &ts, 2);
1451 else if (se != NULL && (*expr)->expr_type == EXPR_VARIABLE)
1453 if ((*expr)->ref == NULL)
1455 se->expr = string_to_single_character
1456 (build_int_cst (integer_type_node, 1),
1457 gfc_build_addr_expr (gfc_get_pchar_type ((*expr)->ts.kind),
1458 gfc_get_symbol_decl
1459 ((*expr)->symtree->n.sym)),
1460 (*expr)->ts.kind);
1462 else
1464 gfc_conv_variable (se, *expr);
1465 se->expr = string_to_single_character
1466 (build_int_cst (integer_type_node, 1),
1467 gfc_build_addr_expr (gfc_get_pchar_type ((*expr)->ts.kind),
1468 se->expr),
1469 (*expr)->ts.kind);
1476 /* Compare two strings. If they are all single characters, the result is the
1477 subtraction of them. Otherwise, we build a library call. */
1479 tree
1480 gfc_build_compare_string (tree len1, tree str1, tree len2, tree str2, int kind)
1482 tree sc1;
1483 tree sc2;
1484 tree tmp;
1486 gcc_assert (POINTER_TYPE_P (TREE_TYPE (str1)));
1487 gcc_assert (POINTER_TYPE_P (TREE_TYPE (str2)));
1489 sc1 = string_to_single_character (len1, str1, kind);
1490 sc2 = string_to_single_character (len2, str2, kind);
1492 if (sc1 != NULL_TREE && sc2 != NULL_TREE)
1494 /* Deal with single character specially. */
1495 sc1 = fold_convert (integer_type_node, sc1);
1496 sc2 = fold_convert (integer_type_node, sc2);
1497 tmp = fold_build2 (MINUS_EXPR, integer_type_node, sc1, sc2);
1499 else
1501 /* Build a call for the comparison. */
1502 tree fndecl;
1504 if (kind == 1)
1505 fndecl = gfor_fndecl_compare_string;
1506 else if (kind == 4)
1507 fndecl = gfor_fndecl_compare_string_char4;
1508 else
1509 gcc_unreachable ();
1511 tmp = build_call_expr_loc (input_location,
1512 fndecl, 4, len1, str1, len2, str2);
1515 return tmp;
1519 /* Return the backend_decl for a procedure pointer component. */
1521 static tree
1522 get_proc_ptr_comp (gfc_expr *e)
1524 gfc_se comp_se;
1525 gfc_expr *e2;
1526 gfc_init_se (&comp_se, NULL);
1527 e2 = gfc_copy_expr (e);
1528 e2->expr_type = EXPR_VARIABLE;
1529 gfc_conv_expr (&comp_se, e2);
1530 gfc_free_expr (e2);
1531 return build_fold_addr_expr_loc (input_location, comp_se.expr);
1535 static void
1536 conv_function_val (gfc_se * se, gfc_symbol * sym, gfc_expr * expr)
1538 tree tmp;
1540 if (gfc_is_proc_ptr_comp (expr, NULL))
1541 tmp = get_proc_ptr_comp (expr);
1542 else if (sym->attr.dummy)
1544 tmp = gfc_get_symbol_decl (sym);
1545 if (sym->attr.proc_pointer)
1546 tmp = build_fold_indirect_ref_loc (input_location,
1547 tmp);
1548 gcc_assert (TREE_CODE (TREE_TYPE (tmp)) == POINTER_TYPE
1549 && TREE_CODE (TREE_TYPE (TREE_TYPE (tmp))) == FUNCTION_TYPE);
1551 else
1553 if (!sym->backend_decl)
1554 sym->backend_decl = gfc_get_extern_function_decl (sym);
1556 tmp = sym->backend_decl;
1558 if (sym->attr.cray_pointee)
1560 /* TODO - make the cray pointee a pointer to a procedure,
1561 assign the pointer to it and use it for the call. This
1562 will do for now! */
1563 tmp = convert (build_pointer_type (TREE_TYPE (tmp)),
1564 gfc_get_symbol_decl (sym->cp_pointer));
1565 tmp = gfc_evaluate_now (tmp, &se->pre);
1568 if (!POINTER_TYPE_P (TREE_TYPE (tmp)))
1570 gcc_assert (TREE_CODE (tmp) == FUNCTION_DECL);
1571 tmp = gfc_build_addr_expr (NULL_TREE, tmp);
1574 se->expr = tmp;
1578 /* Initialize MAPPING. */
1580 void
1581 gfc_init_interface_mapping (gfc_interface_mapping * mapping)
1583 mapping->syms = NULL;
1584 mapping->charlens = NULL;
1588 /* Free all memory held by MAPPING (but not MAPPING itself). */
1590 void
1591 gfc_free_interface_mapping (gfc_interface_mapping * mapping)
1593 gfc_interface_sym_mapping *sym;
1594 gfc_interface_sym_mapping *nextsym;
1595 gfc_charlen *cl;
1596 gfc_charlen *nextcl;
1598 for (sym = mapping->syms; sym; sym = nextsym)
1600 nextsym = sym->next;
1601 sym->new_sym->n.sym->formal = NULL;
1602 gfc_free_symbol (sym->new_sym->n.sym);
1603 gfc_free_expr (sym->expr);
1604 gfc_free (sym->new_sym);
1605 gfc_free (sym);
1607 for (cl = mapping->charlens; cl; cl = nextcl)
1609 nextcl = cl->next;
1610 gfc_free_expr (cl->length);
1611 gfc_free (cl);
1616 /* Return a copy of gfc_charlen CL. Add the returned structure to
1617 MAPPING so that it will be freed by gfc_free_interface_mapping. */
1619 static gfc_charlen *
1620 gfc_get_interface_mapping_charlen (gfc_interface_mapping * mapping,
1621 gfc_charlen * cl)
1623 gfc_charlen *new_charlen;
1625 new_charlen = gfc_get_charlen ();
1626 new_charlen->next = mapping->charlens;
1627 new_charlen->length = gfc_copy_expr (cl->length);
1629 mapping->charlens = new_charlen;
1630 return new_charlen;
1634 /* A subroutine of gfc_add_interface_mapping. Return a descriptorless
1635 array variable that can be used as the actual argument for dummy
1636 argument SYM. Add any initialization code to BLOCK. PACKED is as
1637 for gfc_get_nodesc_array_type and DATA points to the first element
1638 in the passed array. */
1640 static tree
1641 gfc_get_interface_mapping_array (stmtblock_t * block, gfc_symbol * sym,
1642 gfc_packed packed, tree data)
1644 tree type;
1645 tree var;
1647 type = gfc_typenode_for_spec (&sym->ts);
1648 type = gfc_get_nodesc_array_type (type, sym->as, packed,
1649 !sym->attr.target && !sym->attr.pointer
1650 && !sym->attr.proc_pointer);
1652 var = gfc_create_var (type, "ifm");
1653 gfc_add_modify (block, var, fold_convert (type, data));
1655 return var;
1659 /* A subroutine of gfc_add_interface_mapping. Set the stride, upper bounds
1660 and offset of descriptorless array type TYPE given that it has the same
1661 size as DESC. Add any set-up code to BLOCK. */
1663 static void
1664 gfc_set_interface_mapping_bounds (stmtblock_t * block, tree type, tree desc)
1666 int n;
1667 tree dim;
1668 tree offset;
1669 tree tmp;
1671 offset = gfc_index_zero_node;
1672 for (n = 0; n < GFC_TYPE_ARRAY_RANK (type); n++)
1674 dim = gfc_rank_cst[n];
1675 GFC_TYPE_ARRAY_STRIDE (type, n) = gfc_conv_array_stride (desc, n);
1676 if (GFC_TYPE_ARRAY_LBOUND (type, n) == NULL_TREE)
1678 GFC_TYPE_ARRAY_LBOUND (type, n)
1679 = gfc_conv_descriptor_lbound_get (desc, dim);
1680 GFC_TYPE_ARRAY_UBOUND (type, n)
1681 = gfc_conv_descriptor_ubound_get (desc, dim);
1683 else if (GFC_TYPE_ARRAY_UBOUND (type, n) == NULL_TREE)
1685 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
1686 gfc_conv_descriptor_ubound_get (desc, dim),
1687 gfc_conv_descriptor_lbound_get (desc, dim));
1688 tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
1689 GFC_TYPE_ARRAY_LBOUND (type, n),
1690 tmp);
1691 tmp = gfc_evaluate_now (tmp, block);
1692 GFC_TYPE_ARRAY_UBOUND (type, n) = tmp;
1694 tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
1695 GFC_TYPE_ARRAY_LBOUND (type, n),
1696 GFC_TYPE_ARRAY_STRIDE (type, n));
1697 offset = fold_build2 (MINUS_EXPR, gfc_array_index_type, offset, tmp);
1699 offset = gfc_evaluate_now (offset, block);
1700 GFC_TYPE_ARRAY_OFFSET (type) = offset;
1704 /* Extend MAPPING so that it maps dummy argument SYM to the value stored
1705 in SE. The caller may still use se->expr and se->string_length after
1706 calling this function. */
1708 void
1709 gfc_add_interface_mapping (gfc_interface_mapping * mapping,
1710 gfc_symbol * sym, gfc_se * se,
1711 gfc_expr *expr)
1713 gfc_interface_sym_mapping *sm;
1714 tree desc;
1715 tree tmp;
1716 tree value;
1717 gfc_symbol *new_sym;
1718 gfc_symtree *root;
1719 gfc_symtree *new_symtree;
1721 /* Create a new symbol to represent the actual argument. */
1722 new_sym = gfc_new_symbol (sym->name, NULL);
1723 new_sym->ts = sym->ts;
1724 new_sym->as = gfc_copy_array_spec (sym->as);
1725 new_sym->attr.referenced = 1;
1726 new_sym->attr.dimension = sym->attr.dimension;
1727 new_sym->attr.codimension = sym->attr.codimension;
1728 new_sym->attr.pointer = sym->attr.pointer;
1729 new_sym->attr.allocatable = sym->attr.allocatable;
1730 new_sym->attr.flavor = sym->attr.flavor;
1731 new_sym->attr.function = sym->attr.function;
1733 /* Ensure that the interface is available and that
1734 descriptors are passed for array actual arguments. */
1735 if (sym->attr.flavor == FL_PROCEDURE)
1737 new_sym->formal = expr->symtree->n.sym->formal;
1738 new_sym->attr.always_explicit
1739 = expr->symtree->n.sym->attr.always_explicit;
1742 /* Create a fake symtree for it. */
1743 root = NULL;
1744 new_symtree = gfc_new_symtree (&root, sym->name);
1745 new_symtree->n.sym = new_sym;
1746 gcc_assert (new_symtree == root);
1748 /* Create a dummy->actual mapping. */
1749 sm = XCNEW (gfc_interface_sym_mapping);
1750 sm->next = mapping->syms;
1751 sm->old = sym;
1752 sm->new_sym = new_symtree;
1753 sm->expr = gfc_copy_expr (expr);
1754 mapping->syms = sm;
1756 /* Stabilize the argument's value. */
1757 if (!sym->attr.function && se)
1758 se->expr = gfc_evaluate_now (se->expr, &se->pre);
1760 if (sym->ts.type == BT_CHARACTER)
1762 /* Create a copy of the dummy argument's length. */
1763 new_sym->ts.u.cl = gfc_get_interface_mapping_charlen (mapping, sym->ts.u.cl);
1764 sm->expr->ts.u.cl = new_sym->ts.u.cl;
1766 /* If the length is specified as "*", record the length that
1767 the caller is passing. We should use the callee's length
1768 in all other cases. */
1769 if (!new_sym->ts.u.cl->length && se)
1771 se->string_length = gfc_evaluate_now (se->string_length, &se->pre);
1772 new_sym->ts.u.cl->backend_decl = se->string_length;
1776 if (!se)
1777 return;
1779 /* Use the passed value as-is if the argument is a function. */
1780 if (sym->attr.flavor == FL_PROCEDURE)
1781 value = se->expr;
1783 /* If the argument is either a string or a pointer to a string,
1784 convert it to a boundless character type. */
1785 else if (!sym->attr.dimension && sym->ts.type == BT_CHARACTER)
1787 tmp = gfc_get_character_type_len (sym->ts.kind, NULL);
1788 tmp = build_pointer_type (tmp);
1789 if (sym->attr.pointer)
1790 value = build_fold_indirect_ref_loc (input_location,
1791 se->expr);
1792 else
1793 value = se->expr;
1794 value = fold_convert (tmp, value);
1797 /* If the argument is a scalar, a pointer to an array or an allocatable,
1798 dereference it. */
1799 else if (!sym->attr.dimension || sym->attr.pointer || sym->attr.allocatable)
1800 value = build_fold_indirect_ref_loc (input_location,
1801 se->expr);
1803 /* For character(*), use the actual argument's descriptor. */
1804 else if (sym->ts.type == BT_CHARACTER && !new_sym->ts.u.cl->length)
1805 value = build_fold_indirect_ref_loc (input_location,
1806 se->expr);
1808 /* If the argument is an array descriptor, use it to determine
1809 information about the actual argument's shape. */
1810 else if (POINTER_TYPE_P (TREE_TYPE (se->expr))
1811 && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (TREE_TYPE (se->expr))))
1813 /* Get the actual argument's descriptor. */
1814 desc = build_fold_indirect_ref_loc (input_location,
1815 se->expr);
1817 /* Create the replacement variable. */
1818 tmp = gfc_conv_descriptor_data_get (desc);
1819 value = gfc_get_interface_mapping_array (&se->pre, sym,
1820 PACKED_NO, tmp);
1822 /* Use DESC to work out the upper bounds, strides and offset. */
1823 gfc_set_interface_mapping_bounds (&se->pre, TREE_TYPE (value), desc);
1825 else
1826 /* Otherwise we have a packed array. */
1827 value = gfc_get_interface_mapping_array (&se->pre, sym,
1828 PACKED_FULL, se->expr);
1830 new_sym->backend_decl = value;
1834 /* Called once all dummy argument mappings have been added to MAPPING,
1835 but before the mapping is used to evaluate expressions. Pre-evaluate
1836 the length of each argument, adding any initialization code to PRE and
1837 any finalization code to POST. */
1839 void
1840 gfc_finish_interface_mapping (gfc_interface_mapping * mapping,
1841 stmtblock_t * pre, stmtblock_t * post)
1843 gfc_interface_sym_mapping *sym;
1844 gfc_expr *expr;
1845 gfc_se se;
1847 for (sym = mapping->syms; sym; sym = sym->next)
1848 if (sym->new_sym->n.sym->ts.type == BT_CHARACTER
1849 && !sym->new_sym->n.sym->ts.u.cl->backend_decl)
1851 expr = sym->new_sym->n.sym->ts.u.cl->length;
1852 gfc_apply_interface_mapping_to_expr (mapping, expr);
1853 gfc_init_se (&se, NULL);
1854 gfc_conv_expr (&se, expr);
1855 se.expr = fold_convert (gfc_charlen_type_node, se.expr);
1856 se.expr = gfc_evaluate_now (se.expr, &se.pre);
1857 gfc_add_block_to_block (pre, &se.pre);
1858 gfc_add_block_to_block (post, &se.post);
1860 sym->new_sym->n.sym->ts.u.cl->backend_decl = se.expr;
1865 /* Like gfc_apply_interface_mapping_to_expr, but applied to
1866 constructor C. */
1868 static void
1869 gfc_apply_interface_mapping_to_cons (gfc_interface_mapping * mapping,
1870 gfc_constructor_base base)
1872 gfc_constructor *c;
1873 for (c = gfc_constructor_first (base); c; c = gfc_constructor_next (c))
1875 gfc_apply_interface_mapping_to_expr (mapping, c->expr);
1876 if (c->iterator)
1878 gfc_apply_interface_mapping_to_expr (mapping, c->iterator->start);
1879 gfc_apply_interface_mapping_to_expr (mapping, c->iterator->end);
1880 gfc_apply_interface_mapping_to_expr (mapping, c->iterator->step);
1886 /* Like gfc_apply_interface_mapping_to_expr, but applied to
1887 reference REF. */
1889 static void
1890 gfc_apply_interface_mapping_to_ref (gfc_interface_mapping * mapping,
1891 gfc_ref * ref)
1893 int n;
1895 for (; ref; ref = ref->next)
1896 switch (ref->type)
1898 case REF_ARRAY:
1899 for (n = 0; n < ref->u.ar.dimen; n++)
1901 gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.start[n]);
1902 gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.end[n]);
1903 gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.stride[n]);
1905 gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.offset);
1906 break;
1908 case REF_COMPONENT:
1909 break;
1911 case REF_SUBSTRING:
1912 gfc_apply_interface_mapping_to_expr (mapping, ref->u.ss.start);
1913 gfc_apply_interface_mapping_to_expr (mapping, ref->u.ss.end);
1914 break;
1919 /* Convert intrinsic function calls into result expressions. */
1921 static bool
1922 gfc_map_intrinsic_function (gfc_expr *expr, gfc_interface_mapping *mapping)
1924 gfc_symbol *sym;
1925 gfc_expr *new_expr;
1926 gfc_expr *arg1;
1927 gfc_expr *arg2;
1928 int d, dup;
1930 arg1 = expr->value.function.actual->expr;
1931 if (expr->value.function.actual->next)
1932 arg2 = expr->value.function.actual->next->expr;
1933 else
1934 arg2 = NULL;
1936 sym = arg1->symtree->n.sym;
1938 if (sym->attr.dummy)
1939 return false;
1941 new_expr = NULL;
1943 switch (expr->value.function.isym->id)
1945 case GFC_ISYM_LEN:
1946 /* TODO figure out why this condition is necessary. */
1947 if (sym->attr.function
1948 && (arg1->ts.u.cl->length == NULL
1949 || (arg1->ts.u.cl->length->expr_type != EXPR_CONSTANT
1950 && arg1->ts.u.cl->length->expr_type != EXPR_VARIABLE)))
1951 return false;
1953 new_expr = gfc_copy_expr (arg1->ts.u.cl->length);
1954 break;
1956 case GFC_ISYM_SIZE:
1957 if (!sym->as || sym->as->rank == 0)
1958 return false;
1960 if (arg2 && arg2->expr_type == EXPR_CONSTANT)
1962 dup = mpz_get_si (arg2->value.integer);
1963 d = dup - 1;
1965 else
1967 dup = sym->as->rank;
1968 d = 0;
1971 for (; d < dup; d++)
1973 gfc_expr *tmp;
1975 if (!sym->as->upper[d] || !sym->as->lower[d])
1977 gfc_free_expr (new_expr);
1978 return false;
1981 tmp = gfc_add (gfc_copy_expr (sym->as->upper[d]),
1982 gfc_get_int_expr (gfc_default_integer_kind,
1983 NULL, 1));
1984 tmp = gfc_subtract (tmp, gfc_copy_expr (sym->as->lower[d]));
1985 if (new_expr)
1986 new_expr = gfc_multiply (new_expr, tmp);
1987 else
1988 new_expr = tmp;
1990 break;
1992 case GFC_ISYM_LBOUND:
1993 case GFC_ISYM_UBOUND:
1994 /* TODO These implementations of lbound and ubound do not limit if
1995 the size < 0, according to F95's 13.14.53 and 13.14.113. */
1997 if (!sym->as || sym->as->rank == 0)
1998 return false;
2000 if (arg2 && arg2->expr_type == EXPR_CONSTANT)
2001 d = mpz_get_si (arg2->value.integer) - 1;
2002 else
2003 /* TODO: If the need arises, this could produce an array of
2004 ubound/lbounds. */
2005 gcc_unreachable ();
2007 if (expr->value.function.isym->id == GFC_ISYM_LBOUND)
2009 if (sym->as->lower[d])
2010 new_expr = gfc_copy_expr (sym->as->lower[d]);
2012 else
2014 if (sym->as->upper[d])
2015 new_expr = gfc_copy_expr (sym->as->upper[d]);
2017 break;
2019 default:
2020 break;
2023 gfc_apply_interface_mapping_to_expr (mapping, new_expr);
2024 if (!new_expr)
2025 return false;
2027 gfc_replace_expr (expr, new_expr);
2028 return true;
2032 static void
2033 gfc_map_fcn_formal_to_actual (gfc_expr *expr, gfc_expr *map_expr,
2034 gfc_interface_mapping * mapping)
2036 gfc_formal_arglist *f;
2037 gfc_actual_arglist *actual;
2039 actual = expr->value.function.actual;
2040 f = map_expr->symtree->n.sym->formal;
2042 for (; f && actual; f = f->next, actual = actual->next)
2044 if (!actual->expr)
2045 continue;
2047 gfc_add_interface_mapping (mapping, f->sym, NULL, actual->expr);
2050 if (map_expr->symtree->n.sym->attr.dimension)
2052 int d;
2053 gfc_array_spec *as;
2055 as = gfc_copy_array_spec (map_expr->symtree->n.sym->as);
2057 for (d = 0; d < as->rank; d++)
2059 gfc_apply_interface_mapping_to_expr (mapping, as->lower[d]);
2060 gfc_apply_interface_mapping_to_expr (mapping, as->upper[d]);
2063 expr->value.function.esym->as = as;
2066 if (map_expr->symtree->n.sym->ts.type == BT_CHARACTER)
2068 expr->value.function.esym->ts.u.cl->length
2069 = gfc_copy_expr (map_expr->symtree->n.sym->ts.u.cl->length);
2071 gfc_apply_interface_mapping_to_expr (mapping,
2072 expr->value.function.esym->ts.u.cl->length);
2077 /* EXPR is a copy of an expression that appeared in the interface
2078 associated with MAPPING. Walk it recursively looking for references to
2079 dummy arguments that MAPPING maps to actual arguments. Replace each such
2080 reference with a reference to the associated actual argument. */
2082 static void
2083 gfc_apply_interface_mapping_to_expr (gfc_interface_mapping * mapping,
2084 gfc_expr * expr)
2086 gfc_interface_sym_mapping *sym;
2087 gfc_actual_arglist *actual;
2089 if (!expr)
2090 return;
2092 /* Copying an expression does not copy its length, so do that here. */
2093 if (expr->ts.type == BT_CHARACTER && expr->ts.u.cl)
2095 expr->ts.u.cl = gfc_get_interface_mapping_charlen (mapping, expr->ts.u.cl);
2096 gfc_apply_interface_mapping_to_expr (mapping, expr->ts.u.cl->length);
2099 /* Apply the mapping to any references. */
2100 gfc_apply_interface_mapping_to_ref (mapping, expr->ref);
2102 /* ...and to the expression's symbol, if it has one. */
2103 /* TODO Find out why the condition on expr->symtree had to be moved into
2104 the loop rather than being outside it, as originally. */
2105 for (sym = mapping->syms; sym; sym = sym->next)
2106 if (expr->symtree && sym->old == expr->symtree->n.sym)
2108 if (sym->new_sym->n.sym->backend_decl)
2109 expr->symtree = sym->new_sym;
2110 else if (sym->expr)
2111 gfc_replace_expr (expr, gfc_copy_expr (sym->expr));
2114 /* ...and to subexpressions in expr->value. */
2115 switch (expr->expr_type)
2117 case EXPR_VARIABLE:
2118 case EXPR_CONSTANT:
2119 case EXPR_NULL:
2120 case EXPR_SUBSTRING:
2121 break;
2123 case EXPR_OP:
2124 gfc_apply_interface_mapping_to_expr (mapping, expr->value.op.op1);
2125 gfc_apply_interface_mapping_to_expr (mapping, expr->value.op.op2);
2126 break;
2128 case EXPR_FUNCTION:
2129 for (actual = expr->value.function.actual; actual; actual = actual->next)
2130 gfc_apply_interface_mapping_to_expr (mapping, actual->expr);
2132 if (expr->value.function.esym == NULL
2133 && expr->value.function.isym != NULL
2134 && expr->value.function.actual->expr->symtree
2135 && gfc_map_intrinsic_function (expr, mapping))
2136 break;
2138 for (sym = mapping->syms; sym; sym = sym->next)
2139 if (sym->old == expr->value.function.esym)
2141 expr->value.function.esym = sym->new_sym->n.sym;
2142 gfc_map_fcn_formal_to_actual (expr, sym->expr, mapping);
2143 expr->value.function.esym->result = sym->new_sym->n.sym;
2145 break;
2147 case EXPR_ARRAY:
2148 case EXPR_STRUCTURE:
2149 gfc_apply_interface_mapping_to_cons (mapping, expr->value.constructor);
2150 break;
2152 case EXPR_COMPCALL:
2153 case EXPR_PPC:
2154 gcc_unreachable ();
2155 break;
2158 return;
2162 /* Evaluate interface expression EXPR using MAPPING. Store the result
2163 in SE. */
2165 void
2166 gfc_apply_interface_mapping (gfc_interface_mapping * mapping,
2167 gfc_se * se, gfc_expr * expr)
2169 expr = gfc_copy_expr (expr);
2170 gfc_apply_interface_mapping_to_expr (mapping, expr);
2171 gfc_conv_expr (se, expr);
2172 se->expr = gfc_evaluate_now (se->expr, &se->pre);
2173 gfc_free_expr (expr);
2177 /* Returns a reference to a temporary array into which a component of
2178 an actual argument derived type array is copied and then returned
2179 after the function call. */
2180 void
2181 gfc_conv_subref_array_arg (gfc_se * parmse, gfc_expr * expr, int g77,
2182 sym_intent intent, bool formal_ptr)
2184 gfc_se lse;
2185 gfc_se rse;
2186 gfc_ss *lss;
2187 gfc_ss *rss;
2188 gfc_loopinfo loop;
2189 gfc_loopinfo loop2;
2190 gfc_ss_info *info;
2191 tree offset;
2192 tree tmp_index;
2193 tree tmp;
2194 tree base_type;
2195 tree size;
2196 stmtblock_t body;
2197 int n;
2198 int dimen;
2200 gcc_assert (expr->expr_type == EXPR_VARIABLE);
2202 gfc_init_se (&lse, NULL);
2203 gfc_init_se (&rse, NULL);
2205 /* Walk the argument expression. */
2206 rss = gfc_walk_expr (expr);
2208 gcc_assert (rss != gfc_ss_terminator);
2210 /* Initialize the scalarizer. */
2211 gfc_init_loopinfo (&loop);
2212 gfc_add_ss_to_loop (&loop, rss);
2214 /* Calculate the bounds of the scalarization. */
2215 gfc_conv_ss_startstride (&loop);
2217 /* Build an ss for the temporary. */
2218 if (expr->ts.type == BT_CHARACTER && !expr->ts.u.cl->backend_decl)
2219 gfc_conv_string_length (expr->ts.u.cl, expr, &parmse->pre);
2221 base_type = gfc_typenode_for_spec (&expr->ts);
2222 if (GFC_ARRAY_TYPE_P (base_type)
2223 || GFC_DESCRIPTOR_TYPE_P (base_type))
2224 base_type = gfc_get_element_type (base_type);
2226 loop.temp_ss = gfc_get_ss ();;
2227 loop.temp_ss->type = GFC_SS_TEMP;
2228 loop.temp_ss->data.temp.type = base_type;
2230 if (expr->ts.type == BT_CHARACTER)
2231 loop.temp_ss->string_length = expr->ts.u.cl->backend_decl;
2232 else
2233 loop.temp_ss->string_length = NULL;
2235 parmse->string_length = loop.temp_ss->string_length;
2236 loop.temp_ss->data.temp.dimen = loop.dimen;
2237 loop.temp_ss->next = gfc_ss_terminator;
2239 /* Associate the SS with the loop. */
2240 gfc_add_ss_to_loop (&loop, loop.temp_ss);
2242 /* Setup the scalarizing loops. */
2243 gfc_conv_loop_setup (&loop, &expr->where);
2245 /* Pass the temporary descriptor back to the caller. */
2246 info = &loop.temp_ss->data.info;
2247 parmse->expr = info->descriptor;
2249 /* Setup the gfc_se structures. */
2250 gfc_copy_loopinfo_to_se (&lse, &loop);
2251 gfc_copy_loopinfo_to_se (&rse, &loop);
2253 rse.ss = rss;
2254 lse.ss = loop.temp_ss;
2255 gfc_mark_ss_chain_used (rss, 1);
2256 gfc_mark_ss_chain_used (loop.temp_ss, 1);
2258 /* Start the scalarized loop body. */
2259 gfc_start_scalarized_body (&loop, &body);
2261 /* Translate the expression. */
2262 gfc_conv_expr (&rse, expr);
2264 gfc_conv_tmp_array_ref (&lse);
2265 gfc_advance_se_ss_chain (&lse);
2267 if (intent != INTENT_OUT)
2269 tmp = gfc_trans_scalar_assign (&lse, &rse, expr->ts, true, false, true);
2270 gfc_add_expr_to_block (&body, tmp);
2271 gcc_assert (rse.ss == gfc_ss_terminator);
2272 gfc_trans_scalarizing_loops (&loop, &body);
2274 else
2276 /* Make sure that the temporary declaration survives by merging
2277 all the loop declarations into the current context. */
2278 for (n = 0; n < loop.dimen; n++)
2280 gfc_merge_block_scope (&body);
2281 body = loop.code[loop.order[n]];
2283 gfc_merge_block_scope (&body);
2286 /* Add the post block after the second loop, so that any
2287 freeing of allocated memory is done at the right time. */
2288 gfc_add_block_to_block (&parmse->pre, &loop.pre);
2290 /**********Copy the temporary back again.*********/
2292 gfc_init_se (&lse, NULL);
2293 gfc_init_se (&rse, NULL);
2295 /* Walk the argument expression. */
2296 lss = gfc_walk_expr (expr);
2297 rse.ss = loop.temp_ss;
2298 lse.ss = lss;
2300 /* Initialize the scalarizer. */
2301 gfc_init_loopinfo (&loop2);
2302 gfc_add_ss_to_loop (&loop2, lss);
2304 /* Calculate the bounds of the scalarization. */
2305 gfc_conv_ss_startstride (&loop2);
2307 /* Setup the scalarizing loops. */
2308 gfc_conv_loop_setup (&loop2, &expr->where);
2310 gfc_copy_loopinfo_to_se (&lse, &loop2);
2311 gfc_copy_loopinfo_to_se (&rse, &loop2);
2313 gfc_mark_ss_chain_used (lss, 1);
2314 gfc_mark_ss_chain_used (loop.temp_ss, 1);
2316 /* Declare the variable to hold the temporary offset and start the
2317 scalarized loop body. */
2318 offset = gfc_create_var (gfc_array_index_type, NULL);
2319 gfc_start_scalarized_body (&loop2, &body);
2321 /* Build the offsets for the temporary from the loop variables. The
2322 temporary array has lbounds of zero and strides of one in all
2323 dimensions, so this is very simple. The offset is only computed
2324 outside the innermost loop, so the overall transfer could be
2325 optimized further. */
2326 info = &rse.ss->data.info;
2327 dimen = info->dimen;
2329 tmp_index = gfc_index_zero_node;
2330 for (n = dimen - 1; n > 0; n--)
2332 tree tmp_str;
2333 tmp = rse.loop->loopvar[n];
2334 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
2335 tmp, rse.loop->from[n]);
2336 tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
2337 tmp, tmp_index);
2339 tmp_str = fold_build2 (MINUS_EXPR, gfc_array_index_type,
2340 rse.loop->to[n-1], rse.loop->from[n-1]);
2341 tmp_str = fold_build2 (PLUS_EXPR, gfc_array_index_type,
2342 tmp_str, gfc_index_one_node);
2344 tmp_index = fold_build2 (MULT_EXPR, gfc_array_index_type,
2345 tmp, tmp_str);
2348 tmp_index = fold_build2 (MINUS_EXPR, gfc_array_index_type,
2349 tmp_index, rse.loop->from[0]);
2350 gfc_add_modify (&rse.loop->code[0], offset, tmp_index);
2352 tmp_index = fold_build2 (PLUS_EXPR, gfc_array_index_type,
2353 rse.loop->loopvar[0], offset);
2355 /* Now use the offset for the reference. */
2356 tmp = build_fold_indirect_ref_loc (input_location,
2357 info->data);
2358 rse.expr = gfc_build_array_ref (tmp, tmp_index, NULL);
2360 if (expr->ts.type == BT_CHARACTER)
2361 rse.string_length = expr->ts.u.cl->backend_decl;
2363 gfc_conv_expr (&lse, expr);
2365 gcc_assert (lse.ss == gfc_ss_terminator);
2367 tmp = gfc_trans_scalar_assign (&lse, &rse, expr->ts, false, false, true);
2368 gfc_add_expr_to_block (&body, tmp);
2370 /* Generate the copying loops. */
2371 gfc_trans_scalarizing_loops (&loop2, &body);
2373 /* Wrap the whole thing up by adding the second loop to the post-block
2374 and following it by the post-block of the first loop. In this way,
2375 if the temporary needs freeing, it is done after use! */
2376 if (intent != INTENT_IN)
2378 gfc_add_block_to_block (&parmse->post, &loop2.pre);
2379 gfc_add_block_to_block (&parmse->post, &loop2.post);
2382 gfc_add_block_to_block (&parmse->post, &loop.post);
2384 gfc_cleanup_loop (&loop);
2385 gfc_cleanup_loop (&loop2);
2387 /* Pass the string length to the argument expression. */
2388 if (expr->ts.type == BT_CHARACTER)
2389 parmse->string_length = expr->ts.u.cl->backend_decl;
2391 /* Determine the offset for pointer formal arguments and set the
2392 lbounds to one. */
2393 if (formal_ptr)
2395 size = gfc_index_one_node;
2396 offset = gfc_index_zero_node;
2397 for (n = 0; n < dimen; n++)
2399 tmp = gfc_conv_descriptor_ubound_get (parmse->expr,
2400 gfc_rank_cst[n]);
2401 tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
2402 tmp, gfc_index_one_node);
2403 gfc_conv_descriptor_ubound_set (&parmse->pre,
2404 parmse->expr,
2405 gfc_rank_cst[n],
2406 tmp);
2407 gfc_conv_descriptor_lbound_set (&parmse->pre,
2408 parmse->expr,
2409 gfc_rank_cst[n],
2410 gfc_index_one_node);
2411 size = gfc_evaluate_now (size, &parmse->pre);
2412 offset = fold_build2 (MINUS_EXPR, gfc_array_index_type,
2413 offset, size);
2414 offset = gfc_evaluate_now (offset, &parmse->pre);
2415 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
2416 rse.loop->to[n], rse.loop->from[n]);
2417 tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
2418 tmp, gfc_index_one_node);
2419 size = fold_build2 (MULT_EXPR, gfc_array_index_type,
2420 size, tmp);
2423 gfc_conv_descriptor_offset_set (&parmse->pre, parmse->expr,
2424 offset);
2427 /* We want either the address for the data or the address of the descriptor,
2428 depending on the mode of passing array arguments. */
2429 if (g77)
2430 parmse->expr = gfc_conv_descriptor_data_get (parmse->expr);
2431 else
2432 parmse->expr = gfc_build_addr_expr (NULL_TREE, parmse->expr);
2434 return;
2438 /* Generate the code for argument list functions. */
2440 static void
2441 conv_arglist_function (gfc_se *se, gfc_expr *expr, const char *name)
2443 /* Pass by value for g77 %VAL(arg), pass the address
2444 indirectly for %LOC, else by reference. Thus %REF
2445 is a "do-nothing" and %LOC is the same as an F95
2446 pointer. */
2447 if (strncmp (name, "%VAL", 4) == 0)
2448 gfc_conv_expr (se, expr);
2449 else if (strncmp (name, "%LOC", 4) == 0)
2451 gfc_conv_expr_reference (se, expr);
2452 se->expr = gfc_build_addr_expr (NULL, se->expr);
2454 else if (strncmp (name, "%REF", 4) == 0)
2455 gfc_conv_expr_reference (se, expr);
2456 else
2457 gfc_error ("Unknown argument list function at %L", &expr->where);
2461 /* Takes a derived type expression and returns the address of a temporary
2462 class object of the 'declared' type. */
2463 static void
2464 gfc_conv_derived_to_class (gfc_se *parmse, gfc_expr *e,
2465 gfc_typespec class_ts)
2467 gfc_component *cmp;
2468 gfc_symbol *vtab;
2469 gfc_symbol *declared = class_ts.u.derived;
2470 gfc_ss *ss;
2471 tree ctree;
2472 tree var;
2473 tree tmp;
2475 /* The derived type needs to be converted to a temporary
2476 CLASS object. */
2477 tmp = gfc_typenode_for_spec (&class_ts);
2478 var = gfc_create_var (tmp, "class");
2480 /* Set the vptr. */
2481 cmp = gfc_find_component (declared, "$vptr", true, true);
2482 ctree = fold_build3 (COMPONENT_REF, TREE_TYPE (cmp->backend_decl),
2483 var, cmp->backend_decl, NULL_TREE);
2485 /* Remember the vtab corresponds to the derived type
2486 not to the class declared type. */
2487 vtab = gfc_find_derived_vtab (e->ts.u.derived, true);
2488 gcc_assert (vtab);
2489 gfc_trans_assign_vtab_procs (&parmse->pre, e->ts.u.derived, vtab);
2490 tmp = gfc_build_addr_expr (NULL_TREE, gfc_get_symbol_decl (vtab));
2491 gfc_add_modify (&parmse->pre, ctree,
2492 fold_convert (TREE_TYPE (ctree), tmp));
2494 /* Now set the data field. */
2495 cmp = gfc_find_component (declared, "$data", true, true);
2496 ctree = fold_build3 (COMPONENT_REF, TREE_TYPE (cmp->backend_decl),
2497 var, cmp->backend_decl, NULL_TREE);
2498 ss = gfc_walk_expr (e);
2499 if (ss == gfc_ss_terminator)
2501 gfc_conv_expr_reference (parmse, e);
2502 tmp = fold_convert (TREE_TYPE (ctree), parmse->expr);
2503 gfc_add_modify (&parmse->pre, ctree, tmp);
2505 else
2507 gfc_conv_expr (parmse, e);
2508 gfc_add_modify (&parmse->pre, ctree, parmse->expr);
2511 /* Pass the address of the class object. */
2512 parmse->expr = gfc_build_addr_expr (NULL_TREE, var);
2516 /* The following routine generates code for the intrinsic
2517 procedures from the ISO_C_BINDING module:
2518 * C_LOC (function)
2519 * C_FUNLOC (function)
2520 * C_F_POINTER (subroutine)
2521 * C_F_PROCPOINTER (subroutine)
2522 * C_ASSOCIATED (function)
2523 One exception which is not handled here is C_F_POINTER with non-scalar
2524 arguments. Returns 1 if the call was replaced by inline code (else: 0). */
2526 static int
2527 conv_isocbinding_procedure (gfc_se * se, gfc_symbol * sym,
2528 gfc_actual_arglist * arg)
2530 gfc_symbol *fsym;
2531 gfc_ss *argss;
2533 if (sym->intmod_sym_id == ISOCBINDING_LOC)
2535 if (arg->expr->rank == 0)
2536 gfc_conv_expr_reference (se, arg->expr);
2537 else
2539 int f;
2540 /* This is really the actual arg because no formal arglist is
2541 created for C_LOC. */
2542 fsym = arg->expr->symtree->n.sym;
2544 /* We should want it to do g77 calling convention. */
2545 f = (fsym != NULL)
2546 && !(fsym->attr.pointer || fsym->attr.allocatable)
2547 && fsym->as->type != AS_ASSUMED_SHAPE;
2548 f = f || !sym->attr.always_explicit;
2550 argss = gfc_walk_expr (arg->expr);
2551 gfc_conv_array_parameter (se, arg->expr, argss, f,
2552 NULL, NULL, NULL);
2555 /* TODO -- the following two lines shouldn't be necessary, but if
2556 they're removed, a bug is exposed later in the code path.
2557 This workaround was thus introduced, but will have to be
2558 removed; please see PR 35150 for details about the issue. */
2559 se->expr = convert (pvoid_type_node, se->expr);
2560 se->expr = gfc_evaluate_now (se->expr, &se->pre);
2562 return 1;
2564 else if (sym->intmod_sym_id == ISOCBINDING_FUNLOC)
2566 arg->expr->ts.type = sym->ts.u.derived->ts.type;
2567 arg->expr->ts.f90_type = sym->ts.u.derived->ts.f90_type;
2568 arg->expr->ts.kind = sym->ts.u.derived->ts.kind;
2569 gfc_conv_expr_reference (se, arg->expr);
2571 return 1;
2573 else if ((sym->intmod_sym_id == ISOCBINDING_F_POINTER
2574 && arg->next->expr->rank == 0)
2575 || sym->intmod_sym_id == ISOCBINDING_F_PROCPOINTER)
2577 /* Convert c_f_pointer if fptr is a scalar
2578 and convert c_f_procpointer. */
2579 gfc_se cptrse;
2580 gfc_se fptrse;
2582 gfc_init_se (&cptrse, NULL);
2583 gfc_conv_expr (&cptrse, arg->expr);
2584 gfc_add_block_to_block (&se->pre, &cptrse.pre);
2585 gfc_add_block_to_block (&se->post, &cptrse.post);
2587 gfc_init_se (&fptrse, NULL);
2588 if (sym->intmod_sym_id == ISOCBINDING_F_POINTER
2589 || gfc_is_proc_ptr_comp (arg->next->expr, NULL))
2590 fptrse.want_pointer = 1;
2592 gfc_conv_expr (&fptrse, arg->next->expr);
2593 gfc_add_block_to_block (&se->pre, &fptrse.pre);
2594 gfc_add_block_to_block (&se->post, &fptrse.post);
2596 if (arg->next->expr->symtree->n.sym->attr.proc_pointer
2597 && arg->next->expr->symtree->n.sym->attr.dummy)
2598 fptrse.expr = build_fold_indirect_ref_loc (input_location,
2599 fptrse.expr);
2601 se->expr = fold_build2 (MODIFY_EXPR, TREE_TYPE (fptrse.expr),
2602 fptrse.expr,
2603 fold_convert (TREE_TYPE (fptrse.expr),
2604 cptrse.expr));
2606 return 1;
2608 else if (sym->intmod_sym_id == ISOCBINDING_ASSOCIATED)
2610 gfc_se arg1se;
2611 gfc_se arg2se;
2613 /* Build the addr_expr for the first argument. The argument is
2614 already an *address* so we don't need to set want_pointer in
2615 the gfc_se. */
2616 gfc_init_se (&arg1se, NULL);
2617 gfc_conv_expr (&arg1se, arg->expr);
2618 gfc_add_block_to_block (&se->pre, &arg1se.pre);
2619 gfc_add_block_to_block (&se->post, &arg1se.post);
2621 /* See if we were given two arguments. */
2622 if (arg->next == NULL)
2623 /* Only given one arg so generate a null and do a
2624 not-equal comparison against the first arg. */
2625 se->expr = fold_build2 (NE_EXPR, boolean_type_node, arg1se.expr,
2626 fold_convert (TREE_TYPE (arg1se.expr),
2627 null_pointer_node));
2628 else
2630 tree eq_expr;
2631 tree not_null_expr;
2633 /* Given two arguments so build the arg2se from second arg. */
2634 gfc_init_se (&arg2se, NULL);
2635 gfc_conv_expr (&arg2se, arg->next->expr);
2636 gfc_add_block_to_block (&se->pre, &arg2se.pre);
2637 gfc_add_block_to_block (&se->post, &arg2se.post);
2639 /* Generate test to compare that the two args are equal. */
2640 eq_expr = fold_build2 (EQ_EXPR, boolean_type_node,
2641 arg1se.expr, arg2se.expr);
2642 /* Generate test to ensure that the first arg is not null. */
2643 not_null_expr = fold_build2 (NE_EXPR, boolean_type_node,
2644 arg1se.expr, null_pointer_node);
2646 /* Finally, the generated test must check that both arg1 is not
2647 NULL and that it is equal to the second arg. */
2648 se->expr = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
2649 not_null_expr, eq_expr);
2652 return 1;
2655 /* Nothing was done. */
2656 return 0;
2660 /* Generate code for a procedure call. Note can return se->post != NULL.
2661 If se->direct_byref is set then se->expr contains the return parameter.
2662 Return nonzero, if the call has alternate specifiers.
2663 'expr' is only needed for procedure pointer components. */
2666 gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
2667 gfc_actual_arglist * arg, gfc_expr * expr,
2668 tree append_args)
2670 gfc_interface_mapping mapping;
2671 tree arglist;
2672 tree retargs;
2673 tree tmp;
2674 tree fntype;
2675 gfc_se parmse;
2676 gfc_ss *argss;
2677 gfc_ss_info *info;
2678 int byref;
2679 int parm_kind;
2680 tree type;
2681 tree var;
2682 tree len;
2683 tree stringargs;
2684 tree result = NULL;
2685 gfc_formal_arglist *formal;
2686 int has_alternate_specifier = 0;
2687 bool need_interface_mapping;
2688 bool callee_alloc;
2689 gfc_typespec ts;
2690 gfc_charlen cl;
2691 gfc_expr *e;
2692 gfc_symbol *fsym;
2693 stmtblock_t post;
2694 enum {MISSING = 0, ELEMENTAL, SCALAR, SCALAR_POINTER, ARRAY};
2695 gfc_component *comp = NULL;
2697 arglist = NULL_TREE;
2698 retargs = NULL_TREE;
2699 stringargs = NULL_TREE;
2700 var = NULL_TREE;
2701 len = NULL_TREE;
2702 gfc_clear_ts (&ts);
2704 if (sym->from_intmod == INTMOD_ISO_C_BINDING
2705 && conv_isocbinding_procedure (se, sym, arg))
2706 return 0;
2708 gfc_is_proc_ptr_comp (expr, &comp);
2710 if (se->ss != NULL)
2712 if (!sym->attr.elemental)
2714 gcc_assert (se->ss->type == GFC_SS_FUNCTION);
2715 if (se->ss->useflags)
2717 gcc_assert ((!comp && gfc_return_by_reference (sym)
2718 && sym->result->attr.dimension)
2719 || (comp && comp->attr.dimension));
2720 gcc_assert (se->loop != NULL);
2722 /* Access the previously obtained result. */
2723 gfc_conv_tmp_array_ref (se);
2724 gfc_advance_se_ss_chain (se);
2725 return 0;
2728 info = &se->ss->data.info;
2730 else
2731 info = NULL;
2733 gfc_init_block (&post);
2734 gfc_init_interface_mapping (&mapping);
2735 if (!comp)
2737 formal = sym->formal;
2738 need_interface_mapping = sym->attr.dimension ||
2739 (sym->ts.type == BT_CHARACTER
2740 && sym->ts.u.cl->length
2741 && sym->ts.u.cl->length->expr_type
2742 != EXPR_CONSTANT);
2744 else
2746 formal = comp->formal;
2747 need_interface_mapping = comp->attr.dimension ||
2748 (comp->ts.type == BT_CHARACTER
2749 && comp->ts.u.cl->length
2750 && comp->ts.u.cl->length->expr_type
2751 != EXPR_CONSTANT);
2754 /* Evaluate the arguments. */
2755 for (; arg != NULL; arg = arg->next, formal = formal ? formal->next : NULL)
2757 e = arg->expr;
2758 fsym = formal ? formal->sym : NULL;
2759 parm_kind = MISSING;
2761 if (e == NULL)
2763 if (se->ignore_optional)
2765 /* Some intrinsics have already been resolved to the correct
2766 parameters. */
2767 continue;
2769 else if (arg->label)
2771 has_alternate_specifier = 1;
2772 continue;
2774 else
2776 /* Pass a NULL pointer for an absent arg. */
2777 gfc_init_se (&parmse, NULL);
2778 parmse.expr = null_pointer_node;
2779 if (arg->missing_arg_type == BT_CHARACTER)
2780 parmse.string_length = build_int_cst (gfc_charlen_type_node, 0);
2783 else if (fsym && fsym->ts.type == BT_CLASS
2784 && e->ts.type == BT_DERIVED)
2786 /* The derived type needs to be converted to a temporary
2787 CLASS object. */
2788 gfc_init_se (&parmse, se);
2789 gfc_conv_derived_to_class (&parmse, e, fsym->ts);
2791 else if (se->ss && se->ss->useflags)
2793 /* An elemental function inside a scalarized loop. */
2794 gfc_init_se (&parmse, se);
2795 gfc_conv_expr_reference (&parmse, e);
2796 parm_kind = ELEMENTAL;
2798 else
2800 /* A scalar or transformational function. */
2801 gfc_init_se (&parmse, NULL);
2802 argss = gfc_walk_expr (e);
2804 if (argss == gfc_ss_terminator)
2806 if (e->expr_type == EXPR_VARIABLE
2807 && e->symtree->n.sym->attr.cray_pointee
2808 && fsym && fsym->attr.flavor == FL_PROCEDURE)
2810 /* The Cray pointer needs to be converted to a pointer to
2811 a type given by the expression. */
2812 gfc_conv_expr (&parmse, e);
2813 type = build_pointer_type (TREE_TYPE (parmse.expr));
2814 tmp = gfc_get_symbol_decl (e->symtree->n.sym->cp_pointer);
2815 parmse.expr = convert (type, tmp);
2817 else if (fsym && fsym->attr.value)
2819 if (fsym->ts.type == BT_CHARACTER
2820 && fsym->ts.is_c_interop
2821 && fsym->ns->proc_name != NULL
2822 && fsym->ns->proc_name->attr.is_bind_c)
2824 parmse.expr = NULL;
2825 gfc_conv_scalar_char_value (fsym, &parmse, &e);
2826 if (parmse.expr == NULL)
2827 gfc_conv_expr (&parmse, e);
2829 else
2830 gfc_conv_expr (&parmse, e);
2832 else if (arg->name && arg->name[0] == '%')
2833 /* Argument list functions %VAL, %LOC and %REF are signalled
2834 through arg->name. */
2835 conv_arglist_function (&parmse, arg->expr, arg->name);
2836 else if ((e->expr_type == EXPR_FUNCTION)
2837 && ((e->value.function.esym
2838 && e->value.function.esym->result->attr.pointer)
2839 || (!e->value.function.esym
2840 && e->symtree->n.sym->attr.pointer))
2841 && fsym && fsym->attr.target)
2843 gfc_conv_expr (&parmse, e);
2844 parmse.expr = gfc_build_addr_expr (NULL_TREE, parmse.expr);
2846 else if (e->expr_type == EXPR_FUNCTION
2847 && e->symtree->n.sym->result
2848 && e->symtree->n.sym->result != e->symtree->n.sym
2849 && e->symtree->n.sym->result->attr.proc_pointer)
2851 /* Functions returning procedure pointers. */
2852 gfc_conv_expr (&parmse, e);
2853 if (fsym && fsym->attr.proc_pointer)
2854 parmse.expr = gfc_build_addr_expr (NULL_TREE, parmse.expr);
2856 else
2858 gfc_conv_expr_reference (&parmse, e);
2860 /* If an ALLOCATABLE dummy argument has INTENT(OUT) and is
2861 allocated on entry, it must be deallocated. */
2862 if (fsym && fsym->attr.allocatable
2863 && fsym->attr.intent == INTENT_OUT)
2865 stmtblock_t block;
2867 gfc_init_block (&block);
2868 tmp = gfc_deallocate_with_status (parmse.expr, NULL_TREE,
2869 true, NULL);
2870 gfc_add_expr_to_block (&block, tmp);
2871 tmp = fold_build2 (MODIFY_EXPR, void_type_node,
2872 parmse.expr, null_pointer_node);
2873 gfc_add_expr_to_block (&block, tmp);
2875 if (fsym->attr.optional
2876 && e->expr_type == EXPR_VARIABLE
2877 && e->symtree->n.sym->attr.optional)
2879 tmp = fold_build3 (COND_EXPR, void_type_node,
2880 gfc_conv_expr_present (e->symtree->n.sym),
2881 gfc_finish_block (&block),
2882 build_empty_stmt (input_location));
2884 else
2885 tmp = gfc_finish_block (&block);
2887 gfc_add_expr_to_block (&se->pre, tmp);
2890 if (fsym && e->expr_type != EXPR_NULL
2891 && ((fsym->attr.pointer
2892 && fsym->attr.flavor != FL_PROCEDURE)
2893 || (fsym->attr.proc_pointer
2894 && !(e->expr_type == EXPR_VARIABLE
2895 && e->symtree->n.sym->attr.dummy))
2896 || (e->expr_type == EXPR_VARIABLE
2897 && gfc_is_proc_ptr_comp (e, NULL))
2898 || fsym->attr.allocatable))
2900 /* Scalar pointer dummy args require an extra level of
2901 indirection. The null pointer already contains
2902 this level of indirection. */
2903 parm_kind = SCALAR_POINTER;
2904 parmse.expr = gfc_build_addr_expr (NULL_TREE, parmse.expr);
2908 else
2910 /* If the procedure requires an explicit interface, the actual
2911 argument is passed according to the corresponding formal
2912 argument. If the corresponding formal argument is a POINTER,
2913 ALLOCATABLE or assumed shape, we do not use g77's calling
2914 convention, and pass the address of the array descriptor
2915 instead. Otherwise we use g77's calling convention. */
2916 bool f;
2917 f = (fsym != NULL)
2918 && !(fsym->attr.pointer || fsym->attr.allocatable)
2919 && fsym->as->type != AS_ASSUMED_SHAPE;
2920 if (comp)
2921 f = f || !comp->attr.always_explicit;
2922 else
2923 f = f || !sym->attr.always_explicit;
2925 if (e->expr_type == EXPR_VARIABLE
2926 && is_subref_array (e))
2927 /* The actual argument is a component reference to an
2928 array of derived types. In this case, the argument
2929 is converted to a temporary, which is passed and then
2930 written back after the procedure call. */
2931 gfc_conv_subref_array_arg (&parmse, e, f,
2932 fsym ? fsym->attr.intent : INTENT_INOUT,
2933 fsym && fsym->attr.pointer);
2934 else
2935 gfc_conv_array_parameter (&parmse, e, argss, f, fsym,
2936 sym->name, NULL);
2938 /* If an ALLOCATABLE dummy argument has INTENT(OUT) and is
2939 allocated on entry, it must be deallocated. */
2940 if (fsym && fsym->attr.allocatable
2941 && fsym->attr.intent == INTENT_OUT)
2943 tmp = build_fold_indirect_ref_loc (input_location,
2944 parmse.expr);
2945 tmp = gfc_trans_dealloc_allocated (tmp);
2946 if (fsym->attr.optional
2947 && e->expr_type == EXPR_VARIABLE
2948 && e->symtree->n.sym->attr.optional)
2949 tmp = fold_build3 (COND_EXPR, void_type_node,
2950 gfc_conv_expr_present (e->symtree->n.sym),
2951 tmp, build_empty_stmt (input_location));
2952 gfc_add_expr_to_block (&se->pre, tmp);
2957 /* The case with fsym->attr.optional is that of a user subroutine
2958 with an interface indicating an optional argument. When we call
2959 an intrinsic subroutine, however, fsym is NULL, but we might still
2960 have an optional argument, so we proceed to the substitution
2961 just in case. */
2962 if (e && (fsym == NULL || fsym->attr.optional))
2964 /* If an optional argument is itself an optional dummy argument,
2965 check its presence and substitute a null if absent. This is
2966 only needed when passing an array to an elemental procedure
2967 as then array elements are accessed - or no NULL pointer is
2968 allowed and a "1" or "0" should be passed if not present.
2969 When passing a non-array-descriptor full array to a
2970 non-array-descriptor dummy, no check is needed. For
2971 array-descriptor actual to array-descriptor dummy, see
2972 PR 41911 for why a check has to be inserted.
2973 fsym == NULL is checked as intrinsics required the descriptor
2974 but do not always set fsym. */
2975 if (e->expr_type == EXPR_VARIABLE
2976 && e->symtree->n.sym->attr.optional
2977 && ((e->rank > 0 && sym->attr.elemental)
2978 || e->representation.length || e->ts.type == BT_CHARACTER
2979 || (e->rank > 0
2980 && (fsym == NULL || fsym->as->type == AS_ASSUMED_SHAPE
2981 || fsym->as->type == AS_DEFERRED))))
2982 gfc_conv_missing_dummy (&parmse, e, fsym ? fsym->ts : e->ts,
2983 e->representation.length);
2986 if (fsym && e)
2988 /* Obtain the character length of an assumed character length
2989 length procedure from the typespec. */
2990 if (fsym->ts.type == BT_CHARACTER
2991 && parmse.string_length == NULL_TREE
2992 && e->ts.type == BT_PROCEDURE
2993 && e->symtree->n.sym->ts.type == BT_CHARACTER
2994 && e->symtree->n.sym->ts.u.cl->length != NULL
2995 && e->symtree->n.sym->ts.u.cl->length->expr_type == EXPR_CONSTANT)
2997 gfc_conv_const_charlen (e->symtree->n.sym->ts.u.cl);
2998 parmse.string_length = e->symtree->n.sym->ts.u.cl->backend_decl;
3002 if (fsym && need_interface_mapping && e)
3003 gfc_add_interface_mapping (&mapping, fsym, &parmse, e);
3005 gfc_add_block_to_block (&se->pre, &parmse.pre);
3006 gfc_add_block_to_block (&post, &parmse.post);
3008 /* Allocated allocatable components of derived types must be
3009 deallocated for non-variable scalars. Non-variable arrays are
3010 dealt with in trans-array.c(gfc_conv_array_parameter). */
3011 if (e && e->ts.type == BT_DERIVED
3012 && e->ts.u.derived->attr.alloc_comp
3013 && !(e->symtree && e->symtree->n.sym->attr.pointer)
3014 && (e->expr_type != EXPR_VARIABLE && !e->rank))
3016 int parm_rank;
3017 tmp = build_fold_indirect_ref_loc (input_location,
3018 parmse.expr);
3019 parm_rank = e->rank;
3020 switch (parm_kind)
3022 case (ELEMENTAL):
3023 case (SCALAR):
3024 parm_rank = 0;
3025 break;
3027 case (SCALAR_POINTER):
3028 tmp = build_fold_indirect_ref_loc (input_location,
3029 tmp);
3030 break;
3033 if (e->expr_type == EXPR_OP
3034 && e->value.op.op == INTRINSIC_PARENTHESES
3035 && e->value.op.op1->expr_type == EXPR_VARIABLE)
3037 tree local_tmp;
3038 local_tmp = gfc_evaluate_now (tmp, &se->pre);
3039 local_tmp = gfc_copy_alloc_comp (e->ts.u.derived, local_tmp, tmp, parm_rank);
3040 gfc_add_expr_to_block (&se->post, local_tmp);
3043 tmp = gfc_deallocate_alloc_comp (e->ts.u.derived, tmp, parm_rank);
3045 gfc_add_expr_to_block (&se->post, tmp);
3048 /* Add argument checking of passing an unallocated/NULL actual to
3049 a nonallocatable/nonpointer dummy. */
3051 if (gfc_option.rtcheck & GFC_RTCHECK_POINTER && e != NULL)
3053 symbol_attribute *attr;
3054 char *msg;
3055 tree cond;
3057 if (e->expr_type == EXPR_VARIABLE)
3058 attr = &e->symtree->n.sym->attr;
3059 else if (e->expr_type == EXPR_FUNCTION)
3061 /* For intrinsic functions, the gfc_attr are not available. */
3062 if (e->symtree->n.sym->attr.generic && e->value.function.isym)
3063 goto end_pointer_check;
3065 if (e->symtree->n.sym->attr.generic)
3066 attr = &e->value.function.esym->attr;
3067 else
3068 attr = &e->symtree->n.sym->result->attr;
3070 else
3071 goto end_pointer_check;
3073 if (attr->optional)
3075 /* If the actual argument is an optional pointer/allocatable and
3076 the formal argument takes an nonpointer optional value,
3077 it is invalid to pass a non-present argument on, even
3078 though there is no technical reason for this in gfortran.
3079 See Fortran 2003, Section 12.4.1.6 item (7)+(8). */
3080 tree present, null_ptr, type;
3082 if (attr->allocatable
3083 && (fsym == NULL || !fsym->attr.allocatable))
3084 asprintf (&msg, "Allocatable actual argument '%s' is not "
3085 "allocated or not present", e->symtree->n.sym->name);
3086 else if (attr->pointer
3087 && (fsym == NULL || !fsym->attr.pointer))
3088 asprintf (&msg, "Pointer actual argument '%s' is not "
3089 "associated or not present",
3090 e->symtree->n.sym->name);
3091 else if (attr->proc_pointer
3092 && (fsym == NULL || !fsym->attr.proc_pointer))
3093 asprintf (&msg, "Proc-pointer actual argument '%s' is not "
3094 "associated or not present",
3095 e->symtree->n.sym->name);
3096 else
3097 goto end_pointer_check;
3099 present = gfc_conv_expr_present (e->symtree->n.sym);
3100 type = TREE_TYPE (present);
3101 present = fold_build2 (EQ_EXPR, boolean_type_node, present,
3102 fold_convert (type, null_pointer_node));
3103 type = TREE_TYPE (parmse.expr);
3104 null_ptr = fold_build2 (EQ_EXPR, boolean_type_node, parmse.expr,
3105 fold_convert (type, null_pointer_node));
3106 cond = fold_build2 (TRUTH_ORIF_EXPR, boolean_type_node,
3107 present, null_ptr);
3109 else
3111 if (attr->allocatable
3112 && (fsym == NULL || !fsym->attr.allocatable))
3113 asprintf (&msg, "Allocatable actual argument '%s' is not "
3114 "allocated", e->symtree->n.sym->name);
3115 else if (attr->pointer
3116 && (fsym == NULL || !fsym->attr.pointer))
3117 asprintf (&msg, "Pointer actual argument '%s' is not "
3118 "associated", e->symtree->n.sym->name);
3119 else if (attr->proc_pointer
3120 && (fsym == NULL || !fsym->attr.proc_pointer))
3121 asprintf (&msg, "Proc-pointer actual argument '%s' is not "
3122 "associated", e->symtree->n.sym->name);
3123 else
3124 goto end_pointer_check;
3127 cond = fold_build2 (EQ_EXPR, boolean_type_node, parmse.expr,
3128 fold_convert (TREE_TYPE (parmse.expr),
3129 null_pointer_node));
3132 gfc_trans_runtime_check (true, false, cond, &se->pre, &e->where,
3133 msg);
3134 gfc_free (msg);
3136 end_pointer_check:
3139 /* Character strings are passed as two parameters, a length and a
3140 pointer - except for Bind(c) which only passes the pointer. */
3141 if (parmse.string_length != NULL_TREE && !sym->attr.is_bind_c)
3142 stringargs = gfc_chainon_list (stringargs, parmse.string_length);
3144 arglist = gfc_chainon_list (arglist, parmse.expr);
3146 gfc_finish_interface_mapping (&mapping, &se->pre, &se->post);
3148 if (comp)
3149 ts = comp->ts;
3150 else
3151 ts = sym->ts;
3153 if (ts.type == BT_CHARACTER && sym->attr.is_bind_c)
3154 se->string_length = build_int_cst (gfc_charlen_type_node, 1);
3155 else if (ts.type == BT_CHARACTER)
3157 if (ts.u.cl->length == NULL)
3159 /* Assumed character length results are not allowed by 5.1.1.5 of the
3160 standard and are trapped in resolve.c; except in the case of SPREAD
3161 (and other intrinsics?) and dummy functions. In the case of SPREAD,
3162 we take the character length of the first argument for the result.
3163 For dummies, we have to look through the formal argument list for
3164 this function and use the character length found there.*/
3165 if (!sym->attr.dummy)
3166 cl.backend_decl = TREE_VALUE (stringargs);
3167 else
3169 formal = sym->ns->proc_name->formal;
3170 for (; formal; formal = formal->next)
3171 if (strcmp (formal->sym->name, sym->name) == 0)
3172 cl.backend_decl = formal->sym->ts.u.cl->backend_decl;
3175 else
3177 tree tmp;
3179 /* Calculate the length of the returned string. */
3180 gfc_init_se (&parmse, NULL);
3181 if (need_interface_mapping)
3182 gfc_apply_interface_mapping (&mapping, &parmse, ts.u.cl->length);
3183 else
3184 gfc_conv_expr (&parmse, ts.u.cl->length);
3185 gfc_add_block_to_block (&se->pre, &parmse.pre);
3186 gfc_add_block_to_block (&se->post, &parmse.post);
3188 tmp = fold_convert (gfc_charlen_type_node, parmse.expr);
3189 tmp = fold_build2 (MAX_EXPR, gfc_charlen_type_node, tmp,
3190 build_int_cst (gfc_charlen_type_node, 0));
3191 cl.backend_decl = tmp;
3194 /* Set up a charlen structure for it. */
3195 cl.next = NULL;
3196 cl.length = NULL;
3197 ts.u.cl = &cl;
3199 len = cl.backend_decl;
3202 byref = (comp && (comp->attr.dimension || comp->ts.type == BT_CHARACTER))
3203 || (!comp && gfc_return_by_reference (sym));
3204 if (byref)
3206 if (se->direct_byref)
3208 /* Sometimes, too much indirection can be applied; e.g. for
3209 function_result = array_valued_recursive_function. */
3210 if (TREE_TYPE (TREE_TYPE (se->expr))
3211 && TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr)))
3212 && GFC_DESCRIPTOR_TYPE_P
3213 (TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr)))))
3214 se->expr = build_fold_indirect_ref_loc (input_location,
3215 se->expr);
3217 result = build_fold_indirect_ref_loc (input_location,
3218 se->expr);
3219 retargs = gfc_chainon_list (retargs, se->expr);
3221 else if (comp && comp->attr.dimension)
3223 gcc_assert (se->loop && info);
3225 /* Set the type of the array. */
3226 tmp = gfc_typenode_for_spec (&comp->ts);
3227 info->dimen = se->loop->dimen;
3229 /* Evaluate the bounds of the result, if known. */
3230 gfc_set_loop_bounds_from_array_spec (&mapping, se, comp->as);
3232 /* Create a temporary to store the result. In case the function
3233 returns a pointer, the temporary will be a shallow copy and
3234 mustn't be deallocated. */
3235 callee_alloc = comp->attr.allocatable || comp->attr.pointer;
3236 gfc_trans_create_temp_array (&se->pre, &se->post, se->loop, info, tmp,
3237 NULL_TREE, false, !comp->attr.pointer,
3238 callee_alloc, &se->ss->expr->where);
3240 /* Pass the temporary as the first argument. */
3241 result = info->descriptor;
3242 tmp = gfc_build_addr_expr (NULL_TREE, result);
3243 retargs = gfc_chainon_list (retargs, tmp);
3245 else if (!comp && sym->result->attr.dimension)
3247 gcc_assert (se->loop && info);
3249 /* Set the type of the array. */
3250 tmp = gfc_typenode_for_spec (&ts);
3251 info->dimen = se->loop->dimen;
3253 /* Evaluate the bounds of the result, if known. */
3254 gfc_set_loop_bounds_from_array_spec (&mapping, se, sym->result->as);
3256 /* Create a temporary to store the result. In case the function
3257 returns a pointer, the temporary will be a shallow copy and
3258 mustn't be deallocated. */
3259 callee_alloc = sym->attr.allocatable || sym->attr.pointer;
3260 gfc_trans_create_temp_array (&se->pre, &se->post, se->loop, info, tmp,
3261 NULL_TREE, false, !sym->attr.pointer,
3262 callee_alloc, &se->ss->expr->where);
3264 /* Pass the temporary as the first argument. */
3265 result = info->descriptor;
3266 tmp = gfc_build_addr_expr (NULL_TREE, result);
3267 retargs = gfc_chainon_list (retargs, tmp);
3269 else if (ts.type == BT_CHARACTER)
3271 /* Pass the string length. */
3272 type = gfc_get_character_type (ts.kind, ts.u.cl);
3273 type = build_pointer_type (type);
3275 /* Return an address to a char[0:len-1]* temporary for
3276 character pointers. */
3277 if ((!comp && (sym->attr.pointer || sym->attr.allocatable))
3278 || (comp && (comp->attr.pointer || comp->attr.allocatable)))
3280 var = gfc_create_var (type, "pstr");
3282 if ((!comp && sym->attr.allocatable)
3283 || (comp && comp->attr.allocatable))
3284 gfc_add_modify (&se->pre, var,
3285 fold_convert (TREE_TYPE (var),
3286 null_pointer_node));
3288 /* Provide an address expression for the function arguments. */
3289 var = gfc_build_addr_expr (NULL_TREE, var);
3291 else
3292 var = gfc_conv_string_tmp (se, type, len);
3294 retargs = gfc_chainon_list (retargs, var);
3296 else
3298 gcc_assert (gfc_option.flag_f2c && ts.type == BT_COMPLEX);
3300 type = gfc_get_complex_type (ts.kind);
3301 var = gfc_build_addr_expr (NULL_TREE, gfc_create_var (type, "cmplx"));
3302 retargs = gfc_chainon_list (retargs, var);
3305 /* Add the string length to the argument list. */
3306 if (ts.type == BT_CHARACTER)
3307 retargs = gfc_chainon_list (retargs, len);
3309 gfc_free_interface_mapping (&mapping);
3311 /* Add the return arguments. */
3312 arglist = chainon (retargs, arglist);
3314 /* Add the hidden string length parameters to the arguments. */
3315 arglist = chainon (arglist, stringargs);
3317 /* We may want to append extra arguments here. This is used e.g. for
3318 calls to libgfortran_matmul_??, which need extra information. */
3319 if (append_args != NULL_TREE)
3320 arglist = chainon (arglist, append_args);
3322 /* Generate the actual call. */
3323 conv_function_val (se, sym, expr);
3325 /* If there are alternate return labels, function type should be
3326 integer. Can't modify the type in place though, since it can be shared
3327 with other functions. For dummy arguments, the typing is done to
3328 to this result, even if it has to be repeated for each call. */
3329 if (has_alternate_specifier
3330 && TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr))) != integer_type_node)
3332 if (!sym->attr.dummy)
3334 TREE_TYPE (sym->backend_decl)
3335 = build_function_type (integer_type_node,
3336 TYPE_ARG_TYPES (TREE_TYPE (sym->backend_decl)));
3337 se->expr = gfc_build_addr_expr (NULL_TREE, sym->backend_decl);
3339 else
3340 TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr))) = integer_type_node;
3343 fntype = TREE_TYPE (TREE_TYPE (se->expr));
3344 se->expr = build_call_list (TREE_TYPE (fntype), se->expr, arglist);
3346 /* If we have a pointer function, but we don't want a pointer, e.g.
3347 something like
3348 x = f()
3349 where f is pointer valued, we have to dereference the result. */
3350 if (!se->want_pointer && !byref
3351 && (sym->attr.pointer || sym->attr.allocatable)
3352 && !gfc_is_proc_ptr_comp (expr, NULL))
3353 se->expr = build_fold_indirect_ref_loc (input_location,
3354 se->expr);
3356 /* f2c calling conventions require a scalar default real function to
3357 return a double precision result. Convert this back to default
3358 real. We only care about the cases that can happen in Fortran 77.
3360 if (gfc_option.flag_f2c && sym->ts.type == BT_REAL
3361 && sym->ts.kind == gfc_default_real_kind
3362 && !sym->attr.always_explicit)
3363 se->expr = fold_convert (gfc_get_real_type (sym->ts.kind), se->expr);
3365 /* A pure function may still have side-effects - it may modify its
3366 parameters. */
3367 TREE_SIDE_EFFECTS (se->expr) = 1;
3368 #if 0
3369 if (!sym->attr.pure)
3370 TREE_SIDE_EFFECTS (se->expr) = 1;
3371 #endif
3373 if (byref)
3375 /* Add the function call to the pre chain. There is no expression. */
3376 gfc_add_expr_to_block (&se->pre, se->expr);
3377 se->expr = NULL_TREE;
3379 if (!se->direct_byref)
3381 if (sym->attr.dimension || (comp && comp->attr.dimension))
3383 if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
3385 /* Check the data pointer hasn't been modified. This would
3386 happen in a function returning a pointer. */
3387 tmp = gfc_conv_descriptor_data_get (info->descriptor);
3388 tmp = fold_build2 (NE_EXPR, boolean_type_node,
3389 tmp, info->data);
3390 gfc_trans_runtime_check (true, false, tmp, &se->pre, NULL,
3391 gfc_msg_fault);
3393 se->expr = info->descriptor;
3394 /* Bundle in the string length. */
3395 se->string_length = len;
3397 else if (ts.type == BT_CHARACTER)
3399 /* Dereference for character pointer results. */
3400 if ((!comp && (sym->attr.pointer || sym->attr.allocatable))
3401 || (comp && (comp->attr.pointer || comp->attr.allocatable)))
3402 se->expr = build_fold_indirect_ref_loc (input_location, var);
3403 else
3404 se->expr = var;
3406 se->string_length = len;
3408 else
3410 gcc_assert (ts.type == BT_COMPLEX && gfc_option.flag_f2c);
3411 se->expr = build_fold_indirect_ref_loc (input_location, var);
3416 /* Follow the function call with the argument post block. */
3417 if (byref)
3419 gfc_add_block_to_block (&se->pre, &post);
3421 /* Transformational functions of derived types with allocatable
3422 components must have the result allocatable components copied. */
3423 arg = expr->value.function.actual;
3424 if (result && arg && expr->rank
3425 && expr->value.function.isym
3426 && expr->value.function.isym->transformational
3427 && arg->expr->ts.type == BT_DERIVED
3428 && arg->expr->ts.u.derived->attr.alloc_comp)
3430 tree tmp2;
3431 /* Copy the allocatable components. We have to use a
3432 temporary here to prevent source allocatable components
3433 from being corrupted. */
3434 tmp2 = gfc_evaluate_now (result, &se->pre);
3435 tmp = gfc_copy_alloc_comp (arg->expr->ts.u.derived,
3436 result, tmp2, expr->rank);
3437 gfc_add_expr_to_block (&se->pre, tmp);
3438 tmp = gfc_copy_allocatable_data (result, tmp2, TREE_TYPE(tmp2),
3439 expr->rank);
3440 gfc_add_expr_to_block (&se->pre, tmp);
3442 /* Finally free the temporary's data field. */
3443 tmp = gfc_conv_descriptor_data_get (tmp2);
3444 tmp = gfc_deallocate_with_status (tmp, NULL_TREE, true, NULL);
3445 gfc_add_expr_to_block (&se->pre, tmp);
3448 else
3449 gfc_add_block_to_block (&se->post, &post);
3451 return has_alternate_specifier;
3455 /* Fill a character string with spaces. */
3457 static tree
3458 fill_with_spaces (tree start, tree type, tree size)
3460 stmtblock_t block, loop;
3461 tree i, el, exit_label, cond, tmp;
3463 /* For a simple char type, we can call memset(). */
3464 if (compare_tree_int (TYPE_SIZE_UNIT (type), 1) == 0)
3465 return build_call_expr_loc (input_location,
3466 built_in_decls[BUILT_IN_MEMSET], 3, start,
3467 build_int_cst (gfc_get_int_type (gfc_c_int_kind),
3468 lang_hooks.to_target_charset (' ')),
3469 size);
3471 /* Otherwise, we use a loop:
3472 for (el = start, i = size; i > 0; el--, i+= TYPE_SIZE_UNIT (type))
3473 *el = (type) ' ';
3476 /* Initialize variables. */
3477 gfc_init_block (&block);
3478 i = gfc_create_var (sizetype, "i");
3479 gfc_add_modify (&block, i, fold_convert (sizetype, size));
3480 el = gfc_create_var (build_pointer_type (type), "el");
3481 gfc_add_modify (&block, el, fold_convert (TREE_TYPE (el), start));
3482 exit_label = gfc_build_label_decl (NULL_TREE);
3483 TREE_USED (exit_label) = 1;
3486 /* Loop body. */
3487 gfc_init_block (&loop);
3489 /* Exit condition. */
3490 cond = fold_build2 (LE_EXPR, boolean_type_node, i,
3491 fold_convert (sizetype, integer_zero_node));
3492 tmp = build1_v (GOTO_EXPR, exit_label);
3493 tmp = fold_build3 (COND_EXPR, void_type_node, cond, tmp,
3494 build_empty_stmt (input_location));
3495 gfc_add_expr_to_block (&loop, tmp);
3497 /* Assignment. */
3498 gfc_add_modify (&loop, fold_build1 (INDIRECT_REF, type, el),
3499 build_int_cst (type,
3500 lang_hooks.to_target_charset (' ')));
3502 /* Increment loop variables. */
3503 gfc_add_modify (&loop, i, fold_build2 (MINUS_EXPR, sizetype, i,
3504 TYPE_SIZE_UNIT (type)));
3505 gfc_add_modify (&loop, el, fold_build2 (POINTER_PLUS_EXPR,
3506 TREE_TYPE (el), el,
3507 TYPE_SIZE_UNIT (type)));
3509 /* Making the loop... actually loop! */
3510 tmp = gfc_finish_block (&loop);
3511 tmp = build1_v (LOOP_EXPR, tmp);
3512 gfc_add_expr_to_block (&block, tmp);
3514 /* The exit label. */
3515 tmp = build1_v (LABEL_EXPR, exit_label);
3516 gfc_add_expr_to_block (&block, tmp);
3519 return gfc_finish_block (&block);
3523 /* Generate code to copy a string. */
3525 void
3526 gfc_trans_string_copy (stmtblock_t * block, tree dlength, tree dest,
3527 int dkind, tree slength, tree src, int skind)
3529 tree tmp, dlen, slen;
3530 tree dsc;
3531 tree ssc;
3532 tree cond;
3533 tree cond2;
3534 tree tmp2;
3535 tree tmp3;
3536 tree tmp4;
3537 tree chartype;
3538 stmtblock_t tempblock;
3540 gcc_assert (dkind == skind);
3542 if (slength != NULL_TREE)
3544 slen = fold_convert (size_type_node, gfc_evaluate_now (slength, block));
3545 ssc = string_to_single_character (slen, src, skind);
3547 else
3549 slen = build_int_cst (size_type_node, 1);
3550 ssc = src;
3553 if (dlength != NULL_TREE)
3555 dlen = fold_convert (size_type_node, gfc_evaluate_now (dlength, block));
3556 dsc = string_to_single_character (slen, dest, dkind);
3558 else
3560 dlen = build_int_cst (size_type_node, 1);
3561 dsc = dest;
3564 if (slength != NULL_TREE && POINTER_TYPE_P (TREE_TYPE (src)))
3565 ssc = string_to_single_character (slen, src, skind);
3566 if (dlength != NULL_TREE && POINTER_TYPE_P (TREE_TYPE (dest)))
3567 dsc = string_to_single_character (dlen, dest, dkind);
3570 /* Assign directly if the types are compatible. */
3571 if (dsc != NULL_TREE && ssc != NULL_TREE
3572 && TREE_TYPE (dsc) == TREE_TYPE (ssc))
3574 gfc_add_modify (block, dsc, ssc);
3575 return;
3578 /* Do nothing if the destination length is zero. */
3579 cond = fold_build2 (GT_EXPR, boolean_type_node, dlen,
3580 build_int_cst (size_type_node, 0));
3582 /* The following code was previously in _gfortran_copy_string:
3584 // The two strings may overlap so we use memmove.
3585 void
3586 copy_string (GFC_INTEGER_4 destlen, char * dest,
3587 GFC_INTEGER_4 srclen, const char * src)
3589 if (srclen >= destlen)
3591 // This will truncate if too long.
3592 memmove (dest, src, destlen);
3594 else
3596 memmove (dest, src, srclen);
3597 // Pad with spaces.
3598 memset (&dest[srclen], ' ', destlen - srclen);
3602 We're now doing it here for better optimization, but the logic
3603 is the same. */
3605 /* For non-default character kinds, we have to multiply the string
3606 length by the base type size. */
3607 chartype = gfc_get_char_type (dkind);
3608 slen = fold_build2 (MULT_EXPR, size_type_node,
3609 fold_convert (size_type_node, slen),
3610 fold_convert (size_type_node, TYPE_SIZE_UNIT (chartype)));
3611 dlen = fold_build2 (MULT_EXPR, size_type_node,
3612 fold_convert (size_type_node, dlen),
3613 fold_convert (size_type_node, TYPE_SIZE_UNIT (chartype)));
3615 if (dlength)
3616 dest = fold_convert (pvoid_type_node, dest);
3617 else
3618 dest = gfc_build_addr_expr (pvoid_type_node, dest);
3620 if (slength)
3621 src = fold_convert (pvoid_type_node, src);
3622 else
3623 src = gfc_build_addr_expr (pvoid_type_node, src);
3625 /* Truncate string if source is too long. */
3626 cond2 = fold_build2 (GE_EXPR, boolean_type_node, slen, dlen);
3627 tmp2 = build_call_expr_loc (input_location,
3628 built_in_decls[BUILT_IN_MEMMOVE],
3629 3, dest, src, dlen);
3631 /* Else copy and pad with spaces. */
3632 tmp3 = build_call_expr_loc (input_location,
3633 built_in_decls[BUILT_IN_MEMMOVE],
3634 3, dest, src, slen);
3636 tmp4 = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (dest), dest,
3637 fold_convert (sizetype, slen));
3638 tmp4 = fill_with_spaces (tmp4, chartype,
3639 fold_build2 (MINUS_EXPR, TREE_TYPE(dlen),
3640 dlen, slen));
3642 gfc_init_block (&tempblock);
3643 gfc_add_expr_to_block (&tempblock, tmp3);
3644 gfc_add_expr_to_block (&tempblock, tmp4);
3645 tmp3 = gfc_finish_block (&tempblock);
3647 /* The whole copy_string function is there. */
3648 tmp = fold_build3 (COND_EXPR, void_type_node, cond2, tmp2, tmp3);
3649 tmp = fold_build3 (COND_EXPR, void_type_node, cond, tmp,
3650 build_empty_stmt (input_location));
3651 gfc_add_expr_to_block (block, tmp);
3655 /* Translate a statement function.
3656 The value of a statement function reference is obtained by evaluating the
3657 expression using the values of the actual arguments for the values of the
3658 corresponding dummy arguments. */
3660 static void
3661 gfc_conv_statement_function (gfc_se * se, gfc_expr * expr)
3663 gfc_symbol *sym;
3664 gfc_symbol *fsym;
3665 gfc_formal_arglist *fargs;
3666 gfc_actual_arglist *args;
3667 gfc_se lse;
3668 gfc_se rse;
3669 gfc_saved_var *saved_vars;
3670 tree *temp_vars;
3671 tree type;
3672 tree tmp;
3673 int n;
3675 sym = expr->symtree->n.sym;
3676 args = expr->value.function.actual;
3677 gfc_init_se (&lse, NULL);
3678 gfc_init_se (&rse, NULL);
3680 n = 0;
3681 for (fargs = sym->formal; fargs; fargs = fargs->next)
3682 n++;
3683 saved_vars = (gfc_saved_var *)gfc_getmem (n * sizeof (gfc_saved_var));
3684 temp_vars = (tree *)gfc_getmem (n * sizeof (tree));
3686 for (fargs = sym->formal, n = 0; fargs; fargs = fargs->next, n++)
3688 /* Each dummy shall be specified, explicitly or implicitly, to be
3689 scalar. */
3690 gcc_assert (fargs->sym->attr.dimension == 0);
3691 fsym = fargs->sym;
3693 /* Create a temporary to hold the value. */
3694 type = gfc_typenode_for_spec (&fsym->ts);
3695 temp_vars[n] = gfc_create_var (type, fsym->name);
3697 if (fsym->ts.type == BT_CHARACTER)
3699 /* Copy string arguments. */
3700 tree arglen;
3702 gcc_assert (fsym->ts.u.cl && fsym->ts.u.cl->length
3703 && fsym->ts.u.cl->length->expr_type == EXPR_CONSTANT);
3705 arglen = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
3706 tmp = gfc_build_addr_expr (build_pointer_type (type),
3707 temp_vars[n]);
3709 gfc_conv_expr (&rse, args->expr);
3710 gfc_conv_string_parameter (&rse);
3711 gfc_add_block_to_block (&se->pre, &lse.pre);
3712 gfc_add_block_to_block (&se->pre, &rse.pre);
3714 gfc_trans_string_copy (&se->pre, arglen, tmp, fsym->ts.kind,
3715 rse.string_length, rse.expr, fsym->ts.kind);
3716 gfc_add_block_to_block (&se->pre, &lse.post);
3717 gfc_add_block_to_block (&se->pre, &rse.post);
3719 else
3721 /* For everything else, just evaluate the expression. */
3722 gfc_conv_expr (&lse, args->expr);
3724 gfc_add_block_to_block (&se->pre, &lse.pre);
3725 gfc_add_modify (&se->pre, temp_vars[n], lse.expr);
3726 gfc_add_block_to_block (&se->pre, &lse.post);
3729 args = args->next;
3732 /* Use the temporary variables in place of the real ones. */
3733 for (fargs = sym->formal, n = 0; fargs; fargs = fargs->next, n++)
3734 gfc_shadow_sym (fargs->sym, temp_vars[n], &saved_vars[n]);
3736 gfc_conv_expr (se, sym->value);
3738 if (sym->ts.type == BT_CHARACTER)
3740 gfc_conv_const_charlen (sym->ts.u.cl);
3742 /* Force the expression to the correct length. */
3743 if (!INTEGER_CST_P (se->string_length)
3744 || tree_int_cst_lt (se->string_length,
3745 sym->ts.u.cl->backend_decl))
3747 type = gfc_get_character_type (sym->ts.kind, sym->ts.u.cl);
3748 tmp = gfc_create_var (type, sym->name);
3749 tmp = gfc_build_addr_expr (build_pointer_type (type), tmp);
3750 gfc_trans_string_copy (&se->pre, sym->ts.u.cl->backend_decl, tmp,
3751 sym->ts.kind, se->string_length, se->expr,
3752 sym->ts.kind);
3753 se->expr = tmp;
3755 se->string_length = sym->ts.u.cl->backend_decl;
3758 /* Restore the original variables. */
3759 for (fargs = sym->formal, n = 0; fargs; fargs = fargs->next, n++)
3760 gfc_restore_sym (fargs->sym, &saved_vars[n]);
3761 gfc_free (saved_vars);
3765 /* Translate a function expression. */
3767 static void
3768 gfc_conv_function_expr (gfc_se * se, gfc_expr * expr)
3770 gfc_symbol *sym;
3772 if (expr->value.function.isym)
3774 gfc_conv_intrinsic_function (se, expr);
3775 return;
3778 /* We distinguish statement functions from general functions to improve
3779 runtime performance. */
3780 if (expr->symtree->n.sym->attr.proc == PROC_ST_FUNCTION)
3782 gfc_conv_statement_function (se, expr);
3783 return;
3786 /* expr.value.function.esym is the resolved (specific) function symbol for
3787 most functions. However this isn't set for dummy procedures. */
3788 sym = expr->value.function.esym;
3789 if (!sym)
3790 sym = expr->symtree->n.sym;
3792 gfc_conv_procedure_call (se, sym, expr->value.function.actual, expr,
3793 NULL_TREE);
3797 /* Determine whether the given EXPR_CONSTANT is a zero initializer. */
3799 static bool
3800 is_zero_initializer_p (gfc_expr * expr)
3802 if (expr->expr_type != EXPR_CONSTANT)
3803 return false;
3805 /* We ignore constants with prescribed memory representations for now. */
3806 if (expr->representation.string)
3807 return false;
3809 switch (expr->ts.type)
3811 case BT_INTEGER:
3812 return mpz_cmp_si (expr->value.integer, 0) == 0;
3814 case BT_REAL:
3815 return mpfr_zero_p (expr->value.real)
3816 && MPFR_SIGN (expr->value.real) >= 0;
3818 case BT_LOGICAL:
3819 return expr->value.logical == 0;
3821 case BT_COMPLEX:
3822 return mpfr_zero_p (mpc_realref (expr->value.complex))
3823 && MPFR_SIGN (mpc_realref (expr->value.complex)) >= 0
3824 && mpfr_zero_p (mpc_imagref (expr->value.complex))
3825 && MPFR_SIGN (mpc_imagref (expr->value.complex)) >= 0;
3827 default:
3828 break;
3830 return false;
3834 static void
3835 gfc_conv_array_constructor_expr (gfc_se * se, gfc_expr * expr)
3837 gcc_assert (se->ss != NULL && se->ss != gfc_ss_terminator);
3838 gcc_assert (se->ss->expr == expr && se->ss->type == GFC_SS_CONSTRUCTOR);
3840 gfc_conv_tmp_array_ref (se);
3841 gfc_advance_se_ss_chain (se);
3845 /* Build a static initializer. EXPR is the expression for the initial value.
3846 The other parameters describe the variable of the component being
3847 initialized. EXPR may be null. */
3849 tree
3850 gfc_conv_initializer (gfc_expr * expr, gfc_typespec * ts, tree type,
3851 bool array, bool pointer)
3853 gfc_se se;
3855 if (!(expr || pointer))
3856 return NULL_TREE;
3858 /* Check if we have ISOCBINDING_NULL_PTR or ISOCBINDING_NULL_FUNPTR
3859 (these are the only two iso_c_binding derived types that can be
3860 used as initialization expressions). If so, we need to modify
3861 the 'expr' to be that for a (void *). */
3862 if (expr != NULL && expr->ts.type == BT_DERIVED
3863 && expr->ts.is_iso_c && expr->ts.u.derived)
3865 gfc_symbol *derived = expr->ts.u.derived;
3867 /* The derived symbol has already been converted to a (void *). Use
3868 its kind. */
3869 expr = gfc_get_int_expr (derived->ts.kind, NULL, 0);
3870 expr->ts.f90_type = derived->ts.f90_type;
3872 gfc_init_se (&se, NULL);
3873 gfc_conv_constant (&se, expr);
3874 return se.expr;
3877 if (array)
3879 /* Arrays need special handling. */
3880 if (pointer)
3881 return gfc_build_null_descriptor (type);
3882 /* Special case assigning an array to zero. */
3883 else if (is_zero_initializer_p (expr))
3884 return build_constructor (type, NULL);
3885 else
3886 return gfc_conv_array_initializer (type, expr);
3888 else if (pointer)
3889 return fold_convert (type, null_pointer_node);
3890 else
3892 switch (ts->type)
3894 case BT_DERIVED:
3895 case BT_CLASS:
3896 gfc_init_se (&se, NULL);
3897 gfc_conv_structure (&se, expr, 1);
3898 return se.expr;
3900 case BT_CHARACTER:
3901 return gfc_conv_string_init (ts->u.cl->backend_decl,expr);
3903 default:
3904 gfc_init_se (&se, NULL);
3905 gfc_conv_constant (&se, expr);
3906 return se.expr;
3911 static tree
3912 gfc_trans_subarray_assign (tree dest, gfc_component * cm, gfc_expr * expr)
3914 gfc_se rse;
3915 gfc_se lse;
3916 gfc_ss *rss;
3917 gfc_ss *lss;
3918 stmtblock_t body;
3919 stmtblock_t block;
3920 gfc_loopinfo loop;
3921 int n;
3922 tree tmp;
3924 gfc_start_block (&block);
3926 /* Initialize the scalarizer. */
3927 gfc_init_loopinfo (&loop);
3929 gfc_init_se (&lse, NULL);
3930 gfc_init_se (&rse, NULL);
3932 /* Walk the rhs. */
3933 rss = gfc_walk_expr (expr);
3934 if (rss == gfc_ss_terminator)
3936 /* The rhs is scalar. Add a ss for the expression. */
3937 rss = gfc_get_ss ();
3938 rss->next = gfc_ss_terminator;
3939 rss->type = GFC_SS_SCALAR;
3940 rss->expr = expr;
3943 /* Create a SS for the destination. */
3944 lss = gfc_get_ss ();
3945 lss->type = GFC_SS_COMPONENT;
3946 lss->expr = NULL;
3947 lss->shape = gfc_get_shape (cm->as->rank);
3948 lss->next = gfc_ss_terminator;
3949 lss->data.info.dimen = cm->as->rank;
3950 lss->data.info.descriptor = dest;
3951 lss->data.info.data = gfc_conv_array_data (dest);
3952 lss->data.info.offset = gfc_conv_array_offset (dest);
3953 for (n = 0; n < cm->as->rank; n++)
3955 lss->data.info.dim[n] = n;
3956 lss->data.info.start[n] = gfc_conv_array_lbound (dest, n);
3957 lss->data.info.stride[n] = gfc_index_one_node;
3959 mpz_init (lss->shape[n]);
3960 mpz_sub (lss->shape[n], cm->as->upper[n]->value.integer,
3961 cm->as->lower[n]->value.integer);
3962 mpz_add_ui (lss->shape[n], lss->shape[n], 1);
3965 /* Associate the SS with the loop. */
3966 gfc_add_ss_to_loop (&loop, lss);
3967 gfc_add_ss_to_loop (&loop, rss);
3969 /* Calculate the bounds of the scalarization. */
3970 gfc_conv_ss_startstride (&loop);
3972 /* Setup the scalarizing loops. */
3973 gfc_conv_loop_setup (&loop, &expr->where);
3975 /* Setup the gfc_se structures. */
3976 gfc_copy_loopinfo_to_se (&lse, &loop);
3977 gfc_copy_loopinfo_to_se (&rse, &loop);
3979 rse.ss = rss;
3980 gfc_mark_ss_chain_used (rss, 1);
3981 lse.ss = lss;
3982 gfc_mark_ss_chain_used (lss, 1);
3984 /* Start the scalarized loop body. */
3985 gfc_start_scalarized_body (&loop, &body);
3987 gfc_conv_tmp_array_ref (&lse);
3988 if (cm->ts.type == BT_CHARACTER)
3989 lse.string_length = cm->ts.u.cl->backend_decl;
3991 gfc_conv_expr (&rse, expr);
3993 tmp = gfc_trans_scalar_assign (&lse, &rse, cm->ts, true, false, true);
3994 gfc_add_expr_to_block (&body, tmp);
3996 gcc_assert (rse.ss == gfc_ss_terminator);
3998 /* Generate the copying loops. */
3999 gfc_trans_scalarizing_loops (&loop, &body);
4001 /* Wrap the whole thing up. */
4002 gfc_add_block_to_block (&block, &loop.pre);
4003 gfc_add_block_to_block (&block, &loop.post);
4005 for (n = 0; n < cm->as->rank; n++)
4006 mpz_clear (lss->shape[n]);
4007 gfc_free (lss->shape);
4009 gfc_cleanup_loop (&loop);
4011 return gfc_finish_block (&block);
4015 static tree
4016 gfc_trans_alloc_subarray_assign (tree dest, gfc_component * cm,
4017 gfc_expr * expr)
4019 gfc_se se;
4020 gfc_ss *rss;
4021 stmtblock_t block;
4022 tree offset;
4023 int n;
4024 tree tmp;
4025 tree tmp2;
4026 gfc_array_spec *as;
4027 gfc_expr *arg = NULL;
4029 gfc_start_block (&block);
4030 gfc_init_se (&se, NULL);
4032 /* Get the descriptor for the expressions. */
4033 rss = gfc_walk_expr (expr);
4034 se.want_pointer = 0;
4035 gfc_conv_expr_descriptor (&se, expr, rss);
4036 gfc_add_block_to_block (&block, &se.pre);
4037 gfc_add_modify (&block, dest, se.expr);
4039 /* Deal with arrays of derived types with allocatable components. */
4040 if (cm->ts.type == BT_DERIVED
4041 && cm->ts.u.derived->attr.alloc_comp)
4042 tmp = gfc_copy_alloc_comp (cm->ts.u.derived,
4043 se.expr, dest,
4044 cm->as->rank);
4045 else
4046 tmp = gfc_duplicate_allocatable (dest, se.expr,
4047 TREE_TYPE(cm->backend_decl),
4048 cm->as->rank);
4050 gfc_add_expr_to_block (&block, tmp);
4051 gfc_add_block_to_block (&block, &se.post);
4053 if (expr->expr_type != EXPR_VARIABLE)
4054 gfc_conv_descriptor_data_set (&block, se.expr,
4055 null_pointer_node);
4057 /* We need to know if the argument of a conversion function is a
4058 variable, so that the correct lower bound can be used. */
4059 if (expr->expr_type == EXPR_FUNCTION
4060 && expr->value.function.isym
4061 && expr->value.function.isym->conversion
4062 && expr->value.function.actual->expr
4063 && expr->value.function.actual->expr->expr_type == EXPR_VARIABLE)
4064 arg = expr->value.function.actual->expr;
4066 /* Obtain the array spec of full array references. */
4067 if (arg)
4068 as = gfc_get_full_arrayspec_from_expr (arg);
4069 else
4070 as = gfc_get_full_arrayspec_from_expr (expr);
4072 /* Shift the lbound and ubound of temporaries to being unity,
4073 rather than zero, based. Always calculate the offset. */
4074 offset = gfc_conv_descriptor_offset_get (dest);
4075 gfc_add_modify (&block, offset, gfc_index_zero_node);
4076 tmp2 =gfc_create_var (gfc_array_index_type, NULL);
4078 for (n = 0; n < expr->rank; n++)
4080 tree span;
4081 tree lbound;
4083 /* Obtain the correct lbound - ISO/IEC TR 15581:2001 page 9.
4084 TODO It looks as if gfc_conv_expr_descriptor should return
4085 the correct bounds and that the following should not be
4086 necessary. This would simplify gfc_conv_intrinsic_bound
4087 as well. */
4088 if (as && as->lower[n])
4090 gfc_se lbse;
4091 gfc_init_se (&lbse, NULL);
4092 gfc_conv_expr (&lbse, as->lower[n]);
4093 gfc_add_block_to_block (&block, &lbse.pre);
4094 lbound = gfc_evaluate_now (lbse.expr, &block);
4096 else if (as && arg)
4098 tmp = gfc_get_symbol_decl (arg->symtree->n.sym);
4099 lbound = gfc_conv_descriptor_lbound_get (tmp,
4100 gfc_rank_cst[n]);
4102 else if (as)
4103 lbound = gfc_conv_descriptor_lbound_get (dest,
4104 gfc_rank_cst[n]);
4105 else
4106 lbound = gfc_index_one_node;
4108 lbound = fold_convert (gfc_array_index_type, lbound);
4110 /* Shift the bounds and set the offset accordingly. */
4111 tmp = gfc_conv_descriptor_ubound_get (dest, gfc_rank_cst[n]);
4112 span = fold_build2 (MINUS_EXPR, gfc_array_index_type, tmp,
4113 gfc_conv_descriptor_lbound_get (dest, gfc_rank_cst[n]));
4114 tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type, span, lbound);
4115 gfc_conv_descriptor_ubound_set (&block, dest,
4116 gfc_rank_cst[n], tmp);
4117 gfc_conv_descriptor_lbound_set (&block, dest,
4118 gfc_rank_cst[n], lbound);
4120 tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
4121 gfc_conv_descriptor_lbound_get (dest,
4122 gfc_rank_cst[n]),
4123 gfc_conv_descriptor_stride_get (dest,
4124 gfc_rank_cst[n]));
4125 gfc_add_modify (&block, tmp2, tmp);
4126 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type, offset, tmp2);
4127 gfc_conv_descriptor_offset_set (&block, dest, tmp);
4130 if (arg)
4132 /* If a conversion expression has a null data pointer
4133 argument, nullify the allocatable component. */
4134 tree non_null_expr;
4135 tree null_expr;
4137 if (arg->symtree->n.sym->attr.allocatable
4138 || arg->symtree->n.sym->attr.pointer)
4140 non_null_expr = gfc_finish_block (&block);
4141 gfc_start_block (&block);
4142 gfc_conv_descriptor_data_set (&block, dest,
4143 null_pointer_node);
4144 null_expr = gfc_finish_block (&block);
4145 tmp = gfc_conv_descriptor_data_get (arg->symtree->n.sym->backend_decl);
4146 tmp = build2 (EQ_EXPR, boolean_type_node, tmp,
4147 fold_convert (TREE_TYPE (tmp),
4148 null_pointer_node));
4149 return build3_v (COND_EXPR, tmp,
4150 null_expr, non_null_expr);
4154 return gfc_finish_block (&block);
4158 /* Assign a single component of a derived type constructor. */
4160 static tree
4161 gfc_trans_subcomponent_assign (tree dest, gfc_component * cm, gfc_expr * expr)
4163 gfc_se se;
4164 gfc_se lse;
4165 gfc_ss *rss;
4166 stmtblock_t block;
4167 tree tmp;
4169 gfc_start_block (&block);
4171 if (cm->attr.pointer)
4173 gfc_init_se (&se, NULL);
4174 /* Pointer component. */
4175 if (cm->attr.dimension)
4177 /* Array pointer. */
4178 if (expr->expr_type == EXPR_NULL)
4179 gfc_conv_descriptor_data_set (&block, dest, null_pointer_node);
4180 else
4182 rss = gfc_walk_expr (expr);
4183 se.direct_byref = 1;
4184 se.expr = dest;
4185 gfc_conv_expr_descriptor (&se, expr, rss);
4186 gfc_add_block_to_block (&block, &se.pre);
4187 gfc_add_block_to_block (&block, &se.post);
4190 else
4192 /* Scalar pointers. */
4193 se.want_pointer = 1;
4194 gfc_conv_expr (&se, expr);
4195 gfc_add_block_to_block (&block, &se.pre);
4196 gfc_add_modify (&block, dest,
4197 fold_convert (TREE_TYPE (dest), se.expr));
4198 gfc_add_block_to_block (&block, &se.post);
4201 else if (cm->ts.type == BT_CLASS && expr->expr_type == EXPR_NULL)
4203 /* NULL initialization for CLASS components. */
4204 tmp = gfc_trans_structure_assign (dest,
4205 gfc_default_initializer (&cm->ts));
4206 gfc_add_expr_to_block (&block, tmp);
4208 else if (cm->attr.dimension)
4210 if (cm->attr.allocatable && expr->expr_type == EXPR_NULL)
4211 gfc_conv_descriptor_data_set (&block, dest, null_pointer_node);
4212 else if (cm->attr.allocatable)
4214 tmp = gfc_trans_alloc_subarray_assign (dest, cm, expr);
4215 gfc_add_expr_to_block (&block, tmp);
4217 else
4219 tmp = gfc_trans_subarray_assign (dest, cm, expr);
4220 gfc_add_expr_to_block (&block, tmp);
4223 else if (expr->ts.type == BT_DERIVED)
4225 if (expr->expr_type != EXPR_STRUCTURE)
4227 gfc_init_se (&se, NULL);
4228 gfc_conv_expr (&se, expr);
4229 gfc_add_block_to_block (&block, &se.pre);
4230 gfc_add_modify (&block, dest,
4231 fold_convert (TREE_TYPE (dest), se.expr));
4232 gfc_add_block_to_block (&block, &se.post);
4234 else
4236 /* Nested constructors. */
4237 tmp = gfc_trans_structure_assign (dest, expr);
4238 gfc_add_expr_to_block (&block, tmp);
4241 else
4243 /* Scalar component. */
4244 gfc_init_se (&se, NULL);
4245 gfc_init_se (&lse, NULL);
4247 gfc_conv_expr (&se, expr);
4248 if (cm->ts.type == BT_CHARACTER)
4249 lse.string_length = cm->ts.u.cl->backend_decl;
4250 lse.expr = dest;
4251 tmp = gfc_trans_scalar_assign (&lse, &se, cm->ts, true, false, true);
4252 gfc_add_expr_to_block (&block, tmp);
4254 return gfc_finish_block (&block);
4257 /* Assign a derived type constructor to a variable. */
4259 static tree
4260 gfc_trans_structure_assign (tree dest, gfc_expr * expr)
4262 gfc_constructor *c;
4263 gfc_component *cm;
4264 stmtblock_t block;
4265 tree field;
4266 tree tmp;
4268 gfc_start_block (&block);
4269 cm = expr->ts.u.derived->components;
4270 for (c = gfc_constructor_first (expr->value.constructor);
4271 c; c = gfc_constructor_next (c), cm = cm->next)
4273 /* Skip absent members in default initializers. */
4274 if (!c->expr)
4275 continue;
4277 /* Handle c_null_(fun)ptr. */
4278 if (c && c->expr && c->expr->ts.is_iso_c)
4280 field = cm->backend_decl;
4281 tmp = fold_build3 (COMPONENT_REF, TREE_TYPE (field),
4282 dest, field, NULL_TREE);
4283 tmp = fold_build2 (MODIFY_EXPR, TREE_TYPE (tmp), tmp,
4284 fold_convert (TREE_TYPE (tmp),
4285 null_pointer_node));
4286 gfc_add_expr_to_block (&block, tmp);
4287 continue;
4290 field = cm->backend_decl;
4291 tmp = fold_build3 (COMPONENT_REF, TREE_TYPE (field),
4292 dest, field, NULL_TREE);
4293 tmp = gfc_trans_subcomponent_assign (tmp, cm, c->expr);
4294 gfc_add_expr_to_block (&block, tmp);
4296 return gfc_finish_block (&block);
4299 /* Build an expression for a constructor. If init is nonzero then
4300 this is part of a static variable initializer. */
4302 void
4303 gfc_conv_structure (gfc_se * se, gfc_expr * expr, int init)
4305 gfc_constructor *c;
4306 gfc_component *cm;
4307 tree val;
4308 tree type;
4309 tree tmp;
4310 VEC(constructor_elt,gc) *v = NULL;
4312 gcc_assert (se->ss == NULL);
4313 gcc_assert (expr->expr_type == EXPR_STRUCTURE);
4314 type = gfc_typenode_for_spec (&expr->ts);
4316 if (!init)
4318 /* Create a temporary variable and fill it in. */
4319 se->expr = gfc_create_var (type, expr->ts.u.derived->name);
4320 tmp = gfc_trans_structure_assign (se->expr, expr);
4321 gfc_add_expr_to_block (&se->pre, tmp);
4322 return;
4325 cm = expr->ts.u.derived->components;
4327 for (c = gfc_constructor_first (expr->value.constructor);
4328 c; c = gfc_constructor_next (c), cm = cm->next)
4330 /* Skip absent members in default initializers and allocatable
4331 components. Although the latter have a default initializer
4332 of EXPR_NULL,... by default, the static nullify is not needed
4333 since this is done every time we come into scope. */
4334 if (!c->expr || cm->attr.allocatable)
4335 continue;
4337 if (cm->ts.type == BT_CLASS && !cm->attr.proc_pointer)
4339 gfc_component *data;
4340 data = gfc_find_component (cm->ts.u.derived, "$data", true, true);
4341 if (!data->backend_decl)
4342 gfc_get_derived_type (cm->ts.u.derived);
4343 val = gfc_conv_initializer (c->expr, &cm->ts,
4344 TREE_TYPE (data->backend_decl),
4345 data->attr.dimension,
4346 data->attr.pointer);
4348 CONSTRUCTOR_APPEND_ELT (v, data->backend_decl, val);
4350 else if (strcmp (cm->name, "$size") == 0)
4352 val = TYPE_SIZE_UNIT (gfc_get_derived_type (cm->ts.u.derived));
4353 CONSTRUCTOR_APPEND_ELT (v, cm->backend_decl, val);
4355 else if (cm->initializer && cm->initializer->expr_type != EXPR_NULL
4356 && strcmp (cm->name, "$extends") == 0)
4358 tree vtab;
4359 gfc_symbol *vtabs;
4360 vtabs = cm->initializer->symtree->n.sym;
4361 vtab = gfc_build_addr_expr (NULL_TREE, gfc_get_symbol_decl (vtabs));
4362 CONSTRUCTOR_APPEND_ELT (v, cm->backend_decl, vtab);
4364 else
4366 val = gfc_conv_initializer (c->expr, &cm->ts,
4367 TREE_TYPE (cm->backend_decl), cm->attr.dimension,
4368 cm->attr.pointer || cm->attr.proc_pointer);
4370 /* Append it to the constructor list. */
4371 CONSTRUCTOR_APPEND_ELT (v, cm->backend_decl, val);
4374 se->expr = build_constructor (type, v);
4375 if (init)
4376 TREE_CONSTANT (se->expr) = 1;
4380 /* Translate a substring expression. */
4382 static void
4383 gfc_conv_substring_expr (gfc_se * se, gfc_expr * expr)
4385 gfc_ref *ref;
4387 ref = expr->ref;
4389 gcc_assert (ref == NULL || ref->type == REF_SUBSTRING);
4391 se->expr = gfc_build_wide_string_const (expr->ts.kind,
4392 expr->value.character.length,
4393 expr->value.character.string);
4395 se->string_length = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (se->expr)));
4396 TYPE_STRING_FLAG (TREE_TYPE (se->expr)) = 1;
4398 if (ref)
4399 gfc_conv_substring (se, ref, expr->ts.kind, NULL, &expr->where);
4403 /* Entry point for expression translation. Evaluates a scalar quantity.
4404 EXPR is the expression to be translated, and SE is the state structure if
4405 called from within the scalarized. */
4407 void
4408 gfc_conv_expr (gfc_se * se, gfc_expr * expr)
4410 if (se->ss && se->ss->expr == expr
4411 && (se->ss->type == GFC_SS_SCALAR || se->ss->type == GFC_SS_REFERENCE))
4413 /* Substitute a scalar expression evaluated outside the scalarization
4414 loop. */
4415 se->expr = se->ss->data.scalar.expr;
4416 if (se->ss->type == GFC_SS_REFERENCE)
4417 se->expr = gfc_build_addr_expr (NULL_TREE, se->expr);
4418 se->string_length = se->ss->string_length;
4419 gfc_advance_se_ss_chain (se);
4420 return;
4423 /* We need to convert the expressions for the iso_c_binding derived types.
4424 C_NULL_PTR and C_NULL_FUNPTR will be made EXPR_NULL, which evaluates to
4425 null_pointer_node. C_PTR and C_FUNPTR are converted to match the
4426 typespec for the C_PTR and C_FUNPTR symbols, which has already been
4427 updated to be an integer with a kind equal to the size of a (void *). */
4428 if (expr->ts.type == BT_DERIVED && expr->ts.u.derived
4429 && expr->ts.u.derived->attr.is_iso_c)
4431 if (expr->symtree->n.sym->intmod_sym_id == ISOCBINDING_NULL_PTR
4432 || expr->symtree->n.sym->intmod_sym_id == ISOCBINDING_NULL_FUNPTR)
4434 /* Set expr_type to EXPR_NULL, which will result in
4435 null_pointer_node being used below. */
4436 expr->expr_type = EXPR_NULL;
4438 else
4440 /* Update the type/kind of the expression to be what the new
4441 type/kind are for the updated symbols of C_PTR/C_FUNPTR. */
4442 expr->ts.type = expr->ts.u.derived->ts.type;
4443 expr->ts.f90_type = expr->ts.u.derived->ts.f90_type;
4444 expr->ts.kind = expr->ts.u.derived->ts.kind;
4448 switch (expr->expr_type)
4450 case EXPR_OP:
4451 gfc_conv_expr_op (se, expr);
4452 break;
4454 case EXPR_FUNCTION:
4455 gfc_conv_function_expr (se, expr);
4456 break;
4458 case EXPR_CONSTANT:
4459 gfc_conv_constant (se, expr);
4460 break;
4462 case EXPR_VARIABLE:
4463 gfc_conv_variable (se, expr);
4464 break;
4466 case EXPR_NULL:
4467 se->expr = null_pointer_node;
4468 break;
4470 case EXPR_SUBSTRING:
4471 gfc_conv_substring_expr (se, expr);
4472 break;
4474 case EXPR_STRUCTURE:
4475 gfc_conv_structure (se, expr, 0);
4476 break;
4478 case EXPR_ARRAY:
4479 gfc_conv_array_constructor_expr (se, expr);
4480 break;
4482 default:
4483 gcc_unreachable ();
4484 break;
4488 /* Like gfc_conv_expr_val, but the value is also suitable for use in the lhs
4489 of an assignment. */
4490 void
4491 gfc_conv_expr_lhs (gfc_se * se, gfc_expr * expr)
4493 gfc_conv_expr (se, expr);
4494 /* All numeric lvalues should have empty post chains. If not we need to
4495 figure out a way of rewriting an lvalue so that it has no post chain. */
4496 gcc_assert (expr->ts.type == BT_CHARACTER || !se->post.head);
4499 /* Like gfc_conv_expr, but the POST block is guaranteed to be empty for
4500 numeric expressions. Used for scalar values where inserting cleanup code
4501 is inconvenient. */
4502 void
4503 gfc_conv_expr_val (gfc_se * se, gfc_expr * expr)
4505 tree val;
4507 gcc_assert (expr->ts.type != BT_CHARACTER);
4508 gfc_conv_expr (se, expr);
4509 if (se->post.head)
4511 val = gfc_create_var (TREE_TYPE (se->expr), NULL);
4512 gfc_add_modify (&se->pre, val, se->expr);
4513 se->expr = val;
4514 gfc_add_block_to_block (&se->pre, &se->post);
4518 /* Helper to translate an expression and convert it to a particular type. */
4519 void
4520 gfc_conv_expr_type (gfc_se * se, gfc_expr * expr, tree type)
4522 gfc_conv_expr_val (se, expr);
4523 se->expr = convert (type, se->expr);
4527 /* Converts an expression so that it can be passed by reference. Scalar
4528 values only. */
4530 void
4531 gfc_conv_expr_reference (gfc_se * se, gfc_expr * expr)
4533 tree var;
4535 if (se->ss && se->ss->expr == expr
4536 && se->ss->type == GFC_SS_REFERENCE)
4538 /* Returns a reference to the scalar evaluated outside the loop
4539 for this case. */
4540 gfc_conv_expr (se, expr);
4541 return;
4544 if (expr->ts.type == BT_CHARACTER)
4546 gfc_conv_expr (se, expr);
4547 gfc_conv_string_parameter (se);
4548 return;
4551 if (expr->expr_type == EXPR_VARIABLE)
4553 se->want_pointer = 1;
4554 gfc_conv_expr (se, expr);
4555 if (se->post.head)
4557 var = gfc_create_var (TREE_TYPE (se->expr), NULL);
4558 gfc_add_modify (&se->pre, var, se->expr);
4559 gfc_add_block_to_block (&se->pre, &se->post);
4560 se->expr = var;
4562 return;
4565 if (expr->expr_type == EXPR_FUNCTION
4566 && ((expr->value.function.esym
4567 && expr->value.function.esym->result->attr.pointer
4568 && !expr->value.function.esym->result->attr.dimension)
4569 || (!expr->value.function.esym
4570 && expr->symtree->n.sym->attr.pointer
4571 && !expr->symtree->n.sym->attr.dimension)))
4573 se->want_pointer = 1;
4574 gfc_conv_expr (se, expr);
4575 var = gfc_create_var (TREE_TYPE (se->expr), NULL);
4576 gfc_add_modify (&se->pre, var, se->expr);
4577 se->expr = var;
4578 return;
4582 gfc_conv_expr (se, expr);
4584 /* Create a temporary var to hold the value. */
4585 if (TREE_CONSTANT (se->expr))
4587 tree tmp = se->expr;
4588 STRIP_TYPE_NOPS (tmp);
4589 var = build_decl (input_location,
4590 CONST_DECL, NULL, TREE_TYPE (tmp));
4591 DECL_INITIAL (var) = tmp;
4592 TREE_STATIC (var) = 1;
4593 pushdecl (var);
4595 else
4597 var = gfc_create_var (TREE_TYPE (se->expr), NULL);
4598 gfc_add_modify (&se->pre, var, se->expr);
4600 gfc_add_block_to_block (&se->pre, &se->post);
4602 /* Take the address of that value. */
4603 se->expr = gfc_build_addr_expr (NULL_TREE, var);
4607 tree
4608 gfc_trans_pointer_assign (gfc_code * code)
4610 return gfc_trans_pointer_assignment (code->expr1, code->expr2);
4614 /* Generate code for a pointer assignment. */
4616 tree
4617 gfc_trans_pointer_assignment (gfc_expr * expr1, gfc_expr * expr2)
4619 gfc_se lse;
4620 gfc_se rse;
4621 gfc_ss *lss;
4622 gfc_ss *rss;
4623 stmtblock_t block;
4624 tree desc;
4625 tree tmp;
4626 tree decl;
4628 gfc_start_block (&block);
4630 gfc_init_se (&lse, NULL);
4632 lss = gfc_walk_expr (expr1);
4633 rss = gfc_walk_expr (expr2);
4634 if (lss == gfc_ss_terminator)
4636 /* Scalar pointers. */
4637 lse.want_pointer = 1;
4638 gfc_conv_expr (&lse, expr1);
4639 gcc_assert (rss == gfc_ss_terminator);
4640 gfc_init_se (&rse, NULL);
4641 rse.want_pointer = 1;
4642 gfc_conv_expr (&rse, expr2);
4644 if (expr1->symtree->n.sym->attr.proc_pointer
4645 && expr1->symtree->n.sym->attr.dummy)
4646 lse.expr = build_fold_indirect_ref_loc (input_location,
4647 lse.expr);
4649 if (expr2->symtree && expr2->symtree->n.sym->attr.proc_pointer
4650 && expr2->symtree->n.sym->attr.dummy)
4651 rse.expr = build_fold_indirect_ref_loc (input_location,
4652 rse.expr);
4654 gfc_add_block_to_block (&block, &lse.pre);
4655 gfc_add_block_to_block (&block, &rse.pre);
4657 /* Check character lengths if character expression. The test is only
4658 really added if -fbounds-check is enabled. */
4659 if (expr1->ts.type == BT_CHARACTER && expr2->expr_type != EXPR_NULL
4660 && !expr1->symtree->n.sym->attr.proc_pointer
4661 && !gfc_is_proc_ptr_comp (expr1, NULL))
4663 gcc_assert (expr2->ts.type == BT_CHARACTER);
4664 gcc_assert (lse.string_length && rse.string_length);
4665 gfc_trans_same_strlen_check ("pointer assignment", &expr1->where,
4666 lse.string_length, rse.string_length,
4667 &block);
4670 gfc_add_modify (&block, lse.expr,
4671 fold_convert (TREE_TYPE (lse.expr), rse.expr));
4673 gfc_add_block_to_block (&block, &rse.post);
4674 gfc_add_block_to_block (&block, &lse.post);
4676 else
4678 tree strlen_lhs;
4679 tree strlen_rhs = NULL_TREE;
4681 /* Array pointer. */
4682 gfc_conv_expr_descriptor (&lse, expr1, lss);
4683 strlen_lhs = lse.string_length;
4684 switch (expr2->expr_type)
4686 case EXPR_NULL:
4687 /* Just set the data pointer to null. */
4688 gfc_conv_descriptor_data_set (&lse.pre, lse.expr, null_pointer_node);
4689 break;
4691 case EXPR_VARIABLE:
4692 /* Assign directly to the pointer's descriptor. */
4693 lse.direct_byref = 1;
4694 gfc_conv_expr_descriptor (&lse, expr2, rss);
4695 strlen_rhs = lse.string_length;
4697 /* If this is a subreference array pointer assignment, use the rhs
4698 descriptor element size for the lhs span. */
4699 if (expr1->symtree->n.sym->attr.subref_array_pointer)
4701 decl = expr1->symtree->n.sym->backend_decl;
4702 gfc_init_se (&rse, NULL);
4703 rse.descriptor_only = 1;
4704 gfc_conv_expr (&rse, expr2);
4705 tmp = gfc_get_element_type (TREE_TYPE (rse.expr));
4706 tmp = fold_convert (gfc_array_index_type, size_in_bytes (tmp));
4707 if (!INTEGER_CST_P (tmp))
4708 gfc_add_block_to_block (&lse.post, &rse.pre);
4709 gfc_add_modify (&lse.post, GFC_DECL_SPAN(decl), tmp);
4712 break;
4714 default:
4715 /* Assign to a temporary descriptor and then copy that
4716 temporary to the pointer. */
4717 desc = lse.expr;
4718 tmp = gfc_create_var (TREE_TYPE (desc), "ptrtemp");
4720 lse.expr = tmp;
4721 lse.direct_byref = 1;
4722 gfc_conv_expr_descriptor (&lse, expr2, rss);
4723 strlen_rhs = lse.string_length;
4724 gfc_add_modify (&lse.pre, desc, tmp);
4725 break;
4728 gfc_add_block_to_block (&block, &lse.pre);
4730 /* Check string lengths if applicable. The check is only really added
4731 to the output code if -fbounds-check is enabled. */
4732 if (expr1->ts.type == BT_CHARACTER && expr2->expr_type != EXPR_NULL)
4734 gcc_assert (expr2->ts.type == BT_CHARACTER);
4735 gcc_assert (strlen_lhs && strlen_rhs);
4736 gfc_trans_same_strlen_check ("pointer assignment", &expr1->where,
4737 strlen_lhs, strlen_rhs, &block);
4740 gfc_add_block_to_block (&block, &lse.post);
4742 return gfc_finish_block (&block);
4746 /* Makes sure se is suitable for passing as a function string parameter. */
4747 /* TODO: Need to check all callers of this function. It may be abused. */
4749 void
4750 gfc_conv_string_parameter (gfc_se * se)
4752 tree type;
4754 if (TREE_CODE (se->expr) == STRING_CST)
4756 type = TREE_TYPE (TREE_TYPE (se->expr));
4757 se->expr = gfc_build_addr_expr (build_pointer_type (type), se->expr);
4758 return;
4761 if (TYPE_STRING_FLAG (TREE_TYPE (se->expr)))
4763 if (TREE_CODE (se->expr) != INDIRECT_REF)
4765 type = TREE_TYPE (se->expr);
4766 se->expr = gfc_build_addr_expr (build_pointer_type (type), se->expr);
4768 else
4770 type = gfc_get_character_type_len (gfc_default_character_kind,
4771 se->string_length);
4772 type = build_pointer_type (type);
4773 se->expr = gfc_build_addr_expr (type, se->expr);
4777 gcc_assert (POINTER_TYPE_P (TREE_TYPE (se->expr)));
4778 gcc_assert (se->string_length
4779 && TREE_CODE (TREE_TYPE (se->string_length)) == INTEGER_TYPE);
4783 /* Generate code for assignment of scalar variables. Includes character
4784 strings and derived types with allocatable components.
4785 If you know that the LHS has no allocations, set dealloc to false. */
4787 tree
4788 gfc_trans_scalar_assign (gfc_se * lse, gfc_se * rse, gfc_typespec ts,
4789 bool l_is_temp, bool r_is_var, bool dealloc)
4791 stmtblock_t block;
4792 tree tmp;
4793 tree cond;
4795 gfc_init_block (&block);
4797 if (ts.type == BT_CHARACTER)
4799 tree rlen = NULL;
4800 tree llen = NULL;
4802 if (lse->string_length != NULL_TREE)
4804 gfc_conv_string_parameter (lse);
4805 gfc_add_block_to_block (&block, &lse->pre);
4806 llen = lse->string_length;
4809 if (rse->string_length != NULL_TREE)
4811 gcc_assert (rse->string_length != NULL_TREE);
4812 gfc_conv_string_parameter (rse);
4813 gfc_add_block_to_block (&block, &rse->pre);
4814 rlen = rse->string_length;
4817 gfc_trans_string_copy (&block, llen, lse->expr, ts.kind, rlen,
4818 rse->expr, ts.kind);
4820 else if (ts.type == BT_DERIVED && ts.u.derived->attr.alloc_comp)
4822 cond = NULL_TREE;
4824 /* Are the rhs and the lhs the same? */
4825 if (r_is_var)
4827 cond = fold_build2 (EQ_EXPR, boolean_type_node,
4828 gfc_build_addr_expr (NULL_TREE, lse->expr),
4829 gfc_build_addr_expr (NULL_TREE, rse->expr));
4830 cond = gfc_evaluate_now (cond, &lse->pre);
4833 /* Deallocate the lhs allocated components as long as it is not
4834 the same as the rhs. This must be done following the assignment
4835 to prevent deallocating data that could be used in the rhs
4836 expression. */
4837 if (!l_is_temp && dealloc)
4839 tmp = gfc_evaluate_now (lse->expr, &lse->pre);
4840 tmp = gfc_deallocate_alloc_comp (ts.u.derived, tmp, 0);
4841 if (r_is_var)
4842 tmp = build3_v (COND_EXPR, cond, build_empty_stmt (input_location),
4843 tmp);
4844 gfc_add_expr_to_block (&lse->post, tmp);
4847 gfc_add_block_to_block (&block, &rse->pre);
4848 gfc_add_block_to_block (&block, &lse->pre);
4850 gfc_add_modify (&block, lse->expr,
4851 fold_convert (TREE_TYPE (lse->expr), rse->expr));
4853 /* Do a deep copy if the rhs is a variable, if it is not the
4854 same as the lhs. */
4855 if (r_is_var)
4857 tmp = gfc_copy_alloc_comp (ts.u.derived, rse->expr, lse->expr, 0);
4858 tmp = build3_v (COND_EXPR, cond, build_empty_stmt (input_location),
4859 tmp);
4860 gfc_add_expr_to_block (&block, tmp);
4863 else if (ts.type == BT_DERIVED || ts.type == BT_CLASS)
4865 gfc_add_block_to_block (&block, &lse->pre);
4866 gfc_add_block_to_block (&block, &rse->pre);
4867 tmp = fold_build1 (VIEW_CONVERT_EXPR, TREE_TYPE (lse->expr), rse->expr);
4868 gfc_add_modify (&block, lse->expr, tmp);
4870 else
4872 gfc_add_block_to_block (&block, &lse->pre);
4873 gfc_add_block_to_block (&block, &rse->pre);
4875 gfc_add_modify (&block, lse->expr,
4876 fold_convert (TREE_TYPE (lse->expr), rse->expr));
4879 gfc_add_block_to_block (&block, &lse->post);
4880 gfc_add_block_to_block (&block, &rse->post);
4882 return gfc_finish_block (&block);
4886 /* Try to translate array(:) = func (...), where func is a transformational
4887 array function, without using a temporary. Returns NULL is this isn't the
4888 case. */
4890 static tree
4891 gfc_trans_arrayfunc_assign (gfc_expr * expr1, gfc_expr * expr2)
4893 gfc_se se;
4894 gfc_ss *ss;
4895 gfc_ref * ref;
4896 bool seen_array_ref;
4897 bool c = false;
4898 gfc_component *comp = NULL;
4900 /* The caller has already checked rank>0 and expr_type == EXPR_FUNCTION. */
4901 if (expr2->value.function.isym && !gfc_is_intrinsic_libcall (expr2))
4902 return NULL;
4904 /* Elemental functions don't need a temporary anyway. */
4905 if (expr2->value.function.esym != NULL
4906 && expr2->value.function.esym->attr.elemental)
4907 return NULL;
4909 /* Fail if rhs is not FULL or a contiguous section. */
4910 if (expr1->ref && !(gfc_full_array_ref_p (expr1->ref, &c) || c))
4911 return NULL;
4913 /* Fail if EXPR1 can't be expressed as a descriptor. */
4914 if (gfc_ref_needs_temporary_p (expr1->ref))
4915 return NULL;
4917 /* Functions returning pointers need temporaries. */
4918 if (expr2->symtree->n.sym->attr.pointer
4919 || expr2->symtree->n.sym->attr.allocatable)
4920 return NULL;
4922 /* Character array functions need temporaries unless the
4923 character lengths are the same. */
4924 if (expr2->ts.type == BT_CHARACTER && expr2->rank > 0)
4926 if (expr1->ts.u.cl->length == NULL
4927 || expr1->ts.u.cl->length->expr_type != EXPR_CONSTANT)
4928 return NULL;
4930 if (expr2->ts.u.cl->length == NULL
4931 || expr2->ts.u.cl->length->expr_type != EXPR_CONSTANT)
4932 return NULL;
4934 if (mpz_cmp (expr1->ts.u.cl->length->value.integer,
4935 expr2->ts.u.cl->length->value.integer) != 0)
4936 return NULL;
4939 /* Check that no LHS component references appear during an array
4940 reference. This is needed because we do not have the means to
4941 span any arbitrary stride with an array descriptor. This check
4942 is not needed for the rhs because the function result has to be
4943 a complete type. */
4944 seen_array_ref = false;
4945 for (ref = expr1->ref; ref; ref = ref->next)
4947 if (ref->type == REF_ARRAY)
4948 seen_array_ref= true;
4949 else if (ref->type == REF_COMPONENT && seen_array_ref)
4950 return NULL;
4953 /* Check for a dependency. */
4954 if (gfc_check_fncall_dependency (expr1, INTENT_OUT,
4955 expr2->value.function.esym,
4956 expr2->value.function.actual,
4957 NOT_ELEMENTAL))
4958 return NULL;
4960 /* The frontend doesn't seem to bother filling in expr->symtree for intrinsic
4961 functions. */
4962 gcc_assert (expr2->value.function.isym
4963 || (gfc_is_proc_ptr_comp (expr2, &comp)
4964 && comp && comp->attr.dimension)
4965 || (!comp && gfc_return_by_reference (expr2->value.function.esym)
4966 && expr2->value.function.esym->result->attr.dimension));
4968 ss = gfc_walk_expr (expr1);
4969 gcc_assert (ss != gfc_ss_terminator);
4970 gfc_init_se (&se, NULL);
4971 gfc_start_block (&se.pre);
4972 se.want_pointer = 1;
4974 gfc_conv_array_parameter (&se, expr1, ss, false, NULL, NULL, NULL);
4976 if (expr1->ts.type == BT_DERIVED
4977 && expr1->ts.u.derived->attr.alloc_comp)
4979 tree tmp;
4980 tmp = gfc_deallocate_alloc_comp (expr1->ts.u.derived, se.expr,
4981 expr1->rank);
4982 gfc_add_expr_to_block (&se.pre, tmp);
4985 se.direct_byref = 1;
4986 se.ss = gfc_walk_expr (expr2);
4987 gcc_assert (se.ss != gfc_ss_terminator);
4988 gfc_conv_function_expr (&se, expr2);
4989 gfc_add_block_to_block (&se.pre, &se.post);
4991 return gfc_finish_block (&se.pre);
4995 /* Try to efficiently translate array(:) = 0. Return NULL if this
4996 can't be done. */
4998 static tree
4999 gfc_trans_zero_assign (gfc_expr * expr)
5001 tree dest, len, type;
5002 tree tmp;
5003 gfc_symbol *sym;
5005 sym = expr->symtree->n.sym;
5006 dest = gfc_get_symbol_decl (sym);
5008 type = TREE_TYPE (dest);
5009 if (POINTER_TYPE_P (type))
5010 type = TREE_TYPE (type);
5011 if (!GFC_ARRAY_TYPE_P (type))
5012 return NULL_TREE;
5014 /* Determine the length of the array. */
5015 len = GFC_TYPE_ARRAY_SIZE (type);
5016 if (!len || TREE_CODE (len) != INTEGER_CST)
5017 return NULL_TREE;
5019 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type));
5020 len = fold_build2 (MULT_EXPR, gfc_array_index_type, len,
5021 fold_convert (gfc_array_index_type, tmp));
5023 /* If we are zeroing a local array avoid taking its address by emitting
5024 a = {} instead. */
5025 if (!POINTER_TYPE_P (TREE_TYPE (dest)))
5026 return build2 (MODIFY_EXPR, void_type_node,
5027 dest, build_constructor (TREE_TYPE (dest), NULL));
5029 /* Convert arguments to the correct types. */
5030 dest = fold_convert (pvoid_type_node, dest);
5031 len = fold_convert (size_type_node, len);
5033 /* Construct call to __builtin_memset. */
5034 tmp = build_call_expr_loc (input_location,
5035 built_in_decls[BUILT_IN_MEMSET],
5036 3, dest, integer_zero_node, len);
5037 return fold_convert (void_type_node, tmp);
5041 /* Helper for gfc_trans_array_copy and gfc_trans_array_constructor_copy
5042 that constructs the call to __builtin_memcpy. */
5044 tree
5045 gfc_build_memcpy_call (tree dst, tree src, tree len)
5047 tree tmp;
5049 /* Convert arguments to the correct types. */
5050 if (!POINTER_TYPE_P (TREE_TYPE (dst)))
5051 dst = gfc_build_addr_expr (pvoid_type_node, dst);
5052 else
5053 dst = fold_convert (pvoid_type_node, dst);
5055 if (!POINTER_TYPE_P (TREE_TYPE (src)))
5056 src = gfc_build_addr_expr (pvoid_type_node, src);
5057 else
5058 src = fold_convert (pvoid_type_node, src);
5060 len = fold_convert (size_type_node, len);
5062 /* Construct call to __builtin_memcpy. */
5063 tmp = build_call_expr_loc (input_location,
5064 built_in_decls[BUILT_IN_MEMCPY], 3, dst, src, len);
5065 return fold_convert (void_type_node, tmp);
5069 /* Try to efficiently translate dst(:) = src(:). Return NULL if this
5070 can't be done. EXPR1 is the destination/lhs and EXPR2 is the
5071 source/rhs, both are gfc_full_array_ref_p which have been checked for
5072 dependencies. */
5074 static tree
5075 gfc_trans_array_copy (gfc_expr * expr1, gfc_expr * expr2)
5077 tree dst, dlen, dtype;
5078 tree src, slen, stype;
5079 tree tmp;
5081 dst = gfc_get_symbol_decl (expr1->symtree->n.sym);
5082 src = gfc_get_symbol_decl (expr2->symtree->n.sym);
5084 dtype = TREE_TYPE (dst);
5085 if (POINTER_TYPE_P (dtype))
5086 dtype = TREE_TYPE (dtype);
5087 stype = TREE_TYPE (src);
5088 if (POINTER_TYPE_P (stype))
5089 stype = TREE_TYPE (stype);
5091 if (!GFC_ARRAY_TYPE_P (dtype) || !GFC_ARRAY_TYPE_P (stype))
5092 return NULL_TREE;
5094 /* Determine the lengths of the arrays. */
5095 dlen = GFC_TYPE_ARRAY_SIZE (dtype);
5096 if (!dlen || TREE_CODE (dlen) != INTEGER_CST)
5097 return NULL_TREE;
5098 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (dtype));
5099 dlen = fold_build2 (MULT_EXPR, gfc_array_index_type, dlen,
5100 fold_convert (gfc_array_index_type, tmp));
5102 slen = GFC_TYPE_ARRAY_SIZE (stype);
5103 if (!slen || TREE_CODE (slen) != INTEGER_CST)
5104 return NULL_TREE;
5105 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (stype));
5106 slen = fold_build2 (MULT_EXPR, gfc_array_index_type, slen,
5107 fold_convert (gfc_array_index_type, tmp));
5109 /* Sanity check that they are the same. This should always be
5110 the case, as we should already have checked for conformance. */
5111 if (!tree_int_cst_equal (slen, dlen))
5112 return NULL_TREE;
5114 return gfc_build_memcpy_call (dst, src, dlen);
5118 /* Try to efficiently translate array(:) = (/ ... /). Return NULL if
5119 this can't be done. EXPR1 is the destination/lhs for which
5120 gfc_full_array_ref_p is true, and EXPR2 is the source/rhs. */
5122 static tree
5123 gfc_trans_array_constructor_copy (gfc_expr * expr1, gfc_expr * expr2)
5125 unsigned HOST_WIDE_INT nelem;
5126 tree dst, dtype;
5127 tree src, stype;
5128 tree len;
5129 tree tmp;
5131 nelem = gfc_constant_array_constructor_p (expr2->value.constructor);
5132 if (nelem == 0)
5133 return NULL_TREE;
5135 dst = gfc_get_symbol_decl (expr1->symtree->n.sym);
5136 dtype = TREE_TYPE (dst);
5137 if (POINTER_TYPE_P (dtype))
5138 dtype = TREE_TYPE (dtype);
5139 if (!GFC_ARRAY_TYPE_P (dtype))
5140 return NULL_TREE;
5142 /* Determine the lengths of the array. */
5143 len = GFC_TYPE_ARRAY_SIZE (dtype);
5144 if (!len || TREE_CODE (len) != INTEGER_CST)
5145 return NULL_TREE;
5147 /* Confirm that the constructor is the same size. */
5148 if (compare_tree_int (len, nelem) != 0)
5149 return NULL_TREE;
5151 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (dtype));
5152 len = fold_build2 (MULT_EXPR, gfc_array_index_type, len,
5153 fold_convert (gfc_array_index_type, tmp));
5155 stype = gfc_typenode_for_spec (&expr2->ts);
5156 src = gfc_build_constant_array_constructor (expr2, stype);
5158 stype = TREE_TYPE (src);
5159 if (POINTER_TYPE_P (stype))
5160 stype = TREE_TYPE (stype);
5162 return gfc_build_memcpy_call (dst, src, len);
5166 /* Subroutine of gfc_trans_assignment that actually scalarizes the
5167 assignment. EXPR1 is the destination/LHS and EXPR2 is the source/RHS.
5168 init_flag indicates initialization expressions and dealloc that no
5169 deallocate prior assignment is needed (if in doubt, set true). */
5171 static tree
5172 gfc_trans_assignment_1 (gfc_expr * expr1, gfc_expr * expr2, bool init_flag,
5173 bool dealloc)
5175 gfc_se lse;
5176 gfc_se rse;
5177 gfc_ss *lss;
5178 gfc_ss *lss_section;
5179 gfc_ss *rss;
5180 gfc_loopinfo loop;
5181 tree tmp;
5182 stmtblock_t block;
5183 stmtblock_t body;
5184 bool l_is_temp;
5185 bool scalar_to_array;
5186 tree string_length;
5188 /* Assignment of the form lhs = rhs. */
5189 gfc_start_block (&block);
5191 gfc_init_se (&lse, NULL);
5192 gfc_init_se (&rse, NULL);
5194 /* Walk the lhs. */
5195 lss = gfc_walk_expr (expr1);
5196 rss = NULL;
5197 if (lss != gfc_ss_terminator)
5199 /* Allow the scalarizer to workshare array assignments. */
5200 if (ompws_flags & OMPWS_WORKSHARE_FLAG)
5201 ompws_flags |= OMPWS_SCALARIZER_WS;
5203 /* The assignment needs scalarization. */
5204 lss_section = lss;
5206 /* Find a non-scalar SS from the lhs. */
5207 while (lss_section != gfc_ss_terminator
5208 && lss_section->type != GFC_SS_SECTION)
5209 lss_section = lss_section->next;
5211 gcc_assert (lss_section != gfc_ss_terminator);
5213 /* Initialize the scalarizer. */
5214 gfc_init_loopinfo (&loop);
5216 /* Walk the rhs. */
5217 rss = gfc_walk_expr (expr2);
5218 if (rss == gfc_ss_terminator)
5220 /* The rhs is scalar. Add a ss for the expression. */
5221 rss = gfc_get_ss ();
5222 rss->next = gfc_ss_terminator;
5223 rss->type = GFC_SS_SCALAR;
5224 rss->expr = expr2;
5226 /* Associate the SS with the loop. */
5227 gfc_add_ss_to_loop (&loop, lss);
5228 gfc_add_ss_to_loop (&loop, rss);
5230 /* Calculate the bounds of the scalarization. */
5231 gfc_conv_ss_startstride (&loop);
5232 /* Resolve any data dependencies in the statement. */
5233 gfc_conv_resolve_dependencies (&loop, lss, rss);
5234 /* Setup the scalarizing loops. */
5235 gfc_conv_loop_setup (&loop, &expr2->where);
5237 /* Setup the gfc_se structures. */
5238 gfc_copy_loopinfo_to_se (&lse, &loop);
5239 gfc_copy_loopinfo_to_se (&rse, &loop);
5241 rse.ss = rss;
5242 gfc_mark_ss_chain_used (rss, 1);
5243 if (loop.temp_ss == NULL)
5245 lse.ss = lss;
5246 gfc_mark_ss_chain_used (lss, 1);
5248 else
5250 lse.ss = loop.temp_ss;
5251 gfc_mark_ss_chain_used (lss, 3);
5252 gfc_mark_ss_chain_used (loop.temp_ss, 3);
5255 /* Start the scalarized loop body. */
5256 gfc_start_scalarized_body (&loop, &body);
5258 else
5259 gfc_init_block (&body);
5261 l_is_temp = (lss != gfc_ss_terminator && loop.temp_ss != NULL);
5263 /* Translate the expression. */
5264 gfc_conv_expr (&rse, expr2);
5266 /* Stabilize a string length for temporaries. */
5267 if (expr2->ts.type == BT_CHARACTER)
5268 string_length = gfc_evaluate_now (rse.string_length, &rse.pre);
5269 else
5270 string_length = NULL_TREE;
5272 if (l_is_temp)
5274 gfc_conv_tmp_array_ref (&lse);
5275 gfc_advance_se_ss_chain (&lse);
5276 if (expr2->ts.type == BT_CHARACTER)
5277 lse.string_length = string_length;
5279 else
5280 gfc_conv_expr (&lse, expr1);
5282 /* Assignments of scalar derived types with allocatable components
5283 to arrays must be done with a deep copy and the rhs temporary
5284 must have its components deallocated afterwards. */
5285 scalar_to_array = (expr2->ts.type == BT_DERIVED
5286 && expr2->ts.u.derived->attr.alloc_comp
5287 && expr2->expr_type != EXPR_VARIABLE
5288 && !gfc_is_constant_expr (expr2)
5289 && expr1->rank && !expr2->rank);
5290 if (scalar_to_array && dealloc)
5292 tmp = gfc_deallocate_alloc_comp (expr2->ts.u.derived, rse.expr, 0);
5293 gfc_add_expr_to_block (&loop.post, tmp);
5296 tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts,
5297 l_is_temp || init_flag,
5298 (expr2->expr_type == EXPR_VARIABLE)
5299 || scalar_to_array, dealloc);
5300 gfc_add_expr_to_block (&body, tmp);
5302 if (lss == gfc_ss_terminator)
5304 /* Use the scalar assignment as is. */
5305 gfc_add_block_to_block (&block, &body);
5307 else
5309 gcc_assert (lse.ss == gfc_ss_terminator
5310 && rse.ss == gfc_ss_terminator);
5312 if (l_is_temp)
5314 gfc_trans_scalarized_loop_boundary (&loop, &body);
5316 /* We need to copy the temporary to the actual lhs. */
5317 gfc_init_se (&lse, NULL);
5318 gfc_init_se (&rse, NULL);
5319 gfc_copy_loopinfo_to_se (&lse, &loop);
5320 gfc_copy_loopinfo_to_se (&rse, &loop);
5322 rse.ss = loop.temp_ss;
5323 lse.ss = lss;
5325 gfc_conv_tmp_array_ref (&rse);
5326 gfc_advance_se_ss_chain (&rse);
5327 gfc_conv_expr (&lse, expr1);
5329 gcc_assert (lse.ss == gfc_ss_terminator
5330 && rse.ss == gfc_ss_terminator);
5332 if (expr2->ts.type == BT_CHARACTER)
5333 rse.string_length = string_length;
5335 tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts,
5336 false, false, dealloc);
5337 gfc_add_expr_to_block (&body, tmp);
5340 /* Generate the copying loops. */
5341 gfc_trans_scalarizing_loops (&loop, &body);
5343 /* Wrap the whole thing up. */
5344 gfc_add_block_to_block (&block, &loop.pre);
5345 gfc_add_block_to_block (&block, &loop.post);
5347 gfc_cleanup_loop (&loop);
5350 return gfc_finish_block (&block);
5354 /* Check whether EXPR is a copyable array. */
5356 static bool
5357 copyable_array_p (gfc_expr * expr)
5359 if (expr->expr_type != EXPR_VARIABLE)
5360 return false;
5362 /* First check it's an array. */
5363 if (expr->rank < 1 || !expr->ref || expr->ref->next)
5364 return false;
5366 if (!gfc_full_array_ref_p (expr->ref, NULL))
5367 return false;
5369 /* Next check that it's of a simple enough type. */
5370 switch (expr->ts.type)
5372 case BT_INTEGER:
5373 case BT_REAL:
5374 case BT_COMPLEX:
5375 case BT_LOGICAL:
5376 return true;
5378 case BT_CHARACTER:
5379 return false;
5381 case BT_DERIVED:
5382 return !expr->ts.u.derived->attr.alloc_comp;
5384 default:
5385 break;
5388 return false;
5391 /* Translate an assignment. */
5393 tree
5394 gfc_trans_assignment (gfc_expr * expr1, gfc_expr * expr2, bool init_flag,
5395 bool dealloc)
5397 tree tmp;
5399 /* Special case a single function returning an array. */
5400 if (expr2->expr_type == EXPR_FUNCTION && expr2->rank > 0)
5402 tmp = gfc_trans_arrayfunc_assign (expr1, expr2);
5403 if (tmp)
5404 return tmp;
5407 /* Special case assigning an array to zero. */
5408 if (copyable_array_p (expr1)
5409 && is_zero_initializer_p (expr2))
5411 tmp = gfc_trans_zero_assign (expr1);
5412 if (tmp)
5413 return tmp;
5416 /* Special case copying one array to another. */
5417 if (copyable_array_p (expr1)
5418 && copyable_array_p (expr2)
5419 && gfc_compare_types (&expr1->ts, &expr2->ts)
5420 && !gfc_check_dependency (expr1, expr2, 0))
5422 tmp = gfc_trans_array_copy (expr1, expr2);
5423 if (tmp)
5424 return tmp;
5427 /* Special case initializing an array from a constant array constructor. */
5428 if (copyable_array_p (expr1)
5429 && expr2->expr_type == EXPR_ARRAY
5430 && gfc_compare_types (&expr1->ts, &expr2->ts))
5432 tmp = gfc_trans_array_constructor_copy (expr1, expr2);
5433 if (tmp)
5434 return tmp;
5437 /* Fallback to the scalarizer to generate explicit loops. */
5438 return gfc_trans_assignment_1 (expr1, expr2, init_flag, dealloc);
5441 tree
5442 gfc_trans_init_assign (gfc_code * code)
5444 return gfc_trans_assignment (code->expr1, code->expr2, true, false);
5447 tree
5448 gfc_trans_assign (gfc_code * code)
5450 return gfc_trans_assignment (code->expr1, code->expr2, false, true);
5454 /* Generate code to assign typebound procedures to a derived vtab. */
5455 void gfc_trans_assign_vtab_procs (stmtblock_t *block, gfc_symbol *dt,
5456 gfc_symbol *vtab)
5458 gfc_component *cmp;
5459 tree vtb;
5460 tree ctree;
5461 tree proc;
5462 tree cond = NULL_TREE;
5463 stmtblock_t body;
5464 bool seen_extends;
5466 /* Point to the first procedure pointer. */
5467 cmp = gfc_find_component (vtab->ts.u.derived, "$extends", true, true);
5469 seen_extends = (cmp != NULL);
5471 vtb = gfc_get_symbol_decl (vtab);
5473 if (seen_extends)
5475 cmp = cmp->next;
5476 if (!cmp)
5477 return;
5478 ctree = fold_build3 (COMPONENT_REF, TREE_TYPE (cmp->backend_decl),
5479 vtb, cmp->backend_decl, NULL_TREE);
5480 cond = fold_build2 (EQ_EXPR, boolean_type_node, ctree,
5481 build_int_cst (TREE_TYPE (ctree), 0));
5483 else
5485 cmp = vtab->ts.u.derived->components;
5488 gfc_init_block (&body);
5489 for (; cmp; cmp = cmp->next)
5491 gfc_symbol *target = NULL;
5493 /* Generic procedure - build its vtab. */
5494 if (cmp->ts.type == BT_DERIVED && !cmp->tb)
5496 gfc_symbol *vt = cmp->ts.interface;
5498 if (vt == NULL)
5500 /* Use association loses the interface. Obtain the vtab
5501 by name instead. */
5502 char name[2 * GFC_MAX_SYMBOL_LEN + 8];
5503 sprintf (name, "vtab$%s$%s", vtab->ts.u.derived->name,
5504 cmp->name);
5505 gfc_find_symbol (name, vtab->ns, 0, &vt);
5506 if (vt == NULL)
5507 continue;
5510 gfc_trans_assign_vtab_procs (&body, dt, vt);
5511 ctree = fold_build3 (COMPONENT_REF, TREE_TYPE (cmp->backend_decl),
5512 vtb, cmp->backend_decl, NULL_TREE);
5513 proc = gfc_get_symbol_decl (vt);
5514 proc = gfc_build_addr_expr (TREE_TYPE (ctree), proc);
5515 gfc_add_modify (&body, ctree, proc);
5516 continue;
5519 /* This is required when typebound generic procedures are called
5520 with derived type targets. The specific procedures do not get
5521 added to the vtype, which remains "empty". */
5522 if (cmp->tb && cmp->tb->u.specific && cmp->tb->u.specific->n.sym)
5523 target = cmp->tb->u.specific->n.sym;
5524 else
5526 gfc_symtree *st;
5527 st = gfc_find_typebound_proc (dt, NULL, cmp->name, false, NULL);
5528 if (st->n.tb && st->n.tb->u.specific)
5529 target = st->n.tb->u.specific->n.sym;
5532 if (!target)
5533 continue;
5535 ctree = fold_build3 (COMPONENT_REF, TREE_TYPE (cmp->backend_decl),
5536 vtb, cmp->backend_decl, NULL_TREE);
5537 proc = gfc_get_symbol_decl (target);
5538 proc = gfc_build_addr_expr (TREE_TYPE (ctree), proc);
5539 gfc_add_modify (&body, ctree, proc);
5542 proc = gfc_finish_block (&body);
5544 if (seen_extends)
5545 proc = build3_v (COND_EXPR, cond, proc, build_empty_stmt (input_location));
5547 gfc_add_expr_to_block (block, proc);
5551 /* Translate an assignment to a CLASS object
5552 (pointer or ordinary assignment). */
5554 tree
5555 gfc_trans_class_assign (gfc_code *code)
5557 stmtblock_t block;
5558 tree tmp;
5559 gfc_expr *lhs;
5560 gfc_expr *rhs;
5562 gfc_start_block (&block);
5564 if (code->op == EXEC_INIT_ASSIGN)
5566 /* Special case for initializing a CLASS variable on allocation.
5567 A MEMCPY is needed to copy the full data of the dynamic type,
5568 which may be different from the declared type. */
5569 gfc_se dst,src;
5570 tree memsz;
5571 gfc_init_se (&dst, NULL);
5572 gfc_init_se (&src, NULL);
5573 gfc_add_component_ref (code->expr1, "$data");
5574 gfc_conv_expr (&dst, code->expr1);
5575 gfc_conv_expr (&src, code->expr2);
5576 gfc_add_block_to_block (&block, &src.pre);
5577 memsz = TYPE_SIZE_UNIT (gfc_typenode_for_spec (&code->expr2->ts));
5578 tmp = gfc_build_memcpy_call (dst.expr, src.expr, memsz);
5579 gfc_add_expr_to_block (&block, tmp);
5580 return gfc_finish_block (&block);
5583 if (code->expr2->ts.type != BT_CLASS)
5585 /* Insert an additional assignment which sets the '$vptr' field. */
5586 lhs = gfc_copy_expr (code->expr1);
5587 gfc_add_component_ref (lhs, "$vptr");
5588 if (code->expr2->ts.type == BT_DERIVED)
5590 gfc_symbol *vtab;
5591 gfc_symtree *st;
5592 vtab = gfc_find_derived_vtab (code->expr2->ts.u.derived, true);
5593 gcc_assert (vtab);
5594 gfc_trans_assign_vtab_procs (&block, code->expr2->ts.u.derived, vtab);
5595 rhs = gfc_get_expr ();
5596 rhs->expr_type = EXPR_VARIABLE;
5597 gfc_find_sym_tree (vtab->name, NULL, 1, &st);
5598 rhs->symtree = st;
5599 rhs->ts = vtab->ts;
5601 else if (code->expr2->expr_type == EXPR_NULL)
5602 rhs = gfc_get_int_expr (gfc_default_integer_kind, NULL, 0);
5603 else
5604 gcc_unreachable ();
5606 tmp = gfc_trans_pointer_assignment (lhs, rhs);
5607 gfc_add_expr_to_block (&block, tmp);
5609 gfc_free_expr (lhs);
5610 gfc_free_expr (rhs);
5613 /* Do the actual CLASS assignment. */
5614 if (code->expr2->ts.type == BT_CLASS)
5615 code->op = EXEC_ASSIGN;
5616 else
5617 gfc_add_component_ref (code->expr1, "$data");
5619 if (code->op == EXEC_ASSIGN)
5620 tmp = gfc_trans_assign (code);
5621 else if (code->op == EXEC_POINTER_ASSIGN)
5622 tmp = gfc_trans_pointer_assign (code);
5623 else
5624 gcc_unreachable();
5626 gfc_add_expr_to_block (&block, tmp);
5628 return gfc_finish_block (&block);