OSDN Git Service

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