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