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