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