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