]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/fortran/trans-stmt.c
re PR fortran/84115 (Failure in associate construct with concatenated character target)
[thirdparty/gcc.git] / gcc / fortran / trans-stmt.c
CommitLineData
6de9cd9a 1/* Statement translation -- generate GCC trees from gfc_code.
85ec4feb 2 Copyright (C) 2002-2018 Free Software Foundation, Inc.
6de9cd9a
DN
3 Contributed by Paul Brook <paul@nowt.org>
4 and Steven Bosscher <s.bosscher@student.tudelft.nl>
5
9fc4d79b 6This file is part of GCC.
6de9cd9a 7
9fc4d79b
TS
8GCC is free software; you can redistribute it and/or modify it under
9the terms of the GNU General Public License as published by the Free
d234d788 10Software Foundation; either version 3, or (at your option) any later
9fc4d79b 11version.
6de9cd9a 12
9fc4d79b
TS
13GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14WARRANTY; without even the implied warranty of MERCHANTABILITY or
15FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16for more details.
6de9cd9a
DN
17
18You should have received a copy of the GNU General Public License
d234d788
NC
19along with GCC; see the file COPYING3. If not see
20<http://www.gnu.org/licenses/>. */
6de9cd9a
DN
21
22
23#include "config.h"
24#include "system.h"
25#include "coretypes.h"
c7131fb2 26#include "options.h"
2adfab87 27#include "tree.h"
6de9cd9a
DN
28#include "gfortran.h"
29#include "trans.h"
2adfab87 30#include "stringpool.h"
2adfab87 31#include "fold-const.h"
6de9cd9a
DN
32#include "trans-stmt.h"
33#include "trans-types.h"
34#include "trans-array.h"
35#include "trans-const.h"
3ded6210 36#include "dependency.h"
6de9cd9a 37
6de9cd9a
DN
38typedef struct iter_info
39{
40 tree var;
41 tree start;
42 tree end;
43 tree step;
44 struct iter_info *next;
45}
46iter_info;
47
6de9cd9a
DN
48typedef struct forall_info
49{
50 iter_info *this_loop;
51 tree mask;
6de9cd9a
DN
52 tree maskindex;
53 int nvar;
54 tree size;
e8d366ec 55 struct forall_info *prev_nest;
2ca4e2c2 56 bool do_concurrent;
6de9cd9a
DN
57}
58forall_info;
59
011daa76
RS
60static void gfc_trans_where_2 (gfc_code *, tree, bool,
61 forall_info *, stmtblock_t *);
6de9cd9a
DN
62
63/* Translate a F95 label number to a LABEL_EXPR. */
64
65tree
66gfc_trans_label_here (gfc_code * code)
67{
68 return build1_v (LABEL_EXPR, gfc_get_label_decl (code->here));
69}
70
ce2df7c6
FW
71
72/* Given a variable expression which has been ASSIGNed to, find the decl
73 containing the auxiliary variables. For variables in common blocks this
74 is a field_decl. */
75
76void
77gfc_conv_label_variable (gfc_se * se, gfc_expr * expr)
78{
79 gcc_assert (expr->symtree->n.sym->attr.assign == 1);
80 gfc_conv_expr (se, expr);
81 /* Deals with variable in common block. Get the field declaration. */
82 if (TREE_CODE (se->expr) == COMPONENT_REF)
83 se->expr = TREE_OPERAND (se->expr, 1);
910450c1
FW
84 /* Deals with dummy argument. Get the parameter declaration. */
85 else if (TREE_CODE (se->expr) == INDIRECT_REF)
86 se->expr = TREE_OPERAND (se->expr, 0);
ce2df7c6
FW
87}
88
6de9cd9a 89/* Translate a label assignment statement. */
ce2df7c6 90
6de9cd9a
DN
91tree
92gfc_trans_label_assign (gfc_code * code)
93{
94 tree label_tree;
95 gfc_se se;
96 tree len;
97 tree addr;
98 tree len_tree;
6de9cd9a
DN
99 int label_len;
100
101 /* Start a new block. */
102 gfc_init_se (&se, NULL);
103 gfc_start_block (&se.pre);
a513927a 104 gfc_conv_label_variable (&se, code->expr1);
ce2df7c6 105
6de9cd9a
DN
106 len = GFC_DECL_STRING_LEN (se.expr);
107 addr = GFC_DECL_ASSIGN_ADDR (se.expr);
108
79bd1948 109 label_tree = gfc_get_label_decl (code->label1);
6de9cd9a 110
f3e7b9d6
TB
111 if (code->label1->defined == ST_LABEL_TARGET
112 || code->label1->defined == ST_LABEL_DO_TARGET)
6de9cd9a
DN
113 {
114 label_tree = gfc_build_addr_expr (pvoid_type_node, label_tree);
f622221a 115 len_tree = build_int_cst (gfc_charlen_type_node, -1);
6de9cd9a
DN
116 }
117 else
118 {
79bd1948 119 gfc_expr *format = code->label1->format;
d393bbd7
FXC
120
121 label_len = format->value.character.length;
df09d1d5 122 len_tree = build_int_cst (gfc_charlen_type_node, label_len);
d393bbd7
FXC
123 label_tree = gfc_build_wide_string_const (format->ts.kind, label_len + 1,
124 format->value.character.string);
b078dfbf 125 label_tree = gfc_build_addr_expr (pvoid_type_node, label_tree);
6de9cd9a
DN
126 }
127
f622221a 128 gfc_add_modify (&se.pre, len, fold_convert (TREE_TYPE (len), len_tree));
726a989a 129 gfc_add_modify (&se.pre, addr, label_tree);
6de9cd9a
DN
130
131 return gfc_finish_block (&se.pre);
132}
133
134/* Translate a GOTO statement. */
135
136tree
137gfc_trans_goto (gfc_code * code)
138{
dd18a33b 139 locus loc = code->loc;
6de9cd9a
DN
140 tree assigned_goto;
141 tree target;
142 tree tmp;
6de9cd9a
DN
143 gfc_se se;
144
79bd1948
SK
145 if (code->label1 != NULL)
146 return build1_v (GOTO_EXPR, gfc_get_label_decl (code->label1));
6de9cd9a
DN
147
148 /* ASSIGNED GOTO. */
149 gfc_init_se (&se, NULL);
150 gfc_start_block (&se.pre);
a513927a 151 gfc_conv_label_variable (&se, code->expr1);
6de9cd9a 152 tmp = GFC_DECL_STRING_LEN (se.expr);
63ee5404 153 tmp = fold_build2_loc (input_location, NE_EXPR, logical_type_node, tmp,
bc98ed60 154 build_int_cst (TREE_TYPE (tmp), -1));
0d52899f 155 gfc_trans_runtime_check (true, false, tmp, &se.pre, &loc,
c8fe94c7 156 "Assigned label is not a target label");
6de9cd9a
DN
157
158 assigned_goto = GFC_DECL_ASSIGN_ADDR (se.expr);
6de9cd9a 159
916bd5f0
DK
160 /* We're going to ignore a label list. It does not really change the
161 statement's semantics (because it is just a further restriction on
162 what's legal code); before, we were comparing label addresses here, but
163 that's a very fragile business and may break with optimization. So
164 just ignore it. */
165
bc98ed60
TB
166 target = fold_build1_loc (input_location, GOTO_EXPR, void_type_node,
167 assigned_goto);
916bd5f0
DK
168 gfc_add_expr_to_block (&se.pre, target);
169 return gfc_finish_block (&se.pre);
6de9cd9a
DN
170}
171
172
3d79abbd
PB
173/* Translate an ENTRY statement. Just adds a label for this entry point. */
174tree
175gfc_trans_entry (gfc_code * code)
176{
177 return build1_v (LABEL_EXPR, code->ext.entry->label);
178}
179
180
fafcf9e6
MM
181/* Replace a gfc_ss structure by another both in the gfc_se struct
182 and the gfc_loopinfo struct. This is used in gfc_conv_elemental_dependencies
183 to replace a variable ss by the corresponding temporary. */
184
185static void
186replace_ss (gfc_se *se, gfc_ss *old_ss, gfc_ss *new_ss)
187{
188 gfc_ss **sess, **loopss;
189
190 /* The old_ss is a ss for a single variable. */
191 gcc_assert (old_ss->info->type == GFC_SS_SECTION);
192
193 for (sess = &(se->ss); *sess != gfc_ss_terminator; sess = &((*sess)->next))
194 if (*sess == old_ss)
195 break;
196 gcc_assert (*sess != gfc_ss_terminator);
197
198 *sess = new_ss;
199 new_ss->next = old_ss->next;
200
201
202 for (loopss = &(se->loop->ss); *loopss != gfc_ss_terminator;
203 loopss = &((*loopss)->loop_chain))
204 if (*loopss == old_ss)
205 break;
206 gcc_assert (*loopss != gfc_ss_terminator);
207
208 *loopss = new_ss;
209 new_ss->loop_chain = old_ss->loop_chain;
210 new_ss->loop = old_ss->loop;
211
212 gfc_free_ss (old_ss);
213}
214
215
476220e7
PT
216/* Check for dependencies between INTENT(IN) and INTENT(OUT) arguments of
217 elemental subroutines. Make temporaries for output arguments if any such
218 dependencies are found. Output arguments are chosen because internal_unpack
219 can be used, as is, to copy the result back to the variable. */
220static void
221gfc_conv_elemental_dependencies (gfc_se * se, gfc_se * loopse,
2b0bd714
MM
222 gfc_symbol * sym, gfc_actual_arglist * arg,
223 gfc_dep_check check_variable)
476220e7
PT
224{
225 gfc_actual_arglist *arg0;
226 gfc_expr *e;
227 gfc_formal_arglist *formal;
476220e7
PT
228 gfc_se parmse;
229 gfc_ss *ss;
476220e7 230 gfc_symbol *fsym;
476220e7 231 tree data;
476220e7
PT
232 tree size;
233 tree tmp;
234
235 if (loopse->ss == NULL)
236 return;
237
238 ss = loopse->ss;
239 arg0 = arg;
4cbc9039 240 formal = gfc_sym_get_dummy_args (sym);
476220e7
PT
241
242 /* Loop over all the arguments testing for dependencies. */
243 for (; arg != NULL; arg = arg->next, formal = formal ? formal->next : NULL)
244 {
245 e = arg->expr;
246 if (e == NULL)
247 continue;
248
8b704316 249 /* Obtain the info structure for the current argument. */
476220e7 250 for (ss = loopse->ss; ss && ss != gfc_ss_terminator; ss = ss->next)
fafcf9e6 251 if (ss->info->expr == e)
476220e7 252 break;
476220e7
PT
253
254 /* If there is a dependency, create a temporary and use it
66e4ab31 255 instead of the variable. */
476220e7
PT
256 fsym = formal ? formal->sym : NULL;
257 if (e->expr_type == EXPR_VARIABLE
258 && e->rank && fsym
06bcd751
PT
259 && fsym->attr.intent != INTENT_IN
260 && gfc_check_fncall_dependency (e, fsym->attr.intent,
2b0bd714 261 sym, arg0, check_variable))
476220e7 262 {
79e5286c 263 tree initial, temptype;
12f681a0 264 stmtblock_t temp_post;
fafcf9e6 265 gfc_ss *tmp_ss;
12f681a0 266
fafcf9e6
MM
267 tmp_ss = gfc_get_array_ss (gfc_ss_terminator, NULL, ss->dimen,
268 GFC_SS_SECTION);
269 gfc_mark_ss_chain_used (tmp_ss, 1);
270 tmp_ss->info->expr = ss->info->expr;
271 replace_ss (loopse, ss, tmp_ss);
476220e7 272
12f681a0
DK
273 /* Obtain the argument descriptor for unpacking. */
274 gfc_init_se (&parmse, NULL);
275 parmse.want_pointer = 1;
2960a368 276 gfc_conv_expr_descriptor (&parmse, e);
12f681a0
DK
277 gfc_add_block_to_block (&se->pre, &parmse.pre);
278
eb74e79b
PT
279 /* If we've got INTENT(INOUT) or a derived type with INTENT(OUT),
280 initialize the array temporary with a copy of the values. */
281 if (fsym->attr.intent == INTENT_INOUT
282 || (fsym->ts.type ==BT_DERIVED
283 && fsym->attr.intent == INTENT_OUT))
12f681a0 284 initial = parmse.expr;
866e6d1b
PT
285 /* For class expressions, we always initialize with the copy of
286 the values. */
287 else if (e->ts.type == BT_CLASS)
288 initial = parmse.expr;
12f681a0
DK
289 else
290 initial = NULL_TREE;
291
866e6d1b
PT
292 if (e->ts.type != BT_CLASS)
293 {
294 /* Find the type of the temporary to create; we don't use the type
295 of e itself as this breaks for subcomponent-references in e
296 (where the type of e is that of the final reference, but
297 parmse.expr's type corresponds to the full derived-type). */
298 /* TODO: Fix this somehow so we don't need a temporary of the whole
299 array but instead only the components referenced. */
300 temptype = TREE_TYPE (parmse.expr); /* Pointer to descriptor. */
301 gcc_assert (TREE_CODE (temptype) == POINTER_TYPE);
302 temptype = TREE_TYPE (temptype);
303 temptype = gfc_get_element_type (temptype);
304 }
305
306 else
307 /* For class arrays signal that the size of the dynamic type has to
308 be obtained from the vtable, using the 'initial' expression. */
309 temptype = NULL_TREE;
79e5286c
DK
310
311 /* Generate the temporary. Cleaning up the temporary should be the
312 very last thing done, so we add the code to a new block and add it
313 to se->post as last instructions. */
476220e7
PT
314 size = gfc_create_var (gfc_array_index_type, NULL);
315 data = gfc_create_var (pvoid_type_node, NULL);
12f681a0 316 gfc_init_block (&temp_post);
fafcf9e6 317 tmp = gfc_trans_create_temp_array (&se->pre, &temp_post, tmp_ss,
41645793
MM
318 temptype, initial, false, true,
319 false, &arg->expr->where);
726a989a 320 gfc_add_modify (&se->pre, size, tmp);
fafcf9e6 321 tmp = fold_convert (pvoid_type_node, tmp_ss->info->data.array.data);
726a989a 322 gfc_add_modify (&se->pre, data, tmp);
476220e7 323
fafcf9e6
MM
324 /* Update other ss' delta. */
325 gfc_set_delta (loopse->loop);
476220e7 326
866e6d1b
PT
327 /* Copy the result back using unpack..... */
328 if (e->ts.type != BT_CLASS)
329 tmp = build_call_expr_loc (input_location,
330 gfor_fndecl_in_unpack, 2, parmse.expr, data);
331 else
332 {
333 /* ... except for class results where the copy is
334 unconditional. */
335 tmp = build_fold_indirect_ref_loc (input_location, parmse.expr);
336 tmp = gfc_conv_descriptor_data_get (tmp);
337 tmp = build_call_expr_loc (input_location,
338 builtin_decl_explicit (BUILT_IN_MEMCPY),
ee4b6b52
JJ
339 3, tmp, data,
340 fold_convert (size_type_node, size));
866e6d1b 341 }
476220e7
PT
342 gfc_add_expr_to_block (&se->post, tmp);
343
79e5286c 344 /* parmse.pre is already added above. */
476220e7 345 gfc_add_block_to_block (&se->post, &parmse.post);
12f681a0 346 gfc_add_block_to_block (&se->post, &temp_post);
476220e7
PT
347 }
348 }
349}
350
351
9436b221
MM
352/* Get the interface symbol for the procedure corresponding to the given call.
353 We can't get the procedure symbol directly as we have to handle the case
354 of (deferred) type-bound procedures. */
355
356static gfc_symbol *
357get_proc_ifc_for_call (gfc_code *c)
358{
359 gfc_symbol *sym;
360
361 gcc_assert (c->op == EXEC_ASSIGN_CALL || c->op == EXEC_CALL);
362
363 sym = gfc_get_proc_ifc_for_expr (c->expr1);
364
365 /* Fall back/last resort try. */
366 if (sym == NULL)
367 sym = c->resolved_sym;
368
369 return sym;
370}
371
372
6de9cd9a
DN
373/* Translate the CALL statement. Builds a call to an F95 subroutine. */
374
375tree
eb74e79b
PT
376gfc_trans_call (gfc_code * code, bool dependency_check,
377 tree mask, tree count1, bool invert)
6de9cd9a
DN
378{
379 gfc_se se;
48474141 380 gfc_ss * ss;
dda895f9 381 int has_alternate_specifier;
2b0bd714 382 gfc_dep_check check_variable;
eb74e79b
PT
383 tree index = NULL_TREE;
384 tree maskexpr = NULL_TREE;
385 tree tmp;
6de9cd9a
DN
386
387 /* A CALL starts a new block because the actual arguments may have to
388 be evaluated first. */
389 gfc_init_se (&se, NULL);
390 gfc_start_block (&se.pre);
391
6e45f57b 392 gcc_assert (code->resolved_sym);
6de9cd9a 393
48474141
PT
394 ss = gfc_ss_terminator;
395 if (code->resolved_sym->attr.elemental)
17d038cd 396 ss = gfc_walk_elemental_function_args (ss, code->ext.actual,
9436b221 397 get_proc_ifc_for_call (code),
dec131b6 398 GFC_SS_REFERENCE);
6de9cd9a 399
48474141
PT
400 /* Is not an elemental subroutine call with array valued arguments. */
401 if (ss == gfc_ss_terminator)
6de9cd9a 402 {
48474141
PT
403
404 /* Translate the call. */
405 has_alternate_specifier
713485cc 406 = gfc_conv_procedure_call (&se, code->resolved_sym, code->ext.actual,
989ea525 407 code->expr1, NULL);
48474141
PT
408
409 /* A subroutine without side-effect, by definition, does nothing! */
410 TREE_SIDE_EFFECTS (se.expr) = 1;
411
412 /* Chain the pieces together and return the block. */
413 if (has_alternate_specifier)
414 {
415 gfc_code *select_code;
416 gfc_symbol *sym;
417 select_code = code->next;
418 gcc_assert(select_code->op == EXEC_SELECT);
a513927a 419 sym = select_code->expr1->symtree->n.sym;
48474141 420 se.expr = convert (gfc_typenode_for_spec (&sym->ts), se.expr);
9ebe2d22
PT
421 if (sym->backend_decl == NULL)
422 sym->backend_decl = gfc_get_symbol_decl (sym);
726a989a 423 gfc_add_modify (&se.pre, sym->backend_decl, se.expr);
48474141
PT
424 }
425 else
426 gfc_add_expr_to_block (&se.pre, se.expr);
427
428 gfc_add_block_to_block (&se.pre, &se.post);
6de9cd9a 429 }
48474141 430
6de9cd9a 431 else
48474141
PT
432 {
433 /* An elemental subroutine call with array valued arguments has
434 to be scalarized. */
435 gfc_loopinfo loop;
436 stmtblock_t body;
437 stmtblock_t block;
438 gfc_se loopse;
70e72065 439 gfc_se depse;
48474141
PT
440
441 /* gfc_walk_elemental_function_args renders the ss chain in the
12f681a0 442 reverse order to the actual argument order. */
48474141
PT
443 ss = gfc_reverse_ss (ss);
444
445 /* Initialize the loop. */
446 gfc_init_se (&loopse, NULL);
447 gfc_init_loopinfo (&loop);
448 gfc_add_ss_to_loop (&loop, ss);
449
450 gfc_conv_ss_startstride (&loop);
8b704316
PT
451 /* TODO: gfc_conv_loop_setup generates a temporary for vector
452 subscripts. This could be prevented in the elemental case
453 as temporaries are handled separatedly
2b0bd714 454 (below in gfc_conv_elemental_dependencies). */
88016532
JD
455 if (code->expr1)
456 gfc_conv_loop_setup (&loop, &code->expr1->where);
457 else
458 gfc_conv_loop_setup (&loop, &code->loc);
459
48474141
PT
460 gfc_mark_ss_chain_used (ss, 1);
461
476220e7
PT
462 /* Convert the arguments, checking for dependencies. */
463 gfc_copy_loopinfo_to_se (&loopse, &loop);
464 loopse.ss = ss;
465
06bcd751 466 /* For operator assignment, do dependency checking. */
476220e7 467 if (dependency_check)
2b0bd714
MM
468 check_variable = ELEM_CHECK_VARIABLE;
469 else
470 check_variable = ELEM_DONT_CHECK_VARIABLE;
70e72065
MM
471
472 gfc_init_se (&depse, NULL);
473 gfc_conv_elemental_dependencies (&depse, &loopse, code->resolved_sym,
2b0bd714 474 code->ext.actual, check_variable);
476220e7 475
70e72065
MM
476 gfc_add_block_to_block (&loop.pre, &depse.pre);
477 gfc_add_block_to_block (&loop.post, &depse.post);
478
48474141
PT
479 /* Generate the loop body. */
480 gfc_start_scalarized_body (&loop, &body);
481 gfc_init_block (&block);
48474141 482
eb74e79b
PT
483 if (mask && count1)
484 {
485 /* Form the mask expression according to the mask. */
486 index = count1;
487 maskexpr = gfc_build_array_ref (mask, index, NULL);
488 if (invert)
bc98ed60
TB
489 maskexpr = fold_build1_loc (input_location, TRUTH_NOT_EXPR,
490 TREE_TYPE (maskexpr), maskexpr);
eb74e79b
PT
491 }
492
48474141 493 /* Add the subroutine call to the block. */
eb74e79b 494 gfc_conv_procedure_call (&loopse, code->resolved_sym,
9771b263
DN
495 code->ext.actual, code->expr1,
496 NULL);
eb74e79b
PT
497
498 if (mask && count1)
499 {
500 tmp = build3_v (COND_EXPR, maskexpr, loopse.expr,
c2255bc4 501 build_empty_stmt (input_location));
eb74e79b 502 gfc_add_expr_to_block (&loopse.pre, tmp);
bc98ed60
TB
503 tmp = fold_build2_loc (input_location, PLUS_EXPR,
504 gfc_array_index_type,
505 count1, gfc_index_one_node);
eb74e79b
PT
506 gfc_add_modify (&loopse.pre, count1, tmp);
507 }
508 else
509 gfc_add_expr_to_block (&loopse.pre, loopse.expr);
48474141
PT
510
511 gfc_add_block_to_block (&block, &loopse.pre);
512 gfc_add_block_to_block (&block, &loopse.post);
513
514 /* Finish up the loop block and the loop. */
515 gfc_add_expr_to_block (&body, gfc_finish_block (&block));
516 gfc_trans_scalarizing_loops (&loop, &body);
517 gfc_add_block_to_block (&se.pre, &loop.pre);
518 gfc_add_block_to_block (&se.pre, &loop.post);
476220e7 519 gfc_add_block_to_block (&se.pre, &se.post);
48474141
PT
520 gfc_cleanup_loop (&loop);
521 }
6de9cd9a 522
6de9cd9a
DN
523 return gfc_finish_block (&se.pre);
524}
525
526
527/* Translate the RETURN statement. */
528
529tree
d74d8807 530gfc_trans_return (gfc_code * code)
6de9cd9a 531{
a513927a 532 if (code->expr1)
6de9cd9a
DN
533 {
534 gfc_se se;
535 tree tmp;
536 tree result;
537
da4c6ed8 538 /* If code->expr is not NULL, this return statement must appear
d74d8807 539 in a subroutine and current_fake_result_decl has already
6de9cd9a
DN
540 been generated. */
541
5f20c93a 542 result = gfc_get_fake_result_decl (NULL, 0);
6de9cd9a 543 if (!result)
d74d8807 544 {
db30e21c
JM
545 gfc_warning (0,
546 "An alternate return at %L without a * dummy argument",
48749dbc 547 &code->expr1->where);
d74d8807
DK
548 return gfc_generate_return ();
549 }
6de9cd9a
DN
550
551 /* Start a new block for this statement. */
552 gfc_init_se (&se, NULL);
553 gfc_start_block (&se.pre);
554
a513927a 555 gfc_conv_expr (&se, code->expr1);
6de9cd9a 556
ba3ff5c2
DK
557 /* Note that the actually returned expression is a simple value and
558 does not depend on any pointers or such; thus we can clean-up with
559 se.post before returning. */
bc98ed60
TB
560 tmp = fold_build2_loc (input_location, MODIFY_EXPR, TREE_TYPE (result),
561 result, fold_convert (TREE_TYPE (result),
562 se.expr));
6de9cd9a 563 gfc_add_expr_to_block (&se.pre, tmp);
ba3ff5c2 564 gfc_add_block_to_block (&se.pre, &se.post);
6de9cd9a 565
d74d8807 566 tmp = gfc_generate_return ();
6de9cd9a 567 gfc_add_expr_to_block (&se.pre, tmp);
6de9cd9a
DN
568 return gfc_finish_block (&se.pre);
569 }
d74d8807
DK
570
571 return gfc_generate_return ();
6de9cd9a
DN
572}
573
574
575/* Translate the PAUSE statement. We have to translate this statement
576 to a runtime library call. */
577
578tree
579gfc_trans_pause (gfc_code * code)
580{
e2cad04b 581 tree gfc_int4_type_node = gfc_get_int_type (4);
6de9cd9a 582 gfc_se se;
6de9cd9a 583 tree tmp;
6de9cd9a
DN
584
585 /* Start a new block for this statement. */
586 gfc_init_se (&se, NULL);
587 gfc_start_block (&se.pre);
588
589
a513927a 590 if (code->expr1 == NULL)
6de9cd9a 591 {
6d1b0f92 592 tmp = build_int_cst (gfc_int4_type_node, 0);
db3927fb 593 tmp = build_call_expr_loc (input_location,
6d1b0f92
JD
594 gfor_fndecl_pause_string, 2,
595 build_int_cst (pchar_type_node, 0), tmp);
596 }
597 else if (code->expr1->ts.type == BT_INTEGER)
598 {
599 gfc_conv_expr (&se, code->expr1);
600 tmp = build_call_expr_loc (input_location,
601 gfor_fndecl_pause_numeric, 1,
602 fold_convert (gfc_int4_type_node, se.expr));
6de9cd9a
DN
603 }
604 else
605 {
a513927a 606 gfc_conv_expr_reference (&se, code->expr1);
db3927fb
AH
607 tmp = build_call_expr_loc (input_location,
608 gfor_fndecl_pause_string, 2,
5039610b 609 se.expr, se.string_length);
6de9cd9a
DN
610 }
611
6de9cd9a
DN
612 gfc_add_expr_to_block (&se.pre, tmp);
613
614 gfc_add_block_to_block (&se.pre, &se.post);
615
616 return gfc_finish_block (&se.pre);
617}
618
619
620/* Translate the STOP statement. We have to translate this statement
621 to a runtime library call. */
622
623tree
d0a4a61c 624gfc_trans_stop (gfc_code *code, bool error_stop)
6de9cd9a 625{
e2cad04b 626 tree gfc_int4_type_node = gfc_get_int_type (4);
6de9cd9a 627 gfc_se se;
6de9cd9a 628 tree tmp;
6de9cd9a
DN
629
630 /* Start a new block for this statement. */
631 gfc_init_se (&se, NULL);
632 gfc_start_block (&se.pre);
633
a513927a 634 if (code->expr1 == NULL)
6de9cd9a 635 {
6d1b0f92
JD
636 tmp = build_int_cst (gfc_int4_type_node, 0);
637 tmp = build_call_expr_loc (input_location,
60386f50 638 error_stop
f19626cf 639 ? (flag_coarray == GFC_FCOARRAY_LIB
60386f50
TB
640 ? gfor_fndecl_caf_error_stop_str
641 : gfor_fndecl_error_stop_string)
0daa7ed9
AF
642 : (flag_coarray == GFC_FCOARRAY_LIB
643 ? gfor_fndecl_caf_stop_str
644 : gfor_fndecl_stop_string),
cea59ace 645 2, build_int_cst (pchar_type_node, 0), tmp);
6d1b0f92
JD
646 }
647 else if (code->expr1->ts.type == BT_INTEGER)
648 {
649 gfc_conv_expr (&se, code->expr1);
db3927fb 650 tmp = build_call_expr_loc (input_location,
60386f50 651 error_stop
f19626cf 652 ? (flag_coarray == GFC_FCOARRAY_LIB
60386f50
TB
653 ? gfor_fndecl_caf_error_stop
654 : gfor_fndecl_error_stop_numeric)
0daa7ed9
AF
655 : (flag_coarray == GFC_FCOARRAY_LIB
656 ? gfor_fndecl_caf_stop_numeric
03506f8c 657 : gfor_fndecl_stop_numeric), 1,
6d1b0f92 658 fold_convert (gfc_int4_type_node, se.expr));
6de9cd9a
DN
659 }
660 else
661 {
a513927a 662 gfc_conv_expr_reference (&se, code->expr1);
db3927fb 663 tmp = build_call_expr_loc (input_location,
60386f50 664 error_stop
f19626cf 665 ? (flag_coarray == GFC_FCOARRAY_LIB
60386f50
TB
666 ? gfor_fndecl_caf_error_stop_str
667 : gfor_fndecl_error_stop_string)
0daa7ed9
AF
668 : (flag_coarray == GFC_FCOARRAY_LIB
669 ? gfor_fndecl_caf_stop_str
670 : gfor_fndecl_stop_string),
cea59ace 671 2, se.expr, se.string_length);
6de9cd9a
DN
672 }
673
6de9cd9a
DN
674 gfc_add_expr_to_block (&se.pre, tmp);
675
676 gfc_add_block_to_block (&se.pre, &se.post);
677
678 return gfc_finish_block (&se.pre);
679}
680
ef78bc3c
AV
681/* Translate the FAIL IMAGE statement. */
682
683tree
684gfc_trans_fail_image (gfc_code *code ATTRIBUTE_UNUSED)
685{
686 if (flag_coarray == GFC_FCOARRAY_LIB)
687 return build_call_expr_loc (input_location,
688 gfor_fndecl_caf_fail_image, 1,
689 build_int_cst (pchar_type_node, 0));
690 else
691 {
692 const char *name = gfc_get_string (PREFIX ("exit_i%d"), 4);
693 gfc_symbol *exsym = gfc_get_intrinsic_sub_symbol (name);
694 tree tmp = gfc_get_symbol_decl (exsym);
695 return build_call_expr_loc (input_location, tmp, 1, integer_zero_node);
696 }
697}
698
f8862a1b
DR
699/* Translate the FORM TEAM statement. */
700
701tree
702gfc_trans_form_team (gfc_code *code)
703{
704 if (flag_coarray == GFC_FCOARRAY_LIB)
705 {
706 gfc_se argse;
707 tree team_id,team_type;
708 gfc_init_se (&argse, NULL);
709 gfc_conv_expr_val (&argse, code->expr1);
710 team_id = fold_convert (integer_type_node, argse.expr);
711 gfc_init_se (&argse, NULL);
712 gfc_conv_expr_val (&argse, code->expr2);
713 team_type = gfc_build_addr_expr (ppvoid_type_node, argse.expr);
714
715 return build_call_expr_loc (input_location,
716 gfor_fndecl_caf_form_team, 3,
717 team_id, team_type,
718 build_int_cst (integer_type_node, 0));
719 }
720 else
721 {
722 const char *name = gfc_get_string (PREFIX ("exit_i%d"), 4);
723 gfc_symbol *exsym = gfc_get_intrinsic_sub_symbol (name);
724 tree tmp = gfc_get_symbol_decl (exsym);
725 return build_call_expr_loc (input_location, tmp, 1, integer_zero_node);
726 }
727}
728
729/* Translate the CHANGE TEAM statement. */
730
731tree
732gfc_trans_change_team (gfc_code *code)
733{
734 if (flag_coarray == GFC_FCOARRAY_LIB)
735 {
736 gfc_se argse;
737 tree team_type;
738
739 gfc_init_se (&argse, NULL);
740 gfc_conv_expr_val (&argse, code->expr1);
741 team_type = gfc_build_addr_expr (ppvoid_type_node, argse.expr);
742
743 return build_call_expr_loc (input_location,
744 gfor_fndecl_caf_change_team, 2, team_type,
745 build_int_cst (integer_type_node, 0));
746 }
747 else
748 {
749 const char *name = gfc_get_string (PREFIX ("exit_i%d"), 4);
750 gfc_symbol *exsym = gfc_get_intrinsic_sub_symbol (name);
751 tree tmp = gfc_get_symbol_decl (exsym);
752 return build_call_expr_loc (input_location, tmp, 1, integer_zero_node);
753 }
754}
755
756/* Translate the END TEAM statement. */
757
758tree
759gfc_trans_end_team (gfc_code *code ATTRIBUTE_UNUSED)
760{
761 if (flag_coarray == GFC_FCOARRAY_LIB)
762 {
763 return build_call_expr_loc (input_location,
764 gfor_fndecl_caf_end_team, 1,
765 build_int_cst (pchar_type_node, 0));
766 }
767 else
768 {
769 const char *name = gfc_get_string (PREFIX ("exit_i%d"), 4);
770 gfc_symbol *exsym = gfc_get_intrinsic_sub_symbol (name);
771 tree tmp = gfc_get_symbol_decl (exsym);
772 return build_call_expr_loc (input_location, tmp, 1, integer_zero_node);
773 }
774}
775
776/* Translate the SYNC TEAM statement. */
777
778tree
779gfc_trans_sync_team (gfc_code *code)
780{
781 if (flag_coarray == GFC_FCOARRAY_LIB)
782 {
783 gfc_se argse;
784 tree team_type;
785
786 gfc_init_se (&argse, NULL);
787 gfc_conv_expr_val (&argse, code->expr1);
788 team_type = gfc_build_addr_expr (ppvoid_type_node, argse.expr);
789
790 return build_call_expr_loc (input_location,
791 gfor_fndecl_caf_sync_team, 2,
792 team_type,
793 build_int_cst (integer_type_node, 0));
794 }
795 else
796 {
797 const char *name = gfc_get_string (PREFIX ("exit_i%d"), 4);
798 gfc_symbol *exsym = gfc_get_intrinsic_sub_symbol (name);
799 tree tmp = gfc_get_symbol_decl (exsym);
800 return build_call_expr_loc (input_location, tmp, 1, integer_zero_node);
801 }
802}
6de9cd9a 803
fea54935 804tree
9f3880d1 805gfc_trans_lock_unlock (gfc_code *code, gfc_exec_op op)
fea54935
TB
806{
807 gfc_se se, argse;
9f3880d1
TB
808 tree stat = NULL_TREE, stat2 = NULL_TREE;
809 tree lock_acquired = NULL_TREE, lock_acquired2 = NULL_TREE;
fea54935
TB
810
811 /* Short cut: For single images without STAT= or LOCK_ACQUIRED
812 return early. (ERRMSG= is always untouched for -fcoarray=single.) */
f19626cf 813 if (!code->expr2 && !code->expr4 && flag_coarray != GFC_FCOARRAY_LIB)
8b704316 814 return NULL_TREE;
fea54935 815
fea54935
TB
816 if (code->expr2)
817 {
818 gcc_assert (code->expr2->expr_type == EXPR_VARIABLE);
819 gfc_init_se (&argse, NULL);
820 gfc_conv_expr_val (&argse, code->expr2);
821 stat = argse.expr;
822 }
9f3880d1
TB
823 else if (flag_coarray == GFC_FCOARRAY_LIB)
824 stat = null_pointer_node;
fea54935
TB
825
826 if (code->expr4)
827 {
828 gcc_assert (code->expr4->expr_type == EXPR_VARIABLE);
829 gfc_init_se (&argse, NULL);
830 gfc_conv_expr_val (&argse, code->expr4);
831 lock_acquired = argse.expr;
832 }
9f3880d1
TB
833 else if (flag_coarray == GFC_FCOARRAY_LIB)
834 lock_acquired = null_pointer_node;
835
836 gfc_start_block (&se.pre);
837 if (flag_coarray == GFC_FCOARRAY_LIB)
838 {
839 tree tmp, token, image_index, errmsg, errmsg_len;
840 tree index = size_zero_node;
841 tree caf_decl = gfc_get_tree_for_caf_expr (code->expr1);
842
843 if (code->expr1->symtree->n.sym->ts.type != BT_DERIVED
844 || code->expr1->symtree->n.sym->ts.u.derived->from_intmod
845 != INTMOD_ISO_FORTRAN_ENV
846 || code->expr1->symtree->n.sym->ts.u.derived->intmod_sym_id
847 != ISOFORTRAN_LOCK_TYPE)
848 {
849 gfc_error ("Sorry, the lock component of derived type at %L is not "
850 "yet supported", &code->expr1->where);
851 return NULL_TREE;
852 }
853
3c9f5092
AV
854 gfc_get_caf_token_offset (&se, &token, NULL, caf_decl, NULL_TREE,
855 code->expr1);
9f3880d1
TB
856
857 if (gfc_is_coindexed (code->expr1))
858 image_index = gfc_caf_get_image_index (&se.pre, code->expr1, caf_decl);
859 else
860 image_index = integer_zero_node;
861
862 /* For arrays, obtain the array index. */
863 if (gfc_expr_attr (code->expr1).dimension)
864 {
865 tree desc, tmp, extent, lbound, ubound;
866 gfc_array_ref *ar, ar2;
867 int i;
868
869 /* TODO: Extend this, once DT components are supported. */
870 ar = &code->expr1->ref->u.ar;
871 ar2 = *ar;
872 memset (ar, '\0', sizeof (*ar));
873 ar->as = ar2.as;
874 ar->type = AR_FULL;
875
876 gfc_init_se (&argse, NULL);
877 argse.descriptor_only = 1;
878 gfc_conv_expr_descriptor (&argse, code->expr1);
879 gfc_add_block_to_block (&se.pre, &argse.pre);
880 desc = argse.expr;
881 *ar = ar2;
882
883 extent = integer_one_node;
884 for (i = 0; i < ar->dimen; i++)
885 {
886 gfc_init_se (&argse, NULL);
887 gfc_conv_expr_type (&argse, ar->start[i], integer_type_node);
888 gfc_add_block_to_block (&argse.pre, &argse.pre);
889 lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[i]);
890 tmp = fold_build2_loc (input_location, MINUS_EXPR,
891 integer_type_node, argse.expr,
892 fold_convert(integer_type_node, lbound));
893 tmp = fold_build2_loc (input_location, MULT_EXPR,
894 integer_type_node, extent, tmp);
895 index = fold_build2_loc (input_location, PLUS_EXPR,
896 integer_type_node, index, tmp);
897 if (i < ar->dimen - 1)
898 {
899 ubound = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[i]);
900 tmp = gfc_conv_array_extent_dim (lbound, ubound, NULL);
901 tmp = fold_convert (integer_type_node, tmp);
902 extent = fold_build2_loc (input_location, MULT_EXPR,
903 integer_type_node, extent, tmp);
904 }
905 }
906 }
907
908 /* errmsg. */
909 if (code->expr3)
910 {
911 gfc_init_se (&argse, NULL);
5df445a2 912 argse.want_pointer = 1;
9f3880d1
TB
913 gfc_conv_expr (&argse, code->expr3);
914 gfc_add_block_to_block (&se.pre, &argse.pre);
915 errmsg = argse.expr;
916 errmsg_len = fold_convert (integer_type_node, argse.string_length);
917 }
918 else
919 {
920 errmsg = null_pointer_node;
921 errmsg_len = integer_zero_node;
922 }
923
924 if (stat != null_pointer_node && TREE_TYPE (stat) != integer_type_node)
925 {
926 stat2 = stat;
927 stat = gfc_create_var (integer_type_node, "stat");
928 }
929
930 if (lock_acquired != null_pointer_node
931 && TREE_TYPE (lock_acquired) != integer_type_node)
932 {
933 lock_acquired2 = lock_acquired;
934 lock_acquired = gfc_create_var (integer_type_node, "acquired");
935 }
936
937 if (op == EXEC_LOCK)
938 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_lock, 7,
939 token, index, image_index,
940 lock_acquired != null_pointer_node
941 ? gfc_build_addr_expr (NULL, lock_acquired)
942 : lock_acquired,
943 stat != null_pointer_node
944 ? gfc_build_addr_expr (NULL, stat) : stat,
945 errmsg, errmsg_len);
946 else
947 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_unlock, 6,
948 token, index, image_index,
949 stat != null_pointer_node
950 ? gfc_build_addr_expr (NULL, stat) : stat,
951 errmsg, errmsg_len);
952 gfc_add_expr_to_block (&se.pre, tmp);
953
985f6c79
TB
954 /* It guarantees memory consistency within the same segment */
955 tmp = gfc_build_string_const (strlen ("memory")+1, "memory"),
956 tmp = build5_loc (input_location, ASM_EXPR, void_type_node,
957 gfc_build_string_const (1, ""), NULL_TREE, NULL_TREE,
958 tree_cons (NULL_TREE, tmp, NULL_TREE), NULL_TREE);
959 ASM_VOLATILE_P (tmp) = 1;
960
961 gfc_add_expr_to_block (&se.pre, tmp);
962
9f3880d1
TB
963 if (stat2 != NULL_TREE)
964 gfc_add_modify (&se.pre, stat2,
965 fold_convert (TREE_TYPE (stat2), stat));
966
967 if (lock_acquired2 != NULL_TREE)
968 gfc_add_modify (&se.pre, lock_acquired2,
969 fold_convert (TREE_TYPE (lock_acquired2),
970 lock_acquired));
971
972 return gfc_finish_block (&se.pre);
973 }
fea54935
TB
974
975 if (stat != NULL_TREE)
976 gfc_add_modify (&se.pre, stat, build_int_cst (TREE_TYPE (stat), 0));
977
978 if (lock_acquired != NULL_TREE)
979 gfc_add_modify (&se.pre, lock_acquired,
980 fold_convert (TREE_TYPE (lock_acquired),
981 boolean_true_node));
982
983 return gfc_finish_block (&se.pre);
984}
985
5df445a2
TB
986tree
987gfc_trans_event_post_wait (gfc_code *code, gfc_exec_op op)
988{
989 gfc_se se, argse;
990 tree stat = NULL_TREE, stat2 = NULL_TREE;
991 tree until_count = NULL_TREE;
992
993 if (code->expr2)
994 {
995 gcc_assert (code->expr2->expr_type == EXPR_VARIABLE);
996 gfc_init_se (&argse, NULL);
997 gfc_conv_expr_val (&argse, code->expr2);
998 stat = argse.expr;
999 }
1000 else if (flag_coarray == GFC_FCOARRAY_LIB)
1001 stat = null_pointer_node;
1002
1003 if (code->expr4)
1004 {
1005 gfc_init_se (&argse, NULL);
1006 gfc_conv_expr_val (&argse, code->expr4);
1007 until_count = fold_convert (integer_type_node, argse.expr);
1008 }
1009 else
1010 until_count = integer_one_node;
1011
1012 if (flag_coarray != GFC_FCOARRAY_LIB)
1013 {
1014 gfc_start_block (&se.pre);
1015 gfc_init_se (&argse, NULL);
1016 gfc_conv_expr_val (&argse, code->expr1);
1017
1018 if (op == EXEC_EVENT_POST)
1019 gfc_add_modify (&se.pre, argse.expr,
1020 fold_build2_loc (input_location, PLUS_EXPR,
1021 TREE_TYPE (argse.expr), argse.expr,
1022 build_int_cst (TREE_TYPE (argse.expr), 1)));
1023 else
1024 gfc_add_modify (&se.pre, argse.expr,
1025 fold_build2_loc (input_location, MINUS_EXPR,
1026 TREE_TYPE (argse.expr), argse.expr,
1027 fold_convert (TREE_TYPE (argse.expr),
1028 until_count)));
1029 if (stat != NULL_TREE)
1030 gfc_add_modify (&se.pre, stat, build_int_cst (TREE_TYPE (stat), 0));
1031
1032 return gfc_finish_block (&se.pre);
1033 }
1034
1035 gfc_start_block (&se.pre);
1036 tree tmp, token, image_index, errmsg, errmsg_len;
1037 tree index = size_zero_node;
1038 tree caf_decl = gfc_get_tree_for_caf_expr (code->expr1);
1039
1040 if (code->expr1->symtree->n.sym->ts.type != BT_DERIVED
1041 || code->expr1->symtree->n.sym->ts.u.derived->from_intmod
1042 != INTMOD_ISO_FORTRAN_ENV
1043 || code->expr1->symtree->n.sym->ts.u.derived->intmod_sym_id
1044 != ISOFORTRAN_EVENT_TYPE)
1045 {
1046 gfc_error ("Sorry, the event component of derived type at %L is not "
1047 "yet supported", &code->expr1->where);
1048 return NULL_TREE;
1049 }
1050
3c9f5092
AV
1051 gfc_init_se (&argse, NULL);
1052 gfc_get_caf_token_offset (&argse, &token, NULL, caf_decl, NULL_TREE,
1053 code->expr1);
1054 gfc_add_block_to_block (&se.pre, &argse.pre);
5df445a2
TB
1055
1056 if (gfc_is_coindexed (code->expr1))
1057 image_index = gfc_caf_get_image_index (&se.pre, code->expr1, caf_decl);
1058 else
1059 image_index = integer_zero_node;
1060
1061 /* For arrays, obtain the array index. */
1062 if (gfc_expr_attr (code->expr1).dimension)
1063 {
1064 tree desc, tmp, extent, lbound, ubound;
1065 gfc_array_ref *ar, ar2;
1066 int i;
1067
1068 /* TODO: Extend this, once DT components are supported. */
1069 ar = &code->expr1->ref->u.ar;
1070 ar2 = *ar;
1071 memset (ar, '\0', sizeof (*ar));
1072 ar->as = ar2.as;
1073 ar->type = AR_FULL;
1074
1075 gfc_init_se (&argse, NULL);
1076 argse.descriptor_only = 1;
1077 gfc_conv_expr_descriptor (&argse, code->expr1);
1078 gfc_add_block_to_block (&se.pre, &argse.pre);
1079 desc = argse.expr;
1080 *ar = ar2;
1081
1082 extent = integer_one_node;
1083 for (i = 0; i < ar->dimen; i++)
1084 {
1085 gfc_init_se (&argse, NULL);
1086 gfc_conv_expr_type (&argse, ar->start[i], integer_type_node);
1087 gfc_add_block_to_block (&argse.pre, &argse.pre);
1088 lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[i]);
1089 tmp = fold_build2_loc (input_location, MINUS_EXPR,
1090 integer_type_node, argse.expr,
1091 fold_convert(integer_type_node, lbound));
1092 tmp = fold_build2_loc (input_location, MULT_EXPR,
1093 integer_type_node, extent, tmp);
1094 index = fold_build2_loc (input_location, PLUS_EXPR,
1095 integer_type_node, index, tmp);
1096 if (i < ar->dimen - 1)
1097 {
1098 ubound = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[i]);
1099 tmp = gfc_conv_array_extent_dim (lbound, ubound, NULL);
1100 tmp = fold_convert (integer_type_node, tmp);
1101 extent = fold_build2_loc (input_location, MULT_EXPR,
1102 integer_type_node, extent, tmp);
1103 }
1104 }
1105 }
1106
1107 /* errmsg. */
1108 if (code->expr3)
1109 {
1110 gfc_init_se (&argse, NULL);
1111 argse.want_pointer = 1;
1112 gfc_conv_expr (&argse, code->expr3);
1113 gfc_add_block_to_block (&se.pre, &argse.pre);
1114 errmsg = argse.expr;
1115 errmsg_len = fold_convert (integer_type_node, argse.string_length);
1116 }
1117 else
1118 {
1119 errmsg = null_pointer_node;
1120 errmsg_len = integer_zero_node;
1121 }
1122
1123 if (stat != null_pointer_node && TREE_TYPE (stat) != integer_type_node)
1124 {
1125 stat2 = stat;
1126 stat = gfc_create_var (integer_type_node, "stat");
1127 }
1128
1129 if (op == EXEC_EVENT_POST)
1130 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_event_post, 6,
1131 token, index, image_index,
1132 stat != null_pointer_node
1133 ? gfc_build_addr_expr (NULL, stat) : stat,
1134 errmsg, errmsg_len);
1135 else
1136 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_event_wait, 6,
1137 token, index, until_count,
1138 stat != null_pointer_node
1139 ? gfc_build_addr_expr (NULL, stat) : stat,
1140 errmsg, errmsg_len);
1141 gfc_add_expr_to_block (&se.pre, tmp);
1142
985f6c79
TB
1143 /* It guarantees memory consistency within the same segment */
1144 tmp = gfc_build_string_const (strlen ("memory")+1, "memory"),
1145 tmp = build5_loc (input_location, ASM_EXPR, void_type_node,
1146 gfc_build_string_const (1, ""), NULL_TREE, NULL_TREE,
1147 tree_cons (NULL_TREE, tmp, NULL_TREE), NULL_TREE);
1148 ASM_VOLATILE_P (tmp) = 1;
1149 gfc_add_expr_to_block (&se.pre, tmp);
1150
5df445a2
TB
1151 if (stat2 != NULL_TREE)
1152 gfc_add_modify (&se.pre, stat2, fold_convert (TREE_TYPE (stat2), stat));
1153
1154 return gfc_finish_block (&se.pre);
1155}
fea54935 1156
d0a4a61c 1157tree
60386f50 1158gfc_trans_sync (gfc_code *code, gfc_exec_op type)
d0a4a61c 1159{
60386f50
TB
1160 gfc_se se, argse;
1161 tree tmp;
1162 tree images = NULL_TREE, stat = NULL_TREE,
1163 errmsg = NULL_TREE, errmsglen = NULL_TREE;
d0a4a61c 1164
60386f50
TB
1165 /* Short cut: For single images without bound checking or without STAT=,
1166 return early. (ERRMSG= is always untouched for -fcoarray=single.) */
1167 if (!code->expr2 && !(gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
f19626cf 1168 && flag_coarray != GFC_FCOARRAY_LIB)
8b704316 1169 return NULL_TREE;
60386f50
TB
1170
1171 gfc_init_se (&se, NULL);
1172 gfc_start_block (&se.pre);
1173
1174 if (code->expr1 && code->expr1->rank == 0)
d0a4a61c 1175 {
60386f50
TB
1176 gfc_init_se (&argse, NULL);
1177 gfc_conv_expr_val (&argse, code->expr1);
1178 images = argse.expr;
1179 }
1180
1181 if (code->expr2)
1182 {
1183 gcc_assert (code->expr2->expr_type == EXPR_VARIABLE);
1184 gfc_init_se (&argse, NULL);
1185 gfc_conv_expr_val (&argse, code->expr2);
1186 stat = argse.expr;
1187 }
f5c01f5b
DC
1188 else
1189 stat = null_pointer_node;
60386f50 1190
9315dff0 1191 if (code->expr3 && flag_coarray == GFC_FCOARRAY_LIB)
60386f50
TB
1192 {
1193 gcc_assert (code->expr3->expr_type == EXPR_VARIABLE);
1194 gfc_init_se (&argse, NULL);
5df445a2 1195 argse.want_pointer = 1;
60386f50
TB
1196 gfc_conv_expr (&argse, code->expr3);
1197 gfc_conv_string_parameter (&argse);
f5c01f5b 1198 errmsg = gfc_build_addr_expr (NULL, argse.expr);
60386f50
TB
1199 errmsglen = argse.string_length;
1200 }
9315dff0 1201 else if (flag_coarray == GFC_FCOARRAY_LIB)
60386f50
TB
1202 {
1203 errmsg = null_pointer_node;
1204 errmsglen = build_int_cst (integer_type_node, 0);
d0a4a61c
TB
1205 }
1206
1207 /* Check SYNC IMAGES(imageset) for valid image index.
1cc0e193 1208 FIXME: Add a check for image-set arrays. */
d0a4a61c
TB
1209 if (code->expr1 && (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
1210 && code->expr1->rank == 0)
1211 {
1212 tree cond;
f19626cf 1213 if (flag_coarray != GFC_FCOARRAY_LIB)
63ee5404 1214 cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
60386f50
TB
1215 images, build_int_cst (TREE_TYPE (images), 1));
1216 else
1217 {
1218 tree cond2;
a8a5f4a9
TB
1219 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_num_images,
1220 2, integer_zero_node,
1221 build_int_cst (integer_type_node, -1));
63ee5404 1222 cond = fold_build2_loc (input_location, GT_EXPR, logical_type_node,
a8a5f4a9 1223 images, tmp);
63ee5404 1224 cond2 = fold_build2_loc (input_location, LT_EXPR, logical_type_node,
60386f50
TB
1225 images,
1226 build_int_cst (TREE_TYPE (images), 1));
45d5889a 1227 cond = fold_build2_loc (input_location, TRUTH_OR_EXPR,
63ee5404 1228 logical_type_node, cond, cond2);
60386f50 1229 }
d0a4a61c
TB
1230 gfc_trans_runtime_check (true, false, cond, &se.pre,
1231 &code->expr1->where, "Invalid image number "
1232 "%d in SYNC IMAGES",
74c49505 1233 fold_convert (integer_type_node, images));
d0a4a61c
TB
1234 }
1235
985f6c79
TB
1236 /* Per F2008, 8.5.1, a SYNC MEMORY is implied by calling the
1237 image control statements SYNC IMAGES and SYNC ALL. */
1238 if (flag_coarray == GFC_FCOARRAY_LIB)
1239 {
1240 tmp = gfc_build_string_const (strlen ("memory")+1, "memory"),
1241 tmp = build5_loc (input_location, ASM_EXPR, void_type_node,
1242 gfc_build_string_const (1, ""), NULL_TREE, NULL_TREE,
1243 tree_cons (NULL_TREE, tmp, NULL_TREE), NULL_TREE);
1244 ASM_VOLATILE_P (tmp) = 1;
1245 gfc_add_expr_to_block (&se.pre, tmp);
1246 }
1247
9315dff0 1248 if (flag_coarray != GFC_FCOARRAY_LIB)
d0a4a61c 1249 {
60386f50
TB
1250 /* Set STAT to zero. */
1251 if (code->expr2)
1252 gfc_add_modify (&se.pre, stat, build_int_cst (TREE_TYPE (stat), 0));
1253 }
9315dff0 1254 else if (type == EXEC_SYNC_ALL || type == EXEC_SYNC_MEMORY)
60386f50 1255 {
f5c01f5b
DC
1256 /* SYNC ALL => stat == null_pointer_node
1257 SYNC ALL(stat=s) => stat has an integer type
1258
1259 If "stat" has the wrong integer type, use a temp variable of
1260 the right type and later cast the result back into "stat". */
1261 if (stat == null_pointer_node || TREE_TYPE (stat) == integer_type_node)
1262 {
1263 if (TREE_TYPE (stat) == integer_type_node)
1264 stat = gfc_build_addr_expr (NULL, stat);
8b704316 1265
9315dff0
AF
1266 if(type == EXEC_SYNC_MEMORY)
1267 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_sync_memory,
1268 3, stat, errmsg, errmsglen);
1269 else
1270 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_sync_all,
1271 3, stat, errmsg, errmsglen);
1272
f5c01f5b
DC
1273 gfc_add_expr_to_block (&se.pre, tmp);
1274 }
60386f50 1275 else
f5c01f5b
DC
1276 {
1277 tree tmp_stat = gfc_create_var (integer_type_node, "stat");
1278
1279 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_sync_all,
1280 3, gfc_build_addr_expr (NULL, tmp_stat),
1281 errmsg, errmsglen);
1282 gfc_add_expr_to_block (&se.pre, tmp);
8b704316 1283
f5c01f5b
DC
1284 gfc_add_modify (&se.pre, stat,
1285 fold_convert (TREE_TYPE (stat), tmp_stat));
1286 }
60386f50
TB
1287 }
1288 else
1289 {
1290 tree len;
1291
1292 gcc_assert (type == EXEC_SYNC_IMAGES);
1293
1294 if (!code->expr1)
1295 {
1296 len = build_int_cst (integer_type_node, -1);
1297 images = null_pointer_node;
1298 }
1299 else if (code->expr1->rank == 0)
1300 {
1301 len = build_int_cst (integer_type_node, 1);
1302 images = gfc_build_addr_expr (NULL_TREE, images);
1303 }
1304 else
1305 {
1306 /* FIXME. */
1307 if (code->expr1->ts.kind != gfc_c_int_kind)
29e0597e
TB
1308 gfc_fatal_error ("Sorry, only support for integer kind %d "
1309 "implemented for image-set at %L",
1310 gfc_c_int_kind, &code->expr1->where);
60386f50 1311
2960a368 1312 gfc_conv_array_parameter (&se, code->expr1, true, NULL, NULL, &len);
60386f50
TB
1313 images = se.expr;
1314
1315 tmp = gfc_typenode_for_spec (&code->expr1->ts);
1316 if (GFC_ARRAY_TYPE_P (tmp) || GFC_DESCRIPTOR_TYPE_P (tmp))
1317 tmp = gfc_get_element_type (tmp);
1318
1319 len = fold_build2_loc (input_location, TRUNC_DIV_EXPR,
1320 TREE_TYPE (len), len,
1321 fold_convert (TREE_TYPE (len),
1322 TYPE_SIZE_UNIT (tmp)));
1323 len = fold_convert (integer_type_node, len);
1324 }
1325
f5c01f5b
DC
1326 /* SYNC IMAGES(imgs) => stat == null_pointer_node
1327 SYNC IMAGES(imgs,stat=s) => stat has an integer type
1328
1329 If "stat" has the wrong integer type, use a temp variable of
1330 the right type and later cast the result back into "stat". */
1331 if (stat == null_pointer_node || TREE_TYPE (stat) == integer_type_node)
1332 {
1333 if (TREE_TYPE (stat) == integer_type_node)
1334 stat = gfc_build_addr_expr (NULL, stat);
1335
8b704316 1336 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_sync_images,
f5c01f5b
DC
1337 5, fold_convert (integer_type_node, len),
1338 images, stat, errmsg, errmsglen);
1339 gfc_add_expr_to_block (&se.pre, tmp);
1340 }
60386f50 1341 else
f5c01f5b
DC
1342 {
1343 tree tmp_stat = gfc_create_var (integer_type_node, "stat");
1344
8b704316 1345 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_sync_images,
f5c01f5b
DC
1346 5, fold_convert (integer_type_node, len),
1347 images, gfc_build_addr_expr (NULL, tmp_stat),
1348 errmsg, errmsglen);
1349 gfc_add_expr_to_block (&se.pre, tmp);
1350
8b704316 1351 gfc_add_modify (&se.pre, stat,
f5c01f5b
DC
1352 fold_convert (TREE_TYPE (stat), tmp_stat));
1353 }
d0a4a61c
TB
1354 }
1355
60386f50 1356 return gfc_finish_block (&se.pre);
d0a4a61c
TB
1357}
1358
1359
6de9cd9a
DN
1360/* Generate GENERIC for the IF construct. This function also deals with
1361 the simple IF statement, because the front end translates the IF
1362 statement into an IF construct.
1363
1364 We translate:
1365
1366 IF (cond) THEN
1367 then_clause
1368 ELSEIF (cond2)
1369 elseif_clause
1370 ELSE
1371 else_clause
1372 ENDIF
1373
1374 into:
1375
1376 pre_cond_s;
1377 if (cond_s)
1378 {
1379 then_clause;
1380 }
1381 else
1382 {
1383 pre_cond_s
1384 if (cond_s)
1385 {
1386 elseif_clause
1387 }
1388 else
1389 {
1390 else_clause;
1391 }
1392 }
1393
1394 where COND_S is the simplified version of the predicate. PRE_COND_S
1395 are the pre side-effects produced by the translation of the
1396 conditional.
1397 We need to build the chain recursively otherwise we run into
1398 problems with folding incomplete statements. */
1399
1400static tree
1401gfc_trans_if_1 (gfc_code * code)
1402{
1403 gfc_se if_se;
1404 tree stmt, elsestmt;
e84589e1 1405 locus saved_loc;
55bd9c35 1406 location_t loc;
6de9cd9a
DN
1407
1408 /* Check for an unconditional ELSE clause. */
a513927a 1409 if (!code->expr1)
6de9cd9a
DN
1410 return gfc_trans_code (code->next);
1411
1412 /* Initialize a statement builder for each block. Puts in NULL_TREEs. */
1413 gfc_init_se (&if_se, NULL);
1414 gfc_start_block (&if_se.pre);
1415
1416 /* Calculate the IF condition expression. */
e84589e1
TB
1417 if (code->expr1->where.lb)
1418 {
1419 gfc_save_backend_locus (&saved_loc);
1420 gfc_set_backend_locus (&code->expr1->where);
1421 }
1422
a513927a 1423 gfc_conv_expr_val (&if_se, code->expr1);
6de9cd9a 1424
e84589e1
TB
1425 if (code->expr1->where.lb)
1426 gfc_restore_backend_locus (&saved_loc);
1427
6de9cd9a
DN
1428 /* Translate the THEN clause. */
1429 stmt = gfc_trans_code (code->next);
1430
1431 /* Translate the ELSE clause. */
1432 if (code->block)
1433 elsestmt = gfc_trans_if_1 (code->block);
1434 else
c2255bc4 1435 elsestmt = build_empty_stmt (input_location);
6de9cd9a
DN
1436
1437 /* Build the condition expression and add it to the condition block. */
55bd9c35
TB
1438 loc = code->expr1->where.lb ? code->expr1->where.lb->location : input_location;
1439 stmt = fold_build3_loc (loc, COND_EXPR, void_type_node, if_se.expr, stmt,
1440 elsestmt);
8b704316 1441
6de9cd9a
DN
1442 gfc_add_expr_to_block (&if_se.pre, stmt);
1443
1444 /* Finish off this statement. */
1445 return gfc_finish_block (&if_se.pre);
1446}
1447
1448tree
1449gfc_trans_if (gfc_code * code)
1450{
e5ca9693
DK
1451 stmtblock_t body;
1452 tree exit_label;
1453
1454 /* Create exit label so it is available for trans'ing the body code. */
1455 exit_label = gfc_build_label_decl (NULL_TREE);
1456 code->exit_label = exit_label;
1457
1458 /* Translate the actual code in code->block. */
1459 gfc_init_block (&body);
1460 gfc_add_expr_to_block (&body, gfc_trans_if_1 (code->block));
1461
1462 /* Add exit label. */
1463 gfc_add_expr_to_block (&body, build1_v (LABEL_EXPR, exit_label));
6de9cd9a 1464
e5ca9693 1465 return gfc_finish_block (&body);
6de9cd9a
DN
1466}
1467
1468
fa951694 1469/* Translate an arithmetic IF expression.
6de9cd9a
DN
1470
1471 IF (cond) label1, label2, label3 translates to
1472
1473 if (cond <= 0)
1474 {
1475 if (cond < 0)
1476 goto label1;
1477 else // cond == 0
1478 goto label2;
1479 }
1480 else // cond > 0
1481 goto label3;
442c1644
CY
1482
1483 An optimized version can be generated in case of equal labels.
1484 E.g., if label1 is equal to label2, we can translate it to
1485
1486 if (cond <= 0)
1487 goto label1;
1488 else
1489 goto label3;
6de9cd9a
DN
1490*/
1491
1492tree
1493gfc_trans_arithmetic_if (gfc_code * code)
1494{
1495 gfc_se se;
1496 tree tmp;
1497 tree branch1;
1498 tree branch2;
1499 tree zero;
1500
1501 /* Start a new block. */
1502 gfc_init_se (&se, NULL);
1503 gfc_start_block (&se.pre);
1504
1505 /* Pre-evaluate COND. */
a513927a 1506 gfc_conv_expr_val (&se, code->expr1);
5ec1334b 1507 se.expr = gfc_evaluate_now (se.expr, &se.pre);
6de9cd9a
DN
1508
1509 /* Build something to compare with. */
1510 zero = gfc_build_const (TREE_TYPE (se.expr), integer_zero_node);
1511
79bd1948 1512 if (code->label1->value != code->label2->value)
442c1644
CY
1513 {
1514 /* If (cond < 0) take branch1 else take branch2.
1515 First build jumps to the COND .LT. 0 and the COND .EQ. 0 cases. */
79bd1948 1516 branch1 = build1_v (GOTO_EXPR, gfc_get_label_decl (code->label1));
442c1644
CY
1517 branch2 = build1_v (GOTO_EXPR, gfc_get_label_decl (code->label2));
1518
79bd1948 1519 if (code->label1->value != code->label3->value)
63ee5404 1520 tmp = fold_build2_loc (input_location, LT_EXPR, logical_type_node,
bc98ed60 1521 se.expr, zero);
442c1644 1522 else
63ee5404 1523 tmp = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
bc98ed60 1524 se.expr, zero);
6de9cd9a 1525
bc98ed60
TB
1526 branch1 = fold_build3_loc (input_location, COND_EXPR, void_type_node,
1527 tmp, branch1, branch2);
442c1644
CY
1528 }
1529 else
79bd1948 1530 branch1 = build1_v (GOTO_EXPR, gfc_get_label_decl (code->label1));
6de9cd9a 1531
79bd1948 1532 if (code->label1->value != code->label3->value
442c1644
CY
1533 && code->label2->value != code->label3->value)
1534 {
1535 /* if (cond <= 0) take branch1 else take branch2. */
1536 branch2 = build1_v (GOTO_EXPR, gfc_get_label_decl (code->label3));
63ee5404 1537 tmp = fold_build2_loc (input_location, LE_EXPR, logical_type_node,
bc98ed60
TB
1538 se.expr, zero);
1539 branch1 = fold_build3_loc (input_location, COND_EXPR, void_type_node,
1540 tmp, branch1, branch2);
442c1644 1541 }
6de9cd9a
DN
1542
1543 /* Append the COND_EXPR to the evaluation of COND, and return. */
1544 gfc_add_expr_to_block (&se.pre, branch1);
1545 return gfc_finish_block (&se.pre);
1546}
1547
1548
1cc0e193 1549/* Translate a CRITICAL block. */
d0a4a61c
TB
1550tree
1551gfc_trans_critical (gfc_code *code)
1552{
1553 stmtblock_t block;
bc0229f9 1554 tree tmp, token = NULL_TREE;
d0a4a61c
TB
1555
1556 gfc_start_block (&block);
60386f50 1557
f19626cf 1558 if (flag_coarray == GFC_FCOARRAY_LIB)
60386f50 1559 {
bc0229f9
TB
1560 token = gfc_get_symbol_decl (code->resolved_sym);
1561 token = GFC_TYPE_ARRAY_CAF_TOKEN (TREE_TYPE (token));
1562 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_lock, 7,
1563 token, integer_zero_node, integer_one_node,
9de8e7af 1564 null_pointer_node, null_pointer_node,
bc0229f9 1565 null_pointer_node, integer_zero_node);
60386f50 1566 gfc_add_expr_to_block (&block, tmp);
985f6c79
TB
1567
1568 /* It guarantees memory consistency within the same segment */
1569 tmp = gfc_build_string_const (strlen ("memory")+1, "memory"),
1570 tmp = build5_loc (input_location, ASM_EXPR, void_type_node,
1571 gfc_build_string_const (1, ""),
1572 NULL_TREE, NULL_TREE,
1573 tree_cons (NULL_TREE, tmp, NULL_TREE),
1574 NULL_TREE);
1575 ASM_VOLATILE_P (tmp) = 1;
afbc5ae8 1576
985f6c79 1577 gfc_add_expr_to_block (&block, tmp);
60386f50
TB
1578 }
1579
d0a4a61c
TB
1580 tmp = gfc_trans_code (code->block->next);
1581 gfc_add_expr_to_block (&block, tmp);
1582
f19626cf 1583 if (flag_coarray == GFC_FCOARRAY_LIB)
60386f50 1584 {
bc0229f9
TB
1585 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_unlock, 6,
1586 token, integer_zero_node, integer_one_node,
1587 null_pointer_node, null_pointer_node,
1588 integer_zero_node);
60386f50 1589 gfc_add_expr_to_block (&block, tmp);
60386f50 1590
985f6c79
TB
1591 /* It guarantees memory consistency within the same segment */
1592 tmp = gfc_build_string_const (strlen ("memory")+1, "memory"),
1593 tmp = build5_loc (input_location, ASM_EXPR, void_type_node,
1594 gfc_build_string_const (1, ""),
1595 NULL_TREE, NULL_TREE,
1596 tree_cons (NULL_TREE, tmp, NULL_TREE),
1597 NULL_TREE);
1598 ASM_VOLATILE_P (tmp) = 1;
1599
1600 gfc_add_expr_to_block (&block, tmp);
1601 }
60386f50 1602
d0a4a61c
TB
1603 return gfc_finish_block (&block);
1604}
1605
1606
5b384b3d
PT
1607/* Return true, when the class has a _len component. */
1608
1609static bool
1610class_has_len_component (gfc_symbol *sym)
1611{
1612 gfc_component *comp = sym->ts.u.derived->components;
1613 while (comp)
1614 {
1615 if (strcmp (comp->name, "_len") == 0)
1616 return true;
1617 comp = comp->next;
1618 }
1619 return false;
1620}
1621
1622
6312ef45
JW
1623/* Do proper initialization for ASSOCIATE names. */
1624
1625static void
1626trans_associate_var (gfc_symbol *sym, gfc_wrapped_block *block)
1627{
1628 gfc_expr *e;
1629 tree tmp;
c49ea23d 1630 bool class_target;
8b704316 1631 bool unlimited;
8f75db9f
PT
1632 tree desc;
1633 tree offset;
1634 tree dim;
1635 int n;
5b384b3d
PT
1636 tree charlen;
1637 bool need_len_assign;
ff3598bc
PT
1638 bool whole_array = true;
1639 gfc_ref *ref;
707905d0 1640 symbol_attribute attr;
6312ef45
JW
1641
1642 gcc_assert (sym->assoc);
1643 e = sym->assoc->target;
1644
c49ea23d
PT
1645 class_target = (e->expr_type == EXPR_VARIABLE)
1646 && (gfc_is_class_scalar_expr (e)
1647 || gfc_is_class_array_ref (e, NULL));
1648
8b704316
PT
1649 unlimited = UNLIMITED_POLY (e);
1650
ff3598bc
PT
1651 for (ref = e->ref; ref; ref = ref->next)
1652 if (ref->type == REF_ARRAY
1653 && ref->u.ar.type == AR_FULL
1654 && ref->next)
1655 {
1656 whole_array = false;
1657 break;
1658 }
1659
5b384b3d
PT
1660 /* Assignments to the string length need to be generated, when
1661 ( sym is a char array or
1662 sym has a _len component)
1663 and the associated expression is unlimited polymorphic, which is
1664 not (yet) correctly in 'unlimited', because for an already associated
1665 BT_DERIVED the u-poly flag is not set, i.e.,
1666 __tmp_CHARACTER_0_1 => w => arg
1667 ^ generated temp ^ from code, the w does not have the u-poly
1668 flag set, where UNLIMITED_POLY(e) expects it. */
1669 need_len_assign = ((unlimited || (e->ts.type == BT_DERIVED
1670 && e->ts.u.derived->attr.unlimited_polymorphic))
1671 && (sym->ts.type == BT_CHARACTER
1672 || ((sym->ts.type == BT_CLASS || sym->ts.type == BT_DERIVED)
1673 && class_has_len_component (sym))));
6312ef45
JW
1674 /* Do a `pointer assignment' with updated descriptor (or assign descriptor
1675 to array temporary) for arrays with either unknown shape or if associating
1676 to a variable. */
c49ea23d 1677 if (sym->attr.dimension && !class_target
6312ef45
JW
1678 && (sym->as->type == AS_DEFERRED || sym->assoc->variable))
1679 {
1680 gfc_se se;
6312ef45 1681 tree desc;
bcac046f 1682 bool cst_array_ctor;
6312ef45
JW
1683
1684 desc = sym->backend_decl;
bcac046f 1685 cst_array_ctor = e->expr_type == EXPR_ARRAY
84ee745e
PT
1686 && gfc_constant_array_constructor_p (e->value.constructor)
1687 && e->ts.type != BT_CHARACTER;
6312ef45
JW
1688
1689 /* If association is to an expression, evaluate it and create temporary.
1690 Otherwise, get descriptor of target for pointer assignment. */
1691 gfc_init_se (&se, NULL);
bcac046f 1692 if (sym->assoc->variable || cst_array_ctor)
6312ef45
JW
1693 {
1694 se.direct_byref = 1;
1cf43a1d 1695 se.use_offset = 1;
6312ef45
JW
1696 se.expr = desc;
1697 }
1cf43a1d 1698
2960a368 1699 gfc_conv_expr_descriptor (&se, e);
6312ef45 1700
707905d0
PT
1701 if (sym->ts.type == BT_CHARACTER
1702 && sym->ts.deferred
1703 && !sym->attr.select_type_temporary
1704 && VAR_P (sym->ts.u.cl->backend_decl)
1705 && se.string_length != sym->ts.u.cl->backend_decl)
1706 {
1707 gfc_add_modify (&se.pre, sym->ts.u.cl->backend_decl,
f622221a 1708 fold_convert (TREE_TYPE (sym->ts.u.cl->backend_decl),
707905d0
PT
1709 se.string_length));
1710 }
1711
6312ef45
JW
1712 /* If we didn't already do the pointer assignment, set associate-name
1713 descriptor to the one generated for the temporary. */
ff3598bc
PT
1714 if ((!sym->assoc->variable && !cst_array_ctor)
1715 || !whole_array)
6312ef45
JW
1716 {
1717 int dim;
1718
ff3598bc
PT
1719 if (whole_array)
1720 gfc_add_modify (&se.pre, desc, se.expr);
6312ef45
JW
1721
1722 /* The generated descriptor has lower bound zero (as array
1723 temporary), shift bounds so we get lower bounds of 1. */
1724 for (dim = 0; dim < e->rank; ++dim)
1725 gfc_conv_shift_descriptor_lbound (&se.pre, desc,
1726 dim, gfc_index_one_node);
1727 }
1728
68b1c5e1
PT
1729 /* If this is a subreference array pointer associate name use the
1730 associate variable element size for the value of 'span'. */
1731 if (sym->attr.subref_array_pointer)
1732 {
1733 gcc_assert (e->expr_type == EXPR_VARIABLE);
76fe932b
AV
1734 tmp = e->symtree->n.sym->ts.type == BT_CLASS
1735 ? gfc_class_data_get (e->symtree->n.sym->backend_decl)
1736 : e->symtree->n.sym->backend_decl;
68b1c5e1
PT
1737 tmp = gfc_get_element_type (TREE_TYPE (tmp));
1738 tmp = fold_convert (gfc_array_index_type, size_in_bytes (tmp));
ff3598bc 1739 gfc_conv_descriptor_span_set (&se.pre, desc, tmp);
68b1c5e1
PT
1740 }
1741
0b627b58
PT
1742 if (e->expr_type == EXPR_FUNCTION
1743 && sym->ts.type == BT_DERIVED
1744 && sym->ts.u.derived
1745 && sym->ts.u.derived->attr.pdt_type)
1746 {
1747 tmp = gfc_deallocate_pdt_comp (sym->ts.u.derived, se.expr,
1748 sym->as->rank);
1749 gfc_add_expr_to_block (&se.post, tmp);
1750 }
1751
6312ef45
JW
1752 /* Done, register stuff as init / cleanup code. */
1753 gfc_add_init_cleanup (block, gfc_finish_block (&se.pre),
1754 gfc_finish_block (&se.post));
1755 }
1756
8b704316
PT
1757 /* Temporaries, arising from TYPE IS, just need the descriptor of class
1758 arrays to be assigned directly. */
1759 else if (class_target && sym->attr.dimension
1760 && (sym->ts.type == BT_DERIVED || unlimited))
c49ea23d
PT
1761 {
1762 gfc_se se;
1763
1764 gfc_init_se (&se, NULL);
102344e2 1765 se.descriptor_only = 1;
f3b0bb7a
AV
1766 /* In a select type the (temporary) associate variable shall point to
1767 a standard fortran array (lower bound == 1), but conv_expr ()
1768 just maps to the input array in the class object, whose lbound may
1769 be arbitrary. conv_expr_descriptor solves this by inserting a
1770 temporary array descriptor. */
1771 gfc_conv_expr_descriptor (&se, e);
c49ea23d 1772
f3b0bb7a
AV
1773 gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se.expr))
1774 || GFC_ARRAY_TYPE_P (TREE_TYPE (se.expr)));
c49ea23d
PT
1775 gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (sym->backend_decl)));
1776
f3b0bb7a
AV
1777 if (GFC_ARRAY_TYPE_P (TREE_TYPE (se.expr)))
1778 {
1779 if (INDIRECT_REF_P (se.expr))
1780 tmp = TREE_OPERAND (se.expr, 0);
1781 else
1782 tmp = se.expr;
1783
1784 gfc_add_modify (&se.pre, sym->backend_decl,
1785 gfc_class_data_get (GFC_DECL_SAVED_DESCRIPTOR (tmp)));
1786 }
1787 else
1788 gfc_add_modify (&se.pre, sym->backend_decl, se.expr);
8b704316
PT
1789
1790 if (unlimited)
1791 {
1792 /* Recover the dtype, which has been overwritten by the
1793 assignment from an unlimited polymorphic object. */
1794 tmp = gfc_conv_descriptor_dtype (sym->backend_decl);
1795 gfc_add_modify (&se.pre, tmp,
1796 gfc_get_dtype (TREE_TYPE (sym->backend_decl)));
1797 }
1798
f3b0bb7a 1799 gfc_add_init_cleanup (block, gfc_finish_block (&se.pre),
c49ea23d
PT
1800 gfc_finish_block (&se.post));
1801 }
1802
6312ef45
JW
1803 /* Do a scalar pointer assignment; this is for scalar variable targets. */
1804 else if (gfc_is_associate_pointer (sym))
1805 {
1806 gfc_se se;
1807
1808 gcc_assert (!sym->attr.dimension);
1809
1810 gfc_init_se (&se, NULL);
8f75db9f
PT
1811
1812 /* Class associate-names come this way because they are
1813 unconditionally associate pointers and the symbol is scalar. */
1814 if (sym->ts.type == BT_CLASS && CLASS_DATA (sym)->attr.dimension)
1815 {
5b384b3d 1816 tree target_expr;
8f75db9f 1817 /* For a class array we need a descriptor for the selector. */
2960a368 1818 gfc_conv_expr_descriptor (&se, e);
5b384b3d
PT
1819 /* Needed to get/set the _len component below. */
1820 target_expr = se.expr;
8f75db9f 1821
8b704316 1822 /* Obtain a temporary class container for the result. */
16e82b25 1823 gfc_conv_class_to_class (&se, e, sym->ts, false, true, false, false);
8f75db9f
PT
1824 se.expr = build_fold_indirect_ref_loc (input_location, se.expr);
1825
1826 /* Set the offset. */
1827 desc = gfc_class_data_get (se.expr);
1828 offset = gfc_index_zero_node;
1829 for (n = 0; n < e->rank; n++)
1830 {
1831 dim = gfc_rank_cst[n];
1832 tmp = fold_build2_loc (input_location, MULT_EXPR,
1833 gfc_array_index_type,
1834 gfc_conv_descriptor_stride_get (desc, dim),
1835 gfc_conv_descriptor_lbound_get (desc, dim));
1836 offset = fold_build2_loc (input_location, MINUS_EXPR,
1837 gfc_array_index_type,
1838 offset, tmp);
1839 }
5b384b3d
PT
1840 if (need_len_assign)
1841 {
f3b0bb7a
AV
1842 if (e->symtree
1843 && DECL_LANG_SPECIFIC (e->symtree->n.sym->backend_decl)
1844 && GFC_DECL_SAVED_DESCRIPTOR (e->symtree->n.sym->backend_decl))
1845 /* Use the original class descriptor stored in the saved
1846 descriptor to get the target_expr. */
1847 target_expr =
1848 GFC_DECL_SAVED_DESCRIPTOR (e->symtree->n.sym->backend_decl);
1849 else
1850 /* Strip the _data component from the target_expr. */
1851 target_expr = TREE_OPERAND (target_expr, 0);
1852 /* Add a reference to the _len comp to the target expr. */
1853 tmp = gfc_class_len_get (target_expr);
5b384b3d
PT
1854 /* Get the component-ref for the temp structure's _len comp. */
1855 charlen = gfc_class_len_get (se.expr);
026c3cfd 1856 /* Add the assign to the beginning of the block... */
5b384b3d
PT
1857 gfc_add_modify (&se.pre, charlen,
1858 fold_convert (TREE_TYPE (charlen), tmp));
1859 /* and the oposite way at the end of the block, to hand changes
1860 on the string length back. */
1861 gfc_add_modify (&se.post, tmp,
1862 fold_convert (TREE_TYPE (tmp), charlen));
1863 /* Length assignment done, prevent adding it again below. */
1864 need_len_assign = false;
1865 }
8f75db9f
PT
1866 gfc_conv_descriptor_offset_set (&se.pre, desc, offset);
1867 }
1868 else if (sym->ts.type == BT_CLASS && e->ts.type == BT_CLASS
1869 && CLASS_DATA (e)->attr.dimension)
1870 {
1871 /* This is bound to be a class array element. */
1872 gfc_conv_expr_reference (&se, e);
8b704316 1873 /* Get the _vptr component of the class object. */
8f75db9f
PT
1874 tmp = gfc_get_vptr_from_expr (se.expr);
1875 /* Obtain a temporary class container for the result. */
16e82b25 1876 gfc_conv_derived_to_class (&se, e, sym->ts, tmp, false, false);
8f75db9f
PT
1877 se.expr = build_fold_indirect_ref_loc (input_location, se.expr);
1878 }
1879 else
5b384b3d
PT
1880 {
1881 /* For BT_CLASS and BT_DERIVED, this boils down to a pointer assign,
1882 which has the string length included. For CHARACTERS it is still
1883 needed and will be done at the end of this routine. */
1884 gfc_conv_expr (&se, e);
1885 need_len_assign = need_len_assign && sym->ts.type == BT_CHARACTER;
1886 }
6312ef45 1887
707905d0
PT
1888 if (sym->ts.type == BT_CHARACTER
1889 && sym->ts.deferred
1890 && !sym->attr.select_type_temporary
1891 && VAR_P (sym->ts.u.cl->backend_decl)
1892 && se.string_length != sym->ts.u.cl->backend_decl)
1893 {
1894 gfc_add_modify (&se.pre, sym->ts.u.cl->backend_decl,
f622221a 1895 fold_convert (TREE_TYPE (sym->ts.u.cl->backend_decl),
707905d0
PT
1896 se.string_length));
1897 if (e->expr_type == EXPR_FUNCTION)
1898 {
1899 tmp = gfc_call_free (sym->backend_decl);
1900 gfc_add_expr_to_block (&se.post, tmp);
1901 }
1902 }
1903
1904 attr = gfc_expr_attr (e);
1905 if (sym->ts.type == BT_CHARACTER && e->ts.type == BT_CHARACTER
1906 && (attr.allocatable || attr.pointer || attr.dummy))
1907 {
1908 /* These are pointer types already. */
1909 tmp = fold_convert (TREE_TYPE (sym->backend_decl), se.expr);
1910 }
1911 else
1912 {
1913 tmp = TREE_TYPE (sym->backend_decl);
1914 tmp = gfc_build_addr_expr (tmp, se.expr);
1915 }
1916
6312ef45 1917 gfc_add_modify (&se.pre, sym->backend_decl, tmp);
8b704316 1918
6312ef45
JW
1919 gfc_add_init_cleanup (block, gfc_finish_block( &se.pre),
1920 gfc_finish_block (&se.post));
1921 }
1922
1923 /* Do a simple assignment. This is for scalar expressions, where we
1924 can simply use expression assignment. */
1925 else
1926 {
1927 gfc_expr *lhs;
0b627b58 1928 tree res;
a8399af8
PT
1929 gfc_se se;
1930
1931 gfc_init_se (&se, NULL);
1932
1933 /* resolve.c converts some associate names to allocatable so that
1934 allocation can take place automatically in gfc_trans_assignment.
1935 The frontend prevents them from being either allocated,
1936 deallocated or reallocated. */
1937 if (sym->attr.allocatable)
1938 {
1939 tmp = sym->backend_decl;
1940 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp)))
1941 tmp = gfc_conv_descriptor_data_get (tmp);
1942 gfc_add_modify (&se.pre, tmp, fold_convert (TREE_TYPE (tmp),
1943 null_pointer_node));
1944 }
6312ef45
JW
1945
1946 lhs = gfc_lval_expr_from_sym (sym);
0b627b58 1947 res = gfc_trans_assignment (lhs, e, false, true);
a8399af8 1948 gfc_add_expr_to_block (&se.pre, res);
0b627b58
PT
1949
1950 tmp = sym->backend_decl;
1951 if (e->expr_type == EXPR_FUNCTION
1952 && sym->ts.type == BT_DERIVED
1953 && sym->ts.u.derived
1954 && sym->ts.u.derived->attr.pdt_type)
1955 {
1956 tmp = gfc_deallocate_pdt_comp (sym->ts.u.derived, tmp,
1957 0);
1958 }
1959 else if (e->expr_type == EXPR_FUNCTION
1960 && sym->ts.type == BT_CLASS
1961 && CLASS_DATA (sym)->ts.u.derived
1962 && CLASS_DATA (sym)->ts.u.derived->attr.pdt_type)
1963 {
1964 tmp = gfc_class_data_get (tmp);
1965 tmp = gfc_deallocate_pdt_comp (CLASS_DATA (sym)->ts.u.derived,
1966 tmp, 0);
1967 }
a8399af8
PT
1968 else if (sym->attr.allocatable)
1969 {
1970 tmp = sym->backend_decl;
1971
1972 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp)))
1973 tmp = gfc_conv_descriptor_data_get (tmp);
1974
1975 /* A simple call to free suffices here. */
1976 tmp = gfc_call_free (tmp);
1977
1978 /* Make sure that reallocation on assignment cannot occur. */
1979 sym->attr.allocatable = 0;
1980 }
1981 else
1982 tmp = NULL_TREE;
0b627b58 1983
a8399af8 1984 res = gfc_finish_block (&se.pre);
0b627b58 1985 gfc_add_init_cleanup (block, res, tmp);
a8399af8 1986 gfc_free_expr (lhs);
6312ef45 1987 }
8b704316 1988
5b384b3d
PT
1989 /* Set the stringlength, when needed. */
1990 if (need_len_assign)
8b704316 1991 {
8b704316
PT
1992 gfc_se se;
1993 gfc_init_se (&se, NULL);
5b384b3d
PT
1994 if (e->symtree->n.sym->ts.type == BT_CHARACTER)
1995 {
707905d0 1996 /* Deferred strings are dealt with in the preceeding. */
5b384b3d
PT
1997 gcc_assert (!e->symtree->n.sym->ts.deferred);
1998 tmp = e->symtree->n.sym->ts.u.cl->backend_decl;
1999 }
6017b8f0 2000 else if (e->symtree->n.sym->attr.function
a7d3cd40 2001 && e->symtree->n.sym == e->symtree->n.sym->result)
6017b8f0
PT
2002 {
2003 tmp = gfc_get_fake_result_decl (e->symtree->n.sym, 0);
2004 tmp = gfc_class_len_get (tmp);
2005 }
5b384b3d
PT
2006 else
2007 tmp = gfc_class_len_get (gfc_get_symbol_decl (e->symtree->n.sym));
8b704316 2008 gfc_get_symbol_decl (sym);
5b384b3d
PT
2009 charlen = sym->ts.type == BT_CHARACTER ? sym->ts.u.cl->backend_decl
2010 : gfc_class_len_get (sym->backend_decl);
2011 /* Prevent adding a noop len= len. */
2012 if (tmp != charlen)
2013 {
2014 gfc_add_modify (&se.pre, charlen,
2015 fold_convert (TREE_TYPE (charlen), tmp));
2016 gfc_add_init_cleanup (block, gfc_finish_block (&se.pre),
2017 gfc_finish_block (&se.post));
2018 }
8b704316 2019 }
6312ef45
JW
2020}
2021
2022
9abe5e56
DK
2023/* Translate a BLOCK construct. This is basically what we would do for a
2024 procedure body. */
2025
2026tree
2027gfc_trans_block_construct (gfc_code* code)
2028{
2029 gfc_namespace* ns;
2030 gfc_symbol* sym;
e5ca9693
DK
2031 gfc_wrapped_block block;
2032 tree exit_label;
2033 stmtblock_t body;
6312ef45 2034 gfc_association_list *ass;
9abe5e56 2035
03af1e4c 2036 ns = code->ext.block.ns;
9abe5e56
DK
2037 gcc_assert (ns);
2038 sym = ns->proc_name;
2039 gcc_assert (sym);
2040
e5ca9693 2041 /* Process local variables. */
9abe5e56
DK
2042 gcc_assert (!sym->tlink);
2043 sym->tlink = sym;
6312ef45 2044 gfc_process_block_locals (ns);
9abe5e56 2045
e5ca9693
DK
2046 /* Generate code including exit-label. */
2047 gfc_init_block (&body);
2048 exit_label = gfc_build_label_decl (NULL_TREE);
2049 code->exit_label = exit_label;
41dbbb37 2050
dc7a8b4b 2051 finish_oacc_declare (ns, sym, true);
41dbbb37 2052
e5ca9693
DK
2053 gfc_add_expr_to_block (&body, gfc_trans_code (ns->code));
2054 gfc_add_expr_to_block (&body, build1_v (LABEL_EXPR, exit_label));
2055
2056 /* Finish everything. */
2057 gfc_start_wrapped_block (&block, gfc_finish_block (&body));
2058 gfc_trans_deferred_vars (sym, &block);
6312ef45
JW
2059 for (ass = code->ext.block.assoc; ass; ass = ass->next)
2060 trans_associate_var (ass->st->n.sym, &block);
8b704316 2061
e5ca9693 2062 return gfc_finish_wrapped_block (&block);
9abe5e56
DK
2063}
2064
1c122092
ML
2065/* Translate the simple DO construct in a C-style manner.
2066 This is where the loop variable has integer type and step +-1.
2067 Following code will generate infinite loop in case where TO is INT_MAX
2068 (for +1 step) or INT_MIN (for -1 step)
9abe5e56 2069
fbdad37d
PB
2070 We translate a do loop from:
2071
2072 DO dovar = from, to, step
2073 body
2074 END DO
2075
2076 to:
2077
2078 [Evaluate loop bounds and step]
1c122092
ML
2079 dovar = from;
2080 for (;;)
2081 {
2082 if (dovar > to)
2083 goto end_label;
2084 body;
2085 cycle_label:
2086 dovar += step;
fbdad37d 2087 }
1c122092 2088 end_label:
fbdad37d 2089
1c122092
ML
2090 This helps the optimizers by avoiding the extra pre-header condition and
2091 we save a register as we just compare the updated IV (not a value in
2092 previous step). */
fbdad37d
PB
2093
2094static tree
2095gfc_trans_simple_do (gfc_code * code, stmtblock_t *pblock, tree dovar,
bc51e726 2096 tree from, tree to, tree step, tree exit_cond)
fbdad37d
PB
2097{
2098 stmtblock_t body;
2099 tree type;
2100 tree cond;
2101 tree tmp;
33abc845 2102 tree saved_dovar = NULL;
fbdad37d
PB
2103 tree cycle_label;
2104 tree exit_label;
55bd9c35 2105 location_t loc;
fbdad37d 2106 type = TREE_TYPE (dovar);
1c122092 2107 bool is_step_positive = tree_int_cst_sgn (step) > 0;
fbdad37d 2108
55bd9c35
TB
2109 loc = code->ext.iterator->start->where.lb->location;
2110
fbdad37d 2111 /* Initialize the DO variable: dovar = from. */
8594f636 2112 gfc_add_modify_loc (loc, pblock, dovar,
1c122092 2113 fold_convert (TREE_TYPE (dovar), from));
8b704316 2114
1cc0e193 2115 /* Save value for do-tinkering checking. */
33abc845
TB
2116 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
2117 {
2118 saved_dovar = gfc_create_var (type, ".saved_dovar");
55bd9c35 2119 gfc_add_modify_loc (loc, pblock, saved_dovar, dovar);
33abc845 2120 }
fbdad37d
PB
2121
2122 /* Cycle and exit statements are implemented with gotos. */
2123 cycle_label = gfc_build_label_decl (NULL_TREE);
2124 exit_label = gfc_build_label_decl (NULL_TREE);
2125
1c122092 2126 /* Put the labels where they can be found later. See gfc_trans_do(). */
e5ca9693
DK
2127 code->cycle_label = cycle_label;
2128 code->exit_label = exit_label;
fbdad37d
PB
2129
2130 /* Loop body. */
2131 gfc_start_block (&body);
2132
1c122092
ML
2133 /* Exit the loop if there is an I/O result condition or error. */
2134 if (exit_cond)
2135 {
2136 tmp = build1_v (GOTO_EXPR, exit_label);
2137 tmp = fold_build3_loc (loc, COND_EXPR, void_type_node,
2138 exit_cond, tmp,
2139 build_empty_stmt (loc));
2140 gfc_add_expr_to_block (&body, tmp);
2141 }
2142
2143 /* Evaluate the loop condition. */
2144 if (is_step_positive)
63ee5404 2145 cond = fold_build2_loc (loc, GT_EXPR, logical_type_node, dovar,
1c122092
ML
2146 fold_convert (type, to));
2147 else
63ee5404 2148 cond = fold_build2_loc (loc, LT_EXPR, logical_type_node, dovar,
1c122092
ML
2149 fold_convert (type, to));
2150
2151 cond = gfc_evaluate_now_loc (loc, cond, &body);
170a8bd6
EB
2152 if (code->ext.iterator->unroll && cond != error_mark_node)
2153 cond
2154 = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
2155 build_int_cst (integer_type_node, annot_expr_unroll_kind),
2156 build_int_cst (integer_type_node, code->ext.iterator->unroll));
1c122092
ML
2157
2158 /* The loop exit. */
2159 tmp = fold_build1_loc (loc, GOTO_EXPR, void_type_node, exit_label);
2160 TREE_USED (exit_label) = 1;
2161 tmp = fold_build3_loc (loc, COND_EXPR, void_type_node,
2162 cond, tmp, build_empty_stmt (loc));
2163 gfc_add_expr_to_block (&body, tmp);
2164
2165 /* Check whether the induction variable is equal to INT_MAX
2166 (respectively to INT_MIN). */
2167 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
2168 {
2169 tree boundary = is_step_positive ? TYPE_MAX_VALUE (type)
2170 : TYPE_MIN_VALUE (type);
2171
63ee5404 2172 tmp = fold_build2_loc (loc, EQ_EXPR, logical_type_node,
1c122092
ML
2173 dovar, boundary);
2174 gfc_trans_runtime_check (true, false, tmp, &body, &code->loc,
2175 "Loop iterates infinitely");
2176 }
2177
fbdad37d 2178 /* Main loop body. */
bc51e726 2179 tmp = gfc_trans_code_cond (code->block->next, exit_cond);
fbdad37d
PB
2180 gfc_add_expr_to_block (&body, tmp);
2181
2182 /* Label for cycle statements (if needed). */
2183 if (TREE_USED (cycle_label))
2184 {
2185 tmp = build1_v (LABEL_EXPR, cycle_label);
2186 gfc_add_expr_to_block (&body, tmp);
2187 }
2188
1cc0e193 2189 /* Check whether someone has modified the loop variable. */
33abc845
TB
2190 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
2191 {
63ee5404 2192 tmp = fold_build2_loc (loc, NE_EXPR, logical_type_node,
bc98ed60 2193 dovar, saved_dovar);
33abc845
TB
2194 gfc_trans_runtime_check (true, false, tmp, &body, &code->loc,
2195 "Loop variable has been modified");
2196 }
2197
fbdad37d 2198 /* Increment the loop variable. */
55bd9c35
TB
2199 tmp = fold_build2_loc (loc, PLUS_EXPR, type, dovar, step);
2200 gfc_add_modify_loc (loc, &body, dovar, tmp);
fbdad37d 2201
33abc845 2202 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
55bd9c35 2203 gfc_add_modify_loc (loc, &body, saved_dovar, dovar);
33abc845 2204
fbdad37d
PB
2205 /* Finish the loop body. */
2206 tmp = gfc_finish_block (&body);
55bd9c35 2207 tmp = fold_build1_loc (loc, LOOP_EXPR, void_type_node, tmp);
fbdad37d 2208
fbdad37d
PB
2209 gfc_add_expr_to_block (pblock, tmp);
2210
2211 /* Add the exit label. */
2212 tmp = build1_v (LABEL_EXPR, exit_label);
2213 gfc_add_expr_to_block (pblock, tmp);
2214
2215 return gfc_finish_block (pblock);
2216}
2217
6de9cd9a
DN
2218/* Translate the DO construct. This obviously is one of the most
2219 important ones to get right with any compiler, but especially
2220 so for Fortran.
2221
fbdad37d
PB
2222 We special case some loop forms as described in gfc_trans_simple_do.
2223 For other cases we implement them with a separate loop count,
2224 as described in the standard.
6de9cd9a
DN
2225
2226 We translate a do loop from:
2227
2228 DO dovar = from, to, step
2229 body
2230 END DO
2231
2232 to:
2233
fbdad37d 2234 [evaluate loop bounds and step]
5d148c08
FXC
2235 empty = (step > 0 ? to < from : to > from);
2236 countm1 = (to - from) / step;
fbdad37d 2237 dovar = from;
5d148c08 2238 if (empty) goto exit_label;
fbdad37d 2239 for (;;)
6de9cd9a
DN
2240 {
2241 body;
2242cycle_label:
fbdad37d 2243 dovar += step
8c01de7f 2244 countm1t = countm1;
76dac339 2245 countm1--;
8c01de7f 2246 if (countm1t == 0) goto exit_label;
6de9cd9a
DN
2247 }
2248exit_label:
2249
5d148c08
FXC
2250 countm1 is an unsigned integer. It is equal to the loop count minus one,
2251 because the loop count itself can overflow. */
6de9cd9a
DN
2252
2253tree
bc51e726 2254gfc_trans_do (gfc_code * code, tree exit_cond)
6de9cd9a
DN
2255{
2256 gfc_se se;
2257 tree dovar;
33abc845 2258 tree saved_dovar = NULL;
6de9cd9a
DN
2259 tree from;
2260 tree to;
2261 tree step;
5d148c08 2262 tree countm1;
6de9cd9a 2263 tree type;
5d148c08 2264 tree utype;
6de9cd9a
DN
2265 tree cond;
2266 tree cycle_label;
2267 tree exit_label;
2268 tree tmp;
2269 stmtblock_t block;
2270 stmtblock_t body;
55bd9c35 2271 location_t loc;
6de9cd9a
DN
2272
2273 gfc_start_block (&block);
2274
55bd9c35
TB
2275 loc = code->ext.iterator->start->where.lb->location;
2276
fbdad37d 2277 /* Evaluate all the expressions in the iterator. */
6de9cd9a
DN
2278 gfc_init_se (&se, NULL);
2279 gfc_conv_expr_lhs (&se, code->ext.iterator->var);
2280 gfc_add_block_to_block (&block, &se.pre);
2281 dovar = se.expr;
2282 type = TREE_TYPE (dovar);
2283
2284 gfc_init_se (&se, NULL);
8d5cfa27 2285 gfc_conv_expr_val (&se, code->ext.iterator->start);
6de9cd9a 2286 gfc_add_block_to_block (&block, &se.pre);
fbdad37d 2287 from = gfc_evaluate_now (se.expr, &block);
6de9cd9a
DN
2288
2289 gfc_init_se (&se, NULL);
8d5cfa27 2290 gfc_conv_expr_val (&se, code->ext.iterator->end);
6de9cd9a 2291 gfc_add_block_to_block (&block, &se.pre);
fbdad37d 2292 to = gfc_evaluate_now (se.expr, &block);
6de9cd9a
DN
2293
2294 gfc_init_se (&se, NULL);
8d5cfa27 2295 gfc_conv_expr_val (&se, code->ext.iterator->step);
6de9cd9a 2296 gfc_add_block_to_block (&block, &se.pre);
fbdad37d
PB
2297 step = gfc_evaluate_now (se.expr, &block);
2298
33abc845
TB
2299 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
2300 {
63ee5404 2301 tmp = fold_build2_loc (input_location, EQ_EXPR, logical_type_node, step,
e8160c9a 2302 build_zero_cst (type));
33abc845
TB
2303 gfc_trans_runtime_check (true, false, tmp, &block, &code->loc,
2304 "DO step value is zero");
2305 }
2306
fbdad37d
PB
2307 /* Special case simple loops. */
2308 if (TREE_CODE (type) == INTEGER_TYPE
2309 && (integer_onep (step)
2310 || tree_int_cst_equal (step, integer_minus_one_node)))
1c122092
ML
2311 return gfc_trans_simple_do (code, &block, dovar, from, to, step,
2312 exit_cond);
6de9cd9a 2313
8d5cfa27 2314 if (TREE_CODE (type) == INTEGER_TYPE)
c0b29099
JJ
2315 utype = unsigned_type_for (type);
2316 else
2317 utype = unsigned_type_for (gfc_array_index_type);
2318 countm1 = gfc_create_var (utype, "countm1");
5d148c08 2319
c0b29099
JJ
2320 /* Cycle and exit statements are implemented with gotos. */
2321 cycle_label = gfc_build_label_decl (NULL_TREE);
2322 exit_label = gfc_build_label_decl (NULL_TREE);
2323 TREE_USED (exit_label) = 1;
2324
e5ca9693
DK
2325 /* Put these labels where they can be found later. */
2326 code->cycle_label = cycle_label;
2327 code->exit_label = exit_label;
2328
c0b29099
JJ
2329 /* Initialize the DO variable: dovar = from. */
2330 gfc_add_modify (&block, dovar, from);
2331
1cc0e193 2332 /* Save value for do-tinkering checking. */
33abc845
TB
2333 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
2334 {
2335 saved_dovar = gfc_create_var (type, ".saved_dovar");
55bd9c35 2336 gfc_add_modify_loc (loc, &block, saved_dovar, dovar);
33abc845
TB
2337 }
2338
c0b29099
JJ
2339 /* Initialize loop count and jump to exit label if the loop is empty.
2340 This code is executed before we enter the loop body. We generate:
2341 if (step > 0)
2342 {
d17271de 2343 countm1 = (to - from) / step;
8146bb58
TK
2344 if (to < from)
2345 goto exit_label;
c0b29099
JJ
2346 }
2347 else
2348 {
d17271de 2349 countm1 = (from - to) / -step;
8146bb58
TK
2350 if (to > from)
2351 goto exit_label;
2352 }
c5e7e996 2353 */
8146bb58 2354
c0b29099
JJ
2355 if (TREE_CODE (type) == INTEGER_TYPE)
2356 {
c5e7e996 2357 tree pos, neg, tou, fromu, stepu, tmp2;
8146bb58 2358
c5e7e996
RB
2359 /* The distance from FROM to TO cannot always be represented in a signed
2360 type, thus use unsigned arithmetic, also to avoid any undefined
2361 overflow issues. */
2362 tou = fold_convert (utype, to);
2363 fromu = fold_convert (utype, from);
2364 stepu = fold_convert (utype, step);
5d148c08 2365
c5e7e996
RB
2366 /* For a positive step, when to < from, exit, otherwise compute
2367 countm1 = ((unsigned)to - (unsigned)from) / (unsigned)step */
63ee5404 2368 tmp = fold_build2_loc (loc, LT_EXPR, logical_type_node, to, from);
c5e7e996
RB
2369 tmp2 = fold_build2_loc (loc, TRUNC_DIV_EXPR, utype,
2370 fold_build2_loc (loc, MINUS_EXPR, utype,
2371 tou, fromu),
2372 stepu);
d17271de
RB
2373 pos = build2 (COMPOUND_EXPR, void_type_node,
2374 fold_build2 (MODIFY_EXPR, void_type_node,
2375 countm1, tmp2),
7119f1b1
ML
2376 build3_loc (loc, COND_EXPR, void_type_node,
2377 gfc_unlikely (tmp, PRED_FORTRAN_LOOP_PREHEADER),
d17271de
RB
2378 build1_loc (loc, GOTO_EXPR, void_type_node,
2379 exit_label), NULL_TREE));
c5e7e996
RB
2380
2381 /* For a negative step, when to > from, exit, otherwise compute
2382 countm1 = ((unsigned)from - (unsigned)to) / -(unsigned)step */
63ee5404 2383 tmp = fold_build2_loc (loc, GT_EXPR, logical_type_node, to, from);
c5e7e996
RB
2384 tmp2 = fold_build2_loc (loc, TRUNC_DIV_EXPR, utype,
2385 fold_build2_loc (loc, MINUS_EXPR, utype,
2386 fromu, tou),
2387 fold_build1_loc (loc, NEGATE_EXPR, utype, stepu));
d17271de
RB
2388 neg = build2 (COMPOUND_EXPR, void_type_node,
2389 fold_build2 (MODIFY_EXPR, void_type_node,
2390 countm1, tmp2),
7119f1b1
ML
2391 build3_loc (loc, COND_EXPR, void_type_node,
2392 gfc_unlikely (tmp, PRED_FORTRAN_LOOP_PREHEADER),
d17271de
RB
2393 build1_loc (loc, GOTO_EXPR, void_type_node,
2394 exit_label), NULL_TREE));
8146bb58 2395
63ee5404 2396 tmp = fold_build2_loc (loc, LT_EXPR, logical_type_node, step,
c5e7e996
RB
2397 build_int_cst (TREE_TYPE (step), 0));
2398 tmp = fold_build3_loc (loc, COND_EXPR, void_type_node, tmp, neg, pos);
8146bb58 2399
c0b29099 2400 gfc_add_expr_to_block (&block, tmp);
8d5cfa27
SK
2401 }
2402 else
2403 {
c5e7e996
RB
2404 tree pos_step;
2405
8d5cfa27
SK
2406 /* TODO: We could use the same width as the real type.
2407 This would probably cause more problems that it solves
2408 when we implement "long double" types. */
c0b29099 2409
55bd9c35
TB
2410 tmp = fold_build2_loc (loc, MINUS_EXPR, type, to, from);
2411 tmp = fold_build2_loc (loc, RDIV_EXPR, type, tmp, step);
2412 tmp = fold_build1_loc (loc, FIX_TRUNC_EXPR, utype, tmp);
c0b29099
JJ
2413 gfc_add_modify (&block, countm1, tmp);
2414
2415 /* We need a special check for empty loops:
2416 empty = (step > 0 ? to < from : to > from); */
63ee5404 2417 pos_step = fold_build2_loc (loc, GT_EXPR, logical_type_node, step,
c5e7e996 2418 build_zero_cst (type));
63ee5404 2419 tmp = fold_build3_loc (loc, COND_EXPR, logical_type_node, pos_step,
55bd9c35 2420 fold_build2_loc (loc, LT_EXPR,
63ee5404 2421 logical_type_node, to, from),
55bd9c35 2422 fold_build2_loc (loc, GT_EXPR,
63ee5404 2423 logical_type_node, to, from));
c0b29099 2424 /* If the loop is empty, go directly to the exit label. */
55bd9c35 2425 tmp = fold_build3_loc (loc, COND_EXPR, void_type_node, tmp,
c0b29099 2426 build1_v (GOTO_EXPR, exit_label),
c2255bc4 2427 build_empty_stmt (input_location));
c0b29099 2428 gfc_add_expr_to_block (&block, tmp);
8d5cfa27 2429 }
5d148c08 2430
6de9cd9a
DN
2431 /* Loop body. */
2432 gfc_start_block (&body);
2433
6de9cd9a 2434 /* Main loop body. */
bc51e726 2435 tmp = gfc_trans_code_cond (code->block->next, exit_cond);
6de9cd9a
DN
2436 gfc_add_expr_to_block (&body, tmp);
2437
2438 /* Label for cycle statements (if needed). */
2439 if (TREE_USED (cycle_label))
2440 {
2441 tmp = build1_v (LABEL_EXPR, cycle_label);
2442 gfc_add_expr_to_block (&body, tmp);
2443 }
2444
1cc0e193 2445 /* Check whether someone has modified the loop variable. */
33abc845
TB
2446 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
2447 {
63ee5404 2448 tmp = fold_build2_loc (loc, NE_EXPR, logical_type_node, dovar,
bc98ed60 2449 saved_dovar);
33abc845
TB
2450 gfc_trans_runtime_check (true, false, tmp, &body, &code->loc,
2451 "Loop variable has been modified");
2452 }
2453
bc51e726
JD
2454 /* Exit the loop if there is an I/O result condition or error. */
2455 if (exit_cond)
2456 {
2457 tmp = build1_v (GOTO_EXPR, exit_label);
55bd9c35 2458 tmp = fold_build3_loc (loc, COND_EXPR, void_type_node,
bc98ed60
TB
2459 exit_cond, tmp,
2460 build_empty_stmt (input_location));
bc51e726
JD
2461 gfc_add_expr_to_block (&body, tmp);
2462 }
2463
244974bd 2464 /* Increment the loop variable. */
55bd9c35
TB
2465 tmp = fold_build2_loc (loc, PLUS_EXPR, type, dovar, step);
2466 gfc_add_modify_loc (loc, &body, dovar, tmp);
244974bd 2467
33abc845 2468 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
55bd9c35 2469 gfc_add_modify_loc (loc, &body, saved_dovar, dovar);
33abc845 2470
8c01de7f
JJ
2471 /* Initialize countm1t. */
2472 tree countm1t = gfc_create_var (utype, "countm1t");
2473 gfc_add_modify_loc (loc, &body, countm1t, countm1);
5d148c08 2474
6de9cd9a 2475 /* Decrement the loop count. */
55bd9c35 2476 tmp = fold_build2_loc (loc, MINUS_EXPR, utype, countm1,
bc98ed60 2477 build_int_cst (utype, 1));
55bd9c35 2478 gfc_add_modify_loc (loc, &body, countm1, tmp);
6de9cd9a 2479
8c01de7f 2480 /* End with the loop condition. Loop until countm1t == 0. */
63ee5404 2481 cond = fold_build2_loc (loc, EQ_EXPR, logical_type_node, countm1t,
8c01de7f 2482 build_int_cst (utype, 0));
170a8bd6
EB
2483 if (code->ext.iterator->unroll && cond != error_mark_node)
2484 cond
2485 = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
2486 build_int_cst (integer_type_node, annot_expr_unroll_kind),
2487 build_int_cst (integer_type_node, code->ext.iterator->unroll));
8c01de7f
JJ
2488 tmp = fold_build1_loc (loc, GOTO_EXPR, void_type_node, exit_label);
2489 tmp = fold_build3_loc (loc, COND_EXPR, void_type_node,
2490 cond, tmp, build_empty_stmt (loc));
2491 gfc_add_expr_to_block (&body, tmp);
2492
6de9cd9a
DN
2493 /* End of loop body. */
2494 tmp = gfc_finish_block (&body);
2495
2496 /* The for loop itself. */
55bd9c35 2497 tmp = fold_build1_loc (loc, LOOP_EXPR, void_type_node, tmp);
6de9cd9a
DN
2498 gfc_add_expr_to_block (&block, tmp);
2499
2500 /* Add the exit label. */
2501 tmp = build1_v (LABEL_EXPR, exit_label);
2502 gfc_add_expr_to_block (&block, tmp);
2503
2504 return gfc_finish_block (&block);
2505}
2506
2507
2508/* Translate the DO WHILE construct.
2509
2510 We translate
2511
2512 DO WHILE (cond)
2513 body
2514 END DO
2515
2516 to:
2517
2518 for ( ; ; )
2519 {
2520 pre_cond;
2521 if (! cond) goto exit_label;
2522 body;
2523cycle_label:
2524 }
2525exit_label:
2526
2527 Because the evaluation of the exit condition `cond' may have side
2528 effects, we can't do much for empty loop bodies. The backend optimizers
2529 should be smart enough to eliminate any dead loops. */
2530
2531tree
2532gfc_trans_do_while (gfc_code * code)
2533{
2534 gfc_se cond;
2535 tree tmp;
2536 tree cycle_label;
2537 tree exit_label;
2538 stmtblock_t block;
2539
2540 /* Everything we build here is part of the loop body. */
2541 gfc_start_block (&block);
2542
2543 /* Cycle and exit statements are implemented with gotos. */
2544 cycle_label = gfc_build_label_decl (NULL_TREE);
2545 exit_label = gfc_build_label_decl (NULL_TREE);
2546
2547 /* Put the labels where they can be found later. See gfc_trans_do(). */
e5ca9693
DK
2548 code->cycle_label = cycle_label;
2549 code->exit_label = exit_label;
6de9cd9a
DN
2550
2551 /* Create a GIMPLE version of the exit condition. */
2552 gfc_init_se (&cond, NULL);
a513927a 2553 gfc_conv_expr_val (&cond, code->expr1);
6de9cd9a 2554 gfc_add_block_to_block (&block, &cond.pre);
55bd9c35 2555 cond.expr = fold_build1_loc (code->expr1->where.lb->location,
1d636855 2556 TRUTH_NOT_EXPR, TREE_TYPE (cond.expr), cond.expr);
6de9cd9a
DN
2557
2558 /* Build "IF (! cond) GOTO exit_label". */
2559 tmp = build1_v (GOTO_EXPR, exit_label);
2560 TREE_USED (exit_label) = 1;
55bd9c35
TB
2561 tmp = fold_build3_loc (code->expr1->where.lb->location, COND_EXPR,
2562 void_type_node, cond.expr, tmp,
2563 build_empty_stmt (code->expr1->where.lb->location));
6de9cd9a
DN
2564 gfc_add_expr_to_block (&block, tmp);
2565
2566 /* The main body of the loop. */
2567 tmp = gfc_trans_code (code->block->next);
2568 gfc_add_expr_to_block (&block, tmp);
2569
2570 /* Label for cycle statements (if needed). */
2571 if (TREE_USED (cycle_label))
2572 {
2573 tmp = build1_v (LABEL_EXPR, cycle_label);
2574 gfc_add_expr_to_block (&block, tmp);
2575 }
2576
2577 /* End of loop body. */
2578 tmp = gfc_finish_block (&block);
2579
2580 gfc_init_block (&block);
2581 /* Build the loop. */
55bd9c35
TB
2582 tmp = fold_build1_loc (code->expr1->where.lb->location, LOOP_EXPR,
2583 void_type_node, tmp);
6de9cd9a
DN
2584 gfc_add_expr_to_block (&block, tmp);
2585
2586 /* Add the exit label. */
2587 tmp = build1_v (LABEL_EXPR, exit_label);
2588 gfc_add_expr_to_block (&block, tmp);
2589
2590 return gfc_finish_block (&block);
2591}
2592
2593
dfd6231e
PT
2594/* Deal with the particular case of SELECT_TYPE, where the vtable
2595 addresses are used for the selection. Since these are not sorted,
2596 the selection has to be made by a series of if statements. */
2597
2598static tree
2599gfc_trans_select_type_cases (gfc_code * code)
2600{
2601 gfc_code *c;
2602 gfc_case *cp;
2603 tree tmp;
2604 tree cond;
2605 tree low;
2606 tree high;
2607 gfc_se se;
2608 gfc_se cse;
2609 stmtblock_t block;
2610 stmtblock_t body;
2611 bool def = false;
2612 gfc_expr *e;
2613 gfc_start_block (&block);
2614
2615 /* Calculate the switch expression. */
2616 gfc_init_se (&se, NULL);
2617 gfc_conv_expr_val (&se, code->expr1);
2618 gfc_add_block_to_block (&block, &se.pre);
2619
2620 /* Generate an expression for the selector hash value, for
2621 use to resolve character cases. */
2622 e = gfc_copy_expr (code->expr1->value.function.actual->expr);
2623 gfc_add_hash_component (e);
2624
2625 TREE_USED (code->exit_label) = 0;
2626
2627repeat:
2628 for (c = code->block; c; c = c->block)
2629 {
2630 cp = c->ext.block.case_list;
2631
2632 /* Assume it's the default case. */
2633 low = NULL_TREE;
2634 high = NULL_TREE;
2635 tmp = NULL_TREE;
2636
2637 /* Put the default case at the end. */
2638 if ((!def && !cp->low) || (def && cp->low))
2639 continue;
2640
2641 if (cp->low && (cp->ts.type == BT_CLASS
2642 || cp->ts.type == BT_DERIVED))
2643 {
2644 gfc_init_se (&cse, NULL);
2645 gfc_conv_expr_val (&cse, cp->low);
2646 gfc_add_block_to_block (&block, &cse.pre);
2647 low = cse.expr;
2648 }
2649 else if (cp->ts.type != BT_UNKNOWN)
2650 {
2651 gcc_assert (cp->high);
2652 gfc_init_se (&cse, NULL);
2653 gfc_conv_expr_val (&cse, cp->high);
2654 gfc_add_block_to_block (&block, &cse.pre);
2655 high = cse.expr;
2656 }
2657
2658 gfc_init_block (&body);
2659
2660 /* Add the statements for this case. */
2661 tmp = gfc_trans_code (c->next);
2662 gfc_add_expr_to_block (&body, tmp);
2663
2664 /* Break to the end of the SELECT TYPE construct. The default
2665 case just falls through. */
2666 if (!def)
2667 {
2668 TREE_USED (code->exit_label) = 1;
2669 tmp = build1_v (GOTO_EXPR, code->exit_label);
2670 gfc_add_expr_to_block (&body, tmp);
2671 }
2672
2673 tmp = gfc_finish_block (&body);
2674
2675 if (low != NULL_TREE)
2676 {
2677 /* Compare vtable pointers. */
2678 cond = fold_build2_loc (input_location, EQ_EXPR,
2679 TREE_TYPE (se.expr), se.expr, low);
2680 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
2681 cond, tmp,
2682 build_empty_stmt (input_location));
2683 }
2684 else if (high != NULL_TREE)
2685 {
2686 /* Compare hash values for character cases. */
2687 gfc_init_se (&cse, NULL);
2688 gfc_conv_expr_val (&cse, e);
2689 gfc_add_block_to_block (&block, &cse.pre);
2690
2691 cond = fold_build2_loc (input_location, EQ_EXPR,
2692 TREE_TYPE (se.expr), high, cse.expr);
2693 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
2694 cond, tmp,
2695 build_empty_stmt (input_location));
2696 }
2697
2698 gfc_add_expr_to_block (&block, tmp);
2699 }
2700
2701 if (!def)
2702 {
2703 def = true;
2704 goto repeat;
2705 }
2706
2707 gfc_free_expr (e);
2708
2709 return gfc_finish_block (&block);
2710}
2711
2712
6de9cd9a
DN
2713/* Translate the SELECT CASE construct for INTEGER case expressions,
2714 without killing all potential optimizations. The problem is that
2715 Fortran allows unbounded cases, but the back-end does not, so we
2716 need to intercept those before we enter the equivalent SWITCH_EXPR
2717 we can build.
2718
2719 For example, we translate this,
2720
2721 SELECT CASE (expr)
2722 CASE (:100,101,105:115)
2723 block_1
2724 CASE (190:199,200:)
2725 block_2
2726 CASE (300)
2727 block_3
2728 CASE DEFAULT
2729 block_4
2730 END SELECT
2731
2732 to the GENERIC equivalent,
2733
2734 switch (expr)
2735 {
2736 case (minimum value for typeof(expr) ... 100:
2737 case 101:
2738 case 105 ... 114:
2739 block1:
2740 goto end_label;
2741
2742 case 200 ... (maximum value for typeof(expr):
2743 case 190 ... 199:
2744 block2;
2745 goto end_label;
2746
2747 case 300:
2748 block_3;
2749 goto end_label;
2750
2751 default:
2752 block_4;
2753 goto end_label;
2754 }
2755
2756 end_label: */
2757
2758static tree
2759gfc_trans_integer_select (gfc_code * code)
2760{
2761 gfc_code *c;
2762 gfc_case *cp;
2763 tree end_label;
2764 tree tmp;
2765 gfc_se se;
2766 stmtblock_t block;
2767 stmtblock_t body;
2768
2769 gfc_start_block (&block);
2770
2771 /* Calculate the switch expression. */
2772 gfc_init_se (&se, NULL);
a513927a 2773 gfc_conv_expr_val (&se, code->expr1);
6de9cd9a
DN
2774 gfc_add_block_to_block (&block, &se.pre);
2775
2776 end_label = gfc_build_label_decl (NULL_TREE);
2777
2778 gfc_init_block (&body);
2779
2780 for (c = code->block; c; c = c->block)
2781 {
29a63d67 2782 for (cp = c->ext.block.case_list; cp; cp = cp->next)
6de9cd9a
DN
2783 {
2784 tree low, high;
2785 tree label;
2786
2787 /* Assume it's the default case. */
2788 low = high = NULL_TREE;
2789
2790 if (cp->low)
2791 {
20585ad6
BM
2792 low = gfc_conv_mpz_to_tree (cp->low->value.integer,
2793 cp->low->ts.kind);
6de9cd9a
DN
2794
2795 /* If there's only a lower bound, set the high bound to the
2796 maximum value of the case expression. */
2797 if (!cp->high)
2798 high = TYPE_MAX_VALUE (TREE_TYPE (se.expr));
2799 }
2800
2801 if (cp->high)
2802 {
2803 /* Three cases are possible here:
2804
2805 1) There is no lower bound, e.g. CASE (:N).
2806 2) There is a lower bound .NE. high bound, that is
2807 a case range, e.g. CASE (N:M) where M>N (we make
2808 sure that M>N during type resolution).
2809 3) There is a lower bound, and it has the same value
2810 as the high bound, e.g. CASE (N:N). This is our
2811 internal representation of CASE(N).
2812
2813 In the first and second case, we need to set a value for
e2ae1407 2814 high. In the third case, we don't because the GCC middle
6de9cd9a
DN
2815 end represents a single case value by just letting high be
2816 a NULL_TREE. We can't do that because we need to be able
2817 to represent unbounded cases. */
2818
2819 if (!cp->low
b2954e12
SK
2820 || (mpz_cmp (cp->low->value.integer,
2821 cp->high->value.integer) != 0))
20585ad6
BM
2822 high = gfc_conv_mpz_to_tree (cp->high->value.integer,
2823 cp->high->ts.kind);
6de9cd9a
DN
2824
2825 /* Unbounded case. */
2826 if (!cp->low)
2827 low = TYPE_MIN_VALUE (TREE_TYPE (se.expr));
2828 }
2829
2830 /* Build a label. */
c006df4e 2831 label = gfc_build_label_decl (NULL_TREE);
6de9cd9a
DN
2832
2833 /* Add this case label.
2834 Add parameter 'label', make it match GCC backend. */
3d528853 2835 tmp = build_case_label (low, high, label);
6de9cd9a
DN
2836 gfc_add_expr_to_block (&body, tmp);
2837 }
2838
2839 /* Add the statements for this case. */
2840 tmp = gfc_trans_code (c->next);
2841 gfc_add_expr_to_block (&body, tmp);
2842
2843 /* Break to the end of the construct. */
2844 tmp = build1_v (GOTO_EXPR, end_label);
2845 gfc_add_expr_to_block (&body, tmp);
2846 }
2847
2848 tmp = gfc_finish_block (&body);
9e851845 2849 tmp = fold_build2_loc (input_location, SWITCH_EXPR, NULL_TREE, se.expr, tmp);
6de9cd9a
DN
2850 gfc_add_expr_to_block (&block, tmp);
2851
2852 tmp = build1_v (LABEL_EXPR, end_label);
2853 gfc_add_expr_to_block (&block, tmp);
2854
2855 return gfc_finish_block (&block);
2856}
2857
2858
2859/* Translate the SELECT CASE construct for LOGICAL case expressions.
2860
2861 There are only two cases possible here, even though the standard
2862 does allow three cases in a LOGICAL SELECT CASE construct: .TRUE.,
2863 .FALSE., and DEFAULT.
2864
2865 We never generate more than two blocks here. Instead, we always
2866 try to eliminate the DEFAULT case. This way, we can translate this
2867 kind of SELECT construct to a simple
2868
2869 if {} else {};
2870
2871 expression in GENERIC. */
2872
2873static tree
2874gfc_trans_logical_select (gfc_code * code)
2875{
2876 gfc_code *c;
2877 gfc_code *t, *f, *d;
2878 gfc_case *cp;
2879 gfc_se se;
2880 stmtblock_t block;
2881
2882 /* Assume we don't have any cases at all. */
2883 t = f = d = NULL;
2884
2885 /* Now see which ones we actually do have. We can have at most two
2886 cases in a single case list: one for .TRUE. and one for .FALSE.
2887 The default case is always separate. If the cases for .TRUE. and
2888 .FALSE. are in the same case list, the block for that case list
2889 always executed, and we don't generate code a COND_EXPR. */
2890 for (c = code->block; c; c = c->block)
2891 {
29a63d67 2892 for (cp = c->ext.block.case_list; cp; cp = cp->next)
6de9cd9a
DN
2893 {
2894 if (cp->low)
2895 {
2896 if (cp->low->value.logical == 0) /* .FALSE. */
2897 f = c;
2898 else /* if (cp->value.logical != 0), thus .TRUE. */
2899 t = c;
2900 }
2901 else
2902 d = c;
2903 }
2904 }
2905
2906 /* Start a new block. */
2907 gfc_start_block (&block);
2908
2909 /* Calculate the switch expression. We always need to do this
2910 because it may have side effects. */
2911 gfc_init_se (&se, NULL);
a513927a 2912 gfc_conv_expr_val (&se, code->expr1);
6de9cd9a
DN
2913 gfc_add_block_to_block (&block, &se.pre);
2914
2915 if (t == f && t != NULL)
2916 {
2917 /* Cases for .TRUE. and .FALSE. are in the same block. Just
2918 translate the code for these cases, append it to the current
2919 block. */
2920 gfc_add_expr_to_block (&block, gfc_trans_code (t->next));
2921 }
2922 else
2923 {
61ead135 2924 tree true_tree, false_tree, stmt;
6de9cd9a 2925
c2255bc4
AH
2926 true_tree = build_empty_stmt (input_location);
2927 false_tree = build_empty_stmt (input_location);
6de9cd9a
DN
2928
2929 /* If we have a case for .TRUE. and for .FALSE., discard the default case.
2930 Otherwise, if .TRUE. or .FALSE. is missing and there is a default case,
2931 make the missing case the default case. */
2932 if (t != NULL && f != NULL)
2933 d = NULL;
2934 else if (d != NULL)
2935 {
2936 if (t == NULL)
2937 t = d;
2938 else
2939 f = d;
2940 }
2941
2942 /* Translate the code for each of these blocks, and append it to
2943 the current block. */
2944 if (t != NULL)
2945 true_tree = gfc_trans_code (t->next);
2946
2947 if (f != NULL)
2948 false_tree = gfc_trans_code (f->next);
2949
bc98ed60
TB
2950 stmt = fold_build3_loc (input_location, COND_EXPR, void_type_node,
2951 se.expr, true_tree, false_tree);
61ead135 2952 gfc_add_expr_to_block (&block, stmt);
6de9cd9a
DN
2953 }
2954
2955 return gfc_finish_block (&block);
2956}
2957
2958
d2886bc7
JJ
2959/* The jump table types are stored in static variables to avoid
2960 constructing them from scratch every single time. */
2961static GTY(()) tree select_struct[2];
2962
6de9cd9a
DN
2963/* Translate the SELECT CASE construct for CHARACTER case expressions.
2964 Instead of generating compares and jumps, it is far simpler to
2965 generate a data structure describing the cases in order and call a
2966 library subroutine that locates the right case.
2967 This is particularly true because this is the only case where we
2968 might have to dispose of a temporary.
2969 The library subroutine returns a pointer to jump to or NULL if no
2970 branches are to be taken. */
2971
2972static tree
2973gfc_trans_character_select (gfc_code *code)
2974{
8748ad99 2975 tree init, end_label, tmp, type, case_num, label, fndecl;
6de9cd9a
DN
2976 stmtblock_t block, body;
2977 gfc_case *cp, *d;
2978 gfc_code *c;
d2886bc7 2979 gfc_se se, expr1se;
d393bbd7 2980 int n, k;
9771b263 2981 vec<constructor_elt, va_gc> *inits = NULL;
d393bbd7 2982
d2886bc7
JJ
2983 tree pchartype = gfc_get_pchar_type (code->expr1->ts.kind);
2984
d393bbd7
FXC
2985 /* The jump table types are stored in static variables to avoid
2986 constructing them from scratch every single time. */
d393bbd7
FXC
2987 static tree ss_string1[2], ss_string1_len[2];
2988 static tree ss_string2[2], ss_string2_len[2];
2989 static tree ss_target[2];
2990
29a63d67 2991 cp = code->block->ext.block.case_list;
d2886bc7
JJ
2992 while (cp->left != NULL)
2993 cp = cp->left;
2994
2995 /* Generate the body */
2996 gfc_start_block (&block);
2997 gfc_init_se (&expr1se, NULL);
2998 gfc_conv_expr_reference (&expr1se, code->expr1);
2999
3000 gfc_add_block_to_block (&block, &expr1se.pre);
3001
3002 end_label = gfc_build_label_decl (NULL_TREE);
3003
3004 gfc_init_block (&body);
3005
3006 /* Attempt to optimize length 1 selects. */
86e033e2 3007 if (integer_onep (expr1se.string_length))
d2886bc7
JJ
3008 {
3009 for (d = cp; d; d = d->right)
3010 {
f622221a 3011 gfc_charlen_t i;
d2886bc7
JJ
3012 if (d->low)
3013 {
3014 gcc_assert (d->low->expr_type == EXPR_CONSTANT
3015 && d->low->ts.type == BT_CHARACTER);
3016 if (d->low->value.character.length > 1)
3017 {
3018 for (i = 1; i < d->low->value.character.length; i++)
3019 if (d->low->value.character.string[i] != ' ')
3020 break;
3021 if (i != d->low->value.character.length)
3022 {
3023 if (optimize && d->high && i == 1)
3024 {
3025 gcc_assert (d->high->expr_type == EXPR_CONSTANT
3026 && d->high->ts.type == BT_CHARACTER);
3027 if (d->high->value.character.length > 1
3028 && (d->low->value.character.string[0]
3029 == d->high->value.character.string[0])
3030 && d->high->value.character.string[1] != ' '
3031 && ((d->low->value.character.string[1] < ' ')
3032 == (d->high->value.character.string[1]
3033 < ' ')))
3034 continue;
3035 }
3036 break;
3037 }
3038 }
3039 }
3040 if (d->high)
3041 {
3042 gcc_assert (d->high->expr_type == EXPR_CONSTANT
3043 && d->high->ts.type == BT_CHARACTER);
3044 if (d->high->value.character.length > 1)
3045 {
3046 for (i = 1; i < d->high->value.character.length; i++)
3047 if (d->high->value.character.string[i] != ' ')
3048 break;
3049 if (i != d->high->value.character.length)
3050 break;
3051 }
3052 }
3053 }
3054 if (d == NULL)
3055 {
3056 tree ctype = gfc_get_char_type (code->expr1->ts.kind);
3057
3058 for (c = code->block; c; c = c->block)
3059 {
29a63d67 3060 for (cp = c->ext.block.case_list; cp; cp = cp->next)
d2886bc7
JJ
3061 {
3062 tree low, high;
3063 tree label;
3064 gfc_char_t r;
3065
3066 /* Assume it's the default case. */
3067 low = high = NULL_TREE;
3068
3069 if (cp->low)
3070 {
3071 /* CASE ('ab') or CASE ('ab':'az') will never match
3072 any length 1 character. */
3073 if (cp->low->value.character.length > 1
3074 && cp->low->value.character.string[1] != ' ')
3075 continue;
3076
3077 if (cp->low->value.character.length > 0)
3078 r = cp->low->value.character.string[0];
3079 else
3080 r = ' ';
3081 low = build_int_cst (ctype, r);
3082
3083 /* If there's only a lower bound, set the high bound
3084 to the maximum value of the case expression. */
3085 if (!cp->high)
3086 high = TYPE_MAX_VALUE (ctype);
3087 }
3088
3089 if (cp->high)
3090 {
3091 if (!cp->low
3092 || (cp->low->value.character.string[0]
3093 != cp->high->value.character.string[0]))
3094 {
3095 if (cp->high->value.character.length > 0)
3096 r = cp->high->value.character.string[0];
3097 else
3098 r = ' ';
3099 high = build_int_cst (ctype, r);
3100 }
3101
3102 /* Unbounded case. */
3103 if (!cp->low)
3104 low = TYPE_MIN_VALUE (ctype);
3105 }
3106
3107 /* Build a label. */
3108 label = gfc_build_label_decl (NULL_TREE);
3109
3110 /* Add this case label.
3111 Add parameter 'label', make it match GCC backend. */
3d528853 3112 tmp = build_case_label (low, high, label);
d2886bc7
JJ
3113 gfc_add_expr_to_block (&body, tmp);
3114 }
3115
3116 /* Add the statements for this case. */
3117 tmp = gfc_trans_code (c->next);
3118 gfc_add_expr_to_block (&body, tmp);
3119
3120 /* Break to the end of the construct. */
3121 tmp = build1_v (GOTO_EXPR, end_label);
3122 gfc_add_expr_to_block (&body, tmp);
3123 }
3124
3125 tmp = gfc_string_to_single_character (expr1se.string_length,
3126 expr1se.expr,
3127 code->expr1->ts.kind);
3128 case_num = gfc_create_var (ctype, "case_num");
3129 gfc_add_modify (&block, case_num, tmp);
3130
3131 gfc_add_block_to_block (&block, &expr1se.post);
3132
3133 tmp = gfc_finish_block (&body);
9e851845
JJ
3134 tmp = fold_build2_loc (input_location, SWITCH_EXPR, NULL_TREE,
3135 case_num, tmp);
d2886bc7
JJ
3136 gfc_add_expr_to_block (&block, tmp);
3137
3138 tmp = build1_v (LABEL_EXPR, end_label);
3139 gfc_add_expr_to_block (&block, tmp);
3140
3141 return gfc_finish_block (&block);
3142 }
3143 }
6de9cd9a 3144
a513927a 3145 if (code->expr1->ts.kind == 1)
d393bbd7 3146 k = 0;
a513927a 3147 else if (code->expr1->ts.kind == 4)
d393bbd7
FXC
3148 k = 1;
3149 else
3150 gcc_unreachable ();
6de9cd9a 3151
d393bbd7 3152 if (select_struct[k] == NULL)
6de9cd9a 3153 {
dfd6ece2 3154 tree *chain = NULL;
d393bbd7 3155 select_struct[k] = make_node (RECORD_TYPE);
e2cad04b 3156
a513927a 3157 if (code->expr1->ts.kind == 1)
d393bbd7 3158 TYPE_NAME (select_struct[k]) = get_identifier ("_jump_struct_char1");
a513927a 3159 else if (code->expr1->ts.kind == 4)
d393bbd7
FXC
3160 TYPE_NAME (select_struct[k]) = get_identifier ("_jump_struct_char4");
3161 else
3162 gcc_unreachable ();
6de9cd9a
DN
3163
3164#undef ADD_FIELD
35151cd5
MM
3165#define ADD_FIELD(NAME, TYPE) \
3166 ss_##NAME[k] = gfc_add_field_to_struct (select_struct[k], \
3167 get_identifier (stringize(NAME)), \
3168 TYPE, \
3169 &chain)
6de9cd9a 3170
d393bbd7
FXC
3171 ADD_FIELD (string1, pchartype);
3172 ADD_FIELD (string1_len, gfc_charlen_type_node);
6de9cd9a 3173
d393bbd7
FXC
3174 ADD_FIELD (string2, pchartype);
3175 ADD_FIELD (string2_len, gfc_charlen_type_node);
6de9cd9a 3176
dd52ecb0 3177 ADD_FIELD (target, integer_type_node);
6de9cd9a
DN
3178#undef ADD_FIELD
3179
d393bbd7 3180 gfc_finish_type (select_struct[k]);
6de9cd9a
DN
3181 }
3182
6de9cd9a
DN
3183 n = 0;
3184 for (d = cp; d; d = d->right)
3185 d->n = n++;
3186
6de9cd9a
DN
3187 for (c = code->block; c; c = c->block)
3188 {
29a63d67 3189 for (d = c->ext.block.case_list; d; d = d->next)
6de9cd9a 3190 {
2b8327ce 3191 label = gfc_build_label_decl (NULL_TREE);
3d528853
NF
3192 tmp = build_case_label ((d->low == NULL && d->high == NULL)
3193 ? NULL
3194 : build_int_cst (integer_type_node, d->n),
3195 NULL, label);
6de9cd9a
DN
3196 gfc_add_expr_to_block (&body, tmp);
3197 }
3198
3199 tmp = gfc_trans_code (c->next);
3200 gfc_add_expr_to_block (&body, tmp);
3201
923ab88c 3202 tmp = build1_v (GOTO_EXPR, end_label);
6de9cd9a
DN
3203 gfc_add_expr_to_block (&body, tmp);
3204 }
3205
3206 /* Generate the structure describing the branches */
d2886bc7 3207 for (d = cp; d; d = d->right)
6de9cd9a 3208 {
9771b263 3209 vec<constructor_elt, va_gc> *node = NULL;
6de9cd9a
DN
3210
3211 gfc_init_se (&se, NULL);
3212
3213 if (d->low == NULL)
3214 {
8748ad99 3215 CONSTRUCTOR_APPEND_ELT (node, ss_string1[k], null_pointer_node);
f622221a 3216 CONSTRUCTOR_APPEND_ELT (node, ss_string1_len[k], build_zero_cst (gfc_charlen_type_node));
6de9cd9a
DN
3217 }
3218 else
3219 {
3220 gfc_conv_expr_reference (&se, d->low);
3221
8748ad99
NF
3222 CONSTRUCTOR_APPEND_ELT (node, ss_string1[k], se.expr);
3223 CONSTRUCTOR_APPEND_ELT (node, ss_string1_len[k], se.string_length);
6de9cd9a
DN
3224 }
3225
3226 if (d->high == NULL)
3227 {
8748ad99 3228 CONSTRUCTOR_APPEND_ELT (node, ss_string2[k], null_pointer_node);
f622221a 3229 CONSTRUCTOR_APPEND_ELT (node, ss_string2_len[k], build_zero_cst (gfc_charlen_type_node));
6de9cd9a
DN
3230 }
3231 else
3232 {
3233 gfc_init_se (&se, NULL);
3234 gfc_conv_expr_reference (&se, d->high);
3235
8748ad99
NF
3236 CONSTRUCTOR_APPEND_ELT (node, ss_string2[k], se.expr);
3237 CONSTRUCTOR_APPEND_ELT (node, ss_string2_len[k], se.string_length);
6de9cd9a
DN
3238 }
3239
8748ad99
NF
3240 CONSTRUCTOR_APPEND_ELT (node, ss_target[k],
3241 build_int_cst (integer_type_node, d->n));
6de9cd9a 3242
8748ad99
NF
3243 tmp = build_constructor (select_struct[k], node);
3244 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, tmp);
6de9cd9a
DN
3245 }
3246
d393bbd7 3247 type = build_array_type (select_struct[k],
df09d1d5 3248 build_index_type (size_int (n-1)));
6de9cd9a 3249
8748ad99 3250 init = build_constructor (type, inits);
6de9cd9a 3251 TREE_CONSTANT (init) = 1;
6de9cd9a
DN
3252 TREE_STATIC (init) = 1;
3253 /* Create a static variable to hold the jump table. */
3254 tmp = gfc_create_var (type, "jumptable");
3255 TREE_CONSTANT (tmp) = 1;
6de9cd9a 3256 TREE_STATIC (tmp) = 1;
0f0707d1 3257 TREE_READONLY (tmp) = 1;
6de9cd9a
DN
3258 DECL_INITIAL (tmp) = init;
3259 init = tmp;
3260
5039610b 3261 /* Build the library call */
6de9cd9a 3262 init = gfc_build_addr_expr (pvoid_type_node, init);
6de9cd9a 3263
a513927a 3264 if (code->expr1->ts.kind == 1)
d393bbd7 3265 fndecl = gfor_fndecl_select_string;
a513927a 3266 else if (code->expr1->ts.kind == 4)
d393bbd7
FXC
3267 fndecl = gfor_fndecl_select_string_char4;
3268 else
3269 gcc_unreachable ();
3270
db3927fb 3271 tmp = build_call_expr_loc (input_location,
df09d1d5
RG
3272 fndecl, 4, init,
3273 build_int_cst (gfc_charlen_type_node, n),
d2886bc7 3274 expr1se.expr, expr1se.string_length);
dd52ecb0 3275 case_num = gfc_create_var (integer_type_node, "case_num");
726a989a 3276 gfc_add_modify (&block, case_num, tmp);
dc6c7714 3277
d2886bc7 3278 gfc_add_block_to_block (&block, &expr1se.post);
dc6c7714 3279
6de9cd9a 3280 tmp = gfc_finish_block (&body);
9e851845
JJ
3281 tmp = fold_build2_loc (input_location, SWITCH_EXPR, NULL_TREE,
3282 case_num, tmp);
6de9cd9a 3283 gfc_add_expr_to_block (&block, tmp);
2b8327ce 3284
923ab88c 3285 tmp = build1_v (LABEL_EXPR, end_label);
6de9cd9a
DN
3286 gfc_add_expr_to_block (&block, tmp);
3287
6de9cd9a
DN
3288 return gfc_finish_block (&block);
3289}
3290
3291
3292/* Translate the three variants of the SELECT CASE construct.
3293
3294 SELECT CASEs with INTEGER case expressions can be translated to an
3295 equivalent GENERIC switch statement, and for LOGICAL case
3296 expressions we build one or two if-else compares.
3297
3298 SELECT CASEs with CHARACTER case expressions are a whole different
3299 story, because they don't exist in GENERIC. So we sort them and
3300 do a binary search at runtime.
3301
3302 Fortran has no BREAK statement, and it does not allow jumps from
3303 one case block to another. That makes things a lot easier for
3304 the optimizers. */
3305
3306tree
3307gfc_trans_select (gfc_code * code)
3308{
e5ca9693
DK
3309 stmtblock_t block;
3310 tree body;
3311 tree exit_label;
3312
a513927a 3313 gcc_assert (code && code->expr1);
e5ca9693
DK
3314 gfc_init_block (&block);
3315
3316 /* Build the exit label and hang it in. */
3317 exit_label = gfc_build_label_decl (NULL_TREE);
3318 code->exit_label = exit_label;
6de9cd9a
DN
3319
3320 /* Empty SELECT constructs are legal. */
3321 if (code->block == NULL)
e5ca9693 3322 body = build_empty_stmt (input_location);
6de9cd9a
DN
3323
3324 /* Select the correct translation function. */
e5ca9693
DK
3325 else
3326 switch (code->expr1->ts.type)
3327 {
3328 case BT_LOGICAL:
3329 body = gfc_trans_logical_select (code);
3330 break;
3331
3332 case BT_INTEGER:
3333 body = gfc_trans_integer_select (code);
3334 break;
3335
3336 case BT_CHARACTER:
3337 body = gfc_trans_character_select (code);
3338 break;
3339
3340 default:
3341 gfc_internal_error ("gfc_trans_select(): Bad type for case expr.");
3342 /* Not reached */
3343 }
3344
3345 /* Build everything together. */
3346 gfc_add_expr_to_block (&block, body);
3347 gfc_add_expr_to_block (&block, build1_v (LABEL_EXPR, exit_label));
3348
dfd6231e
PT
3349 return gfc_finish_block (&block);
3350}
3351
3352tree
3353gfc_trans_select_type (gfc_code * code)
3354{
3355 stmtblock_t block;
3356 tree body;
3357 tree exit_label;
3358
3359 gcc_assert (code && code->expr1);
3360 gfc_init_block (&block);
3361
3362 /* Build the exit label and hang it in. */
3363 exit_label = gfc_build_label_decl (NULL_TREE);
3364 code->exit_label = exit_label;
3365
3366 /* Empty SELECT constructs are legal. */
3367 if (code->block == NULL)
3368 body = build_empty_stmt (input_location);
3369 else
3370 body = gfc_trans_select_type_cases (code);
3371
3372 /* Build everything together. */
3373 gfc_add_expr_to_block (&block, body);
3374
3375 if (TREE_USED (exit_label))
3376 gfc_add_expr_to_block (&block, build1_v (LABEL_EXPR, exit_label));
3377
e5ca9693 3378 return gfc_finish_block (&block);
6de9cd9a
DN
3379}
3380
3381
640670c7
PT
3382/* Traversal function to substitute a replacement symtree if the symbol
3383 in the expression is the same as that passed. f == 2 signals that
3384 that variable itself is not to be checked - only the references.
3385 This group of functions is used when the variable expression in a
3386 FORALL assignment has internal references. For example:
3387 FORALL (i = 1:4) p(p(i)) = i
3388 The only recourse here is to store a copy of 'p' for the index
3389 expression. */
3390
3391static gfc_symtree *new_symtree;
3392static gfc_symtree *old_symtree;
3393
3394static bool
3395forall_replace (gfc_expr *expr, gfc_symbol *sym, int *f)
3396{
908a2235
PT
3397 if (expr->expr_type != EXPR_VARIABLE)
3398 return false;
640670c7
PT
3399
3400 if (*f == 2)
3401 *f = 1;
3402 else if (expr->symtree->n.sym == sym)
3403 expr->symtree = new_symtree;
3404
3405 return false;
3406}
3407
3408static void
3409forall_replace_symtree (gfc_expr *e, gfc_symbol *sym, int f)
3410{
3411 gfc_traverse_expr (e, sym, forall_replace, f);
3412}
3413
3414static bool
3415forall_restore (gfc_expr *expr,
3416 gfc_symbol *sym ATTRIBUTE_UNUSED,
3417 int *f ATTRIBUTE_UNUSED)
3418{
908a2235
PT
3419 if (expr->expr_type != EXPR_VARIABLE)
3420 return false;
640670c7
PT
3421
3422 if (expr->symtree == new_symtree)
3423 expr->symtree = old_symtree;
3424
3425 return false;
3426}
3427
3428static void
3429forall_restore_symtree (gfc_expr *e)
3430{
3431 gfc_traverse_expr (e, NULL, forall_restore, 0);
3432}
3433
3434static void
3435forall_make_variable_temp (gfc_code *c, stmtblock_t *pre, stmtblock_t *post)
3436{
3437 gfc_se tse;
3438 gfc_se rse;
3439 gfc_expr *e;
3440 gfc_symbol *new_sym;
3441 gfc_symbol *old_sym;
3442 gfc_symtree *root;
3443 tree tmp;
3444
3445 /* Build a copy of the lvalue. */
a513927a 3446 old_symtree = c->expr1->symtree;
640670c7
PT
3447 old_sym = old_symtree->n.sym;
3448 e = gfc_lval_expr_from_sym (old_sym);
3449 if (old_sym->attr.dimension)
3450 {
3451 gfc_init_se (&tse, NULL);
430f2d1f 3452 gfc_conv_subref_array_arg (&tse, e, 0, INTENT_IN, false);
640670c7
PT
3453 gfc_add_block_to_block (pre, &tse.pre);
3454 gfc_add_block_to_block (post, &tse.post);
db3927fb 3455 tse.expr = build_fold_indirect_ref_loc (input_location, tse.expr);
640670c7 3456
7bd5dad2 3457 if (c->expr1->ref->u.ar.type != AR_SECTION)
640670c7
PT
3458 {
3459 /* Use the variable offset for the temporary. */
568e8e1e
PT
3460 tmp = gfc_conv_array_offset (old_sym->backend_decl);
3461 gfc_conv_descriptor_offset_set (pre, tse.expr, tmp);
640670c7
PT
3462 }
3463 }
3464 else
3465 {
3466 gfc_init_se (&tse, NULL);
3467 gfc_init_se (&rse, NULL);
3468 gfc_conv_expr (&rse, e);
3469 if (e->ts.type == BT_CHARACTER)
3470 {
3471 tse.string_length = rse.string_length;
3472 tmp = gfc_get_character_type_len (gfc_default_character_kind,
3473 tse.string_length);
3474 tse.expr = gfc_conv_string_tmp (&tse, build_pointer_type (tmp),
3475 rse.string_length);
3476 gfc_add_block_to_block (pre, &tse.pre);
3477 gfc_add_block_to_block (post, &tse.post);
3478 }
3479 else
3480 {
3481 tmp = gfc_typenode_for_spec (&e->ts);
3482 tse.expr = gfc_create_var (tmp, "temp");
3483 }
3484
ed673c00
MM
3485 tmp = gfc_trans_scalar_assign (&tse, &rse, e->ts,
3486 e->expr_type == EXPR_VARIABLE, false);
640670c7
PT
3487 gfc_add_expr_to_block (pre, tmp);
3488 }
3489 gfc_free_expr (e);
3490
3491 /* Create a new symbol to represent the lvalue. */
3492 new_sym = gfc_new_symbol (old_sym->name, NULL);
3493 new_sym->ts = old_sym->ts;
3494 new_sym->attr.referenced = 1;
59e36b72 3495 new_sym->attr.temporary = 1;
640670c7
PT
3496 new_sym->attr.dimension = old_sym->attr.dimension;
3497 new_sym->attr.flavor = old_sym->attr.flavor;
3498
3499 /* Use the temporary as the backend_decl. */
3500 new_sym->backend_decl = tse.expr;
3501
3502 /* Create a fake symtree for it. */
3503 root = NULL;
3504 new_symtree = gfc_new_symtree (&root, old_sym->name);
3505 new_symtree->n.sym = new_sym;
3506 gcc_assert (new_symtree == root);
3507
3508 /* Go through the expression reference replacing the old_symtree
3509 with the new. */
a513927a 3510 forall_replace_symtree (c->expr1, old_sym, 2);
640670c7
PT
3511
3512 /* Now we have made this temporary, we might as well use it for
3513 the right hand side. */
3514 forall_replace_symtree (c->expr2, old_sym, 1);
3515}
3516
3517
3518/* Handles dependencies in forall assignments. */
3519static int
3520check_forall_dependencies (gfc_code *c, stmtblock_t *pre, stmtblock_t *post)
3521{
3522 gfc_ref *lref;
3523 gfc_ref *rref;
3524 int need_temp;
3525 gfc_symbol *lsym;
3526
a513927a
SK
3527 lsym = c->expr1->symtree->n.sym;
3528 need_temp = gfc_check_dependency (c->expr1, c->expr2, 0);
640670c7
PT
3529
3530 /* Now check for dependencies within the 'variable'
3531 expression itself. These are treated by making a complete
3532 copy of variable and changing all the references to it
3533 point to the copy instead. Note that the shallow copy of
3534 the variable will not suffice for derived types with
3535 pointer components. We therefore leave these to their
3536 own devices. */
3537 if (lsym->ts.type == BT_DERIVED
bc21d315 3538 && lsym->ts.u.derived->attr.pointer_comp)
640670c7
PT
3539 return need_temp;
3540
3541 new_symtree = NULL;
524af0d6 3542 if (find_forall_index (c->expr1, lsym, 2))
640670c7
PT
3543 {
3544 forall_make_variable_temp (c, pre, post);
3545 need_temp = 0;
3546 }
3547
3548 /* Substrings with dependencies are treated in the same
3549 way. */
a513927a
SK
3550 if (c->expr1->ts.type == BT_CHARACTER
3551 && c->expr1->ref
640670c7
PT
3552 && c->expr2->expr_type == EXPR_VARIABLE
3553 && lsym == c->expr2->symtree->n.sym)
3554 {
a513927a 3555 for (lref = c->expr1->ref; lref; lref = lref->next)
640670c7
PT
3556 if (lref->type == REF_SUBSTRING)
3557 break;
3558 for (rref = c->expr2->ref; rref; rref = rref->next)
3559 if (rref->type == REF_SUBSTRING)
3560 break;
3561
3562 if (rref && lref
3563 && gfc_dep_compare_expr (rref->u.ss.start, lref->u.ss.start) < 0)
3564 {
3565 forall_make_variable_temp (c, pre, post);
3566 need_temp = 0;
3567 }
3568 }
3569 return need_temp;
3570}
3571
3572
3573static void
3574cleanup_forall_symtrees (gfc_code *c)
3575{
a513927a 3576 forall_restore_symtree (c->expr1);
640670c7 3577 forall_restore_symtree (c->expr2);
cede9502
JM
3578 free (new_symtree->n.sym);
3579 free (new_symtree);
640670c7
PT
3580}
3581
3582
bfcabc6c
RS
3583/* Generate the loops for a FORALL block, specified by FORALL_TMP. BODY
3584 is the contents of the FORALL block/stmt to be iterated. MASK_FLAG
3585 indicates whether we should generate code to test the FORALLs mask
3586 array. OUTER is the loop header to be used for initializing mask
3587 indices.
3588
3589 The generated loop format is:
6de9cd9a
DN
3590 count = (end - start + step) / step
3591 loopvar = start
3592 while (1)
3593 {
3594 if (count <=0 )
3595 goto end_of_loop
3596 <body>
3597 loopvar += step
3598 count --
3599 }
3600 end_of_loop: */
3601
3602static tree
bfcabc6c
RS
3603gfc_trans_forall_loop (forall_info *forall_tmp, tree body,
3604 int mask_flag, stmtblock_t *outer)
6de9cd9a 3605{
bfcabc6c 3606 int n, nvar;
6de9cd9a
DN
3607 tree tmp;
3608 tree cond;
3609 stmtblock_t block;
3610 tree exit_label;
3611 tree count;
fcf3be37 3612 tree var, start, end, step;
6de9cd9a
DN
3613 iter_info *iter;
3614
bfcabc6c
RS
3615 /* Initialize the mask index outside the FORALL nest. */
3616 if (mask_flag && forall_tmp->mask)
726a989a 3617 gfc_add_modify (outer, forall_tmp->maskindex, gfc_index_zero_node);
bfcabc6c 3618
6de9cd9a 3619 iter = forall_tmp->this_loop;
bfcabc6c 3620 nvar = forall_tmp->nvar;
6de9cd9a
DN
3621 for (n = 0; n < nvar; n++)
3622 {
3623 var = iter->var;
3624 start = iter->start;
3625 end = iter->end;
3626 step = iter->step;
3627
3628 exit_label = gfc_build_label_decl (NULL_TREE);
3629 TREE_USED (exit_label) = 1;
3630
3631 /* The loop counter. */
3632 count = gfc_create_var (TREE_TYPE (var), "count");
3633
3634 /* The body of the loop. */
3635 gfc_init_block (&block);
3636
3637 /* The exit condition. */
63ee5404 3638 cond = fold_build2_loc (input_location, LE_EXPR, logical_type_node,
bc98ed60 3639 count, build_int_cst (TREE_TYPE (count), 0));
2ca4e2c2 3640 if (forall_tmp->do_concurrent)
ac9effed 3641 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
2ca4e2c2 3642 build_int_cst (integer_type_node,
ac9effed
EB
3643 annot_expr_parallel_kind),
3644 integer_zero_node);
2ca4e2c2 3645
6de9cd9a 3646 tmp = build1_v (GOTO_EXPR, exit_label);
bc98ed60
TB
3647 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
3648 cond, tmp, build_empty_stmt (input_location));
6de9cd9a
DN
3649 gfc_add_expr_to_block (&block, tmp);
3650
3651 /* The main loop body. */
3652 gfc_add_expr_to_block (&block, body);
3653
3654 /* Increment the loop variable. */
bc98ed60
TB
3655 tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (var), var,
3656 step);
726a989a 3657 gfc_add_modify (&block, var, tmp);
6de9cd9a 3658
a8e12e4d
TS
3659 /* Advance to the next mask element. Only do this for the
3660 innermost loop. */
fcf3be37
JJ
3661 if (n == 0 && mask_flag && forall_tmp->mask)
3662 {
3663 tree maskindex = forall_tmp->maskindex;
bc98ed60
TB
3664 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
3665 maskindex, gfc_index_one_node);
726a989a 3666 gfc_add_modify (&block, maskindex, tmp);
fcf3be37
JJ
3667 }
3668
6de9cd9a 3669 /* Decrement the loop counter. */
bc98ed60
TB
3670 tmp = fold_build2_loc (input_location, MINUS_EXPR, TREE_TYPE (var), count,
3671 build_int_cst (TREE_TYPE (var), 1));
726a989a 3672 gfc_add_modify (&block, count, tmp);
6de9cd9a
DN
3673
3674 body = gfc_finish_block (&block);
3675
3676 /* Loop var initialization. */
3677 gfc_init_block (&block);
726a989a 3678 gfc_add_modify (&block, var, start);
6de9cd9a 3679
fcf3be37 3680
6de9cd9a 3681 /* Initialize the loop counter. */
bc98ed60
TB
3682 tmp = fold_build2_loc (input_location, MINUS_EXPR, TREE_TYPE (var), step,
3683 start);
3684 tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (var), end,
3685 tmp);
3686 tmp = fold_build2_loc (input_location, TRUNC_DIV_EXPR, TREE_TYPE (var),
3687 tmp, step);
726a989a 3688 gfc_add_modify (&block, count, tmp);
6de9cd9a
DN
3689
3690 /* The loop expression. */
923ab88c 3691 tmp = build1_v (LOOP_EXPR, body);
6de9cd9a
DN
3692 gfc_add_expr_to_block (&block, tmp);
3693
3694 /* The exit label. */
3695 tmp = build1_v (LABEL_EXPR, exit_label);
3696 gfc_add_expr_to_block (&block, tmp);
3697
3698 body = gfc_finish_block (&block);
3699 iter = iter->next;
3700 }
3701 return body;
3702}
3703
3704
bfcabc6c
RS
3705/* Generate the body and loops according to MASK_FLAG. If MASK_FLAG
3706 is nonzero, the body is controlled by all masks in the forall nest.
3707 Otherwise, the innermost loop is not controlled by it's mask. This
3708 is used for initializing that mask. */
6de9cd9a
DN
3709
3710static tree
3711gfc_trans_nested_forall_loop (forall_info * nested_forall_info, tree body,
bfcabc6c 3712 int mask_flag)
6de9cd9a
DN
3713{
3714 tree tmp;
bfcabc6c 3715 stmtblock_t header;
6de9cd9a 3716 forall_info *forall_tmp;
bfcabc6c
RS
3717 tree mask, maskindex;
3718
3719 gfc_start_block (&header);
6de9cd9a
DN
3720
3721 forall_tmp = nested_forall_info;
bfcabc6c 3722 while (forall_tmp != NULL)
6de9cd9a 3723 {
bfcabc6c
RS
3724 /* Generate body with masks' control. */
3725 if (mask_flag)
6de9cd9a 3726 {
bfcabc6c
RS
3727 mask = forall_tmp->mask;
3728 maskindex = forall_tmp->maskindex;
6de9cd9a 3729
bfcabc6c
RS
3730 /* If a mask was specified make the assignment conditional. */
3731 if (mask)
3732 {
1d6b7f39 3733 tmp = gfc_build_array_ref (mask, maskindex, NULL);
c2255bc4
AH
3734 body = build3_v (COND_EXPR, tmp, body,
3735 build_empty_stmt (input_location));
6de9cd9a 3736 }
6de9cd9a 3737 }
bfcabc6c 3738 body = gfc_trans_forall_loop (forall_tmp, body, mask_flag, &header);
e8d366ec 3739 forall_tmp = forall_tmp->prev_nest;
bfcabc6c 3740 mask_flag = 1;
6de9cd9a
DN
3741 }
3742
bfcabc6c
RS
3743 gfc_add_expr_to_block (&header, body);
3744 return gfc_finish_block (&header);
6de9cd9a
DN
3745}
3746
3747
3748/* Allocate data for holding a temporary array. Returns either a local
3749 temporary array or a pointer variable. */
3750
3751static tree
3752gfc_do_allocate (tree bytesize, tree size, tree * pdata, stmtblock_t * pblock,
3753 tree elem_type)
3754{
3755 tree tmpvar;
3756 tree type;
3757 tree tmp;
6de9cd9a
DN
3758
3759 if (INTEGER_CST_P (size))
bc98ed60
TB
3760 tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
3761 size, gfc_index_one_node);
6de9cd9a
DN
3762 else
3763 tmp = NULL_TREE;
3764
7ab92584 3765 type = build_range_type (gfc_array_index_type, gfc_index_zero_node, tmp);
6de9cd9a 3766 type = build_array_type (elem_type, type);
55250ed7 3767 if (gfc_can_put_var_on_stack (bytesize) && INTEGER_CST_P (size))
6de9cd9a 3768 {
6de9cd9a
DN
3769 tmpvar = gfc_create_var (type, "temp");
3770 *pdata = NULL_TREE;
3771 }
3772 else
3773 {
3774 tmpvar = gfc_create_var (build_pointer_type (type), "temp");
3775 *pdata = convert (pvoid_type_node, tmpvar);
3776
1529b8d9 3777 tmp = gfc_call_malloc (pblock, TREE_TYPE (tmpvar), bytesize);
726a989a 3778 gfc_add_modify (pblock, tmpvar, tmp);
6de9cd9a
DN
3779 }
3780 return tmpvar;
3781}
3782
3783
3784/* Generate codes to copy the temporary to the actual lhs. */
3785
3786static tree
8de1f441 3787generate_loop_for_temp_to_lhs (gfc_expr *expr, tree tmp1, tree count3,
7bd5dad2
LK
3788 tree count1,
3789 gfc_ss *lss, gfc_ss *rss,
3790 tree wheremask, bool invert)
6de9cd9a 3791{
7bd5dad2
LK
3792 stmtblock_t block, body1;
3793 gfc_loopinfo loop;
3794 gfc_se lse;
3795 gfc_se rse;
011daa76 3796 tree tmp;
6de9cd9a
DN
3797 tree wheremaskexpr;
3798
7bd5dad2 3799 (void) rss; /* TODO: unused. */
6de9cd9a 3800
7bd5dad2 3801 gfc_start_block (&block);
6de9cd9a 3802
7bd5dad2
LK
3803 gfc_init_se (&rse, NULL);
3804 gfc_init_se (&lse, NULL);
6de9cd9a 3805
7bd5dad2
LK
3806 if (lss == gfc_ss_terminator)
3807 {
3808 gfc_init_block (&body1);
6de9cd9a 3809 gfc_conv_expr (&lse, expr);
7bd5dad2 3810 rse.expr = gfc_build_array_ref (tmp1, count1, NULL);
6de9cd9a
DN
3811 }
3812 else
3813 {
7bd5dad2
LK
3814 /* Initialize the loop. */
3815 gfc_init_loopinfo (&loop);
6de9cd9a 3816
7bd5dad2
LK
3817 /* We may need LSS to determine the shape of the expression. */
3818 gfc_add_ss_to_loop (&loop, lss);
6de9cd9a 3819
7bd5dad2
LK
3820 gfc_conv_ss_startstride (&loop);
3821 gfc_conv_loop_setup (&loop, &expr->where);
6de9cd9a
DN
3822
3823 gfc_mark_ss_chain_used (lss, 1);
7bd5dad2
LK
3824 /* Start the loop body. */
3825 gfc_start_scalarized_body (&loop, &body1);
6de9cd9a 3826
7bd5dad2
LK
3827 /* Translate the expression. */
3828 gfc_copy_loopinfo_to_se (&lse, &loop);
6de9cd9a 3829 lse.ss = lss;
7bd5dad2 3830 gfc_conv_expr (&lse, expr);
6de9cd9a
DN
3831
3832 /* Form the expression of the temporary. */
7bd5dad2
LK
3833 rse.expr = gfc_build_array_ref (tmp1, count1, NULL);
3834 }
6de9cd9a 3835
7bd5dad2
LK
3836 /* Use the scalar assignment. */
3837 rse.string_length = lse.string_length;
3838 tmp = gfc_trans_scalar_assign (&lse, &rse, expr->ts,
3839 expr->expr_type == EXPR_VARIABLE, false);
6de9cd9a 3840
7bd5dad2
LK
3841 /* Form the mask expression according to the mask tree list. */
3842 if (wheremask)
3843 {
3844 wheremaskexpr = gfc_build_array_ref (wheremask, count3, NULL);
3845 if (invert)
3846 wheremaskexpr = fold_build1_loc (input_location, TRUTH_NOT_EXPR,
3847 TREE_TYPE (wheremaskexpr),
3848 wheremaskexpr);
3849 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
3850 wheremaskexpr, tmp,
3851 build_empty_stmt (input_location));
3852 }
6de9cd9a 3853
7bd5dad2 3854 gfc_add_expr_to_block (&body1, tmp);
6de9cd9a 3855
7bd5dad2
LK
3856 tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (count1),
3857 count1, gfc_index_one_node);
3858 gfc_add_modify (&body1, count1, tmp);
6de9cd9a 3859
7bd5dad2
LK
3860 if (lss == gfc_ss_terminator)
3861 gfc_add_block_to_block (&block, &body1);
3862 else
3863 {
6de9cd9a
DN
3864 /* Increment count3. */
3865 if (count3)
8de1f441 3866 {
bc98ed60 3867 tmp = fold_build2_loc (input_location, PLUS_EXPR,
7bd5dad2
LK
3868 gfc_array_index_type,
3869 count3, gfc_index_one_node);
3870 gfc_add_modify (&body1, count3, tmp);
8de1f441 3871 }
6de9cd9a
DN
3872
3873 /* Generate the copying loops. */
7bd5dad2
LK
3874 gfc_trans_scalarizing_loops (&loop, &body1);
3875
3876 gfc_add_block_to_block (&block, &loop.pre);
3877 gfc_add_block_to_block (&block, &loop.post);
6de9cd9a 3878
7bd5dad2
LK
3879 gfc_cleanup_loop (&loop);
3880 /* TODO: Reuse lss and rss when copying temp->lhs. Need to be careful
3881 as tree nodes in SS may not be valid in different scope. */
6de9cd9a 3882 }
7bd5dad2
LK
3883
3884 tmp = gfc_finish_block (&block);
6de9cd9a
DN
3885 return tmp;
3886}
3887
3888
011daa76
RS
3889/* Generate codes to copy rhs to the temporary. TMP1 is the address of
3890 temporary, LSS and RSS are formed in function compute_inner_temp_size(),
3891 and should not be freed. WHEREMASK is the conditional execution mask
3892 whose sense may be inverted by INVERT. */
6de9cd9a
DN
3893
3894static tree
8de1f441
JJ
3895generate_loop_for_rhs_to_temp (gfc_expr *expr2, tree tmp1, tree count3,
3896 tree count1, gfc_ss *lss, gfc_ss *rss,
011daa76 3897 tree wheremask, bool invert)
6de9cd9a
DN
3898{
3899 stmtblock_t block, body1;
3900 gfc_loopinfo loop;
3901 gfc_se lse;
3902 gfc_se rse;
011daa76 3903 tree tmp;
6de9cd9a
DN
3904 tree wheremaskexpr;
3905
3906 gfc_start_block (&block);
3907
3908 gfc_init_se (&rse, NULL);
3909 gfc_init_se (&lse, NULL);
3910
3911 if (lss == gfc_ss_terminator)
3912 {
3913 gfc_init_block (&body1);
3914 gfc_conv_expr (&rse, expr2);
1d6b7f39 3915 lse.expr = gfc_build_array_ref (tmp1, count1, NULL);
6de9cd9a
DN
3916 }
3917 else
3918 {
1f2959f0 3919 /* Initialize the loop. */
6de9cd9a
DN
3920 gfc_init_loopinfo (&loop);
3921
3922 /* We may need LSS to determine the shape of the expression. */
3923 gfc_add_ss_to_loop (&loop, lss);
3924 gfc_add_ss_to_loop (&loop, rss);
3925
3926 gfc_conv_ss_startstride (&loop);
bdfd2ff0 3927 gfc_conv_loop_setup (&loop, &expr2->where);
6de9cd9a
DN
3928
3929 gfc_mark_ss_chain_used (rss, 1);
3930 /* Start the loop body. */
3931 gfc_start_scalarized_body (&loop, &body1);
3932
3933 /* Translate the expression. */
3934 gfc_copy_loopinfo_to_se (&rse, &loop);
3935 rse.ss = rss;
3936 gfc_conv_expr (&rse, expr2);
3937
3938 /* Form the expression of the temporary. */
1d6b7f39 3939 lse.expr = gfc_build_array_ref (tmp1, count1, NULL);
6de9cd9a
DN
3940 }
3941
3942 /* Use the scalar assignment. */
5046aff5 3943 lse.string_length = rse.string_length;
ed673c00
MM
3944 tmp = gfc_trans_scalar_assign (&lse, &rse, expr2->ts,
3945 expr2->expr_type == EXPR_VARIABLE, false);
6de9cd9a
DN
3946
3947 /* Form the mask expression according to the mask tree list. */
3948 if (wheremask)
3949 {
1d6b7f39 3950 wheremaskexpr = gfc_build_array_ref (wheremask, count3, NULL);
011daa76 3951 if (invert)
bc98ed60
TB
3952 wheremaskexpr = fold_build1_loc (input_location, TRUTH_NOT_EXPR,
3953 TREE_TYPE (wheremaskexpr),
3954 wheremaskexpr);
3955 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
3956 wheremaskexpr, tmp,
3957 build_empty_stmt (input_location));
6de9cd9a
DN
3958 }
3959
3960 gfc_add_expr_to_block (&body1, tmp);
3961
3962 if (lss == gfc_ss_terminator)
3963 {
3964 gfc_add_block_to_block (&block, &body1);
8de1f441
JJ
3965
3966 /* Increment count1. */
bc98ed60
TB
3967 tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (count1),
3968 count1, gfc_index_one_node);
726a989a 3969 gfc_add_modify (&block, count1, tmp);
6de9cd9a
DN
3970 }
3971 else
3972 {
8de1f441 3973 /* Increment count1. */
bc98ed60
TB
3974 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
3975 count1, gfc_index_one_node);
726a989a 3976 gfc_add_modify (&body1, count1, tmp);
6de9cd9a
DN
3977
3978 /* Increment count3. */
3979 if (count3)
8de1f441 3980 {
bc98ed60
TB
3981 tmp = fold_build2_loc (input_location, PLUS_EXPR,
3982 gfc_array_index_type,
3983 count3, gfc_index_one_node);
726a989a 3984 gfc_add_modify (&body1, count3, tmp);
8de1f441 3985 }
6de9cd9a
DN
3986
3987 /* Generate the copying loops. */
3988 gfc_trans_scalarizing_loops (&loop, &body1);
3989
3990 gfc_add_block_to_block (&block, &loop.pre);
3991 gfc_add_block_to_block (&block, &loop.post);
3992
3993 gfc_cleanup_loop (&loop);
3994 /* TODO: Reuse lss and rss when copying temp->lhs. Need to be careful
8de1f441 3995 as tree nodes in SS may not be valid in different scope. */
6de9cd9a 3996 }
6de9cd9a
DN
3997
3998 tmp = gfc_finish_block (&block);
3999 return tmp;
4000}
4001
4002
4003/* Calculate the size of temporary needed in the assignment inside forall.
4004 LSS and RSS are filled in this function. */
4005
4006static tree
4007compute_inner_temp_size (gfc_expr *expr1, gfc_expr *expr2,
4008 stmtblock_t * pblock,
4009 gfc_ss **lss, gfc_ss **rss)
4010{
4011 gfc_loopinfo loop;
4012 tree size;
4013 int i;
ca86ddcc 4014 int save_flag;
6de9cd9a
DN
4015 tree tmp;
4016
4017 *lss = gfc_walk_expr (expr1);
4018 *rss = NULL;
4019
7ab92584 4020 size = gfc_index_one_node;
6de9cd9a
DN
4021 if (*lss != gfc_ss_terminator)
4022 {
4023 gfc_init_loopinfo (&loop);
4024
4025 /* Walk the RHS of the expression. */
4026 *rss = gfc_walk_expr (expr2);
4027 if (*rss == gfc_ss_terminator)
26f77530
MM
4028 /* The rhs is scalar. Add a ss for the expression. */
4029 *rss = gfc_get_scalar_ss (gfc_ss_terminator, expr2);
6de9cd9a
DN
4030
4031 /* Associate the SS with the loop. */
4032 gfc_add_ss_to_loop (&loop, *lss);
4033 /* We don't actually need to add the rhs at this point, but it might
4034 make guessing the loop bounds a bit easier. */
4035 gfc_add_ss_to_loop (&loop, *rss);
4036
4037 /* We only want the shape of the expression, not rest of the junk
4038 generated by the scalarizer. */
4039 loop.array_parameter = 1;
4040
4041 /* Calculate the bounds of the scalarization. */
d3d3011f 4042 save_flag = gfc_option.rtcheck;
c3fb8214 4043 gfc_option.rtcheck &= ~GFC_RTCHECK_BOUNDS;
6de9cd9a 4044 gfc_conv_ss_startstride (&loop);
d3d3011f 4045 gfc_option.rtcheck = save_flag;
bdfd2ff0 4046 gfc_conv_loop_setup (&loop, &expr2->where);
6de9cd9a
DN
4047
4048 /* Figure out how many elements we need. */
4049 for (i = 0; i < loop.dimen; i++)
4050 {
bc98ed60
TB
4051 tmp = fold_build2_loc (input_location, MINUS_EXPR,
4052 gfc_array_index_type,
4053 gfc_index_one_node, loop.from[i]);
4054 tmp = fold_build2_loc (input_location, PLUS_EXPR,
4055 gfc_array_index_type, tmp, loop.to[i]);
4056 size = fold_build2_loc (input_location, MULT_EXPR,
4057 gfc_array_index_type, size, tmp);
6de9cd9a
DN
4058 }
4059 gfc_add_block_to_block (pblock, &loop.pre);
4060 size = gfc_evaluate_now (size, pblock);
4061 gfc_add_block_to_block (pblock, &loop.post);
4062
4063 /* TODO: write a function that cleans up a loopinfo without freeing
4064 the SS chains. Currently a NOP. */
4065 }
4066
4067 return size;
4068}
4069
4070
2ad62c9b
RS
4071/* Calculate the overall iterator number of the nested forall construct.
4072 This routine actually calculates the number of times the body of the
4073 nested forall specified by NESTED_FORALL_INFO is executed and multiplies
4074 that by the expression INNER_SIZE. The BLOCK argument specifies the
4075 block in which to calculate the result, and the optional INNER_SIZE_BODY
4076 argument contains any statements that need to executed (inside the loop)
4077 to initialize or calculate INNER_SIZE. */
6de9cd9a
DN
4078
4079static tree
4080compute_overall_iter_number (forall_info *nested_forall_info, tree inner_size,
8de1f441 4081 stmtblock_t *inner_size_body, stmtblock_t *block)
6de9cd9a 4082{
2ad62c9b 4083 forall_info *forall_tmp = nested_forall_info;
6de9cd9a
DN
4084 tree tmp, number;
4085 stmtblock_t body;
4086
2ad62c9b
RS
4087 /* We can eliminate the innermost unconditional loops with constant
4088 array bounds. */
3bf783b7
RS
4089 if (INTEGER_CST_P (inner_size))
4090 {
2ad62c9b 4091 while (forall_tmp
8b704316 4092 && !forall_tmp->mask
2ad62c9b 4093 && INTEGER_CST_P (forall_tmp->size))
3bf783b7 4094 {
bc98ed60
TB
4095 inner_size = fold_build2_loc (input_location, MULT_EXPR,
4096 gfc_array_index_type,
4097 inner_size, forall_tmp->size);
2ad62c9b 4098 forall_tmp = forall_tmp->prev_nest;
3bf783b7 4099 }
2ad62c9b
RS
4100
4101 /* If there are no loops left, we have our constant result. */
4102 if (!forall_tmp)
4103 return inner_size;
3bf783b7 4104 }
2ad62c9b
RS
4105
4106 /* Otherwise, create a temporary variable to compute the result. */
6de9cd9a 4107 number = gfc_create_var (gfc_array_index_type, "num");
726a989a 4108 gfc_add_modify (block, number, gfc_index_zero_node);
6de9cd9a
DN
4109
4110 gfc_start_block (&body);
8de1f441
JJ
4111 if (inner_size_body)
4112 gfc_add_block_to_block (&body, inner_size_body);
2ad62c9b 4113 if (forall_tmp)
bc98ed60
TB
4114 tmp = fold_build2_loc (input_location, PLUS_EXPR,
4115 gfc_array_index_type, number, inner_size);
6de9cd9a
DN
4116 else
4117 tmp = inner_size;
726a989a 4118 gfc_add_modify (&body, number, tmp);
6de9cd9a
DN
4119 tmp = gfc_finish_block (&body);
4120
4121 /* Generate loops. */
2ad62c9b
RS
4122 if (forall_tmp != NULL)
4123 tmp = gfc_trans_nested_forall_loop (forall_tmp, tmp, 1);
6de9cd9a
DN
4124
4125 gfc_add_expr_to_block (block, tmp);
4126
4127 return number;
4128}
4129
4130
8de1f441
JJ
4131/* Allocate temporary for forall construct. SIZE is the size of temporary
4132 needed. PTEMP1 is returned for space free. */
6de9cd9a
DN
4133
4134static tree
8de1f441
JJ
4135allocate_temp_for_forall_nest_1 (tree type, tree size, stmtblock_t * block,
4136 tree * ptemp1)
6de9cd9a 4137{
bfcabc6c 4138 tree bytesize;
6de9cd9a 4139 tree unit;
6de9cd9a 4140 tree tmp;
6de9cd9a 4141
7c57b2f1 4142 unit = fold_convert (gfc_array_index_type, TYPE_SIZE_UNIT (type));
bfcabc6c 4143 if (!integer_onep (unit))
bc98ed60
TB
4144 bytesize = fold_build2_loc (input_location, MULT_EXPR,
4145 gfc_array_index_type, size, unit);
bfcabc6c
RS
4146 else
4147 bytesize = size;
6de9cd9a
DN
4148
4149 *ptemp1 = NULL;
bfcabc6c 4150 tmp = gfc_do_allocate (bytesize, size, ptemp1, block, type);
6de9cd9a
DN
4151
4152 if (*ptemp1)
db3927fb 4153 tmp = build_fold_indirect_ref_loc (input_location, tmp);
6de9cd9a
DN
4154 return tmp;
4155}
4156
4157
8de1f441
JJ
4158/* Allocate temporary for forall construct according to the information in
4159 nested_forall_info. INNER_SIZE is the size of temporary needed in the
4160 assignment inside forall. PTEMP1 is returned for space free. */
4161
4162static tree
4163allocate_temp_for_forall_nest (forall_info * nested_forall_info, tree type,
4164 tree inner_size, stmtblock_t * inner_size_body,
4165 stmtblock_t * block, tree * ptemp1)
4166{
4167 tree size;
4168
4169 /* Calculate the total size of temporary needed in forall construct. */
4170 size = compute_overall_iter_number (nested_forall_info, inner_size,
4171 inner_size_body, block);
4172
4173 return allocate_temp_for_forall_nest_1 (type, size, block, ptemp1);
4174}
4175
4176
4177/* Handle assignments inside forall which need temporary.
4178
4179 forall (i=start:end:stride; maskexpr)
4180 e<i> = f<i>
4181 end forall
4182 (where e,f<i> are arbitrary expressions possibly involving i
4183 and there is a dependency between e<i> and f<i>)
4184 Translates to:
4185 masktmp(:) = maskexpr(:)
4186
4187 maskindex = 0;
4188 count1 = 0;
4189 num = 0;
4190 for (i = start; i <= end; i += stride)
4191 num += SIZE (f<i>)
4192 count1 = 0;
4193 ALLOCATE (tmp(num))
4194 for (i = start; i <= end; i += stride)
4195 {
4196 if (masktmp[maskindex++])
4197 tmp[count1++] = f<i>
4198 }
4199 maskindex = 0;
4200 count1 = 0;
4201 for (i = start; i <= end; i += stride)
4202 {
4203 if (masktmp[maskindex++])
4204 e<i> = tmp[count1++]
4205 }
4206 DEALLOCATE (tmp)
4207 */
6de9cd9a 4208static void
011daa76
RS
4209gfc_trans_assign_need_temp (gfc_expr * expr1, gfc_expr * expr2,
4210 tree wheremask, bool invert,
6de9cd9a
DN
4211 forall_info * nested_forall_info,
4212 stmtblock_t * block)
4213{
4214 tree type;
4215 tree inner_size;
4216 gfc_ss *lss, *rss;
8de1f441 4217 tree count, count1;
6de9cd9a
DN
4218 tree tmp, tmp1;
4219 tree ptemp1;
8de1f441 4220 stmtblock_t inner_size_body;
6de9cd9a 4221
8de1f441
JJ
4222 /* Create vars. count1 is the current iterator number of the nested
4223 forall. */
6de9cd9a 4224 count1 = gfc_create_var (gfc_array_index_type, "count1");
6de9cd9a
DN
4225
4226 /* Count is the wheremask index. */
4227 if (wheremask)
4228 {
4229 count = gfc_create_var (gfc_array_index_type, "count");
726a989a 4230 gfc_add_modify (block, count, gfc_index_zero_node);
6de9cd9a
DN
4231 }
4232 else
4233 count = NULL;
4234
4235 /* Initialize count1. */
726a989a 4236 gfc_add_modify (block, count1, gfc_index_zero_node);
6de9cd9a
DN
4237
4238 /* Calculate the size of temporary needed in the assignment. Return loop, lss
4239 and rss which are used in function generate_loop_for_rhs_to_temp(). */
6de9cd9a 4240 /* The type of LHS. Used in function allocate_temp_for_forall_nest */
7bd5dad2 4241 if (expr1->ts.type == BT_CHARACTER)
640670c7 4242 {
7bd5dad2
LK
4243 type = NULL;
4244 if (expr1->ref && expr1->ref->type == REF_SUBSTRING)
640670c7 4245 {
7bd5dad2
LK
4246 gfc_se ssse;
4247 gfc_init_se (&ssse, NULL);
4248 gfc_conv_expr (&ssse, expr1);
4249 type = gfc_get_character_type_len (gfc_default_character_kind,
4250 ssse.string_length);
4251 }
4252 else
4253 {
4254 if (!expr1->ts.u.cl->backend_decl)
4255 {
4256 gfc_se tse;
4257 gcc_assert (expr1->ts.u.cl->length);
4258 gfc_init_se (&tse, NULL);
4259 gfc_conv_expr (&tse, expr1->ts.u.cl->length);
4260 expr1->ts.u.cl->backend_decl = tse.expr;
4261 }
4262 type = gfc_get_character_type_len (gfc_default_character_kind,
4263 expr1->ts.u.cl->backend_decl);
640670c7 4264 }
640670c7
PT
4265 }
4266 else
4267 type = gfc_typenode_for_spec (&expr1->ts);
6de9cd9a 4268
7bd5dad2
LK
4269 gfc_init_block (&inner_size_body);
4270 inner_size = compute_inner_temp_size (expr1, expr2, &inner_size_body,
4271 &lss, &rss);
4272
6de9cd9a 4273 /* Allocate temporary for nested forall construct according to the
f7b529fa 4274 information in nested_forall_info and inner_size. */
8de1f441
JJ
4275 tmp1 = allocate_temp_for_forall_nest (nested_forall_info, type, inner_size,
4276 &inner_size_body, block, &ptemp1);
6de9cd9a 4277
6de9cd9a 4278 /* Generate codes to copy rhs to the temporary . */
8de1f441 4279 tmp = generate_loop_for_rhs_to_temp (expr2, tmp1, count, count1, lss, rss,
011daa76 4280 wheremask, invert);
6de9cd9a 4281
1f2959f0 4282 /* Generate body and loops according to the information in
6de9cd9a 4283 nested_forall_info. */
bfcabc6c 4284 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
6de9cd9a
DN
4285 gfc_add_expr_to_block (block, tmp);
4286
4287 /* Reset count1. */
726a989a 4288 gfc_add_modify (block, count1, gfc_index_zero_node);
6de9cd9a 4289
6de9cd9a
DN
4290 /* Reset count. */
4291 if (wheremask)
726a989a 4292 gfc_add_modify (block, count, gfc_index_zero_node);
6de9cd9a 4293
7bd5dad2
LK
4294 /* TODO: Second call to compute_inner_temp_size to initialize lss and
4295 rss; there must be a better way. */
4296 inner_size = compute_inner_temp_size (expr1, expr2, &inner_size_body,
4297 &lss, &rss);
4298
6de9cd9a 4299 /* Generate codes to copy the temporary to lhs. */
011daa76 4300 tmp = generate_loop_for_temp_to_lhs (expr1, tmp1, count, count1,
7bd5dad2 4301 lss, rss,
011daa76 4302 wheremask, invert);
6de9cd9a 4303
1f2959f0 4304 /* Generate body and loops according to the information in
6de9cd9a 4305 nested_forall_info. */
bfcabc6c 4306 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
6de9cd9a
DN
4307 gfc_add_expr_to_block (block, tmp);
4308
4309 if (ptemp1)
4310 {
4311 /* Free the temporary. */
1529b8d9 4312 tmp = gfc_call_free (ptemp1);
6de9cd9a
DN
4313 gfc_add_expr_to_block (block, tmp);
4314 }
4315}
4316
4317
4318/* Translate pointer assignment inside FORALL which need temporary. */
4319
4320static void
4321gfc_trans_pointer_assign_need_temp (gfc_expr * expr1, gfc_expr * expr2,
4322 forall_info * nested_forall_info,
4323 stmtblock_t * block)
4324{
4325 tree type;
4326 tree inner_size;
4327 gfc_ss *lss, *rss;
4328 gfc_se lse;
4329 gfc_se rse;
6d63e468 4330 gfc_array_info *info;
6de9cd9a
DN
4331 gfc_loopinfo loop;
4332 tree desc;
4333 tree parm;
4334 tree parmtype;
4335 stmtblock_t body;
4336 tree count;
4337 tree tmp, tmp1, ptemp1;
6de9cd9a
DN
4338
4339 count = gfc_create_var (gfc_array_index_type, "count");
726a989a 4340 gfc_add_modify (block, count, gfc_index_zero_node);
6de9cd9a 4341
932ebb94 4342 inner_size = gfc_index_one_node;
6de9cd9a
DN
4343 lss = gfc_walk_expr (expr1);
4344 rss = gfc_walk_expr (expr2);
4345 if (lss == gfc_ss_terminator)
4346 {
4347 type = gfc_typenode_for_spec (&expr1->ts);
4348 type = build_pointer_type (type);
4349
4350 /* Allocate temporary for nested forall construct according to the
4351 information in nested_forall_info and inner_size. */
8de1f441
JJ
4352 tmp1 = allocate_temp_for_forall_nest (nested_forall_info, type,
4353 inner_size, NULL, block, &ptemp1);
6de9cd9a
DN
4354 gfc_start_block (&body);
4355 gfc_init_se (&lse, NULL);
1d6b7f39 4356 lse.expr = gfc_build_array_ref (tmp1, count, NULL);
6de9cd9a
DN
4357 gfc_init_se (&rse, NULL);
4358 rse.want_pointer = 1;
4359 gfc_conv_expr (&rse, expr2);
4360 gfc_add_block_to_block (&body, &rse.pre);
726a989a 4361 gfc_add_modify (&body, lse.expr,
cc2804f1 4362 fold_convert (TREE_TYPE (lse.expr), rse.expr));
6de9cd9a
DN
4363 gfc_add_block_to_block (&body, &rse.post);
4364
4365 /* Increment count. */
bc98ed60
TB
4366 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
4367 count, gfc_index_one_node);
726a989a 4368 gfc_add_modify (&body, count, tmp);
6de9cd9a
DN
4369
4370 tmp = gfc_finish_block (&body);
4371
1f2959f0 4372 /* Generate body and loops according to the information in
6de9cd9a 4373 nested_forall_info. */
bfcabc6c 4374 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
6de9cd9a
DN
4375 gfc_add_expr_to_block (block, tmp);
4376
4377 /* Reset count. */
726a989a 4378 gfc_add_modify (block, count, gfc_index_zero_node);
6de9cd9a 4379
6de9cd9a
DN
4380 gfc_start_block (&body);
4381 gfc_init_se (&lse, NULL);
4382 gfc_init_se (&rse, NULL);
1d6b7f39 4383 rse.expr = gfc_build_array_ref (tmp1, count, NULL);
6de9cd9a
DN
4384 lse.want_pointer = 1;
4385 gfc_conv_expr (&lse, expr1);
4386 gfc_add_block_to_block (&body, &lse.pre);
726a989a 4387 gfc_add_modify (&body, lse.expr, rse.expr);
6de9cd9a
DN
4388 gfc_add_block_to_block (&body, &lse.post);
4389 /* Increment count. */
bc98ed60
TB
4390 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
4391 count, gfc_index_one_node);
726a989a 4392 gfc_add_modify (&body, count, tmp);
6de9cd9a
DN
4393 tmp = gfc_finish_block (&body);
4394
1f2959f0 4395 /* Generate body and loops according to the information in
6de9cd9a 4396 nested_forall_info. */
bfcabc6c 4397 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
6de9cd9a
DN
4398 gfc_add_expr_to_block (block, tmp);
4399 }
4400 else
4401 {
4402 gfc_init_loopinfo (&loop);
4403
4404 /* Associate the SS with the loop. */
4405 gfc_add_ss_to_loop (&loop, rss);
4406
4407 /* Setup the scalarizing loops and bounds. */
4408 gfc_conv_ss_startstride (&loop);
4409
bdfd2ff0 4410 gfc_conv_loop_setup (&loop, &expr2->where);
6de9cd9a 4411
1838afec 4412 info = &rss->info->data.array;
6de9cd9a
DN
4413 desc = info->descriptor;
4414
4415 /* Make a new descriptor. */
4416 parmtype = gfc_get_element_type (TREE_TYPE (desc));
f33beee9 4417 parmtype = gfc_get_array_type_bounds (parmtype, loop.dimen, 0,
fad0afd7 4418 loop.from, loop.to, 1,
10174ddf 4419 GFC_ARRAY_UNKNOWN, true);
6de9cd9a
DN
4420
4421 /* Allocate temporary for nested forall construct. */
4422 tmp1 = allocate_temp_for_forall_nest (nested_forall_info, parmtype,
8de1f441 4423 inner_size, NULL, block, &ptemp1);
6de9cd9a
DN
4424 gfc_start_block (&body);
4425 gfc_init_se (&lse, NULL);
1d6b7f39 4426 lse.expr = gfc_build_array_ref (tmp1, count, NULL);
6de9cd9a 4427 lse.direct_byref = 1;
2960a368 4428 gfc_conv_expr_descriptor (&lse, expr2);
6de9cd9a
DN
4429
4430 gfc_add_block_to_block (&body, &lse.pre);
4431 gfc_add_block_to_block (&body, &lse.post);
4432
4433 /* Increment count. */
bc98ed60
TB
4434 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
4435 count, gfc_index_one_node);
726a989a 4436 gfc_add_modify (&body, count, tmp);
6de9cd9a
DN
4437
4438 tmp = gfc_finish_block (&body);
4439
1f2959f0 4440 /* Generate body and loops according to the information in
6de9cd9a 4441 nested_forall_info. */
bfcabc6c 4442 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
6de9cd9a
DN
4443 gfc_add_expr_to_block (block, tmp);
4444
4445 /* Reset count. */
726a989a 4446 gfc_add_modify (block, count, gfc_index_zero_node);
6de9cd9a 4447
1d6b7f39 4448 parm = gfc_build_array_ref (tmp1, count, NULL);
6de9cd9a 4449 gfc_init_se (&lse, NULL);
2960a368 4450 gfc_conv_expr_descriptor (&lse, expr1);
726a989a 4451 gfc_add_modify (&lse.pre, lse.expr, parm);
6de9cd9a
DN
4452 gfc_start_block (&body);
4453 gfc_add_block_to_block (&body, &lse.pre);
4454 gfc_add_block_to_block (&body, &lse.post);
4455
4456 /* Increment count. */
bc98ed60
TB
4457 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
4458 count, gfc_index_one_node);
726a989a 4459 gfc_add_modify (&body, count, tmp);
6de9cd9a
DN
4460
4461 tmp = gfc_finish_block (&body);
4462
bfcabc6c 4463 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
6de9cd9a
DN
4464 gfc_add_expr_to_block (block, tmp);
4465 }
4466 /* Free the temporary. */
4467 if (ptemp1)
4468 {
1529b8d9 4469 tmp = gfc_call_free (ptemp1);
6de9cd9a
DN
4470 gfc_add_expr_to_block (block, tmp);
4471 }
4472}
4473
4474
4475/* FORALL and WHERE statements are really nasty, especially when you nest
4476 them. All the rhs of a forall assignment must be evaluated before the
4477 actual assignments are performed. Presumably this also applies to all the
4478 assignments in an inner where statement. */
4479
4480/* Generate code for a FORALL statement. Any temporaries are allocated as a
4481 linear array, relying on the fact that we process in the same order in all
4482 loops.
4483
4484 forall (i=start:end:stride; maskexpr)
4485 e<i> = f<i>
4486 g<i> = h<i>
4487 end forall
e7dc5b4f 4488 (where e,f,g,h<i> are arbitrary expressions possibly involving i)
6de9cd9a 4489 Translates to:
8de1f441 4490 count = ((end + 1 - start) / stride)
6de9cd9a
DN
4491 masktmp(:) = maskexpr(:)
4492
4493 maskindex = 0;
4494 for (i = start; i <= end; i += stride)
4495 {
4496 if (masktmp[maskindex++])
4497 e<i> = f<i>
4498 }
4499 maskindex = 0;
4500 for (i = start; i <= end; i += stride)
4501 {
4502 if (masktmp[maskindex++])
cafa34aa 4503 g<i> = h<i>
6de9cd9a
DN
4504 }
4505
4506 Note that this code only works when there are no dependencies.
4507 Forall loop with array assignments and data dependencies are a real pain,
4508 because the size of the temporary cannot always be determined before the
1f2959f0 4509 loop is executed. This problem is compounded by the presence of nested
6de9cd9a
DN
4510 FORALL constructs.
4511 */
4512
4513static tree
4514gfc_trans_forall_1 (gfc_code * code, forall_info * nested_forall_info)
4515{
640670c7
PT
4516 stmtblock_t pre;
4517 stmtblock_t post;
6de9cd9a
DN
4518 stmtblock_t block;
4519 stmtblock_t body;
4520 tree *var;
4521 tree *start;
4522 tree *end;
4523 tree *step;
4524 gfc_expr **varexpr;
4525 tree tmp;
4526 tree assign;
4527 tree size;
6de9cd9a
DN
4528 tree maskindex;
4529 tree mask;
4530 tree pmask;
8c6a85e3 4531 tree cycle_label = NULL_TREE;
6de9cd9a
DN
4532 int n;
4533 int nvar;
4534 int need_temp;
4535 gfc_forall_iterator *fa;
4536 gfc_se se;
4537 gfc_code *c;
7b5b57b7 4538 gfc_saved_var *saved_vars;
bfcabc6c
RS
4539 iter_info *this_forall;
4540 forall_info *info;
e35a0e64
RS
4541 bool need_mask;
4542
4543 /* Do nothing if the mask is false. */
a513927a
SK
4544 if (code->expr1
4545 && code->expr1->expr_type == EXPR_CONSTANT
4546 && !code->expr1->value.logical)
c2255bc4 4547 return build_empty_stmt (input_location);
6de9cd9a
DN
4548
4549 n = 0;
4550 /* Count the FORALL index number. */
4551 for (fa = code->ext.forall_iterator; fa; fa = fa->next)
4552 n++;
4553 nvar = n;
4554
4555 /* Allocate the space for var, start, end, step, varexpr. */
93acb62c
JB
4556 var = XCNEWVEC (tree, nvar);
4557 start = XCNEWVEC (tree, nvar);
4558 end = XCNEWVEC (tree, nvar);
4559 step = XCNEWVEC (tree, nvar);
4560 varexpr = XCNEWVEC (gfc_expr *, nvar);
4561 saved_vars = XCNEWVEC (gfc_saved_var, nvar);
6de9cd9a
DN
4562
4563 /* Allocate the space for info. */
93acb62c 4564 info = XCNEW (forall_info);
bfcabc6c 4565
640670c7
PT
4566 gfc_start_block (&pre);
4567 gfc_init_block (&post);
4568 gfc_init_block (&block);
bfcabc6c 4569
6de9cd9a
DN
4570 n = 0;
4571 for (fa = code->ext.forall_iterator; fa; fa = fa->next)
4572 {
4573 gfc_symbol *sym = fa->var->symtree->n.sym;
4574
bfcabc6c 4575 /* Allocate space for this_forall. */
93acb62c 4576 this_forall = XCNEW (iter_info);
6de9cd9a 4577
6de9cd9a
DN
4578 /* Create a temporary variable for the FORALL index. */
4579 tmp = gfc_typenode_for_spec (&sym->ts);
4580 var[n] = gfc_create_var (tmp, sym->name);
7b5b57b7
PB
4581 gfc_shadow_sym (sym, var[n], &saved_vars[n]);
4582
6de9cd9a
DN
4583 /* Record it in this_forall. */
4584 this_forall->var = var[n];
4585
4586 /* Replace the index symbol's backend_decl with the temporary decl. */
4587 sym->backend_decl = var[n];
4588
4589 /* Work out the start, end and stride for the loop. */
4590 gfc_init_se (&se, NULL);
4591 gfc_conv_expr_val (&se, fa->start);
4592 /* Record it in this_forall. */
4593 this_forall->start = se.expr;
4594 gfc_add_block_to_block (&block, &se.pre);
4595 start[n] = se.expr;
4596
4597 gfc_init_se (&se, NULL);
4598 gfc_conv_expr_val (&se, fa->end);
4599 /* Record it in this_forall. */
4600 this_forall->end = se.expr;
4601 gfc_make_safe_expr (&se);
4602 gfc_add_block_to_block (&block, &se.pre);
4603 end[n] = se.expr;
4604
4605 gfc_init_se (&se, NULL);
4606 gfc_conv_expr_val (&se, fa->stride);
4607 /* Record it in this_forall. */
4608 this_forall->step = se.expr;
4609 gfc_make_safe_expr (&se);
4610 gfc_add_block_to_block (&block, &se.pre);
4611 step[n] = se.expr;
4612
4613 /* Set the NEXT field of this_forall to NULL. */
4614 this_forall->next = NULL;
4615 /* Link this_forall to the info construct. */
bfcabc6c 4616 if (info->this_loop)
6de9cd9a 4617 {
bfcabc6c 4618 iter_info *iter_tmp = info->this_loop;
6de9cd9a
DN
4619 while (iter_tmp->next != NULL)
4620 iter_tmp = iter_tmp->next;
4621 iter_tmp->next = this_forall;
4622 }
bfcabc6c
RS
4623 else
4624 info->this_loop = this_forall;
6de9cd9a
DN
4625
4626 n++;
4627 }
4628 nvar = n;
4629
bfcabc6c 4630 /* Calculate the size needed for the current forall level. */
7ab92584 4631 size = gfc_index_one_node;
6de9cd9a
DN
4632 for (n = 0; n < nvar; n++)
4633 {
6de9cd9a 4634 /* size = (end + step - start) / step. */
8b704316 4635 tmp = fold_build2_loc (input_location, MINUS_EXPR, TREE_TYPE (start[n]),
bc98ed60
TB
4636 step[n], start[n]);
4637 tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (end[n]),
4638 end[n], tmp);
4639 tmp = fold_build2_loc (input_location, FLOOR_DIV_EXPR, TREE_TYPE (tmp),
4640 tmp, step[n]);
6de9cd9a
DN
4641 tmp = convert (gfc_array_index_type, tmp);
4642
bc98ed60
TB
4643 size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
4644 size, tmp);
6de9cd9a
DN
4645 }
4646
4647 /* Record the nvar and size of current forall level. */
4648 info->nvar = nvar;
4649 info->size = size;
4650
a513927a 4651 if (code->expr1)
e35a0e64
RS
4652 {
4653 /* If the mask is .true., consider the FORALL unconditional. */
a513927a
SK
4654 if (code->expr1->expr_type == EXPR_CONSTANT
4655 && code->expr1->value.logical)
e35a0e64
RS
4656 need_mask = false;
4657 else
4658 need_mask = true;
4659 }
4660 else
4661 need_mask = false;
4662
4663 /* First we need to allocate the mask. */
4664 if (need_mask)
bfcabc6c
RS
4665 {
4666 /* As the mask array can be very big, prefer compact boolean types. */
4667 tree mask_type = gfc_get_logical_type (gfc_logical_kinds[0].kind);
4668 mask = allocate_temp_for_forall_nest (nested_forall_info, mask_type,
4669 size, NULL, &block, &pmask);
4670 maskindex = gfc_create_var_np (gfc_array_index_type, "mi");
4671
4672 /* Record them in the info structure. */
4673 info->maskindex = maskindex;
4674 info->mask = mask;
4675 }
6de9cd9a
DN
4676 else
4677 {
bfcabc6c
RS
4678 /* No mask was specified. */
4679 maskindex = NULL_TREE;
4680 mask = pmask = NULL_TREE;
4681 }
4682
4683 /* Link the current forall level to nested_forall_info. */
e8d366ec
RS
4684 info->prev_nest = nested_forall_info;
4685 nested_forall_info = info;
6de9cd9a
DN
4686
4687 /* Copy the mask into a temporary variable if required.
f7b529fa 4688 For now we assume a mask temporary is needed. */
e35a0e64 4689 if (need_mask)
6de9cd9a 4690 {
bfcabc6c
RS
4691 /* As the mask array can be very big, prefer compact boolean types. */
4692 tree mask_type = gfc_get_logical_type (gfc_logical_kinds[0].kind);
6de9cd9a 4693
726a989a 4694 gfc_add_modify (&block, maskindex, gfc_index_zero_node);
6de9cd9a
DN
4695
4696 /* Start of mask assignment loop body. */
4697 gfc_start_block (&body);
4698
4699 /* Evaluate the mask expression. */
4700 gfc_init_se (&se, NULL);
a513927a 4701 gfc_conv_expr_val (&se, code->expr1);
6de9cd9a
DN
4702 gfc_add_block_to_block (&body, &se.pre);
4703
4704 /* Store the mask. */
bfcabc6c 4705 se.expr = convert (mask_type, se.expr);
6de9cd9a 4706
1d6b7f39 4707 tmp = gfc_build_array_ref (mask, maskindex, NULL);
726a989a 4708 gfc_add_modify (&body, tmp, se.expr);
6de9cd9a
DN
4709
4710 /* Advance to the next mask element. */
bc98ed60
TB
4711 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
4712 maskindex, gfc_index_one_node);
726a989a 4713 gfc_add_modify (&body, maskindex, tmp);
6de9cd9a
DN
4714
4715 /* Generate the loops. */
4716 tmp = gfc_finish_block (&body);
bfcabc6c 4717 tmp = gfc_trans_nested_forall_loop (info, tmp, 0);
6de9cd9a
DN
4718 gfc_add_expr_to_block (&block, tmp);
4719 }
6de9cd9a 4720
8c6a85e3
TB
4721 if (code->op == EXEC_DO_CONCURRENT)
4722 {
4723 gfc_init_block (&body);
4724 cycle_label = gfc_build_label_decl (NULL_TREE);
4725 code->cycle_label = cycle_label;
4726 tmp = gfc_trans_code (code->block->next);
4727 gfc_add_expr_to_block (&body, tmp);
4728
4729 if (TREE_USED (cycle_label))
4730 {
4731 tmp = build1_v (LABEL_EXPR, cycle_label);
4732 gfc_add_expr_to_block (&body, tmp);
4733 }
4734
4735 tmp = gfc_finish_block (&body);
2ca4e2c2 4736 nested_forall_info->do_concurrent = true;
8c6a85e3
TB
4737 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
4738 gfc_add_expr_to_block (&block, tmp);
4739 goto done;
4740 }
4741
6de9cd9a
DN
4742 c = code->block->next;
4743
4744 /* TODO: loop merging in FORALL statements. */
4745 /* Now that we've got a copy of the mask, generate the assignment loops. */
4746 while (c)
4747 {
4748 switch (c->op)
4749 {
4750 case EXEC_ASSIGN:
640670c7
PT
4751 /* A scalar or array assignment. DO the simple check for
4752 lhs to rhs dependencies. These make a temporary for the
4753 rhs and form a second forall block to copy to variable. */
4754 need_temp = check_forall_dependencies(c, &pre, &post);
4755
69de3b83 4756 /* Temporaries due to array assignment data dependencies introduce
6de9cd9a 4757 no end of problems. */
7bd5dad2
LK
4758 if (need_temp || flag_test_forall_temp)
4759 gfc_trans_assign_need_temp (c->expr1, c->expr2, NULL, false,
6de9cd9a
DN
4760 nested_forall_info, &block);
4761 else
4762 {
4763 /* Use the normal assignment copying routines. */
2b56d6a4 4764 assign = gfc_trans_assignment (c->expr1, c->expr2, false, true);
6de9cd9a 4765
6de9cd9a 4766 /* Generate body and loops. */
bfcabc6c
RS
4767 tmp = gfc_trans_nested_forall_loop (nested_forall_info,
4768 assign, 1);
6de9cd9a
DN
4769 gfc_add_expr_to_block (&block, tmp);
4770 }
4771
640670c7
PT
4772 /* Cleanup any temporary symtrees that have been made to deal
4773 with dependencies. */
4774 if (new_symtree)
4775 cleanup_forall_symtrees (c);
4776
6de9cd9a
DN
4777 break;
4778
4779 case EXEC_WHERE:
6de9cd9a 4780 /* Translate WHERE or WHERE construct nested in FORALL. */
011daa76 4781 gfc_trans_where_2 (c, NULL, false, nested_forall_info, &block);
3891cee2 4782 break;
6de9cd9a
DN
4783
4784 /* Pointer assignment inside FORALL. */
4785 case EXEC_POINTER_ASSIGN:
a513927a 4786 need_temp = gfc_check_dependency (c->expr1, c->expr2, 0);
7bd5dad2
LK
4787 /* Avoid cases where a temporary would never be needed and where
4788 the temp code is guaranteed to fail. */
4789 if (need_temp
4790 || (flag_test_forall_temp
4791 && c->expr2->expr_type != EXPR_CONSTANT
4792 && c->expr2->expr_type != EXPR_NULL))
a513927a 4793 gfc_trans_pointer_assign_need_temp (c->expr1, c->expr2,
6de9cd9a
DN
4794 nested_forall_info, &block);
4795 else
4796 {
4797 /* Use the normal assignment copying routines. */
a513927a 4798 assign = gfc_trans_pointer_assignment (c->expr1, c->expr2);
6de9cd9a 4799
6de9cd9a 4800 /* Generate body and loops. */
bfcabc6c
RS
4801 tmp = gfc_trans_nested_forall_loop (nested_forall_info,
4802 assign, 1);
6de9cd9a
DN
4803 gfc_add_expr_to_block (&block, tmp);
4804 }
4805 break;
4806
4807 case EXEC_FORALL:
4808 tmp = gfc_trans_forall_1 (c, nested_forall_info);
4809 gfc_add_expr_to_block (&block, tmp);
4810 break;
4811
48474141
PT
4812 /* Explicit subroutine calls are prevented by the frontend but interface
4813 assignments can legitimately produce them. */
476220e7 4814 case EXEC_ASSIGN_CALL:
eb74e79b 4815 assign = gfc_trans_call (c, true, NULL_TREE, NULL_TREE, false);
bfcabc6c 4816 tmp = gfc_trans_nested_forall_loop (nested_forall_info, assign, 1);
48474141
PT
4817 gfc_add_expr_to_block (&block, tmp);
4818 break;
4819
6de9cd9a 4820 default:
6e45f57b 4821 gcc_unreachable ();
6de9cd9a
DN
4822 }
4823
4824 c = c->next;
4825 }
4826
8c6a85e3 4827done:
7b5b57b7
PB
4828 /* Restore the original index variables. */
4829 for (fa = code->ext.forall_iterator, n = 0; fa; fa = fa->next, n++)
4830 gfc_restore_sym (fa->var->symtree->n.sym, &saved_vars[n]);
6de9cd9a
DN
4831
4832 /* Free the space for var, start, end, step, varexpr. */
cede9502
JM
4833 free (var);
4834 free (start);
4835 free (end);
4836 free (step);
4837 free (varexpr);
4838 free (saved_vars);
6de9cd9a 4839
3231fe90
MM
4840 for (this_forall = info->this_loop; this_forall;)
4841 {
4842 iter_info *next = this_forall->next;
cede9502 4843 free (this_forall);
3231fe90
MM
4844 this_forall = next;
4845 }
4846
e8d366ec 4847 /* Free the space for this forall_info. */
cede9502 4848 free (info);
e8d366ec 4849
6de9cd9a
DN
4850 if (pmask)
4851 {
4852 /* Free the temporary for the mask. */
1529b8d9 4853 tmp = gfc_call_free (pmask);
6de9cd9a
DN
4854 gfc_add_expr_to_block (&block, tmp);
4855 }
4856 if (maskindex)
4857 pushdecl (maskindex);
4858
640670c7
PT
4859 gfc_add_block_to_block (&pre, &block);
4860 gfc_add_block_to_block (&pre, &post);
4861
4862 return gfc_finish_block (&pre);
6de9cd9a
DN
4863}
4864
4865
4866/* Translate the FORALL statement or construct. */
4867
4868tree gfc_trans_forall (gfc_code * code)
4869{
4870 return gfc_trans_forall_1 (code, NULL);
4871}
4872
4873
8c6a85e3
TB
4874/* Translate the DO CONCURRENT construct. */
4875
4876tree gfc_trans_do_concurrent (gfc_code * code)
4877{
4878 return gfc_trans_forall_1 (code, NULL);
4879}
4880
4881
6de9cd9a
DN
4882/* Evaluate the WHERE mask expression, copy its value to a temporary.
4883 If the WHERE construct is nested in FORALL, compute the overall temporary
4884 needed by the WHERE mask expression multiplied by the iterator number of
4885 the nested forall.
4886 ME is the WHERE mask expression.
011daa76
RS
4887 MASK is the current execution mask upon input, whose sense may or may
4888 not be inverted as specified by the INVERT argument.
3891cee2
RS
4889 CMASK is the updated execution mask on output, or NULL if not required.
4890 PMASK is the pending execution mask on output, or NULL if not required.
4891 BLOCK is the block in which to place the condition evaluation loops. */
6de9cd9a 4892
3891cee2 4893static void
6de9cd9a 4894gfc_evaluate_where_mask (gfc_expr * me, forall_info * nested_forall_info,
011daa76 4895 tree mask, bool invert, tree cmask, tree pmask,
3891cee2 4896 tree mask_type, stmtblock_t * block)
6de9cd9a
DN
4897{
4898 tree tmp, tmp1;
4899 gfc_ss *lss, *rss;
4900 gfc_loopinfo loop;
3891cee2
RS
4901 stmtblock_t body, body1;
4902 tree count, cond, mtmp;
6de9cd9a 4903 gfc_se lse, rse;
6de9cd9a
DN
4904
4905 gfc_init_loopinfo (&loop);
4906
3891cee2
RS
4907 lss = gfc_walk_expr (me);
4908 rss = gfc_walk_expr (me);
6de9cd9a
DN
4909
4910 /* Variable to index the temporary. */
4911 count = gfc_create_var (gfc_array_index_type, "count");
1f2959f0 4912 /* Initialize count. */
726a989a 4913 gfc_add_modify (block, count, gfc_index_zero_node);
6de9cd9a
DN
4914
4915 gfc_start_block (&body);
4916
4917 gfc_init_se (&rse, NULL);
4918 gfc_init_se (&lse, NULL);
4919
4920 if (lss == gfc_ss_terminator)
4921 {
4922 gfc_init_block (&body1);
4923 }
4924 else
4925 {
1f2959f0 4926 /* Initialize the loop. */
6de9cd9a
DN
4927 gfc_init_loopinfo (&loop);
4928
4929 /* We may need LSS to determine the shape of the expression. */
4930 gfc_add_ss_to_loop (&loop, lss);
4931 gfc_add_ss_to_loop (&loop, rss);
4932
4933 gfc_conv_ss_startstride (&loop);
bdfd2ff0 4934 gfc_conv_loop_setup (&loop, &me->where);
6de9cd9a
DN
4935
4936 gfc_mark_ss_chain_used (rss, 1);
4937 /* Start the loop body. */
4938 gfc_start_scalarized_body (&loop, &body1);
4939
4940 /* Translate the expression. */
4941 gfc_copy_loopinfo_to_se (&rse, &loop);
4942 rse.ss = rss;
4943 gfc_conv_expr (&rse, me);
4944 }
6de9cd9a 4945
b82feea5 4946 /* Variable to evaluate mask condition. */
3891cee2
RS
4947 cond = gfc_create_var (mask_type, "cond");
4948 if (mask && (cmask || pmask))
4949 mtmp = gfc_create_var (mask_type, "mask");
4950 else mtmp = NULL_TREE;
4951
4952 gfc_add_block_to_block (&body1, &lse.pre);
4953 gfc_add_block_to_block (&body1, &rse.pre);
6de9cd9a 4954
726a989a 4955 gfc_add_modify (&body1, cond, fold_convert (mask_type, rse.expr));
3891cee2
RS
4956
4957 if (mask && (cmask || pmask))
42e73749 4958 {
1d6b7f39 4959 tmp = gfc_build_array_ref (mask, count, NULL);
011daa76 4960 if (invert)
bc98ed60 4961 tmp = fold_build1_loc (input_location, TRUTH_NOT_EXPR, mask_type, tmp);
726a989a 4962 gfc_add_modify (&body1, mtmp, tmp);
42e73749 4963 }
6de9cd9a 4964
3891cee2
RS
4965 if (cmask)
4966 {
1d6b7f39 4967 tmp1 = gfc_build_array_ref (cmask, count, NULL);
3891cee2
RS
4968 tmp = cond;
4969 if (mask)
bc98ed60
TB
4970 tmp = fold_build2_loc (input_location, TRUTH_AND_EXPR, mask_type,
4971 mtmp, tmp);
726a989a 4972 gfc_add_modify (&body1, tmp1, tmp);
3891cee2
RS
4973 }
4974
4975 if (pmask)
4976 {
1d6b7f39 4977 tmp1 = gfc_build_array_ref (pmask, count, NULL);
bc98ed60 4978 tmp = fold_build1_loc (input_location, TRUTH_NOT_EXPR, mask_type, cond);
3891cee2 4979 if (mask)
bc98ed60
TB
4980 tmp = fold_build2_loc (input_location, TRUTH_AND_EXPR, mask_type, mtmp,
4981 tmp);
726a989a 4982 gfc_add_modify (&body1, tmp1, tmp);
3891cee2
RS
4983 }
4984
4985 gfc_add_block_to_block (&body1, &lse.post);
4986 gfc_add_block_to_block (&body1, &rse.post);
4987
4988 if (lss == gfc_ss_terminator)
6de9cd9a
DN
4989 {
4990 gfc_add_block_to_block (&body, &body1);
4991 }
4992 else
4993 {
4994 /* Increment count. */
bc98ed60
TB
4995 tmp1 = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
4996 count, gfc_index_one_node);
726a989a 4997 gfc_add_modify (&body1, count, tmp1);
6de9cd9a
DN
4998
4999 /* Generate the copying loops. */
5000 gfc_trans_scalarizing_loops (&loop, &body1);
5001
5002 gfc_add_block_to_block (&body, &loop.pre);
5003 gfc_add_block_to_block (&body, &loop.post);
5004
5005 gfc_cleanup_loop (&loop);
5006 /* TODO: Reuse lss and rss when copying temp->lhs. Need to be careful
5007 as tree nodes in SS may not be valid in different scope. */
5008 }
5009
5010 tmp1 = gfc_finish_block (&body);
5011 /* If the WHERE construct is inside FORALL, fill the full temporary. */
5012 if (nested_forall_info != NULL)
bfcabc6c 5013 tmp1 = gfc_trans_nested_forall_loop (nested_forall_info, tmp1, 1);
6de9cd9a
DN
5014
5015 gfc_add_expr_to_block (block, tmp1);
6de9cd9a
DN
5016}
5017
5018
5019/* Translate an assignment statement in a WHERE statement or construct
5020 statement. The MASK expression is used to control which elements
011daa76
RS
5021 of EXPR1 shall be assigned. The sense of MASK is specified by
5022 INVERT. */
6de9cd9a
DN
5023
5024static tree
011daa76
RS
5025gfc_trans_where_assign (gfc_expr *expr1, gfc_expr *expr2,
5026 tree mask, bool invert,
a00b8d1a 5027 tree count1, tree count2,
eb74e79b 5028 gfc_code *cnext)
6de9cd9a
DN
5029{
5030 gfc_se lse;
5031 gfc_se rse;
5032 gfc_ss *lss;
5033 gfc_ss *lss_section;
5034 gfc_ss *rss;
5035
5036 gfc_loopinfo loop;
5037 tree tmp;
5038 stmtblock_t block;
5039 stmtblock_t body;
3c90c9ae 5040 tree index, maskexpr;
6de9cd9a 5041
1cc0e193 5042 /* A defined assignment. */
eb74e79b
PT
5043 if (cnext && cnext->resolved_sym)
5044 return gfc_trans_call (cnext, true, mask, count1, invert);
5045
6de9cd9a
DN
5046#if 0
5047 /* TODO: handle this special case.
5048 Special case a single function returning an array. */
5049 if (expr2->expr_type == EXPR_FUNCTION && expr2->rank > 0)
5050 {
5051 tmp = gfc_trans_arrayfunc_assign (expr1, expr2);
5052 if (tmp)
5053 return tmp;
5054 }
5055#endif
5056
5057 /* Assignment of the form lhs = rhs. */
5058 gfc_start_block (&block);
5059
5060 gfc_init_se (&lse, NULL);
5061 gfc_init_se (&rse, NULL);
5062
5063 /* Walk the lhs. */
5064 lss = gfc_walk_expr (expr1);
5065 rss = NULL;
5066
5067 /* In each where-assign-stmt, the mask-expr and the variable being
5068 defined shall be arrays of the same shape. */
6e45f57b 5069 gcc_assert (lss != gfc_ss_terminator);
6de9cd9a
DN
5070
5071 /* The assignment needs scalarization. */
5072 lss_section = lss;
5073
5074 /* Find a non-scalar SS from the lhs. */
5075 while (lss_section != gfc_ss_terminator
bcc4d4e0 5076 && lss_section->info->type != GFC_SS_SECTION)
6de9cd9a
DN
5077 lss_section = lss_section->next;
5078
6e45f57b 5079 gcc_assert (lss_section != gfc_ss_terminator);
6de9cd9a
DN
5080
5081 /* Initialize the scalarizer. */
5082 gfc_init_loopinfo (&loop);
5083
5084 /* Walk the rhs. */
5085 rss = gfc_walk_expr (expr2);
5086 if (rss == gfc_ss_terminator)
26f77530
MM
5087 {
5088 /* The rhs is scalar. Add a ss for the expression. */
5089 rss = gfc_get_scalar_ss (gfc_ss_terminator, expr2);
42d0058e 5090 rss->info->where = 1;
6de9cd9a
DN
5091 }
5092
5093 /* Associate the SS with the loop. */
5094 gfc_add_ss_to_loop (&loop, lss);
5095 gfc_add_ss_to_loop (&loop, rss);
5096
5097 /* Calculate the bounds of the scalarization. */
5098 gfc_conv_ss_startstride (&loop);
5099
5100 /* Resolve any data dependencies in the statement. */
5101 gfc_conv_resolve_dependencies (&loop, lss_section, rss);
5102
5103 /* Setup the scalarizing loops. */
bdfd2ff0 5104 gfc_conv_loop_setup (&loop, &expr2->where);
6de9cd9a
DN
5105
5106 /* Setup the gfc_se structures. */
5107 gfc_copy_loopinfo_to_se (&lse, &loop);
5108 gfc_copy_loopinfo_to_se (&rse, &loop);
5109
5110 rse.ss = rss;
5111 gfc_mark_ss_chain_used (rss, 1);
5112 if (loop.temp_ss == NULL)
5113 {
5114 lse.ss = lss;
5115 gfc_mark_ss_chain_used (lss, 1);
5116 }
5117 else
5118 {
5119 lse.ss = loop.temp_ss;
5120 gfc_mark_ss_chain_used (lss, 3);
5121 gfc_mark_ss_chain_used (loop.temp_ss, 3);
5122 }
5123
5124 /* Start the scalarized loop body. */
5125 gfc_start_scalarized_body (&loop, &body);
5126
5127 /* Translate the expression. */
5128 gfc_conv_expr (&rse, expr2);
5129 if (lss != gfc_ss_terminator && loop.temp_ss != NULL)
3db5d687 5130 gfc_conv_tmp_array_ref (&lse);
6de9cd9a
DN
5131 else
5132 gfc_conv_expr (&lse, expr1);
5133
3c90c9ae 5134 /* Form the mask expression according to the mask. */
6de9cd9a 5135 index = count1;
1d6b7f39 5136 maskexpr = gfc_build_array_ref (mask, index, NULL);
011daa76 5137 if (invert)
bc98ed60
TB
5138 maskexpr = fold_build1_loc (input_location, TRUTH_NOT_EXPR,
5139 TREE_TYPE (maskexpr), maskexpr);
6de9cd9a 5140
6de9cd9a 5141 /* Use the scalar assignment as is. */
eb74e79b 5142 tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts,
ed673c00 5143 false, loop.temp_ss == NULL);
a00b8d1a 5144
c2255bc4 5145 tmp = build3_v (COND_EXPR, maskexpr, tmp, build_empty_stmt (input_location));
6de9cd9a
DN
5146
5147 gfc_add_expr_to_block (&body, tmp);
5148
5149 if (lss == gfc_ss_terminator)
5150 {
5151 /* Increment count1. */
bc98ed60
TB
5152 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
5153 count1, gfc_index_one_node);
726a989a 5154 gfc_add_modify (&body, count1, tmp);
6de9cd9a
DN
5155
5156 /* Use the scalar assignment as is. */
5157 gfc_add_block_to_block (&block, &body);
5158 }
5159 else
5160 {
6e45f57b
PB
5161 gcc_assert (lse.ss == gfc_ss_terminator
5162 && rse.ss == gfc_ss_terminator);
6de9cd9a
DN
5163
5164 if (loop.temp_ss != NULL)
5165 {
5166 /* Increment count1 before finish the main body of a scalarized
5167 expression. */
bc98ed60
TB
5168 tmp = fold_build2_loc (input_location, PLUS_EXPR,
5169 gfc_array_index_type, count1, gfc_index_one_node);
726a989a 5170 gfc_add_modify (&body, count1, tmp);
6de9cd9a
DN
5171 gfc_trans_scalarized_loop_boundary (&loop, &body);
5172
5173 /* We need to copy the temporary to the actual lhs. */
5174 gfc_init_se (&lse, NULL);
5175 gfc_init_se (&rse, NULL);
5176 gfc_copy_loopinfo_to_se (&lse, &loop);
5177 gfc_copy_loopinfo_to_se (&rse, &loop);
5178
5179 rse.ss = loop.temp_ss;
5180 lse.ss = lss;
5181
5182 gfc_conv_tmp_array_ref (&rse);
6de9cd9a
DN
5183 gfc_conv_expr (&lse, expr1);
5184
6e45f57b
PB
5185 gcc_assert (lse.ss == gfc_ss_terminator
5186 && rse.ss == gfc_ss_terminator);
6de9cd9a
DN
5187
5188 /* Form the mask expression according to the mask tree list. */
5189 index = count2;
1d6b7f39 5190 maskexpr = gfc_build_array_ref (mask, index, NULL);
011daa76 5191 if (invert)
bc98ed60
TB
5192 maskexpr = fold_build1_loc (input_location, TRUTH_NOT_EXPR,
5193 TREE_TYPE (maskexpr), maskexpr);
6de9cd9a 5194
6de9cd9a 5195 /* Use the scalar assignment as is. */
ed673c00 5196 tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts, false, true);
c2255bc4
AH
5197 tmp = build3_v (COND_EXPR, maskexpr, tmp,
5198 build_empty_stmt (input_location));
6de9cd9a 5199 gfc_add_expr_to_block (&body, tmp);
7ab92584 5200
6de9cd9a 5201 /* Increment count2. */
bc98ed60
TB
5202 tmp = fold_build2_loc (input_location, PLUS_EXPR,
5203 gfc_array_index_type, count2,
5204 gfc_index_one_node);
726a989a 5205 gfc_add_modify (&body, count2, tmp);
6de9cd9a
DN
5206 }
5207 else
5208 {
5209 /* Increment count1. */
bc98ed60
TB
5210 tmp = fold_build2_loc (input_location, PLUS_EXPR,
5211 gfc_array_index_type, count1,
5212 gfc_index_one_node);
726a989a 5213 gfc_add_modify (&body, count1, tmp);
6de9cd9a
DN
5214 }
5215
5216 /* Generate the copying loops. */
5217 gfc_trans_scalarizing_loops (&loop, &body);
5218
5219 /* Wrap the whole thing up. */
5220 gfc_add_block_to_block (&block, &loop.pre);
5221 gfc_add_block_to_block (&block, &loop.post);
5222 gfc_cleanup_loop (&loop);
5223 }
5224
5225 return gfc_finish_block (&block);
5226}
5227
5228
5229/* Translate the WHERE construct or statement.
aa9c57ec 5230 This function can be called iteratively to translate the nested WHERE
6de9cd9a 5231 construct or statement.
3891cee2 5232 MASK is the control mask. */
6de9cd9a
DN
5233
5234static void
011daa76 5235gfc_trans_where_2 (gfc_code * code, tree mask, bool invert,
3891cee2 5236 forall_info * nested_forall_info, stmtblock_t * block)
6de9cd9a 5237{
3891cee2
RS
5238 stmtblock_t inner_size_body;
5239 tree inner_size, size;
5240 gfc_ss *lss, *rss;
5241 tree mask_type;
6de9cd9a
DN
5242 gfc_expr *expr1;
5243 gfc_expr *expr2;
5244 gfc_code *cblock;
5245 gfc_code *cnext;
3891cee2 5246 tree tmp;
ae772c2d 5247 tree cond;
6de9cd9a 5248 tree count1, count2;
011daa76
RS
5249 bool need_cmask;
5250 bool need_pmask;
6de9cd9a 5251 int need_temp;
3891cee2
RS
5252 tree pcmask = NULL_TREE;
5253 tree ppmask = NULL_TREE;
5254 tree cmask = NULL_TREE;
5255 tree pmask = NULL_TREE;
a00b8d1a 5256 gfc_actual_arglist *arg;
6de9cd9a
DN
5257
5258 /* the WHERE statement or the WHERE construct statement. */
5259 cblock = code->block;
3891cee2 5260
3891cee2
RS
5261 /* As the mask array can be very big, prefer compact boolean types. */
5262 mask_type = gfc_get_logical_type (gfc_logical_kinds[0].kind);
5263
011daa76
RS
5264 /* Determine which temporary masks are needed. */
5265 if (!cblock->block)
90f58ec8 5266 {
011daa76
RS
5267 /* One clause: No ELSEWHEREs. */
5268 need_cmask = (cblock->next != 0);
5269 need_pmask = false;
90f58ec8 5270 }
011daa76 5271 else if (cblock->block->block)
90f58ec8 5272 {
011daa76
RS
5273 /* Three or more clauses: Conditional ELSEWHEREs. */
5274 need_cmask = true;
5275 need_pmask = true;
90f58ec8 5276 }
011daa76
RS
5277 else if (cblock->next)
5278 {
5279 /* Two clauses, the first non-empty. */
5280 need_cmask = true;
5281 need_pmask = (mask != NULL_TREE
5282 && cblock->block->next != 0);
5283 }
5284 else if (!cblock->block->next)
3891cee2 5285 {
011daa76
RS
5286 /* Two clauses, both empty. */
5287 need_cmask = false;
5288 need_pmask = false;
5289 }
5290 /* Two clauses, the first empty, the second non-empty. */
5291 else if (mask)
5292 {
a513927a 5293 need_cmask = (cblock->block->expr1 != 0);
011daa76 5294 need_pmask = true;
3891cee2
RS
5295 }
5296 else
5297 {
011daa76
RS
5298 need_cmask = true;
5299 need_pmask = false;
5300 }
5301
5302 if (need_cmask || need_pmask)
5303 {
5304 /* Calculate the size of temporary needed by the mask-expr. */
5305 gfc_init_block (&inner_size_body);
a513927a 5306 inner_size = compute_inner_temp_size (cblock->expr1, cblock->expr1,
011daa76
RS
5307 &inner_size_body, &lss, &rss);
5308
fcba5509
MM
5309 gfc_free_ss_chain (lss);
5310 gfc_free_ss_chain (rss);
5311
011daa76
RS
5312 /* Calculate the total size of temporary needed. */
5313 size = compute_overall_iter_number (nested_forall_info, inner_size,
5314 &inner_size_body, block);
5315
ae772c2d 5316 /* Check whether the size is negative. */
63ee5404 5317 cond = fold_build2_loc (input_location, LE_EXPR, logical_type_node, size,
bc98ed60
TB
5318 gfc_index_zero_node);
5319 size = fold_build3_loc (input_location, COND_EXPR, gfc_array_index_type,
5320 cond, gfc_index_zero_node, size);
ae772c2d
PT
5321 size = gfc_evaluate_now (size, block);
5322
011daa76
RS
5323 /* Allocate temporary for WHERE mask if needed. */
5324 if (need_cmask)
5325 cmask = allocate_temp_for_forall_nest_1 (mask_type, size, block,
5326 &pcmask);
5327
5328 /* Allocate temporary for !mask if needed. */
5329 if (need_pmask)
5330 pmask = allocate_temp_for_forall_nest_1 (mask_type, size, block,
5331 &ppmask);
3891cee2
RS
5332 }
5333
6de9cd9a
DN
5334 while (cblock)
5335 {
011daa76
RS
5336 /* Each time around this loop, the where clause is conditional
5337 on the value of mask and invert, which are updated at the
5338 bottom of the loop. */
5339
6de9cd9a 5340 /* Has mask-expr. */
a513927a 5341 if (cblock->expr1)
6de9cd9a 5342 {
90f58ec8
RS
5343 /* Ensure that the WHERE mask will be evaluated exactly once.
5344 If there are no statements in this WHERE/ELSEWHERE clause,
5345 then we don't need to update the control mask (cmask).
5346 If this is the last clause of the WHERE construct, then
3891cee2 5347 we don't need to update the pending control mask (pmask). */
011daa76 5348 if (mask)
a513927a 5349 gfc_evaluate_where_mask (cblock->expr1, nested_forall_info,
011daa76
RS
5350 mask, invert,
5351 cblock->next ? cmask : NULL_TREE,
5352 cblock->block ? pmask : NULL_TREE,
5353 mask_type, block);
5354 else
a513927a 5355 gfc_evaluate_where_mask (cblock->expr1, nested_forall_info,
011daa76
RS
5356 NULL_TREE, false,
5357 (cblock->next || cblock->block)
5358 ? cmask : NULL_TREE,
5359 NULL_TREE, mask_type, block);
6de9cd9a 5360
011daa76 5361 invert = false;
6de9cd9a 5362 }
90f58ec8 5363 /* It's a final elsewhere-stmt. No mask-expr is present. */
6de9cd9a 5364 else
3891cee2 5365 cmask = mask;
6de9cd9a 5366
011daa76
RS
5367 /* The body of this where clause are controlled by cmask with
5368 sense specified by invert. */
5369
6de9cd9a
DN
5370 /* Get the assignment statement of a WHERE statement, or the first
5371 statement in where-body-construct of a WHERE construct. */
5372 cnext = cblock->next;
5373 while (cnext)
5374 {
5375 switch (cnext->op)
5376 {
5377 /* WHERE assignment statement. */
a00b8d1a
PT
5378 case EXEC_ASSIGN_CALL:
5379
5380 arg = cnext->ext.actual;
5381 expr1 = expr2 = NULL;
5382 for (; arg; arg = arg->next)
5383 {
5384 if (!arg->expr)
5385 continue;
5386 if (expr1 == NULL)
5387 expr1 = arg->expr;
5388 else
5389 expr2 = arg->expr;
5390 }
5391 goto evaluate;
5392
6de9cd9a 5393 case EXEC_ASSIGN:
a513927a 5394 expr1 = cnext->expr1;
6de9cd9a 5395 expr2 = cnext->expr2;
a00b8d1a 5396 evaluate:
6de9cd9a
DN
5397 if (nested_forall_info != NULL)
5398 {
3ded6210 5399 need_temp = gfc_check_dependency (expr1, expr2, 0);
7bd5dad2
LK
5400 if ((need_temp || flag_test_forall_temp)
5401 && cnext->op != EXEC_ASSIGN_CALL)
011daa76
RS
5402 gfc_trans_assign_need_temp (expr1, expr2,
5403 cmask, invert,
6de9cd9a
DN
5404 nested_forall_info, block);
5405 else
5406 {
5407 /* Variables to control maskexpr. */
5408 count1 = gfc_create_var (gfc_array_index_type, "count1");
5409 count2 = gfc_create_var (gfc_array_index_type, "count2");
726a989a
RB
5410 gfc_add_modify (block, count1, gfc_index_zero_node);
5411 gfc_add_modify (block, count2, gfc_index_zero_node);
6de9cd9a 5412
011daa76
RS
5413 tmp = gfc_trans_where_assign (expr1, expr2,
5414 cmask, invert,
a00b8d1a 5415 count1, count2,
eb74e79b 5416 cnext);
8de1f441 5417
6de9cd9a 5418 tmp = gfc_trans_nested_forall_loop (nested_forall_info,
bfcabc6c 5419 tmp, 1);
6de9cd9a
DN
5420 gfc_add_expr_to_block (block, tmp);
5421 }
5422 }
5423 else
5424 {
5425 /* Variables to control maskexpr. */
5426 count1 = gfc_create_var (gfc_array_index_type, "count1");
5427 count2 = gfc_create_var (gfc_array_index_type, "count2");
726a989a
RB
5428 gfc_add_modify (block, count1, gfc_index_zero_node);
5429 gfc_add_modify (block, count2, gfc_index_zero_node);
6de9cd9a 5430
011daa76
RS
5431 tmp = gfc_trans_where_assign (expr1, expr2,
5432 cmask, invert,
a00b8d1a 5433 count1, count2,
eb74e79b 5434 cnext);
6de9cd9a
DN
5435 gfc_add_expr_to_block (block, tmp);
5436
5437 }
5438 break;
5439
5440 /* WHERE or WHERE construct is part of a where-body-construct. */
5441 case EXEC_WHERE:
011daa76
RS
5442 gfc_trans_where_2 (cnext, cmask, invert,
5443 nested_forall_info, block);
3891cee2 5444 break;
6de9cd9a
DN
5445
5446 default:
6e45f57b 5447 gcc_unreachable ();
6de9cd9a
DN
5448 }
5449
5450 /* The next statement within the same where-body-construct. */
5451 cnext = cnext->next;
5452 }
5453 /* The next masked-elsewhere-stmt, elsewhere-stmt, or end-where-stmt. */
5454 cblock = cblock->block;
011daa76
RS
5455 if (mask == NULL_TREE)
5456 {
5457 /* If we're the initial WHERE, we can simply invert the sense
5458 of the current mask to obtain the "mask" for the remaining
5459 ELSEWHEREs. */
5460 invert = true;
5461 mask = cmask;
5462 }
5463 else
5464 {
5465 /* Otherwise, for nested WHERE's we need to use the pending mask. */
5466 invert = false;
5467 mask = pmask;
5468 }
6de9cd9a 5469 }
3891cee2
RS
5470
5471 /* If we allocated a pending mask array, deallocate it now. */
5472 if (ppmask)
5473 {
1529b8d9 5474 tmp = gfc_call_free (ppmask);
3891cee2
RS
5475 gfc_add_expr_to_block (block, tmp);
5476 }
5477
5478 /* If we allocated a current mask array, deallocate it now. */
5479 if (pcmask)
5480 {
1529b8d9 5481 tmp = gfc_call_free (pcmask);
3891cee2
RS
5482 gfc_add_expr_to_block (block, tmp);
5483 }
6de9cd9a
DN
5484}
5485
3ded6210
RS
5486/* Translate a simple WHERE construct or statement without dependencies.
5487 CBLOCK is the "then" clause of the WHERE statement, where CBLOCK->EXPR
5488 is the mask condition, and EBLOCK if non-NULL is the "else" clause.
5489 Currently both CBLOCK and EBLOCK are restricted to single assignments. */
5490
5491static tree
5492gfc_trans_where_3 (gfc_code * cblock, gfc_code * eblock)
5493{
5494 stmtblock_t block, body;
5495 gfc_expr *cond, *tdst, *tsrc, *edst, *esrc;
5496 tree tmp, cexpr, tstmt, estmt;
5497 gfc_ss *css, *tdss, *tsss;
5498 gfc_se cse, tdse, tsse, edse, esse;
5499 gfc_loopinfo loop;
5500 gfc_ss *edss = 0;
5501 gfc_ss *esss = 0;
57bf3072 5502 bool maybe_workshare = false;
3ded6210 5503
34d01e1d 5504 /* Allow the scalarizer to workshare simple where loops. */
57bf3072
JJ
5505 if ((ompws_flags & (OMPWS_WORKSHARE_FLAG | OMPWS_SCALARIZER_BODY))
5506 == OMPWS_WORKSHARE_FLAG)
5507 {
5508 maybe_workshare = true;
5509 ompws_flags |= OMPWS_SCALARIZER_WS | OMPWS_SCALARIZER_BODY;
5510 }
34d01e1d 5511
a513927a
SK
5512 cond = cblock->expr1;
5513 tdst = cblock->next->expr1;
3ded6210 5514 tsrc = cblock->next->expr2;
a513927a 5515 edst = eblock ? eblock->next->expr1 : NULL;
3ded6210
RS
5516 esrc = eblock ? eblock->next->expr2 : NULL;
5517
5518 gfc_start_block (&block);
5519 gfc_init_loopinfo (&loop);
5520
5521 /* Handle the condition. */
5522 gfc_init_se (&cse, NULL);
5523 css = gfc_walk_expr (cond);
5524 gfc_add_ss_to_loop (&loop, css);
5525
5526 /* Handle the then-clause. */
5527 gfc_init_se (&tdse, NULL);
5528 gfc_init_se (&tsse, NULL);
5529 tdss = gfc_walk_expr (tdst);
5530 tsss = gfc_walk_expr (tsrc);
5531 if (tsss == gfc_ss_terminator)
5532 {
26f77530 5533 tsss = gfc_get_scalar_ss (gfc_ss_terminator, tsrc);
42d0058e 5534 tsss->info->where = 1;
3ded6210
RS
5535 }
5536 gfc_add_ss_to_loop (&loop, tdss);
5537 gfc_add_ss_to_loop (&loop, tsss);
5538
5539 if (eblock)
5540 {
5541 /* Handle the else clause. */
5542 gfc_init_se (&edse, NULL);
5543 gfc_init_se (&esse, NULL);
5544 edss = gfc_walk_expr (edst);
5545 esss = gfc_walk_expr (esrc);
5546 if (esss == gfc_ss_terminator)
5547 {
26f77530 5548 esss = gfc_get_scalar_ss (gfc_ss_terminator, esrc);
42d0058e 5549 esss->info->where = 1;
3ded6210
RS
5550 }
5551 gfc_add_ss_to_loop (&loop, edss);
5552 gfc_add_ss_to_loop (&loop, esss);
5553 }
5554
5555 gfc_conv_ss_startstride (&loop);
bdfd2ff0 5556 gfc_conv_loop_setup (&loop, &tdst->where);
3ded6210
RS
5557
5558 gfc_mark_ss_chain_used (css, 1);
5559 gfc_mark_ss_chain_used (tdss, 1);
5560 gfc_mark_ss_chain_used (tsss, 1);
5561 if (eblock)
5562 {
5563 gfc_mark_ss_chain_used (edss, 1);
5564 gfc_mark_ss_chain_used (esss, 1);
5565 }
5566
5567 gfc_start_scalarized_body (&loop, &body);
5568
5569 gfc_copy_loopinfo_to_se (&cse, &loop);
5570 gfc_copy_loopinfo_to_se (&tdse, &loop);
5571 gfc_copy_loopinfo_to_se (&tsse, &loop);
5572 cse.ss = css;
5573 tdse.ss = tdss;
5574 tsse.ss = tsss;
5575 if (eblock)
5576 {
5577 gfc_copy_loopinfo_to_se (&edse, &loop);
5578 gfc_copy_loopinfo_to_se (&esse, &loop);
5579 edse.ss = edss;
5580 esse.ss = esss;
5581 }
5582
5583 gfc_conv_expr (&cse, cond);
5584 gfc_add_block_to_block (&body, &cse.pre);
5585 cexpr = cse.expr;
5586
5587 gfc_conv_expr (&tsse, tsrc);
5588 if (tdss != gfc_ss_terminator && loop.temp_ss != NULL)
3db5d687 5589 gfc_conv_tmp_array_ref (&tdse);
3ded6210
RS
5590 else
5591 gfc_conv_expr (&tdse, tdst);
5592
5593 if (eblock)
5594 {
5595 gfc_conv_expr (&esse, esrc);
5596 if (edss != gfc_ss_terminator && loop.temp_ss != NULL)
3db5d687 5597 gfc_conv_tmp_array_ref (&edse);
3ded6210 5598 else
3db5d687 5599 gfc_conv_expr (&edse, edst);
3ded6210
RS
5600 }
5601
ed673c00
MM
5602 tstmt = gfc_trans_scalar_assign (&tdse, &tsse, tdst->ts, false, true);
5603 estmt = eblock ? gfc_trans_scalar_assign (&edse, &esse, edst->ts,
2b56d6a4 5604 false, true)
c2255bc4 5605 : build_empty_stmt (input_location);
3ded6210
RS
5606 tmp = build3_v (COND_EXPR, cexpr, tstmt, estmt);
5607 gfc_add_expr_to_block (&body, tmp);
5608 gfc_add_block_to_block (&body, &cse.post);
5609
57bf3072
JJ
5610 if (maybe_workshare)
5611 ompws_flags &= ~OMPWS_SCALARIZER_BODY;
3ded6210
RS
5612 gfc_trans_scalarizing_loops (&loop, &body);
5613 gfc_add_block_to_block (&block, &loop.pre);
5614 gfc_add_block_to_block (&block, &loop.post);
5615 gfc_cleanup_loop (&loop);
5616
5617 return gfc_finish_block (&block);
5618}
6de9cd9a
DN
5619
5620/* As the WHERE or WHERE construct statement can be nested, we call
5621 gfc_trans_where_2 to do the translation, and pass the initial
f7b529fa 5622 NULL values for both the control mask and the pending control mask. */
6de9cd9a
DN
5623
5624tree
5625gfc_trans_where (gfc_code * code)
5626{
5627 stmtblock_t block;
3ded6210
RS
5628 gfc_code *cblock;
5629 gfc_code *eblock;
6de9cd9a 5630
3ded6210
RS
5631 cblock = code->block;
5632 if (cblock->next
5633 && cblock->next->op == EXEC_ASSIGN
5634 && !cblock->next->next)
5635 {
5636 eblock = cblock->block;
5637 if (!eblock)
5638 {
5639 /* A simple "WHERE (cond) x = y" statement or block is
5640 dependence free if cond is not dependent upon writing x,
5641 and the source y is unaffected by the destination x. */
a513927a
SK
5642 if (!gfc_check_dependency (cblock->next->expr1,
5643 cblock->expr1, 0)
5644 && !gfc_check_dependency (cblock->next->expr1,
3ded6210
RS
5645 cblock->next->expr2, 0))
5646 return gfc_trans_where_3 (cblock, NULL);
5647 }
a513927a 5648 else if (!eblock->expr1
3ded6210
RS
5649 && !eblock->block
5650 && eblock->next
5651 && eblock->next->op == EXEC_ASSIGN
5652 && !eblock->next->next)
5653 {
5654 /* A simple "WHERE (cond) x1 = y1 ELSEWHERE x2 = y2 ENDWHERE"
5655 block is dependence free if cond is not dependent on writes
5656 to x1 and x2, y1 is not dependent on writes to x2, and y2
5657 is not dependent on writes to x1, and both y's are not
ae772c2d
PT
5658 dependent upon their own x's. In addition to this, the
5659 final two dependency checks below exclude all but the same
5660 array reference if the where and elswhere destinations
5661 are the same. In short, this is VERY conservative and this
5662 is needed because the two loops, required by the standard
5663 are coalesced in gfc_trans_where_3. */
524af0d6 5664 if (!gfc_check_dependency (cblock->next->expr1,
a513927a 5665 cblock->expr1, 0)
524af0d6 5666 && !gfc_check_dependency (eblock->next->expr1,
a513927a 5667 cblock->expr1, 0)
524af0d6 5668 && !gfc_check_dependency (cblock->next->expr1,
ae772c2d 5669 eblock->next->expr2, 1)
524af0d6 5670 && !gfc_check_dependency (eblock->next->expr1,
ae772c2d 5671 cblock->next->expr2, 1)
524af0d6 5672 && !gfc_check_dependency (cblock->next->expr1,
ae772c2d 5673 cblock->next->expr2, 1)
524af0d6 5674 && !gfc_check_dependency (eblock->next->expr1,
ae772c2d 5675 eblock->next->expr2, 1)
524af0d6 5676 && !gfc_check_dependency (cblock->next->expr1,
a513927a 5677 eblock->next->expr1, 0)
524af0d6 5678 && !gfc_check_dependency (eblock->next->expr1,
a513927a 5679 cblock->next->expr1, 0))
3ded6210
RS
5680 return gfc_trans_where_3 (cblock, eblock);
5681 }
5682 }
5683
6de9cd9a 5684 gfc_start_block (&block);
6de9cd9a 5685
011daa76 5686 gfc_trans_where_2 (code, NULL, false, NULL, &block);
6de9cd9a 5687
6de9cd9a
DN
5688 return gfc_finish_block (&block);
5689}
5690
5691
5692/* CYCLE a DO loop. The label decl has already been created by
5693 gfc_trans_do(), it's in TREE_PURPOSE (backend_decl) of the gfc_code
5694 node at the head of the loop. We must mark the label as used. */
5695
5696tree
5697gfc_trans_cycle (gfc_code * code)
5698{
5699 tree cycle_label;
5700
e5ca9693
DK
5701 cycle_label = code->ext.which_construct->cycle_label;
5702 gcc_assert (cycle_label);
5703
6de9cd9a
DN
5704 TREE_USED (cycle_label) = 1;
5705 return build1_v (GOTO_EXPR, cycle_label);
5706}
5707
5708
e7dc5b4f 5709/* EXIT a DO loop. Similar to CYCLE, but now the label is in
6de9cd9a
DN
5710 TREE_VALUE (backend_decl) of the gfc_code node at the head of the
5711 loop. */
5712
5713tree
5714gfc_trans_exit (gfc_code * code)
5715{
5716 tree exit_label;
5717
e5ca9693
DK
5718 exit_label = code->ext.which_construct->exit_label;
5719 gcc_assert (exit_label);
5720
6de9cd9a
DN
5721 TREE_USED (exit_label) = 1;
5722 return build1_v (GOTO_EXPR, exit_label);
5723}
5724
5725
cc03bf7a
AV
5726/* Get the initializer expression for the code and expr of an allocate.
5727 When no initializer is needed return NULL. */
5728
5729static gfc_expr *
5730allocate_get_initializer (gfc_code * code, gfc_expr * expr)
5731{
5732 if (!gfc_bt_struct (expr->ts.type) && expr->ts.type != BT_CLASS)
5733 return NULL;
5734
5735 /* An explicit type was given in allocate ( T:: object). */
5736 if (code->ext.alloc.ts.type == BT_DERIVED
5737 && (code->ext.alloc.ts.u.derived->attr.alloc_comp
5738 || gfc_has_default_initializer (code->ext.alloc.ts.u.derived)))
5739 return gfc_default_initializer (&code->ext.alloc.ts);
5740
5741 if (gfc_bt_struct (expr->ts.type)
5742 && (expr->ts.u.derived->attr.alloc_comp
5743 || gfc_has_default_initializer (expr->ts.u.derived)))
5744 return gfc_default_initializer (&expr->ts);
5745
5746 if (expr->ts.type == BT_CLASS
5747 && (CLASS_DATA (expr)->ts.u.derived->attr.alloc_comp
5748 || gfc_has_default_initializer (CLASS_DATA (expr)->ts.u.derived)))
5749 return gfc_default_initializer (&CLASS_DATA (expr)->ts);
5750
5751 return NULL;
5752}
5753
6de9cd9a
DN
5754/* Translate the ALLOCATE statement. */
5755
5756tree
5757gfc_trans_allocate (gfc_code * code)
5758{
5759 gfc_alloc *al;
cc03bf7a 5760 gfc_expr *expr, *e3rhs = NULL, *init_expr;
34d9d749 5761 gfc_se se, se_sz;
6de9cd9a
DN
5762 tree tmp;
5763 tree parm;
6de9cd9a 5764 tree stat;
8f992d64
DC
5765 tree errmsg;
5766 tree errlen;
5767 tree label_errmsg;
5768 tree label_finish;
60f5ed26 5769 tree memsz;
34d9d749
AV
5770 tree al_vptr, al_len;
5771 /* If an expr3 is present, then store the tree for accessing its
5772 _vptr, and _len components in the variables, respectively. The
5773 element size, i.e. _vptr%size, is stored in expr3_esize. Any of
5774 the trees may be the NULL_TREE indicating that this is not
5775 available for expr3's type. */
5776 tree expr3, expr3_vptr, expr3_len, expr3_esize;
1792349b
AV
5777 /* Classify what expr3 stores. */
5778 enum { E3_UNSET = 0, E3_SOURCE, E3_MOLD, E3_DESC } e3_is;
6de9cd9a 5779 stmtblock_t block;
90cf3ecc 5780 stmtblock_t post;
4daa71b0 5781 tree nelems;
525a5e33
AV
5782 bool upoly_expr, tmp_expr3_len_flag = false, al_len_needs_set, is_coarray;
5783 bool needs_caf_sync, caf_refs_comp;
db7ffcab 5784 gfc_symtree *newsym = NULL;
525a5e33 5785 symbol_attribute caf_attr;
5bab4c96 5786 gfc_actual_arglist *param_list;
6de9cd9a 5787
cf2b3c22 5788 if (!code->ext.alloc.list)
6de9cd9a
DN
5789 return NULL_TREE;
5790
34d9d749
AV
5791 stat = tmp = memsz = al_vptr = al_len = NULL_TREE;
5792 expr3 = expr3_vptr = expr3_len = expr3_esize = NULL_TREE;
8f992d64 5793 label_errmsg = label_finish = errmsg = errlen = NULL_TREE;
1792349b 5794 e3_is = E3_UNSET;
525a5e33 5795 is_coarray = needs_caf_sync = false;
3759634f 5796
90cf3ecc
PT
5797 gfc_init_block (&block);
5798 gfc_init_block (&post);
6de9cd9a 5799
8f992d64
DC
5800 /* STAT= (and maybe ERRMSG=) is present. */
5801 if (code->expr1)
6de9cd9a 5802 {
8f992d64 5803 /* STAT=. */
e2cad04b 5804 tree gfc_int4_type_node = gfc_get_int_type (4);
6de9cd9a 5805 stat = gfc_create_var (gfc_int4_type_node, "stat");
6de9cd9a 5806
8f992d64
DC
5807 /* ERRMSG= only makes sense with STAT=. */
5808 if (code->expr2)
5809 {
5810 gfc_init_se (&se, NULL);
5d81ddd0 5811 se.want_pointer = 1;
8f992d64 5812 gfc_conv_expr_lhs (&se, code->expr2);
5d81ddd0
TB
5813 errmsg = se.expr;
5814 errlen = se.string_length;
8f992d64
DC
5815 }
5816 else
5817 {
5818 errmsg = null_pointer_node;
5819 errlen = build_int_cst (gfc_charlen_type_node, 0);
5820 }
5821
5822 /* GOTO destinations. */
5823 label_errmsg = gfc_build_label_decl (NULL_TREE);
5824 label_finish = gfc_build_label_decl (NULL_TREE);
5d81ddd0 5825 TREE_USED (label_finish) = 0;
6de9cd9a 5826 }
6de9cd9a 5827
db7ffcab
AV
5828 /* When an expr3 is present evaluate it only once. The standards prevent a
5829 dependency of expr3 on the objects in the allocate list. An expr3 can
5830 be pre-evaluated in all cases. One just has to make sure, to use the
5831 correct way, i.e., to get the descriptor or to get a reference
5832 expression. */
34d9d749
AV
5833 if (code->expr3)
5834 {
139d4065
AV
5835 bool vtab_needed = false, temp_var_needed = false,
5836 temp_obj_created = false;
ffaf9305
AV
5837
5838 is_coarray = gfc_is_coarray (code->expr3);
34d9d749
AV
5839
5840 /* Figure whether we need the vtab from expr3. */
5841 for (al = code->ext.alloc.list; !vtab_needed && al != NULL;
5842 al = al->next)
5843 vtab_needed = (al->expr->ts.type == BT_CLASS);
5844
1792349b 5845 gfc_init_se (&se, NULL);
db7ffcab 5846 /* When expr3 is a variable, i.e., a very simple expression,
34d9d749 5847 then convert it once here. */
db7ffcab
AV
5848 if (code->expr3->expr_type == EXPR_VARIABLE
5849 || code->expr3->expr_type == EXPR_ARRAY
5850 || code->expr3->expr_type == EXPR_CONSTANT)
5851 {
5852 if (!code->expr3->mold
5853 || code->expr3->ts.type == BT_CHARACTER
1792349b
AV
5854 || vtab_needed
5855 || code->ext.alloc.arr_spec_from_expr3)
34d9d749 5856 {
1792349b
AV
5857 /* Convert expr3 to a tree. For all "simple" expression just
5858 get the descriptor or the reference, respectively, depending
5859 on the rank of the expr. */
5860 if (code->ext.alloc.arr_spec_from_expr3 || code->expr3->rank != 0)
440f9408
AV
5861 gfc_conv_expr_descriptor (&se, code->expr3);
5862 else
1c645536
AV
5863 {
5864 gfc_conv_expr_reference (&se, code->expr3);
5865
5866 /* gfc_conv_expr_reference wraps POINTER_PLUS_EXPR in a
5867 NOP_EXPR, which prevents gfortran from getting the vptr
5868 from the source=-expression. Remove the NOP_EXPR and go
5869 with the POINTER_PLUS_EXPR in this case. */
5870 if (code->expr3->ts.type == BT_CLASS
5871 && TREE_CODE (se.expr) == NOP_EXPR
781d83d9
AV
5872 && (TREE_CODE (TREE_OPERAND (se.expr, 0))
5873 == POINTER_PLUS_EXPR
5874 || is_coarray))
1c645536
AV
5875 se.expr = TREE_OPERAND (se.expr, 0);
5876 }
1792349b
AV
5877 /* Create a temp variable only for component refs to prevent
5878 having to go through the full deref-chain each time and to
5879 simplfy computation of array properties. */
5880 temp_var_needed = TREE_CODE (se.expr) == COMPONENT_REF;
db7ffcab 5881 }
db7ffcab
AV
5882 }
5883 else
5884 {
1792349b 5885 /* In all other cases evaluate the expr3. */
db7ffcab
AV
5886 symbol_attribute attr;
5887 /* Get the descriptor for all arrays, that are not allocatable or
b8ac4f3b
AV
5888 pointer, because the latter are descriptors already.
5889 The exception are function calls returning a class object:
5890 The descriptor is stored in their results _data component, which
5891 is easier to access, when first a temporary variable for the
5892 result is created and the descriptor retrieved from there. */
db7ffcab 5893 attr = gfc_expr_attr (code->expr3);
b8ac4f3b
AV
5894 if (code->expr3->rank != 0
5895 && ((!attr.allocatable && !attr.pointer)
5896 || (code->expr3->expr_type == EXPR_FUNCTION
574284e9
AV
5897 && (code->expr3->ts.type != BT_CLASS
5898 || (code->expr3->value.function.isym
5899 && code->expr3->value.function.isym
5900 ->transformational)))))
db7ffcab
AV
5901 gfc_conv_expr_descriptor (&se, code->expr3);
5902 else
5903 gfc_conv_expr_reference (&se, code->expr3);
5904 if (code->expr3->ts.type == BT_CLASS)
5905 gfc_conv_class_to_class (&se, code->expr3,
5906 code->expr3->ts,
5907 false, true,
5908 false, false);
139d4065 5909 temp_obj_created = temp_var_needed = !VAR_P (se.expr);
1792349b
AV
5910 }
5911 gfc_add_block_to_block (&block, &se.pre);
5912 gfc_add_block_to_block (&post, &se.post);
64e56ab0
AV
5913
5914 /* Special case when string in expr3 is zero. */
5915 if (code->expr3->ts.type == BT_CHARACTER
5916 && integer_zerop (se.string_length))
5917 {
5918 gfc_init_se (&se, NULL);
5919 temp_var_needed = false;
f622221a 5920 expr3_len = build_zero_cst (gfc_charlen_type_node);
64e56ab0
AV
5921 e3_is = E3_MOLD;
5922 }
1792349b
AV
5923 /* Prevent aliasing, i.e., se.expr may be already a
5924 variable declaration. */
64e56ab0 5925 else if (se.expr != NULL_TREE && temp_var_needed)
1792349b 5926 {
b8ac4f3b 5927 tree var, desc;
781d83d9 5928 tmp = GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se.expr)) || is_coarray ?
1792349b
AV
5929 se.expr
5930 : build_fold_indirect_ref_loc (input_location, se.expr);
b8ac4f3b
AV
5931
5932 /* Get the array descriptor and prepare it to be assigned to the
5933 temporary variable var. For classes the array descriptor is
5934 in the _data component and the object goes into the
5935 GFC_DECL_SAVED_DESCRIPTOR. */
5936 if (code->expr3->ts.type == BT_CLASS
5937 && code->expr3->rank != 0)
5938 {
5939 /* When an array_ref was in expr3, then the descriptor is the
5940 first operand. */
781d83d9 5941 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp)) || is_coarray)
b8ac4f3b
AV
5942 {
5943 desc = TREE_OPERAND (tmp, 0);
5944 }
5945 else
5946 {
5947 desc = tmp;
5948 tmp = gfc_class_data_get (tmp);
5949 }
92c5266b
AV
5950 if (code->ext.alloc.arr_spec_from_expr3)
5951 e3_is = E3_DESC;
b8ac4f3b
AV
5952 }
5953 else
781d83d9
AV
5954 desc = !is_coarray ? se.expr
5955 : TREE_OPERAND (TREE_OPERAND (se.expr, 0), 0);
1792349b
AV
5956 /* We need a regular (non-UID) symbol here, therefore give a
5957 prefix. */
5958 var = gfc_create_var (TREE_TYPE (tmp), "source");
781d83d9 5959 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp)) || is_coarray)
db7ffcab 5960 {
1792349b 5961 gfc_allocate_lang_decl (var);
b8ac4f3b 5962 GFC_DECL_SAVED_DESCRIPTOR (var) = desc;
1792349b
AV
5963 }
5964 gfc_add_modify_loc (input_location, &block, var, tmp);
26e46e4b 5965
1792349b 5966 expr3 = var;
db7ffcab 5967 if (se.string_length)
1792349b 5968 /* Evaluate it assuming that it also is complicated like expr3. */
db7ffcab 5969 expr3_len = gfc_evaluate_now (se.string_length, &block);
34d9d749 5970 }
1792349b
AV
5971 else
5972 {
5973 expr3 = se.expr;
5974 expr3_len = se.string_length;
5975 }
3cae214f
PT
5976
5977 /* Deallocate any allocatable components in expressions that use a
139d4065
AV
5978 temporary object, i.e. are not a simple alias of to an EXPR_VARIABLE.
5979 E.g. temporaries of a function call need freeing of their components
5980 here. */
3cae214f
PT
5981 if ((code->expr3->ts.type == BT_DERIVED
5982 || code->expr3->ts.type == BT_CLASS)
139d4065 5983 && (code->expr3->expr_type != EXPR_VARIABLE || temp_obj_created)
3cae214f
PT
5984 && code->expr3->ts.u.derived->attr.alloc_comp)
5985 {
5986 tmp = gfc_deallocate_alloc_comp (code->expr3->ts.u.derived,
5987 expr3, code->expr3->rank);
5988 gfc_prepend_expr_to_block (&post, tmp);
5989 }
5990
1792349b 5991 /* Store what the expr3 is to be used for. */
b8ac4f3b
AV
5992 if (e3_is == E3_UNSET)
5993 e3_is = expr3 != NULL_TREE ?
5994 (code->ext.alloc.arr_spec_from_expr3 ?
5995 E3_DESC
5996 : (code->expr3->mold ? E3_MOLD : E3_SOURCE))
5997 : E3_UNSET;
34d9d749
AV
5998
5999 /* Figure how to get the _vtab entry. This also obtains the tree
6000 expression for accessing the _len component, because only
6001 unlimited polymorphic objects, which are a subcategory of class
6002 types, have a _len component. */
6003 if (code->expr3->ts.type == BT_CLASS)
6004 {
6005 gfc_expr *rhs;
b8ac4f3b
AV
6006 tmp = expr3 != NULL_TREE && POINTER_TYPE_P (TREE_TYPE (expr3)) ?
6007 build_fold_indirect_ref (expr3): expr3;
db7ffcab
AV
6008 /* Polymorphic SOURCE: VPTR must be determined at run time.
6009 expr3 may be a temporary array declaration, therefore check for
6010 GFC_CLASS_TYPE_P before trying to get the _vptr component. */
b8ac4f3b 6011 if (tmp != NULL_TREE
b8ac4f3b
AV
6012 && (e3_is == E3_DESC
6013 || (GFC_CLASS_TYPE_P (TREE_TYPE (tmp))
6014 && (VAR_P (tmp) || !code->expr3->ref))
6015 || (VAR_P (tmp) && DECL_LANG_SPECIFIC (tmp))))
34d9d749 6016 tmp = gfc_class_vptr_get (expr3);
34d9d749
AV
6017 else
6018 {
6019 rhs = gfc_find_and_cut_at_last_class_ref (code->expr3);
6020 gfc_add_vptr_component (rhs);
6021 gfc_init_se (&se, NULL);
6022 se.want_pointer = 1;
6023 gfc_conv_expr (&se, rhs);
6024 tmp = se.expr;
6025 gfc_free_expr (rhs);
6026 }
6027 /* Set the element size. */
6028 expr3_esize = gfc_vptr_size_get (tmp);
6029 if (vtab_needed)
6030 expr3_vptr = tmp;
6031 /* Initialize the ref to the _len component. */
6032 if (expr3_len == NULL_TREE && UNLIMITED_POLY (code->expr3))
6033 {
6034 /* Same like for retrieving the _vptr. */
6035 if (expr3 != NULL_TREE && !code->expr3->ref)
1792349b 6036 expr3_len = gfc_class_len_get (expr3);
34d9d749
AV
6037 else
6038 {
6039 rhs = gfc_find_and_cut_at_last_class_ref (code->expr3);
6040 gfc_add_len_component (rhs);
6041 gfc_init_se (&se, NULL);
6042 gfc_conv_expr (&se, rhs);
6043 expr3_len = se.expr;
6044 gfc_free_expr (rhs);
6045 }
6046 }
6047 }
6048 else
6049 {
6050 /* When the object to allocate is polymorphic type, then it
6051 needs its vtab set correctly, so deduce the required _vtab
6052 and _len from the source expression. */
6053 if (vtab_needed)
6054 {
6055 /* VPTR is fixed at compile time. */
6056 gfc_symbol *vtab;
90cf3ecc 6057
34d9d749
AV
6058 vtab = gfc_find_vtab (&code->expr3->ts);
6059 gcc_assert (vtab);
6060 expr3_vptr = gfc_get_symbol_decl (vtab);
6061 expr3_vptr = gfc_build_addr_expr (NULL_TREE,
6062 expr3_vptr);
6063 }
6064 /* _len component needs to be set, when ts is a character
6065 array. */
6066 if (expr3_len == NULL_TREE
6067 && code->expr3->ts.type == BT_CHARACTER)
6068 {
6069 if (code->expr3->ts.u.cl
6070 && code->expr3->ts.u.cl->length)
6071 {
6072 gfc_init_se (&se, NULL);
6073 gfc_conv_expr (&se, code->expr3->ts.u.cl->length);
6074 gfc_add_block_to_block (&block, &se.pre);
6075 expr3_len = gfc_evaluate_now (se.expr, &block);
6076 }
6077 gcc_assert (expr3_len);
6078 }
6079 /* For character arrays only the kind's size is needed, because
6080 the array mem_size is _len * (elem_size = kind_size).
6081 For all other get the element size in the normal way. */
6082 if (code->expr3->ts.type == BT_CHARACTER)
6083 expr3_esize = TYPE_SIZE_UNIT (
6084 gfc_get_char_type (code->expr3->ts.kind));
6085 else
6086 expr3_esize = TYPE_SIZE_UNIT (
6087 gfc_typenode_for_spec (&code->expr3->ts));
6088 }
6089 gcc_assert (expr3_esize);
6090 expr3_esize = fold_convert (sizetype, expr3_esize);
1792349b 6091 if (e3_is == E3_MOLD)
64e56ab0
AV
6092 /* The expr3 is no longer valid after this point. */
6093 expr3 = NULL_TREE;
34d9d749
AV
6094 }
6095 else if (code->ext.alloc.ts.type != BT_UNKNOWN)
6096 {
6097 /* Compute the explicit typespec given only once for all objects
6098 to allocate. */
6099 if (code->ext.alloc.ts.type != BT_CHARACTER)
6100 expr3_esize = TYPE_SIZE_UNIT (
6101 gfc_typenode_for_spec (&code->ext.alloc.ts));
8cd119d8 6102 else if (code->ext.alloc.ts.u.cl->length != NULL)
34d9d749
AV
6103 {
6104 gfc_expr *sz;
34d9d749
AV
6105 sz = gfc_copy_expr (code->ext.alloc.ts.u.cl->length);
6106 gfc_init_se (&se_sz, NULL);
6107 gfc_conv_expr (&se_sz, sz);
6108 gfc_free_expr (sz);
6109 tmp = gfc_get_char_type (code->ext.alloc.ts.kind);
6110 tmp = TYPE_SIZE_UNIT (tmp);
6111 tmp = fold_convert (TREE_TYPE (se_sz.expr), tmp);
69aaea06 6112 gfc_add_block_to_block (&block, &se_sz.pre);
34d9d749
AV
6113 expr3_esize = fold_build2_loc (input_location, MULT_EXPR,
6114 TREE_TYPE (se_sz.expr),
6115 tmp, se_sz.expr);
69aaea06 6116 expr3_esize = gfc_evaluate_now (expr3_esize, &block);
34d9d749 6117 }
8cd119d8
PT
6118 else
6119 expr3_esize = NULL_TREE;
34d9d749
AV
6120 }
6121
574284e9
AV
6122 /* The routine gfc_trans_assignment () already implements all
6123 techniques needed. Unfortunately we may have a temporary
6124 variable for the source= expression here. When that is the
6125 case convert this variable into a temporary gfc_expr of type
6126 EXPR_VARIABLE and used it as rhs for the assignment. The
6127 advantage is, that we get scalarizer support for free,
6128 don't have to take care about scalar to array treatment and
6129 will benefit of every enhancements gfc_trans_assignment ()
6130 gets.
6131 No need to check whether e3_is is E3_UNSET, because that is
6132 done by expr3 != NULL_TREE.
6133 Exclude variables since the following block does not handle
6134 array sections. In any case, there is no harm in sending
6135 variables to gfc_trans_assignment because there is no
6136 evaluation of variables. */
6137 if (code->expr3)
6138 {
6139 if (code->expr3->expr_type != EXPR_VARIABLE
6140 && e3_is != E3_MOLD && expr3 != NULL_TREE
6141 && DECL_P (expr3) && DECL_ARTIFICIAL (expr3))
6142 {
6143 /* Build a temporary symtree and symbol. Do not add it to the current
6144 namespace to prevent accidently modifying a colliding
6145 symbol's as. */
6146 newsym = XCNEW (gfc_symtree);
6147 /* The name of the symtree should be unique, because gfc_create_var ()
6148 took care about generating the identifier. */
51f03c6b
JJ
6149 newsym->name
6150 = gfc_get_string ("%s", IDENTIFIER_POINTER (DECL_NAME (expr3)));
574284e9
AV
6151 newsym->n.sym = gfc_new_symbol (newsym->name, NULL);
6152 /* The backend_decl is known. It is expr3, which is inserted
6153 here. */
6154 newsym->n.sym->backend_decl = expr3;
6155 e3rhs = gfc_get_expr ();
6156 e3rhs->rank = code->expr3->rank;
6157 e3rhs->symtree = newsym;
6158 /* Mark the symbol referenced or gfc_trans_assignment will bug. */
6159 newsym->n.sym->attr.referenced = 1;
6160 e3rhs->expr_type = EXPR_VARIABLE;
6161 e3rhs->where = code->expr3->where;
6162 /* Set the symbols type, upto it was BT_UNKNOWN. */
6163 if (IS_CLASS_ARRAY (code->expr3)
6164 && code->expr3->expr_type == EXPR_FUNCTION
6165 && code->expr3->value.function.isym
6166 && code->expr3->value.function.isym->transformational)
6167 {
6168 e3rhs->ts = CLASS_DATA (code->expr3)->ts;
6169 }
6170 else if (code->expr3->ts.type == BT_CLASS
6171 && !GFC_CLASS_TYPE_P (TREE_TYPE (expr3)))
6172 e3rhs->ts = CLASS_DATA (code->expr3)->ts;
6173 else
6174 e3rhs->ts = code->expr3->ts;
6175 newsym->n.sym->ts = e3rhs->ts;
6176 /* Check whether the expr3 is array valued. */
6177 if (e3rhs->rank)
6178 {
6179 gfc_array_spec *arr;
6180 arr = gfc_get_array_spec ();
6181 arr->rank = e3rhs->rank;
6182 arr->type = AS_DEFERRED;
6183 /* Set the dimension and pointer attribute for arrays
6184 to be on the safe side. */
6185 newsym->n.sym->attr.dimension = 1;
6186 newsym->n.sym->attr.pointer = 1;
6187 newsym->n.sym->as = arr;
6188 if (IS_CLASS_ARRAY (code->expr3)
6189 && code->expr3->expr_type == EXPR_FUNCTION
6190 && code->expr3->value.function.isym
6191 && code->expr3->value.function.isym->transformational)
6192 {
6193 gfc_array_spec *tarr;
6194 tarr = gfc_get_array_spec ();
6195 *tarr = *arr;
6196 e3rhs->ts.u.derived->as = tarr;
6197 }
6198 gfc_add_full_array_ref (e3rhs, arr);
6199 }
6200 else if (POINTER_TYPE_P (TREE_TYPE (expr3)))
6201 newsym->n.sym->attr.pointer = 1;
6202 /* The string length is known, too. Set it for char arrays. */
6203 if (e3rhs->ts.type == BT_CHARACTER)
6204 newsym->n.sym->ts.u.cl->backend_decl = expr3_len;
6205 gfc_commit_symbol (newsym->n.sym);
6206 }
6207 else
6208 e3rhs = gfc_copy_expr (code->expr3);
6209 }
6210
34d9d749 6211 /* Loop over all objects to allocate. */
cf2b3c22 6212 for (al = code->ext.alloc.list; al != NULL; al = al->next)
6de9cd9a 6213 {
f43085aa 6214 expr = gfc_copy_expr (al->expr);
34d9d749
AV
6215 /* UNLIMITED_POLY () needs the _data component to be set, when
6216 expr is a unlimited polymorphic object. But the _data component
6217 has not been set yet, so check the derived type's attr for the
6218 unlimited polymorphic flag to be safe. */
6219 upoly_expr = UNLIMITED_POLY (expr)
6220 || (expr->ts.type == BT_DERIVED
6221 && expr->ts.u.derived->attr.unlimited_polymorphic);
6222 gfc_init_se (&se, NULL);
f43085aa 6223
34d9d749
AV
6224 /* For class types prepare the expressions to ref the _vptr
6225 and the _len component. The latter for unlimited polymorphic
6226 types only. */
f43085aa 6227 if (expr->ts.type == BT_CLASS)
34d9d749
AV
6228 {
6229 gfc_expr *expr_ref_vptr, *expr_ref_len;
6230 gfc_add_data_component (expr);
6231 /* Prep the vptr handle. */
6232 expr_ref_vptr = gfc_copy_expr (al->expr);
6233 gfc_add_vptr_component (expr_ref_vptr);
6234 se.want_pointer = 1;
6235 gfc_conv_expr (&se, expr_ref_vptr);
6236 al_vptr = se.expr;
6237 se.want_pointer = 0;
6238 gfc_free_expr (expr_ref_vptr);
6239 /* Allocated unlimited polymorphic objects always have a _len
6240 component. */
6241 if (upoly_expr)
6242 {
6243 expr_ref_len = gfc_copy_expr (al->expr);
6244 gfc_add_len_component (expr_ref_len);
6245 gfc_conv_expr (&se, expr_ref_len);
6246 al_len = se.expr;
6247 gfc_free_expr (expr_ref_len);
6248 }
6249 else
6250 /* In a loop ensure that all loop variable dependent variables
6251 are initialized at the same spot in all execution paths. */
6252 al_len = NULL_TREE;
6253 }
6254 else
6255 al_vptr = al_len = NULL_TREE;
6de9cd9a
DN
6256
6257 se.want_pointer = 1;
6258 se.descriptor_only = 1;
78ab5260 6259
6de9cd9a 6260 gfc_conv_expr (&se, expr);
34d9d749
AV
6261 if (expr->ts.type == BT_CHARACTER && expr->ts.deferred)
6262 /* se.string_length now stores the .string_length variable of expr
6263 needed to allocate character(len=:) arrays. */
6264 al_len = se.string_length;
6265
6266 al_len_needs_set = al_len != NULL_TREE;
6267 /* When allocating an array one can not use much of the
6268 pre-evaluated expr3 expressions, because for most of them the
6269 scalarizer is needed which is not available in the pre-evaluation
6270 step. Therefore gfc_array_allocate () is responsible (and able)
6271 to handle the complete array allocation. Only the element size
6272 needs to be provided, which is done most of the time by the
6273 pre-evaluation step. */
4daa71b0 6274 nelems = NULL_TREE;
764d5c7b
AV
6275 if (expr3_len && (code->expr3->ts.type == BT_CHARACTER
6276 || code->expr3->ts.type == BT_CLASS))
6277 {
6278 /* When al is an array, then the element size for each element
6279 in the array is needed, which is the product of the len and
6280 esize for char arrays. For unlimited polymorphics len can be
6281 zero, therefore take the maximum of len and one. */
6282 tmp = fold_build2_loc (input_location, MAX_EXPR,
6283 TREE_TYPE (expr3_len),
6284 expr3_len, fold_convert (TREE_TYPE (expr3_len),
6285 integer_one_node));
6286 tmp = fold_build2_loc (input_location, MULT_EXPR,
6287 TREE_TYPE (expr3_esize), expr3_esize,
6288 fold_convert (TREE_TYPE (expr3_esize), tmp));
6289 }
34d9d749
AV
6290 else
6291 tmp = expr3_esize;
6292 if (!gfc_array_allocate (&se, expr, stat, errmsg, errlen,
1792349b
AV
6293 label_finish, tmp, &nelems,
6294 e3rhs ? e3rhs : code->expr3,
6295 e3_is == E3_DESC ? expr3 : NULL_TREE,
6296 code->expr3 != NULL && e3_is == E3_DESC
6297 && code->expr3->expr_type == EXPR_ARRAY))
6de9cd9a 6298 {
34d9d749
AV
6299 /* A scalar or derived type. First compute the size to
6300 allocate.
cf2b3c22 6301
34d9d749
AV
6302 expr3_len is set when expr3 is an unlimited polymorphic
6303 object or a deferred length string. */
6304 if (expr3_len != NULL_TREE)
8d51f26f 6305 {
34d9d749
AV
6306 tmp = fold_convert (TREE_TYPE (expr3_esize), expr3_len);
6307 tmp = fold_build2_loc (input_location, MULT_EXPR,
6308 TREE_TYPE (expr3_esize),
6309 expr3_esize, tmp);
6310 if (code->expr3->ts.type != BT_CLASS)
6311 /* expr3 is a deferred length string, i.e., we are
6312 done. */
6313 memsz = tmp;
8d51f26f 6314 else
5b384b3d 6315 {
34d9d749
AV
6316 /* For unlimited polymorphic enties build
6317 (len > 0) ? element_size * len : element_size
6318 to compute the number of bytes to allocate.
6319 This allows the allocation of unlimited polymorphic
6320 objects from an expr3 that is also unlimited
6321 polymorphic and stores a _len dependent object,
6322 e.g., a string. */
6323 memsz = fold_build2_loc (input_location, GT_EXPR,
63ee5404 6324 logical_type_node, expr3_len,
f622221a
JB
6325 build_zero_cst
6326 (TREE_TYPE (expr3_len)));
34d9d749
AV
6327 memsz = fold_build3_loc (input_location, COND_EXPR,
6328 TREE_TYPE (expr3_esize),
6329 memsz, tmp, expr3_esize);
5b384b3d 6330 }
8d51f26f 6331 }
34d9d749
AV
6332 else if (expr3_esize != NULL_TREE)
6333 /* Any other object in expr3 just needs element size in
6334 bytes. */
6335 memsz = expr3_esize;
6336 else if ((expr->ts.type == BT_CHARACTER && expr->ts.deferred)
6337 || (upoly_expr
6338 && code->ext.alloc.ts.type == BT_CHARACTER))
2573aab9 6339 {
34d9d749
AV
6340 /* Allocating deferred length char arrays need the length
6341 to allocate in the alloc_type_spec. But also unlimited
6342 polymorphic objects may be allocated as char arrays.
6343 Both are handled here. */
2573aab9
TB
6344 gfc_init_se (&se_sz, NULL);
6345 gfc_conv_expr (&se_sz, code->ext.alloc.ts.u.cl->length);
6346 gfc_add_block_to_block (&se.pre, &se_sz.pre);
6347 se_sz.expr = gfc_evaluate_now (se_sz.expr, &se.pre);
6348 gfc_add_block_to_block (&se.pre, &se_sz.post);
34d9d749
AV
6349 expr3_len = se_sz.expr;
6350 tmp_expr3_len_flag = true;
6351 tmp = TYPE_SIZE_UNIT (
6352 gfc_get_char_type (code->ext.alloc.ts.kind));
2573aab9 6353 memsz = fold_build2_loc (input_location, MULT_EXPR,
34d9d749
AV
6354 TREE_TYPE (tmp),
6355 fold_convert (TREE_TYPE (tmp),
6356 expr3_len),
6357 tmp);
2573aab9 6358 }
34d9d749 6359 else if (expr->ts.type == BT_CHARACTER)
8d51f26f 6360 {
34d9d749
AV
6361 /* Compute the number of bytes needed to allocate a fixed
6362 length char array. */
6363 gcc_assert (se.string_length != NULL_TREE);
6364 tmp = TYPE_SIZE_UNIT (gfc_get_char_type (expr->ts.kind));
8d51f26f
PT
6365 memsz = fold_build2_loc (input_location, MULT_EXPR,
6366 TREE_TYPE (tmp), tmp,
34d9d749
AV
6367 fold_convert (TREE_TYPE (tmp),
6368 se.string_length));
8d51f26f 6369 }
34d9d749
AV
6370 else if (code->ext.alloc.ts.type != BT_UNKNOWN)
6371 /* Handle all types, where the alloc_type_spec is set. */
6372 memsz = TYPE_SIZE_UNIT (gfc_typenode_for_spec (&code->ext.alloc.ts));
6373 else
6374 /* Handle size computation of the type declared to alloc. */
6f3d1a5e 6375 memsz = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (se.expr)));
90cf3ecc 6376
525a5e33
AV
6377 /* Store the caf-attributes for latter use. */
6378 if (flag_coarray == GFC_FCOARRAY_LIB
6379 && (caf_attr = gfc_caf_attr (expr, true, &caf_refs_comp))
6380 .codimension)
3c9f5092
AV
6381 {
6382 /* Scalar allocatable components in coarray'ed derived types make
6383 it here and are treated now. */
6384 tree caf_decl, token;
6385 gfc_se caf_se;
6386
ffaf9305 6387 is_coarray = true;
525a5e33
AV
6388 /* Set flag, to add synchronize after the allocate. */
6389 needs_caf_sync = needs_caf_sync
6390 || caf_attr.coarray_comp || !caf_refs_comp;
ffaf9305 6391
3c9f5092
AV
6392 gfc_init_se (&caf_se, NULL);
6393
6394 caf_decl = gfc_get_tree_for_caf_expr (expr);
6395 gfc_get_caf_token_offset (&caf_se, &token, NULL, caf_decl,
6396 NULL_TREE, NULL);
6397 gfc_add_block_to_block (&se.pre, &caf_se.pre);
6398 gfc_allocate_allocatable (&se.pre, se.expr, memsz,
6399 gfc_build_addr_expr (NULL_TREE, token),
6400 NULL_TREE, NULL_TREE, NULL_TREE,
6401 label_finish, expr, 1);
6402 }
5b130807 6403 /* Allocate - for non-pointers with re-alloc checking. */
3c9f5092
AV
6404 else if (gfc_expr_attr (expr).allocatable)
6405 gfc_allocate_allocatable (&se.pre, se.expr, memsz,
6406 NULL_TREE, stat, errmsg, errlen,
6407 label_finish, expr, 0);
90cf3ecc 6408 else
4f13e17f 6409 gfc_allocate_using_malloc (&se.pre, se.expr, memsz, stat);
6de9cd9a 6410 }
34d9d749
AV
6411 else
6412 {
ffaf9305
AV
6413 /* Allocating coarrays needs a sync after the allocate executed.
6414 Set the flag to add the sync after all objects are allocated. */
525a5e33
AV
6415 if (flag_coarray == GFC_FCOARRAY_LIB
6416 && (caf_attr = gfc_caf_attr (expr, true, &caf_refs_comp))
6417 .codimension)
6418 {
6419 is_coarray = true;
6420 needs_caf_sync = needs_caf_sync
6421 || caf_attr.coarray_comp || !caf_refs_comp;
6422 }
ffaf9305 6423
34d9d749
AV
6424 if (expr->ts.type == BT_CHARACTER && al_len != NULL_TREE
6425 && expr3_len != NULL_TREE)
6426 {
6427 /* Arrays need to have a _len set before the array
6428 descriptor is filled. */
6429 gfc_add_modify (&block, al_len,
6430 fold_convert (TREE_TYPE (al_len), expr3_len));
6431 /* Prevent setting the length twice. */
6432 al_len_needs_set = false;
6433 }
afbc5ae8 6434 else if (expr->ts.type == BT_CHARACTER && al_len != NULL_TREE
323c5722 6435 && code->ext.alloc.ts.u.cl->length)
afbc5ae8
PT
6436 {
6437 /* Cover the cases where a string length is explicitly
6438 specified by a type spec for deferred length character
6439 arrays or unlimited polymorphic objects without a
6440 source= or mold= expression. */
6441 gfc_init_se (&se_sz, NULL);
6442 gfc_conv_expr (&se_sz, code->ext.alloc.ts.u.cl->length);
69aaea06 6443 gfc_add_block_to_block (&block, &se_sz.pre);
afbc5ae8
PT
6444 gfc_add_modify (&block, al_len,
6445 fold_convert (TREE_TYPE (al_len),
6446 se_sz.expr));
6447 al_len_needs_set = false;
6448 }
34d9d749 6449 }
6de9cd9a 6450
90cf3ecc 6451 gfc_add_block_to_block (&block, &se.pre);
cf2b3c22 6452
8f992d64
DC
6453 /* Error checking -- Note: ERRMSG only makes sense with STAT. */
6454 if (code->expr1)
6455 {
5d81ddd0 6456 tmp = build1_v (GOTO_EXPR, label_errmsg);
8f992d64 6457 parm = fold_build2_loc (input_location, NE_EXPR,
63ee5404 6458 logical_type_node, stat,
8f992d64
DC
6459 build_int_cst (TREE_TYPE (stat), 0));
6460 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
ed9c79e1
JJ
6461 gfc_unlikely (parm, PRED_FORTRAN_FAIL_ALLOC),
6462 tmp, build_empty_stmt (input_location));
8f992d64
DC
6463 gfc_add_expr_to_block (&block, tmp);
6464 }
8b704316 6465
574284e9
AV
6466 /* Set the vptr only when no source= is set. When source= is set, then
6467 the trans_assignment below will set the vptr. */
6468 if (al_vptr != NULL_TREE && (!code->expr3 || code->expr3->mold))
c49ea23d 6469 {
34d9d749
AV
6470 if (expr3_vptr != NULL_TREE)
6471 /* The vtab is already known, so just assign it. */
6472 gfc_add_modify (&block, al_vptr,
6473 fold_convert (TREE_TYPE (al_vptr), expr3_vptr));
c49ea23d
PT
6474 else
6475 {
6476 /* VPTR is fixed at compile time. */
6477 gfc_symbol *vtab;
6478 gfc_typespec *ts;
34d9d749 6479
c49ea23d 6480 if (code->expr3)
34d9d749
AV
6481 /* Although expr3 is pre-evaluated above, it may happen,
6482 that for arrays or in mold= cases the pre-evaluation
6483 was not successful. In these rare cases take the vtab
6484 from the typespec of expr3 here. */
c49ea23d 6485 ts = &code->expr3->ts;
34d9d749
AV
6486 else if (code->ext.alloc.ts.type == BT_DERIVED || upoly_expr)
6487 /* The alloc_type_spec gives the type to allocate or the
6488 al is unlimited polymorphic, which enforces the use of
6489 an alloc_type_spec that is not necessarily a BT_DERIVED. */
c49ea23d 6490 ts = &code->ext.alloc.ts;
c49ea23d 6491 else
34d9d749
AV
6492 /* Prepare for setting the vtab as declared. */
6493 ts = &expr->ts;
6494
6495 vtab = gfc_find_vtab (ts);
6496 gcc_assert (vtab);
6497 tmp = gfc_build_addr_expr (NULL_TREE,
6498 gfc_get_symbol_decl (vtab));
6499 gfc_add_modify (&block, al_vptr,
6500 fold_convert (TREE_TYPE (al_vptr), tmp));
c49ea23d 6501 }
c49ea23d
PT
6502 }
6503
34d9d749
AV
6504 /* Add assignment for string length. */
6505 if (al_len != NULL_TREE && al_len_needs_set)
6506 {
6507 if (expr3_len != NULL_TREE)
6508 {
6509 gfc_add_modify (&block, al_len,
6510 fold_convert (TREE_TYPE (al_len),
6511 expr3_len));
6512 /* When tmp_expr3_len_flag is set, then expr3_len is
6513 abused to carry the length information from the
6514 alloc_type. Clear it to prevent setting incorrect len
6515 information in future loop iterations. */
6516 if (tmp_expr3_len_flag)
6517 /* No need to reset tmp_expr3_len_flag, because the
6518 presence of an expr3 can not change within in the
6519 loop. */
6520 expr3_len = NULL_TREE;
6521 }
6522 else if (code->ext.alloc.ts.type == BT_CHARACTER
323c5722 6523 && code->ext.alloc.ts.u.cl->length)
34d9d749
AV
6524 {
6525 /* Cover the cases where a string length is explicitly
6526 specified by a type spec for deferred length character
6527 arrays or unlimited polymorphic objects without a
6528 source= or mold= expression. */
69aaea06
AV
6529 if (expr3_esize == NULL_TREE || code->ext.alloc.ts.kind != 1)
6530 {
6531 gfc_init_se (&se_sz, NULL);
6532 gfc_conv_expr (&se_sz, code->ext.alloc.ts.u.cl->length);
6533 gfc_add_block_to_block (&block, &se_sz.pre);
6534 gfc_add_modify (&block, al_len,
6535 fold_convert (TREE_TYPE (al_len),
6536 se_sz.expr));
6537 }
6538 else
6539 gfc_add_modify (&block, al_len,
6540 fold_convert (TREE_TYPE (al_len),
6541 expr3_esize));
34d9d749
AV
6542 }
6543 else
6544 /* No length information needed, because type to allocate
6545 has no length. Set _len to 0. */
6546 gfc_add_modify (&block, al_len,
6547 fold_convert (TREE_TYPE (al_len),
6548 integer_zero_node));
6549 }
cc03bf7a
AV
6550
6551 init_expr = NULL;
64e56ab0 6552 if (code->expr3 && !code->expr3->mold && e3_is != E3_MOLD)
cf2b3c22 6553 {
db7ffcab 6554 /* Initialization via SOURCE block (or static default initializer).
574284e9
AV
6555 Switch off automatic reallocation since we have just done the
6556 ALLOCATE. */
6557 int realloc_lhs = flag_realloc_lhs;
6558 gfc_expr *init_expr = gfc_expr_to_initialize (expr);
6559 gfc_expr *rhs = e3rhs ? e3rhs : gfc_copy_expr (code->expr3);
6560 flag_realloc_lhs = 0;
6561 tmp = gfc_trans_assignment (init_expr, rhs, false, false, true,
6562 false);
6563 flag_realloc_lhs = realloc_lhs;
6564 /* Free the expression allocated for init_expr. */
6565 gfc_free_expr (init_expr);
6566 if (rhs != e3rhs)
6567 gfc_free_expr (rhs);
f43085aa
JW
6568 gfc_add_expr_to_block (&block, tmp);
6569 }
5bab4c96
PT
6570 /* Set KIND and LEN PDT components and allocate those that are
6571 parameterized. */
6572 else if (expr->ts.type == BT_DERIVED
6573 && expr->ts.u.derived->attr.pdt_type)
6574 {
6575 if (code->expr3 && code->expr3->param_list)
6576 param_list = code->expr3->param_list;
6577 else if (expr->param_list)
6578 param_list = expr->param_list;
6579 else
6580 param_list = expr->symtree->n.sym->param_list;
6581 tmp = gfc_allocate_pdt_comp (expr->ts.u.derived, se.expr,
6582 expr->rank, param_list);
6583 gfc_add_expr_to_block (&block, tmp);
6584 }
6585 /* Ditto for CLASS expressions. */
6586 else if (expr->ts.type == BT_CLASS
6587 && CLASS_DATA (expr)->ts.u.derived->attr.pdt_type)
6588 {
6589 if (code->expr3 && code->expr3->param_list)
6590 param_list = code->expr3->param_list;
6591 else if (expr->param_list)
6592 param_list = expr->param_list;
6593 else
6594 param_list = expr->symtree->n.sym->param_list;
6595 tmp = gfc_allocate_pdt_comp (CLASS_DATA (expr)->ts.u.derived,
6596 se.expr, expr->rank, param_list);
6597 gfc_add_expr_to_block (&block, tmp);
6598 }
574284e9
AV
6599 else if (code->expr3 && code->expr3->mold
6600 && code->expr3->ts.type == BT_CLASS)
50f30801 6601 {
574284e9
AV
6602 /* Use class_init_assign to initialize expr. */
6603 gfc_code *ini;
6604 ini = gfc_get_code (EXEC_INIT_ASSIGN);
6605 ini->expr1 = gfc_find_and_cut_at_last_class_ref (expr);
6606 tmp = gfc_trans_class_init_assign (ini);
6607 gfc_free_statements (ini);
b6ff8128 6608 gfc_add_expr_to_block (&block, tmp);
50f30801 6609 }
cc03bf7a
AV
6610 else if ((init_expr = allocate_get_initializer (code, expr)))
6611 {
6612 /* Use class_init_assign to initialize expr. */
6613 gfc_code *ini;
6614 int realloc_lhs = flag_realloc_lhs;
6615 ini = gfc_get_code (EXEC_INIT_ASSIGN);
6616 ini->expr1 = gfc_expr_to_initialize (expr);
6617 ini->expr2 = init_expr;
6618 flag_realloc_lhs = 0;
6619 tmp= gfc_trans_init_assign (ini);
6620 flag_realloc_lhs = realloc_lhs;
6621 gfc_free_statements (ini);
6622 /* Init_expr is freeed by above free_statements, just need to null
6623 it here. */
6624 init_expr = NULL;
6625 gfc_add_expr_to_block (&block, tmp);
6626 }
f43085aa 6627
de91486c
AV
6628 /* Nullify all pointers in derived type coarrays. This registers a
6629 token for them which allows their allocation. */
6630 if (is_coarray)
6631 {
6632 gfc_symbol *type = NULL;
6633 symbol_attribute caf_attr;
6634 int rank = 0;
6635 if (code->ext.alloc.ts.type == BT_DERIVED
6636 && code->ext.alloc.ts.u.derived->attr.pointer_comp)
6637 {
6638 type = code->ext.alloc.ts.u.derived;
6639 rank = type->attr.dimension ? type->as->rank : 0;
6640 gfc_clear_attr (&caf_attr);
6641 }
6642 else if (expr->ts.type == BT_DERIVED
6643 && expr->ts.u.derived->attr.pointer_comp)
6644 {
6645 type = expr->ts.u.derived;
6646 rank = expr->rank;
6647 caf_attr = gfc_caf_attr (expr, true);
6648 }
6649
6650 /* Initialize the tokens of pointer components in derived type
6651 coarrays. */
6652 if (type)
6653 {
6654 tmp = (caf_attr.codimension && !caf_attr.dimension)
6655 ? gfc_conv_descriptor_data_get (se.expr) : se.expr;
6656 tmp = gfc_nullify_alloc_comp (type, tmp, rank,
6657 GFC_STRUCTURE_CAF_MODE_IN_COARRAY);
6658 gfc_add_expr_to_block (&block, tmp);
6659 }
6660 }
6661
574284e9 6662 gfc_free_expr (expr);
34d9d749 6663 } // for-loop
6de9cd9a 6664
db7ffcab
AV
6665 if (e3rhs)
6666 {
6667 if (newsym)
6668 {
6669 gfc_free_symbol (newsym->n.sym);
6670 XDELETE (newsym);
6671 }
6672 gfc_free_expr (e3rhs);
6673 }
5d81ddd0 6674 /* STAT. */
a513927a 6675 if (code->expr1)
6de9cd9a 6676 {
8f992d64 6677 tmp = build1_v (LABEL_EXPR, label_errmsg);
6de9cd9a 6678 gfc_add_expr_to_block (&block, tmp);
6de9cd9a
DN
6679 }
6680
5d81ddd0
TB
6681 /* ERRMSG - only useful if STAT is present. */
6682 if (code->expr1 && code->expr2)
3759634f 6683 {
3759634f 6684 const char *msg = "Attempt to allocate an allocated object";
5d81ddd0
TB
6685 tree slen, dlen, errmsg_str;
6686 stmtblock_t errmsg_block;
3759634f 6687
5d81ddd0 6688 gfc_init_block (&errmsg_block);
3759634f 6689
5d81ddd0
TB
6690 errmsg_str = gfc_create_var (pchar_type_node, "ERRMSG");
6691 gfc_add_modify (&errmsg_block, errmsg_str,
3759634f
SK
6692 gfc_build_addr_expr (pchar_type_node,
6693 gfc_build_localized_cstring_const (msg)));
6694
f622221a 6695 slen = build_int_cst (gfc_charlen_type_node, strlen (msg));
3759634f 6696 dlen = gfc_get_expr_charlen (code->expr2);
34d9d749
AV
6697 slen = fold_build2_loc (input_location, MIN_EXPR,
6698 TREE_TYPE (slen), dlen, slen);
3759634f 6699
34d9d749
AV
6700 gfc_trans_string_copy (&errmsg_block, dlen, errmsg,
6701 code->expr2->ts.kind,
6702 slen, errmsg_str,
6703 gfc_default_character_kind);
5d81ddd0 6704 dlen = gfc_finish_block (&errmsg_block);
3759634f 6705
63ee5404 6706 tmp = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
34d9d749 6707 stat, build_int_cst (TREE_TYPE (stat), 0));
3759634f 6708
34d9d749
AV
6709 tmp = build3_v (COND_EXPR, tmp,
6710 dlen, build_empty_stmt (input_location));
3759634f
SK
6711
6712 gfc_add_expr_to_block (&block, tmp);
6713 }
6714
8f992d64
DC
6715 /* STAT block. */
6716 if (code->expr1)
6717 {
5d81ddd0
TB
6718 if (TREE_USED (label_finish))
6719 {
6720 tmp = build1_v (LABEL_EXPR, label_finish);
6721 gfc_add_expr_to_block (&block, tmp);
6722 }
6723
8f992d64
DC
6724 gfc_init_se (&se, NULL);
6725 gfc_conv_expr_lhs (&se, code->expr1);
6726 tmp = convert (TREE_TYPE (se.expr), stat);
6727 gfc_add_modify (&block, se.expr, tmp);
6728 }
6729
525a5e33 6730 if (needs_caf_sync)
ffaf9305
AV
6731 {
6732 /* Add a sync all after the allocation has been executed. */
6733 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_sync_all,
6734 3, null_pointer_node, null_pointer_node,
6735 integer_zero_node);
6736 gfc_add_expr_to_block (&post, tmp);
6737 }
6738
90cf3ecc
PT
6739 gfc_add_block_to_block (&block, &se.post);
6740 gfc_add_block_to_block (&block, &post);
6741
6de9cd9a
DN
6742 return gfc_finish_block (&block);
6743}
6744
6745
3759634f
SK
6746/* Translate a DEALLOCATE statement. */
6747
6de9cd9a 6748tree
3759634f 6749gfc_trans_deallocate (gfc_code *code)
6de9cd9a
DN
6750{
6751 gfc_se se;
6752 gfc_alloc *al;
5d81ddd0
TB
6753 tree apstat, pstat, stat, errmsg, errlen, tmp;
6754 tree label_finish, label_errmsg;
6de9cd9a
DN
6755 stmtblock_t block;
6756
5d81ddd0
TB
6757 pstat = apstat = stat = errmsg = errlen = tmp = NULL_TREE;
6758 label_finish = label_errmsg = NULL_TREE;
3759634f 6759
6de9cd9a
DN
6760 gfc_start_block (&block);
6761
3759634f
SK
6762 /* Count the number of failed deallocations. If deallocate() was
6763 called with STAT= , then set STAT to the count. If deallocate
6764 was called with ERRMSG, then set ERRMG to a string. */
5d81ddd0 6765 if (code->expr1)
364667a1
SK
6766 {
6767 tree gfc_int4_type_node = gfc_get_int_type (4);
6768
364667a1 6769 stat = gfc_create_var (gfc_int4_type_node, "stat");
628c189e 6770 pstat = gfc_build_addr_expr (NULL_TREE, stat);
364667a1 6771
5d81ddd0
TB
6772 /* GOTO destinations. */
6773 label_errmsg = gfc_build_label_decl (NULL_TREE);
6774 label_finish = gfc_build_label_decl (NULL_TREE);
6775 TREE_USED (label_finish) = 0;
6776 }
364667a1 6777
5d81ddd0
TB
6778 /* Set ERRMSG - only needed if STAT is available. */
6779 if (code->expr1 && code->expr2)
6780 {
6781 gfc_init_se (&se, NULL);
6782 se.want_pointer = 1;
6783 gfc_conv_expr_lhs (&se, code->expr2);
6784 errmsg = se.expr;
6785 errlen = se.string_length;
364667a1 6786 }
364667a1 6787
cf2b3c22 6788 for (al = code->ext.alloc.list; al != NULL; al = al->next)
6de9cd9a 6789 {
0d87fa8c 6790 gfc_expr *expr = gfc_copy_expr (al->expr);
ba85c8c3
AV
6791 bool is_coarray = false, is_coarray_array = false;
6792 int caf_mode = 0;
6793
6e45f57b 6794 gcc_assert (expr->expr_type == EXPR_VARIABLE);
6de9cd9a 6795
0d87fa8c
JW
6796 if (expr->ts.type == BT_CLASS)
6797 gfc_add_data_component (expr);
6798
6de9cd9a
DN
6799 gfc_init_se (&se, NULL);
6800 gfc_start_block (&se.pre);
6801
6802 se.want_pointer = 1;
6803 se.descriptor_only = 1;
6804 gfc_conv_expr (&se, expr);
6805
5bab4c96
PT
6806 /* Deallocate PDT components that are parameterized. */
6807 tmp = NULL;
6808 if (expr->ts.type == BT_DERIVED
6809 && expr->ts.u.derived->attr.pdt_type
6810 && expr->symtree->n.sym->param_list)
6811 tmp = gfc_deallocate_pdt_comp (expr->ts.u.derived, se.expr, expr->rank);
6812 else if (expr->ts.type == BT_CLASS
6813 && CLASS_DATA (expr)->ts.u.derived->attr.pdt_type
6814 && expr->symtree->n.sym->param_list)
6815 tmp = gfc_deallocate_pdt_comp (CLASS_DATA (expr)->ts.u.derived,
6816 se.expr, expr->rank);
6817
6818 if (tmp)
6819 gfc_add_expr_to_block (&block, tmp);
6820
de91486c
AV
6821 if (flag_coarray == GFC_FCOARRAY_LIB
6822 || flag_coarray == GFC_FCOARRAY_SINGLE)
ba85c8c3
AV
6823 {
6824 bool comp_ref;
6825 symbol_attribute caf_attr = gfc_caf_attr (expr, false, &comp_ref);
6826 if (caf_attr.codimension)
6827 {
6828 is_coarray = true;
6829 is_coarray_array = caf_attr.dimension || !comp_ref
6830 || caf_attr.coarray_comp;
6831
de91486c
AV
6832 if (flag_coarray == GFC_FCOARRAY_LIB)
6833 /* When the expression to deallocate is referencing a
6834 component, then only deallocate it, but do not
6835 deregister. */
6836 caf_mode = GFC_STRUCTURE_CAF_MODE_IN_COARRAY
6837 | (comp_ref && !caf_attr.coarray_comp
6838 ? GFC_STRUCTURE_CAF_MODE_DEALLOC_ONLY : 0);
ba85c8c3
AV
6839 }
6840 }
ba85c8c3
AV
6841
6842 if (expr->rank || is_coarray_array)
2c807128 6843 {
ec6a7096
PT
6844 gfc_ref *ref;
6845
ba85c8c3
AV
6846 if (gfc_bt_struct (expr->ts.type)
6847 && expr->ts.u.derived->attr.alloc_comp
ef292537 6848 && !gfc_is_finalizable (expr->ts.u.derived, NULL))
5046aff5 6849 {
2c807128 6850 gfc_ref *last = NULL;
ec6a7096 6851
2c807128
JW
6852 for (ref = expr->ref; ref; ref = ref->next)
6853 if (ref->type == REF_COMPONENT)
6854 last = ref;
6855
6856 /* Do not deallocate the components of a derived type
34d9d749 6857 ultimate pointer component. */
2c807128
JW
6858 if (!(last && last->u.c.component->attr.pointer)
6859 && !(!last && expr->symtree->n.sym->attr.pointer))
6860 {
ba85c8c3 6861 if (is_coarray && expr->rank == 0
eb401400
AV
6862 && (!last || !last->u.c.component->attr.dimension)
6863 && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se.expr)))
ba85c8c3
AV
6864 {
6865 /* Add the ref to the data member only, when this is not
6866 a regular array or deallocate_alloc_comp will try to
6867 add another one. */
6868 tmp = gfc_conv_descriptor_data_get (se.expr);
6869 }
6870 else
6871 tmp = se.expr;
6872 tmp = gfc_deallocate_alloc_comp (expr->ts.u.derived, tmp,
6873 expr->rank, caf_mode);
2c807128
JW
6874 gfc_add_expr_to_block (&se.pre, tmp);
6875 }
5046aff5 6876 }
ec6a7096
PT
6877
6878 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se.expr)))
6879 {
ba85c8c3
AV
6880 gfc_coarray_deregtype caf_dtype;
6881
6882 if (is_coarray)
6883 caf_dtype = gfc_caf_is_dealloc_only (caf_mode)
6884 ? GFC_CAF_COARRAY_DEALLOCATE_ONLY
6885 : GFC_CAF_COARRAY_DEREGISTER;
6886 else
6887 caf_dtype = GFC_CAF_COARRAY_NOCOARRAY;
39da5866
AV
6888 tmp = gfc_deallocate_with_status (se.expr, pstat, errmsg, errlen,
6889 label_finish, false, expr,
6890 caf_dtype);
ec6a7096
PT
6891 gfc_add_expr_to_block (&se.pre, tmp);
6892 }
6893 else if (TREE_CODE (se.expr) == COMPONENT_REF
6894 && TREE_CODE (TREE_TYPE (se.expr)) == ARRAY_TYPE
6895 && TREE_CODE (TREE_TYPE (TREE_TYPE (se.expr)))
6896 == RECORD_TYPE)
6897 {
6898 /* class.c(finalize_component) generates these, when a
6899 finalizable entity has a non-allocatable derived type array
6900 component, which has allocatable components. Obtain the
6901 derived type of the array and deallocate the allocatable
6902 components. */
6903 for (ref = expr->ref; ref; ref = ref->next)
6904 {
6905 if (ref->u.c.component->attr.dimension
6906 && ref->u.c.component->ts.type == BT_DERIVED)
6907 break;
6908 }
6909
6910 if (ref && ref->u.c.component->ts.u.derived->attr.alloc_comp
6911 && !gfc_is_finalizable (ref->u.c.component->ts.u.derived,
6912 NULL))
6913 {
6914 tmp = gfc_deallocate_alloc_comp
6915 (ref->u.c.component->ts.u.derived,
6916 se.expr, expr->rank);
6917 gfc_add_expr_to_block (&se.pre, tmp);
6918 }
6919 }
6920
4fb5478c 6921 if (al->expr->ts.type == BT_CLASS)
34d9d749
AV
6922 {
6923 gfc_reset_vptr (&se.pre, al->expr);
6924 if (UNLIMITED_POLY (al->expr)
6925 || (al->expr->ts.type == BT_DERIVED
6926 && al->expr->ts.u.derived->attr.unlimited_polymorphic))
6927 /* Clear _len, too. */
6928 gfc_reset_len (&se.pre, al->expr);
6929 }
5046aff5 6930 }
6de9cd9a
DN
6931 else
6932 {
ba85c8c3
AV
6933 tmp = gfc_deallocate_scalar_with_status (se.expr, pstat, label_finish,
6934 false, al->expr,
6935 al->expr->ts, is_coarray);
54200abb
RG
6936 gfc_add_expr_to_block (&se.pre, tmp);
6937
0d87fa8c 6938 /* Set to zero after deallocation. */
bc98ed60
TB
6939 tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node,
6940 se.expr,
6941 build_int_cst (TREE_TYPE (se.expr), 0));
0d87fa8c 6942 gfc_add_expr_to_block (&se.pre, tmp);
8b704316 6943
0d87fa8c 6944 if (al->expr->ts.type == BT_CLASS)
34d9d749
AV
6945 {
6946 gfc_reset_vptr (&se.pre, al->expr);
6947 if (UNLIMITED_POLY (al->expr)
6948 || (al->expr->ts.type == BT_DERIVED
6949 && al->expr->ts.u.derived->attr.unlimited_polymorphic))
6950 /* Clear _len, too. */
6951 gfc_reset_len (&se.pre, al->expr);
6952 }
6de9cd9a 6953 }
364667a1 6954
5d81ddd0 6955 if (code->expr1)
364667a1 6956 {
5d81ddd0
TB
6957 tree cond;
6958
63ee5404 6959 cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node, stat,
5d81ddd0
TB
6960 build_int_cst (TREE_TYPE (stat), 0));
6961 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
ed9c79e1 6962 gfc_unlikely (cond, PRED_FORTRAN_FAIL_ALLOC),
5d81ddd0
TB
6963 build1_v (GOTO_EXPR, label_errmsg),
6964 build_empty_stmt (input_location));
6965 gfc_add_expr_to_block (&se.pre, tmp);
364667a1
SK
6966 }
6967
6de9cd9a
DN
6968 tmp = gfc_finish_block (&se.pre);
6969 gfc_add_expr_to_block (&block, tmp);
0d87fa8c 6970 gfc_free_expr (expr);
364667a1
SK
6971 }
6972
a513927a 6973 if (code->expr1)
364667a1 6974 {
5d81ddd0
TB
6975 tmp = build1_v (LABEL_EXPR, label_errmsg);
6976 gfc_add_expr_to_block (&block, tmp);
6de9cd9a
DN
6977 }
6978
5d81ddd0
TB
6979 /* Set ERRMSG - only needed if STAT is available. */
6980 if (code->expr1 && code->expr2)
3759634f 6981 {
3759634f 6982 const char *msg = "Attempt to deallocate an unallocated object";
5d81ddd0
TB
6983 stmtblock_t errmsg_block;
6984 tree errmsg_str, slen, dlen, cond;
3759634f 6985
5d81ddd0 6986 gfc_init_block (&errmsg_block);
3759634f 6987
5d81ddd0
TB
6988 errmsg_str = gfc_create_var (pchar_type_node, "ERRMSG");
6989 gfc_add_modify (&errmsg_block, errmsg_str,
3759634f
SK
6990 gfc_build_addr_expr (pchar_type_node,
6991 gfc_build_localized_cstring_const (msg)));
f622221a 6992 slen = build_int_cst (gfc_charlen_type_node, strlen (msg));
3759634f 6993 dlen = gfc_get_expr_charlen (code->expr2);
3759634f 6994
5d81ddd0
TB
6995 gfc_trans_string_copy (&errmsg_block, dlen, errmsg, code->expr2->ts.kind,
6996 slen, errmsg_str, gfc_default_character_kind);
6997 tmp = gfc_finish_block (&errmsg_block);
3759634f 6998
63ee5404 6999 cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node, stat,
5d81ddd0
TB
7000 build_int_cst (TREE_TYPE (stat), 0));
7001 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
ed9c79e1 7002 gfc_unlikely (cond, PRED_FORTRAN_FAIL_ALLOC), tmp,
5d81ddd0 7003 build_empty_stmt (input_location));
3759634f 7004
5d81ddd0
TB
7005 gfc_add_expr_to_block (&block, tmp);
7006 }
3759634f 7007
5d81ddd0
TB
7008 if (code->expr1 && TREE_USED (label_finish))
7009 {
7010 tmp = build1_v (LABEL_EXPR, label_finish);
3759634f
SK
7011 gfc_add_expr_to_block (&block, tmp);
7012 }
7013
5d81ddd0
TB
7014 /* Set STAT. */
7015 if (code->expr1)
7016 {
7017 gfc_init_se (&se, NULL);
7018 gfc_conv_expr_lhs (&se, code->expr1);
7019 tmp = convert (TREE_TYPE (se.expr), stat);
7020 gfc_add_modify (&block, se.expr, tmp);
7021 }
7022
6de9cd9a
DN
7023 return gfc_finish_block (&block);
7024}
7025
d2886bc7 7026#include "gt-fortran-trans-stmt.h"