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