re PR fortran/30720 ([4.1 only] runtime: check for empty array slices before allocati...
[gcc.git] / gcc / fortran / trans-expr.c
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>
5
6 This file is part of GCC.
7
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.
12
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.
17
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. */
22
23 /* trans-expr.c-- generate GENERIC trees for gfc_expr. */
24
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"
44
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 *);
48
49 /* Copy the scalarization loop variables. */
50
51 static void
52 gfc_copy_se_loopvars (gfc_se * dest, gfc_se * src)
53 {
54 dest->ss = src->ss;
55 dest->loop = src->loop;
56 }
57
58
59 /* Initialize a simple expression holder.
60
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. */
64
65 void
66 gfc_init_se (gfc_se * se, gfc_se * parent)
67 {
68 memset (se, 0, sizeof (gfc_se));
69 gfc_init_block (&se->pre);
70 gfc_init_block (&se->post);
71
72 se->parent = parent;
73
74 if (parent)
75 gfc_copy_se_loopvars (se, parent);
76 }
77
78
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. */
82
83 void
84 gfc_advance_se_ss_chain (gfc_se * se)
85 {
86 gfc_se *p;
87
88 gcc_assert (se != NULL && se->ss != NULL && se->ss != gfc_ss_terminator);
89
90 p = se;
91 /* Walk down the parent chain. */
92 while (p != NULL)
93 {
94 /* Simple consistency check. */
95 gcc_assert (p->parent == NULL || p->parent->ss == p->ss);
96
97 p->ss = p->ss->next;
98
99 p = p->parent;
100 }
101 }
102
103
104 /* Ensures the result of the expression as either a temporary variable
105 or a constant so that it can be used repeatedly. */
106
107 void
108 gfc_make_safe_expr (gfc_se * se)
109 {
110 tree var;
111
112 if (CONSTANT_CLASS_P (se->expr))
113 return;
114
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;
119 }
120
121
122 /* Return an expression which determines if a dummy parameter is present.
123 Also used for arguments to procedures with multiple entry points. */
124
125 tree
126 gfc_conv_expr_present (gfc_symbol * sym)
127 {
128 tree decl;
129
130 gcc_assert (sym->attr.dummy);
131
132 decl = gfc_get_symbol_decl (sym);
133 if (TREE_CODE (decl) != PARM_DECL)
134 {
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);
140 }
141 return build2 (NE_EXPR, boolean_type_node, decl,
142 fold_convert (TREE_TYPE (decl), null_pointer_node));
143 }
144
145
146 /* Converts a missing, dummy argument into a null or zero. */
147
148 void
149 gfc_conv_missing_dummy (gfc_se * se, gfc_expr * arg, gfc_typespec ts)
150 {
151 tree present;
152 tree tmp;
153
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));
157
158 tmp = gfc_evaluate_now (tmp, &se->pre);
159 se->expr = tmp;
160 if (ts.type == BT_CHARACTER)
161 {
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;
167 }
168 return;
169 }
170
171
172 /* Get the character length of an expression, looking through gfc_refs
173 if necessary. */
174
175 tree
176 gfc_get_expr_charlen (gfc_expr *e)
177 {
178 gfc_ref *r;
179 tree length;
180
181 gcc_assert (e->expr_type == EXPR_VARIABLE
182 && e->ts.type == BT_CHARACTER);
183
184 length = NULL; /* To silence compiler warning. */
185
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;
191
192 /* Look through the reference chain for component references. */
193 for (r = e->ref; r; r = r->next)
194 {
195 switch (r->type)
196 {
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;
201
202 case REF_ARRAY:
203 /* Do nothing. */
204 break;
205
206 default:
207 /* We should never got substring references here. These will be
208 broken down by the scalarizer. */
209 gcc_unreachable ();
210 }
211 }
212
213 gcc_assert (length != NULL);
214 return length;
215 }
216
217
218
219 /* Generate code to initialize a string length variable. Returns the
220 value. */
221
222 void
223 gfc_trans_init_string_length (gfc_charlen * cl, stmtblock_t * pblock)
224 {
225 gfc_se se;
226 tree tmp;
227
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);
231
232 tmp = cl->backend_decl;
233 gfc_add_modify_expr (pblock, tmp, se.expr);
234 }
235
236
237 static void
238 gfc_conv_substring (gfc_se * se, gfc_ref * ref, int kind,
239 const char *name, locus *where)
240 {
241 tree tmp;
242 tree type;
243 tree var;
244 tree fault;
245 gfc_se start;
246 gfc_se end;
247 char *msg;
248
249 type = gfc_get_character_type (kind, ref->u.ss.length);
250 type = build_pointer_type (type);
251
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);
256
257 if (integer_onep (start.expr))
258 gfc_conv_string_parameter (se);
259 else
260 {
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);
268 }
269
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
275 {
276 gfc_conv_expr_type (&end, ref->u.ss.end, gfc_charlen_type_node);
277 gfc_add_block_to_block (&se->pre, &end.pre);
278 }
279 if (flag_bounds_check)
280 {
281 tree nonempty = fold_build2 (LE_EXPR, boolean_type_node,
282 start.expr, end.expr);
283
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);
297
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);
311 }
312
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;
320 }
321
322
323 /* Convert a derived type component reference. */
324
325 static void
326 gfc_conv_component_ref (gfc_se * se, gfc_ref * ref)
327 {
328 gfc_component *c;
329 tree tmp;
330 tree decl;
331 tree field;
332
333 c = ref->u.c.component;
334
335 gcc_assert (c->backend_decl);
336
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);
341
342 se->expr = tmp;
343
344 if (c->ts.type == BT_CHARACTER)
345 {
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;
350 }
351
352 if (c->pointer && c->dimension == 0 && c->ts.type != BT_CHARACTER)
353 se->expr = build_fold_indirect_ref (se->expr);
354 }
355
356
357 /* Return the contents of a variable. Also handles reference/pointer
358 variables (all Fortran pointer references are implicit). */
359
360 static void
361 gfc_conv_variable (gfc_se * se, gfc_expr * expr)
362 {
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;
370
371 sym = expr->symtree->n.sym;
372 if (se->ss != NULL)
373 {
374 /* Check that something hasn't gone horribly wrong. */
375 gcc_assert (se->ss != gfc_ss_terminator);
376 gcc_assert (se->ss->expr == expr);
377
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;
384 }
385 else
386 {
387 tree se_expr = NULL_TREE;
388
389 se->expr = gfc_get_symbol_decl (sym);
390
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);
400
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;
409
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);
414
415 /* Similarly for alternate entry points. */
416 else if (alternate_entry
417 && (sym->ns->proc_name->backend_decl == current_function_decl
418 || parent_flag))
419 {
420 gfc_entry_list *el = NULL;
421
422 for (el = sym->ns->entries; el; el = el->next)
423 if (sym == el->sym)
424 {
425 se_expr = gfc_get_fake_result_decl (sym, parent_flag);
426 break;
427 }
428 }
429
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);
434
435 if (se_expr)
436 se->expr = se_expr;
437
438 /* Procedure actual arguments. */
439 else if (sym->attr.flavor == FL_PROCEDURE
440 && se->expr != current_function_decl)
441 {
442 gcc_assert (se->want_pointer);
443 if (!sym->attr.dummy)
444 {
445 gcc_assert (TREE_CODE (se->expr) == FUNCTION_DECL);
446 se->expr = build_fold_addr_expr (se->expr);
447 }
448 return;
449 }
450
451
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)
456 {
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);
464
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);
469
470 }
471 else if (!sym->attr.value)
472 {
473 /* Dereference non-character scalar dummy arguments. */
474 if (sym->attr.dummy && !sym->attr.dimension)
475 se->expr = build_fold_indirect_ref (se->expr);
476
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);
482
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);
491 }
492
493 ref = expr->ref;
494 }
495
496 /* For character variables, also get the length. */
497 if (sym->ts.type == BT_CHARACTER)
498 {
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);
506 }
507
508 while (ref)
509 {
510 switch (ref->type)
511 {
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;
522
523 gfc_conv_array_ref (se, &ref->u.ar, sym, &expr->where);
524 /* Return a pointer to an element. */
525 break;
526
527 case REF_COMPONENT:
528 gfc_conv_component_ref (se, ref);
529 break;
530
531 case REF_SUBSTRING:
532 gfc_conv_substring (se, ref, expr->ts.kind,
533 expr->symtree->name, &expr->where);
534 break;
535
536 default:
537 gcc_unreachable ();
538 break;
539 }
540 ref = ref->next;
541 }
542 /* Pointer assignment, allocation or pass by reference. Arrays are handled
543 separately. */
544 if (se->want_pointer)
545 {
546 if (expr->ts.type == BT_CHARACTER)
547 gfc_conv_string_parameter (se);
548 else
549 se->expr = build_fold_addr_expr (se->expr);
550 }
551 }
552
553
554 /* Unary ops are easy... Or they would be if ! was a valid op. */
555
556 static void
557 gfc_conv_unary_op (enum tree_code code, gfc_se * se, gfc_expr * expr)
558 {
559 gfc_se operand;
560 tree type;
561
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);
567
568 type = gfc_typenode_for_spec (&expr->ts);
569
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);
578
579 }
580
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. */
585
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
592
593 /* The table is from builtins.c. */
594 static const unsigned char powi_table[POWI_TABLE_SIZE] =
595 {
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 */
628 };
629
630 /* If n is larger than lookup table's max index, we use the "window
631 method". */
632 #define POWI_WINDOW_SIZE 3
633
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)
638 {
639 tree op0;
640 tree op1;
641 tree tmp;
642 int digit;
643
644 if (n < POWI_TABLE_SIZE)
645 {
646 if (tmpvar[n])
647 return tmpvar[n];
648
649 op0 = gfc_conv_powi (se, n - powi_table[n], tmpvar);
650 op1 = gfc_conv_powi (se, powi_table[n], tmpvar);
651 }
652 else if (n & 1)
653 {
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);
657 }
658 else
659 {
660 op0 = gfc_conv_powi (se, n >> 1, tmpvar);
661 op1 = op0;
662 }
663
664 tmp = fold_build2 (MULT_EXPR, TREE_TYPE (op0), op0, op1);
665 tmp = gfc_evaluate_now (tmp, &se->pre);
666
667 if (n < POWI_TABLE_SIZE)
668 tmpvar[n] = tmp;
669
670 return tmp;
671 }
672
673
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)
679 {
680 tree cond;
681 tree tmp;
682 tree type;
683 tree vartmp[POWI_TABLE_SIZE];
684 int n;
685 int sgn;
686
687 type = TREE_TYPE (lhs);
688 n = abs (TREE_INT_CST_LOW (rhs));
689 sgn = tree_int_cst_sgn (rhs);
690
691 if (((FLOAT_TYPE_P (type) && !flag_unsafe_math_optimizations) || optimize_size)
692 && (n > 2 || n < -1))
693 return 0;
694
695 /* rhs == 0 */
696 if (sgn == 0)
697 {
698 se->expr = gfc_build_const (type, integer_one_node);
699 return 1;
700 }
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))
703 {
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));
708
709 /* If rhs is even,
710 result = (lhs == 1 || lhs == -1) ? 1 : 0. */
711 if ((n & 1) == 0)
712 {
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;
717 }
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;
724 }
725
726 memset (vartmp, 0, sizeof (vartmp));
727 vartmp[1] = lhs;
728 if (sgn == -1)
729 {
730 tmp = gfc_build_const (type, integer_one_node);
731 vartmp[1] = build2 (RDIV_EXPR, type, tmp, vartmp[1]);
732 }
733
734 se->expr = gfc_conv_powi (se, n, vartmp);
735
736 return 1;
737 }
738
739
740 /* Power op (**). Constant integer exponent has special handling. */
741
742 static void
743 gfc_conv_power_op (gfc_se * se, gfc_expr * expr)
744 {
745 tree gfc_int4_type_node;
746 int kind;
747 int ikind;
748 gfc_se lse;
749 gfc_se rse;
750 tree fndecl;
751 tree tmp;
752
753 gfc_init_se (&lse, se);
754 gfc_conv_expr_val (&lse, expr->value.op.op1);
755 lse.expr = gfc_evaluate_now (lse.expr, &lse.pre);
756 gfc_add_block_to_block (&se->pre, &lse.pre);
757
758 gfc_init_se (&rse, se);
759 gfc_conv_expr_val (&rse, expr->value.op.op2);
760 gfc_add_block_to_block (&se->pre, &rse.pre);
761
762 if (expr->value.op.op2->ts.type == BT_INTEGER
763 && expr->value.op.op2->expr_type == EXPR_CONSTANT)
764 if (gfc_conv_cst_int_power (se, lse.expr, rse.expr))
765 return;
766
767 gfc_int4_type_node = gfc_get_int_type (4);
768
769 kind = expr->value.op.op1->ts.kind;
770 switch (expr->value.op.op2->ts.type)
771 {
772 case BT_INTEGER:
773 ikind = expr->value.op.op2->ts.kind;
774 switch (ikind)
775 {
776 case 1:
777 case 2:
778 rse.expr = convert (gfc_int4_type_node, rse.expr);
779 /* Fall through. */
780
781 case 4:
782 ikind = 0;
783 break;
784
785 case 8:
786 ikind = 1;
787 break;
788
789 case 16:
790 ikind = 2;
791 break;
792
793 default:
794 gcc_unreachable ();
795 }
796 switch (kind)
797 {
798 case 1:
799 case 2:
800 if (expr->value.op.op1->ts.type == BT_INTEGER)
801 lse.expr = convert (gfc_int4_type_node, lse.expr);
802 else
803 gcc_unreachable ();
804 /* Fall through. */
805
806 case 4:
807 kind = 0;
808 break;
809
810 case 8:
811 kind = 1;
812 break;
813
814 case 10:
815 kind = 2;
816 break;
817
818 case 16:
819 kind = 3;
820 break;
821
822 default:
823 gcc_unreachable ();
824 }
825
826 switch (expr->value.op.op1->ts.type)
827 {
828 case BT_INTEGER:
829 if (kind == 3) /* Case 16 was not handled properly above. */
830 kind = 2;
831 fndecl = gfor_fndecl_math_powi[kind][ikind].integer;
832 break;
833
834 case BT_REAL:
835 fndecl = gfor_fndecl_math_powi[kind][ikind].real;
836 break;
837
838 case BT_COMPLEX:
839 fndecl = gfor_fndecl_math_powi[kind][ikind].cmplx;
840 break;
841
842 default:
843 gcc_unreachable ();
844 }
845 break;
846
847 case BT_REAL:
848 switch (kind)
849 {
850 case 4:
851 fndecl = built_in_decls[BUILT_IN_POWF];
852 break;
853 case 8:
854 fndecl = built_in_decls[BUILT_IN_POW];
855 break;
856 case 10:
857 case 16:
858 fndecl = built_in_decls[BUILT_IN_POWL];
859 break;
860 default:
861 gcc_unreachable ();
862 }
863 break;
864
865 case BT_COMPLEX:
866 switch (kind)
867 {
868 case 4:
869 fndecl = gfor_fndecl_math_cpowf;
870 break;
871 case 8:
872 fndecl = gfor_fndecl_math_cpow;
873 break;
874 case 10:
875 fndecl = gfor_fndecl_math_cpowl10;
876 break;
877 case 16:
878 fndecl = gfor_fndecl_math_cpowl16;
879 break;
880 default:
881 gcc_unreachable ();
882 }
883 break;
884
885 default:
886 gcc_unreachable ();
887 break;
888 }
889
890 tmp = gfc_chainon_list (NULL_TREE, lse.expr);
891 tmp = gfc_chainon_list (tmp, rse.expr);
892 se->expr = build_function_call_expr (fndecl, tmp);
893 }
894
895
896 /* Generate code to allocate a string temporary. */
897
898 tree
899 gfc_conv_string_tmp (gfc_se * se, tree type, tree len)
900 {
901 tree var;
902 tree tmp;
903 tree args;
904
905 gcc_assert (TREE_TYPE (len) == gfc_charlen_type_node);
906
907 if (gfc_can_put_var_on_stack (len))
908 {
909 /* Create a temporary variable to hold the result. */
910 tmp = fold_build2 (MINUS_EXPR, gfc_charlen_type_node, len,
911 build_int_cst (gfc_charlen_type_node, 1));
912 tmp = build_range_type (gfc_array_index_type, gfc_index_zero_node, tmp);
913 tmp = build_array_type (gfc_character1_type_node, tmp);
914 var = gfc_create_var (tmp, "str");
915 var = gfc_build_addr_expr (type, var);
916 }
917 else
918 {
919 /* Allocate a temporary to hold the result. */
920 var = gfc_create_var (type, "pstr");
921 args = gfc_chainon_list (NULL_TREE, len);
922 tmp = build_function_call_expr (gfor_fndecl_internal_malloc, args);
923 tmp = convert (type, tmp);
924 gfc_add_modify_expr (&se->pre, var, tmp);
925
926 /* Free the temporary afterwards. */
927 tmp = convert (pvoid_type_node, var);
928 args = gfc_chainon_list (NULL_TREE, tmp);
929 tmp = build_function_call_expr (gfor_fndecl_internal_free, args);
930 gfc_add_expr_to_block (&se->post, tmp);
931 }
932
933 return var;
934 }
935
936
937 /* Handle a string concatenation operation. A temporary will be allocated to
938 hold the result. */
939
940 static void
941 gfc_conv_concat_op (gfc_se * se, gfc_expr * expr)
942 {
943 gfc_se lse;
944 gfc_se rse;
945 tree len;
946 tree type;
947 tree var;
948 tree args;
949 tree tmp;
950
951 gcc_assert (expr->value.op.op1->ts.type == BT_CHARACTER
952 && expr->value.op.op2->ts.type == BT_CHARACTER);
953
954 gfc_init_se (&lse, se);
955 gfc_conv_expr (&lse, expr->value.op.op1);
956 gfc_conv_string_parameter (&lse);
957 gfc_init_se (&rse, se);
958 gfc_conv_expr (&rse, expr->value.op.op2);
959 gfc_conv_string_parameter (&rse);
960
961 gfc_add_block_to_block (&se->pre, &lse.pre);
962 gfc_add_block_to_block (&se->pre, &rse.pre);
963
964 type = gfc_get_character_type (expr->ts.kind, expr->ts.cl);
965 len = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
966 if (len == NULL_TREE)
967 {
968 len = fold_build2 (PLUS_EXPR, TREE_TYPE (lse.string_length),
969 lse.string_length, rse.string_length);
970 }
971
972 type = build_pointer_type (type);
973
974 var = gfc_conv_string_tmp (se, type, len);
975
976 /* Do the actual concatenation. */
977 args = NULL_TREE;
978 args = gfc_chainon_list (args, len);
979 args = gfc_chainon_list (args, var);
980 args = gfc_chainon_list (args, lse.string_length);
981 args = gfc_chainon_list (args, lse.expr);
982 args = gfc_chainon_list (args, rse.string_length);
983 args = gfc_chainon_list (args, rse.expr);
984 tmp = build_function_call_expr (gfor_fndecl_concat_string, args);
985 gfc_add_expr_to_block (&se->pre, tmp);
986
987 /* Add the cleanup for the operands. */
988 gfc_add_block_to_block (&se->pre, &rse.post);
989 gfc_add_block_to_block (&se->pre, &lse.post);
990
991 se->expr = var;
992 se->string_length = len;
993 }
994
995 /* Translates an op expression. Common (binary) cases are handled by this
996 function, others are passed on. Recursion is used in either case.
997 We use the fact that (op1.ts == op2.ts) (except for the power
998 operator **).
999 Operators need no special handling for scalarized expressions as long as
1000 they call gfc_conv_simple_val to get their operands.
1001 Character strings get special handling. */
1002
1003 static void
1004 gfc_conv_expr_op (gfc_se * se, gfc_expr * expr)
1005 {
1006 enum tree_code code;
1007 gfc_se lse;
1008 gfc_se rse;
1009 tree type;
1010 tree tmp;
1011 int lop;
1012 int checkstring;
1013
1014 checkstring = 0;
1015 lop = 0;
1016 switch (expr->value.op.operator)
1017 {
1018 case INTRINSIC_UPLUS:
1019 case INTRINSIC_PARENTHESES:
1020 gfc_conv_expr (se, expr->value.op.op1);
1021 return;
1022
1023 case INTRINSIC_UMINUS:
1024 gfc_conv_unary_op (NEGATE_EXPR, se, expr);
1025 return;
1026
1027 case INTRINSIC_NOT:
1028 gfc_conv_unary_op (TRUTH_NOT_EXPR, se, expr);
1029 return;
1030
1031 case INTRINSIC_PLUS:
1032 code = PLUS_EXPR;
1033 break;
1034
1035 case INTRINSIC_MINUS:
1036 code = MINUS_EXPR;
1037 break;
1038
1039 case INTRINSIC_TIMES:
1040 code = MULT_EXPR;
1041 break;
1042
1043 case INTRINSIC_DIVIDE:
1044 /* If expr is a real or complex expr, use an RDIV_EXPR. If op1 is
1045 an integer, we must round towards zero, so we use a
1046 TRUNC_DIV_EXPR. */
1047 if (expr->ts.type == BT_INTEGER)
1048 code = TRUNC_DIV_EXPR;
1049 else
1050 code = RDIV_EXPR;
1051 break;
1052
1053 case INTRINSIC_POWER:
1054 gfc_conv_power_op (se, expr);
1055 return;
1056
1057 case INTRINSIC_CONCAT:
1058 gfc_conv_concat_op (se, expr);
1059 return;
1060
1061 case INTRINSIC_AND:
1062 code = TRUTH_ANDIF_EXPR;
1063 lop = 1;
1064 break;
1065
1066 case INTRINSIC_OR:
1067 code = TRUTH_ORIF_EXPR;
1068 lop = 1;
1069 break;
1070
1071 /* EQV and NEQV only work on logicals, but since we represent them
1072 as integers, we can use EQ_EXPR and NE_EXPR for them in GIMPLE. */
1073 case INTRINSIC_EQ:
1074 case INTRINSIC_EQV:
1075 code = EQ_EXPR;
1076 checkstring = 1;
1077 lop = 1;
1078 break;
1079
1080 case INTRINSIC_NE:
1081 case INTRINSIC_NEQV:
1082 code = NE_EXPR;
1083 checkstring = 1;
1084 lop = 1;
1085 break;
1086
1087 case INTRINSIC_GT:
1088 code = GT_EXPR;
1089 checkstring = 1;
1090 lop = 1;
1091 break;
1092
1093 case INTRINSIC_GE:
1094 code = GE_EXPR;
1095 checkstring = 1;
1096 lop = 1;
1097 break;
1098
1099 case INTRINSIC_LT:
1100 code = LT_EXPR;
1101 checkstring = 1;
1102 lop = 1;
1103 break;
1104
1105 case INTRINSIC_LE:
1106 code = LE_EXPR;
1107 checkstring = 1;
1108 lop = 1;
1109 break;
1110
1111 case INTRINSIC_USER:
1112 case INTRINSIC_ASSIGN:
1113 /* These should be converted into function calls by the frontend. */
1114 gcc_unreachable ();
1115
1116 default:
1117 fatal_error ("Unknown intrinsic op");
1118 return;
1119 }
1120
1121 /* The only exception to this is **, which is handled separately anyway. */
1122 gcc_assert (expr->value.op.op1->ts.type == expr->value.op.op2->ts.type);
1123
1124 if (checkstring && expr->value.op.op1->ts.type != BT_CHARACTER)
1125 checkstring = 0;
1126
1127 /* lhs */
1128 gfc_init_se (&lse, se);
1129 gfc_conv_expr (&lse, expr->value.op.op1);
1130 gfc_add_block_to_block (&se->pre, &lse.pre);
1131
1132 /* rhs */
1133 gfc_init_se (&rse, se);
1134 gfc_conv_expr (&rse, expr->value.op.op2);
1135 gfc_add_block_to_block (&se->pre, &rse.pre);
1136
1137 if (checkstring)
1138 {
1139 gfc_conv_string_parameter (&lse);
1140 gfc_conv_string_parameter (&rse);
1141
1142 lse.expr = gfc_build_compare_string (lse.string_length, lse.expr,
1143 rse.string_length, rse.expr);
1144 rse.expr = integer_zero_node;
1145 gfc_add_block_to_block (&lse.post, &rse.post);
1146 }
1147
1148 type = gfc_typenode_for_spec (&expr->ts);
1149
1150 if (lop)
1151 {
1152 /* The result of logical ops is always boolean_type_node. */
1153 tmp = fold_build2 (code, type, lse.expr, rse.expr);
1154 se->expr = convert (type, tmp);
1155 }
1156 else
1157 se->expr = fold_build2 (code, type, lse.expr, rse.expr);
1158
1159 /* Add the post blocks. */
1160 gfc_add_block_to_block (&se->post, &rse.post);
1161 gfc_add_block_to_block (&se->post, &lse.post);
1162 }
1163
1164 /* If a string's length is one, we convert it to a single character. */
1165
1166 static tree
1167 gfc_to_single_character (tree len, tree str)
1168 {
1169 gcc_assert (POINTER_TYPE_P (TREE_TYPE (str)));
1170
1171 if (INTEGER_CST_P (len) && TREE_INT_CST_LOW (len) == 1
1172 && TREE_INT_CST_HIGH (len) == 0)
1173 {
1174 str = fold_convert (pchar_type_node, str);
1175 return build_fold_indirect_ref (str);
1176 }
1177
1178 return NULL_TREE;
1179 }
1180
1181 /* Compare two strings. If they are all single characters, the result is the
1182 subtraction of them. Otherwise, we build a library call. */
1183
1184 tree
1185 gfc_build_compare_string (tree len1, tree str1, tree len2, tree str2)
1186 {
1187 tree sc1;
1188 tree sc2;
1189 tree type;
1190 tree tmp;
1191
1192 gcc_assert (POINTER_TYPE_P (TREE_TYPE (str1)));
1193 gcc_assert (POINTER_TYPE_P (TREE_TYPE (str2)));
1194
1195 type = gfc_get_int_type (gfc_default_integer_kind);
1196
1197 sc1 = gfc_to_single_character (len1, str1);
1198 sc2 = gfc_to_single_character (len2, str2);
1199
1200 /* Deal with single character specially. */
1201 if (sc1 != NULL_TREE && sc2 != NULL_TREE)
1202 {
1203 sc1 = fold_convert (type, sc1);
1204 sc2 = fold_convert (type, sc2);
1205 tmp = fold_build2 (MINUS_EXPR, type, sc1, sc2);
1206 }
1207 else
1208 {
1209 tmp = NULL_TREE;
1210 tmp = gfc_chainon_list (tmp, len1);
1211 tmp = gfc_chainon_list (tmp, str1);
1212 tmp = gfc_chainon_list (tmp, len2);
1213 tmp = gfc_chainon_list (tmp, str2);
1214
1215 /* Build a call for the comparison. */
1216 tmp = build_function_call_expr (gfor_fndecl_compare_string, tmp);
1217 }
1218
1219 return tmp;
1220 }
1221
1222 static void
1223 gfc_conv_function_val (gfc_se * se, gfc_symbol * sym)
1224 {
1225 tree tmp;
1226
1227 if (sym->attr.dummy)
1228 {
1229 tmp = gfc_get_symbol_decl (sym);
1230 gcc_assert (TREE_CODE (TREE_TYPE (tmp)) == POINTER_TYPE
1231 && TREE_CODE (TREE_TYPE (TREE_TYPE (tmp))) == FUNCTION_TYPE);
1232 }
1233 else
1234 {
1235 if (!sym->backend_decl)
1236 sym->backend_decl = gfc_get_extern_function_decl (sym);
1237
1238 tmp = sym->backend_decl;
1239 if (sym->attr.cray_pointee)
1240 tmp = convert (build_pointer_type (TREE_TYPE (tmp)),
1241 gfc_get_symbol_decl (sym->cp_pointer));
1242 if (!POINTER_TYPE_P (TREE_TYPE (tmp)))
1243 {
1244 gcc_assert (TREE_CODE (tmp) == FUNCTION_DECL);
1245 tmp = build_fold_addr_expr (tmp);
1246 }
1247 }
1248 se->expr = tmp;
1249 }
1250
1251
1252 /* Translate the call for an elemental subroutine call used in an operator
1253 assignment. This is a simplified version of gfc_conv_function_call. */
1254
1255 tree
1256 gfc_conv_operator_assign (gfc_se *lse, gfc_se *rse, gfc_symbol *sym)
1257 {
1258 tree args;
1259 tree tmp;
1260 gfc_se se;
1261 stmtblock_t block;
1262
1263 /* Only elemental subroutines with two arguments. */
1264 gcc_assert (sym->attr.elemental && sym->attr.subroutine);
1265 gcc_assert (sym->formal->next->next == NULL);
1266
1267 gfc_init_block (&block);
1268
1269 gfc_add_block_to_block (&block, &lse->pre);
1270 gfc_add_block_to_block (&block, &rse->pre);
1271
1272 /* Build the argument list for the call, including hidden string lengths. */
1273 args = gfc_chainon_list (NULL_TREE, build_fold_addr_expr (lse->expr));
1274 args = gfc_chainon_list (args, build_fold_addr_expr (rse->expr));
1275 if (lse->string_length != NULL_TREE)
1276 args = gfc_chainon_list (args, lse->string_length);
1277 if (rse->string_length != NULL_TREE)
1278 args = gfc_chainon_list (args, rse->string_length);
1279
1280 /* Build the function call. */
1281 gfc_init_se (&se, NULL);
1282 gfc_conv_function_val (&se, sym);
1283 tmp = TREE_TYPE (TREE_TYPE (TREE_TYPE (se.expr)));
1284 tmp = build3 (CALL_EXPR, tmp, se.expr, args, NULL_TREE);
1285 gfc_add_expr_to_block (&block, tmp);
1286
1287 gfc_add_block_to_block (&block, &lse->post);
1288 gfc_add_block_to_block (&block, &rse->post);
1289
1290 return gfc_finish_block (&block);
1291 }
1292
1293
1294 /* Initialize MAPPING. */
1295
1296 void
1297 gfc_init_interface_mapping (gfc_interface_mapping * mapping)
1298 {
1299 mapping->syms = NULL;
1300 mapping->charlens = NULL;
1301 }
1302
1303
1304 /* Free all memory held by MAPPING (but not MAPPING itself). */
1305
1306 void
1307 gfc_free_interface_mapping (gfc_interface_mapping * mapping)
1308 {
1309 gfc_interface_sym_mapping *sym;
1310 gfc_interface_sym_mapping *nextsym;
1311 gfc_charlen *cl;
1312 gfc_charlen *nextcl;
1313
1314 for (sym = mapping->syms; sym; sym = nextsym)
1315 {
1316 nextsym = sym->next;
1317 gfc_free_symbol (sym->new->n.sym);
1318 gfc_free (sym->new);
1319 gfc_free (sym);
1320 }
1321 for (cl = mapping->charlens; cl; cl = nextcl)
1322 {
1323 nextcl = cl->next;
1324 gfc_free_expr (cl->length);
1325 gfc_free (cl);
1326 }
1327 }
1328
1329
1330 /* Return a copy of gfc_charlen CL. Add the returned structure to
1331 MAPPING so that it will be freed by gfc_free_interface_mapping. */
1332
1333 static gfc_charlen *
1334 gfc_get_interface_mapping_charlen (gfc_interface_mapping * mapping,
1335 gfc_charlen * cl)
1336 {
1337 gfc_charlen *new;
1338
1339 new = gfc_get_charlen ();
1340 new->next = mapping->charlens;
1341 new->length = gfc_copy_expr (cl->length);
1342
1343 mapping->charlens = new;
1344 return new;
1345 }
1346
1347
1348 /* A subroutine of gfc_add_interface_mapping. Return a descriptorless
1349 array variable that can be used as the actual argument for dummy
1350 argument SYM. Add any initialization code to BLOCK. PACKED is as
1351 for gfc_get_nodesc_array_type and DATA points to the first element
1352 in the passed array. */
1353
1354 static tree
1355 gfc_get_interface_mapping_array (stmtblock_t * block, gfc_symbol * sym,
1356 int packed, tree data)
1357 {
1358 tree type;
1359 tree var;
1360
1361 type = gfc_typenode_for_spec (&sym->ts);
1362 type = gfc_get_nodesc_array_type (type, sym->as, packed);
1363
1364 var = gfc_create_var (type, "ifm");
1365 gfc_add_modify_expr (block, var, fold_convert (type, data));
1366
1367 return var;
1368 }
1369
1370
1371 /* A subroutine of gfc_add_interface_mapping. Set the stride, upper bounds
1372 and offset of descriptorless array type TYPE given that it has the same
1373 size as DESC. Add any set-up code to BLOCK. */
1374
1375 static void
1376 gfc_set_interface_mapping_bounds (stmtblock_t * block, tree type, tree desc)
1377 {
1378 int n;
1379 tree dim;
1380 tree offset;
1381 tree tmp;
1382
1383 offset = gfc_index_zero_node;
1384 for (n = 0; n < GFC_TYPE_ARRAY_RANK (type); n++)
1385 {
1386 dim = gfc_rank_cst[n];
1387 GFC_TYPE_ARRAY_STRIDE (type, n) = gfc_conv_array_stride (desc, n);
1388 if (GFC_TYPE_ARRAY_LBOUND (type, n) == NULL_TREE)
1389 {
1390 GFC_TYPE_ARRAY_LBOUND (type, n)
1391 = gfc_conv_descriptor_lbound (desc, dim);
1392 GFC_TYPE_ARRAY_UBOUND (type, n)
1393 = gfc_conv_descriptor_ubound (desc, dim);
1394 }
1395 else if (GFC_TYPE_ARRAY_UBOUND (type, n) == NULL_TREE)
1396 {
1397 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
1398 gfc_conv_descriptor_ubound (desc, dim),
1399 gfc_conv_descriptor_lbound (desc, dim));
1400 tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
1401 GFC_TYPE_ARRAY_LBOUND (type, n),
1402 tmp);
1403 tmp = gfc_evaluate_now (tmp, block);
1404 GFC_TYPE_ARRAY_UBOUND (type, n) = tmp;
1405 }
1406 tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
1407 GFC_TYPE_ARRAY_LBOUND (type, n),
1408 GFC_TYPE_ARRAY_STRIDE (type, n));
1409 offset = fold_build2 (MINUS_EXPR, gfc_array_index_type, offset, tmp);
1410 }
1411 offset = gfc_evaluate_now (offset, block);
1412 GFC_TYPE_ARRAY_OFFSET (type) = offset;
1413 }
1414
1415
1416 /* Extend MAPPING so that it maps dummy argument SYM to the value stored
1417 in SE. The caller may still use se->expr and se->string_length after
1418 calling this function. */
1419
1420 void
1421 gfc_add_interface_mapping (gfc_interface_mapping * mapping,
1422 gfc_symbol * sym, gfc_se * se)
1423 {
1424 gfc_interface_sym_mapping *sm;
1425 tree desc;
1426 tree tmp;
1427 tree value;
1428 gfc_symbol *new_sym;
1429 gfc_symtree *root;
1430 gfc_symtree *new_symtree;
1431
1432 /* Create a new symbol to represent the actual argument. */
1433 new_sym = gfc_new_symbol (sym->name, NULL);
1434 new_sym->ts = sym->ts;
1435 new_sym->attr.referenced = 1;
1436 new_sym->attr.dimension = sym->attr.dimension;
1437 new_sym->attr.pointer = sym->attr.pointer;
1438 new_sym->attr.allocatable = sym->attr.allocatable;
1439 new_sym->attr.flavor = sym->attr.flavor;
1440
1441 /* Create a fake symtree for it. */
1442 root = NULL;
1443 new_symtree = gfc_new_symtree (&root, sym->name);
1444 new_symtree->n.sym = new_sym;
1445 gcc_assert (new_symtree == root);
1446
1447 /* Create a dummy->actual mapping. */
1448 sm = gfc_getmem (sizeof (*sm));
1449 sm->next = mapping->syms;
1450 sm->old = sym;
1451 sm->new = new_symtree;
1452 mapping->syms = sm;
1453
1454 /* Stabilize the argument's value. */
1455 se->expr = gfc_evaluate_now (se->expr, &se->pre);
1456
1457 if (sym->ts.type == BT_CHARACTER)
1458 {
1459 /* Create a copy of the dummy argument's length. */
1460 new_sym->ts.cl = gfc_get_interface_mapping_charlen (mapping, sym->ts.cl);
1461
1462 /* If the length is specified as "*", record the length that
1463 the caller is passing. We should use the callee's length
1464 in all other cases. */
1465 if (!new_sym->ts.cl->length)
1466 {
1467 se->string_length = gfc_evaluate_now (se->string_length, &se->pre);
1468 new_sym->ts.cl->backend_decl = se->string_length;
1469 }
1470 }
1471
1472 /* Use the passed value as-is if the argument is a function. */
1473 if (sym->attr.flavor == FL_PROCEDURE)
1474 value = se->expr;
1475
1476 /* If the argument is either a string or a pointer to a string,
1477 convert it to a boundless character type. */
1478 else if (!sym->attr.dimension && sym->ts.type == BT_CHARACTER)
1479 {
1480 tmp = gfc_get_character_type_len (sym->ts.kind, NULL);
1481 tmp = build_pointer_type (tmp);
1482 if (sym->attr.pointer)
1483 value = build_fold_indirect_ref (se->expr);
1484 else
1485 value = se->expr;
1486 value = fold_convert (tmp, value);
1487 }
1488
1489 /* If the argument is a scalar, a pointer to an array or an allocatable,
1490 dereference it. */
1491 else if (!sym->attr.dimension || sym->attr.pointer || sym->attr.allocatable)
1492 value = build_fold_indirect_ref (se->expr);
1493
1494 /* For character(*), use the actual argument's descriptor. */
1495 else if (sym->ts.type == BT_CHARACTER && !new_sym->ts.cl->length)
1496 value = build_fold_indirect_ref (se->expr);
1497
1498 /* If the argument is an array descriptor, use it to determine
1499 information about the actual argument's shape. */
1500 else if (POINTER_TYPE_P (TREE_TYPE (se->expr))
1501 && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (TREE_TYPE (se->expr))))
1502 {
1503 /* Get the actual argument's descriptor. */
1504 desc = build_fold_indirect_ref (se->expr);
1505
1506 /* Create the replacement variable. */
1507 tmp = gfc_conv_descriptor_data_get (desc);
1508 value = gfc_get_interface_mapping_array (&se->pre, sym, 0, tmp);
1509
1510 /* Use DESC to work out the upper bounds, strides and offset. */
1511 gfc_set_interface_mapping_bounds (&se->pre, TREE_TYPE (value), desc);
1512 }
1513 else
1514 /* Otherwise we have a packed array. */
1515 value = gfc_get_interface_mapping_array (&se->pre, sym, 2, se->expr);
1516
1517 new_sym->backend_decl = value;
1518 }
1519
1520
1521 /* Called once all dummy argument mappings have been added to MAPPING,
1522 but before the mapping is used to evaluate expressions. Pre-evaluate
1523 the length of each argument, adding any initialization code to PRE and
1524 any finalization code to POST. */
1525
1526 void
1527 gfc_finish_interface_mapping (gfc_interface_mapping * mapping,
1528 stmtblock_t * pre, stmtblock_t * post)
1529 {
1530 gfc_interface_sym_mapping *sym;
1531 gfc_expr *expr;
1532 gfc_se se;
1533
1534 for (sym = mapping->syms; sym; sym = sym->next)
1535 if (sym->new->n.sym->ts.type == BT_CHARACTER
1536 && !sym->new->n.sym->ts.cl->backend_decl)
1537 {
1538 expr = sym->new->n.sym->ts.cl->length;
1539 gfc_apply_interface_mapping_to_expr (mapping, expr);
1540 gfc_init_se (&se, NULL);
1541 gfc_conv_expr (&se, expr);
1542
1543 se.expr = gfc_evaluate_now (se.expr, &se.pre);
1544 gfc_add_block_to_block (pre, &se.pre);
1545 gfc_add_block_to_block (post, &se.post);
1546
1547 sym->new->n.sym->ts.cl->backend_decl = se.expr;
1548 }
1549 }
1550
1551
1552 /* Like gfc_apply_interface_mapping_to_expr, but applied to
1553 constructor C. */
1554
1555 static void
1556 gfc_apply_interface_mapping_to_cons (gfc_interface_mapping * mapping,
1557 gfc_constructor * c)
1558 {
1559 for (; c; c = c->next)
1560 {
1561 gfc_apply_interface_mapping_to_expr (mapping, c->expr);
1562 if (c->iterator)
1563 {
1564 gfc_apply_interface_mapping_to_expr (mapping, c->iterator->start);
1565 gfc_apply_interface_mapping_to_expr (mapping, c->iterator->end);
1566 gfc_apply_interface_mapping_to_expr (mapping, c->iterator->step);
1567 }
1568 }
1569 }
1570
1571
1572 /* Like gfc_apply_interface_mapping_to_expr, but applied to
1573 reference REF. */
1574
1575 static void
1576 gfc_apply_interface_mapping_to_ref (gfc_interface_mapping * mapping,
1577 gfc_ref * ref)
1578 {
1579 int n;
1580
1581 for (; ref; ref = ref->next)
1582 switch (ref->type)
1583 {
1584 case REF_ARRAY:
1585 for (n = 0; n < ref->u.ar.dimen; n++)
1586 {
1587 gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.start[n]);
1588 gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.end[n]);
1589 gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.stride[n]);
1590 }
1591 gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.offset);
1592 break;
1593
1594 case REF_COMPONENT:
1595 break;
1596
1597 case REF_SUBSTRING:
1598 gfc_apply_interface_mapping_to_expr (mapping, ref->u.ss.start);
1599 gfc_apply_interface_mapping_to_expr (mapping, ref->u.ss.end);
1600 break;
1601 }
1602 }
1603
1604
1605 /* EXPR is a copy of an expression that appeared in the interface
1606 associated with MAPPING. Walk it recursively looking for references to
1607 dummy arguments that MAPPING maps to actual arguments. Replace each such
1608 reference with a reference to the associated actual argument. */
1609
1610 static void
1611 gfc_apply_interface_mapping_to_expr (gfc_interface_mapping * mapping,
1612 gfc_expr * expr)
1613 {
1614 gfc_interface_sym_mapping *sym;
1615 gfc_actual_arglist *actual;
1616
1617 if (!expr)
1618 return;
1619
1620 /* Copying an expression does not copy its length, so do that here. */
1621 if (expr->ts.type == BT_CHARACTER && expr->ts.cl)
1622 {
1623 expr->ts.cl = gfc_get_interface_mapping_charlen (mapping, expr->ts.cl);
1624 gfc_apply_interface_mapping_to_expr (mapping, expr->ts.cl->length);
1625 }
1626
1627 /* Apply the mapping to any references. */
1628 gfc_apply_interface_mapping_to_ref (mapping, expr->ref);
1629
1630 /* ...and to the expression's symbol, if it has one. */
1631 if (expr->symtree)
1632 for (sym = mapping->syms; sym; sym = sym->next)
1633 if (sym->old == expr->symtree->n.sym)
1634 expr->symtree = sym->new;
1635
1636 /* ...and to subexpressions in expr->value. */
1637 switch (expr->expr_type)
1638 {
1639 case EXPR_VARIABLE:
1640 case EXPR_CONSTANT:
1641 case EXPR_NULL:
1642 case EXPR_SUBSTRING:
1643 break;
1644
1645 case EXPR_OP:
1646 gfc_apply_interface_mapping_to_expr (mapping, expr->value.op.op1);
1647 gfc_apply_interface_mapping_to_expr (mapping, expr->value.op.op2);
1648 break;
1649
1650 case EXPR_FUNCTION:
1651 for (sym = mapping->syms; sym; sym = sym->next)
1652 if (sym->old == expr->value.function.esym)
1653 expr->value.function.esym = sym->new->n.sym;
1654
1655 for (actual = expr->value.function.actual; actual; actual = actual->next)
1656 gfc_apply_interface_mapping_to_expr (mapping, actual->expr);
1657 break;
1658
1659 case EXPR_ARRAY:
1660 case EXPR_STRUCTURE:
1661 gfc_apply_interface_mapping_to_cons (mapping, expr->value.constructor);
1662 break;
1663 }
1664 }
1665
1666
1667 /* Evaluate interface expression EXPR using MAPPING. Store the result
1668 in SE. */
1669
1670 void
1671 gfc_apply_interface_mapping (gfc_interface_mapping * mapping,
1672 gfc_se * se, gfc_expr * expr)
1673 {
1674 expr = gfc_copy_expr (expr);
1675 gfc_apply_interface_mapping_to_expr (mapping, expr);
1676 gfc_conv_expr (se, expr);
1677 se->expr = gfc_evaluate_now (se->expr, &se->pre);
1678 gfc_free_expr (expr);
1679 }
1680
1681 /* Returns a reference to a temporary array into which a component of
1682 an actual argument derived type array is copied and then returned
1683 after the function call.
1684 TODO Get rid of this kludge, when array descriptors are capable of
1685 handling arrays with a bigger stride in bytes than size. */
1686
1687 void
1688 gfc_conv_aliased_arg (gfc_se * parmse, gfc_expr * expr,
1689 int g77, sym_intent intent)
1690 {
1691 gfc_se lse;
1692 gfc_se rse;
1693 gfc_ss *lss;
1694 gfc_ss *rss;
1695 gfc_loopinfo loop;
1696 gfc_loopinfo loop2;
1697 gfc_ss_info *info;
1698 tree offset;
1699 tree tmp_index;
1700 tree tmp;
1701 tree base_type;
1702 stmtblock_t body;
1703 int n;
1704
1705 gcc_assert (expr->expr_type == EXPR_VARIABLE);
1706
1707 gfc_init_se (&lse, NULL);
1708 gfc_init_se (&rse, NULL);
1709
1710 /* Walk the argument expression. */
1711 rss = gfc_walk_expr (expr);
1712
1713 gcc_assert (rss != gfc_ss_terminator);
1714
1715 /* Initialize the scalarizer. */
1716 gfc_init_loopinfo (&loop);
1717 gfc_add_ss_to_loop (&loop, rss);
1718
1719 /* Calculate the bounds of the scalarization. */
1720 gfc_conv_ss_startstride (&loop);
1721
1722 /* Build an ss for the temporary. */
1723 base_type = gfc_typenode_for_spec (&expr->ts);
1724 if (GFC_ARRAY_TYPE_P (base_type)
1725 || GFC_DESCRIPTOR_TYPE_P (base_type))
1726 base_type = gfc_get_element_type (base_type);
1727
1728 loop.temp_ss = gfc_get_ss ();;
1729 loop.temp_ss->type = GFC_SS_TEMP;
1730 loop.temp_ss->data.temp.type = base_type;
1731
1732 if (expr->ts.type == BT_CHARACTER)
1733 {
1734 gfc_ref *char_ref = expr->ref;
1735
1736 for (; char_ref; char_ref = char_ref->next)
1737 if (char_ref->type == REF_SUBSTRING)
1738 {
1739 gfc_se tmp_se;
1740
1741 expr->ts.cl = gfc_get_charlen ();
1742 expr->ts.cl->next = char_ref->u.ss.length->next;
1743 char_ref->u.ss.length->next = expr->ts.cl;
1744
1745 gfc_init_se (&tmp_se, NULL);
1746 gfc_conv_expr_type (&tmp_se, char_ref->u.ss.end,
1747 gfc_array_index_type);
1748 tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
1749 tmp_se.expr, gfc_index_one_node);
1750 tmp = gfc_evaluate_now (tmp, &parmse->pre);
1751 gfc_init_se (&tmp_se, NULL);
1752 gfc_conv_expr_type (&tmp_se, char_ref->u.ss.start,
1753 gfc_array_index_type);
1754 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
1755 tmp, tmp_se.expr);
1756 expr->ts.cl->backend_decl = tmp;
1757
1758 break;
1759 }
1760 loop.temp_ss->data.temp.type
1761 = gfc_typenode_for_spec (&expr->ts);
1762 loop.temp_ss->string_length = expr->ts.cl->backend_decl;
1763 }
1764
1765 loop.temp_ss->data.temp.dimen = loop.dimen;
1766 loop.temp_ss->next = gfc_ss_terminator;
1767
1768 /* Associate the SS with the loop. */
1769 gfc_add_ss_to_loop (&loop, loop.temp_ss);
1770
1771 /* Setup the scalarizing loops. */
1772 gfc_conv_loop_setup (&loop);
1773
1774 /* Pass the temporary descriptor back to the caller. */
1775 info = &loop.temp_ss->data.info;
1776 parmse->expr = info->descriptor;
1777
1778 /* Setup the gfc_se structures. */
1779 gfc_copy_loopinfo_to_se (&lse, &loop);
1780 gfc_copy_loopinfo_to_se (&rse, &loop);
1781
1782 rse.ss = rss;
1783 lse.ss = loop.temp_ss;
1784 gfc_mark_ss_chain_used (rss, 1);
1785 gfc_mark_ss_chain_used (loop.temp_ss, 1);
1786
1787 /* Start the scalarized loop body. */
1788 gfc_start_scalarized_body (&loop, &body);
1789
1790 /* Translate the expression. */
1791 gfc_conv_expr (&rse, expr);
1792
1793 gfc_conv_tmp_array_ref (&lse);
1794 gfc_advance_se_ss_chain (&lse);
1795
1796 if (intent != INTENT_OUT)
1797 {
1798 tmp = gfc_trans_scalar_assign (&lse, &rse, expr->ts, true, false);
1799 gfc_add_expr_to_block (&body, tmp);
1800 gcc_assert (rse.ss == gfc_ss_terminator);
1801 gfc_trans_scalarizing_loops (&loop, &body);
1802 }
1803 else
1804 {
1805 /* Make sure that the temporary declaration survives by merging
1806 all the loop declarations into the current context. */
1807 for (n = 0; n < loop.dimen; n++)
1808 {
1809 gfc_merge_block_scope (&body);
1810 body = loop.code[loop.order[n]];
1811 }
1812 gfc_merge_block_scope (&body);
1813 }
1814
1815 /* Add the post block after the second loop, so that any
1816 freeing of allocated memory is done at the right time. */
1817 gfc_add_block_to_block (&parmse->pre, &loop.pre);
1818
1819 /**********Copy the temporary back again.*********/
1820
1821 gfc_init_se (&lse, NULL);
1822 gfc_init_se (&rse, NULL);
1823
1824 /* Walk the argument expression. */
1825 lss = gfc_walk_expr (expr);
1826 rse.ss = loop.temp_ss;
1827 lse.ss = lss;
1828
1829 /* Initialize the scalarizer. */
1830 gfc_init_loopinfo (&loop2);
1831 gfc_add_ss_to_loop (&loop2, lss);
1832
1833 /* Calculate the bounds of the scalarization. */
1834 gfc_conv_ss_startstride (&loop2);
1835
1836 /* Setup the scalarizing loops. */
1837 gfc_conv_loop_setup (&loop2);
1838
1839 gfc_copy_loopinfo_to_se (&lse, &loop2);
1840 gfc_copy_loopinfo_to_se (&rse, &loop2);
1841
1842 gfc_mark_ss_chain_used (lss, 1);
1843 gfc_mark_ss_chain_used (loop.temp_ss, 1);
1844
1845 /* Declare the variable to hold the temporary offset and start the
1846 scalarized loop body. */
1847 offset = gfc_create_var (gfc_array_index_type, NULL);
1848 gfc_start_scalarized_body (&loop2, &body);
1849
1850 /* Build the offsets for the temporary from the loop variables. The
1851 temporary array has lbounds of zero and strides of one in all
1852 dimensions, so this is very simple. The offset is only computed
1853 outside the innermost loop, so the overall transfer could be
1854 optimized further. */
1855 info = &rse.ss->data.info;
1856
1857 tmp_index = gfc_index_zero_node;
1858 for (n = info->dimen - 1; n > 0; n--)
1859 {
1860 tree tmp_str;
1861 tmp = rse.loop->loopvar[n];
1862 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
1863 tmp, rse.loop->from[n]);
1864 tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
1865 tmp, tmp_index);
1866
1867 tmp_str = fold_build2 (MINUS_EXPR, gfc_array_index_type,
1868 rse.loop->to[n-1], rse.loop->from[n-1]);
1869 tmp_str = fold_build2 (PLUS_EXPR, gfc_array_index_type,
1870 tmp_str, gfc_index_one_node);
1871
1872 tmp_index = fold_build2 (MULT_EXPR, gfc_array_index_type,
1873 tmp, tmp_str);
1874 }
1875
1876 tmp_index = fold_build2 (MINUS_EXPR, gfc_array_index_type,
1877 tmp_index, rse.loop->from[0]);
1878 gfc_add_modify_expr (&rse.loop->code[0], offset, tmp_index);
1879
1880 tmp_index = fold_build2 (PLUS_EXPR, gfc_array_index_type,
1881 rse.loop->loopvar[0], offset);
1882
1883 /* Now use the offset for the reference. */
1884 tmp = build_fold_indirect_ref (info->data);
1885 rse.expr = gfc_build_array_ref (tmp, tmp_index);
1886
1887 if (expr->ts.type == BT_CHARACTER)
1888 rse.string_length = expr->ts.cl->backend_decl;
1889
1890 gfc_conv_expr (&lse, expr);
1891
1892 gcc_assert (lse.ss == gfc_ss_terminator);
1893
1894 tmp = gfc_trans_scalar_assign (&lse, &rse, expr->ts, false, false);
1895 gfc_add_expr_to_block (&body, tmp);
1896
1897 /* Generate the copying loops. */
1898 gfc_trans_scalarizing_loops (&loop2, &body);
1899
1900 /* Wrap the whole thing up by adding the second loop to the post-block
1901 and following it by the post-block of the first loop. In this way,
1902 if the temporary needs freeing, it is done after use! */
1903 if (intent != INTENT_IN)
1904 {
1905 gfc_add_block_to_block (&parmse->post, &loop2.pre);
1906 gfc_add_block_to_block (&parmse->post, &loop2.post);
1907 }
1908
1909 gfc_add_block_to_block (&parmse->post, &loop.post);
1910
1911 gfc_cleanup_loop (&loop);
1912 gfc_cleanup_loop (&loop2);
1913
1914 /* Pass the string length to the argument expression. */
1915 if (expr->ts.type == BT_CHARACTER)
1916 parmse->string_length = expr->ts.cl->backend_decl;
1917
1918 /* We want either the address for the data or the address of the descriptor,
1919 depending on the mode of passing array arguments. */
1920 if (g77)
1921 parmse->expr = gfc_conv_descriptor_data_get (parmse->expr);
1922 else
1923 parmse->expr = build_fold_addr_expr (parmse->expr);
1924
1925 return;
1926 }
1927
1928 /* Is true if an array reference is followed by a component or substring
1929 reference. */
1930
1931 bool
1932 is_aliased_array (gfc_expr * e)
1933 {
1934 gfc_ref * ref;
1935 bool seen_array;
1936
1937 seen_array = false;
1938 for (ref = e->ref; ref; ref = ref->next)
1939 {
1940 if (ref->type == REF_ARRAY
1941 && ref->u.ar.type != AR_ELEMENT)
1942 seen_array = true;
1943
1944 if (seen_array
1945 && ref->type != REF_ARRAY)
1946 return seen_array;
1947 }
1948 return false;
1949 }
1950
1951 /* Generate the code for argument list functions. */
1952
1953 static void
1954 conv_arglist_function (gfc_se *se, gfc_expr *expr, const char *name)
1955 {
1956 tree type = NULL_TREE;
1957 /* Pass by value for g77 %VAL(arg), pass the address
1958 indirectly for %LOC, else by reference. Thus %REF
1959 is a "do-nothing" and %LOC is the same as an F95
1960 pointer. */
1961 if (strncmp (name, "%VAL", 4) == 0)
1962 {
1963 gfc_conv_expr (se, expr);
1964 /* %VAL converts argument to default kind. */
1965 switch (expr->ts.type)
1966 {
1967 case BT_REAL:
1968 type = gfc_get_real_type (gfc_default_real_kind);
1969 se->expr = fold_convert (type, se->expr);
1970 break;
1971 case BT_COMPLEX:
1972 type = gfc_get_complex_type (gfc_default_complex_kind);
1973 se->expr = fold_convert (type, se->expr);
1974 break;
1975 case BT_INTEGER:
1976 type = gfc_get_int_type (gfc_default_integer_kind);
1977 se->expr = fold_convert (type, se->expr);
1978 break;
1979 case BT_LOGICAL:
1980 type = gfc_get_logical_type (gfc_default_logical_kind);
1981 se->expr = fold_convert (type, se->expr);
1982 break;
1983 /* This should have been resolved away. */
1984 case BT_UNKNOWN: case BT_CHARACTER: case BT_DERIVED:
1985 case BT_PROCEDURE: case BT_HOLLERITH:
1986 gfc_internal_error ("Bad type in conv_arglist_function");
1987 }
1988
1989 }
1990 else if (strncmp (name, "%LOC", 4) == 0)
1991 {
1992 gfc_conv_expr_reference (se, expr);
1993 se->expr = gfc_build_addr_expr (NULL, se->expr);
1994 }
1995 else if (strncmp (name, "%REF", 4) == 0)
1996 gfc_conv_expr_reference (se, expr);
1997 else
1998 gfc_error ("Unknown argument list function at %L", &expr->where);
1999 }
2000
2001
2002 /* Generate code for a procedure call. Note can return se->post != NULL.
2003 If se->direct_byref is set then se->expr contains the return parameter.
2004 Return nonzero, if the call has alternate specifiers. */
2005
2006 int
2007 gfc_conv_function_call (gfc_se * se, gfc_symbol * sym,
2008 gfc_actual_arglist * arg, tree append_args)
2009 {
2010 gfc_interface_mapping mapping;
2011 tree arglist;
2012 tree retargs;
2013 tree tmp;
2014 tree fntype;
2015 gfc_se parmse;
2016 gfc_ss *argss;
2017 gfc_ss_info *info;
2018 int byref;
2019 int parm_kind;
2020 tree type;
2021 tree var;
2022 tree len;
2023 tree stringargs;
2024 gfc_formal_arglist *formal;
2025 int has_alternate_specifier = 0;
2026 bool need_interface_mapping;
2027 bool callee_alloc;
2028 gfc_typespec ts;
2029 gfc_charlen cl;
2030 gfc_expr *e;
2031 gfc_symbol *fsym;
2032 stmtblock_t post;
2033 enum {MISSING = 0, ELEMENTAL, SCALAR, SCALAR_POINTER, ARRAY};
2034
2035 arglist = NULL_TREE;
2036 retargs = NULL_TREE;
2037 stringargs = NULL_TREE;
2038 var = NULL_TREE;
2039 len = NULL_TREE;
2040
2041 if (se->ss != NULL)
2042 {
2043 if (!sym->attr.elemental)
2044 {
2045 gcc_assert (se->ss->type == GFC_SS_FUNCTION);
2046 if (se->ss->useflags)
2047 {
2048 gcc_assert (gfc_return_by_reference (sym)
2049 && sym->result->attr.dimension);
2050 gcc_assert (se->loop != NULL);
2051
2052 /* Access the previously obtained result. */
2053 gfc_conv_tmp_array_ref (se);
2054 gfc_advance_se_ss_chain (se);
2055 return 0;
2056 }
2057 }
2058 info = &se->ss->data.info;
2059 }
2060 else
2061 info = NULL;
2062
2063 gfc_init_block (&post);
2064 gfc_init_interface_mapping (&mapping);
2065 need_interface_mapping = ((sym->ts.type == BT_CHARACTER
2066 && sym->ts.cl->length
2067 && sym->ts.cl->length->expr_type
2068 != EXPR_CONSTANT)
2069 || sym->attr.dimension);
2070 formal = sym->formal;
2071 /* Evaluate the arguments. */
2072 for (; arg != NULL; arg = arg->next, formal = formal ? formal->next : NULL)
2073 {
2074 e = arg->expr;
2075 fsym = formal ? formal->sym : NULL;
2076 parm_kind = MISSING;
2077 if (e == NULL)
2078 {
2079
2080 if (se->ignore_optional)
2081 {
2082 /* Some intrinsics have already been resolved to the correct
2083 parameters. */
2084 continue;
2085 }
2086 else if (arg->label)
2087 {
2088 has_alternate_specifier = 1;
2089 continue;
2090 }
2091 else
2092 {
2093 /* Pass a NULL pointer for an absent arg. */
2094 gfc_init_se (&parmse, NULL);
2095 parmse.expr = null_pointer_node;
2096 if (arg->missing_arg_type == BT_CHARACTER)
2097 parmse.string_length = build_int_cst (gfc_charlen_type_node, 0);
2098 }
2099 }
2100 else if (se->ss && se->ss->useflags)
2101 {
2102 /* An elemental function inside a scalarized loop. */
2103 gfc_init_se (&parmse, se);
2104 gfc_conv_expr_reference (&parmse, e);
2105 parm_kind = ELEMENTAL;
2106 }
2107 else
2108 {
2109 /* A scalar or transformational function. */
2110 gfc_init_se (&parmse, NULL);
2111 argss = gfc_walk_expr (e);
2112
2113 if (argss == gfc_ss_terminator)
2114 {
2115 parm_kind = SCALAR;
2116 if (fsym && fsym->attr.value)
2117 {
2118 gfc_conv_expr (&parmse, e);
2119 }
2120 else if (arg->name && arg->name[0] == '%')
2121 /* Argument list functions %VAL, %LOC and %REF are signalled
2122 through arg->name. */
2123 conv_arglist_function (&parmse, arg->expr, arg->name);
2124 else
2125 {
2126 gfc_conv_expr_reference (&parmse, e);
2127 if (fsym && fsym->attr.pointer
2128 && e->expr_type != EXPR_NULL)
2129 {
2130 /* Scalar pointer dummy args require an extra level of
2131 indirection. The null pointer already contains
2132 this level of indirection. */
2133 parm_kind = SCALAR_POINTER;
2134 parmse.expr = build_fold_addr_expr (parmse.expr);
2135 }
2136 }
2137 }
2138 else
2139 {
2140 /* If the procedure requires an explicit interface, the actual
2141 argument is passed according to the corresponding formal
2142 argument. If the corresponding formal argument is a POINTER,
2143 ALLOCATABLE or assumed shape, we do not use g77's calling
2144 convention, and pass the address of the array descriptor
2145 instead. Otherwise we use g77's calling convention. */
2146 int f;
2147 f = (fsym != NULL)
2148 && !(fsym->attr.pointer || fsym->attr.allocatable)
2149 && fsym->as->type != AS_ASSUMED_SHAPE;
2150 f = f || !sym->attr.always_explicit;
2151
2152 if (e->expr_type == EXPR_VARIABLE
2153 && is_aliased_array (e))
2154 /* The actual argument is a component reference to an
2155 array of derived types. In this case, the argument
2156 is converted to a temporary, which is passed and then
2157 written back after the procedure call. */
2158 gfc_conv_aliased_arg (&parmse, e, f,
2159 fsym ? fsym->attr.intent : INTENT_INOUT);
2160 else
2161 gfc_conv_array_parameter (&parmse, e, argss, f);
2162
2163 /* If an ALLOCATABLE dummy argument has INTENT(OUT) and is
2164 allocated on entry, it must be deallocated. */
2165 if (fsym && fsym->attr.allocatable
2166 && fsym->attr.intent == INTENT_OUT)
2167 {
2168 tmp = build_fold_indirect_ref (parmse.expr);
2169 tmp = gfc_trans_dealloc_allocated (tmp);
2170 gfc_add_expr_to_block (&se->pre, tmp);
2171 }
2172
2173 }
2174 }
2175
2176 if (fsym)
2177 {
2178 if (e)
2179 {
2180 /* If an optional argument is itself an optional dummy
2181 argument, check its presence and substitute a null
2182 if absent. */
2183 if (e->expr_type == EXPR_VARIABLE
2184 && e->symtree->n.sym->attr.optional
2185 && fsym->attr.optional)
2186 gfc_conv_missing_dummy (&parmse, e, fsym->ts);
2187
2188 /* If an INTENT(OUT) dummy of derived type has a default
2189 initializer, it must be (re)initialized here. */
2190 if (fsym->attr.intent == INTENT_OUT
2191 && fsym->ts.type == BT_DERIVED
2192 && fsym->value)
2193 {
2194 gcc_assert (!fsym->attr.allocatable);
2195 tmp = gfc_trans_assignment (e, fsym->value, false);
2196 gfc_add_expr_to_block (&se->pre, tmp);
2197 }
2198
2199 /* Obtain the character length of an assumed character
2200 length procedure from the typespec. */
2201 if (fsym->ts.type == BT_CHARACTER
2202 && parmse.string_length == NULL_TREE
2203 && e->ts.type == BT_PROCEDURE
2204 && e->symtree->n.sym->ts.type == BT_CHARACTER
2205 && e->symtree->n.sym->ts.cl->length != NULL)
2206 {
2207 gfc_conv_const_charlen (e->symtree->n.sym->ts.cl);
2208 parmse.string_length
2209 = e->symtree->n.sym->ts.cl->backend_decl;
2210 }
2211 }
2212
2213 if (need_interface_mapping)
2214 gfc_add_interface_mapping (&mapping, fsym, &parmse);
2215 }
2216
2217 gfc_add_block_to_block (&se->pre, &parmse.pre);
2218 gfc_add_block_to_block (&post, &parmse.post);
2219
2220 /* Allocated allocatable components of derived types must be
2221 deallocated for INTENT(OUT) dummy arguments and non-variable
2222 scalars. Non-variable arrays are dealt with in trans-array.c
2223 (gfc_conv_array_parameter). */
2224 if (e && e->ts.type == BT_DERIVED
2225 && e->ts.derived->attr.alloc_comp
2226 && ((formal && formal->sym->attr.intent == INTENT_OUT)
2227 ||
2228 (e->expr_type != EXPR_VARIABLE && !e->rank)))
2229 {
2230 int parm_rank;
2231 tmp = build_fold_indirect_ref (parmse.expr);
2232 parm_rank = e->rank;
2233 switch (parm_kind)
2234 {
2235 case (ELEMENTAL):
2236 case (SCALAR):
2237 parm_rank = 0;
2238 break;
2239
2240 case (SCALAR_POINTER):
2241 tmp = build_fold_indirect_ref (tmp);
2242 break;
2243 case (ARRAY):
2244 tmp = parmse.expr;
2245 break;
2246 }
2247
2248 tmp = gfc_deallocate_alloc_comp (e->ts.derived, tmp, parm_rank);
2249 if (e->expr_type == EXPR_VARIABLE && e->symtree->n.sym->attr.optional)
2250 tmp = build3_v (COND_EXPR, gfc_conv_expr_present (e->symtree->n.sym),
2251 tmp, build_empty_stmt ());
2252
2253 if (e->expr_type != EXPR_VARIABLE)
2254 /* Don't deallocate non-variables until they have been used. */
2255 gfc_add_expr_to_block (&se->post, tmp);
2256 else
2257 {
2258 gcc_assert (formal && formal->sym->attr.intent == INTENT_OUT);
2259 gfc_add_expr_to_block (&se->pre, tmp);
2260 }
2261 }
2262
2263 /* Character strings are passed as two parameters, a length and a
2264 pointer. */
2265 if (parmse.string_length != NULL_TREE)
2266 stringargs = gfc_chainon_list (stringargs, parmse.string_length);
2267
2268 arglist = gfc_chainon_list (arglist, parmse.expr);
2269 }
2270 gfc_finish_interface_mapping (&mapping, &se->pre, &se->post);
2271
2272 ts = sym->ts;
2273 if (ts.type == BT_CHARACTER)
2274 {
2275 if (sym->ts.cl->length == NULL)
2276 {
2277 /* Assumed character length results are not allowed by 5.1.1.5 of the
2278 standard and are trapped in resolve.c; except in the case of SPREAD
2279 (and other intrinsics?) and dummy functions. In the case of SPREAD,
2280 we take the character length of the first argument for the result.
2281 For dummies, we have to look through the formal argument list for
2282 this function and use the character length found there.*/
2283 if (!sym->attr.dummy)
2284 cl.backend_decl = TREE_VALUE (stringargs);
2285 else
2286 {
2287 formal = sym->ns->proc_name->formal;
2288 for (; formal; formal = formal->next)
2289 if (strcmp (formal->sym->name, sym->name) == 0)
2290 cl.backend_decl = formal->sym->ts.cl->backend_decl;
2291 }
2292 }
2293 else
2294 {
2295 /* Calculate the length of the returned string. */
2296 gfc_init_se (&parmse, NULL);
2297 if (need_interface_mapping)
2298 gfc_apply_interface_mapping (&mapping, &parmse, sym->ts.cl->length);
2299 else
2300 gfc_conv_expr (&parmse, sym->ts.cl->length);
2301 gfc_add_block_to_block (&se->pre, &parmse.pre);
2302 gfc_add_block_to_block (&se->post, &parmse.post);
2303 cl.backend_decl = fold_convert (gfc_charlen_type_node, parmse.expr);
2304 }
2305
2306 /* Set up a charlen structure for it. */
2307 cl.next = NULL;
2308 cl.length = NULL;
2309 ts.cl = &cl;
2310
2311 len = cl.backend_decl;
2312 }
2313
2314 byref = gfc_return_by_reference (sym);
2315 if (byref)
2316 {
2317 if (se->direct_byref)
2318 retargs = gfc_chainon_list (retargs, se->expr);
2319 else if (sym->result->attr.dimension)
2320 {
2321 gcc_assert (se->loop && info);
2322
2323 /* Set the type of the array. */
2324 tmp = gfc_typenode_for_spec (&ts);
2325 info->dimen = se->loop->dimen;
2326
2327 /* Evaluate the bounds of the result, if known. */
2328 gfc_set_loop_bounds_from_array_spec (&mapping, se, sym->result->as);
2329
2330 /* Create a temporary to store the result. In case the function
2331 returns a pointer, the temporary will be a shallow copy and
2332 mustn't be deallocated. */
2333 callee_alloc = sym->attr.allocatable || sym->attr.pointer;
2334 gfc_trans_create_temp_array (&se->pre, &se->post, se->loop, info, tmp,
2335 false, !sym->attr.pointer, callee_alloc);
2336
2337 /* Pass the temporary as the first argument. */
2338 tmp = info->descriptor;
2339 tmp = build_fold_addr_expr (tmp);
2340 retargs = gfc_chainon_list (retargs, tmp);
2341 }
2342 else if (ts.type == BT_CHARACTER)
2343 {
2344 /* Pass the string length. */
2345 type = gfc_get_character_type (ts.kind, ts.cl);
2346 type = build_pointer_type (type);
2347
2348 /* Return an address to a char[0:len-1]* temporary for
2349 character pointers. */
2350 if (sym->attr.pointer || sym->attr.allocatable)
2351 {
2352 /* Build char[0:len-1] * pstr. */
2353 tmp = fold_build2 (MINUS_EXPR, gfc_charlen_type_node, len,
2354 build_int_cst (gfc_charlen_type_node, 1));
2355 tmp = build_range_type (gfc_array_index_type,
2356 gfc_index_zero_node, tmp);
2357 tmp = build_array_type (gfc_character1_type_node, tmp);
2358 var = gfc_create_var (build_pointer_type (tmp), "pstr");
2359
2360 /* Provide an address expression for the function arguments. */
2361 var = build_fold_addr_expr (var);
2362 }
2363 else
2364 var = gfc_conv_string_tmp (se, type, len);
2365
2366 retargs = gfc_chainon_list (retargs, var);
2367 }
2368 else
2369 {
2370 gcc_assert (gfc_option.flag_f2c && ts.type == BT_COMPLEX);
2371
2372 type = gfc_get_complex_type (ts.kind);
2373 var = build_fold_addr_expr (gfc_create_var (type, "cmplx"));
2374 retargs = gfc_chainon_list (retargs, var);
2375 }
2376
2377 /* Add the string length to the argument list. */
2378 if (ts.type == BT_CHARACTER)
2379 retargs = gfc_chainon_list (retargs, len);
2380 }
2381 gfc_free_interface_mapping (&mapping);
2382
2383 /* Add the return arguments. */
2384 arglist = chainon (retargs, arglist);
2385
2386 /* Add the hidden string length parameters to the arguments. */
2387 arglist = chainon (arglist, stringargs);
2388
2389 /* We may want to append extra arguments here. This is used e.g. for
2390 calls to libgfortran_matmul_??, which need extra information. */
2391 if (append_args != NULL_TREE)
2392 arglist = chainon (arglist, append_args);
2393
2394 /* Generate the actual call. */
2395 gfc_conv_function_val (se, sym);
2396 /* If there are alternate return labels, function type should be
2397 integer. Can't modify the type in place though, since it can be shared
2398 with other functions. */
2399 if (has_alternate_specifier
2400 && TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr))) != integer_type_node)
2401 {
2402 gcc_assert (! sym->attr.dummy);
2403 TREE_TYPE (sym->backend_decl)
2404 = build_function_type (integer_type_node,
2405 TYPE_ARG_TYPES (TREE_TYPE (sym->backend_decl)));
2406 se->expr = build_fold_addr_expr (sym->backend_decl);
2407 }
2408
2409 fntype = TREE_TYPE (TREE_TYPE (se->expr));
2410 se->expr = build3 (CALL_EXPR, TREE_TYPE (fntype), se->expr,
2411 arglist, NULL_TREE);
2412
2413 /* If we have a pointer function, but we don't want a pointer, e.g.
2414 something like
2415 x = f()
2416 where f is pointer valued, we have to dereference the result. */
2417 if (!se->want_pointer && !byref && sym->attr.pointer)
2418 se->expr = build_fold_indirect_ref (se->expr);
2419
2420 /* f2c calling conventions require a scalar default real function to
2421 return a double precision result. Convert this back to default
2422 real. We only care about the cases that can happen in Fortran 77.
2423 */
2424 if (gfc_option.flag_f2c && sym->ts.type == BT_REAL
2425 && sym->ts.kind == gfc_default_real_kind
2426 && !sym->attr.always_explicit)
2427 se->expr = fold_convert (gfc_get_real_type (sym->ts.kind), se->expr);
2428
2429 /* A pure function may still have side-effects - it may modify its
2430 parameters. */
2431 TREE_SIDE_EFFECTS (se->expr) = 1;
2432 #if 0
2433 if (!sym->attr.pure)
2434 TREE_SIDE_EFFECTS (se->expr) = 1;
2435 #endif
2436
2437 if (byref)
2438 {
2439 /* Add the function call to the pre chain. There is no expression. */
2440 gfc_add_expr_to_block (&se->pre, se->expr);
2441 se->expr = NULL_TREE;
2442
2443 if (!se->direct_byref)
2444 {
2445 if (sym->attr.dimension)
2446 {
2447 if (flag_bounds_check)
2448 {
2449 /* Check the data pointer hasn't been modified. This would
2450 happen in a function returning a pointer. */
2451 tmp = gfc_conv_descriptor_data_get (info->descriptor);
2452 tmp = fold_build2 (NE_EXPR, boolean_type_node,
2453 tmp, info->data);
2454 gfc_trans_runtime_check (tmp, gfc_msg_fault, &se->pre, NULL);
2455 }
2456 se->expr = info->descriptor;
2457 /* Bundle in the string length. */
2458 se->string_length = len;
2459 }
2460 else if (sym->ts.type == BT_CHARACTER)
2461 {
2462 /* Dereference for character pointer results. */
2463 if (sym->attr.pointer || sym->attr.allocatable)
2464 se->expr = build_fold_indirect_ref (var);
2465 else
2466 se->expr = var;
2467
2468 se->string_length = len;
2469 }
2470 else
2471 {
2472 gcc_assert (sym->ts.type == BT_COMPLEX && gfc_option.flag_f2c);
2473 se->expr = build_fold_indirect_ref (var);
2474 }
2475 }
2476 }
2477
2478 /* Follow the function call with the argument post block. */
2479 if (byref)
2480 gfc_add_block_to_block (&se->pre, &post);
2481 else
2482 gfc_add_block_to_block (&se->post, &post);
2483
2484 return has_alternate_specifier;
2485 }
2486
2487
2488 /* Generate code to copy a string. */
2489
2490 static void
2491 gfc_trans_string_copy (stmtblock_t * block, tree dlength, tree dest,
2492 tree slength, tree src)
2493 {
2494 tree tmp, dlen, slen;
2495 tree dsc;
2496 tree ssc;
2497 tree cond;
2498 tree cond2;
2499 tree tmp2;
2500 tree tmp3;
2501 tree tmp4;
2502 stmtblock_t tempblock;
2503
2504 dlen = fold_convert (size_type_node, gfc_evaluate_now (dlength, block));
2505 slen = fold_convert (size_type_node, gfc_evaluate_now (slength, block));
2506
2507 /* Deal with single character specially. */
2508 dsc = gfc_to_single_character (dlen, dest);
2509 ssc = gfc_to_single_character (slen, src);
2510 if (dsc != NULL_TREE && ssc != NULL_TREE)
2511 {
2512 gfc_add_modify_expr (block, dsc, ssc);
2513 return;
2514 }
2515
2516 /* Do nothing if the destination length is zero. */
2517 cond = fold_build2 (GT_EXPR, boolean_type_node, dlen,
2518 build_int_cst (gfc_charlen_type_node, 0));
2519
2520 /* The following code was previously in _gfortran_copy_string:
2521
2522 // The two strings may overlap so we use memmove.
2523 void
2524 copy_string (GFC_INTEGER_4 destlen, char * dest,
2525 GFC_INTEGER_4 srclen, const char * src)
2526 {
2527 if (srclen >= destlen)
2528 {
2529 // This will truncate if too long.
2530 memmove (dest, src, destlen);
2531 }
2532 else
2533 {
2534 memmove (dest, src, srclen);
2535 // Pad with spaces.
2536 memset (&dest[srclen], ' ', destlen - srclen);
2537 }
2538 }
2539
2540 We're now doing it here for better optimization, but the logic
2541 is the same. */
2542
2543 /* Truncate string if source is too long. */
2544 cond2 = fold_build2 (GE_EXPR, boolean_type_node, slen, dlen);
2545 tmp2 = gfc_chainon_list (NULL_TREE, dest);
2546 tmp2 = gfc_chainon_list (tmp2, src);
2547 tmp2 = gfc_chainon_list (tmp2, dlen);
2548 tmp2 = build_function_call_expr (built_in_decls[BUILT_IN_MEMMOVE], tmp2);
2549
2550 /* Else copy and pad with spaces. */
2551 tmp3 = gfc_chainon_list (NULL_TREE, dest);
2552 tmp3 = gfc_chainon_list (tmp3, src);
2553 tmp3 = gfc_chainon_list (tmp3, slen);
2554 tmp3 = build_function_call_expr (built_in_decls[BUILT_IN_MEMMOVE], tmp3);
2555
2556 tmp4 = fold_build2 (PLUS_EXPR, pchar_type_node, dest,
2557 fold_convert (pchar_type_node, slen));
2558 tmp4 = gfc_chainon_list (NULL_TREE, tmp4);
2559 tmp4 = gfc_chainon_list (tmp4, build_int_cst
2560 (gfc_get_int_type (gfc_c_int_kind),
2561 lang_hooks.to_target_charset (' ')));
2562 tmp4 = gfc_chainon_list (tmp4, fold_build2 (MINUS_EXPR, TREE_TYPE(dlen),
2563 dlen, slen));
2564 tmp4 = build_function_call_expr (built_in_decls[BUILT_IN_MEMSET], tmp4);
2565
2566 gfc_init_block (&tempblock);
2567 gfc_add_expr_to_block (&tempblock, tmp3);
2568 gfc_add_expr_to_block (&tempblock, tmp4);
2569 tmp3 = gfc_finish_block (&tempblock);
2570
2571 /* The whole copy_string function is there. */
2572 tmp = fold_build3 (COND_EXPR, void_type_node, cond2, tmp2, tmp3);
2573 tmp = fold_build3 (COND_EXPR, void_type_node, cond, tmp, build_empty_stmt ());
2574 gfc_add_expr_to_block (block, tmp);
2575 }
2576
2577
2578 /* Translate a statement function.
2579 The value of a statement function reference is obtained by evaluating the
2580 expression using the values of the actual arguments for the values of the
2581 corresponding dummy arguments. */
2582
2583 static void
2584 gfc_conv_statement_function (gfc_se * se, gfc_expr * expr)
2585 {
2586 gfc_symbol *sym;
2587 gfc_symbol *fsym;
2588 gfc_formal_arglist *fargs;
2589 gfc_actual_arglist *args;
2590 gfc_se lse;
2591 gfc_se rse;
2592 gfc_saved_var *saved_vars;
2593 tree *temp_vars;
2594 tree type;
2595 tree tmp;
2596 int n;
2597
2598 sym = expr->symtree->n.sym;
2599 args = expr->value.function.actual;
2600 gfc_init_se (&lse, NULL);
2601 gfc_init_se (&rse, NULL);
2602
2603 n = 0;
2604 for (fargs = sym->formal; fargs; fargs = fargs->next)
2605 n++;
2606 saved_vars = (gfc_saved_var *)gfc_getmem (n * sizeof (gfc_saved_var));
2607 temp_vars = (tree *)gfc_getmem (n * sizeof (tree));
2608
2609 for (fargs = sym->formal, n = 0; fargs; fargs = fargs->next, n++)
2610 {
2611 /* Each dummy shall be specified, explicitly or implicitly, to be
2612 scalar. */
2613 gcc_assert (fargs->sym->attr.dimension == 0);
2614 fsym = fargs->sym;
2615
2616 /* Create a temporary to hold the value. */
2617 type = gfc_typenode_for_spec (&fsym->ts);
2618 temp_vars[n] = gfc_create_var (type, fsym->name);
2619
2620 if (fsym->ts.type == BT_CHARACTER)
2621 {
2622 /* Copy string arguments. */
2623 tree arglen;
2624
2625 gcc_assert (fsym->ts.cl && fsym->ts.cl->length
2626 && fsym->ts.cl->length->expr_type == EXPR_CONSTANT);
2627
2628 arglen = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
2629 tmp = gfc_build_addr_expr (build_pointer_type (type),
2630 temp_vars[n]);
2631
2632 gfc_conv_expr (&rse, args->expr);
2633 gfc_conv_string_parameter (&rse);
2634 gfc_add_block_to_block (&se->pre, &lse.pre);
2635 gfc_add_block_to_block (&se->pre, &rse.pre);
2636
2637 gfc_trans_string_copy (&se->pre, arglen, tmp, rse.string_length,
2638 rse.expr);
2639 gfc_add_block_to_block (&se->pre, &lse.post);
2640 gfc_add_block_to_block (&se->pre, &rse.post);
2641 }
2642 else
2643 {
2644 /* For everything else, just evaluate the expression. */
2645 gfc_conv_expr (&lse, args->expr);
2646
2647 gfc_add_block_to_block (&se->pre, &lse.pre);
2648 gfc_add_modify_expr (&se->pre, temp_vars[n], lse.expr);
2649 gfc_add_block_to_block (&se->pre, &lse.post);
2650 }
2651
2652 args = args->next;
2653 }
2654
2655 /* Use the temporary variables in place of the real ones. */
2656 for (fargs = sym->formal, n = 0; fargs; fargs = fargs->next, n++)
2657 gfc_shadow_sym (fargs->sym, temp_vars[n], &saved_vars[n]);
2658
2659 gfc_conv_expr (se, sym->value);
2660
2661 if (sym->ts.type == BT_CHARACTER)
2662 {
2663 gfc_conv_const_charlen (sym->ts.cl);
2664
2665 /* Force the expression to the correct length. */
2666 if (!INTEGER_CST_P (se->string_length)
2667 || tree_int_cst_lt (se->string_length,
2668 sym->ts.cl->backend_decl))
2669 {
2670 type = gfc_get_character_type (sym->ts.kind, sym->ts.cl);
2671 tmp = gfc_create_var (type, sym->name);
2672 tmp = gfc_build_addr_expr (build_pointer_type (type), tmp);
2673 gfc_trans_string_copy (&se->pre, sym->ts.cl->backend_decl, tmp,
2674 se->string_length, se->expr);
2675 se->expr = tmp;
2676 }
2677 se->string_length = sym->ts.cl->backend_decl;
2678 }
2679
2680 /* Restore the original variables. */
2681 for (fargs = sym->formal, n = 0; fargs; fargs = fargs->next, n++)
2682 gfc_restore_sym (fargs->sym, &saved_vars[n]);
2683 gfc_free (saved_vars);
2684 }
2685
2686
2687 /* Translate a function expression. */
2688
2689 static void
2690 gfc_conv_function_expr (gfc_se * se, gfc_expr * expr)
2691 {
2692 gfc_symbol *sym;
2693
2694 if (expr->value.function.isym)
2695 {
2696 gfc_conv_intrinsic_function (se, expr);
2697 return;
2698 }
2699
2700 /* We distinguish statement functions from general functions to improve
2701 runtime performance. */
2702 if (expr->symtree->n.sym->attr.proc == PROC_ST_FUNCTION)
2703 {
2704 gfc_conv_statement_function (se, expr);
2705 return;
2706 }
2707
2708 /* expr.value.function.esym is the resolved (specific) function symbol for
2709 most functions. However this isn't set for dummy procedures. */
2710 sym = expr->value.function.esym;
2711 if (!sym)
2712 sym = expr->symtree->n.sym;
2713 gfc_conv_function_call (se, sym, expr->value.function.actual, NULL_TREE);
2714 }
2715
2716
2717 static void
2718 gfc_conv_array_constructor_expr (gfc_se * se, gfc_expr * expr)
2719 {
2720 gcc_assert (se->ss != NULL && se->ss != gfc_ss_terminator);
2721 gcc_assert (se->ss->expr == expr && se->ss->type == GFC_SS_CONSTRUCTOR);
2722
2723 gfc_conv_tmp_array_ref (se);
2724 gfc_advance_se_ss_chain (se);
2725 }
2726
2727
2728 /* Build a static initializer. EXPR is the expression for the initial value.
2729 The other parameters describe the variable of the component being
2730 initialized. EXPR may be null. */
2731
2732 tree
2733 gfc_conv_initializer (gfc_expr * expr, gfc_typespec * ts, tree type,
2734 bool array, bool pointer)
2735 {
2736 gfc_se se;
2737
2738 if (!(expr || pointer))
2739 return NULL_TREE;
2740
2741 if (array)
2742 {
2743 /* Arrays need special handling. */
2744 if (pointer)
2745 return gfc_build_null_descriptor (type);
2746 else
2747 return gfc_conv_array_initializer (type, expr);
2748 }
2749 else if (pointer)
2750 return fold_convert (type, null_pointer_node);
2751 else
2752 {
2753 switch (ts->type)
2754 {
2755 case BT_DERIVED:
2756 gfc_init_se (&se, NULL);
2757 gfc_conv_structure (&se, expr, 1);
2758 return se.expr;
2759
2760 case BT_CHARACTER:
2761 return gfc_conv_string_init (ts->cl->backend_decl,expr);
2762
2763 default:
2764 gfc_init_se (&se, NULL);
2765 gfc_conv_constant (&se, expr);
2766 return se.expr;
2767 }
2768 }
2769 }
2770
2771 static tree
2772 gfc_trans_subarray_assign (tree dest, gfc_component * cm, gfc_expr * expr)
2773 {
2774 gfc_se rse;
2775 gfc_se lse;
2776 gfc_ss *rss;
2777 gfc_ss *lss;
2778 stmtblock_t body;
2779 stmtblock_t block;
2780 gfc_loopinfo loop;
2781 int n;
2782 tree tmp;
2783
2784 gfc_start_block (&block);
2785
2786 /* Initialize the scalarizer. */
2787 gfc_init_loopinfo (&loop);
2788
2789 gfc_init_se (&lse, NULL);
2790 gfc_init_se (&rse, NULL);
2791
2792 /* Walk the rhs. */
2793 rss = gfc_walk_expr (expr);
2794 if (rss == gfc_ss_terminator)
2795 {
2796 /* The rhs is scalar. Add a ss for the expression. */
2797 rss = gfc_get_ss ();
2798 rss->next = gfc_ss_terminator;
2799 rss->type = GFC_SS_SCALAR;
2800 rss->expr = expr;
2801 }
2802
2803 /* Create a SS for the destination. */
2804 lss = gfc_get_ss ();
2805 lss->type = GFC_SS_COMPONENT;
2806 lss->expr = NULL;
2807 lss->shape = gfc_get_shape (cm->as->rank);
2808 lss->next = gfc_ss_terminator;
2809 lss->data.info.dimen = cm->as->rank;
2810 lss->data.info.descriptor = dest;
2811 lss->data.info.data = gfc_conv_array_data (dest);
2812 lss->data.info.offset = gfc_conv_array_offset (dest);
2813 for (n = 0; n < cm->as->rank; n++)
2814 {
2815 lss->data.info.dim[n] = n;
2816 lss->data.info.start[n] = gfc_conv_array_lbound (dest, n);
2817 lss->data.info.stride[n] = gfc_index_one_node;
2818
2819 mpz_init (lss->shape[n]);
2820 mpz_sub (lss->shape[n], cm->as->upper[n]->value.integer,
2821 cm->as->lower[n]->value.integer);
2822 mpz_add_ui (lss->shape[n], lss->shape[n], 1);
2823 }
2824
2825 /* Associate the SS with the loop. */
2826 gfc_add_ss_to_loop (&loop, lss);
2827 gfc_add_ss_to_loop (&loop, rss);
2828
2829 /* Calculate the bounds of the scalarization. */
2830 gfc_conv_ss_startstride (&loop);
2831
2832 /* Setup the scalarizing loops. */
2833 gfc_conv_loop_setup (&loop);
2834
2835 /* Setup the gfc_se structures. */
2836 gfc_copy_loopinfo_to_se (&lse, &loop);
2837 gfc_copy_loopinfo_to_se (&rse, &loop);
2838
2839 rse.ss = rss;
2840 gfc_mark_ss_chain_used (rss, 1);
2841 lse.ss = lss;
2842 gfc_mark_ss_chain_used (lss, 1);
2843
2844 /* Start the scalarized loop body. */
2845 gfc_start_scalarized_body (&loop, &body);
2846
2847 gfc_conv_tmp_array_ref (&lse);
2848 if (cm->ts.type == BT_CHARACTER)
2849 lse.string_length = cm->ts.cl->backend_decl;
2850
2851 gfc_conv_expr (&rse, expr);
2852
2853 tmp = gfc_trans_scalar_assign (&lse, &rse, cm->ts, true, false);
2854 gfc_add_expr_to_block (&body, tmp);
2855
2856 gcc_assert (rse.ss == gfc_ss_terminator);
2857
2858 /* Generate the copying loops. */
2859 gfc_trans_scalarizing_loops (&loop, &body);
2860
2861 /* Wrap the whole thing up. */
2862 gfc_add_block_to_block (&block, &loop.pre);
2863 gfc_add_block_to_block (&block, &loop.post);
2864
2865 for (n = 0; n < cm->as->rank; n++)
2866 mpz_clear (lss->shape[n]);
2867 gfc_free (lss->shape);
2868
2869 gfc_cleanup_loop (&loop);
2870
2871 return gfc_finish_block (&block);
2872 }
2873
2874
2875 /* Assign a single component of a derived type constructor. */
2876
2877 static tree
2878 gfc_trans_subcomponent_assign (tree dest, gfc_component * cm, gfc_expr * expr)
2879 {
2880 gfc_se se;
2881 gfc_se lse;
2882 gfc_ss *rss;
2883 stmtblock_t block;
2884 tree tmp;
2885 tree offset;
2886 int n;
2887
2888 gfc_start_block (&block);
2889
2890 if (cm->pointer)
2891 {
2892 gfc_init_se (&se, NULL);
2893 /* Pointer component. */
2894 if (cm->dimension)
2895 {
2896 /* Array pointer. */
2897 if (expr->expr_type == EXPR_NULL)
2898 gfc_conv_descriptor_data_set (&block, dest, null_pointer_node);
2899 else
2900 {
2901 rss = gfc_walk_expr (expr);
2902 se.direct_byref = 1;
2903 se.expr = dest;
2904 gfc_conv_expr_descriptor (&se, expr, rss);
2905 gfc_add_block_to_block (&block, &se.pre);
2906 gfc_add_block_to_block (&block, &se.post);
2907 }
2908 }
2909 else
2910 {
2911 /* Scalar pointers. */
2912 se.want_pointer = 1;
2913 gfc_conv_expr (&se, expr);
2914 gfc_add_block_to_block (&block, &se.pre);
2915 gfc_add_modify_expr (&block, dest,
2916 fold_convert (TREE_TYPE (dest), se.expr));
2917 gfc_add_block_to_block (&block, &se.post);
2918 }
2919 }
2920 else if (cm->dimension)
2921 {
2922 if (cm->allocatable && expr->expr_type == EXPR_NULL)
2923 gfc_conv_descriptor_data_set (&block, dest, null_pointer_node);
2924 else if (cm->allocatable)
2925 {
2926 tree tmp2;
2927
2928 gfc_init_se (&se, NULL);
2929
2930 rss = gfc_walk_expr (expr);
2931 se.want_pointer = 0;
2932 gfc_conv_expr_descriptor (&se, expr, rss);
2933 gfc_add_block_to_block (&block, &se.pre);
2934
2935 tmp = fold_convert (TREE_TYPE (dest), se.expr);
2936 gfc_add_modify_expr (&block, dest, tmp);
2937
2938 if (cm->ts.type == BT_DERIVED && cm->ts.derived->attr.alloc_comp)
2939 tmp = gfc_copy_alloc_comp (cm->ts.derived, se.expr, dest,
2940 cm->as->rank);
2941 else
2942 tmp = gfc_duplicate_allocatable (dest, se.expr,
2943 TREE_TYPE(cm->backend_decl),
2944 cm->as->rank);
2945
2946 gfc_add_expr_to_block (&block, tmp);
2947
2948 gfc_add_block_to_block (&block, &se.post);
2949 gfc_conv_descriptor_data_set (&block, se.expr, null_pointer_node);
2950
2951 /* Shift the lbound and ubound of temporaries to being unity, rather
2952 than zero, based. Calculate the offset for all cases. */
2953 offset = gfc_conv_descriptor_offset (dest);
2954 gfc_add_modify_expr (&block, offset, gfc_index_zero_node);
2955 tmp2 =gfc_create_var (gfc_array_index_type, NULL);
2956 for (n = 0; n < expr->rank; n++)
2957 {
2958 if (expr->expr_type != EXPR_VARIABLE
2959 && expr->expr_type != EXPR_CONSTANT)
2960 {
2961 tmp = gfc_conv_descriptor_ubound (dest, gfc_rank_cst[n]);
2962 gfc_add_modify_expr (&block, tmp,
2963 fold_build2 (PLUS_EXPR,
2964 gfc_array_index_type,
2965 tmp, gfc_index_one_node));
2966 tmp = gfc_conv_descriptor_lbound (dest, gfc_rank_cst[n]);
2967 gfc_add_modify_expr (&block, tmp, gfc_index_one_node);
2968 }
2969 tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
2970 gfc_conv_descriptor_lbound (dest,
2971 gfc_rank_cst[n]),
2972 gfc_conv_descriptor_stride (dest,
2973 gfc_rank_cst[n]));
2974 gfc_add_modify_expr (&block, tmp2, tmp);
2975 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type, offset, tmp2);
2976 gfc_add_modify_expr (&block, offset, tmp);
2977 }
2978 }
2979 else
2980 {
2981 tmp = gfc_trans_subarray_assign (dest, cm, expr);
2982 gfc_add_expr_to_block (&block, tmp);
2983 }
2984 }
2985 else if (expr->ts.type == BT_DERIVED)
2986 {
2987 if (expr->expr_type != EXPR_STRUCTURE)
2988 {
2989 gfc_init_se (&se, NULL);
2990 gfc_conv_expr (&se, expr);
2991 gfc_add_modify_expr (&block, dest,
2992 fold_convert (TREE_TYPE (dest), se.expr));
2993 }
2994 else
2995 {
2996 /* Nested constructors. */
2997 tmp = gfc_trans_structure_assign (dest, expr);
2998 gfc_add_expr_to_block (&block, tmp);
2999 }
3000 }
3001 else
3002 {
3003 /* Scalar component. */
3004 gfc_init_se (&se, NULL);
3005 gfc_init_se (&lse, NULL);
3006
3007 gfc_conv_expr (&se, expr);
3008 if (cm->ts.type == BT_CHARACTER)
3009 lse.string_length = cm->ts.cl->backend_decl;
3010 lse.expr = dest;
3011 tmp = gfc_trans_scalar_assign (&lse, &se, cm->ts, true, false);
3012 gfc_add_expr_to_block (&block, tmp);
3013 }
3014 return gfc_finish_block (&block);
3015 }
3016
3017 /* Assign a derived type constructor to a variable. */
3018
3019 static tree
3020 gfc_trans_structure_assign (tree dest, gfc_expr * expr)
3021 {
3022 gfc_constructor *c;
3023 gfc_component *cm;
3024 stmtblock_t block;
3025 tree field;
3026 tree tmp;
3027
3028 gfc_start_block (&block);
3029 cm = expr->ts.derived->components;
3030 for (c = expr->value.constructor; c; c = c->next, cm = cm->next)
3031 {
3032 /* Skip absent members in default initializers. */
3033 if (!c->expr)
3034 continue;
3035
3036 field = cm->backend_decl;
3037 tmp = build3 (COMPONENT_REF, TREE_TYPE (field), dest, field, NULL_TREE);
3038 tmp = gfc_trans_subcomponent_assign (tmp, cm, c->expr);
3039 gfc_add_expr_to_block (&block, tmp);
3040 }
3041 return gfc_finish_block (&block);
3042 }
3043
3044 /* Build an expression for a constructor. If init is nonzero then
3045 this is part of a static variable initializer. */
3046
3047 void
3048 gfc_conv_structure (gfc_se * se, gfc_expr * expr, int init)
3049 {
3050 gfc_constructor *c;
3051 gfc_component *cm;
3052 tree val;
3053 tree type;
3054 tree tmp;
3055 VEC(constructor_elt,gc) *v = NULL;
3056
3057 gcc_assert (se->ss == NULL);
3058 gcc_assert (expr->expr_type == EXPR_STRUCTURE);
3059 type = gfc_typenode_for_spec (&expr->ts);
3060
3061 if (!init)
3062 {
3063 /* Create a temporary variable and fill it in. */
3064 se->expr = gfc_create_var (type, expr->ts.derived->name);
3065 tmp = gfc_trans_structure_assign (se->expr, expr);
3066 gfc_add_expr_to_block (&se->pre, tmp);
3067 return;
3068 }
3069
3070 cm = expr->ts.derived->components;
3071
3072 for (c = expr->value.constructor; c; c = c->next, cm = cm->next)
3073 {
3074 /* Skip absent members in default initializers and allocatable
3075 components. Although the latter have a default initializer
3076 of EXPR_NULL,... by default, the static nullify is not needed
3077 since this is done every time we come into scope. */
3078 if (!c->expr || cm->allocatable)
3079 continue;
3080
3081 val = gfc_conv_initializer (c->expr, &cm->ts,
3082 TREE_TYPE (cm->backend_decl), cm->dimension, cm->pointer);
3083
3084 /* Append it to the constructor list. */
3085 CONSTRUCTOR_APPEND_ELT (v, cm->backend_decl, val);
3086 }
3087 se->expr = build_constructor (type, v);
3088 }
3089
3090
3091 /* Translate a substring expression. */
3092
3093 static void
3094 gfc_conv_substring_expr (gfc_se * se, gfc_expr * expr)
3095 {
3096 gfc_ref *ref;
3097
3098 ref = expr->ref;
3099
3100 gcc_assert (ref->type == REF_SUBSTRING);
3101
3102 se->expr = gfc_build_string_const(expr->value.character.length,
3103 expr->value.character.string);
3104 se->string_length = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (se->expr)));
3105 TYPE_STRING_FLAG (TREE_TYPE (se->expr))=1;
3106
3107 gfc_conv_substring(se,ref,expr->ts.kind,NULL,&expr->where);
3108 }
3109
3110
3111 /* Entry point for expression translation. Evaluates a scalar quantity.
3112 EXPR is the expression to be translated, and SE is the state structure if
3113 called from within the scalarized. */
3114
3115 void
3116 gfc_conv_expr (gfc_se * se, gfc_expr * expr)
3117 {
3118 if (se->ss && se->ss->expr == expr
3119 && (se->ss->type == GFC_SS_SCALAR || se->ss->type == GFC_SS_REFERENCE))
3120 {
3121 /* Substitute a scalar expression evaluated outside the scalarization
3122 loop. */
3123 se->expr = se->ss->data.scalar.expr;
3124 se->string_length = se->ss->string_length;
3125 gfc_advance_se_ss_chain (se);
3126 return;
3127 }
3128
3129 switch (expr->expr_type)
3130 {
3131 case EXPR_OP:
3132 gfc_conv_expr_op (se, expr);
3133 break;
3134
3135 case EXPR_FUNCTION:
3136 gfc_conv_function_expr (se, expr);
3137 break;
3138
3139 case EXPR_CONSTANT:
3140 gfc_conv_constant (se, expr);
3141 break;
3142
3143 case EXPR_VARIABLE:
3144 gfc_conv_variable (se, expr);
3145 break;
3146
3147 case EXPR_NULL:
3148 se->expr = null_pointer_node;
3149 break;
3150
3151 case EXPR_SUBSTRING:
3152 gfc_conv_substring_expr (se, expr);
3153 break;
3154
3155 case EXPR_STRUCTURE:
3156 gfc_conv_structure (se, expr, 0);
3157 break;
3158
3159 case EXPR_ARRAY:
3160 gfc_conv_array_constructor_expr (se, expr);
3161 break;
3162
3163 default:
3164 gcc_unreachable ();
3165 break;
3166 }
3167 }
3168
3169 /* Like gfc_conv_expr_val, but the value is also suitable for use in the lhs
3170 of an assignment. */
3171 void
3172 gfc_conv_expr_lhs (gfc_se * se, gfc_expr * expr)
3173 {
3174 gfc_conv_expr (se, expr);
3175 /* All numeric lvalues should have empty post chains. If not we need to
3176 figure out a way of rewriting an lvalue so that it has no post chain. */
3177 gcc_assert (expr->ts.type == BT_CHARACTER || !se->post.head);
3178 }
3179
3180 /* Like gfc_conv_expr, but the POST block is guaranteed to be empty for
3181 numeric expressions. Used for scalar values where inserting cleanup code
3182 is inconvenient. */
3183 void
3184 gfc_conv_expr_val (gfc_se * se, gfc_expr * expr)
3185 {
3186 tree val;
3187
3188 gcc_assert (expr->ts.type != BT_CHARACTER);
3189 gfc_conv_expr (se, expr);
3190 if (se->post.head)
3191 {
3192 val = gfc_create_var (TREE_TYPE (se->expr), NULL);
3193 gfc_add_modify_expr (&se->pre, val, se->expr);
3194 se->expr = val;
3195 gfc_add_block_to_block (&se->pre, &se->post);
3196 }
3197 }
3198
3199 /* Helper to translate and expression and convert it to a particular type. */
3200 void
3201 gfc_conv_expr_type (gfc_se * se, gfc_expr * expr, tree type)
3202 {
3203 gfc_conv_expr_val (se, expr);
3204 se->expr = convert (type, se->expr);
3205 }
3206
3207
3208 /* Converts an expression so that it can be passed by reference. Scalar
3209 values only. */
3210
3211 void
3212 gfc_conv_expr_reference (gfc_se * se, gfc_expr * expr)
3213 {
3214 tree var;
3215
3216 if (se->ss && se->ss->expr == expr
3217 && se->ss->type == GFC_SS_REFERENCE)
3218 {
3219 se->expr = se->ss->data.scalar.expr;
3220 se->string_length = se->ss->string_length;
3221 gfc_advance_se_ss_chain (se);
3222 return;
3223 }
3224
3225 if (expr->ts.type == BT_CHARACTER)
3226 {
3227 gfc_conv_expr (se, expr);
3228 gfc_conv_string_parameter (se);
3229 return;
3230 }
3231
3232 if (expr->expr_type == EXPR_VARIABLE)
3233 {
3234 se->want_pointer = 1;
3235 gfc_conv_expr (se, expr);
3236 if (se->post.head)
3237 {
3238 var = gfc_create_var (TREE_TYPE (se->expr), NULL);
3239 gfc_add_modify_expr (&se->pre, var, se->expr);
3240 gfc_add_block_to_block (&se->pre, &se->post);
3241 se->expr = var;
3242 }
3243 return;
3244 }
3245
3246 gfc_conv_expr (se, expr);
3247
3248 /* Create a temporary var to hold the value. */
3249 if (TREE_CONSTANT (se->expr))
3250 {
3251 tree tmp = se->expr;
3252 STRIP_TYPE_NOPS (tmp);
3253 var = build_decl (CONST_DECL, NULL, TREE_TYPE (tmp));
3254 DECL_INITIAL (var) = tmp;
3255 TREE_STATIC (var) = 1;
3256 pushdecl (var);
3257 }
3258 else
3259 {
3260 var = gfc_create_var (TREE_TYPE (se->expr), NULL);
3261 gfc_add_modify_expr (&se->pre, var, se->expr);
3262 }
3263 gfc_add_block_to_block (&se->pre, &se->post);
3264
3265 /* Take the address of that value. */
3266 se->expr = build_fold_addr_expr (var);
3267 }
3268
3269
3270 tree
3271 gfc_trans_pointer_assign (gfc_code * code)
3272 {
3273 return gfc_trans_pointer_assignment (code->expr, code->expr2);
3274 }
3275
3276
3277 /* Generate code for a pointer assignment. */
3278
3279 tree
3280 gfc_trans_pointer_assignment (gfc_expr * expr1, gfc_expr * expr2)
3281 {
3282 gfc_se lse;
3283 gfc_se rse;
3284 gfc_ss *lss;
3285 gfc_ss *rss;
3286 stmtblock_t block;
3287 tree desc;
3288 tree tmp;
3289
3290 gfc_start_block (&block);
3291
3292 gfc_init_se (&lse, NULL);
3293
3294 lss = gfc_walk_expr (expr1);
3295 rss = gfc_walk_expr (expr2);
3296 if (lss == gfc_ss_terminator)
3297 {
3298 /* Scalar pointers. */
3299 lse.want_pointer = 1;
3300 gfc_conv_expr (&lse, expr1);
3301 gcc_assert (rss == gfc_ss_terminator);
3302 gfc_init_se (&rse, NULL);
3303 rse.want_pointer = 1;
3304 gfc_conv_expr (&rse, expr2);
3305 gfc_add_block_to_block (&block, &lse.pre);
3306 gfc_add_block_to_block (&block, &rse.pre);
3307 gfc_add_modify_expr (&block, lse.expr,
3308 fold_convert (TREE_TYPE (lse.expr), rse.expr));
3309 gfc_add_block_to_block (&block, &rse.post);
3310 gfc_add_block_to_block (&block, &lse.post);
3311 }
3312 else
3313 {
3314 /* Array pointer. */
3315 gfc_conv_expr_descriptor (&lse, expr1, lss);
3316 switch (expr2->expr_type)
3317 {
3318 case EXPR_NULL:
3319 /* Just set the data pointer to null. */
3320 gfc_conv_descriptor_data_set (&lse.pre, lse.expr, null_pointer_node);
3321 break;
3322
3323 case EXPR_VARIABLE:
3324 /* Assign directly to the pointer's descriptor. */
3325 lse.direct_byref = 1;
3326 gfc_conv_expr_descriptor (&lse, expr2, rss);
3327 break;
3328
3329 default:
3330 /* Assign to a temporary descriptor and then copy that
3331 temporary to the pointer. */
3332 desc = lse.expr;
3333 tmp = gfc_create_var (TREE_TYPE (desc), "ptrtemp");
3334
3335 lse.expr = tmp;
3336 lse.direct_byref = 1;
3337 gfc_conv_expr_descriptor (&lse, expr2, rss);
3338 gfc_add_modify_expr (&lse.pre, desc, tmp);
3339 break;
3340 }
3341 gfc_add_block_to_block (&block, &lse.pre);
3342 gfc_add_block_to_block (&block, &lse.post);
3343 }
3344 return gfc_finish_block (&block);
3345 }
3346
3347
3348 /* Makes sure se is suitable for passing as a function string parameter. */
3349 /* TODO: Need to check all callers fo this function. It may be abused. */
3350
3351 void
3352 gfc_conv_string_parameter (gfc_se * se)
3353 {
3354 tree type;
3355
3356 if (TREE_CODE (se->expr) == STRING_CST)
3357 {
3358 se->expr = gfc_build_addr_expr (pchar_type_node, se->expr);
3359 return;
3360 }
3361
3362 type = TREE_TYPE (se->expr);
3363 if (TYPE_STRING_FLAG (type))
3364 {
3365 gcc_assert (TREE_CODE (se->expr) != INDIRECT_REF);
3366 se->expr = gfc_build_addr_expr (pchar_type_node, se->expr);
3367 }
3368
3369 gcc_assert (POINTER_TYPE_P (TREE_TYPE (se->expr)));
3370 gcc_assert (se->string_length
3371 && TREE_CODE (TREE_TYPE (se->string_length)) == INTEGER_TYPE);
3372 }
3373
3374
3375 /* Generate code for assignment of scalar variables. Includes character
3376 strings and derived types with allocatable components. */
3377
3378 tree
3379 gfc_trans_scalar_assign (gfc_se * lse, gfc_se * rse, gfc_typespec ts,
3380 bool l_is_temp, bool r_is_var)
3381 {
3382 stmtblock_t block;
3383 tree tmp;
3384 tree cond;
3385
3386 gfc_init_block (&block);
3387
3388 if (ts.type == BT_CHARACTER)
3389 {
3390 gcc_assert (lse->string_length != NULL_TREE
3391 && rse->string_length != NULL_TREE);
3392
3393 gfc_conv_string_parameter (lse);
3394 gfc_conv_string_parameter (rse);
3395
3396 gfc_add_block_to_block (&block, &lse->pre);
3397 gfc_add_block_to_block (&block, &rse->pre);
3398
3399 gfc_trans_string_copy (&block, lse->string_length, lse->expr,
3400 rse->string_length, rse->expr);
3401 }
3402 else if (ts.type == BT_DERIVED && ts.derived->attr.alloc_comp)
3403 {
3404 cond = NULL_TREE;
3405
3406 /* Are the rhs and the lhs the same? */
3407 if (r_is_var)
3408 {
3409 cond = fold_build2 (EQ_EXPR, boolean_type_node,
3410 build_fold_addr_expr (lse->expr),
3411 build_fold_addr_expr (rse->expr));
3412 cond = gfc_evaluate_now (cond, &lse->pre);
3413 }
3414
3415 /* Deallocate the lhs allocated components as long as it is not
3416 the same as the rhs. */
3417 if (!l_is_temp)
3418 {
3419 tmp = gfc_deallocate_alloc_comp (ts.derived, lse->expr, 0);
3420 if (r_is_var)
3421 tmp = build3_v (COND_EXPR, cond, build_empty_stmt (), tmp);
3422 gfc_add_expr_to_block (&lse->pre, tmp);
3423 }
3424
3425 gfc_add_block_to_block (&block, &lse->pre);
3426 gfc_add_block_to_block (&block, &rse->pre);
3427
3428 gfc_add_modify_expr (&block, lse->expr,
3429 fold_convert (TREE_TYPE (lse->expr), rse->expr));
3430
3431 /* Do a deep copy if the rhs is a variable, if it is not the
3432 same as the lhs. */
3433 if (r_is_var)
3434 {
3435 tmp = gfc_copy_alloc_comp (ts.derived, rse->expr, lse->expr, 0);
3436 tmp = build3_v (COND_EXPR, cond, build_empty_stmt (), tmp);
3437 gfc_add_expr_to_block (&block, tmp);
3438 }
3439 }
3440 else
3441 {
3442 gfc_add_block_to_block (&block, &lse->pre);
3443 gfc_add_block_to_block (&block, &rse->pre);
3444
3445 gfc_add_modify_expr (&block, lse->expr,
3446 fold_convert (TREE_TYPE (lse->expr), rse->expr));
3447 }
3448
3449 gfc_add_block_to_block (&block, &lse->post);
3450 gfc_add_block_to_block (&block, &rse->post);
3451
3452 return gfc_finish_block (&block);
3453 }
3454
3455
3456 /* Try to translate array(:) = func (...), where func is a transformational
3457 array function, without using a temporary. Returns NULL is this isn't the
3458 case. */
3459
3460 static tree
3461 gfc_trans_arrayfunc_assign (gfc_expr * expr1, gfc_expr * expr2)
3462 {
3463 gfc_se se;
3464 gfc_ss *ss;
3465 gfc_ref * ref;
3466 bool seen_array_ref;
3467
3468 /* The caller has already checked rank>0 and expr_type == EXPR_FUNCTION. */
3469 if (expr2->value.function.isym && !gfc_is_intrinsic_libcall (expr2))
3470 return NULL;
3471
3472 /* Elemental functions don't need a temporary anyway. */
3473 if (expr2->value.function.esym != NULL
3474 && expr2->value.function.esym->attr.elemental)
3475 return NULL;
3476
3477 /* Fail if EXPR1 can't be expressed as a descriptor. */
3478 if (gfc_ref_needs_temporary_p (expr1->ref))
3479 return NULL;
3480
3481 /* Functions returning pointers need temporaries. */
3482 if (expr2->symtree->n.sym->attr.pointer
3483 || expr2->symtree->n.sym->attr.allocatable)
3484 return NULL;
3485
3486 /* Character array functions need temporaries unless the
3487 character lengths are the same. */
3488 if (expr2->ts.type == BT_CHARACTER && expr2->rank > 0)
3489 {
3490 if (expr1->ts.cl->length == NULL
3491 || expr1->ts.cl->length->expr_type != EXPR_CONSTANT)
3492 return NULL;
3493
3494 if (expr2->ts.cl->length == NULL
3495 || expr2->ts.cl->length->expr_type != EXPR_CONSTANT)
3496 return NULL;
3497
3498 if (mpz_cmp (expr1->ts.cl->length->value.integer,
3499 expr2->ts.cl->length->value.integer) != 0)
3500 return NULL;
3501 }
3502
3503 /* Check that no LHS component references appear during an array
3504 reference. This is needed because we do not have the means to
3505 span any arbitrary stride with an array descriptor. This check
3506 is not needed for the rhs because the function result has to be
3507 a complete type. */
3508 seen_array_ref = false;
3509 for (ref = expr1->ref; ref; ref = ref->next)
3510 {
3511 if (ref->type == REF_ARRAY)
3512 seen_array_ref= true;
3513 else if (ref->type == REF_COMPONENT && seen_array_ref)
3514 return NULL;
3515 }
3516
3517 /* Check for a dependency. */
3518 if (gfc_check_fncall_dependency (expr1, INTENT_OUT,
3519 expr2->value.function.esym,
3520 expr2->value.function.actual))
3521 return NULL;
3522
3523 /* The frontend doesn't seem to bother filling in expr->symtree for intrinsic
3524 functions. */
3525 gcc_assert (expr2->value.function.isym
3526 || (gfc_return_by_reference (expr2->value.function.esym)
3527 && expr2->value.function.esym->result->attr.dimension));
3528
3529 ss = gfc_walk_expr (expr1);
3530 gcc_assert (ss != gfc_ss_terminator);
3531 gfc_init_se (&se, NULL);
3532 gfc_start_block (&se.pre);
3533 se.want_pointer = 1;
3534
3535 gfc_conv_array_parameter (&se, expr1, ss, 0);
3536
3537 se.direct_byref = 1;
3538 se.ss = gfc_walk_expr (expr2);
3539 gcc_assert (se.ss != gfc_ss_terminator);
3540 gfc_conv_function_expr (&se, expr2);
3541 gfc_add_block_to_block (&se.pre, &se.post);
3542
3543 return gfc_finish_block (&se.pre);
3544 }
3545
3546 /* Determine whether the given EXPR_CONSTANT is a zero initializer. */
3547
3548 static bool
3549 is_zero_initializer_p (gfc_expr * expr)
3550 {
3551 if (expr->expr_type != EXPR_CONSTANT)
3552 return false;
3553 /* We ignore Hollerith constants for the time being. */
3554 if (expr->from_H)
3555 return false;
3556
3557 switch (expr->ts.type)
3558 {
3559 case BT_INTEGER:
3560 return mpz_cmp_si (expr->value.integer, 0) == 0;
3561
3562 case BT_REAL:
3563 return mpfr_zero_p (expr->value.real)
3564 && MPFR_SIGN (expr->value.real) >= 0;
3565
3566 case BT_LOGICAL:
3567 return expr->value.logical == 0;
3568
3569 case BT_COMPLEX:
3570 return mpfr_zero_p (expr->value.complex.r)
3571 && MPFR_SIGN (expr->value.complex.r) >= 0
3572 && mpfr_zero_p (expr->value.complex.i)
3573 && MPFR_SIGN (expr->value.complex.i) >= 0;
3574
3575 default:
3576 break;
3577 }
3578 return false;
3579 }
3580
3581 /* Try to efficiently translate array(:) = 0. Return NULL if this
3582 can't be done. */
3583
3584 static tree
3585 gfc_trans_zero_assign (gfc_expr * expr)
3586 {
3587 tree dest, len, type;
3588 tree tmp, args;
3589 gfc_symbol *sym;
3590
3591 sym = expr->symtree->n.sym;
3592 dest = gfc_get_symbol_decl (sym);
3593
3594 type = TREE_TYPE (dest);
3595 if (POINTER_TYPE_P (type))
3596 type = TREE_TYPE (type);
3597 if (!GFC_ARRAY_TYPE_P (type))
3598 return NULL_TREE;
3599
3600 /* Determine the length of the array. */
3601 len = GFC_TYPE_ARRAY_SIZE (type);
3602 if (!len || TREE_CODE (len) != INTEGER_CST)
3603 return NULL_TREE;
3604
3605 len = fold_build2 (MULT_EXPR, gfc_array_index_type, len,
3606 TYPE_SIZE_UNIT (gfc_get_element_type (type)));
3607
3608 /* Convert arguments to the correct types. */
3609 if (!POINTER_TYPE_P (TREE_TYPE (dest)))
3610 dest = gfc_build_addr_expr (pvoid_type_node, dest);
3611 else
3612 dest = fold_convert (pvoid_type_node, dest);
3613 len = fold_convert (size_type_node, len);
3614
3615 /* Construct call to __builtin_memset. */
3616 args = build_tree_list (NULL_TREE, len);
3617 args = tree_cons (NULL_TREE, integer_zero_node, args);
3618 args = tree_cons (NULL_TREE, dest, args);
3619 tmp = build_function_call_expr (built_in_decls[BUILT_IN_MEMSET], args);
3620 return fold_convert (void_type_node, tmp);
3621 }
3622
3623
3624 /* Helper for gfc_trans_array_copy and gfc_trans_array_constructor_copy
3625 that constructs the call to __builtin_memcpy. */
3626
3627 static tree
3628 gfc_build_memcpy_call (tree dst, tree src, tree len)
3629 {
3630 tree tmp, args;
3631
3632 /* Convert arguments to the correct types. */
3633 if (!POINTER_TYPE_P (TREE_TYPE (dst)))
3634 dst = gfc_build_addr_expr (pvoid_type_node, dst);
3635 else
3636 dst = fold_convert (pvoid_type_node, dst);
3637
3638 if (!POINTER_TYPE_P (TREE_TYPE (src)))
3639 src = gfc_build_addr_expr (pvoid_type_node, src);
3640 else
3641 src = fold_convert (pvoid_type_node, src);
3642
3643 len = fold_convert (size_type_node, len);
3644
3645 /* Construct call to __builtin_memcpy. */
3646 args = build_tree_list (NULL_TREE, len);
3647 args = tree_cons (NULL_TREE, src, args);
3648 args = tree_cons (NULL_TREE, dst, args);
3649 tmp = build_function_call_expr (built_in_decls[BUILT_IN_MEMCPY], args);
3650 return fold_convert (void_type_node, tmp);
3651 }
3652
3653
3654 /* Try to efficiently translate dst(:) = src(:). Return NULL if this
3655 can't be done. EXPR1 is the destination/lhs and EXPR2 is the
3656 source/rhs, both are gfc_full_array_ref_p which have been checked for
3657 dependencies. */
3658
3659 static tree
3660 gfc_trans_array_copy (gfc_expr * expr1, gfc_expr * expr2)
3661 {
3662 tree dst, dlen, dtype;
3663 tree src, slen, stype;
3664
3665 dst = gfc_get_symbol_decl (expr1->symtree->n.sym);
3666 src = gfc_get_symbol_decl (expr2->symtree->n.sym);
3667
3668 dtype = TREE_TYPE (dst);
3669 if (POINTER_TYPE_P (dtype))
3670 dtype = TREE_TYPE (dtype);
3671 stype = TREE_TYPE (src);
3672 if (POINTER_TYPE_P (stype))
3673 stype = TREE_TYPE (stype);
3674
3675 if (!GFC_ARRAY_TYPE_P (dtype) || !GFC_ARRAY_TYPE_P (stype))
3676 return NULL_TREE;
3677
3678 /* Determine the lengths of the arrays. */
3679 dlen = GFC_TYPE_ARRAY_SIZE (dtype);
3680 if (!dlen || TREE_CODE (dlen) != INTEGER_CST)
3681 return NULL_TREE;
3682 dlen = fold_build2 (MULT_EXPR, gfc_array_index_type, dlen,
3683 TYPE_SIZE_UNIT (gfc_get_element_type (dtype)));
3684
3685 slen = GFC_TYPE_ARRAY_SIZE (stype);
3686 if (!slen || TREE_CODE (slen) != INTEGER_CST)
3687 return NULL_TREE;
3688 slen = fold_build2 (MULT_EXPR, gfc_array_index_type, slen,
3689 TYPE_SIZE_UNIT (gfc_get_element_type (stype)));
3690
3691 /* Sanity check that they are the same. This should always be
3692 the case, as we should already have checked for conformance. */
3693 if (!tree_int_cst_equal (slen, dlen))
3694 return NULL_TREE;
3695
3696 return gfc_build_memcpy_call (dst, src, dlen);
3697 }
3698
3699
3700 /* Try to efficiently translate array(:) = (/ ... /). Return NULL if
3701 this can't be done. EXPR1 is the destination/lhs for which
3702 gfc_full_array_ref_p is true, and EXPR2 is the source/rhs. */
3703
3704 static tree
3705 gfc_trans_array_constructor_copy (gfc_expr * expr1, gfc_expr * expr2)
3706 {
3707 unsigned HOST_WIDE_INT nelem;
3708 tree dst, dtype;
3709 tree src, stype;
3710 tree len;
3711
3712 nelem = gfc_constant_array_constructor_p (expr2->value.constructor);
3713 if (nelem == 0)
3714 return NULL_TREE;
3715
3716 dst = gfc_get_symbol_decl (expr1->symtree->n.sym);
3717 dtype = TREE_TYPE (dst);
3718 if (POINTER_TYPE_P (dtype))
3719 dtype = TREE_TYPE (dtype);
3720 if (!GFC_ARRAY_TYPE_P (dtype))
3721 return NULL_TREE;
3722
3723 /* Determine the lengths of the array. */
3724 len = GFC_TYPE_ARRAY_SIZE (dtype);
3725 if (!len || TREE_CODE (len) != INTEGER_CST)
3726 return NULL_TREE;
3727
3728 /* Confirm that the constructor is the same size. */
3729 if (compare_tree_int (len, nelem) != 0)
3730 return NULL_TREE;
3731
3732 len = fold_build2 (MULT_EXPR, gfc_array_index_type, len,
3733 TYPE_SIZE_UNIT (gfc_get_element_type (dtype)));
3734
3735 stype = gfc_typenode_for_spec (&expr2->ts);
3736 src = gfc_build_constant_array_constructor (expr2, stype);
3737
3738 stype = TREE_TYPE (src);
3739 if (POINTER_TYPE_P (stype))
3740 stype = TREE_TYPE (stype);
3741
3742 return gfc_build_memcpy_call (dst, src, len);
3743 }
3744
3745
3746 /* Subroutine of gfc_trans_assignment that actually scalarizes the
3747 assignment. EXPR1 is the destination/RHS and EXPR2 is the source/LHS. */
3748
3749 static tree
3750 gfc_trans_assignment_1 (gfc_expr * expr1, gfc_expr * expr2, bool init_flag)
3751 {
3752 gfc_se lse;
3753 gfc_se rse;
3754 gfc_ss *lss;
3755 gfc_ss *lss_section;
3756 gfc_ss *rss;
3757 gfc_loopinfo loop;
3758 tree tmp;
3759 stmtblock_t block;
3760 stmtblock_t body;
3761 bool l_is_temp;
3762
3763 /* Assignment of the form lhs = rhs. */
3764 gfc_start_block (&block);
3765
3766 gfc_init_se (&lse, NULL);
3767 gfc_init_se (&rse, NULL);
3768
3769 /* Walk the lhs. */
3770 lss = gfc_walk_expr (expr1);
3771 rss = NULL;
3772 if (lss != gfc_ss_terminator)
3773 {
3774 /* The assignment needs scalarization. */
3775 lss_section = lss;
3776
3777 /* Find a non-scalar SS from the lhs. */
3778 while (lss_section != gfc_ss_terminator
3779 && lss_section->type != GFC_SS_SECTION)
3780 lss_section = lss_section->next;
3781
3782 gcc_assert (lss_section != gfc_ss_terminator);
3783
3784 /* Initialize the scalarizer. */
3785 gfc_init_loopinfo (&loop);
3786
3787 /* Walk the rhs. */
3788 rss = gfc_walk_expr (expr2);
3789 if (rss == gfc_ss_terminator)
3790 {
3791 /* The rhs is scalar. Add a ss for the expression. */
3792 rss = gfc_get_ss ();
3793 rss->next = gfc_ss_terminator;
3794 rss->type = GFC_SS_SCALAR;
3795 rss->expr = expr2;
3796 }
3797 /* Associate the SS with the loop. */
3798 gfc_add_ss_to_loop (&loop, lss);
3799 gfc_add_ss_to_loop (&loop, rss);
3800
3801 /* Calculate the bounds of the scalarization. */
3802 gfc_conv_ss_startstride (&loop);
3803 /* Resolve any data dependencies in the statement. */
3804 gfc_conv_resolve_dependencies (&loop, lss, rss);
3805 /* Setup the scalarizing loops. */
3806 gfc_conv_loop_setup (&loop);
3807
3808 /* Setup the gfc_se structures. */
3809 gfc_copy_loopinfo_to_se (&lse, &loop);
3810 gfc_copy_loopinfo_to_se (&rse, &loop);
3811
3812 rse.ss = rss;
3813 gfc_mark_ss_chain_used (rss, 1);
3814 if (loop.temp_ss == NULL)
3815 {
3816 lse.ss = lss;
3817 gfc_mark_ss_chain_used (lss, 1);
3818 }
3819 else
3820 {
3821 lse.ss = loop.temp_ss;
3822 gfc_mark_ss_chain_used (lss, 3);
3823 gfc_mark_ss_chain_used (loop.temp_ss, 3);
3824 }
3825
3826 /* Start the scalarized loop body. */
3827 gfc_start_scalarized_body (&loop, &body);
3828 }
3829 else
3830 gfc_init_block (&body);
3831
3832 l_is_temp = (lss != gfc_ss_terminator && loop.temp_ss != NULL);
3833
3834 /* Translate the expression. */
3835 gfc_conv_expr (&rse, expr2);
3836
3837 if (l_is_temp)
3838 {
3839 gfc_conv_tmp_array_ref (&lse);
3840 gfc_advance_se_ss_chain (&lse);
3841 }
3842 else
3843 gfc_conv_expr (&lse, expr1);
3844
3845 tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts,
3846 l_is_temp || init_flag,
3847 expr2->expr_type == EXPR_VARIABLE);
3848 gfc_add_expr_to_block (&body, tmp);
3849
3850 if (lss == gfc_ss_terminator)
3851 {
3852 /* Use the scalar assignment as is. */
3853 gfc_add_block_to_block (&block, &body);
3854 }
3855 else
3856 {
3857 gcc_assert (lse.ss == gfc_ss_terminator
3858 && rse.ss == gfc_ss_terminator);
3859
3860 if (l_is_temp)
3861 {
3862 gfc_trans_scalarized_loop_boundary (&loop, &body);
3863
3864 /* We need to copy the temporary to the actual lhs. */
3865 gfc_init_se (&lse, NULL);
3866 gfc_init_se (&rse, NULL);
3867 gfc_copy_loopinfo_to_se (&lse, &loop);
3868 gfc_copy_loopinfo_to_se (&rse, &loop);
3869
3870 rse.ss = loop.temp_ss;
3871 lse.ss = lss;
3872
3873 gfc_conv_tmp_array_ref (&rse);
3874 gfc_advance_se_ss_chain (&rse);
3875 gfc_conv_expr (&lse, expr1);
3876
3877 gcc_assert (lse.ss == gfc_ss_terminator
3878 && rse.ss == gfc_ss_terminator);
3879
3880 tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts,
3881 false, false);
3882 gfc_add_expr_to_block (&body, tmp);
3883 }
3884
3885 /* Generate the copying loops. */
3886 gfc_trans_scalarizing_loops (&loop, &body);
3887
3888 /* Wrap the whole thing up. */
3889 gfc_add_block_to_block (&block, &loop.pre);
3890 gfc_add_block_to_block (&block, &loop.post);
3891
3892 gfc_cleanup_loop (&loop);
3893 }
3894
3895 return gfc_finish_block (&block);
3896 }
3897
3898
3899 /* Check whether EXPR, which is an EXPR_VARIABLE, is a copyable array. */
3900
3901 static bool
3902 copyable_array_p (gfc_expr * expr)
3903 {
3904 /* First check it's an array. */
3905 if (expr->rank < 1 || !expr->ref)
3906 return false;
3907
3908 /* Next check that it's of a simple enough type. */
3909 switch (expr->ts.type)
3910 {
3911 case BT_INTEGER:
3912 case BT_REAL:
3913 case BT_COMPLEX:
3914 case BT_LOGICAL:
3915 return true;
3916
3917 case BT_CHARACTER:
3918 return false;
3919
3920 case BT_DERIVED:
3921 return !expr->ts.derived->attr.alloc_comp;
3922
3923 default:
3924 break;
3925 }
3926
3927 return false;
3928 }
3929
3930 /* Translate an assignment. */
3931
3932 tree
3933 gfc_trans_assignment (gfc_expr * expr1, gfc_expr * expr2, bool init_flag)
3934 {
3935 tree tmp;
3936
3937 /* Special case a single function returning an array. */
3938 if (expr2->expr_type == EXPR_FUNCTION && expr2->rank > 0)
3939 {
3940 tmp = gfc_trans_arrayfunc_assign (expr1, expr2);
3941 if (tmp)
3942 return tmp;
3943 }
3944
3945 /* Special case assigning an array to zero. */
3946 if (expr1->expr_type == EXPR_VARIABLE
3947 && expr1->rank > 0
3948 && expr1->ref
3949 && gfc_full_array_ref_p (expr1->ref)
3950 && is_zero_initializer_p (expr2))
3951 {
3952 tmp = gfc_trans_zero_assign (expr1);
3953 if (tmp)
3954 return tmp;
3955 }
3956
3957 /* Special case copying one array to another. */
3958 if (expr1->expr_type == EXPR_VARIABLE
3959 && copyable_array_p (expr1)
3960 && gfc_full_array_ref_p (expr1->ref)
3961 && expr2->expr_type == EXPR_VARIABLE
3962 && copyable_array_p (expr2)
3963 && gfc_full_array_ref_p (expr2->ref)
3964 && gfc_compare_types (&expr1->ts, &expr2->ts)
3965 && !gfc_check_dependency (expr1, expr2, 0))
3966 {
3967 tmp = gfc_trans_array_copy (expr1, expr2);
3968 if (tmp)
3969 return tmp;
3970 }
3971
3972 /* Special case initializing an array from a constant array constructor. */
3973 if (expr1->expr_type == EXPR_VARIABLE
3974 && copyable_array_p (expr1)
3975 && gfc_full_array_ref_p (expr1->ref)
3976 && expr2->expr_type == EXPR_ARRAY
3977 && gfc_compare_types (&expr1->ts, &expr2->ts))
3978 {
3979 tmp = gfc_trans_array_constructor_copy (expr1, expr2);
3980 if (tmp)
3981 return tmp;
3982 }
3983
3984 /* Fallback to the scalarizer to generate explicit loops. */
3985 return gfc_trans_assignment_1 (expr1, expr2, init_flag);
3986 }
3987
3988 tree
3989 gfc_trans_init_assign (gfc_code * code)
3990 {
3991 return gfc_trans_assignment (code->expr, code->expr2, true);
3992 }
3993
3994 tree
3995 gfc_trans_assign (gfc_code * code)
3996 {
3997 return gfc_trans_assignment (code->expr, code->expr2, false);
3998 }