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