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