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