* c-common.c (get_priority): Add check for
[official-gcc.git] / gcc / fortran / trans-expr.c
blob839d768318e7b9ff5a663fb8ee63df4d81581c1f
1 /* Expression translation
2 Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
3 Contributed by Paul Brook <paul@nowt.org>
4 and Steven Bosscher <s.bosscher@student.tudelft.nl>
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 2, or (at your option) any later
11 version.
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 for more details.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING. If not, write to the Free
20 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
21 02110-1301, USA. */
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 "tree-gimple.h"
34 #include "langhooks.h"
35 #include "flags.h"
36 #include "gfortran.h"
37 #include "trans.h"
38 #include "trans-const.h"
39 #include "trans-types.h"
40 #include "trans-array.h"
41 /* Only for gfc_trans_assign and gfc_trans_pointer_assign. */
42 #include "trans-stmt.h"
43 #include "dependency.h"
45 static tree gfc_trans_structure_assign (tree dest, gfc_expr * expr);
46 static void gfc_apply_interface_mapping_to_expr (gfc_interface_mapping *,
47 gfc_expr *);
49 /* Copy the scalarization loop variables. */
51 static void
52 gfc_copy_se_loopvars (gfc_se * dest, gfc_se * src)
54 dest->ss = src->ss;
55 dest->loop = src->loop;
59 /* Initialize a simple expression holder.
61 Care must be taken when multiple se are created with the same parent.
62 The child se must be kept in sync. The easiest way is to delay creation
63 of a child se until after after the previous se has been translated. */
65 void
66 gfc_init_se (gfc_se * se, gfc_se * parent)
68 memset (se, 0, sizeof (gfc_se));
69 gfc_init_block (&se->pre);
70 gfc_init_block (&se->post);
72 se->parent = parent;
74 if (parent)
75 gfc_copy_se_loopvars (se, parent);
79 /* Advances to the next SS in the chain. Use this rather than setting
80 se->ss = se->ss->next because all the parents needs to be kept in sync.
81 See gfc_init_se. */
83 void
84 gfc_advance_se_ss_chain (gfc_se * se)
86 gfc_se *p;
88 gcc_assert (se != NULL && se->ss != NULL && se->ss != gfc_ss_terminator);
90 p = se;
91 /* Walk down the parent chain. */
92 while (p != NULL)
94 /* Simple consistency check. */
95 gcc_assert (p->parent == NULL || p->parent->ss == p->ss);
97 p->ss = p->ss->next;
99 p = p->parent;
104 /* Ensures the result of the expression as either a temporary variable
105 or a constant so that it can be used repeatedly. */
107 void
108 gfc_make_safe_expr (gfc_se * se)
110 tree var;
112 if (CONSTANT_CLASS_P (se->expr))
113 return;
115 /* We need a temporary for this result. */
116 var = gfc_create_var (TREE_TYPE (se->expr), NULL);
117 gfc_add_modify_expr (&se->pre, var, se->expr);
118 se->expr = var;
122 /* Return an expression which determines if a dummy parameter is present.
123 Also used for arguments to procedures with multiple entry points. */
125 tree
126 gfc_conv_expr_present (gfc_symbol * sym)
128 tree decl;
130 gcc_assert (sym->attr.dummy);
132 decl = gfc_get_symbol_decl (sym);
133 if (TREE_CODE (decl) != PARM_DECL)
135 /* Array parameters use a temporary descriptor, we want the real
136 parameter. */
137 gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl))
138 || GFC_ARRAY_TYPE_P (TREE_TYPE (decl)));
139 decl = GFC_DECL_SAVED_DESCRIPTOR (decl);
141 return build2 (NE_EXPR, boolean_type_node, decl,
142 fold_convert (TREE_TYPE (decl), null_pointer_node));
146 /* Converts a missing, dummy argument into a null or zero. */
148 void
149 gfc_conv_missing_dummy (gfc_se * se, gfc_expr * arg, gfc_typespec ts)
151 tree present;
152 tree tmp;
154 present = gfc_conv_expr_present (arg->symtree->n.sym);
155 tmp = build3 (COND_EXPR, TREE_TYPE (se->expr), present, se->expr,
156 fold_convert (TREE_TYPE (se->expr), integer_zero_node));
158 tmp = gfc_evaluate_now (tmp, &se->pre);
159 se->expr = tmp;
160 if (ts.type == BT_CHARACTER)
162 tmp = build_int_cst (gfc_charlen_type_node, 0);
163 tmp = build3 (COND_EXPR, gfc_charlen_type_node, present,
164 se->string_length, tmp);
165 tmp = gfc_evaluate_now (tmp, &se->pre);
166 se->string_length = tmp;
168 return;
172 /* Get the character length of an expression, looking through gfc_refs
173 if necessary. */
175 tree
176 gfc_get_expr_charlen (gfc_expr *e)
178 gfc_ref *r;
179 tree length;
181 gcc_assert (e->expr_type == EXPR_VARIABLE
182 && e->ts.type == BT_CHARACTER);
184 length = NULL; /* To silence compiler warning. */
186 /* First candidate: if the variable is of type CHARACTER, the
187 expression's length could be the length of the character
188 variable. */
189 if (e->symtree->n.sym->ts.type == BT_CHARACTER)
190 length = e->symtree->n.sym->ts.cl->backend_decl;
192 /* Look through the reference chain for component references. */
193 for (r = e->ref; r; r = r->next)
195 switch (r->type)
197 case REF_COMPONENT:
198 if (r->u.c.component->ts.type == BT_CHARACTER)
199 length = r->u.c.component->ts.cl->backend_decl;
200 break;
202 case REF_ARRAY:
203 /* Do nothing. */
204 break;
206 default:
207 /* We should never got substring references here. These will be
208 broken down by the scalarizer. */
209 gcc_unreachable ();
213 gcc_assert (length != NULL);
214 return length;
219 /* Generate code to initialize a string length variable. Returns the
220 value. */
222 void
223 gfc_trans_init_string_length (gfc_charlen * cl, stmtblock_t * pblock)
225 gfc_se se;
226 tree tmp;
228 gfc_init_se (&se, NULL);
229 gfc_conv_expr_type (&se, cl->length, gfc_charlen_type_node);
230 gfc_add_block_to_block (pblock, &se.pre);
232 tmp = cl->backend_decl;
233 gfc_add_modify_expr (pblock, tmp, se.expr);
237 static void
238 gfc_conv_substring (gfc_se * se, gfc_ref * ref, int kind,
239 const char *name, locus *where)
241 tree tmp;
242 tree type;
243 tree var;
244 tree fault;
245 gfc_se start;
246 gfc_se end;
247 char *msg;
249 type = gfc_get_character_type (kind, ref->u.ss.length);
250 type = build_pointer_type (type);
252 var = NULL_TREE;
253 gfc_init_se (&start, se);
254 gfc_conv_expr_type (&start, ref->u.ss.start, gfc_charlen_type_node);
255 gfc_add_block_to_block (&se->pre, &start.pre);
257 if (integer_onep (start.expr))
258 gfc_conv_string_parameter (se);
259 else
261 /* Change the start of the string. */
262 if (TYPE_STRING_FLAG (TREE_TYPE (se->expr)))
263 tmp = se->expr;
264 else
265 tmp = build_fold_indirect_ref (se->expr);
266 tmp = gfc_build_array_ref (tmp, start.expr);
267 se->expr = gfc_build_addr_expr (type, tmp);
270 /* Length = end + 1 - start. */
271 gfc_init_se (&end, se);
272 if (ref->u.ss.end == NULL)
273 end.expr = se->string_length;
274 else
276 gfc_conv_expr_type (&end, ref->u.ss.end, gfc_charlen_type_node);
277 gfc_add_block_to_block (&se->pre, &end.pre);
279 if (flag_bounds_check)
281 tree nonempty = fold_build2 (LE_EXPR, boolean_type_node,
282 start.expr, end.expr);
284 /* Check lower bound. */
285 fault = fold_build2 (LT_EXPR, boolean_type_node, start.expr,
286 build_int_cst (gfc_charlen_type_node, 1));
287 fault = fold_build2 (TRUTH_ANDIF_EXPR, boolean_type_node,
288 nonempty, fault);
289 if (name)
290 asprintf (&msg, "Substring out of bounds: lower bound of '%s' "
291 "is less than one", name);
292 else
293 asprintf (&msg, "Substring out of bounds: lower bound "
294 "is less than one");
295 gfc_trans_runtime_check (fault, msg, &se->pre, where);
296 gfc_free (msg);
298 /* Check upper bound. */
299 fault = fold_build2 (GT_EXPR, boolean_type_node, end.expr,
300 se->string_length);
301 fault = fold_build2 (TRUTH_ANDIF_EXPR, boolean_type_node,
302 nonempty, fault);
303 if (name)
304 asprintf (&msg, "Substring out of bounds: upper bound of '%s' "
305 "exceeds string length", name);
306 else
307 asprintf (&msg, "Substring out of bounds: upper bound "
308 "exceeds string length");
309 gfc_trans_runtime_check (fault, msg, &se->pre, where);
310 gfc_free (msg);
313 tmp = fold_build2 (MINUS_EXPR, gfc_charlen_type_node,
314 build_int_cst (gfc_charlen_type_node, 1),
315 start.expr);
316 tmp = fold_build2 (PLUS_EXPR, gfc_charlen_type_node, end.expr, tmp);
317 tmp = fold_build2 (MAX_EXPR, gfc_charlen_type_node, tmp,
318 build_int_cst (gfc_charlen_type_node, 0));
319 se->string_length = tmp;
323 /* Convert a derived type component reference. */
325 static void
326 gfc_conv_component_ref (gfc_se * se, gfc_ref * ref)
328 gfc_component *c;
329 tree tmp;
330 tree decl;
331 tree field;
333 c = ref->u.c.component;
335 gcc_assert (c->backend_decl);
337 field = c->backend_decl;
338 gcc_assert (TREE_CODE (field) == FIELD_DECL);
339 decl = se->expr;
340 tmp = build3 (COMPONENT_REF, TREE_TYPE (field), decl, field, NULL_TREE);
342 se->expr = tmp;
344 if (c->ts.type == BT_CHARACTER)
346 tmp = c->ts.cl->backend_decl;
347 /* Components must always be constant length. */
348 gcc_assert (tmp && INTEGER_CST_P (tmp));
349 se->string_length = tmp;
352 if (c->pointer && c->dimension == 0 && c->ts.type != BT_CHARACTER)
353 se->expr = build_fold_indirect_ref (se->expr);
357 /* Return the contents of a variable. Also handles reference/pointer
358 variables (all Fortran pointer references are implicit). */
360 static void
361 gfc_conv_variable (gfc_se * se, gfc_expr * expr)
363 gfc_ref *ref;
364 gfc_symbol *sym;
365 tree parent_decl;
366 int parent_flag;
367 bool return_value;
368 bool alternate_entry;
369 bool entry_master;
371 sym = expr->symtree->n.sym;
372 if (se->ss != NULL)
374 /* Check that something hasn't gone horribly wrong. */
375 gcc_assert (se->ss != gfc_ss_terminator);
376 gcc_assert (se->ss->expr == expr);
378 /* A scalarized term. We already know the descriptor. */
379 se->expr = se->ss->data.info.descriptor;
380 se->string_length = se->ss->string_length;
381 for (ref = se->ss->data.info.ref; ref; ref = ref->next)
382 if (ref->type == REF_ARRAY && ref->u.ar.type != AR_ELEMENT)
383 break;
385 else
387 tree se_expr = NULL_TREE;
389 se->expr = gfc_get_symbol_decl (sym);
391 /* Deal with references to a parent results or entries by storing
392 the current_function_decl and moving to the parent_decl. */
393 return_value = sym->attr.function && sym->result == sym;
394 alternate_entry = sym->attr.function && sym->attr.entry
395 && sym->result == sym;
396 entry_master = sym->attr.result
397 && sym->ns->proc_name->attr.entry_master
398 && !gfc_return_by_reference (sym->ns->proc_name);
399 parent_decl = DECL_CONTEXT (current_function_decl);
401 if ((se->expr == parent_decl && return_value)
402 || (sym->ns && sym->ns->proc_name
403 && parent_decl
404 && sym->ns->proc_name->backend_decl == parent_decl
405 && (alternate_entry || entry_master)))
406 parent_flag = 1;
407 else
408 parent_flag = 0;
410 /* Special case for assigning the return value of a function.
411 Self recursive functions must have an explicit return value. */
412 if (return_value && (se->expr == current_function_decl || parent_flag))
413 se_expr = gfc_get_fake_result_decl (sym, parent_flag);
415 /* Similarly for alternate entry points. */
416 else if (alternate_entry
417 && (sym->ns->proc_name->backend_decl == current_function_decl
418 || parent_flag))
420 gfc_entry_list *el = NULL;
422 for (el = sym->ns->entries; el; el = el->next)
423 if (sym == el->sym)
425 se_expr = gfc_get_fake_result_decl (sym, parent_flag);
426 break;
430 else if (entry_master
431 && (sym->ns->proc_name->backend_decl == current_function_decl
432 || parent_flag))
433 se_expr = gfc_get_fake_result_decl (sym, parent_flag);
435 if (se_expr)
436 se->expr = se_expr;
438 /* Procedure actual arguments. */
439 else if (sym->attr.flavor == FL_PROCEDURE
440 && se->expr != current_function_decl)
442 gcc_assert (se->want_pointer);
443 if (!sym->attr.dummy)
445 gcc_assert (TREE_CODE (se->expr) == FUNCTION_DECL);
446 se->expr = build_fold_addr_expr (se->expr);
448 return;
452 /* Dereference the expression, where needed. Since characters
453 are entirely different from other types, they are treated
454 separately. */
455 if (sym->ts.type == BT_CHARACTER)
457 /* Dereference character pointer dummy arguments
458 or results. */
459 if ((sym->attr.pointer || sym->attr.allocatable)
460 && (sym->attr.dummy
461 || sym->attr.function
462 || sym->attr.result))
463 se->expr = build_fold_indirect_ref (se->expr);
465 /* A character with VALUE attribute needs an address
466 expression. */
467 if (sym->attr.value)
468 se->expr = build_fold_addr_expr (se->expr);
471 else if (!sym->attr.value)
473 /* Dereference non-character scalar dummy arguments. */
474 if (sym->attr.dummy && !sym->attr.dimension)
475 se->expr = build_fold_indirect_ref (se->expr);
477 /* Dereference scalar hidden result. */
478 if (gfc_option.flag_f2c && sym->ts.type == BT_COMPLEX
479 && (sym->attr.function || sym->attr.result)
480 && !sym->attr.dimension && !sym->attr.pointer)
481 se->expr = build_fold_indirect_ref (se->expr);
483 /* Dereference non-character pointer variables.
484 These must be dummies, results, or scalars. */
485 if ((sym->attr.pointer || sym->attr.allocatable)
486 && (sym->attr.dummy
487 || sym->attr.function
488 || sym->attr.result
489 || !sym->attr.dimension))
490 se->expr = build_fold_indirect_ref (se->expr);
493 ref = expr->ref;
496 /* For character variables, also get the length. */
497 if (sym->ts.type == BT_CHARACTER)
499 /* If the character length of an entry isn't set, get the length from
500 the master function instead. */
501 if (sym->attr.entry && !sym->ts.cl->backend_decl)
502 se->string_length = sym->ns->proc_name->ts.cl->backend_decl;
503 else
504 se->string_length = sym->ts.cl->backend_decl;
505 gcc_assert (se->string_length);
508 while (ref)
510 switch (ref->type)
512 case REF_ARRAY:
513 /* Return the descriptor if that's what we want and this is an array
514 section reference. */
515 if (se->descriptor_only && ref->u.ar.type != AR_ELEMENT)
516 return;
517 /* TODO: Pointers to single elements of array sections, eg elemental subs. */
518 /* Return the descriptor for array pointers and allocations. */
519 if (se->want_pointer
520 && ref->next == NULL && (se->descriptor_only))
521 return;
523 gfc_conv_array_ref (se, &ref->u.ar, sym, &expr->where);
524 /* Return a pointer to an element. */
525 break;
527 case REF_COMPONENT:
528 gfc_conv_component_ref (se, ref);
529 break;
531 case REF_SUBSTRING:
532 gfc_conv_substring (se, ref, expr->ts.kind,
533 expr->symtree->name, &expr->where);
534 break;
536 default:
537 gcc_unreachable ();
538 break;
540 ref = ref->next;
542 /* Pointer assignment, allocation or pass by reference. Arrays are handled
543 separately. */
544 if (se->want_pointer)
546 if (expr->ts.type == BT_CHARACTER)
547 gfc_conv_string_parameter (se);
548 else
549 se->expr = build_fold_addr_expr (se->expr);
554 /* Unary ops are easy... Or they would be if ! was a valid op. */
556 static void
557 gfc_conv_unary_op (enum tree_code code, gfc_se * se, gfc_expr * expr)
559 gfc_se operand;
560 tree type;
562 gcc_assert (expr->ts.type != BT_CHARACTER);
563 /* Initialize the operand. */
564 gfc_init_se (&operand, se);
565 gfc_conv_expr_val (&operand, expr->value.op.op1);
566 gfc_add_block_to_block (&se->pre, &operand.pre);
568 type = gfc_typenode_for_spec (&expr->ts);
570 /* TRUTH_NOT_EXPR is not a "true" unary operator in GCC.
571 We must convert it to a compare to 0 (e.g. EQ_EXPR (op1, 0)).
572 All other unary operators have an equivalent GIMPLE unary operator. */
573 if (code == TRUTH_NOT_EXPR)
574 se->expr = build2 (EQ_EXPR, type, operand.expr,
575 build_int_cst (type, 0));
576 else
577 se->expr = build1 (code, type, operand.expr);
581 /* Expand power operator to optimal multiplications when a value is raised
582 to a constant integer n. See section 4.6.3, "Evaluation of Powers" of
583 Donald E. Knuth, "Seminumerical Algorithms", Vol. 2, "The Art of Computer
584 Programming", 3rd Edition, 1998. */
586 /* This code is mostly duplicated from expand_powi in the backend.
587 We establish the "optimal power tree" lookup table with the defined size.
588 The items in the table are the exponents used to calculate the index
589 exponents. Any integer n less than the value can get an "addition chain",
590 with the first node being one. */
591 #define POWI_TABLE_SIZE 256
593 /* The table is from builtins.c. */
594 static const unsigned char powi_table[POWI_TABLE_SIZE] =
596 0, 1, 1, 2, 2, 3, 3, 4, /* 0 - 7 */
597 4, 6, 5, 6, 6, 10, 7, 9, /* 8 - 15 */
598 8, 16, 9, 16, 10, 12, 11, 13, /* 16 - 23 */
599 12, 17, 13, 18, 14, 24, 15, 26, /* 24 - 31 */
600 16, 17, 17, 19, 18, 33, 19, 26, /* 32 - 39 */
601 20, 25, 21, 40, 22, 27, 23, 44, /* 40 - 47 */
602 24, 32, 25, 34, 26, 29, 27, 44, /* 48 - 55 */
603 28, 31, 29, 34, 30, 60, 31, 36, /* 56 - 63 */
604 32, 64, 33, 34, 34, 46, 35, 37, /* 64 - 71 */
605 36, 65, 37, 50, 38, 48, 39, 69, /* 72 - 79 */
606 40, 49, 41, 43, 42, 51, 43, 58, /* 80 - 87 */
607 44, 64, 45, 47, 46, 59, 47, 76, /* 88 - 95 */
608 48, 65, 49, 66, 50, 67, 51, 66, /* 96 - 103 */
609 52, 70, 53, 74, 54, 104, 55, 74, /* 104 - 111 */
610 56, 64, 57, 69, 58, 78, 59, 68, /* 112 - 119 */
611 60, 61, 61, 80, 62, 75, 63, 68, /* 120 - 127 */
612 64, 65, 65, 128, 66, 129, 67, 90, /* 128 - 135 */
613 68, 73, 69, 131, 70, 94, 71, 88, /* 136 - 143 */
614 72, 128, 73, 98, 74, 132, 75, 121, /* 144 - 151 */
615 76, 102, 77, 124, 78, 132, 79, 106, /* 152 - 159 */
616 80, 97, 81, 160, 82, 99, 83, 134, /* 160 - 167 */
617 84, 86, 85, 95, 86, 160, 87, 100, /* 168 - 175 */
618 88, 113, 89, 98, 90, 107, 91, 122, /* 176 - 183 */
619 92, 111, 93, 102, 94, 126, 95, 150, /* 184 - 191 */
620 96, 128, 97, 130, 98, 133, 99, 195, /* 192 - 199 */
621 100, 128, 101, 123, 102, 164, 103, 138, /* 200 - 207 */
622 104, 145, 105, 146, 106, 109, 107, 149, /* 208 - 215 */
623 108, 200, 109, 146, 110, 170, 111, 157, /* 216 - 223 */
624 112, 128, 113, 130, 114, 182, 115, 132, /* 224 - 231 */
625 116, 200, 117, 132, 118, 158, 119, 206, /* 232 - 239 */
626 120, 240, 121, 162, 122, 147, 123, 152, /* 240 - 247 */
627 124, 166, 125, 214, 126, 138, 127, 153, /* 248 - 255 */
630 /* If n is larger than lookup table's max index, we use the "window
631 method". */
632 #define POWI_WINDOW_SIZE 3
634 /* Recursive function to expand the power operator. The temporary
635 values are put in tmpvar. The function returns tmpvar[1] ** n. */
636 static tree
637 gfc_conv_powi (gfc_se * se, int n, tree * tmpvar)
639 tree op0;
640 tree op1;
641 tree tmp;
642 int digit;
644 if (n < POWI_TABLE_SIZE)
646 if (tmpvar[n])
647 return tmpvar[n];
649 op0 = gfc_conv_powi (se, n - powi_table[n], tmpvar);
650 op1 = gfc_conv_powi (se, powi_table[n], tmpvar);
652 else if (n & 1)
654 digit = n & ((1 << POWI_WINDOW_SIZE) - 1);
655 op0 = gfc_conv_powi (se, n - digit, tmpvar);
656 op1 = gfc_conv_powi (se, digit, tmpvar);
658 else
660 op0 = gfc_conv_powi (se, n >> 1, tmpvar);
661 op1 = op0;
664 tmp = fold_build2 (MULT_EXPR, TREE_TYPE (op0), op0, op1);
665 tmp = gfc_evaluate_now (tmp, &se->pre);
667 if (n < POWI_TABLE_SIZE)
668 tmpvar[n] = tmp;
670 return tmp;
674 /* Expand lhs ** rhs. rhs is a constant integer. If it expands successfully,
675 return 1. Else return 0 and a call to runtime library functions
676 will have to be built. */
677 static int
678 gfc_conv_cst_int_power (gfc_se * se, tree lhs, tree rhs)
680 tree cond;
681 tree tmp;
682 tree type;
683 tree vartmp[POWI_TABLE_SIZE];
684 int n;
685 int sgn;
687 type = TREE_TYPE (lhs);
688 n = abs (TREE_INT_CST_LOW (rhs));
689 sgn = tree_int_cst_sgn (rhs);
691 if (((FLOAT_TYPE_P (type) && !flag_unsafe_math_optimizations) || optimize_size)
692 && (n > 2 || n < -1))
693 return 0;
695 /* rhs == 0 */
696 if (sgn == 0)
698 se->expr = gfc_build_const (type, integer_one_node);
699 return 1;
701 /* If rhs < 0 and lhs is an integer, the result is -1, 0 or 1. */
702 if ((sgn == -1) && (TREE_CODE (type) == INTEGER_TYPE))
704 tmp = build2 (EQ_EXPR, boolean_type_node, lhs,
705 build_int_cst (TREE_TYPE (lhs), -1));
706 cond = build2 (EQ_EXPR, boolean_type_node, lhs,
707 build_int_cst (TREE_TYPE (lhs), 1));
709 /* If rhs is even,
710 result = (lhs == 1 || lhs == -1) ? 1 : 0. */
711 if ((n & 1) == 0)
713 tmp = build2 (TRUTH_OR_EXPR, boolean_type_node, tmp, cond);
714 se->expr = build3 (COND_EXPR, type, tmp, build_int_cst (type, 1),
715 build_int_cst (type, 0));
716 return 1;
718 /* If rhs is odd,
719 result = (lhs == 1) ? 1 : (lhs == -1) ? -1 : 0. */
720 tmp = build3 (COND_EXPR, type, tmp, build_int_cst (type, -1),
721 build_int_cst (type, 0));
722 se->expr = build3 (COND_EXPR, type, cond, build_int_cst (type, 1), tmp);
723 return 1;
726 memset (vartmp, 0, sizeof (vartmp));
727 vartmp[1] = lhs;
728 if (sgn == -1)
730 tmp = gfc_build_const (type, integer_one_node);
731 vartmp[1] = build2 (RDIV_EXPR, type, tmp, vartmp[1]);
734 se->expr = gfc_conv_powi (se, n, vartmp);
736 return 1;
740 /* Power op (**). Constant integer exponent has special handling. */
742 static void
743 gfc_conv_power_op (gfc_se * se, gfc_expr * expr)
745 tree gfc_int4_type_node;
746 int kind;
747 int ikind;
748 gfc_se lse;
749 gfc_se rse;
750 tree fndecl;
752 gfc_init_se (&lse, se);
753 gfc_conv_expr_val (&lse, expr->value.op.op1);
754 lse.expr = gfc_evaluate_now (lse.expr, &lse.pre);
755 gfc_add_block_to_block (&se->pre, &lse.pre);
757 gfc_init_se (&rse, se);
758 gfc_conv_expr_val (&rse, expr->value.op.op2);
759 gfc_add_block_to_block (&se->pre, &rse.pre);
761 if (expr->value.op.op2->ts.type == BT_INTEGER
762 && expr->value.op.op2->expr_type == EXPR_CONSTANT)
763 if (gfc_conv_cst_int_power (se, lse.expr, rse.expr))
764 return;
766 gfc_int4_type_node = gfc_get_int_type (4);
768 kind = expr->value.op.op1->ts.kind;
769 switch (expr->value.op.op2->ts.type)
771 case BT_INTEGER:
772 ikind = expr->value.op.op2->ts.kind;
773 switch (ikind)
775 case 1:
776 case 2:
777 rse.expr = convert (gfc_int4_type_node, rse.expr);
778 /* Fall through. */
780 case 4:
781 ikind = 0;
782 break;
784 case 8:
785 ikind = 1;
786 break;
788 case 16:
789 ikind = 2;
790 break;
792 default:
793 gcc_unreachable ();
795 switch (kind)
797 case 1:
798 case 2:
799 if (expr->value.op.op1->ts.type == BT_INTEGER)
800 lse.expr = convert (gfc_int4_type_node, lse.expr);
801 else
802 gcc_unreachable ();
803 /* Fall through. */
805 case 4:
806 kind = 0;
807 break;
809 case 8:
810 kind = 1;
811 break;
813 case 10:
814 kind = 2;
815 break;
817 case 16:
818 kind = 3;
819 break;
821 default:
822 gcc_unreachable ();
825 switch (expr->value.op.op1->ts.type)
827 case BT_INTEGER:
828 if (kind == 3) /* Case 16 was not handled properly above. */
829 kind = 2;
830 fndecl = gfor_fndecl_math_powi[kind][ikind].integer;
831 break;
833 case BT_REAL:
834 fndecl = gfor_fndecl_math_powi[kind][ikind].real;
835 break;
837 case BT_COMPLEX:
838 fndecl = gfor_fndecl_math_powi[kind][ikind].cmplx;
839 break;
841 default:
842 gcc_unreachable ();
844 break;
846 case BT_REAL:
847 switch (kind)
849 case 4:
850 fndecl = built_in_decls[BUILT_IN_POWF];
851 break;
852 case 8:
853 fndecl = built_in_decls[BUILT_IN_POW];
854 break;
855 case 10:
856 case 16:
857 fndecl = built_in_decls[BUILT_IN_POWL];
858 break;
859 default:
860 gcc_unreachable ();
862 break;
864 case BT_COMPLEX:
865 switch (kind)
867 case 4:
868 fndecl = gfor_fndecl_math_cpowf;
869 break;
870 case 8:
871 fndecl = gfor_fndecl_math_cpow;
872 break;
873 case 10:
874 fndecl = gfor_fndecl_math_cpowl10;
875 break;
876 case 16:
877 fndecl = gfor_fndecl_math_cpowl16;
878 break;
879 default:
880 gcc_unreachable ();
882 break;
884 default:
885 gcc_unreachable ();
886 break;
889 se->expr = build_call_expr (fndecl, 2, lse.expr, rse.expr);
893 /* Generate code to allocate a string temporary. */
895 tree
896 gfc_conv_string_tmp (gfc_se * se, tree type, tree len)
898 tree var;
899 tree tmp;
901 gcc_assert (TREE_TYPE (len) == gfc_charlen_type_node);
903 if (gfc_can_put_var_on_stack (len))
905 /* Create a temporary variable to hold the result. */
906 tmp = fold_build2 (MINUS_EXPR, gfc_charlen_type_node, len,
907 build_int_cst (gfc_charlen_type_node, 1));
908 tmp = build_range_type (gfc_array_index_type, gfc_index_zero_node, tmp);
909 tmp = build_array_type (gfc_character1_type_node, tmp);
910 var = gfc_create_var (tmp, "str");
911 var = gfc_build_addr_expr (type, var);
913 else
915 /* Allocate a temporary to hold the result. */
916 var = gfc_create_var (type, "pstr");
917 tmp = build_call_expr (gfor_fndecl_internal_malloc, 1, len);
918 tmp = convert (type, tmp);
919 gfc_add_modify_expr (&se->pre, var, tmp);
921 /* Free the temporary afterwards. */
922 tmp = convert (pvoid_type_node, var);
923 tmp = build_call_expr (gfor_fndecl_internal_free, 1, tmp);
924 gfc_add_expr_to_block (&se->post, tmp);
927 return var;
931 /* Handle a string concatenation operation. A temporary will be allocated to
932 hold the result. */
934 static void
935 gfc_conv_concat_op (gfc_se * se, gfc_expr * expr)
937 gfc_se lse;
938 gfc_se rse;
939 tree len;
940 tree type;
941 tree var;
942 tree tmp;
944 gcc_assert (expr->value.op.op1->ts.type == BT_CHARACTER
945 && expr->value.op.op2->ts.type == BT_CHARACTER);
947 gfc_init_se (&lse, se);
948 gfc_conv_expr (&lse, expr->value.op.op1);
949 gfc_conv_string_parameter (&lse);
950 gfc_init_se (&rse, se);
951 gfc_conv_expr (&rse, expr->value.op.op2);
952 gfc_conv_string_parameter (&rse);
954 gfc_add_block_to_block (&se->pre, &lse.pre);
955 gfc_add_block_to_block (&se->pre, &rse.pre);
957 type = gfc_get_character_type (expr->ts.kind, expr->ts.cl);
958 len = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
959 if (len == NULL_TREE)
961 len = fold_build2 (PLUS_EXPR, TREE_TYPE (lse.string_length),
962 lse.string_length, rse.string_length);
965 type = build_pointer_type (type);
967 var = gfc_conv_string_tmp (se, type, len);
969 /* Do the actual concatenation. */
970 tmp = build_call_expr (gfor_fndecl_concat_string, 6,
971 len, var,
972 lse.string_length, lse.expr,
973 rse.string_length, rse.expr);
974 gfc_add_expr_to_block (&se->pre, tmp);
976 /* Add the cleanup for the operands. */
977 gfc_add_block_to_block (&se->pre, &rse.post);
978 gfc_add_block_to_block (&se->pre, &lse.post);
980 se->expr = var;
981 se->string_length = len;
984 /* Translates an op expression. Common (binary) cases are handled by this
985 function, others are passed on. Recursion is used in either case.
986 We use the fact that (op1.ts == op2.ts) (except for the power
987 operator **).
988 Operators need no special handling for scalarized expressions as long as
989 they call gfc_conv_simple_val to get their operands.
990 Character strings get special handling. */
992 static void
993 gfc_conv_expr_op (gfc_se * se, gfc_expr * expr)
995 enum tree_code code;
996 gfc_se lse;
997 gfc_se rse;
998 tree type;
999 tree tmp;
1000 int lop;
1001 int checkstring;
1003 checkstring = 0;
1004 lop = 0;
1005 switch (expr->value.op.operator)
1007 case INTRINSIC_UPLUS:
1008 case INTRINSIC_PARENTHESES:
1009 gfc_conv_expr (se, expr->value.op.op1);
1010 return;
1012 case INTRINSIC_UMINUS:
1013 gfc_conv_unary_op (NEGATE_EXPR, se, expr);
1014 return;
1016 case INTRINSIC_NOT:
1017 gfc_conv_unary_op (TRUTH_NOT_EXPR, se, expr);
1018 return;
1020 case INTRINSIC_PLUS:
1021 code = PLUS_EXPR;
1022 break;
1024 case INTRINSIC_MINUS:
1025 code = MINUS_EXPR;
1026 break;
1028 case INTRINSIC_TIMES:
1029 code = MULT_EXPR;
1030 break;
1032 case INTRINSIC_DIVIDE:
1033 /* If expr is a real or complex expr, use an RDIV_EXPR. If op1 is
1034 an integer, we must round towards zero, so we use a
1035 TRUNC_DIV_EXPR. */
1036 if (expr->ts.type == BT_INTEGER)
1037 code = TRUNC_DIV_EXPR;
1038 else
1039 code = RDIV_EXPR;
1040 break;
1042 case INTRINSIC_POWER:
1043 gfc_conv_power_op (se, expr);
1044 return;
1046 case INTRINSIC_CONCAT:
1047 gfc_conv_concat_op (se, expr);
1048 return;
1050 case INTRINSIC_AND:
1051 code = TRUTH_ANDIF_EXPR;
1052 lop = 1;
1053 break;
1055 case INTRINSIC_OR:
1056 code = TRUTH_ORIF_EXPR;
1057 lop = 1;
1058 break;
1060 /* EQV and NEQV only work on logicals, but since we represent them
1061 as integers, we can use EQ_EXPR and NE_EXPR for them in GIMPLE. */
1062 case INTRINSIC_EQ:
1063 case INTRINSIC_EQV:
1064 code = EQ_EXPR;
1065 checkstring = 1;
1066 lop = 1;
1067 break;
1069 case INTRINSIC_NE:
1070 case INTRINSIC_NEQV:
1071 code = NE_EXPR;
1072 checkstring = 1;
1073 lop = 1;
1074 break;
1076 case INTRINSIC_GT:
1077 code = GT_EXPR;
1078 checkstring = 1;
1079 lop = 1;
1080 break;
1082 case INTRINSIC_GE:
1083 code = GE_EXPR;
1084 checkstring = 1;
1085 lop = 1;
1086 break;
1088 case INTRINSIC_LT:
1089 code = LT_EXPR;
1090 checkstring = 1;
1091 lop = 1;
1092 break;
1094 case INTRINSIC_LE:
1095 code = LE_EXPR;
1096 checkstring = 1;
1097 lop = 1;
1098 break;
1100 case INTRINSIC_USER:
1101 case INTRINSIC_ASSIGN:
1102 /* These should be converted into function calls by the frontend. */
1103 gcc_unreachable ();
1105 default:
1106 fatal_error ("Unknown intrinsic op");
1107 return;
1110 /* The only exception to this is **, which is handled separately anyway. */
1111 gcc_assert (expr->value.op.op1->ts.type == expr->value.op.op2->ts.type);
1113 if (checkstring && expr->value.op.op1->ts.type != BT_CHARACTER)
1114 checkstring = 0;
1116 /* lhs */
1117 gfc_init_se (&lse, se);
1118 gfc_conv_expr (&lse, expr->value.op.op1);
1119 gfc_add_block_to_block (&se->pre, &lse.pre);
1121 /* rhs */
1122 gfc_init_se (&rse, se);
1123 gfc_conv_expr (&rse, expr->value.op.op2);
1124 gfc_add_block_to_block (&se->pre, &rse.pre);
1126 if (checkstring)
1128 gfc_conv_string_parameter (&lse);
1129 gfc_conv_string_parameter (&rse);
1131 lse.expr = gfc_build_compare_string (lse.string_length, lse.expr,
1132 rse.string_length, rse.expr);
1133 rse.expr = integer_zero_node;
1134 gfc_add_block_to_block (&lse.post, &rse.post);
1137 type = gfc_typenode_for_spec (&expr->ts);
1139 if (lop)
1141 /* The result of logical ops is always boolean_type_node. */
1142 tmp = fold_build2 (code, type, lse.expr, rse.expr);
1143 se->expr = convert (type, tmp);
1145 else
1146 se->expr = fold_build2 (code, type, lse.expr, rse.expr);
1148 /* Add the post blocks. */
1149 gfc_add_block_to_block (&se->post, &rse.post);
1150 gfc_add_block_to_block (&se->post, &lse.post);
1153 /* If a string's length is one, we convert it to a single character. */
1155 static tree
1156 gfc_to_single_character (tree len, tree str)
1158 gcc_assert (POINTER_TYPE_P (TREE_TYPE (str)));
1160 if (INTEGER_CST_P (len) && TREE_INT_CST_LOW (len) == 1
1161 && TREE_INT_CST_HIGH (len) == 0)
1163 str = fold_convert (pchar_type_node, str);
1164 return build_fold_indirect_ref (str);
1167 return NULL_TREE;
1170 /* Compare two strings. If they are all single characters, the result is the
1171 subtraction of them. Otherwise, we build a library call. */
1173 tree
1174 gfc_build_compare_string (tree len1, tree str1, tree len2, tree str2)
1176 tree sc1;
1177 tree sc2;
1178 tree type;
1179 tree tmp;
1181 gcc_assert (POINTER_TYPE_P (TREE_TYPE (str1)));
1182 gcc_assert (POINTER_TYPE_P (TREE_TYPE (str2)));
1184 type = gfc_get_int_type (gfc_default_integer_kind);
1186 sc1 = gfc_to_single_character (len1, str1);
1187 sc2 = gfc_to_single_character (len2, str2);
1189 /* Deal with single character specially. */
1190 if (sc1 != NULL_TREE && sc2 != NULL_TREE)
1192 sc1 = fold_convert (type, sc1);
1193 sc2 = fold_convert (type, sc2);
1194 tmp = fold_build2 (MINUS_EXPR, type, sc1, sc2);
1196 else
1197 /* Build a call for the comparison. */
1198 tmp = build_call_expr (gfor_fndecl_compare_string, 4,
1199 len1, str1, len2, str2);
1200 return tmp;
1203 static void
1204 gfc_conv_function_val (gfc_se * se, gfc_symbol * sym)
1206 tree tmp;
1208 if (sym->attr.dummy)
1210 tmp = gfc_get_symbol_decl (sym);
1211 gcc_assert (TREE_CODE (TREE_TYPE (tmp)) == POINTER_TYPE
1212 && TREE_CODE (TREE_TYPE (TREE_TYPE (tmp))) == FUNCTION_TYPE);
1214 else
1216 if (!sym->backend_decl)
1217 sym->backend_decl = gfc_get_extern_function_decl (sym);
1219 tmp = sym->backend_decl;
1220 if (sym->attr.cray_pointee)
1221 tmp = convert (build_pointer_type (TREE_TYPE (tmp)),
1222 gfc_get_symbol_decl (sym->cp_pointer));
1223 if (!POINTER_TYPE_P (TREE_TYPE (tmp)))
1225 gcc_assert (TREE_CODE (tmp) == FUNCTION_DECL);
1226 tmp = build_fold_addr_expr (tmp);
1229 se->expr = tmp;
1233 /* Translate the call for an elemental subroutine call used in an operator
1234 assignment. This is a simplified version of gfc_conv_function_call. */
1236 tree
1237 gfc_conv_operator_assign (gfc_se *lse, gfc_se *rse, gfc_symbol *sym)
1239 tree args;
1240 tree tmp;
1241 gfc_se se;
1242 stmtblock_t block;
1244 /* Only elemental subroutines with two arguments. */
1245 gcc_assert (sym->attr.elemental && sym->attr.subroutine);
1246 gcc_assert (sym->formal->next->next == NULL);
1248 gfc_init_block (&block);
1250 gfc_add_block_to_block (&block, &lse->pre);
1251 gfc_add_block_to_block (&block, &rse->pre);
1253 /* Build the argument list for the call, including hidden string lengths. */
1254 args = gfc_chainon_list (NULL_TREE, build_fold_addr_expr (lse->expr));
1255 args = gfc_chainon_list (args, build_fold_addr_expr (rse->expr));
1256 if (lse->string_length != NULL_TREE)
1257 args = gfc_chainon_list (args, lse->string_length);
1258 if (rse->string_length != NULL_TREE)
1259 args = gfc_chainon_list (args, rse->string_length);
1261 /* Build the function call. */
1262 gfc_init_se (&se, NULL);
1263 gfc_conv_function_val (&se, sym);
1264 tmp = TREE_TYPE (TREE_TYPE (TREE_TYPE (se.expr)));
1265 tmp = build_call_list (tmp, se.expr, args);
1266 gfc_add_expr_to_block (&block, tmp);
1268 gfc_add_block_to_block (&block, &lse->post);
1269 gfc_add_block_to_block (&block, &rse->post);
1271 return gfc_finish_block (&block);
1275 /* Initialize MAPPING. */
1277 void
1278 gfc_init_interface_mapping (gfc_interface_mapping * mapping)
1280 mapping->syms = NULL;
1281 mapping->charlens = NULL;
1285 /* Free all memory held by MAPPING (but not MAPPING itself). */
1287 void
1288 gfc_free_interface_mapping (gfc_interface_mapping * mapping)
1290 gfc_interface_sym_mapping *sym;
1291 gfc_interface_sym_mapping *nextsym;
1292 gfc_charlen *cl;
1293 gfc_charlen *nextcl;
1295 for (sym = mapping->syms; sym; sym = nextsym)
1297 nextsym = sym->next;
1298 gfc_free_symbol (sym->new->n.sym);
1299 gfc_free (sym->new);
1300 gfc_free (sym);
1302 for (cl = mapping->charlens; cl; cl = nextcl)
1304 nextcl = cl->next;
1305 gfc_free_expr (cl->length);
1306 gfc_free (cl);
1311 /* Return a copy of gfc_charlen CL. Add the returned structure to
1312 MAPPING so that it will be freed by gfc_free_interface_mapping. */
1314 static gfc_charlen *
1315 gfc_get_interface_mapping_charlen (gfc_interface_mapping * mapping,
1316 gfc_charlen * cl)
1318 gfc_charlen *new;
1320 new = gfc_get_charlen ();
1321 new->next = mapping->charlens;
1322 new->length = gfc_copy_expr (cl->length);
1324 mapping->charlens = new;
1325 return new;
1329 /* A subroutine of gfc_add_interface_mapping. Return a descriptorless
1330 array variable that can be used as the actual argument for dummy
1331 argument SYM. Add any initialization code to BLOCK. PACKED is as
1332 for gfc_get_nodesc_array_type and DATA points to the first element
1333 in the passed array. */
1335 static tree
1336 gfc_get_interface_mapping_array (stmtblock_t * block, gfc_symbol * sym,
1337 int packed, tree data)
1339 tree type;
1340 tree var;
1342 type = gfc_typenode_for_spec (&sym->ts);
1343 type = gfc_get_nodesc_array_type (type, sym->as, packed);
1345 var = gfc_create_var (type, "ifm");
1346 gfc_add_modify_expr (block, var, fold_convert (type, data));
1348 return var;
1352 /* A subroutine of gfc_add_interface_mapping. Set the stride, upper bounds
1353 and offset of descriptorless array type TYPE given that it has the same
1354 size as DESC. Add any set-up code to BLOCK. */
1356 static void
1357 gfc_set_interface_mapping_bounds (stmtblock_t * block, tree type, tree desc)
1359 int n;
1360 tree dim;
1361 tree offset;
1362 tree tmp;
1364 offset = gfc_index_zero_node;
1365 for (n = 0; n < GFC_TYPE_ARRAY_RANK (type); n++)
1367 dim = gfc_rank_cst[n];
1368 GFC_TYPE_ARRAY_STRIDE (type, n) = gfc_conv_array_stride (desc, n);
1369 if (GFC_TYPE_ARRAY_LBOUND (type, n) == NULL_TREE)
1371 GFC_TYPE_ARRAY_LBOUND (type, n)
1372 = gfc_conv_descriptor_lbound (desc, dim);
1373 GFC_TYPE_ARRAY_UBOUND (type, n)
1374 = gfc_conv_descriptor_ubound (desc, dim);
1376 else if (GFC_TYPE_ARRAY_UBOUND (type, n) == NULL_TREE)
1378 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
1379 gfc_conv_descriptor_ubound (desc, dim),
1380 gfc_conv_descriptor_lbound (desc, dim));
1381 tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
1382 GFC_TYPE_ARRAY_LBOUND (type, n),
1383 tmp);
1384 tmp = gfc_evaluate_now (tmp, block);
1385 GFC_TYPE_ARRAY_UBOUND (type, n) = tmp;
1387 tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
1388 GFC_TYPE_ARRAY_LBOUND (type, n),
1389 GFC_TYPE_ARRAY_STRIDE (type, n));
1390 offset = fold_build2 (MINUS_EXPR, gfc_array_index_type, offset, tmp);
1392 offset = gfc_evaluate_now (offset, block);
1393 GFC_TYPE_ARRAY_OFFSET (type) = offset;
1397 /* Extend MAPPING so that it maps dummy argument SYM to the value stored
1398 in SE. The caller may still use se->expr and se->string_length after
1399 calling this function. */
1401 void
1402 gfc_add_interface_mapping (gfc_interface_mapping * mapping,
1403 gfc_symbol * sym, gfc_se * se)
1405 gfc_interface_sym_mapping *sm;
1406 tree desc;
1407 tree tmp;
1408 tree value;
1409 gfc_symbol *new_sym;
1410 gfc_symtree *root;
1411 gfc_symtree *new_symtree;
1413 /* Create a new symbol to represent the actual argument. */
1414 new_sym = gfc_new_symbol (sym->name, NULL);
1415 new_sym->ts = sym->ts;
1416 new_sym->attr.referenced = 1;
1417 new_sym->attr.dimension = sym->attr.dimension;
1418 new_sym->attr.pointer = sym->attr.pointer;
1419 new_sym->attr.allocatable = sym->attr.allocatable;
1420 new_sym->attr.flavor = sym->attr.flavor;
1422 /* Create a fake symtree for it. */
1423 root = NULL;
1424 new_symtree = gfc_new_symtree (&root, sym->name);
1425 new_symtree->n.sym = new_sym;
1426 gcc_assert (new_symtree == root);
1428 /* Create a dummy->actual mapping. */
1429 sm = gfc_getmem (sizeof (*sm));
1430 sm->next = mapping->syms;
1431 sm->old = sym;
1432 sm->new = new_symtree;
1433 mapping->syms = sm;
1435 /* Stabilize the argument's value. */
1436 se->expr = gfc_evaluate_now (se->expr, &se->pre);
1438 if (sym->ts.type == BT_CHARACTER)
1440 /* Create a copy of the dummy argument's length. */
1441 new_sym->ts.cl = gfc_get_interface_mapping_charlen (mapping, sym->ts.cl);
1443 /* If the length is specified as "*", record the length that
1444 the caller is passing. We should use the callee's length
1445 in all other cases. */
1446 if (!new_sym->ts.cl->length)
1448 se->string_length = gfc_evaluate_now (se->string_length, &se->pre);
1449 new_sym->ts.cl->backend_decl = se->string_length;
1453 /* Use the passed value as-is if the argument is a function. */
1454 if (sym->attr.flavor == FL_PROCEDURE)
1455 value = se->expr;
1457 /* If the argument is either a string or a pointer to a string,
1458 convert it to a boundless character type. */
1459 else if (!sym->attr.dimension && sym->ts.type == BT_CHARACTER)
1461 tmp = gfc_get_character_type_len (sym->ts.kind, NULL);
1462 tmp = build_pointer_type (tmp);
1463 if (sym->attr.pointer)
1464 value = build_fold_indirect_ref (se->expr);
1465 else
1466 value = se->expr;
1467 value = fold_convert (tmp, value);
1470 /* If the argument is a scalar, a pointer to an array or an allocatable,
1471 dereference it. */
1472 else if (!sym->attr.dimension || sym->attr.pointer || sym->attr.allocatable)
1473 value = build_fold_indirect_ref (se->expr);
1475 /* For character(*), use the actual argument's descriptor. */
1476 else if (sym->ts.type == BT_CHARACTER && !new_sym->ts.cl->length)
1477 value = build_fold_indirect_ref (se->expr);
1479 /* If the argument is an array descriptor, use it to determine
1480 information about the actual argument's shape. */
1481 else if (POINTER_TYPE_P (TREE_TYPE (se->expr))
1482 && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (TREE_TYPE (se->expr))))
1484 /* Get the actual argument's descriptor. */
1485 desc = build_fold_indirect_ref (se->expr);
1487 /* Create the replacement variable. */
1488 tmp = gfc_conv_descriptor_data_get (desc);
1489 value = gfc_get_interface_mapping_array (&se->pre, sym, 0, tmp);
1491 /* Use DESC to work out the upper bounds, strides and offset. */
1492 gfc_set_interface_mapping_bounds (&se->pre, TREE_TYPE (value), desc);
1494 else
1495 /* Otherwise we have a packed array. */
1496 value = gfc_get_interface_mapping_array (&se->pre, sym, 2, se->expr);
1498 new_sym->backend_decl = value;
1502 /* Called once all dummy argument mappings have been added to MAPPING,
1503 but before the mapping is used to evaluate expressions. Pre-evaluate
1504 the length of each argument, adding any initialization code to PRE and
1505 any finalization code to POST. */
1507 void
1508 gfc_finish_interface_mapping (gfc_interface_mapping * mapping,
1509 stmtblock_t * pre, stmtblock_t * post)
1511 gfc_interface_sym_mapping *sym;
1512 gfc_expr *expr;
1513 gfc_se se;
1515 for (sym = mapping->syms; sym; sym = sym->next)
1516 if (sym->new->n.sym->ts.type == BT_CHARACTER
1517 && !sym->new->n.sym->ts.cl->backend_decl)
1519 expr = sym->new->n.sym->ts.cl->length;
1520 gfc_apply_interface_mapping_to_expr (mapping, expr);
1521 gfc_init_se (&se, NULL);
1522 gfc_conv_expr (&se, expr);
1524 se.expr = gfc_evaluate_now (se.expr, &se.pre);
1525 gfc_add_block_to_block (pre, &se.pre);
1526 gfc_add_block_to_block (post, &se.post);
1528 sym->new->n.sym->ts.cl->backend_decl = se.expr;
1533 /* Like gfc_apply_interface_mapping_to_expr, but applied to
1534 constructor C. */
1536 static void
1537 gfc_apply_interface_mapping_to_cons (gfc_interface_mapping * mapping,
1538 gfc_constructor * c)
1540 for (; c; c = c->next)
1542 gfc_apply_interface_mapping_to_expr (mapping, c->expr);
1543 if (c->iterator)
1545 gfc_apply_interface_mapping_to_expr (mapping, c->iterator->start);
1546 gfc_apply_interface_mapping_to_expr (mapping, c->iterator->end);
1547 gfc_apply_interface_mapping_to_expr (mapping, c->iterator->step);
1553 /* Like gfc_apply_interface_mapping_to_expr, but applied to
1554 reference REF. */
1556 static void
1557 gfc_apply_interface_mapping_to_ref (gfc_interface_mapping * mapping,
1558 gfc_ref * ref)
1560 int n;
1562 for (; ref; ref = ref->next)
1563 switch (ref->type)
1565 case REF_ARRAY:
1566 for (n = 0; n < ref->u.ar.dimen; n++)
1568 gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.start[n]);
1569 gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.end[n]);
1570 gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.stride[n]);
1572 gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.offset);
1573 break;
1575 case REF_COMPONENT:
1576 break;
1578 case REF_SUBSTRING:
1579 gfc_apply_interface_mapping_to_expr (mapping, ref->u.ss.start);
1580 gfc_apply_interface_mapping_to_expr (mapping, ref->u.ss.end);
1581 break;
1586 /* EXPR is a copy of an expression that appeared in the interface
1587 associated with MAPPING. Walk it recursively looking for references to
1588 dummy arguments that MAPPING maps to actual arguments. Replace each such
1589 reference with a reference to the associated actual argument. */
1591 static void
1592 gfc_apply_interface_mapping_to_expr (gfc_interface_mapping * mapping,
1593 gfc_expr * expr)
1595 gfc_interface_sym_mapping *sym;
1596 gfc_actual_arglist *actual;
1598 if (!expr)
1599 return;
1601 /* Copying an expression does not copy its length, so do that here. */
1602 if (expr->ts.type == BT_CHARACTER && expr->ts.cl)
1604 expr->ts.cl = gfc_get_interface_mapping_charlen (mapping, expr->ts.cl);
1605 gfc_apply_interface_mapping_to_expr (mapping, expr->ts.cl->length);
1608 /* Apply the mapping to any references. */
1609 gfc_apply_interface_mapping_to_ref (mapping, expr->ref);
1611 /* ...and to the expression's symbol, if it has one. */
1612 if (expr->symtree)
1613 for (sym = mapping->syms; sym; sym = sym->next)
1614 if (sym->old == expr->symtree->n.sym)
1615 expr->symtree = sym->new;
1617 /* ...and to subexpressions in expr->value. */
1618 switch (expr->expr_type)
1620 case EXPR_VARIABLE:
1621 case EXPR_CONSTANT:
1622 case EXPR_NULL:
1623 case EXPR_SUBSTRING:
1624 break;
1626 case EXPR_OP:
1627 gfc_apply_interface_mapping_to_expr (mapping, expr->value.op.op1);
1628 gfc_apply_interface_mapping_to_expr (mapping, expr->value.op.op2);
1629 break;
1631 case EXPR_FUNCTION:
1632 for (sym = mapping->syms; sym; sym = sym->next)
1633 if (sym->old == expr->value.function.esym)
1634 expr->value.function.esym = sym->new->n.sym;
1636 for (actual = expr->value.function.actual; actual; actual = actual->next)
1637 gfc_apply_interface_mapping_to_expr (mapping, actual->expr);
1638 break;
1640 case EXPR_ARRAY:
1641 case EXPR_STRUCTURE:
1642 gfc_apply_interface_mapping_to_cons (mapping, expr->value.constructor);
1643 break;
1648 /* Evaluate interface expression EXPR using MAPPING. Store the result
1649 in SE. */
1651 void
1652 gfc_apply_interface_mapping (gfc_interface_mapping * mapping,
1653 gfc_se * se, gfc_expr * expr)
1655 expr = gfc_copy_expr (expr);
1656 gfc_apply_interface_mapping_to_expr (mapping, expr);
1657 gfc_conv_expr (se, expr);
1658 se->expr = gfc_evaluate_now (se->expr, &se->pre);
1659 gfc_free_expr (expr);
1662 /* Returns a reference to a temporary array into which a component of
1663 an actual argument derived type array is copied and then returned
1664 after the function call.
1665 TODO Get rid of this kludge, when array descriptors are capable of
1666 handling arrays with a bigger stride in bytes than size. */
1668 void
1669 gfc_conv_aliased_arg (gfc_se * parmse, gfc_expr * expr,
1670 int g77, sym_intent intent)
1672 gfc_se lse;
1673 gfc_se rse;
1674 gfc_ss *lss;
1675 gfc_ss *rss;
1676 gfc_loopinfo loop;
1677 gfc_loopinfo loop2;
1678 gfc_ss_info *info;
1679 tree offset;
1680 tree tmp_index;
1681 tree tmp;
1682 tree base_type;
1683 stmtblock_t body;
1684 int n;
1686 gcc_assert (expr->expr_type == EXPR_VARIABLE);
1688 gfc_init_se (&lse, NULL);
1689 gfc_init_se (&rse, NULL);
1691 /* Walk the argument expression. */
1692 rss = gfc_walk_expr (expr);
1694 gcc_assert (rss != gfc_ss_terminator);
1696 /* Initialize the scalarizer. */
1697 gfc_init_loopinfo (&loop);
1698 gfc_add_ss_to_loop (&loop, rss);
1700 /* Calculate the bounds of the scalarization. */
1701 gfc_conv_ss_startstride (&loop);
1703 /* Build an ss for the temporary. */
1704 base_type = gfc_typenode_for_spec (&expr->ts);
1705 if (GFC_ARRAY_TYPE_P (base_type)
1706 || GFC_DESCRIPTOR_TYPE_P (base_type))
1707 base_type = gfc_get_element_type (base_type);
1709 loop.temp_ss = gfc_get_ss ();;
1710 loop.temp_ss->type = GFC_SS_TEMP;
1711 loop.temp_ss->data.temp.type = base_type;
1713 if (expr->ts.type == BT_CHARACTER)
1715 gfc_ref *char_ref = expr->ref;
1717 for (; char_ref; char_ref = char_ref->next)
1718 if (char_ref->type == REF_SUBSTRING)
1720 gfc_se tmp_se;
1722 expr->ts.cl = gfc_get_charlen ();
1723 expr->ts.cl->next = char_ref->u.ss.length->next;
1724 char_ref->u.ss.length->next = expr->ts.cl;
1726 gfc_init_se (&tmp_se, NULL);
1727 gfc_conv_expr_type (&tmp_se, char_ref->u.ss.end,
1728 gfc_array_index_type);
1729 tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
1730 tmp_se.expr, gfc_index_one_node);
1731 tmp = gfc_evaluate_now (tmp, &parmse->pre);
1732 gfc_init_se (&tmp_se, NULL);
1733 gfc_conv_expr_type (&tmp_se, char_ref->u.ss.start,
1734 gfc_array_index_type);
1735 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
1736 tmp, tmp_se.expr);
1737 expr->ts.cl->backend_decl = tmp;
1739 break;
1741 loop.temp_ss->data.temp.type
1742 = gfc_typenode_for_spec (&expr->ts);
1743 loop.temp_ss->string_length = expr->ts.cl->backend_decl;
1746 loop.temp_ss->data.temp.dimen = loop.dimen;
1747 loop.temp_ss->next = gfc_ss_terminator;
1749 /* Associate the SS with the loop. */
1750 gfc_add_ss_to_loop (&loop, loop.temp_ss);
1752 /* Setup the scalarizing loops. */
1753 gfc_conv_loop_setup (&loop);
1755 /* Pass the temporary descriptor back to the caller. */
1756 info = &loop.temp_ss->data.info;
1757 parmse->expr = info->descriptor;
1759 /* Setup the gfc_se structures. */
1760 gfc_copy_loopinfo_to_se (&lse, &loop);
1761 gfc_copy_loopinfo_to_se (&rse, &loop);
1763 rse.ss = rss;
1764 lse.ss = loop.temp_ss;
1765 gfc_mark_ss_chain_used (rss, 1);
1766 gfc_mark_ss_chain_used (loop.temp_ss, 1);
1768 /* Start the scalarized loop body. */
1769 gfc_start_scalarized_body (&loop, &body);
1771 /* Translate the expression. */
1772 gfc_conv_expr (&rse, expr);
1774 gfc_conv_tmp_array_ref (&lse);
1775 gfc_advance_se_ss_chain (&lse);
1777 if (intent != INTENT_OUT)
1779 tmp = gfc_trans_scalar_assign (&lse, &rse, expr->ts, true, false);
1780 gfc_add_expr_to_block (&body, tmp);
1781 gcc_assert (rse.ss == gfc_ss_terminator);
1782 gfc_trans_scalarizing_loops (&loop, &body);
1784 else
1786 /* Make sure that the temporary declaration survives by merging
1787 all the loop declarations into the current context. */
1788 for (n = 0; n < loop.dimen; n++)
1790 gfc_merge_block_scope (&body);
1791 body = loop.code[loop.order[n]];
1793 gfc_merge_block_scope (&body);
1796 /* Add the post block after the second loop, so that any
1797 freeing of allocated memory is done at the right time. */
1798 gfc_add_block_to_block (&parmse->pre, &loop.pre);
1800 /**********Copy the temporary back again.*********/
1802 gfc_init_se (&lse, NULL);
1803 gfc_init_se (&rse, NULL);
1805 /* Walk the argument expression. */
1806 lss = gfc_walk_expr (expr);
1807 rse.ss = loop.temp_ss;
1808 lse.ss = lss;
1810 /* Initialize the scalarizer. */
1811 gfc_init_loopinfo (&loop2);
1812 gfc_add_ss_to_loop (&loop2, lss);
1814 /* Calculate the bounds of the scalarization. */
1815 gfc_conv_ss_startstride (&loop2);
1817 /* Setup the scalarizing loops. */
1818 gfc_conv_loop_setup (&loop2);
1820 gfc_copy_loopinfo_to_se (&lse, &loop2);
1821 gfc_copy_loopinfo_to_se (&rse, &loop2);
1823 gfc_mark_ss_chain_used (lss, 1);
1824 gfc_mark_ss_chain_used (loop.temp_ss, 1);
1826 /* Declare the variable to hold the temporary offset and start the
1827 scalarized loop body. */
1828 offset = gfc_create_var (gfc_array_index_type, NULL);
1829 gfc_start_scalarized_body (&loop2, &body);
1831 /* Build the offsets for the temporary from the loop variables. The
1832 temporary array has lbounds of zero and strides of one in all
1833 dimensions, so this is very simple. The offset is only computed
1834 outside the innermost loop, so the overall transfer could be
1835 optimized further. */
1836 info = &rse.ss->data.info;
1838 tmp_index = gfc_index_zero_node;
1839 for (n = info->dimen - 1; n > 0; n--)
1841 tree tmp_str;
1842 tmp = rse.loop->loopvar[n];
1843 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
1844 tmp, rse.loop->from[n]);
1845 tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
1846 tmp, tmp_index);
1848 tmp_str = fold_build2 (MINUS_EXPR, gfc_array_index_type,
1849 rse.loop->to[n-1], rse.loop->from[n-1]);
1850 tmp_str = fold_build2 (PLUS_EXPR, gfc_array_index_type,
1851 tmp_str, gfc_index_one_node);
1853 tmp_index = fold_build2 (MULT_EXPR, gfc_array_index_type,
1854 tmp, tmp_str);
1857 tmp_index = fold_build2 (MINUS_EXPR, gfc_array_index_type,
1858 tmp_index, rse.loop->from[0]);
1859 gfc_add_modify_expr (&rse.loop->code[0], offset, tmp_index);
1861 tmp_index = fold_build2 (PLUS_EXPR, gfc_array_index_type,
1862 rse.loop->loopvar[0], offset);
1864 /* Now use the offset for the reference. */
1865 tmp = build_fold_indirect_ref (info->data);
1866 rse.expr = gfc_build_array_ref (tmp, tmp_index);
1868 if (expr->ts.type == BT_CHARACTER)
1869 rse.string_length = expr->ts.cl->backend_decl;
1871 gfc_conv_expr (&lse, expr);
1873 gcc_assert (lse.ss == gfc_ss_terminator);
1875 tmp = gfc_trans_scalar_assign (&lse, &rse, expr->ts, false, false);
1876 gfc_add_expr_to_block (&body, tmp);
1878 /* Generate the copying loops. */
1879 gfc_trans_scalarizing_loops (&loop2, &body);
1881 /* Wrap the whole thing up by adding the second loop to the post-block
1882 and following it by the post-block of the first loop. In this way,
1883 if the temporary needs freeing, it is done after use! */
1884 if (intent != INTENT_IN)
1886 gfc_add_block_to_block (&parmse->post, &loop2.pre);
1887 gfc_add_block_to_block (&parmse->post, &loop2.post);
1890 gfc_add_block_to_block (&parmse->post, &loop.post);
1892 gfc_cleanup_loop (&loop);
1893 gfc_cleanup_loop (&loop2);
1895 /* Pass the string length to the argument expression. */
1896 if (expr->ts.type == BT_CHARACTER)
1897 parmse->string_length = expr->ts.cl->backend_decl;
1899 /* We want either the address for the data or the address of the descriptor,
1900 depending on the mode of passing array arguments. */
1901 if (g77)
1902 parmse->expr = gfc_conv_descriptor_data_get (parmse->expr);
1903 else
1904 parmse->expr = build_fold_addr_expr (parmse->expr);
1906 return;
1909 /* Is true if an array reference is followed by a component or substring
1910 reference. */
1912 bool
1913 is_aliased_array (gfc_expr * e)
1915 gfc_ref * ref;
1916 bool seen_array;
1918 seen_array = false;
1919 for (ref = e->ref; ref; ref = ref->next)
1921 if (ref->type == REF_ARRAY
1922 && ref->u.ar.type != AR_ELEMENT)
1923 seen_array = true;
1925 if (seen_array
1926 && ref->type != REF_ARRAY)
1927 return seen_array;
1929 return false;
1932 /* Generate the code for argument list functions. */
1934 static void
1935 conv_arglist_function (gfc_se *se, gfc_expr *expr, const char *name)
1937 tree type = NULL_TREE;
1938 /* Pass by value for g77 %VAL(arg), pass the address
1939 indirectly for %LOC, else by reference. Thus %REF
1940 is a "do-nothing" and %LOC is the same as an F95
1941 pointer. */
1942 if (strncmp (name, "%VAL", 4) == 0)
1944 gfc_conv_expr (se, expr);
1945 /* %VAL converts argument to default kind. */
1946 switch (expr->ts.type)
1948 case BT_REAL:
1949 type = gfc_get_real_type (gfc_default_real_kind);
1950 se->expr = fold_convert (type, se->expr);
1951 break;
1952 case BT_COMPLEX:
1953 type = gfc_get_complex_type (gfc_default_complex_kind);
1954 se->expr = fold_convert (type, se->expr);
1955 break;
1956 case BT_INTEGER:
1957 type = gfc_get_int_type (gfc_default_integer_kind);
1958 se->expr = fold_convert (type, se->expr);
1959 break;
1960 case BT_LOGICAL:
1961 type = gfc_get_logical_type (gfc_default_logical_kind);
1962 se->expr = fold_convert (type, se->expr);
1963 break;
1964 /* This should have been resolved away. */
1965 case BT_UNKNOWN: case BT_CHARACTER: case BT_DERIVED:
1966 case BT_PROCEDURE: case BT_HOLLERITH:
1967 gfc_internal_error ("Bad type in conv_arglist_function");
1971 else if (strncmp (name, "%LOC", 4) == 0)
1973 gfc_conv_expr_reference (se, expr);
1974 se->expr = gfc_build_addr_expr (NULL, se->expr);
1976 else if (strncmp (name, "%REF", 4) == 0)
1977 gfc_conv_expr_reference (se, expr);
1978 else
1979 gfc_error ("Unknown argument list function at %L", &expr->where);
1983 /* Generate code for a procedure call. Note can return se->post != NULL.
1984 If se->direct_byref is set then se->expr contains the return parameter.
1985 Return nonzero, if the call has alternate specifiers. */
1988 gfc_conv_function_call (gfc_se * se, gfc_symbol * sym,
1989 gfc_actual_arglist * arg, tree append_args)
1991 gfc_interface_mapping mapping;
1992 tree arglist;
1993 tree retargs;
1994 tree tmp;
1995 tree fntype;
1996 gfc_se parmse;
1997 gfc_ss *argss;
1998 gfc_ss_info *info;
1999 int byref;
2000 int parm_kind;
2001 tree type;
2002 tree var;
2003 tree len;
2004 tree stringargs;
2005 gfc_formal_arglist *formal;
2006 int has_alternate_specifier = 0;
2007 bool need_interface_mapping;
2008 bool callee_alloc;
2009 gfc_typespec ts;
2010 gfc_charlen cl;
2011 gfc_expr *e;
2012 gfc_symbol *fsym;
2013 stmtblock_t post;
2014 enum {MISSING = 0, ELEMENTAL, SCALAR, SCALAR_POINTER, ARRAY};
2016 arglist = NULL_TREE;
2017 retargs = NULL_TREE;
2018 stringargs = NULL_TREE;
2019 var = NULL_TREE;
2020 len = NULL_TREE;
2022 if (se->ss != NULL)
2024 if (!sym->attr.elemental)
2026 gcc_assert (se->ss->type == GFC_SS_FUNCTION);
2027 if (se->ss->useflags)
2029 gcc_assert (gfc_return_by_reference (sym)
2030 && sym->result->attr.dimension);
2031 gcc_assert (se->loop != NULL);
2033 /* Access the previously obtained result. */
2034 gfc_conv_tmp_array_ref (se);
2035 gfc_advance_se_ss_chain (se);
2036 return 0;
2039 info = &se->ss->data.info;
2041 else
2042 info = NULL;
2044 gfc_init_block (&post);
2045 gfc_init_interface_mapping (&mapping);
2046 need_interface_mapping = ((sym->ts.type == BT_CHARACTER
2047 && sym->ts.cl->length
2048 && sym->ts.cl->length->expr_type
2049 != EXPR_CONSTANT)
2050 || sym->attr.dimension);
2051 formal = sym->formal;
2052 /* Evaluate the arguments. */
2053 for (; arg != NULL; arg = arg->next, formal = formal ? formal->next : NULL)
2055 e = arg->expr;
2056 fsym = formal ? formal->sym : NULL;
2057 parm_kind = MISSING;
2058 if (e == NULL)
2061 if (se->ignore_optional)
2063 /* Some intrinsics have already been resolved to the correct
2064 parameters. */
2065 continue;
2067 else if (arg->label)
2069 has_alternate_specifier = 1;
2070 continue;
2072 else
2074 /* Pass a NULL pointer for an absent arg. */
2075 gfc_init_se (&parmse, NULL);
2076 parmse.expr = null_pointer_node;
2077 if (arg->missing_arg_type == BT_CHARACTER)
2078 parmse.string_length = build_int_cst (gfc_charlen_type_node, 0);
2081 else if (se->ss && se->ss->useflags)
2083 /* An elemental function inside a scalarized loop. */
2084 gfc_init_se (&parmse, se);
2085 gfc_conv_expr_reference (&parmse, e);
2086 parm_kind = ELEMENTAL;
2088 else
2090 /* A scalar or transformational function. */
2091 gfc_init_se (&parmse, NULL);
2092 argss = gfc_walk_expr (e);
2094 if (argss == gfc_ss_terminator)
2096 parm_kind = SCALAR;
2097 if (fsym && fsym->attr.value)
2099 gfc_conv_expr (&parmse, e);
2101 else if (arg->name && arg->name[0] == '%')
2102 /* Argument list functions %VAL, %LOC and %REF are signalled
2103 through arg->name. */
2104 conv_arglist_function (&parmse, arg->expr, arg->name);
2105 else
2107 gfc_conv_expr_reference (&parmse, e);
2108 if (fsym && fsym->attr.pointer
2109 && e->expr_type != EXPR_NULL)
2111 /* Scalar pointer dummy args require an extra level of
2112 indirection. The null pointer already contains
2113 this level of indirection. */
2114 parm_kind = SCALAR_POINTER;
2115 parmse.expr = build_fold_addr_expr (parmse.expr);
2119 else
2121 /* If the procedure requires an explicit interface, the actual
2122 argument is passed according to the corresponding formal
2123 argument. If the corresponding formal argument is a POINTER,
2124 ALLOCATABLE or assumed shape, we do not use g77's calling
2125 convention, and pass the address of the array descriptor
2126 instead. Otherwise we use g77's calling convention. */
2127 int f;
2128 f = (fsym != NULL)
2129 && !(fsym->attr.pointer || fsym->attr.allocatable)
2130 && fsym->as->type != AS_ASSUMED_SHAPE;
2131 f = f || !sym->attr.always_explicit;
2133 if (e->expr_type == EXPR_VARIABLE
2134 && is_aliased_array (e))
2135 /* The actual argument is a component reference to an
2136 array of derived types. In this case, the argument
2137 is converted to a temporary, which is passed and then
2138 written back after the procedure call. */
2139 gfc_conv_aliased_arg (&parmse, e, f,
2140 fsym ? fsym->attr.intent : INTENT_INOUT);
2141 else
2142 gfc_conv_array_parameter (&parmse, e, argss, f);
2144 /* If an ALLOCATABLE dummy argument has INTENT(OUT) and is
2145 allocated on entry, it must be deallocated. */
2146 if (fsym && fsym->attr.allocatable
2147 && fsym->attr.intent == INTENT_OUT)
2149 tmp = build_fold_indirect_ref (parmse.expr);
2150 tmp = gfc_trans_dealloc_allocated (tmp);
2151 gfc_add_expr_to_block (&se->pre, tmp);
2157 if (fsym)
2159 if (e)
2161 /* If an optional argument is itself an optional dummy
2162 argument, check its presence and substitute a null
2163 if absent. */
2164 if (e->expr_type == EXPR_VARIABLE
2165 && e->symtree->n.sym->attr.optional
2166 && fsym->attr.optional)
2167 gfc_conv_missing_dummy (&parmse, e, fsym->ts);
2169 /* If an INTENT(OUT) dummy of derived type has a default
2170 initializer, it must be (re)initialized here. */
2171 if (fsym->attr.intent == INTENT_OUT
2172 && fsym->ts.type == BT_DERIVED
2173 && fsym->value)
2175 gcc_assert (!fsym->attr.allocatable);
2176 tmp = gfc_trans_assignment (e, fsym->value, false);
2177 gfc_add_expr_to_block (&se->pre, tmp);
2180 /* Obtain the character length of an assumed character
2181 length procedure from the typespec. */
2182 if (fsym->ts.type == BT_CHARACTER
2183 && parmse.string_length == NULL_TREE
2184 && e->ts.type == BT_PROCEDURE
2185 && e->symtree->n.sym->ts.type == BT_CHARACTER
2186 && e->symtree->n.sym->ts.cl->length != NULL)
2188 gfc_conv_const_charlen (e->symtree->n.sym->ts.cl);
2189 parmse.string_length
2190 = e->symtree->n.sym->ts.cl->backend_decl;
2194 if (need_interface_mapping)
2195 gfc_add_interface_mapping (&mapping, fsym, &parmse);
2198 gfc_add_block_to_block (&se->pre, &parmse.pre);
2199 gfc_add_block_to_block (&post, &parmse.post);
2201 /* Allocated allocatable components of derived types must be
2202 deallocated for INTENT(OUT) dummy arguments and non-variable
2203 scalars. Non-variable arrays are dealt with in trans-array.c
2204 (gfc_conv_array_parameter). */
2205 if (e && e->ts.type == BT_DERIVED
2206 && e->ts.derived->attr.alloc_comp
2207 && ((formal && formal->sym->attr.intent == INTENT_OUT)
2209 (e->expr_type != EXPR_VARIABLE && !e->rank)))
2211 int parm_rank;
2212 tmp = build_fold_indirect_ref (parmse.expr);
2213 parm_rank = e->rank;
2214 switch (parm_kind)
2216 case (ELEMENTAL):
2217 case (SCALAR):
2218 parm_rank = 0;
2219 break;
2221 case (SCALAR_POINTER):
2222 tmp = build_fold_indirect_ref (tmp);
2223 break;
2224 case (ARRAY):
2225 tmp = parmse.expr;
2226 break;
2229 tmp = gfc_deallocate_alloc_comp (e->ts.derived, tmp, parm_rank);
2230 if (e->expr_type == EXPR_VARIABLE && e->symtree->n.sym->attr.optional)
2231 tmp = build3_v (COND_EXPR, gfc_conv_expr_present (e->symtree->n.sym),
2232 tmp, build_empty_stmt ());
2234 if (e->expr_type != EXPR_VARIABLE)
2235 /* Don't deallocate non-variables until they have been used. */
2236 gfc_add_expr_to_block (&se->post, tmp);
2237 else
2239 gcc_assert (formal && formal->sym->attr.intent == INTENT_OUT);
2240 gfc_add_expr_to_block (&se->pre, tmp);
2244 /* Character strings are passed as two parameters, a length and a
2245 pointer. */
2246 if (parmse.string_length != NULL_TREE)
2247 stringargs = gfc_chainon_list (stringargs, parmse.string_length);
2249 arglist = gfc_chainon_list (arglist, parmse.expr);
2251 gfc_finish_interface_mapping (&mapping, &se->pre, &se->post);
2253 ts = sym->ts;
2254 if (ts.type == BT_CHARACTER)
2256 if (sym->ts.cl->length == NULL)
2258 /* Assumed character length results are not allowed by 5.1.1.5 of the
2259 standard and are trapped in resolve.c; except in the case of SPREAD
2260 (and other intrinsics?) and dummy functions. In the case of SPREAD,
2261 we take the character length of the first argument for the result.
2262 For dummies, we have to look through the formal argument list for
2263 this function and use the character length found there.*/
2264 if (!sym->attr.dummy)
2265 cl.backend_decl = TREE_VALUE (stringargs);
2266 else
2268 formal = sym->ns->proc_name->formal;
2269 for (; formal; formal = formal->next)
2270 if (strcmp (formal->sym->name, sym->name) == 0)
2271 cl.backend_decl = formal->sym->ts.cl->backend_decl;
2274 else
2276 /* Calculate the length of the returned string. */
2277 gfc_init_se (&parmse, NULL);
2278 if (need_interface_mapping)
2279 gfc_apply_interface_mapping (&mapping, &parmse, sym->ts.cl->length);
2280 else
2281 gfc_conv_expr (&parmse, sym->ts.cl->length);
2282 gfc_add_block_to_block (&se->pre, &parmse.pre);
2283 gfc_add_block_to_block (&se->post, &parmse.post);
2284 cl.backend_decl = fold_convert (gfc_charlen_type_node, parmse.expr);
2287 /* Set up a charlen structure for it. */
2288 cl.next = NULL;
2289 cl.length = NULL;
2290 ts.cl = &cl;
2292 len = cl.backend_decl;
2295 byref = gfc_return_by_reference (sym);
2296 if (byref)
2298 if (se->direct_byref)
2299 retargs = gfc_chainon_list (retargs, se->expr);
2300 else if (sym->result->attr.dimension)
2302 gcc_assert (se->loop && info);
2304 /* Set the type of the array. */
2305 tmp = gfc_typenode_for_spec (&ts);
2306 info->dimen = se->loop->dimen;
2308 /* Evaluate the bounds of the result, if known. */
2309 gfc_set_loop_bounds_from_array_spec (&mapping, se, sym->result->as);
2311 /* Create a temporary to store the result. In case the function
2312 returns a pointer, the temporary will be a shallow copy and
2313 mustn't be deallocated. */
2314 callee_alloc = sym->attr.allocatable || sym->attr.pointer;
2315 gfc_trans_create_temp_array (&se->pre, &se->post, se->loop, info, tmp,
2316 false, !sym->attr.pointer, callee_alloc);
2318 /* Pass the temporary as the first argument. */
2319 tmp = info->descriptor;
2320 tmp = build_fold_addr_expr (tmp);
2321 retargs = gfc_chainon_list (retargs, tmp);
2323 else if (ts.type == BT_CHARACTER)
2325 /* Pass the string length. */
2326 type = gfc_get_character_type (ts.kind, ts.cl);
2327 type = build_pointer_type (type);
2329 /* Return an address to a char[0:len-1]* temporary for
2330 character pointers. */
2331 if (sym->attr.pointer || sym->attr.allocatable)
2333 /* Build char[0:len-1] * pstr. */
2334 tmp = fold_build2 (MINUS_EXPR, gfc_charlen_type_node, len,
2335 build_int_cst (gfc_charlen_type_node, 1));
2336 tmp = build_range_type (gfc_array_index_type,
2337 gfc_index_zero_node, tmp);
2338 tmp = build_array_type (gfc_character1_type_node, tmp);
2339 var = gfc_create_var (build_pointer_type (tmp), "pstr");
2341 /* Provide an address expression for the function arguments. */
2342 var = build_fold_addr_expr (var);
2344 else
2345 var = gfc_conv_string_tmp (se, type, len);
2347 retargs = gfc_chainon_list (retargs, var);
2349 else
2351 gcc_assert (gfc_option.flag_f2c && ts.type == BT_COMPLEX);
2353 type = gfc_get_complex_type (ts.kind);
2354 var = build_fold_addr_expr (gfc_create_var (type, "cmplx"));
2355 retargs = gfc_chainon_list (retargs, var);
2358 /* Add the string length to the argument list. */
2359 if (ts.type == BT_CHARACTER)
2360 retargs = gfc_chainon_list (retargs, len);
2362 gfc_free_interface_mapping (&mapping);
2364 /* Add the return arguments. */
2365 arglist = chainon (retargs, arglist);
2367 /* Add the hidden string length parameters to the arguments. */
2368 arglist = chainon (arglist, stringargs);
2370 /* We may want to append extra arguments here. This is used e.g. for
2371 calls to libgfortran_matmul_??, which need extra information. */
2372 if (append_args != NULL_TREE)
2373 arglist = chainon (arglist, append_args);
2375 /* Generate the actual call. */
2376 gfc_conv_function_val (se, sym);
2377 /* If there are alternate return labels, function type should be
2378 integer. Can't modify the type in place though, since it can be shared
2379 with other functions. */
2380 if (has_alternate_specifier
2381 && TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr))) != integer_type_node)
2383 gcc_assert (! sym->attr.dummy);
2384 TREE_TYPE (sym->backend_decl)
2385 = build_function_type (integer_type_node,
2386 TYPE_ARG_TYPES (TREE_TYPE (sym->backend_decl)));
2387 se->expr = build_fold_addr_expr (sym->backend_decl);
2390 fntype = TREE_TYPE (TREE_TYPE (se->expr));
2391 se->expr = build_call_list (TREE_TYPE (fntype), se->expr, arglist);
2393 /* If we have a pointer function, but we don't want a pointer, e.g.
2394 something like
2395 x = f()
2396 where f is pointer valued, we have to dereference the result. */
2397 if (!se->want_pointer && !byref && sym->attr.pointer)
2398 se->expr = build_fold_indirect_ref (se->expr);
2400 /* f2c calling conventions require a scalar default real function to
2401 return a double precision result. Convert this back to default
2402 real. We only care about the cases that can happen in Fortran 77.
2404 if (gfc_option.flag_f2c && sym->ts.type == BT_REAL
2405 && sym->ts.kind == gfc_default_real_kind
2406 && !sym->attr.always_explicit)
2407 se->expr = fold_convert (gfc_get_real_type (sym->ts.kind), se->expr);
2409 /* A pure function may still have side-effects - it may modify its
2410 parameters. */
2411 TREE_SIDE_EFFECTS (se->expr) = 1;
2412 #if 0
2413 if (!sym->attr.pure)
2414 TREE_SIDE_EFFECTS (se->expr) = 1;
2415 #endif
2417 if (byref)
2419 /* Add the function call to the pre chain. There is no expression. */
2420 gfc_add_expr_to_block (&se->pre, se->expr);
2421 se->expr = NULL_TREE;
2423 if (!se->direct_byref)
2425 if (sym->attr.dimension)
2427 if (flag_bounds_check)
2429 /* Check the data pointer hasn't been modified. This would
2430 happen in a function returning a pointer. */
2431 tmp = gfc_conv_descriptor_data_get (info->descriptor);
2432 tmp = fold_build2 (NE_EXPR, boolean_type_node,
2433 tmp, info->data);
2434 gfc_trans_runtime_check (tmp, gfc_msg_fault, &se->pre, NULL);
2436 se->expr = info->descriptor;
2437 /* Bundle in the string length. */
2438 se->string_length = len;
2440 else if (sym->ts.type == BT_CHARACTER)
2442 /* Dereference for character pointer results. */
2443 if (sym->attr.pointer || sym->attr.allocatable)
2444 se->expr = build_fold_indirect_ref (var);
2445 else
2446 se->expr = var;
2448 se->string_length = len;
2450 else
2452 gcc_assert (sym->ts.type == BT_COMPLEX && gfc_option.flag_f2c);
2453 se->expr = build_fold_indirect_ref (var);
2458 /* Follow the function call with the argument post block. */
2459 if (byref)
2460 gfc_add_block_to_block (&se->pre, &post);
2461 else
2462 gfc_add_block_to_block (&se->post, &post);
2464 return has_alternate_specifier;
2468 /* Generate code to copy a string. */
2470 static void
2471 gfc_trans_string_copy (stmtblock_t * block, tree dlength, tree dest,
2472 tree slength, tree src)
2474 tree tmp, dlen, slen;
2475 tree dsc;
2476 tree ssc;
2477 tree cond;
2478 tree cond2;
2479 tree tmp2;
2480 tree tmp3;
2481 tree tmp4;
2482 stmtblock_t tempblock;
2484 dlen = fold_convert (size_type_node, gfc_evaluate_now (dlength, block));
2485 slen = fold_convert (size_type_node, gfc_evaluate_now (slength, block));
2487 /* Deal with single character specially. */
2488 dsc = gfc_to_single_character (dlen, dest);
2489 ssc = gfc_to_single_character (slen, src);
2490 if (dsc != NULL_TREE && ssc != NULL_TREE)
2492 gfc_add_modify_expr (block, dsc, ssc);
2493 return;
2496 /* Do nothing if the destination length is zero. */
2497 cond = fold_build2 (GT_EXPR, boolean_type_node, dlen,
2498 build_int_cst (gfc_charlen_type_node, 0));
2500 /* The following code was previously in _gfortran_copy_string:
2502 // The two strings may overlap so we use memmove.
2503 void
2504 copy_string (GFC_INTEGER_4 destlen, char * dest,
2505 GFC_INTEGER_4 srclen, const char * src)
2507 if (srclen >= destlen)
2509 // This will truncate if too long.
2510 memmove (dest, src, destlen);
2512 else
2514 memmove (dest, src, srclen);
2515 // Pad with spaces.
2516 memset (&dest[srclen], ' ', destlen - srclen);
2520 We're now doing it here for better optimization, but the logic
2521 is the same. */
2523 /* Truncate string if source is too long. */
2524 cond2 = fold_build2 (GE_EXPR, boolean_type_node, slen, dlen);
2525 tmp2 = build_call_expr (built_in_decls[BUILT_IN_MEMMOVE],
2526 3, dest, src, dlen);
2528 /* Else copy and pad with spaces. */
2529 tmp3 = build_call_expr (built_in_decls[BUILT_IN_MEMMOVE],
2530 3, dest, src, slen);
2532 tmp4 = fold_build2 (PLUS_EXPR, pchar_type_node, dest,
2533 fold_convert (pchar_type_node, slen));
2534 tmp4 = build_call_expr (built_in_decls[BUILT_IN_MEMSET], 3,
2535 tmp4,
2536 build_int_cst (gfc_get_int_type (gfc_c_int_kind),
2537 lang_hooks.to_target_charset (' ')),
2538 fold_build2 (MINUS_EXPR, TREE_TYPE(dlen),
2539 dlen, slen));
2541 gfc_init_block (&tempblock);
2542 gfc_add_expr_to_block (&tempblock, tmp3);
2543 gfc_add_expr_to_block (&tempblock, tmp4);
2544 tmp3 = gfc_finish_block (&tempblock);
2546 /* The whole copy_string function is there. */
2547 tmp = fold_build3 (COND_EXPR, void_type_node, cond2, tmp2, tmp3);
2548 tmp = fold_build3 (COND_EXPR, void_type_node, cond, tmp, build_empty_stmt ());
2549 gfc_add_expr_to_block (block, tmp);
2553 /* Translate a statement function.
2554 The value of a statement function reference is obtained by evaluating the
2555 expression using the values of the actual arguments for the values of the
2556 corresponding dummy arguments. */
2558 static void
2559 gfc_conv_statement_function (gfc_se * se, gfc_expr * expr)
2561 gfc_symbol *sym;
2562 gfc_symbol *fsym;
2563 gfc_formal_arglist *fargs;
2564 gfc_actual_arglist *args;
2565 gfc_se lse;
2566 gfc_se rse;
2567 gfc_saved_var *saved_vars;
2568 tree *temp_vars;
2569 tree type;
2570 tree tmp;
2571 int n;
2573 sym = expr->symtree->n.sym;
2574 args = expr->value.function.actual;
2575 gfc_init_se (&lse, NULL);
2576 gfc_init_se (&rse, NULL);
2578 n = 0;
2579 for (fargs = sym->formal; fargs; fargs = fargs->next)
2580 n++;
2581 saved_vars = (gfc_saved_var *)gfc_getmem (n * sizeof (gfc_saved_var));
2582 temp_vars = (tree *)gfc_getmem (n * sizeof (tree));
2584 for (fargs = sym->formal, n = 0; fargs; fargs = fargs->next, n++)
2586 /* Each dummy shall be specified, explicitly or implicitly, to be
2587 scalar. */
2588 gcc_assert (fargs->sym->attr.dimension == 0);
2589 fsym = fargs->sym;
2591 /* Create a temporary to hold the value. */
2592 type = gfc_typenode_for_spec (&fsym->ts);
2593 temp_vars[n] = gfc_create_var (type, fsym->name);
2595 if (fsym->ts.type == BT_CHARACTER)
2597 /* Copy string arguments. */
2598 tree arglen;
2600 gcc_assert (fsym->ts.cl && fsym->ts.cl->length
2601 && fsym->ts.cl->length->expr_type == EXPR_CONSTANT);
2603 arglen = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
2604 tmp = gfc_build_addr_expr (build_pointer_type (type),
2605 temp_vars[n]);
2607 gfc_conv_expr (&rse, args->expr);
2608 gfc_conv_string_parameter (&rse);
2609 gfc_add_block_to_block (&se->pre, &lse.pre);
2610 gfc_add_block_to_block (&se->pre, &rse.pre);
2612 gfc_trans_string_copy (&se->pre, arglen, tmp, rse.string_length,
2613 rse.expr);
2614 gfc_add_block_to_block (&se->pre, &lse.post);
2615 gfc_add_block_to_block (&se->pre, &rse.post);
2617 else
2619 /* For everything else, just evaluate the expression. */
2620 gfc_conv_expr (&lse, args->expr);
2622 gfc_add_block_to_block (&se->pre, &lse.pre);
2623 gfc_add_modify_expr (&se->pre, temp_vars[n], lse.expr);
2624 gfc_add_block_to_block (&se->pre, &lse.post);
2627 args = args->next;
2630 /* Use the temporary variables in place of the real ones. */
2631 for (fargs = sym->formal, n = 0; fargs; fargs = fargs->next, n++)
2632 gfc_shadow_sym (fargs->sym, temp_vars[n], &saved_vars[n]);
2634 gfc_conv_expr (se, sym->value);
2636 if (sym->ts.type == BT_CHARACTER)
2638 gfc_conv_const_charlen (sym->ts.cl);
2640 /* Force the expression to the correct length. */
2641 if (!INTEGER_CST_P (se->string_length)
2642 || tree_int_cst_lt (se->string_length,
2643 sym->ts.cl->backend_decl))
2645 type = gfc_get_character_type (sym->ts.kind, sym->ts.cl);
2646 tmp = gfc_create_var (type, sym->name);
2647 tmp = gfc_build_addr_expr (build_pointer_type (type), tmp);
2648 gfc_trans_string_copy (&se->pre, sym->ts.cl->backend_decl, tmp,
2649 se->string_length, se->expr);
2650 se->expr = tmp;
2652 se->string_length = sym->ts.cl->backend_decl;
2655 /* Restore the original variables. */
2656 for (fargs = sym->formal, n = 0; fargs; fargs = fargs->next, n++)
2657 gfc_restore_sym (fargs->sym, &saved_vars[n]);
2658 gfc_free (saved_vars);
2662 /* Translate a function expression. */
2664 static void
2665 gfc_conv_function_expr (gfc_se * se, gfc_expr * expr)
2667 gfc_symbol *sym;
2669 if (expr->value.function.isym)
2671 gfc_conv_intrinsic_function (se, expr);
2672 return;
2675 /* We distinguish statement functions from general functions to improve
2676 runtime performance. */
2677 if (expr->symtree->n.sym->attr.proc == PROC_ST_FUNCTION)
2679 gfc_conv_statement_function (se, expr);
2680 return;
2683 /* expr.value.function.esym is the resolved (specific) function symbol for
2684 most functions. However this isn't set for dummy procedures. */
2685 sym = expr->value.function.esym;
2686 if (!sym)
2687 sym = expr->symtree->n.sym;
2688 gfc_conv_function_call (se, sym, expr->value.function.actual, NULL_TREE);
2692 static void
2693 gfc_conv_array_constructor_expr (gfc_se * se, gfc_expr * expr)
2695 gcc_assert (se->ss != NULL && se->ss != gfc_ss_terminator);
2696 gcc_assert (se->ss->expr == expr && se->ss->type == GFC_SS_CONSTRUCTOR);
2698 gfc_conv_tmp_array_ref (se);
2699 gfc_advance_se_ss_chain (se);
2703 /* Build a static initializer. EXPR is the expression for the initial value.
2704 The other parameters describe the variable of the component being
2705 initialized. EXPR may be null. */
2707 tree
2708 gfc_conv_initializer (gfc_expr * expr, gfc_typespec * ts, tree type,
2709 bool array, bool pointer)
2711 gfc_se se;
2713 if (!(expr || pointer))
2714 return NULL_TREE;
2716 if (array)
2718 /* Arrays need special handling. */
2719 if (pointer)
2720 return gfc_build_null_descriptor (type);
2721 else
2722 return gfc_conv_array_initializer (type, expr);
2724 else if (pointer)
2725 return fold_convert (type, null_pointer_node);
2726 else
2728 switch (ts->type)
2730 case BT_DERIVED:
2731 gfc_init_se (&se, NULL);
2732 gfc_conv_structure (&se, expr, 1);
2733 return se.expr;
2735 case BT_CHARACTER:
2736 return gfc_conv_string_init (ts->cl->backend_decl,expr);
2738 default:
2739 gfc_init_se (&se, NULL);
2740 gfc_conv_constant (&se, expr);
2741 return se.expr;
2746 static tree
2747 gfc_trans_subarray_assign (tree dest, gfc_component * cm, gfc_expr * expr)
2749 gfc_se rse;
2750 gfc_se lse;
2751 gfc_ss *rss;
2752 gfc_ss *lss;
2753 stmtblock_t body;
2754 stmtblock_t block;
2755 gfc_loopinfo loop;
2756 int n;
2757 tree tmp;
2759 gfc_start_block (&block);
2761 /* Initialize the scalarizer. */
2762 gfc_init_loopinfo (&loop);
2764 gfc_init_se (&lse, NULL);
2765 gfc_init_se (&rse, NULL);
2767 /* Walk the rhs. */
2768 rss = gfc_walk_expr (expr);
2769 if (rss == gfc_ss_terminator)
2771 /* The rhs is scalar. Add a ss for the expression. */
2772 rss = gfc_get_ss ();
2773 rss->next = gfc_ss_terminator;
2774 rss->type = GFC_SS_SCALAR;
2775 rss->expr = expr;
2778 /* Create a SS for the destination. */
2779 lss = gfc_get_ss ();
2780 lss->type = GFC_SS_COMPONENT;
2781 lss->expr = NULL;
2782 lss->shape = gfc_get_shape (cm->as->rank);
2783 lss->next = gfc_ss_terminator;
2784 lss->data.info.dimen = cm->as->rank;
2785 lss->data.info.descriptor = dest;
2786 lss->data.info.data = gfc_conv_array_data (dest);
2787 lss->data.info.offset = gfc_conv_array_offset (dest);
2788 for (n = 0; n < cm->as->rank; n++)
2790 lss->data.info.dim[n] = n;
2791 lss->data.info.start[n] = gfc_conv_array_lbound (dest, n);
2792 lss->data.info.stride[n] = gfc_index_one_node;
2794 mpz_init (lss->shape[n]);
2795 mpz_sub (lss->shape[n], cm->as->upper[n]->value.integer,
2796 cm->as->lower[n]->value.integer);
2797 mpz_add_ui (lss->shape[n], lss->shape[n], 1);
2800 /* Associate the SS with the loop. */
2801 gfc_add_ss_to_loop (&loop, lss);
2802 gfc_add_ss_to_loop (&loop, rss);
2804 /* Calculate the bounds of the scalarization. */
2805 gfc_conv_ss_startstride (&loop);
2807 /* Setup the scalarizing loops. */
2808 gfc_conv_loop_setup (&loop);
2810 /* Setup the gfc_se structures. */
2811 gfc_copy_loopinfo_to_se (&lse, &loop);
2812 gfc_copy_loopinfo_to_se (&rse, &loop);
2814 rse.ss = rss;
2815 gfc_mark_ss_chain_used (rss, 1);
2816 lse.ss = lss;
2817 gfc_mark_ss_chain_used (lss, 1);
2819 /* Start the scalarized loop body. */
2820 gfc_start_scalarized_body (&loop, &body);
2822 gfc_conv_tmp_array_ref (&lse);
2823 if (cm->ts.type == BT_CHARACTER)
2824 lse.string_length = cm->ts.cl->backend_decl;
2826 gfc_conv_expr (&rse, expr);
2828 tmp = gfc_trans_scalar_assign (&lse, &rse, cm->ts, true, false);
2829 gfc_add_expr_to_block (&body, tmp);
2831 gcc_assert (rse.ss == gfc_ss_terminator);
2833 /* Generate the copying loops. */
2834 gfc_trans_scalarizing_loops (&loop, &body);
2836 /* Wrap the whole thing up. */
2837 gfc_add_block_to_block (&block, &loop.pre);
2838 gfc_add_block_to_block (&block, &loop.post);
2840 for (n = 0; n < cm->as->rank; n++)
2841 mpz_clear (lss->shape[n]);
2842 gfc_free (lss->shape);
2844 gfc_cleanup_loop (&loop);
2846 return gfc_finish_block (&block);
2850 /* Assign a single component of a derived type constructor. */
2852 static tree
2853 gfc_trans_subcomponent_assign (tree dest, gfc_component * cm, gfc_expr * expr)
2855 gfc_se se;
2856 gfc_se lse;
2857 gfc_ss *rss;
2858 stmtblock_t block;
2859 tree tmp;
2860 tree offset;
2861 int n;
2863 gfc_start_block (&block);
2865 if (cm->pointer)
2867 gfc_init_se (&se, NULL);
2868 /* Pointer component. */
2869 if (cm->dimension)
2871 /* Array pointer. */
2872 if (expr->expr_type == EXPR_NULL)
2873 gfc_conv_descriptor_data_set (&block, dest, null_pointer_node);
2874 else
2876 rss = gfc_walk_expr (expr);
2877 se.direct_byref = 1;
2878 se.expr = dest;
2879 gfc_conv_expr_descriptor (&se, expr, rss);
2880 gfc_add_block_to_block (&block, &se.pre);
2881 gfc_add_block_to_block (&block, &se.post);
2884 else
2886 /* Scalar pointers. */
2887 se.want_pointer = 1;
2888 gfc_conv_expr (&se, expr);
2889 gfc_add_block_to_block (&block, &se.pre);
2890 gfc_add_modify_expr (&block, dest,
2891 fold_convert (TREE_TYPE (dest), se.expr));
2892 gfc_add_block_to_block (&block, &se.post);
2895 else if (cm->dimension)
2897 if (cm->allocatable && expr->expr_type == EXPR_NULL)
2898 gfc_conv_descriptor_data_set (&block, dest, null_pointer_node);
2899 else if (cm->allocatable)
2901 tree tmp2;
2903 gfc_init_se (&se, NULL);
2905 rss = gfc_walk_expr (expr);
2906 se.want_pointer = 0;
2907 gfc_conv_expr_descriptor (&se, expr, rss);
2908 gfc_add_block_to_block (&block, &se.pre);
2910 tmp = fold_convert (TREE_TYPE (dest), se.expr);
2911 gfc_add_modify_expr (&block, dest, tmp);
2913 if (cm->ts.type == BT_DERIVED && cm->ts.derived->attr.alloc_comp)
2914 tmp = gfc_copy_alloc_comp (cm->ts.derived, se.expr, dest,
2915 cm->as->rank);
2916 else
2917 tmp = gfc_duplicate_allocatable (dest, se.expr,
2918 TREE_TYPE(cm->backend_decl),
2919 cm->as->rank);
2921 gfc_add_expr_to_block (&block, tmp);
2923 gfc_add_block_to_block (&block, &se.post);
2924 gfc_conv_descriptor_data_set (&block, se.expr, null_pointer_node);
2926 /* Shift the lbound and ubound of temporaries to being unity, rather
2927 than zero, based. Calculate the offset for all cases. */
2928 offset = gfc_conv_descriptor_offset (dest);
2929 gfc_add_modify_expr (&block, offset, gfc_index_zero_node);
2930 tmp2 =gfc_create_var (gfc_array_index_type, NULL);
2931 for (n = 0; n < expr->rank; n++)
2933 if (expr->expr_type != EXPR_VARIABLE
2934 && expr->expr_type != EXPR_CONSTANT)
2936 tmp = gfc_conv_descriptor_ubound (dest, gfc_rank_cst[n]);
2937 gfc_add_modify_expr (&block, tmp,
2938 fold_build2 (PLUS_EXPR,
2939 gfc_array_index_type,
2940 tmp, gfc_index_one_node));
2941 tmp = gfc_conv_descriptor_lbound (dest, gfc_rank_cst[n]);
2942 gfc_add_modify_expr (&block, tmp, gfc_index_one_node);
2944 tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
2945 gfc_conv_descriptor_lbound (dest,
2946 gfc_rank_cst[n]),
2947 gfc_conv_descriptor_stride (dest,
2948 gfc_rank_cst[n]));
2949 gfc_add_modify_expr (&block, tmp2, tmp);
2950 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type, offset, tmp2);
2951 gfc_add_modify_expr (&block, offset, tmp);
2954 else
2956 tmp = gfc_trans_subarray_assign (dest, cm, expr);
2957 gfc_add_expr_to_block (&block, tmp);
2960 else if (expr->ts.type == BT_DERIVED)
2962 if (expr->expr_type != EXPR_STRUCTURE)
2964 gfc_init_se (&se, NULL);
2965 gfc_conv_expr (&se, expr);
2966 gfc_add_modify_expr (&block, dest,
2967 fold_convert (TREE_TYPE (dest), se.expr));
2969 else
2971 /* Nested constructors. */
2972 tmp = gfc_trans_structure_assign (dest, expr);
2973 gfc_add_expr_to_block (&block, tmp);
2976 else
2978 /* Scalar component. */
2979 gfc_init_se (&se, NULL);
2980 gfc_init_se (&lse, NULL);
2982 gfc_conv_expr (&se, expr);
2983 if (cm->ts.type == BT_CHARACTER)
2984 lse.string_length = cm->ts.cl->backend_decl;
2985 lse.expr = dest;
2986 tmp = gfc_trans_scalar_assign (&lse, &se, cm->ts, true, false);
2987 gfc_add_expr_to_block (&block, tmp);
2989 return gfc_finish_block (&block);
2992 /* Assign a derived type constructor to a variable. */
2994 static tree
2995 gfc_trans_structure_assign (tree dest, gfc_expr * expr)
2997 gfc_constructor *c;
2998 gfc_component *cm;
2999 stmtblock_t block;
3000 tree field;
3001 tree tmp;
3003 gfc_start_block (&block);
3004 cm = expr->ts.derived->components;
3005 for (c = expr->value.constructor; c; c = c->next, cm = cm->next)
3007 /* Skip absent members in default initializers. */
3008 if (!c->expr)
3009 continue;
3011 field = cm->backend_decl;
3012 tmp = build3 (COMPONENT_REF, TREE_TYPE (field), dest, field, NULL_TREE);
3013 tmp = gfc_trans_subcomponent_assign (tmp, cm, c->expr);
3014 gfc_add_expr_to_block (&block, tmp);
3016 return gfc_finish_block (&block);
3019 /* Build an expression for a constructor. If init is nonzero then
3020 this is part of a static variable initializer. */
3022 void
3023 gfc_conv_structure (gfc_se * se, gfc_expr * expr, int init)
3025 gfc_constructor *c;
3026 gfc_component *cm;
3027 tree val;
3028 tree type;
3029 tree tmp;
3030 VEC(constructor_elt,gc) *v = NULL;
3032 gcc_assert (se->ss == NULL);
3033 gcc_assert (expr->expr_type == EXPR_STRUCTURE);
3034 type = gfc_typenode_for_spec (&expr->ts);
3036 if (!init)
3038 /* Create a temporary variable and fill it in. */
3039 se->expr = gfc_create_var (type, expr->ts.derived->name);
3040 tmp = gfc_trans_structure_assign (se->expr, expr);
3041 gfc_add_expr_to_block (&se->pre, tmp);
3042 return;
3045 cm = expr->ts.derived->components;
3047 for (c = expr->value.constructor; c; c = c->next, cm = cm->next)
3049 /* Skip absent members in default initializers and allocatable
3050 components. Although the latter have a default initializer
3051 of EXPR_NULL,... by default, the static nullify is not needed
3052 since this is done every time we come into scope. */
3053 if (!c->expr || cm->allocatable)
3054 continue;
3056 val = gfc_conv_initializer (c->expr, &cm->ts,
3057 TREE_TYPE (cm->backend_decl), cm->dimension, cm->pointer);
3059 /* Append it to the constructor list. */
3060 CONSTRUCTOR_APPEND_ELT (v, cm->backend_decl, val);
3062 se->expr = build_constructor (type, v);
3066 /* Translate a substring expression. */
3068 static void
3069 gfc_conv_substring_expr (gfc_se * se, gfc_expr * expr)
3071 gfc_ref *ref;
3073 ref = expr->ref;
3075 gcc_assert (ref->type == REF_SUBSTRING);
3077 se->expr = gfc_build_string_const(expr->value.character.length,
3078 expr->value.character.string);
3079 se->string_length = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (se->expr)));
3080 TYPE_STRING_FLAG (TREE_TYPE (se->expr))=1;
3082 gfc_conv_substring(se,ref,expr->ts.kind,NULL,&expr->where);
3086 /* Entry point for expression translation. Evaluates a scalar quantity.
3087 EXPR is the expression to be translated, and SE is the state structure if
3088 called from within the scalarized. */
3090 void
3091 gfc_conv_expr (gfc_se * se, gfc_expr * expr)
3093 if (se->ss && se->ss->expr == expr
3094 && (se->ss->type == GFC_SS_SCALAR || se->ss->type == GFC_SS_REFERENCE))
3096 /* Substitute a scalar expression evaluated outside the scalarization
3097 loop. */
3098 se->expr = se->ss->data.scalar.expr;
3099 se->string_length = se->ss->string_length;
3100 gfc_advance_se_ss_chain (se);
3101 return;
3104 switch (expr->expr_type)
3106 case EXPR_OP:
3107 gfc_conv_expr_op (se, expr);
3108 break;
3110 case EXPR_FUNCTION:
3111 gfc_conv_function_expr (se, expr);
3112 break;
3114 case EXPR_CONSTANT:
3115 gfc_conv_constant (se, expr);
3116 break;
3118 case EXPR_VARIABLE:
3119 gfc_conv_variable (se, expr);
3120 break;
3122 case EXPR_NULL:
3123 se->expr = null_pointer_node;
3124 break;
3126 case EXPR_SUBSTRING:
3127 gfc_conv_substring_expr (se, expr);
3128 break;
3130 case EXPR_STRUCTURE:
3131 gfc_conv_structure (se, expr, 0);
3132 break;
3134 case EXPR_ARRAY:
3135 gfc_conv_array_constructor_expr (se, expr);
3136 break;
3138 default:
3139 gcc_unreachable ();
3140 break;
3144 /* Like gfc_conv_expr_val, but the value is also suitable for use in the lhs
3145 of an assignment. */
3146 void
3147 gfc_conv_expr_lhs (gfc_se * se, gfc_expr * expr)
3149 gfc_conv_expr (se, expr);
3150 /* All numeric lvalues should have empty post chains. If not we need to
3151 figure out a way of rewriting an lvalue so that it has no post chain. */
3152 gcc_assert (expr->ts.type == BT_CHARACTER || !se->post.head);
3155 /* Like gfc_conv_expr, but the POST block is guaranteed to be empty for
3156 numeric expressions. Used for scalar values where inserting cleanup code
3157 is inconvenient. */
3158 void
3159 gfc_conv_expr_val (gfc_se * se, gfc_expr * expr)
3161 tree val;
3163 gcc_assert (expr->ts.type != BT_CHARACTER);
3164 gfc_conv_expr (se, expr);
3165 if (se->post.head)
3167 val = gfc_create_var (TREE_TYPE (se->expr), NULL);
3168 gfc_add_modify_expr (&se->pre, val, se->expr);
3169 se->expr = val;
3170 gfc_add_block_to_block (&se->pre, &se->post);
3174 /* Helper to translate and expression and convert it to a particular type. */
3175 void
3176 gfc_conv_expr_type (gfc_se * se, gfc_expr * expr, tree type)
3178 gfc_conv_expr_val (se, expr);
3179 se->expr = convert (type, se->expr);
3183 /* Converts an expression so that it can be passed by reference. Scalar
3184 values only. */
3186 void
3187 gfc_conv_expr_reference (gfc_se * se, gfc_expr * expr)
3189 tree var;
3191 if (se->ss && se->ss->expr == expr
3192 && se->ss->type == GFC_SS_REFERENCE)
3194 se->expr = se->ss->data.scalar.expr;
3195 se->string_length = se->ss->string_length;
3196 gfc_advance_se_ss_chain (se);
3197 return;
3200 if (expr->ts.type == BT_CHARACTER)
3202 gfc_conv_expr (se, expr);
3203 gfc_conv_string_parameter (se);
3204 return;
3207 if (expr->expr_type == EXPR_VARIABLE)
3209 se->want_pointer = 1;
3210 gfc_conv_expr (se, expr);
3211 if (se->post.head)
3213 var = gfc_create_var (TREE_TYPE (se->expr), NULL);
3214 gfc_add_modify_expr (&se->pre, var, se->expr);
3215 gfc_add_block_to_block (&se->pre, &se->post);
3216 se->expr = var;
3218 return;
3221 gfc_conv_expr (se, expr);
3223 /* Create a temporary var to hold the value. */
3224 if (TREE_CONSTANT (se->expr))
3226 tree tmp = se->expr;
3227 STRIP_TYPE_NOPS (tmp);
3228 var = build_decl (CONST_DECL, NULL, TREE_TYPE (tmp));
3229 DECL_INITIAL (var) = tmp;
3230 TREE_STATIC (var) = 1;
3231 pushdecl (var);
3233 else
3235 var = gfc_create_var (TREE_TYPE (se->expr), NULL);
3236 gfc_add_modify_expr (&se->pre, var, se->expr);
3238 gfc_add_block_to_block (&se->pre, &se->post);
3240 /* Take the address of that value. */
3241 se->expr = build_fold_addr_expr (var);
3245 tree
3246 gfc_trans_pointer_assign (gfc_code * code)
3248 return gfc_trans_pointer_assignment (code->expr, code->expr2);
3252 /* Generate code for a pointer assignment. */
3254 tree
3255 gfc_trans_pointer_assignment (gfc_expr * expr1, gfc_expr * expr2)
3257 gfc_se lse;
3258 gfc_se rse;
3259 gfc_ss *lss;
3260 gfc_ss *rss;
3261 stmtblock_t block;
3262 tree desc;
3263 tree tmp;
3265 gfc_start_block (&block);
3267 gfc_init_se (&lse, NULL);
3269 lss = gfc_walk_expr (expr1);
3270 rss = gfc_walk_expr (expr2);
3271 if (lss == gfc_ss_terminator)
3273 /* Scalar pointers. */
3274 lse.want_pointer = 1;
3275 gfc_conv_expr (&lse, expr1);
3276 gcc_assert (rss == gfc_ss_terminator);
3277 gfc_init_se (&rse, NULL);
3278 rse.want_pointer = 1;
3279 gfc_conv_expr (&rse, expr2);
3280 gfc_add_block_to_block (&block, &lse.pre);
3281 gfc_add_block_to_block (&block, &rse.pre);
3282 gfc_add_modify_expr (&block, lse.expr,
3283 fold_convert (TREE_TYPE (lse.expr), rse.expr));
3284 gfc_add_block_to_block (&block, &rse.post);
3285 gfc_add_block_to_block (&block, &lse.post);
3287 else
3289 /* Array pointer. */
3290 gfc_conv_expr_descriptor (&lse, expr1, lss);
3291 switch (expr2->expr_type)
3293 case EXPR_NULL:
3294 /* Just set the data pointer to null. */
3295 gfc_conv_descriptor_data_set (&lse.pre, lse.expr, null_pointer_node);
3296 break;
3298 case EXPR_VARIABLE:
3299 /* Assign directly to the pointer's descriptor. */
3300 lse.direct_byref = 1;
3301 gfc_conv_expr_descriptor (&lse, expr2, rss);
3302 break;
3304 default:
3305 /* Assign to a temporary descriptor and then copy that
3306 temporary to the pointer. */
3307 desc = lse.expr;
3308 tmp = gfc_create_var (TREE_TYPE (desc), "ptrtemp");
3310 lse.expr = tmp;
3311 lse.direct_byref = 1;
3312 gfc_conv_expr_descriptor (&lse, expr2, rss);
3313 gfc_add_modify_expr (&lse.pre, desc, tmp);
3314 break;
3316 gfc_add_block_to_block (&block, &lse.pre);
3317 gfc_add_block_to_block (&block, &lse.post);
3319 return gfc_finish_block (&block);
3323 /* Makes sure se is suitable for passing as a function string parameter. */
3324 /* TODO: Need to check all callers fo this function. It may be abused. */
3326 void
3327 gfc_conv_string_parameter (gfc_se * se)
3329 tree type;
3331 if (TREE_CODE (se->expr) == STRING_CST)
3333 se->expr = gfc_build_addr_expr (pchar_type_node, se->expr);
3334 return;
3337 type = TREE_TYPE (se->expr);
3338 if (TYPE_STRING_FLAG (type))
3340 gcc_assert (TREE_CODE (se->expr) != INDIRECT_REF);
3341 se->expr = gfc_build_addr_expr (pchar_type_node, se->expr);
3344 gcc_assert (POINTER_TYPE_P (TREE_TYPE (se->expr)));
3345 gcc_assert (se->string_length
3346 && TREE_CODE (TREE_TYPE (se->string_length)) == INTEGER_TYPE);
3350 /* Generate code for assignment of scalar variables. Includes character
3351 strings and derived types with allocatable components. */
3353 tree
3354 gfc_trans_scalar_assign (gfc_se * lse, gfc_se * rse, gfc_typespec ts,
3355 bool l_is_temp, bool r_is_var)
3357 stmtblock_t block;
3358 tree tmp;
3359 tree cond;
3361 gfc_init_block (&block);
3363 if (ts.type == BT_CHARACTER)
3365 gcc_assert (lse->string_length != NULL_TREE
3366 && rse->string_length != NULL_TREE);
3368 gfc_conv_string_parameter (lse);
3369 gfc_conv_string_parameter (rse);
3371 gfc_add_block_to_block (&block, &lse->pre);
3372 gfc_add_block_to_block (&block, &rse->pre);
3374 gfc_trans_string_copy (&block, lse->string_length, lse->expr,
3375 rse->string_length, rse->expr);
3377 else if (ts.type == BT_DERIVED && ts.derived->attr.alloc_comp)
3379 cond = NULL_TREE;
3381 /* Are the rhs and the lhs the same? */
3382 if (r_is_var)
3384 cond = fold_build2 (EQ_EXPR, boolean_type_node,
3385 build_fold_addr_expr (lse->expr),
3386 build_fold_addr_expr (rse->expr));
3387 cond = gfc_evaluate_now (cond, &lse->pre);
3390 /* Deallocate the lhs allocated components as long as it is not
3391 the same as the rhs. */
3392 if (!l_is_temp)
3394 tmp = gfc_deallocate_alloc_comp (ts.derived, lse->expr, 0);
3395 if (r_is_var)
3396 tmp = build3_v (COND_EXPR, cond, build_empty_stmt (), tmp);
3397 gfc_add_expr_to_block (&lse->pre, tmp);
3400 gfc_add_block_to_block (&block, &lse->pre);
3401 gfc_add_block_to_block (&block, &rse->pre);
3403 gfc_add_modify_expr (&block, lse->expr,
3404 fold_convert (TREE_TYPE (lse->expr), rse->expr));
3406 /* Do a deep copy if the rhs is a variable, if it is not the
3407 same as the lhs. */
3408 if (r_is_var)
3410 tmp = gfc_copy_alloc_comp (ts.derived, rse->expr, lse->expr, 0);
3411 tmp = build3_v (COND_EXPR, cond, build_empty_stmt (), tmp);
3412 gfc_add_expr_to_block (&block, tmp);
3415 else
3417 gfc_add_block_to_block (&block, &lse->pre);
3418 gfc_add_block_to_block (&block, &rse->pre);
3420 gfc_add_modify_expr (&block, lse->expr,
3421 fold_convert (TREE_TYPE (lse->expr), rse->expr));
3424 gfc_add_block_to_block (&block, &lse->post);
3425 gfc_add_block_to_block (&block, &rse->post);
3427 return gfc_finish_block (&block);
3431 /* Try to translate array(:) = func (...), where func is a transformational
3432 array function, without using a temporary. Returns NULL is this isn't the
3433 case. */
3435 static tree
3436 gfc_trans_arrayfunc_assign (gfc_expr * expr1, gfc_expr * expr2)
3438 gfc_se se;
3439 gfc_ss *ss;
3440 gfc_ref * ref;
3441 bool seen_array_ref;
3443 /* The caller has already checked rank>0 and expr_type == EXPR_FUNCTION. */
3444 if (expr2->value.function.isym && !gfc_is_intrinsic_libcall (expr2))
3445 return NULL;
3447 /* Elemental functions don't need a temporary anyway. */
3448 if (expr2->value.function.esym != NULL
3449 && expr2->value.function.esym->attr.elemental)
3450 return NULL;
3452 /* Fail if EXPR1 can't be expressed as a descriptor. */
3453 if (gfc_ref_needs_temporary_p (expr1->ref))
3454 return NULL;
3456 /* Functions returning pointers need temporaries. */
3457 if (expr2->symtree->n.sym->attr.pointer
3458 || expr2->symtree->n.sym->attr.allocatable)
3459 return NULL;
3461 /* Character array functions need temporaries unless the
3462 character lengths are the same. */
3463 if (expr2->ts.type == BT_CHARACTER && expr2->rank > 0)
3465 if (expr1->ts.cl->length == NULL
3466 || expr1->ts.cl->length->expr_type != EXPR_CONSTANT)
3467 return NULL;
3469 if (expr2->ts.cl->length == NULL
3470 || expr2->ts.cl->length->expr_type != EXPR_CONSTANT)
3471 return NULL;
3473 if (mpz_cmp (expr1->ts.cl->length->value.integer,
3474 expr2->ts.cl->length->value.integer) != 0)
3475 return NULL;
3478 /* Check that no LHS component references appear during an array
3479 reference. This is needed because we do not have the means to
3480 span any arbitrary stride with an array descriptor. This check
3481 is not needed for the rhs because the function result has to be
3482 a complete type. */
3483 seen_array_ref = false;
3484 for (ref = expr1->ref; ref; ref = ref->next)
3486 if (ref->type == REF_ARRAY)
3487 seen_array_ref= true;
3488 else if (ref->type == REF_COMPONENT && seen_array_ref)
3489 return NULL;
3492 /* Check for a dependency. */
3493 if (gfc_check_fncall_dependency (expr1, INTENT_OUT,
3494 expr2->value.function.esym,
3495 expr2->value.function.actual))
3496 return NULL;
3498 /* The frontend doesn't seem to bother filling in expr->symtree for intrinsic
3499 functions. */
3500 gcc_assert (expr2->value.function.isym
3501 || (gfc_return_by_reference (expr2->value.function.esym)
3502 && expr2->value.function.esym->result->attr.dimension));
3504 ss = gfc_walk_expr (expr1);
3505 gcc_assert (ss != gfc_ss_terminator);
3506 gfc_init_se (&se, NULL);
3507 gfc_start_block (&se.pre);
3508 se.want_pointer = 1;
3510 gfc_conv_array_parameter (&se, expr1, ss, 0);
3512 se.direct_byref = 1;
3513 se.ss = gfc_walk_expr (expr2);
3514 gcc_assert (se.ss != gfc_ss_terminator);
3515 gfc_conv_function_expr (&se, expr2);
3516 gfc_add_block_to_block (&se.pre, &se.post);
3518 return gfc_finish_block (&se.pre);
3521 /* Determine whether the given EXPR_CONSTANT is a zero initializer. */
3523 static bool
3524 is_zero_initializer_p (gfc_expr * expr)
3526 if (expr->expr_type != EXPR_CONSTANT)
3527 return false;
3528 /* We ignore Hollerith constants for the time being. */
3529 if (expr->from_H)
3530 return false;
3532 switch (expr->ts.type)
3534 case BT_INTEGER:
3535 return mpz_cmp_si (expr->value.integer, 0) == 0;
3537 case BT_REAL:
3538 return mpfr_zero_p (expr->value.real)
3539 && MPFR_SIGN (expr->value.real) >= 0;
3541 case BT_LOGICAL:
3542 return expr->value.logical == 0;
3544 case BT_COMPLEX:
3545 return mpfr_zero_p (expr->value.complex.r)
3546 && MPFR_SIGN (expr->value.complex.r) >= 0
3547 && mpfr_zero_p (expr->value.complex.i)
3548 && MPFR_SIGN (expr->value.complex.i) >= 0;
3550 default:
3551 break;
3553 return false;
3556 /* Try to efficiently translate array(:) = 0. Return NULL if this
3557 can't be done. */
3559 static tree
3560 gfc_trans_zero_assign (gfc_expr * expr)
3562 tree dest, len, type;
3563 tree tmp;
3564 gfc_symbol *sym;
3566 sym = expr->symtree->n.sym;
3567 dest = gfc_get_symbol_decl (sym);
3569 type = TREE_TYPE (dest);
3570 if (POINTER_TYPE_P (type))
3571 type = TREE_TYPE (type);
3572 if (!GFC_ARRAY_TYPE_P (type))
3573 return NULL_TREE;
3575 /* Determine the length of the array. */
3576 len = GFC_TYPE_ARRAY_SIZE (type);
3577 if (!len || TREE_CODE (len) != INTEGER_CST)
3578 return NULL_TREE;
3580 len = fold_build2 (MULT_EXPR, gfc_array_index_type, len,
3581 TYPE_SIZE_UNIT (gfc_get_element_type (type)));
3583 /* Convert arguments to the correct types. */
3584 if (!POINTER_TYPE_P (TREE_TYPE (dest)))
3585 dest = gfc_build_addr_expr (pvoid_type_node, dest);
3586 else
3587 dest = fold_convert (pvoid_type_node, dest);
3588 len = fold_convert (size_type_node, len);
3590 /* Construct call to __builtin_memset. */
3591 tmp = build_call_expr (built_in_decls[BUILT_IN_MEMSET],
3592 3, dest, integer_zero_node, len);
3593 return fold_convert (void_type_node, tmp);
3597 /* Helper for gfc_trans_array_copy and gfc_trans_array_constructor_copy
3598 that constructs the call to __builtin_memcpy. */
3600 static tree
3601 gfc_build_memcpy_call (tree dst, tree src, tree len)
3603 tree tmp;
3605 /* Convert arguments to the correct types. */
3606 if (!POINTER_TYPE_P (TREE_TYPE (dst)))
3607 dst = gfc_build_addr_expr (pvoid_type_node, dst);
3608 else
3609 dst = fold_convert (pvoid_type_node, dst);
3611 if (!POINTER_TYPE_P (TREE_TYPE (src)))
3612 src = gfc_build_addr_expr (pvoid_type_node, src);
3613 else
3614 src = fold_convert (pvoid_type_node, src);
3616 len = fold_convert (size_type_node, len);
3618 /* Construct call to __builtin_memcpy. */
3619 tmp = build_call_expr (built_in_decls[BUILT_IN_MEMCPY], 3, dst, src, len);
3620 return fold_convert (void_type_node, tmp);
3624 /* Try to efficiently translate dst(:) = src(:). Return NULL if this
3625 can't be done. EXPR1 is the destination/lhs and EXPR2 is the
3626 source/rhs, both are gfc_full_array_ref_p which have been checked for
3627 dependencies. */
3629 static tree
3630 gfc_trans_array_copy (gfc_expr * expr1, gfc_expr * expr2)
3632 tree dst, dlen, dtype;
3633 tree src, slen, stype;
3635 dst = gfc_get_symbol_decl (expr1->symtree->n.sym);
3636 src = gfc_get_symbol_decl (expr2->symtree->n.sym);
3638 dtype = TREE_TYPE (dst);
3639 if (POINTER_TYPE_P (dtype))
3640 dtype = TREE_TYPE (dtype);
3641 stype = TREE_TYPE (src);
3642 if (POINTER_TYPE_P (stype))
3643 stype = TREE_TYPE (stype);
3645 if (!GFC_ARRAY_TYPE_P (dtype) || !GFC_ARRAY_TYPE_P (stype))
3646 return NULL_TREE;
3648 /* Determine the lengths of the arrays. */
3649 dlen = GFC_TYPE_ARRAY_SIZE (dtype);
3650 if (!dlen || TREE_CODE (dlen) != INTEGER_CST)
3651 return NULL_TREE;
3652 dlen = fold_build2 (MULT_EXPR, gfc_array_index_type, dlen,
3653 TYPE_SIZE_UNIT (gfc_get_element_type (dtype)));
3655 slen = GFC_TYPE_ARRAY_SIZE (stype);
3656 if (!slen || TREE_CODE (slen) != INTEGER_CST)
3657 return NULL_TREE;
3658 slen = fold_build2 (MULT_EXPR, gfc_array_index_type, slen,
3659 TYPE_SIZE_UNIT (gfc_get_element_type (stype)));
3661 /* Sanity check that they are the same. This should always be
3662 the case, as we should already have checked for conformance. */
3663 if (!tree_int_cst_equal (slen, dlen))
3664 return NULL_TREE;
3666 return gfc_build_memcpy_call (dst, src, dlen);
3670 /* Try to efficiently translate array(:) = (/ ... /). Return NULL if
3671 this can't be done. EXPR1 is the destination/lhs for which
3672 gfc_full_array_ref_p is true, and EXPR2 is the source/rhs. */
3674 static tree
3675 gfc_trans_array_constructor_copy (gfc_expr * expr1, gfc_expr * expr2)
3677 unsigned HOST_WIDE_INT nelem;
3678 tree dst, dtype;
3679 tree src, stype;
3680 tree len;
3682 nelem = gfc_constant_array_constructor_p (expr2->value.constructor);
3683 if (nelem == 0)
3684 return NULL_TREE;
3686 dst = gfc_get_symbol_decl (expr1->symtree->n.sym);
3687 dtype = TREE_TYPE (dst);
3688 if (POINTER_TYPE_P (dtype))
3689 dtype = TREE_TYPE (dtype);
3690 if (!GFC_ARRAY_TYPE_P (dtype))
3691 return NULL_TREE;
3693 /* Determine the lengths of the array. */
3694 len = GFC_TYPE_ARRAY_SIZE (dtype);
3695 if (!len || TREE_CODE (len) != INTEGER_CST)
3696 return NULL_TREE;
3698 /* Confirm that the constructor is the same size. */
3699 if (compare_tree_int (len, nelem) != 0)
3700 return NULL_TREE;
3702 len = fold_build2 (MULT_EXPR, gfc_array_index_type, len,
3703 TYPE_SIZE_UNIT (gfc_get_element_type (dtype)));
3705 stype = gfc_typenode_for_spec (&expr2->ts);
3706 src = gfc_build_constant_array_constructor (expr2, stype);
3708 stype = TREE_TYPE (src);
3709 if (POINTER_TYPE_P (stype))
3710 stype = TREE_TYPE (stype);
3712 return gfc_build_memcpy_call (dst, src, len);
3716 /* Subroutine of gfc_trans_assignment that actually scalarizes the
3717 assignment. EXPR1 is the destination/RHS and EXPR2 is the source/LHS. */
3719 static tree
3720 gfc_trans_assignment_1 (gfc_expr * expr1, gfc_expr * expr2, bool init_flag)
3722 gfc_se lse;
3723 gfc_se rse;
3724 gfc_ss *lss;
3725 gfc_ss *lss_section;
3726 gfc_ss *rss;
3727 gfc_loopinfo loop;
3728 tree tmp;
3729 stmtblock_t block;
3730 stmtblock_t body;
3731 bool l_is_temp;
3733 /* Assignment of the form lhs = rhs. */
3734 gfc_start_block (&block);
3736 gfc_init_se (&lse, NULL);
3737 gfc_init_se (&rse, NULL);
3739 /* Walk the lhs. */
3740 lss = gfc_walk_expr (expr1);
3741 rss = NULL;
3742 if (lss != gfc_ss_terminator)
3744 /* The assignment needs scalarization. */
3745 lss_section = lss;
3747 /* Find a non-scalar SS from the lhs. */
3748 while (lss_section != gfc_ss_terminator
3749 && lss_section->type != GFC_SS_SECTION)
3750 lss_section = lss_section->next;
3752 gcc_assert (lss_section != gfc_ss_terminator);
3754 /* Initialize the scalarizer. */
3755 gfc_init_loopinfo (&loop);
3757 /* Walk the rhs. */
3758 rss = gfc_walk_expr (expr2);
3759 if (rss == gfc_ss_terminator)
3761 /* The rhs is scalar. Add a ss for the expression. */
3762 rss = gfc_get_ss ();
3763 rss->next = gfc_ss_terminator;
3764 rss->type = GFC_SS_SCALAR;
3765 rss->expr = expr2;
3767 /* Associate the SS with the loop. */
3768 gfc_add_ss_to_loop (&loop, lss);
3769 gfc_add_ss_to_loop (&loop, rss);
3771 /* Calculate the bounds of the scalarization. */
3772 gfc_conv_ss_startstride (&loop);
3773 /* Resolve any data dependencies in the statement. */
3774 gfc_conv_resolve_dependencies (&loop, lss, rss);
3775 /* Setup the scalarizing loops. */
3776 gfc_conv_loop_setup (&loop);
3778 /* Setup the gfc_se structures. */
3779 gfc_copy_loopinfo_to_se (&lse, &loop);
3780 gfc_copy_loopinfo_to_se (&rse, &loop);
3782 rse.ss = rss;
3783 gfc_mark_ss_chain_used (rss, 1);
3784 if (loop.temp_ss == NULL)
3786 lse.ss = lss;
3787 gfc_mark_ss_chain_used (lss, 1);
3789 else
3791 lse.ss = loop.temp_ss;
3792 gfc_mark_ss_chain_used (lss, 3);
3793 gfc_mark_ss_chain_used (loop.temp_ss, 3);
3796 /* Start the scalarized loop body. */
3797 gfc_start_scalarized_body (&loop, &body);
3799 else
3800 gfc_init_block (&body);
3802 l_is_temp = (lss != gfc_ss_terminator && loop.temp_ss != NULL);
3804 /* Translate the expression. */
3805 gfc_conv_expr (&rse, expr2);
3807 if (l_is_temp)
3809 gfc_conv_tmp_array_ref (&lse);
3810 gfc_advance_se_ss_chain (&lse);
3812 else
3813 gfc_conv_expr (&lse, expr1);
3815 tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts,
3816 l_is_temp || init_flag,
3817 expr2->expr_type == EXPR_VARIABLE);
3818 gfc_add_expr_to_block (&body, tmp);
3820 if (lss == gfc_ss_terminator)
3822 /* Use the scalar assignment as is. */
3823 gfc_add_block_to_block (&block, &body);
3825 else
3827 gcc_assert (lse.ss == gfc_ss_terminator
3828 && rse.ss == gfc_ss_terminator);
3830 if (l_is_temp)
3832 gfc_trans_scalarized_loop_boundary (&loop, &body);
3834 /* We need to copy the temporary to the actual lhs. */
3835 gfc_init_se (&lse, NULL);
3836 gfc_init_se (&rse, NULL);
3837 gfc_copy_loopinfo_to_se (&lse, &loop);
3838 gfc_copy_loopinfo_to_se (&rse, &loop);
3840 rse.ss = loop.temp_ss;
3841 lse.ss = lss;
3843 gfc_conv_tmp_array_ref (&rse);
3844 gfc_advance_se_ss_chain (&rse);
3845 gfc_conv_expr (&lse, expr1);
3847 gcc_assert (lse.ss == gfc_ss_terminator
3848 && rse.ss == gfc_ss_terminator);
3850 tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts,
3851 false, false);
3852 gfc_add_expr_to_block (&body, tmp);
3855 /* Generate the copying loops. */
3856 gfc_trans_scalarizing_loops (&loop, &body);
3858 /* Wrap the whole thing up. */
3859 gfc_add_block_to_block (&block, &loop.pre);
3860 gfc_add_block_to_block (&block, &loop.post);
3862 gfc_cleanup_loop (&loop);
3865 return gfc_finish_block (&block);
3869 /* Check whether EXPR, which is an EXPR_VARIABLE, is a copyable array. */
3871 static bool
3872 copyable_array_p (gfc_expr * expr)
3874 /* First check it's an array. */
3875 if (expr->rank < 1 || !expr->ref)
3876 return false;
3878 /* Next check that it's of a simple enough type. */
3879 switch (expr->ts.type)
3881 case BT_INTEGER:
3882 case BT_REAL:
3883 case BT_COMPLEX:
3884 case BT_LOGICAL:
3885 return true;
3887 case BT_CHARACTER:
3888 return false;
3890 case BT_DERIVED:
3891 return !expr->ts.derived->attr.alloc_comp;
3893 default:
3894 break;
3897 return false;
3900 /* Translate an assignment. */
3902 tree
3903 gfc_trans_assignment (gfc_expr * expr1, gfc_expr * expr2, bool init_flag)
3905 tree tmp;
3907 /* Special case a single function returning an array. */
3908 if (expr2->expr_type == EXPR_FUNCTION && expr2->rank > 0)
3910 tmp = gfc_trans_arrayfunc_assign (expr1, expr2);
3911 if (tmp)
3912 return tmp;
3915 /* Special case assigning an array to zero. */
3916 if (expr1->expr_type == EXPR_VARIABLE
3917 && expr1->rank > 0
3918 && expr1->ref
3919 && gfc_full_array_ref_p (expr1->ref)
3920 && is_zero_initializer_p (expr2))
3922 tmp = gfc_trans_zero_assign (expr1);
3923 if (tmp)
3924 return tmp;
3927 /* Special case copying one array to another. */
3928 if (expr1->expr_type == EXPR_VARIABLE
3929 && copyable_array_p (expr1)
3930 && gfc_full_array_ref_p (expr1->ref)
3931 && expr2->expr_type == EXPR_VARIABLE
3932 && copyable_array_p (expr2)
3933 && gfc_full_array_ref_p (expr2->ref)
3934 && gfc_compare_types (&expr1->ts, &expr2->ts)
3935 && !gfc_check_dependency (expr1, expr2, 0))
3937 tmp = gfc_trans_array_copy (expr1, expr2);
3938 if (tmp)
3939 return tmp;
3942 /* Special case initializing an array from a constant array constructor. */
3943 if (expr1->expr_type == EXPR_VARIABLE
3944 && copyable_array_p (expr1)
3945 && gfc_full_array_ref_p (expr1->ref)
3946 && expr2->expr_type == EXPR_ARRAY
3947 && gfc_compare_types (&expr1->ts, &expr2->ts))
3949 tmp = gfc_trans_array_constructor_copy (expr1, expr2);
3950 if (tmp)
3951 return tmp;
3954 /* Fallback to the scalarizer to generate explicit loops. */
3955 return gfc_trans_assignment_1 (expr1, expr2, init_flag);
3958 tree
3959 gfc_trans_init_assign (gfc_code * code)
3961 return gfc_trans_assignment (code->expr, code->expr2, true);
3964 tree
3965 gfc_trans_assign (gfc_code * code)
3967 return gfc_trans_assignment (code->expr, code->expr2, false);