OSDN Git Service

2007-09-16 Paul Thomas <pault@gcc.gnu.org>
[pf3gnuchains/gcc-fork.git] / gcc / fortran / trans-array.c
1 /* Array translation routines
2    Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007
3    Free Software Foundation, Inc.
4    Contributed by Paul Brook <paul@nowt.org>
5    and Steven Bosscher <s.bosscher@student.tudelft.nl>
6
7 This file is part of GCC.
8
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 3, or (at your option) any later
12 version.
13
14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
17 for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3.  If not see
21 <http://www.gnu.org/licenses/>.  */
22
23 /* trans-array.c-- Various array related code, including scalarization,
24                    allocation, initialization and other support routines.  */
25
26 /* How the scalarizer works.
27    In gfortran, array expressions use the same core routines as scalar
28    expressions.
29    First, a Scalarization State (SS) chain is built.  This is done by walking
30    the expression tree, and building a linear list of the terms in the
31    expression.  As the tree is walked, scalar subexpressions are translated.
32
33    The scalarization parameters are stored in a gfc_loopinfo structure.
34    First the start and stride of each term is calculated by
35    gfc_conv_ss_startstride.  During this process the expressions for the array
36    descriptors and data pointers are also translated.
37
38    If the expression is an assignment, we must then resolve any dependencies.
39    In fortran all the rhs values of an assignment must be evaluated before
40    any assignments take place.  This can require a temporary array to store the
41    values.  We also require a temporary when we are passing array expressions
42    or vector subecripts as procedure parameters.
43
44    Array sections are passed without copying to a temporary.  These use the
45    scalarizer to determine the shape of the section.  The flag
46    loop->array_parameter tells the scalarizer that the actual values and loop
47    variables will not be required.
48
49    The function gfc_conv_loop_setup generates the scalarization setup code.
50    It determines the range of the scalarizing loop variables.  If a temporary
51    is required, this is created and initialized.  Code for scalar expressions
52    taken outside the loop is also generated at this time.  Next the offset and
53    scaling required to translate from loop variables to array indices for each
54    term is calculated.
55
56    A call to gfc_start_scalarized_body marks the start of the scalarized
57    expression.  This creates a scope and declares the loop variables.  Before
58    calling this gfc_make_ss_chain_used must be used to indicate which terms
59    will be used inside this loop.
60
61    The scalar gfc_conv_* functions are then used to build the main body of the
62    scalarization loop.  Scalarization loop variables and precalculated scalar
63    values are automatically substituted.  Note that gfc_advance_se_ss_chain
64    must be used, rather than changing the se->ss directly.
65
66    For assignment expressions requiring a temporary two sub loops are
67    generated.  The first stores the result of the expression in the temporary,
68    the second copies it to the result.  A call to
69    gfc_trans_scalarized_loop_boundary marks the end of the main loop code and
70    the start of the copying loop.  The temporary may be less than full rank.
71
72    Finally gfc_trans_scalarizing_loops is called to generate the implicit do
73    loops.  The loops are added to the pre chain of the loopinfo.  The post
74    chain may still contain cleanup code.
75
76    After the loop code has been added into its parent scope gfc_cleanup_loop
77    is called to free all the SS allocated by the scalarizer.  */
78
79 #include "config.h"
80 #include "system.h"
81 #include "coretypes.h"
82 #include "tree.h"
83 #include "tree-gimple.h"
84 #include "ggc.h"
85 #include "toplev.h"
86 #include "real.h"
87 #include "flags.h"
88 #include "gfortran.h"
89 #include "trans.h"
90 #include "trans-stmt.h"
91 #include "trans-types.h"
92 #include "trans-array.h"
93 #include "trans-const.h"
94 #include "dependency.h"
95
96 static gfc_ss *gfc_walk_subexpr (gfc_ss *, gfc_expr *);
97 static bool gfc_get_array_constructor_size (mpz_t *, gfc_constructor *);
98
99 /* The contents of this structure aren't actually used, just the address.  */
100 static gfc_ss gfc_ss_terminator_var;
101 gfc_ss * const gfc_ss_terminator = &gfc_ss_terminator_var;
102
103
104 static tree
105 gfc_array_dataptr_type (tree desc)
106 {
107   return (GFC_TYPE_ARRAY_DATAPTR_TYPE (TREE_TYPE (desc)));
108 }
109
110
111 /* Build expressions to access the members of an array descriptor.
112    It's surprisingly easy to mess up here, so never access
113    an array descriptor by "brute force", always use these
114    functions.  This also avoids problems if we change the format
115    of an array descriptor.
116
117    To understand these magic numbers, look at the comments
118    before gfc_build_array_type() in trans-types.c.
119
120    The code within these defines should be the only code which knows the format
121    of an array descriptor.
122
123    Any code just needing to read obtain the bounds of an array should use
124    gfc_conv_array_* rather than the following functions as these will return
125    know constant values, and work with arrays which do not have descriptors.
126
127    Don't forget to #undef these!  */
128
129 #define DATA_FIELD 0
130 #define OFFSET_FIELD 1
131 #define DTYPE_FIELD 2
132 #define DIMENSION_FIELD 3
133
134 #define STRIDE_SUBFIELD 0
135 #define LBOUND_SUBFIELD 1
136 #define UBOUND_SUBFIELD 2
137
138 /* This provides READ-ONLY access to the data field.  The field itself
139    doesn't have the proper type.  */
140
141 tree
142 gfc_conv_descriptor_data_get (tree desc)
143 {
144   tree field, type, t;
145
146   type = TREE_TYPE (desc);
147   gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
148
149   field = TYPE_FIELDS (type);
150   gcc_assert (DATA_FIELD == 0);
151
152   t = build3 (COMPONENT_REF, TREE_TYPE (field), desc, field, NULL_TREE);
153   t = fold_convert (GFC_TYPE_ARRAY_DATAPTR_TYPE (type), t);
154
155   return t;
156 }
157
158 /* This provides WRITE access to the data field.
159
160    TUPLES_P is true if we are generating tuples.
161    
162    This function gets called through the following macros:
163      gfc_conv_descriptor_data_set
164      gfc_conv_descriptor_data_set_tuples.  */
165
166 void
167 gfc_conv_descriptor_data_set_internal (stmtblock_t *block,
168                                        tree desc, tree value,
169                                        bool tuples_p)
170 {
171   tree field, type, t;
172
173   type = TREE_TYPE (desc);
174   gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
175
176   field = TYPE_FIELDS (type);
177   gcc_assert (DATA_FIELD == 0);
178
179   t = build3 (COMPONENT_REF, TREE_TYPE (field), desc, field, NULL_TREE);
180   gfc_add_modify (block, t, fold_convert (TREE_TYPE (field), value), tuples_p);
181 }
182
183
184 /* This provides address access to the data field.  This should only be
185    used by array allocation, passing this on to the runtime.  */
186
187 tree
188 gfc_conv_descriptor_data_addr (tree desc)
189 {
190   tree field, type, t;
191
192   type = TREE_TYPE (desc);
193   gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
194
195   field = TYPE_FIELDS (type);
196   gcc_assert (DATA_FIELD == 0);
197
198   t = build3 (COMPONENT_REF, TREE_TYPE (field), desc, field, NULL_TREE);
199   return build_fold_addr_expr (t);
200 }
201
202 tree
203 gfc_conv_descriptor_offset (tree desc)
204 {
205   tree type;
206   tree field;
207
208   type = TREE_TYPE (desc);
209   gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
210
211   field = gfc_advance_chain (TYPE_FIELDS (type), OFFSET_FIELD);
212   gcc_assert (field != NULL_TREE && TREE_TYPE (field) == gfc_array_index_type);
213
214   return build3 (COMPONENT_REF, TREE_TYPE (field), desc, field, NULL_TREE);
215 }
216
217 tree
218 gfc_conv_descriptor_dtype (tree desc)
219 {
220   tree field;
221   tree type;
222
223   type = TREE_TYPE (desc);
224   gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
225
226   field = gfc_advance_chain (TYPE_FIELDS (type), DTYPE_FIELD);
227   gcc_assert (field != NULL_TREE && TREE_TYPE (field) == gfc_array_index_type);
228
229   return build3 (COMPONENT_REF, TREE_TYPE (field), desc, field, NULL_TREE);
230 }
231
232 static tree
233 gfc_conv_descriptor_dimension (tree desc, tree dim)
234 {
235   tree field;
236   tree type;
237   tree tmp;
238
239   type = TREE_TYPE (desc);
240   gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
241
242   field = gfc_advance_chain (TYPE_FIELDS (type), DIMENSION_FIELD);
243   gcc_assert (field != NULL_TREE
244           && TREE_CODE (TREE_TYPE (field)) == ARRAY_TYPE
245           && TREE_CODE (TREE_TYPE (TREE_TYPE (field))) == RECORD_TYPE);
246
247   tmp = build3 (COMPONENT_REF, TREE_TYPE (field), desc, field, NULL_TREE);
248   tmp = gfc_build_array_ref (tmp, dim, NULL);
249   return tmp;
250 }
251
252 tree
253 gfc_conv_descriptor_stride (tree desc, tree dim)
254 {
255   tree tmp;
256   tree field;
257
258   tmp = gfc_conv_descriptor_dimension (desc, dim);
259   field = TYPE_FIELDS (TREE_TYPE (tmp));
260   field = gfc_advance_chain (field, STRIDE_SUBFIELD);
261   gcc_assert (field != NULL_TREE && TREE_TYPE (field) == gfc_array_index_type);
262
263   tmp = build3 (COMPONENT_REF, TREE_TYPE (field), tmp, field, NULL_TREE);
264   return tmp;
265 }
266
267 tree
268 gfc_conv_descriptor_lbound (tree desc, tree dim)
269 {
270   tree tmp;
271   tree field;
272
273   tmp = gfc_conv_descriptor_dimension (desc, dim);
274   field = TYPE_FIELDS (TREE_TYPE (tmp));
275   field = gfc_advance_chain (field, LBOUND_SUBFIELD);
276   gcc_assert (field != NULL_TREE && TREE_TYPE (field) == gfc_array_index_type);
277
278   tmp = build3 (COMPONENT_REF, TREE_TYPE (field), tmp, field, NULL_TREE);
279   return tmp;
280 }
281
282 tree
283 gfc_conv_descriptor_ubound (tree desc, tree dim)
284 {
285   tree tmp;
286   tree field;
287
288   tmp = gfc_conv_descriptor_dimension (desc, dim);
289   field = TYPE_FIELDS (TREE_TYPE (tmp));
290   field = gfc_advance_chain (field, UBOUND_SUBFIELD);
291   gcc_assert (field != NULL_TREE && TREE_TYPE (field) == gfc_array_index_type);
292
293   tmp = build3 (COMPONENT_REF, TREE_TYPE (field), tmp, field, NULL_TREE);
294   return tmp;
295 }
296
297
298 /* Build a null array descriptor constructor.  */
299
300 tree
301 gfc_build_null_descriptor (tree type)
302 {
303   tree field;
304   tree tmp;
305
306   gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
307   gcc_assert (DATA_FIELD == 0);
308   field = TYPE_FIELDS (type);
309
310   /* Set a NULL data pointer.  */
311   tmp = build_constructor_single (type, field, null_pointer_node);
312   TREE_CONSTANT (tmp) = 1;
313   TREE_INVARIANT (tmp) = 1;
314   /* All other fields are ignored.  */
315
316   return tmp;
317 }
318
319
320 /* Cleanup those #defines.  */
321
322 #undef DATA_FIELD
323 #undef OFFSET_FIELD
324 #undef DTYPE_FIELD
325 #undef DIMENSION_FIELD
326 #undef STRIDE_SUBFIELD
327 #undef LBOUND_SUBFIELD
328 #undef UBOUND_SUBFIELD
329
330
331 /* Mark a SS chain as used.  Flags specifies in which loops the SS is used.
332    flags & 1 = Main loop body.
333    flags & 2 = temp copy loop.  */
334
335 void
336 gfc_mark_ss_chain_used (gfc_ss * ss, unsigned flags)
337 {
338   for (; ss != gfc_ss_terminator; ss = ss->next)
339     ss->useflags = flags;
340 }
341
342 static void gfc_free_ss (gfc_ss *);
343
344
345 /* Free a gfc_ss chain.  */
346
347 static void
348 gfc_free_ss_chain (gfc_ss * ss)
349 {
350   gfc_ss *next;
351
352   while (ss != gfc_ss_terminator)
353     {
354       gcc_assert (ss != NULL);
355       next = ss->next;
356       gfc_free_ss (ss);
357       ss = next;
358     }
359 }
360
361
362 /* Free a SS.  */
363
364 static void
365 gfc_free_ss (gfc_ss * ss)
366 {
367   int n;
368
369   switch (ss->type)
370     {
371     case GFC_SS_SECTION:
372       for (n = 0; n < GFC_MAX_DIMENSIONS; n++)
373         {
374           if (ss->data.info.subscript[n])
375             gfc_free_ss_chain (ss->data.info.subscript[n]);
376         }
377       break;
378
379     default:
380       break;
381     }
382
383   gfc_free (ss);
384 }
385
386
387 /* Free all the SS associated with a loop.  */
388
389 void
390 gfc_cleanup_loop (gfc_loopinfo * loop)
391 {
392   gfc_ss *ss;
393   gfc_ss *next;
394
395   ss = loop->ss;
396   while (ss != gfc_ss_terminator)
397     {
398       gcc_assert (ss != NULL);
399       next = ss->loop_chain;
400       gfc_free_ss (ss);
401       ss = next;
402     }
403 }
404
405
406 /* Associate a SS chain with a loop.  */
407
408 void
409 gfc_add_ss_to_loop (gfc_loopinfo * loop, gfc_ss * head)
410 {
411   gfc_ss *ss;
412
413   if (head == gfc_ss_terminator)
414     return;
415
416   ss = head;
417   for (; ss && ss != gfc_ss_terminator; ss = ss->next)
418     {
419       if (ss->next == gfc_ss_terminator)
420         ss->loop_chain = loop->ss;
421       else
422         ss->loop_chain = ss->next;
423     }
424   gcc_assert (ss == gfc_ss_terminator);
425   loop->ss = head;
426 }
427
428
429 /* Generate an initializer for a static pointer or allocatable array.  */
430
431 void
432 gfc_trans_static_array_pointer (gfc_symbol * sym)
433 {
434   tree type;
435
436   gcc_assert (TREE_STATIC (sym->backend_decl));
437   /* Just zero the data member.  */
438   type = TREE_TYPE (sym->backend_decl);
439   DECL_INITIAL (sym->backend_decl) = gfc_build_null_descriptor (type);
440 }
441
442
443 /* If the bounds of SE's loop have not yet been set, see if they can be
444    determined from array spec AS, which is the array spec of a called
445    function.  MAPPING maps the callee's dummy arguments to the values
446    that the caller is passing.  Add any initialization and finalization
447    code to SE.  */
448
449 void
450 gfc_set_loop_bounds_from_array_spec (gfc_interface_mapping * mapping,
451                                      gfc_se * se, gfc_array_spec * as)
452 {
453   int n, dim;
454   gfc_se tmpse;
455   tree lower;
456   tree upper;
457   tree tmp;
458
459   if (as && as->type == AS_EXPLICIT)
460     for (dim = 0; dim < se->loop->dimen; dim++)
461       {
462         n = se->loop->order[dim];
463         if (se->loop->to[n] == NULL_TREE)
464           {
465             /* Evaluate the lower bound.  */
466             gfc_init_se (&tmpse, NULL);
467             gfc_apply_interface_mapping (mapping, &tmpse, as->lower[dim]);
468             gfc_add_block_to_block (&se->pre, &tmpse.pre);
469             gfc_add_block_to_block (&se->post, &tmpse.post);
470             lower = tmpse.expr;
471
472             /* ...and the upper bound.  */
473             gfc_init_se (&tmpse, NULL);
474             gfc_apply_interface_mapping (mapping, &tmpse, as->upper[dim]);
475             gfc_add_block_to_block (&se->pre, &tmpse.pre);
476             gfc_add_block_to_block (&se->post, &tmpse.post);
477             upper = tmpse.expr;
478
479             /* Set the upper bound of the loop to UPPER - LOWER.  */
480             tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type, upper, lower);
481             tmp = gfc_evaluate_now (tmp, &se->pre);
482             se->loop->to[n] = tmp;
483           }
484       }
485 }
486
487
488 /* Generate code to allocate an array temporary, or create a variable to
489    hold the data.  If size is NULL, zero the descriptor so that the
490    callee will allocate the array.  If DEALLOC is true, also generate code to
491    free the array afterwards.
492
493    Initialization code is added to PRE and finalization code to POST.
494    DYNAMIC is true if the caller may want to extend the array later
495    using realloc.  This prevents us from putting the array on the stack.  */
496
497 static void
498 gfc_trans_allocate_array_storage (stmtblock_t * pre, stmtblock_t * post,
499                                   gfc_ss_info * info, tree size, tree nelem,
500                                   bool dynamic, bool dealloc)
501 {
502   tree tmp;
503   tree desc;
504   bool onstack;
505
506   desc = info->descriptor;
507   info->offset = gfc_index_zero_node;
508   if (size == NULL_TREE || integer_zerop (size))
509     {
510       /* A callee allocated array.  */
511       gfc_conv_descriptor_data_set (pre, desc, null_pointer_node);
512       onstack = FALSE;
513     }
514   else
515     {
516       /* Allocate the temporary.  */
517       onstack = !dynamic && gfc_can_put_var_on_stack (size);
518
519       if (onstack)
520         {
521           /* Make a temporary variable to hold the data.  */
522           tmp = fold_build2 (MINUS_EXPR, TREE_TYPE (nelem), nelem,
523                              gfc_index_one_node);
524           tmp = build_range_type (gfc_array_index_type, gfc_index_zero_node,
525                                   tmp);
526           tmp = build_array_type (gfc_get_element_type (TREE_TYPE (desc)),
527                                   tmp);
528           tmp = gfc_create_var (tmp, "A");
529           tmp = build_fold_addr_expr (tmp);
530           gfc_conv_descriptor_data_set (pre, desc, tmp);
531         }
532       else
533         {
534           /* Allocate memory to hold the data.  */
535           tmp = gfc_call_malloc (pre, NULL, size);
536           tmp = gfc_evaluate_now (tmp, pre);
537           gfc_conv_descriptor_data_set (pre, desc, tmp);
538         }
539     }
540   info->data = gfc_conv_descriptor_data_get (desc);
541
542   /* The offset is zero because we create temporaries with a zero
543      lower bound.  */
544   tmp = gfc_conv_descriptor_offset (desc);
545   gfc_add_modify_expr (pre, tmp, gfc_index_zero_node);
546
547   if (dealloc && !onstack)
548     {
549       /* Free the temporary.  */
550       tmp = gfc_conv_descriptor_data_get (desc);
551       tmp = gfc_call_free (fold_convert (pvoid_type_node, tmp));
552       gfc_add_expr_to_block (post, tmp);
553     }
554 }
555
556
557 /* Generate code to create and initialize the descriptor for a temporary
558    array.  This is used for both temporaries needed by the scalarizer, and
559    functions returning arrays.  Adjusts the loop variables to be
560    zero-based, and calculates the loop bounds for callee allocated arrays.
561    Allocate the array unless it's callee allocated (we have a callee
562    allocated array if 'callee_alloc' is true, or if loop->to[n] is
563    NULL_TREE for any n).  Also fills in the descriptor, data and offset
564    fields of info if known.  Returns the size of the array, or NULL for a
565    callee allocated array.
566
567    PRE, POST, DYNAMIC and DEALLOC are as for gfc_trans_allocate_array_storage.
568  */
569
570 tree
571 gfc_trans_create_temp_array (stmtblock_t * pre, stmtblock_t * post,
572                              gfc_loopinfo * loop, gfc_ss_info * info,
573                              tree eltype, bool dynamic, bool dealloc,
574                              bool callee_alloc)
575 {
576   tree type;
577   tree desc;
578   tree tmp;
579   tree size;
580   tree nelem;
581   tree cond;
582   tree or_expr;
583   int n;
584   int dim;
585
586   gcc_assert (info->dimen > 0);
587   /* Set the lower bound to zero.  */
588   for (dim = 0; dim < info->dimen; dim++)
589     {
590       n = loop->order[dim];
591       if (n < loop->temp_dim)
592         gcc_assert (integer_zerop (loop->from[n]));
593       else
594         {
595           /* Callee allocated arrays may not have a known bound yet.  */
596           if (loop->to[n])
597               loop->to[n] = fold_build2 (MINUS_EXPR, gfc_array_index_type,
598                                          loop->to[n], loop->from[n]);
599           loop->from[n] = gfc_index_zero_node;
600         }
601
602       info->delta[dim] = gfc_index_zero_node;
603       info->start[dim] = gfc_index_zero_node;
604       info->end[dim] = gfc_index_zero_node;
605       info->stride[dim] = gfc_index_one_node;
606       info->dim[dim] = dim;
607     }
608
609   /* Initialize the descriptor.  */
610   type =
611     gfc_get_array_type_bounds (eltype, info->dimen, loop->from, loop->to, 1);
612   desc = gfc_create_var (type, "atmp");
613   GFC_DECL_PACKED_ARRAY (desc) = 1;
614
615   info->descriptor = desc;
616   size = gfc_index_one_node;
617
618   /* Fill in the array dtype.  */
619   tmp = gfc_conv_descriptor_dtype (desc);
620   gfc_add_modify_expr (pre, tmp, gfc_get_dtype (TREE_TYPE (desc)));
621
622   /*
623      Fill in the bounds and stride.  This is a packed array, so:
624
625      size = 1;
626      for (n = 0; n < rank; n++)
627        {
628          stride[n] = size
629          delta = ubound[n] + 1 - lbound[n];
630          size = size * delta;
631        }
632      size = size * sizeof(element);
633   */
634
635   or_expr = NULL_TREE;
636
637   for (n = 0; n < info->dimen; n++)
638     {
639       if (loop->to[n] == NULL_TREE)
640         {
641           /* For a callee allocated array express the loop bounds in terms
642              of the descriptor fields.  */
643           tmp = build2 (MINUS_EXPR, gfc_array_index_type,
644                         gfc_conv_descriptor_ubound (desc, gfc_rank_cst[n]),
645                         gfc_conv_descriptor_lbound (desc, gfc_rank_cst[n]));
646           loop->to[n] = tmp;
647           size = NULL_TREE;
648           continue;
649         }
650         
651       /* Store the stride and bound components in the descriptor.  */
652       tmp = gfc_conv_descriptor_stride (desc, gfc_rank_cst[n]);
653       gfc_add_modify_expr (pre, tmp, size);
654
655       tmp = gfc_conv_descriptor_lbound (desc, gfc_rank_cst[n]);
656       gfc_add_modify_expr (pre, tmp, gfc_index_zero_node);
657
658       tmp = gfc_conv_descriptor_ubound (desc, gfc_rank_cst[n]);
659       gfc_add_modify_expr (pre, tmp, loop->to[n]);
660
661       tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
662                          loop->to[n], gfc_index_one_node);
663
664       /* Check whether the size for this dimension is negative.  */
665       cond = fold_build2 (LE_EXPR, boolean_type_node, tmp,
666                           gfc_index_zero_node);
667       cond = gfc_evaluate_now (cond, pre);
668
669       if (n == 0)
670         or_expr = cond;
671       else
672         or_expr = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, or_expr, cond);
673
674       size = fold_build2 (MULT_EXPR, gfc_array_index_type, size, tmp);
675       size = gfc_evaluate_now (size, pre);
676     }
677
678   /* Get the size of the array.  */
679
680   if (size && !callee_alloc)
681     {
682       /* If or_expr is true, then the extent in at least one
683          dimension is zero and the size is set to zero.  */
684       size = fold_build3 (COND_EXPR, gfc_array_index_type,
685                           or_expr, gfc_index_zero_node, size);
686
687       nelem = size;
688       size = fold_build2 (MULT_EXPR, gfc_array_index_type, size,
689                 fold_convert (gfc_array_index_type,
690                               TYPE_SIZE_UNIT (gfc_get_element_type (type))));
691     }
692   else
693     {
694       nelem = size;
695       size = NULL_TREE;
696     }
697
698   gfc_trans_allocate_array_storage (pre, post, info, size, nelem, dynamic,
699                                     dealloc);
700
701   if (info->dimen > loop->temp_dim)
702     loop->temp_dim = info->dimen;
703
704   return size;
705 }
706
707
708 /* Generate code to transpose array EXPR by creating a new descriptor
709    in which the dimension specifications have been reversed.  */
710
711 void
712 gfc_conv_array_transpose (gfc_se * se, gfc_expr * expr)
713 {
714   tree dest, src, dest_index, src_index;
715   gfc_loopinfo *loop;
716   gfc_ss_info *dest_info, *src_info;
717   gfc_ss *dest_ss, *src_ss;
718   gfc_se src_se;
719   int n;
720
721   loop = se->loop;
722
723   src_ss = gfc_walk_expr (expr);
724   dest_ss = se->ss;
725
726   src_info = &src_ss->data.info;
727   dest_info = &dest_ss->data.info;
728   gcc_assert (dest_info->dimen == 2);
729   gcc_assert (src_info->dimen == 2);
730
731   /* Get a descriptor for EXPR.  */
732   gfc_init_se (&src_se, NULL);
733   gfc_conv_expr_descriptor (&src_se, expr, src_ss);
734   gfc_add_block_to_block (&se->pre, &src_se.pre);
735   gfc_add_block_to_block (&se->post, &src_se.post);
736   src = src_se.expr;
737
738   /* Allocate a new descriptor for the return value.  */
739   dest = gfc_create_var (TREE_TYPE (src), "atmp");
740   dest_info->descriptor = dest;
741   se->expr = dest;
742
743   /* Copy across the dtype field.  */
744   gfc_add_modify_expr (&se->pre,
745                        gfc_conv_descriptor_dtype (dest),
746                        gfc_conv_descriptor_dtype (src));
747
748   /* Copy the dimension information, renumbering dimension 1 to 0 and
749      0 to 1.  */
750   for (n = 0; n < 2; n++)
751     {
752       dest_info->delta[n] = gfc_index_zero_node;
753       dest_info->start[n] = gfc_index_zero_node;
754       dest_info->end[n] = gfc_index_zero_node;
755       dest_info->stride[n] = gfc_index_one_node;
756       dest_info->dim[n] = n;
757
758       dest_index = gfc_rank_cst[n];
759       src_index = gfc_rank_cst[1 - n];
760
761       gfc_add_modify_expr (&se->pre,
762                            gfc_conv_descriptor_stride (dest, dest_index),
763                            gfc_conv_descriptor_stride (src, src_index));
764
765       gfc_add_modify_expr (&se->pre,
766                            gfc_conv_descriptor_lbound (dest, dest_index),
767                            gfc_conv_descriptor_lbound (src, src_index));
768
769       gfc_add_modify_expr (&se->pre,
770                            gfc_conv_descriptor_ubound (dest, dest_index),
771                            gfc_conv_descriptor_ubound (src, src_index));
772
773       if (!loop->to[n])
774         {
775           gcc_assert (integer_zerop (loop->from[n]));
776           loop->to[n] = build2 (MINUS_EXPR, gfc_array_index_type,
777                                 gfc_conv_descriptor_ubound (dest, dest_index),
778                                 gfc_conv_descriptor_lbound (dest, dest_index));
779         }
780     }
781
782   /* Copy the data pointer.  */
783   dest_info->data = gfc_conv_descriptor_data_get (src);
784   gfc_conv_descriptor_data_set (&se->pre, dest, dest_info->data);
785
786   /* Copy the offset.  This is not changed by transposition; the top-left
787      element is still at the same offset as before, except where the loop
788      starts at zero.  */
789   if (!integer_zerop (loop->from[0]))
790     dest_info->offset = gfc_conv_descriptor_offset (src);
791   else
792     dest_info->offset = gfc_index_zero_node;
793
794   gfc_add_modify_expr (&se->pre,
795                        gfc_conv_descriptor_offset (dest),
796                        dest_info->offset);
797           
798   if (dest_info->dimen > loop->temp_dim)
799     loop->temp_dim = dest_info->dimen;
800 }
801
802
803 /* Return the number of iterations in a loop that starts at START,
804    ends at END, and has step STEP.  */
805
806 static tree
807 gfc_get_iteration_count (tree start, tree end, tree step)
808 {
809   tree tmp;
810   tree type;
811
812   type = TREE_TYPE (step);
813   tmp = fold_build2 (MINUS_EXPR, type, end, start);
814   tmp = fold_build2 (FLOOR_DIV_EXPR, type, tmp, step);
815   tmp = fold_build2 (PLUS_EXPR, type, tmp, build_int_cst (type, 1));
816   tmp = fold_build2 (MAX_EXPR, type, tmp, build_int_cst (type, 0));
817   return fold_convert (gfc_array_index_type, tmp);
818 }
819
820
821 /* Extend the data in array DESC by EXTRA elements.  */
822
823 static void
824 gfc_grow_array (stmtblock_t * pblock, tree desc, tree extra)
825 {
826   tree arg0, arg1;
827   tree tmp;
828   tree size;
829   tree ubound;
830
831   if (integer_zerop (extra))
832     return;
833
834   ubound = gfc_conv_descriptor_ubound (desc, gfc_rank_cst[0]);
835
836   /* Add EXTRA to the upper bound.  */
837   tmp = build2 (PLUS_EXPR, gfc_array_index_type, ubound, extra);
838   gfc_add_modify_expr (pblock, ubound, tmp);
839
840   /* Get the value of the current data pointer.  */
841   arg0 = gfc_conv_descriptor_data_get (desc);
842
843   /* Calculate the new array size.  */
844   size = TYPE_SIZE_UNIT (gfc_get_element_type (TREE_TYPE (desc)));
845   tmp = build2 (PLUS_EXPR, gfc_array_index_type, ubound, gfc_index_one_node);
846   arg1 = build2 (MULT_EXPR, size_type_node, fold_convert (size_type_node, tmp),
847                  fold_convert (size_type_node, size));
848
849   /* Call the realloc() function.  */
850   tmp = gfc_call_realloc (pblock, arg0, arg1);
851   gfc_conv_descriptor_data_set (pblock, desc, tmp);
852 }
853
854
855 /* Return true if the bounds of iterator I can only be determined
856    at run time.  */
857
858 static inline bool
859 gfc_iterator_has_dynamic_bounds (gfc_iterator * i)
860 {
861   return (i->start->expr_type != EXPR_CONSTANT
862           || i->end->expr_type != EXPR_CONSTANT
863           || i->step->expr_type != EXPR_CONSTANT);
864 }
865
866
867 /* Split the size of constructor element EXPR into the sum of two terms,
868    one of which can be determined at compile time and one of which must
869    be calculated at run time.  Set *SIZE to the former and return true
870    if the latter might be nonzero.  */
871
872 static bool
873 gfc_get_array_constructor_element_size (mpz_t * size, gfc_expr * expr)
874 {
875   if (expr->expr_type == EXPR_ARRAY)
876     return gfc_get_array_constructor_size (size, expr->value.constructor);
877   else if (expr->rank > 0)
878     {
879       /* Calculate everything at run time.  */
880       mpz_set_ui (*size, 0);
881       return true;
882     }
883   else
884     {
885       /* A single element.  */
886       mpz_set_ui (*size, 1);
887       return false;
888     }
889 }
890
891
892 /* Like gfc_get_array_constructor_element_size, but applied to the whole
893    of array constructor C.  */
894
895 static bool
896 gfc_get_array_constructor_size (mpz_t * size, gfc_constructor * c)
897 {
898   gfc_iterator *i;
899   mpz_t val;
900   mpz_t len;
901   bool dynamic;
902
903   mpz_set_ui (*size, 0);
904   mpz_init (len);
905   mpz_init (val);
906
907   dynamic = false;
908   for (; c; c = c->next)
909     {
910       i = c->iterator;
911       if (i && gfc_iterator_has_dynamic_bounds (i))
912         dynamic = true;
913       else
914         {
915           dynamic |= gfc_get_array_constructor_element_size (&len, c->expr);
916           if (i)
917             {
918               /* Multiply the static part of the element size by the
919                  number of iterations.  */
920               mpz_sub (val, i->end->value.integer, i->start->value.integer);
921               mpz_fdiv_q (val, val, i->step->value.integer);
922               mpz_add_ui (val, val, 1);
923               if (mpz_sgn (val) > 0)
924                 mpz_mul (len, len, val);
925               else
926                 mpz_set_ui (len, 0);
927             }
928           mpz_add (*size, *size, len);
929         }
930     }
931   mpz_clear (len);
932   mpz_clear (val);
933   return dynamic;
934 }
935
936
937 /* Make sure offset is a variable.  */
938
939 static void
940 gfc_put_offset_into_var (stmtblock_t * pblock, tree * poffset,
941                          tree * offsetvar)
942 {
943   /* We should have already created the offset variable.  We cannot
944      create it here because we may be in an inner scope.  */
945   gcc_assert (*offsetvar != NULL_TREE);
946   gfc_add_modify_expr (pblock, *offsetvar, *poffset);
947   *poffset = *offsetvar;
948   TREE_USED (*offsetvar) = 1;
949 }
950
951
952 /* Assign an element of an array constructor.  */
953
954 static void
955 gfc_trans_array_ctor_element (stmtblock_t * pblock, tree desc,
956                               tree offset, gfc_se * se, gfc_expr * expr)
957 {
958   tree tmp;
959
960   gfc_conv_expr (se, expr);
961
962   /* Store the value.  */
963   tmp = build_fold_indirect_ref (gfc_conv_descriptor_data_get (desc));
964   tmp = gfc_build_array_ref (tmp, offset, NULL);
965   if (expr->ts.type == BT_CHARACTER)
966     {
967       gfc_conv_string_parameter (se);
968       if (POINTER_TYPE_P (TREE_TYPE (tmp)))
969         {
970           /* The temporary is an array of pointers.  */
971           se->expr = fold_convert (TREE_TYPE (tmp), se->expr);
972           gfc_add_modify_expr (&se->pre, tmp, se->expr);
973         }
974       else
975         {
976           /* The temporary is an array of string values.  */
977           tmp = gfc_build_addr_expr (pchar_type_node, tmp);
978           /* We know the temporary and the value will be the same length,
979              so can use memcpy.  */
980           tmp = build_call_expr (built_in_decls[BUILT_IN_MEMCPY], 3,
981                                  tmp, se->expr, se->string_length);
982           gfc_add_expr_to_block (&se->pre, tmp);
983         }
984     }
985   else
986     {
987       /* TODO: Should the frontend already have done this conversion?  */
988       se->expr = fold_convert (TREE_TYPE (tmp), se->expr);
989       gfc_add_modify_expr (&se->pre, tmp, se->expr);
990     }
991
992   gfc_add_block_to_block (pblock, &se->pre);
993   gfc_add_block_to_block (pblock, &se->post);
994 }
995
996
997 /* Add the contents of an array to the constructor.  DYNAMIC is as for
998    gfc_trans_array_constructor_value.  */
999
1000 static void
1001 gfc_trans_array_constructor_subarray (stmtblock_t * pblock,
1002                                       tree type ATTRIBUTE_UNUSED,
1003                                       tree desc, gfc_expr * expr,
1004                                       tree * poffset, tree * offsetvar,
1005                                       bool dynamic)
1006 {
1007   gfc_se se;
1008   gfc_ss *ss;
1009   gfc_loopinfo loop;
1010   stmtblock_t body;
1011   tree tmp;
1012   tree size;
1013   int n;
1014
1015   /* We need this to be a variable so we can increment it.  */
1016   gfc_put_offset_into_var (pblock, poffset, offsetvar);
1017
1018   gfc_init_se (&se, NULL);
1019
1020   /* Walk the array expression.  */
1021   ss = gfc_walk_expr (expr);
1022   gcc_assert (ss != gfc_ss_terminator);
1023
1024   /* Initialize the scalarizer.  */
1025   gfc_init_loopinfo (&loop);
1026   gfc_add_ss_to_loop (&loop, ss);
1027
1028   /* Initialize the loop.  */
1029   gfc_conv_ss_startstride (&loop);
1030   gfc_conv_loop_setup (&loop);
1031
1032   /* Make sure the constructed array has room for the new data.  */
1033   if (dynamic)
1034     {
1035       /* Set SIZE to the total number of elements in the subarray.  */
1036       size = gfc_index_one_node;
1037       for (n = 0; n < loop.dimen; n++)
1038         {
1039           tmp = gfc_get_iteration_count (loop.from[n], loop.to[n],
1040                                          gfc_index_one_node);
1041           size = fold_build2 (MULT_EXPR, gfc_array_index_type, size, tmp);
1042         }
1043
1044       /* Grow the constructed array by SIZE elements.  */
1045       gfc_grow_array (&loop.pre, desc, size);
1046     }
1047
1048   /* Make the loop body.  */
1049   gfc_mark_ss_chain_used (ss, 1);
1050   gfc_start_scalarized_body (&loop, &body);
1051   gfc_copy_loopinfo_to_se (&se, &loop);
1052   se.ss = ss;
1053
1054   gfc_trans_array_ctor_element (&body, desc, *poffset, &se, expr);
1055   gcc_assert (se.ss == gfc_ss_terminator);
1056
1057   /* Increment the offset.  */
1058   tmp = build2 (PLUS_EXPR, gfc_array_index_type, *poffset, gfc_index_one_node);
1059   gfc_add_modify_expr (&body, *poffset, tmp);
1060
1061   /* Finish the loop.  */
1062   gfc_trans_scalarizing_loops (&loop, &body);
1063   gfc_add_block_to_block (&loop.pre, &loop.post);
1064   tmp = gfc_finish_block (&loop.pre);
1065   gfc_add_expr_to_block (pblock, tmp);
1066
1067   gfc_cleanup_loop (&loop);
1068 }
1069
1070
1071 /* Assign the values to the elements of an array constructor.  DYNAMIC
1072    is true if descriptor DESC only contains enough data for the static
1073    size calculated by gfc_get_array_constructor_size.  When true, memory
1074    for the dynamic parts must be allocated using realloc.  */
1075
1076 static void
1077 gfc_trans_array_constructor_value (stmtblock_t * pblock, tree type,
1078                                    tree desc, gfc_constructor * c,
1079                                    tree * poffset, tree * offsetvar,
1080                                    bool dynamic)
1081 {
1082   tree tmp;
1083   stmtblock_t body;
1084   gfc_se se;
1085   mpz_t size;
1086
1087   mpz_init (size);
1088   for (; c; c = c->next)
1089     {
1090       /* If this is an iterator or an array, the offset must be a variable.  */
1091       if ((c->iterator || c->expr->rank > 0) && INTEGER_CST_P (*poffset))
1092         gfc_put_offset_into_var (pblock, poffset, offsetvar);
1093
1094       gfc_start_block (&body);
1095
1096       if (c->expr->expr_type == EXPR_ARRAY)
1097         {
1098           /* Array constructors can be nested.  */
1099           gfc_trans_array_constructor_value (&body, type, desc,
1100                                              c->expr->value.constructor,
1101                                              poffset, offsetvar, dynamic);
1102         }
1103       else if (c->expr->rank > 0)
1104         {
1105           gfc_trans_array_constructor_subarray (&body, type, desc, c->expr,
1106                                                 poffset, offsetvar, dynamic);
1107         }
1108       else
1109         {
1110           /* This code really upsets the gimplifier so don't bother for now.  */
1111           gfc_constructor *p;
1112           HOST_WIDE_INT n;
1113           HOST_WIDE_INT size;
1114
1115           p = c;
1116           n = 0;
1117           while (p && !(p->iterator || p->expr->expr_type != EXPR_CONSTANT))
1118             {
1119               p = p->next;
1120               n++;
1121             }
1122           if (n < 4)
1123             {
1124               /* Scalar values.  */
1125               gfc_init_se (&se, NULL);
1126               gfc_trans_array_ctor_element (&body, desc, *poffset,
1127                                             &se, c->expr);
1128
1129               *poffset = fold_build2 (PLUS_EXPR, gfc_array_index_type,
1130                                       *poffset, gfc_index_one_node);
1131             }
1132           else
1133             {
1134               /* Collect multiple scalar constants into a constructor.  */
1135               tree list;
1136               tree init;
1137               tree bound;
1138               tree tmptype;
1139
1140               p = c;
1141               list = NULL_TREE;
1142               /* Count the number of consecutive scalar constants.  */
1143               while (p && !(p->iterator
1144                             || p->expr->expr_type != EXPR_CONSTANT))
1145                 {
1146                   gfc_init_se (&se, NULL);
1147                   gfc_conv_constant (&se, p->expr);
1148                   if (p->expr->ts.type == BT_CHARACTER
1149                       && POINTER_TYPE_P (type))
1150                     {
1151                       /* For constant character array constructors we build
1152                          an array of pointers.  */
1153                       se.expr = gfc_build_addr_expr (pchar_type_node,
1154                                                      se.expr);
1155                     }
1156                     
1157                   list = tree_cons (NULL_TREE, se.expr, list);
1158                   c = p;
1159                   p = p->next;
1160                 }
1161
1162               bound = build_int_cst (NULL_TREE, n - 1);
1163               /* Create an array type to hold them.  */
1164               tmptype = build_range_type (gfc_array_index_type,
1165                                           gfc_index_zero_node, bound);
1166               tmptype = build_array_type (type, tmptype);
1167
1168               init = build_constructor_from_list (tmptype, nreverse (list));
1169               TREE_CONSTANT (init) = 1;
1170               TREE_INVARIANT (init) = 1;
1171               TREE_STATIC (init) = 1;
1172               /* Create a static variable to hold the data.  */
1173               tmp = gfc_create_var (tmptype, "data");
1174               TREE_STATIC (tmp) = 1;
1175               TREE_CONSTANT (tmp) = 1;
1176               TREE_INVARIANT (tmp) = 1;
1177               TREE_READONLY (tmp) = 1;
1178               DECL_INITIAL (tmp) = init;
1179               init = tmp;
1180
1181               /* Use BUILTIN_MEMCPY to assign the values.  */
1182               tmp = gfc_conv_descriptor_data_get (desc);
1183               tmp = build_fold_indirect_ref (tmp);
1184               tmp = gfc_build_array_ref (tmp, *poffset, NULL);
1185               tmp = build_fold_addr_expr (tmp);
1186               init = build_fold_addr_expr (init);
1187
1188               size = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (type));
1189               bound = build_int_cst (NULL_TREE, n * size);
1190               tmp = build_call_expr (built_in_decls[BUILT_IN_MEMCPY], 3,
1191                                      tmp, init, bound);
1192               gfc_add_expr_to_block (&body, tmp);
1193
1194               *poffset = fold_build2 (PLUS_EXPR, gfc_array_index_type,
1195                                       *poffset,
1196                                       build_int_cst (gfc_array_index_type, n));
1197             }
1198           if (!INTEGER_CST_P (*poffset))
1199             {
1200               gfc_add_modify_expr (&body, *offsetvar, *poffset);
1201               *poffset = *offsetvar;
1202             }
1203         }
1204
1205       /* The frontend should already have done any expansions possible
1206          at compile-time.  */
1207       if (!c->iterator)
1208         {
1209           /* Pass the code as is.  */
1210           tmp = gfc_finish_block (&body);
1211           gfc_add_expr_to_block (pblock, tmp);
1212         }
1213       else
1214         {
1215           /* Build the implied do-loop.  */
1216           tree cond;
1217           tree end;
1218           tree step;
1219           tree loopvar;
1220           tree exit_label;
1221           tree loopbody;
1222           tree tmp2;
1223           tree tmp_loopvar;
1224
1225           loopbody = gfc_finish_block (&body);
1226
1227           gfc_init_se (&se, NULL);
1228           gfc_conv_expr (&se, c->iterator->var);
1229           gfc_add_block_to_block (pblock, &se.pre);
1230           loopvar = se.expr;
1231
1232           /* Make a temporary, store the current value in that
1233              and return it, once the loop is done.  */
1234           tmp_loopvar = gfc_create_var (TREE_TYPE (loopvar), "loopvar");
1235           gfc_add_modify_expr (pblock, tmp_loopvar, loopvar);
1236
1237           /* Initialize the loop.  */
1238           gfc_init_se (&se, NULL);
1239           gfc_conv_expr_val (&se, c->iterator->start);
1240           gfc_add_block_to_block (pblock, &se.pre);
1241           gfc_add_modify_expr (pblock, loopvar, se.expr);
1242
1243           gfc_init_se (&se, NULL);
1244           gfc_conv_expr_val (&se, c->iterator->end);
1245           gfc_add_block_to_block (pblock, &se.pre);
1246           end = gfc_evaluate_now (se.expr, pblock);
1247
1248           gfc_init_se (&se, NULL);
1249           gfc_conv_expr_val (&se, c->iterator->step);
1250           gfc_add_block_to_block (pblock, &se.pre);
1251           step = gfc_evaluate_now (se.expr, pblock);
1252
1253           /* If this array expands dynamically, and the number of iterations
1254              is not constant, we won't have allocated space for the static
1255              part of C->EXPR's size.  Do that now.  */
1256           if (dynamic && gfc_iterator_has_dynamic_bounds (c->iterator))
1257             {
1258               /* Get the number of iterations.  */
1259               tmp = gfc_get_iteration_count (loopvar, end, step);
1260
1261               /* Get the static part of C->EXPR's size.  */
1262               gfc_get_array_constructor_element_size (&size, c->expr);
1263               tmp2 = gfc_conv_mpz_to_tree (size, gfc_index_integer_kind);
1264
1265               /* Grow the array by TMP * TMP2 elements.  */
1266               tmp = fold_build2 (MULT_EXPR, gfc_array_index_type, tmp, tmp2);
1267               gfc_grow_array (pblock, desc, tmp);
1268             }
1269
1270           /* Generate the loop body.  */
1271           exit_label = gfc_build_label_decl (NULL_TREE);
1272           gfc_start_block (&body);
1273
1274           /* Generate the exit condition.  Depending on the sign of
1275              the step variable we have to generate the correct
1276              comparison.  */
1277           tmp = fold_build2 (GT_EXPR, boolean_type_node, step, 
1278                              build_int_cst (TREE_TYPE (step), 0));
1279           cond = fold_build3 (COND_EXPR, boolean_type_node, tmp,
1280                               build2 (GT_EXPR, boolean_type_node,
1281                                       loopvar, end),
1282                               build2 (LT_EXPR, boolean_type_node,
1283                                       loopvar, end));
1284           tmp = build1_v (GOTO_EXPR, exit_label);
1285           TREE_USED (exit_label) = 1;
1286           tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
1287           gfc_add_expr_to_block (&body, tmp);
1288
1289           /* The main loop body.  */
1290           gfc_add_expr_to_block (&body, loopbody);
1291
1292           /* Increase loop variable by step.  */
1293           tmp = build2 (PLUS_EXPR, TREE_TYPE (loopvar), loopvar, step);
1294           gfc_add_modify_expr (&body, loopvar, tmp);
1295
1296           /* Finish the loop.  */
1297           tmp = gfc_finish_block (&body);
1298           tmp = build1_v (LOOP_EXPR, tmp);
1299           gfc_add_expr_to_block (pblock, tmp);
1300
1301           /* Add the exit label.  */
1302           tmp = build1_v (LABEL_EXPR, exit_label);
1303           gfc_add_expr_to_block (pblock, tmp);
1304
1305           /* Restore the original value of the loop counter.  */
1306           gfc_add_modify_expr (pblock, loopvar, tmp_loopvar);
1307         }
1308     }
1309   mpz_clear (size);
1310 }
1311
1312
1313 /* Figure out the string length of a variable reference expression.
1314    Used by get_array_ctor_strlen.  */
1315
1316 static void
1317 get_array_ctor_var_strlen (gfc_expr * expr, tree * len)
1318 {
1319   gfc_ref *ref;
1320   gfc_typespec *ts;
1321   mpz_t char_len;
1322
1323   /* Don't bother if we already know the length is a constant.  */
1324   if (*len && INTEGER_CST_P (*len))
1325     return;
1326
1327   ts = &expr->symtree->n.sym->ts;
1328   for (ref = expr->ref; ref; ref = ref->next)
1329     {
1330       switch (ref->type)
1331         {
1332         case REF_ARRAY:
1333           /* Array references don't change the string length.  */
1334           break;
1335
1336         case REF_COMPONENT:
1337           /* Use the length of the component.  */
1338           ts = &ref->u.c.component->ts;
1339           break;
1340
1341         case REF_SUBSTRING:
1342           if (ref->u.ss.start->expr_type != EXPR_CONSTANT
1343                 || ref->u.ss.start->expr_type != EXPR_CONSTANT)
1344             break;
1345           mpz_init_set_ui (char_len, 1);
1346           mpz_add (char_len, char_len, ref->u.ss.end->value.integer);
1347           mpz_sub (char_len, char_len, ref->u.ss.start->value.integer);
1348           *len = gfc_conv_mpz_to_tree (char_len,
1349                                        gfc_default_character_kind);
1350           *len = convert (gfc_charlen_type_node, *len);
1351           mpz_clear (char_len);
1352           return;
1353
1354         default:
1355           /* TODO: Substrings are tricky because we can't evaluate the
1356              expression more than once.  For now we just give up, and hope
1357              we can figure it out elsewhere.  */
1358           return;
1359         }
1360     }
1361
1362   *len = ts->cl->backend_decl;
1363 }
1364
1365
1366 /* A catch-all to obtain the string length for anything that is not a
1367    constant, array or variable.  */
1368 static void
1369 get_array_ctor_all_strlen (stmtblock_t *block, gfc_expr *e, tree *len)
1370 {
1371   gfc_se se;
1372   gfc_ss *ss;
1373
1374   /* Don't bother if we already know the length is a constant.  */
1375   if (*len && INTEGER_CST_P (*len))
1376     return;
1377
1378   if (!e->ref && e->ts.cl && e->ts.cl->length
1379         && e->ts.cl->length->expr_type == EXPR_CONSTANT)
1380     {
1381       /* This is easy.  */
1382       gfc_conv_const_charlen (e->ts.cl);
1383       *len = e->ts.cl->backend_decl;
1384     }
1385   else
1386     {
1387       /* Otherwise, be brutal even if inefficient.  */
1388       ss = gfc_walk_expr (e);
1389       gfc_init_se (&se, NULL);
1390
1391       /* No function call, in case of side effects.  */
1392       se.no_function_call = 1;
1393       if (ss == gfc_ss_terminator)
1394         gfc_conv_expr (&se, e);
1395       else
1396         gfc_conv_expr_descriptor (&se, e, ss);
1397
1398       /* Fix the value.  */
1399       *len = gfc_evaluate_now (se.string_length, &se.pre);
1400
1401       gfc_add_block_to_block (block, &se.pre);
1402       gfc_add_block_to_block (block, &se.post);
1403
1404       e->ts.cl->backend_decl = *len;
1405     }
1406 }
1407
1408
1409 /* Figure out the string length of a character array constructor.
1410    Returns TRUE if all elements are character constants.  */
1411
1412 bool
1413 get_array_ctor_strlen (stmtblock_t *block, gfc_constructor * c, tree * len)
1414 {
1415   bool is_const;
1416   
1417   is_const = TRUE;
1418
1419   if (c == NULL)
1420     {
1421       *len = build_int_cstu (gfc_charlen_type_node, 0);
1422       return is_const;
1423     }
1424
1425   for (; c; c = c->next)
1426     {
1427       switch (c->expr->expr_type)
1428         {
1429         case EXPR_CONSTANT:
1430           if (!(*len && INTEGER_CST_P (*len)))
1431             *len = build_int_cstu (gfc_charlen_type_node,
1432                                    c->expr->value.character.length);
1433           break;
1434
1435         case EXPR_ARRAY:
1436           if (!get_array_ctor_strlen (block, c->expr->value.constructor, len))
1437             is_const = false;
1438           break;
1439
1440         case EXPR_VARIABLE:
1441           is_const = false;
1442           get_array_ctor_var_strlen (c->expr, len);
1443           break;
1444
1445         default:
1446           is_const = false;
1447           get_array_ctor_all_strlen (block, c->expr, len);
1448           break;
1449         }
1450     }
1451
1452   return is_const;
1453 }
1454
1455 /* Check whether the array constructor C consists entirely of constant
1456    elements, and if so returns the number of those elements, otherwise
1457    return zero.  Note, an empty or NULL array constructor returns zero.  */
1458
1459 unsigned HOST_WIDE_INT
1460 gfc_constant_array_constructor_p (gfc_constructor * c)
1461 {
1462   unsigned HOST_WIDE_INT nelem = 0;
1463
1464   while (c)
1465     {
1466       if (c->iterator
1467           || c->expr->rank > 0
1468           || c->expr->expr_type != EXPR_CONSTANT)
1469         return 0;
1470       c = c->next;
1471       nelem++;
1472     }
1473   return nelem;
1474 }
1475
1476
1477 /* Given EXPR, the constant array constructor specified by an EXPR_ARRAY,
1478    and the tree type of it's elements, TYPE, return a static constant
1479    variable that is compile-time initialized.  */
1480
1481 tree
1482 gfc_build_constant_array_constructor (gfc_expr * expr, tree type)
1483 {
1484   tree tmptype, list, init, tmp;
1485   HOST_WIDE_INT nelem;
1486   gfc_constructor *c;
1487   gfc_array_spec as;
1488   gfc_se se;
1489   int i;
1490
1491   /* First traverse the constructor list, converting the constants
1492      to tree to build an initializer.  */
1493   nelem = 0;
1494   list = NULL_TREE;
1495   c = expr->value.constructor;
1496   while (c)
1497     {
1498       gfc_init_se (&se, NULL);
1499       gfc_conv_constant (&se, c->expr);
1500       if (c->expr->ts.type == BT_CHARACTER
1501           && POINTER_TYPE_P (type))
1502         se.expr = gfc_build_addr_expr (pchar_type_node, se.expr);
1503       list = tree_cons (NULL_TREE, se.expr, list);
1504       c = c->next;
1505       nelem++;
1506     }
1507
1508   /* Next determine the tree type for the array.  We use the gfortran
1509      front-end's gfc_get_nodesc_array_type in order to create a suitable
1510      GFC_ARRAY_TYPE_P that may be used by the scalarizer.  */
1511
1512   memset (&as, 0, sizeof (gfc_array_spec));
1513
1514   as.rank = expr->rank;
1515   as.type = AS_EXPLICIT;
1516   if (!expr->shape)
1517     {
1518       as.lower[0] = gfc_int_expr (0);
1519       as.upper[0] = gfc_int_expr (nelem - 1);
1520     }
1521   else
1522     for (i = 0; i < expr->rank; i++)
1523       {
1524         int tmp = (int) mpz_get_si (expr->shape[i]);
1525         as.lower[i] = gfc_int_expr (0);
1526         as.upper[i] = gfc_int_expr (tmp - 1);
1527       }
1528
1529   tmptype = gfc_get_nodesc_array_type (type, &as, PACKED_STATIC);
1530
1531   init = build_constructor_from_list (tmptype, nreverse (list));
1532
1533   TREE_CONSTANT (init) = 1;
1534   TREE_INVARIANT (init) = 1;
1535   TREE_STATIC (init) = 1;
1536
1537   tmp = gfc_create_var (tmptype, "A");
1538   TREE_STATIC (tmp) = 1;
1539   TREE_CONSTANT (tmp) = 1;
1540   TREE_INVARIANT (tmp) = 1;
1541   TREE_READONLY (tmp) = 1;
1542   DECL_INITIAL (tmp) = init;
1543
1544   return tmp;
1545 }
1546
1547
1548 /* Translate a constant EXPR_ARRAY array constructor for the scalarizer.
1549    This mostly initializes the scalarizer state info structure with the
1550    appropriate values to directly use the array created by the function
1551    gfc_build_constant_array_constructor.  */
1552
1553 static void
1554 gfc_trans_constant_array_constructor (gfc_loopinfo * loop,
1555                                       gfc_ss * ss, tree type)
1556 {
1557   gfc_ss_info *info;
1558   tree tmp;
1559   int i;
1560
1561   tmp = gfc_build_constant_array_constructor (ss->expr, type);
1562
1563   info = &ss->data.info;
1564
1565   info->descriptor = tmp;
1566   info->data = build_fold_addr_expr (tmp);
1567   info->offset = fold_build1 (NEGATE_EXPR, gfc_array_index_type,
1568                               loop->from[0]);
1569
1570   for (i = 0; i < info->dimen; i++)
1571     {
1572       info->delta[i] = gfc_index_zero_node;
1573       info->start[i] = gfc_index_zero_node;
1574       info->end[i] = gfc_index_zero_node;
1575       info->stride[i] = gfc_index_one_node;
1576       info->dim[i] = i;
1577     }
1578
1579   if (info->dimen > loop->temp_dim)
1580     loop->temp_dim = info->dimen;
1581 }
1582
1583 /* Helper routine of gfc_trans_array_constructor to determine if the
1584    bounds of the loop specified by LOOP are constant and simple enough
1585    to use with gfc_trans_constant_array_constructor.  Returns the
1586    the iteration count of the loop if suitable, and NULL_TREE otherwise.  */
1587
1588 static tree
1589 constant_array_constructor_loop_size (gfc_loopinfo * loop)
1590 {
1591   tree size = gfc_index_one_node;
1592   tree tmp;
1593   int i;
1594
1595   for (i = 0; i < loop->dimen; i++)
1596     {
1597       /* If the bounds aren't constant, return NULL_TREE.  */
1598       if (!INTEGER_CST_P (loop->from[i]) || !INTEGER_CST_P (loop->to[i]))
1599         return NULL_TREE;
1600       if (!integer_zerop (loop->from[i]))
1601         {
1602           /* Only allow nonzero "from" in one-dimensional arrays.  */
1603           if (loop->dimen != 1)
1604             return NULL_TREE;
1605           tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
1606                              loop->to[i], loop->from[i]);
1607         }
1608       else
1609         tmp = loop->to[i];
1610       tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
1611                          tmp, gfc_index_one_node);
1612       size = fold_build2 (MULT_EXPR, gfc_array_index_type, size, tmp);
1613     }
1614
1615   return size;
1616 }
1617
1618
1619 /* Array constructors are handled by constructing a temporary, then using that
1620    within the scalarization loop.  This is not optimal, but seems by far the
1621    simplest method.  */
1622
1623 static void
1624 gfc_trans_array_constructor (gfc_loopinfo * loop, gfc_ss * ss)
1625 {
1626   gfc_constructor *c;
1627   tree offset;
1628   tree offsetvar;
1629   tree desc;
1630   tree type;
1631   bool dynamic;
1632
1633   ss->data.info.dimen = loop->dimen;
1634
1635   c = ss->expr->value.constructor;
1636   if (ss->expr->ts.type == BT_CHARACTER)
1637     {
1638       bool const_string = get_array_ctor_strlen (&loop->pre, c, &ss->string_length);
1639       if (!ss->string_length)
1640         gfc_todo_error ("complex character array constructors");
1641
1642       ss->expr->ts.cl->backend_decl = ss->string_length;
1643
1644       type = gfc_get_character_type_len (ss->expr->ts.kind, ss->string_length);
1645       if (const_string)
1646         type = build_pointer_type (type);
1647     }
1648   else
1649     type = gfc_typenode_for_spec (&ss->expr->ts);
1650
1651   /* See if the constructor determines the loop bounds.  */
1652   dynamic = false;
1653
1654   if (ss->expr->shape && loop->dimen > 1 && loop->to[0] == NULL_TREE)
1655     {
1656       /* We have a multidimensional parameter.  */
1657       int n;
1658       for (n = 0; n < ss->expr->rank; n++)
1659       {
1660         loop->from[n] = gfc_index_zero_node;
1661         loop->to[n] = gfc_conv_mpz_to_tree (ss->expr->shape [n],
1662                                             gfc_index_integer_kind);
1663         loop->to[n] = fold_build2 (MINUS_EXPR, gfc_array_index_type,
1664                                    loop->to[n], gfc_index_one_node);
1665       }
1666     }
1667
1668   if (loop->to[0] == NULL_TREE)
1669     {
1670       mpz_t size;
1671
1672       /* We should have a 1-dimensional, zero-based loop.  */
1673       gcc_assert (loop->dimen == 1);
1674       gcc_assert (integer_zerop (loop->from[0]));
1675
1676       /* Split the constructor size into a static part and a dynamic part.
1677          Allocate the static size up-front and record whether the dynamic
1678          size might be nonzero.  */
1679       mpz_init (size);
1680       dynamic = gfc_get_array_constructor_size (&size, c);
1681       mpz_sub_ui (size, size, 1);
1682       loop->to[0] = gfc_conv_mpz_to_tree (size, gfc_index_integer_kind);
1683       mpz_clear (size);
1684     }
1685
1686   /* Special case constant array constructors.  */
1687   if (!dynamic)
1688     {
1689       unsigned HOST_WIDE_INT nelem = gfc_constant_array_constructor_p (c);
1690       if (nelem > 0)
1691         {
1692           tree size = constant_array_constructor_loop_size (loop);
1693           if (size && compare_tree_int (size, nelem) == 0)
1694             {
1695               gfc_trans_constant_array_constructor (loop, ss, type);
1696               return;
1697             }
1698         }
1699     }
1700
1701   gfc_trans_create_temp_array (&loop->pre, &loop->post, loop, &ss->data.info,
1702                                type, dynamic, true, false);
1703
1704   desc = ss->data.info.descriptor;
1705   offset = gfc_index_zero_node;
1706   offsetvar = gfc_create_var_np (gfc_array_index_type, "offset");
1707   TREE_NO_WARNING (offsetvar) = 1;
1708   TREE_USED (offsetvar) = 0;
1709   gfc_trans_array_constructor_value (&loop->pre, type, desc, c,
1710                                      &offset, &offsetvar, dynamic);
1711
1712   /* If the array grows dynamically, the upper bound of the loop variable
1713      is determined by the array's final upper bound.  */
1714   if (dynamic)
1715     loop->to[0] = gfc_conv_descriptor_ubound (desc, gfc_rank_cst[0]);
1716
1717   if (TREE_USED (offsetvar))
1718     pushdecl (offsetvar);
1719   else
1720     gcc_assert (INTEGER_CST_P (offset));
1721 #if 0
1722   /* Disable bound checking for now because it's probably broken.  */
1723   if (flag_bounds_check)
1724     {
1725       gcc_unreachable ();
1726     }
1727 #endif
1728 }
1729
1730
1731 /* INFO describes a GFC_SS_SECTION in loop LOOP, and this function is
1732    called after evaluating all of INFO's vector dimensions.  Go through
1733    each such vector dimension and see if we can now fill in any missing
1734    loop bounds.  */
1735
1736 static void
1737 gfc_set_vector_loop_bounds (gfc_loopinfo * loop, gfc_ss_info * info)
1738 {
1739   gfc_se se;
1740   tree tmp;
1741   tree desc;
1742   tree zero;
1743   int n;
1744   int dim;
1745
1746   for (n = 0; n < loop->dimen; n++)
1747     {
1748       dim = info->dim[n];
1749       if (info->ref->u.ar.dimen_type[dim] == DIMEN_VECTOR
1750           && loop->to[n] == NULL)
1751         {
1752           /* Loop variable N indexes vector dimension DIM, and we don't
1753              yet know the upper bound of loop variable N.  Set it to the
1754              difference between the vector's upper and lower bounds.  */
1755           gcc_assert (loop->from[n] == gfc_index_zero_node);
1756           gcc_assert (info->subscript[dim]
1757                       && info->subscript[dim]->type == GFC_SS_VECTOR);
1758
1759           gfc_init_se (&se, NULL);
1760           desc = info->subscript[dim]->data.info.descriptor;
1761           zero = gfc_rank_cst[0];
1762           tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
1763                              gfc_conv_descriptor_ubound (desc, zero),
1764                              gfc_conv_descriptor_lbound (desc, zero));
1765           tmp = gfc_evaluate_now (tmp, &loop->pre);
1766           loop->to[n] = tmp;
1767         }
1768     }
1769 }
1770
1771
1772 /* Add the pre and post chains for all the scalar expressions in a SS chain
1773    to loop.  This is called after the loop parameters have been calculated,
1774    but before the actual scalarizing loops.  */
1775
1776 static void
1777 gfc_add_loop_ss_code (gfc_loopinfo * loop, gfc_ss * ss, bool subscript)
1778 {
1779   gfc_se se;
1780   int n;
1781
1782   /* TODO: This can generate bad code if there are ordering dependencies.
1783      eg. a callee allocated function and an unknown size constructor.  */
1784   gcc_assert (ss != NULL);
1785
1786   for (; ss != gfc_ss_terminator; ss = ss->loop_chain)
1787     {
1788       gcc_assert (ss);
1789
1790       switch (ss->type)
1791         {
1792         case GFC_SS_SCALAR:
1793           /* Scalar expression.  Evaluate this now.  This includes elemental
1794              dimension indices, but not array section bounds.  */
1795           gfc_init_se (&se, NULL);
1796           gfc_conv_expr (&se, ss->expr);
1797           gfc_add_block_to_block (&loop->pre, &se.pre);
1798
1799           if (ss->expr->ts.type != BT_CHARACTER)
1800             {
1801               /* Move the evaluation of scalar expressions outside the
1802                  scalarization loop.  */
1803               if (subscript)
1804                 se.expr = convert(gfc_array_index_type, se.expr);
1805               se.expr = gfc_evaluate_now (se.expr, &loop->pre);
1806               gfc_add_block_to_block (&loop->pre, &se.post);
1807             }
1808           else
1809             gfc_add_block_to_block (&loop->post, &se.post);
1810
1811           ss->data.scalar.expr = se.expr;
1812           ss->string_length = se.string_length;
1813           break;
1814
1815         case GFC_SS_REFERENCE:
1816           /* Scalar reference.  Evaluate this now.  */
1817           gfc_init_se (&se, NULL);
1818           gfc_conv_expr_reference (&se, ss->expr);
1819           gfc_add_block_to_block (&loop->pre, &se.pre);
1820           gfc_add_block_to_block (&loop->post, &se.post);
1821
1822           ss->data.scalar.expr = gfc_evaluate_now (se.expr, &loop->pre);
1823           ss->string_length = se.string_length;
1824           break;
1825
1826         case GFC_SS_SECTION:
1827           /* Add the expressions for scalar and vector subscripts.  */
1828           for (n = 0; n < GFC_MAX_DIMENSIONS; n++)
1829             if (ss->data.info.subscript[n])
1830               gfc_add_loop_ss_code (loop, ss->data.info.subscript[n], true);
1831
1832           gfc_set_vector_loop_bounds (loop, &ss->data.info);
1833           break;
1834
1835         case GFC_SS_VECTOR:
1836           /* Get the vector's descriptor and store it in SS.  */
1837           gfc_init_se (&se, NULL);
1838           gfc_conv_expr_descriptor (&se, ss->expr, gfc_walk_expr (ss->expr));
1839           gfc_add_block_to_block (&loop->pre, &se.pre);
1840           gfc_add_block_to_block (&loop->post, &se.post);
1841           ss->data.info.descriptor = se.expr;
1842           break;
1843
1844         case GFC_SS_INTRINSIC:
1845           gfc_add_intrinsic_ss_code (loop, ss);
1846           break;
1847
1848         case GFC_SS_FUNCTION:
1849           /* Array function return value.  We call the function and save its
1850              result in a temporary for use inside the loop.  */
1851           gfc_init_se (&se, NULL);
1852           se.loop = loop;
1853           se.ss = ss;
1854           gfc_conv_expr (&se, ss->expr);
1855           gfc_add_block_to_block (&loop->pre, &se.pre);
1856           gfc_add_block_to_block (&loop->post, &se.post);
1857           ss->string_length = se.string_length;
1858           break;
1859
1860         case GFC_SS_CONSTRUCTOR:
1861           gfc_trans_array_constructor (loop, ss);
1862           break;
1863
1864         case GFC_SS_TEMP:
1865         case GFC_SS_COMPONENT:
1866           /* Do nothing.  These are handled elsewhere.  */
1867           break;
1868
1869         default:
1870           gcc_unreachable ();
1871         }
1872     }
1873 }
1874
1875
1876 /* Translate expressions for the descriptor and data pointer of a SS.  */
1877 /*GCC ARRAYS*/
1878
1879 static void
1880 gfc_conv_ss_descriptor (stmtblock_t * block, gfc_ss * ss, int base)
1881 {
1882   gfc_se se;
1883   tree tmp;
1884
1885   /* Get the descriptor for the array to be scalarized.  */
1886   gcc_assert (ss->expr->expr_type == EXPR_VARIABLE);
1887   gfc_init_se (&se, NULL);
1888   se.descriptor_only = 1;
1889   gfc_conv_expr_lhs (&se, ss->expr);
1890   gfc_add_block_to_block (block, &se.pre);
1891   ss->data.info.descriptor = se.expr;
1892   ss->string_length = se.string_length;
1893
1894   if (base)
1895     {
1896       /* Also the data pointer.  */
1897       tmp = gfc_conv_array_data (se.expr);
1898       /* If this is a variable or address of a variable we use it directly.
1899          Otherwise we must evaluate it now to avoid breaking dependency
1900          analysis by pulling the expressions for elemental array indices
1901          inside the loop.  */
1902       if (!(DECL_P (tmp)
1903             || (TREE_CODE (tmp) == ADDR_EXPR
1904                 && DECL_P (TREE_OPERAND (tmp, 0)))))
1905         tmp = gfc_evaluate_now (tmp, block);
1906       ss->data.info.data = tmp;
1907
1908       tmp = gfc_conv_array_offset (se.expr);
1909       ss->data.info.offset = gfc_evaluate_now (tmp, block);
1910     }
1911 }
1912
1913
1914 /* Initialize a gfc_loopinfo structure.  */
1915
1916 void
1917 gfc_init_loopinfo (gfc_loopinfo * loop)
1918 {
1919   int n;
1920
1921   memset (loop, 0, sizeof (gfc_loopinfo));
1922   gfc_init_block (&loop->pre);
1923   gfc_init_block (&loop->post);
1924
1925   /* Initially scalarize in order.  */
1926   for (n = 0; n < GFC_MAX_DIMENSIONS; n++)
1927     loop->order[n] = n;
1928
1929   loop->ss = gfc_ss_terminator;
1930 }
1931
1932
1933 /* Copies the loop variable info to a gfc_se structure. Does not copy the SS
1934    chain.  */
1935
1936 void
1937 gfc_copy_loopinfo_to_se (gfc_se * se, gfc_loopinfo * loop)
1938 {
1939   se->loop = loop;
1940 }
1941
1942
1943 /* Return an expression for the data pointer of an array.  */
1944
1945 tree
1946 gfc_conv_array_data (tree descriptor)
1947 {
1948   tree type;
1949
1950   type = TREE_TYPE (descriptor);
1951   if (GFC_ARRAY_TYPE_P (type))
1952     {
1953       if (TREE_CODE (type) == POINTER_TYPE)
1954         return descriptor;
1955       else
1956         {
1957           /* Descriptorless arrays.  */
1958           return build_fold_addr_expr (descriptor);
1959         }
1960     }
1961   else
1962     return gfc_conv_descriptor_data_get (descriptor);
1963 }
1964
1965
1966 /* Return an expression for the base offset of an array.  */
1967
1968 tree
1969 gfc_conv_array_offset (tree descriptor)
1970 {
1971   tree type;
1972
1973   type = TREE_TYPE (descriptor);
1974   if (GFC_ARRAY_TYPE_P (type))
1975     return GFC_TYPE_ARRAY_OFFSET (type);
1976   else
1977     return gfc_conv_descriptor_offset (descriptor);
1978 }
1979
1980
1981 /* Get an expression for the array stride.  */
1982
1983 tree
1984 gfc_conv_array_stride (tree descriptor, int dim)
1985 {
1986   tree tmp;
1987   tree type;
1988
1989   type = TREE_TYPE (descriptor);
1990
1991   /* For descriptorless arrays use the array size.  */
1992   tmp = GFC_TYPE_ARRAY_STRIDE (type, dim);
1993   if (tmp != NULL_TREE)
1994     return tmp;
1995
1996   tmp = gfc_conv_descriptor_stride (descriptor, gfc_rank_cst[dim]);
1997   return tmp;
1998 }
1999
2000
2001 /* Like gfc_conv_array_stride, but for the lower bound.  */
2002
2003 tree
2004 gfc_conv_array_lbound (tree descriptor, int dim)
2005 {
2006   tree tmp;
2007   tree type;
2008
2009   type = TREE_TYPE (descriptor);
2010
2011   tmp = GFC_TYPE_ARRAY_LBOUND (type, dim);
2012   if (tmp != NULL_TREE)
2013     return tmp;
2014
2015   tmp = gfc_conv_descriptor_lbound (descriptor, gfc_rank_cst[dim]);
2016   return tmp;
2017 }
2018
2019
2020 /* Like gfc_conv_array_stride, but for the upper bound.  */
2021
2022 tree
2023 gfc_conv_array_ubound (tree descriptor, int dim)
2024 {
2025   tree tmp;
2026   tree type;
2027
2028   type = TREE_TYPE (descriptor);
2029
2030   tmp = GFC_TYPE_ARRAY_UBOUND (type, dim);
2031   if (tmp != NULL_TREE)
2032     return tmp;
2033
2034   /* This should only ever happen when passing an assumed shape array
2035      as an actual parameter.  The value will never be used.  */
2036   if (GFC_ARRAY_TYPE_P (TREE_TYPE (descriptor)))
2037     return gfc_index_zero_node;
2038
2039   tmp = gfc_conv_descriptor_ubound (descriptor, gfc_rank_cst[dim]);
2040   return tmp;
2041 }
2042
2043
2044 /* Generate code to perform an array index bound check.  */
2045
2046 static tree
2047 gfc_trans_array_bound_check (gfc_se * se, tree descriptor, tree index, int n,
2048                              locus * where, bool check_upper)
2049 {
2050   tree fault;
2051   tree tmp;
2052   char *msg;
2053   const char * name = NULL;
2054
2055   if (!flag_bounds_check)
2056     return index;
2057
2058   index = gfc_evaluate_now (index, &se->pre);
2059
2060   /* We find a name for the error message.  */
2061   if (se->ss)
2062     name = se->ss->expr->symtree->name;
2063
2064   if (!name && se->loop && se->loop->ss && se->loop->ss->expr
2065       && se->loop->ss->expr->symtree)
2066     name = se->loop->ss->expr->symtree->name;
2067
2068   if (!name && se->loop && se->loop->ss && se->loop->ss->loop_chain
2069       && se->loop->ss->loop_chain->expr
2070       && se->loop->ss->loop_chain->expr->symtree)
2071     name = se->loop->ss->loop_chain->expr->symtree->name;
2072
2073   if (!name && se->loop && se->loop->ss && se->loop->ss->loop_chain
2074       && se->loop->ss->loop_chain->expr->symtree)
2075     name = se->loop->ss->loop_chain->expr->symtree->name;
2076
2077   if (!name && se->loop && se->loop->ss && se->loop->ss->expr)
2078     {
2079       if (se->loop->ss->expr->expr_type == EXPR_FUNCTION
2080           && se->loop->ss->expr->value.function.name)
2081         name = se->loop->ss->expr->value.function.name;
2082       else
2083         if (se->loop->ss->type == GFC_SS_CONSTRUCTOR
2084             || se->loop->ss->type == GFC_SS_SCALAR)
2085           name = "unnamed constant";
2086     }
2087
2088   /* Check lower bound.  */
2089   tmp = gfc_conv_array_lbound (descriptor, n);
2090   fault = fold_build2 (LT_EXPR, boolean_type_node, index, tmp);
2091   if (name)
2092     asprintf (&msg, "%s for array '%s', lower bound of dimension %d exceeded",
2093               gfc_msg_fault, name, n+1);
2094   else
2095     asprintf (&msg, "%s, lower bound of dimension %d exceeded, %%ld is "
2096               "smaller than %%ld", gfc_msg_fault, n+1);
2097   gfc_trans_runtime_check (fault, &se->pre, where, msg,
2098                            fold_convert (long_integer_type_node, index),
2099                            fold_convert (long_integer_type_node, tmp));
2100   gfc_free (msg);
2101
2102   /* Check upper bound.  */
2103   if (check_upper)
2104     {
2105       tmp = gfc_conv_array_ubound (descriptor, n);
2106       fault = fold_build2 (GT_EXPR, boolean_type_node, index, tmp);
2107       if (name)
2108         asprintf (&msg, "%s for array '%s', upper bound of dimension %d "
2109                         " exceeded", gfc_msg_fault, name, n+1);
2110       else
2111         asprintf (&msg, "%s, upper bound of dimension %d exceeded, %%ld is "
2112                   "larger than %%ld", gfc_msg_fault, n+1);
2113       gfc_trans_runtime_check (fault, &se->pre, where, msg,
2114                                fold_convert (long_integer_type_node, index),
2115                                fold_convert (long_integer_type_node, tmp));
2116       gfc_free (msg);
2117     }
2118
2119   return index;
2120 }
2121
2122
2123 /* Return the offset for an index.  Performs bound checking for elemental
2124    dimensions.  Single element references are processed separately.  */
2125
2126 static tree
2127 gfc_conv_array_index_offset (gfc_se * se, gfc_ss_info * info, int dim, int i,
2128                              gfc_array_ref * ar, tree stride)
2129 {
2130   tree index;
2131   tree desc;
2132   tree data;
2133
2134   /* Get the index into the array for this dimension.  */
2135   if (ar)
2136     {
2137       gcc_assert (ar->type != AR_ELEMENT);
2138       switch (ar->dimen_type[dim])
2139         {
2140         case DIMEN_ELEMENT:
2141           gcc_assert (i == -1);
2142           /* Elemental dimension.  */
2143           gcc_assert (info->subscript[dim]
2144                       && info->subscript[dim]->type == GFC_SS_SCALAR);
2145           /* We've already translated this value outside the loop.  */
2146           index = info->subscript[dim]->data.scalar.expr;
2147
2148           index = gfc_trans_array_bound_check (se, info->descriptor,
2149                         index, dim, &ar->where,
2150                         (ar->as->type != AS_ASSUMED_SIZE
2151                          && !ar->as->cp_was_assumed) || dim < ar->dimen - 1);
2152           break;
2153
2154         case DIMEN_VECTOR:
2155           gcc_assert (info && se->loop);
2156           gcc_assert (info->subscript[dim]
2157                       && info->subscript[dim]->type == GFC_SS_VECTOR);
2158           desc = info->subscript[dim]->data.info.descriptor;
2159
2160           /* Get a zero-based index into the vector.  */
2161           index = fold_build2 (MINUS_EXPR, gfc_array_index_type,
2162                                se->loop->loopvar[i], se->loop->from[i]);
2163
2164           /* Multiply the index by the stride.  */
2165           index = fold_build2 (MULT_EXPR, gfc_array_index_type,
2166                                index, gfc_conv_array_stride (desc, 0));
2167
2168           /* Read the vector to get an index into info->descriptor.  */
2169           data = build_fold_indirect_ref (gfc_conv_array_data (desc));
2170           index = gfc_build_array_ref (data, index, NULL);
2171           index = gfc_evaluate_now (index, &se->pre);
2172
2173           /* Do any bounds checking on the final info->descriptor index.  */
2174           index = gfc_trans_array_bound_check (se, info->descriptor,
2175                         index, dim, &ar->where,
2176                         (ar->as->type != AS_ASSUMED_SIZE
2177                          && !ar->as->cp_was_assumed) || dim < ar->dimen - 1);
2178           break;
2179
2180         case DIMEN_RANGE:
2181           /* Scalarized dimension.  */
2182           gcc_assert (info && se->loop);
2183
2184           /* Multiply the loop variable by the stride and delta.  */
2185           index = se->loop->loopvar[i];
2186           if (!integer_onep (info->stride[i]))
2187             index = fold_build2 (MULT_EXPR, gfc_array_index_type, index,
2188                                  info->stride[i]);
2189           if (!integer_zerop (info->delta[i]))
2190             index = fold_build2 (PLUS_EXPR, gfc_array_index_type, index,
2191                                  info->delta[i]);
2192           break;
2193
2194         default:
2195           gcc_unreachable ();
2196         }
2197     }
2198   else
2199     {
2200       /* Temporary array or derived type component.  */
2201       gcc_assert (se->loop);
2202       index = se->loop->loopvar[se->loop->order[i]];
2203       if (!integer_zerop (info->delta[i]))
2204         index = fold_build2 (PLUS_EXPR, gfc_array_index_type,
2205                              index, info->delta[i]);
2206     }
2207
2208   /* Multiply by the stride.  */
2209   if (!integer_onep (stride))
2210     index = fold_build2 (MULT_EXPR, gfc_array_index_type, index, stride);
2211
2212   return index;
2213 }
2214
2215
2216 /* Build a scalarized reference to an array.  */
2217
2218 static void
2219 gfc_conv_scalarized_array_ref (gfc_se * se, gfc_array_ref * ar)
2220 {
2221   gfc_ss_info *info;
2222   tree decl = NULL_TREE;
2223   tree index;
2224   tree tmp;
2225   int n;
2226
2227   info = &se->ss->data.info;
2228   if (ar)
2229     n = se->loop->order[0];
2230   else
2231     n = 0;
2232
2233   index = gfc_conv_array_index_offset (se, info, info->dim[n], n, ar,
2234                                        info->stride0);
2235   /* Add the offset for this dimension to the stored offset for all other
2236      dimensions.  */
2237   if (!integer_zerop (info->offset))
2238     index = fold_build2 (PLUS_EXPR, gfc_array_index_type, index, info->offset);
2239
2240   if (se->ss->expr && is_subref_array (se->ss->expr))
2241     decl = se->ss->expr->symtree->n.sym->backend_decl;
2242
2243   tmp = build_fold_indirect_ref (info->data);
2244   se->expr = gfc_build_array_ref (tmp, index, decl);
2245 }
2246
2247
2248 /* Translate access of temporary array.  */
2249
2250 void
2251 gfc_conv_tmp_array_ref (gfc_se * se)
2252 {
2253   se->string_length = se->ss->string_length;
2254   gfc_conv_scalarized_array_ref (se, NULL);
2255 }
2256
2257
2258 /* Build an array reference.  se->expr already holds the array descriptor.
2259    This should be either a variable, indirect variable reference or component
2260    reference.  For arrays which do not have a descriptor, se->expr will be
2261    the data pointer.
2262    a(i, j, k) = base[offset + i * stride[0] + j * stride[1] + k * stride[2]]*/
2263
2264 void
2265 gfc_conv_array_ref (gfc_se * se, gfc_array_ref * ar, gfc_symbol * sym,
2266                     locus * where)
2267 {
2268   int n;
2269   tree index;
2270   tree tmp;
2271   tree stride;
2272   gfc_se indexse;
2273
2274   /* Handle scalarized references separately.  */
2275   if (ar->type != AR_ELEMENT)
2276     {
2277       gfc_conv_scalarized_array_ref (se, ar);
2278       gfc_advance_se_ss_chain (se);
2279       return;
2280     }
2281
2282   index = gfc_index_zero_node;
2283
2284   /* Calculate the offsets from all the dimensions.  */
2285   for (n = 0; n < ar->dimen; n++)
2286     {
2287       /* Calculate the index for this dimension.  */
2288       gfc_init_se (&indexse, se);
2289       gfc_conv_expr_type (&indexse, ar->start[n], gfc_array_index_type);
2290       gfc_add_block_to_block (&se->pre, &indexse.pre);
2291
2292       if (flag_bounds_check)
2293         {
2294           /* Check array bounds.  */
2295           tree cond;
2296           char *msg;
2297
2298           /* Evaluate the indexse.expr only once.  */
2299           indexse.expr = save_expr (indexse.expr);
2300
2301           /* Lower bound.  */
2302           tmp = gfc_conv_array_lbound (se->expr, n);
2303           cond = fold_build2 (LT_EXPR, boolean_type_node, 
2304                               indexse.expr, tmp);
2305           asprintf (&msg, "%s for array '%s', "
2306                     "lower bound of dimension %d exceeded, %%ld is smaller "
2307                     "than %%ld", gfc_msg_fault, sym->name, n+1);
2308           gfc_trans_runtime_check (cond, &se->pre, where, msg,
2309                                    fold_convert (long_integer_type_node,
2310                                                  indexse.expr),
2311                                    fold_convert (long_integer_type_node, tmp));
2312           gfc_free (msg);
2313
2314           /* Upper bound, but not for the last dimension of assumed-size
2315              arrays.  */
2316           if (n < ar->dimen - 1
2317               || (ar->as->type != AS_ASSUMED_SIZE && !ar->as->cp_was_assumed))
2318             {
2319               tmp = gfc_conv_array_ubound (se->expr, n);
2320               cond = fold_build2 (GT_EXPR, boolean_type_node, 
2321                                   indexse.expr, tmp);
2322               asprintf (&msg, "%s for array '%s', "
2323                         "upper bound of dimension %d exceeded, %%ld is "
2324                         "greater than %%ld", gfc_msg_fault, sym->name, n+1);
2325               gfc_trans_runtime_check (cond, &se->pre, where, msg,
2326                                    fold_convert (long_integer_type_node,
2327                                                  indexse.expr),
2328                                    fold_convert (long_integer_type_node, tmp));
2329               gfc_free (msg);
2330             }
2331         }
2332
2333       /* Multiply the index by the stride.  */
2334       stride = gfc_conv_array_stride (se->expr, n);
2335       tmp = fold_build2 (MULT_EXPR, gfc_array_index_type, indexse.expr,
2336                          stride);
2337
2338       /* And add it to the total.  */
2339       index = fold_build2 (PLUS_EXPR, gfc_array_index_type, index, tmp);
2340     }
2341
2342   tmp = gfc_conv_array_offset (se->expr);
2343   if (!integer_zerop (tmp))
2344     index = fold_build2 (PLUS_EXPR, gfc_array_index_type, index, tmp);
2345
2346   /* Access the calculated element.  */
2347   tmp = gfc_conv_array_data (se->expr);
2348   tmp = build_fold_indirect_ref (tmp);
2349   se->expr = gfc_build_array_ref (tmp, index, sym->backend_decl);
2350 }
2351
2352
2353 /* Generate the code to be executed immediately before entering a
2354    scalarization loop.  */
2355
2356 static void
2357 gfc_trans_preloop_setup (gfc_loopinfo * loop, int dim, int flag,
2358                          stmtblock_t * pblock)
2359 {
2360   tree index;
2361   tree stride;
2362   gfc_ss_info *info;
2363   gfc_ss *ss;
2364   gfc_se se;
2365   int i;
2366
2367   /* This code will be executed before entering the scalarization loop
2368      for this dimension.  */
2369   for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
2370     {
2371       if ((ss->useflags & flag) == 0)
2372         continue;
2373
2374       if (ss->type != GFC_SS_SECTION
2375           && ss->type != GFC_SS_FUNCTION && ss->type != GFC_SS_CONSTRUCTOR
2376           && ss->type != GFC_SS_COMPONENT)
2377         continue;
2378
2379       info = &ss->data.info;
2380
2381       if (dim >= info->dimen)
2382         continue;
2383
2384       if (dim == info->dimen - 1)
2385         {
2386           /* For the outermost loop calculate the offset due to any
2387              elemental dimensions.  It will have been initialized with the
2388              base offset of the array.  */
2389           if (info->ref)
2390             {
2391               for (i = 0; i < info->ref->u.ar.dimen; i++)
2392                 {
2393                   if (info->ref->u.ar.dimen_type[i] != DIMEN_ELEMENT)
2394                     continue;
2395
2396                   gfc_init_se (&se, NULL);
2397                   se.loop = loop;
2398                   se.expr = info->descriptor;
2399                   stride = gfc_conv_array_stride (info->descriptor, i);
2400                   index = gfc_conv_array_index_offset (&se, info, i, -1,
2401                                                        &info->ref->u.ar,
2402                                                        stride);
2403                   gfc_add_block_to_block (pblock, &se.pre);
2404
2405                   info->offset = fold_build2 (PLUS_EXPR, gfc_array_index_type,
2406                                               info->offset, index);
2407                   info->offset = gfc_evaluate_now (info->offset, pblock);
2408                 }
2409
2410               i = loop->order[0];
2411               stride = gfc_conv_array_stride (info->descriptor, info->dim[i]);
2412             }
2413           else
2414             stride = gfc_conv_array_stride (info->descriptor, 0);
2415
2416           /* Calculate the stride of the innermost loop.  Hopefully this will
2417              allow the backend optimizers to do their stuff more effectively.
2418            */
2419           info->stride0 = gfc_evaluate_now (stride, pblock);
2420         }
2421       else
2422         {
2423           /* Add the offset for the previous loop dimension.  */
2424           gfc_array_ref *ar;
2425
2426           if (info->ref)
2427             {
2428               ar = &info->ref->u.ar;
2429               i = loop->order[dim + 1];
2430             }
2431           else
2432             {
2433               ar = NULL;
2434               i = dim + 1;
2435             }
2436
2437           gfc_init_se (&se, NULL);
2438           se.loop = loop;
2439           se.expr = info->descriptor;
2440           stride = gfc_conv_array_stride (info->descriptor, info->dim[i]);
2441           index = gfc_conv_array_index_offset (&se, info, info->dim[i], i,
2442                                                ar, stride);
2443           gfc_add_block_to_block (pblock, &se.pre);
2444           info->offset = fold_build2 (PLUS_EXPR, gfc_array_index_type,
2445                                       info->offset, index);
2446           info->offset = gfc_evaluate_now (info->offset, pblock);
2447         }
2448
2449       /* Remember this offset for the second loop.  */
2450       if (dim == loop->temp_dim - 1)
2451         info->saved_offset = info->offset;
2452     }
2453 }
2454
2455
2456 /* Start a scalarized expression.  Creates a scope and declares loop
2457    variables.  */
2458
2459 void
2460 gfc_start_scalarized_body (gfc_loopinfo * loop, stmtblock_t * pbody)
2461 {
2462   int dim;
2463   int n;
2464   int flags;
2465
2466   gcc_assert (!loop->array_parameter);
2467
2468   for (dim = loop->dimen - 1; dim >= 0; dim--)
2469     {
2470       n = loop->order[dim];
2471
2472       gfc_start_block (&loop->code[n]);
2473
2474       /* Create the loop variable.  */
2475       loop->loopvar[n] = gfc_create_var (gfc_array_index_type, "S");
2476
2477       if (dim < loop->temp_dim)
2478         flags = 3;
2479       else
2480         flags = 1;
2481       /* Calculate values that will be constant within this loop.  */
2482       gfc_trans_preloop_setup (loop, dim, flags, &loop->code[n]);
2483     }
2484   gfc_start_block (pbody);
2485 }
2486
2487
2488 /* Generates the actual loop code for a scalarization loop.  */
2489
2490 static void
2491 gfc_trans_scalarized_loop_end (gfc_loopinfo * loop, int n,
2492                                stmtblock_t * pbody)
2493 {
2494   stmtblock_t block;
2495   tree cond;
2496   tree tmp;
2497   tree loopbody;
2498   tree exit_label;
2499
2500   loopbody = gfc_finish_block (pbody);
2501
2502   /* Initialize the loopvar.  */
2503   gfc_add_modify_expr (&loop->code[n], loop->loopvar[n], loop->from[n]);
2504
2505   exit_label = gfc_build_label_decl (NULL_TREE);
2506
2507   /* Generate the loop body.  */
2508   gfc_init_block (&block);
2509
2510   /* The exit condition.  */
2511   cond = build2 (GT_EXPR, boolean_type_node, loop->loopvar[n], loop->to[n]);
2512   tmp = build1_v (GOTO_EXPR, exit_label);
2513   TREE_USED (exit_label) = 1;
2514   tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
2515   gfc_add_expr_to_block (&block, tmp);
2516
2517   /* The main body.  */
2518   gfc_add_expr_to_block (&block, loopbody);
2519
2520   /* Increment the loopvar.  */
2521   tmp = build2 (PLUS_EXPR, gfc_array_index_type,
2522                 loop->loopvar[n], gfc_index_one_node);
2523   gfc_add_modify_expr (&block, loop->loopvar[n], tmp);
2524
2525   /* Build the loop.  */
2526   tmp = gfc_finish_block (&block);
2527   tmp = build1_v (LOOP_EXPR, tmp);
2528   gfc_add_expr_to_block (&loop->code[n], tmp);
2529
2530   /* Add the exit label.  */
2531   tmp = build1_v (LABEL_EXPR, exit_label);
2532   gfc_add_expr_to_block (&loop->code[n], tmp);
2533 }
2534
2535
2536 /* Finishes and generates the loops for a scalarized expression.  */
2537
2538 void
2539 gfc_trans_scalarizing_loops (gfc_loopinfo * loop, stmtblock_t * body)
2540 {
2541   int dim;
2542   int n;
2543   gfc_ss *ss;
2544   stmtblock_t *pblock;
2545   tree tmp;
2546
2547   pblock = body;
2548   /* Generate the loops.  */
2549   for (dim = 0; dim < loop->dimen; dim++)
2550     {
2551       n = loop->order[dim];
2552       gfc_trans_scalarized_loop_end (loop, n, pblock);
2553       loop->loopvar[n] = NULL_TREE;
2554       pblock = &loop->code[n];
2555     }
2556
2557   tmp = gfc_finish_block (pblock);
2558   gfc_add_expr_to_block (&loop->pre, tmp);
2559
2560   /* Clear all the used flags.  */
2561   for (ss = loop->ss; ss; ss = ss->loop_chain)
2562     ss->useflags = 0;
2563 }
2564
2565
2566 /* Finish the main body of a scalarized expression, and start the secondary
2567    copying body.  */
2568
2569 void
2570 gfc_trans_scalarized_loop_boundary (gfc_loopinfo * loop, stmtblock_t * body)
2571 {
2572   int dim;
2573   int n;
2574   stmtblock_t *pblock;
2575   gfc_ss *ss;
2576
2577   pblock = body;
2578   /* We finish as many loops as are used by the temporary.  */
2579   for (dim = 0; dim < loop->temp_dim - 1; dim++)
2580     {
2581       n = loop->order[dim];
2582       gfc_trans_scalarized_loop_end (loop, n, pblock);
2583       loop->loopvar[n] = NULL_TREE;
2584       pblock = &loop->code[n];
2585     }
2586
2587   /* We don't want to finish the outermost loop entirely.  */
2588   n = loop->order[loop->temp_dim - 1];
2589   gfc_trans_scalarized_loop_end (loop, n, pblock);
2590
2591   /* Restore the initial offsets.  */
2592   for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
2593     {
2594       if ((ss->useflags & 2) == 0)
2595         continue;
2596
2597       if (ss->type != GFC_SS_SECTION
2598           && ss->type != GFC_SS_FUNCTION && ss->type != GFC_SS_CONSTRUCTOR
2599           && ss->type != GFC_SS_COMPONENT)
2600         continue;
2601
2602       ss->data.info.offset = ss->data.info.saved_offset;
2603     }
2604
2605   /* Restart all the inner loops we just finished.  */
2606   for (dim = loop->temp_dim - 2; dim >= 0; dim--)
2607     {
2608       n = loop->order[dim];
2609
2610       gfc_start_block (&loop->code[n]);
2611
2612       loop->loopvar[n] = gfc_create_var (gfc_array_index_type, "Q");
2613
2614       gfc_trans_preloop_setup (loop, dim, 2, &loop->code[n]);
2615     }
2616
2617   /* Start a block for the secondary copying code.  */
2618   gfc_start_block (body);
2619 }
2620
2621
2622 /* Calculate the upper bound of an array section.  */
2623
2624 static tree
2625 gfc_conv_section_upper_bound (gfc_ss * ss, int n, stmtblock_t * pblock)
2626 {
2627   int dim;
2628   gfc_expr *end;
2629   tree desc;
2630   tree bound;
2631   gfc_se se;
2632   gfc_ss_info *info;
2633
2634   gcc_assert (ss->type == GFC_SS_SECTION);
2635
2636   info = &ss->data.info;
2637   dim = info->dim[n];
2638
2639   if (info->ref->u.ar.dimen_type[dim] == DIMEN_VECTOR)
2640     /* We'll calculate the upper bound once we have access to the
2641        vector's descriptor.  */
2642     return NULL;
2643
2644   gcc_assert (info->ref->u.ar.dimen_type[dim] == DIMEN_RANGE);
2645   desc = info->descriptor;
2646   end = info->ref->u.ar.end[dim];
2647
2648   if (end)
2649     {
2650       /* The upper bound was specified.  */
2651       gfc_init_se (&se, NULL);
2652       gfc_conv_expr_type (&se, end, gfc_array_index_type);
2653       gfc_add_block_to_block (pblock, &se.pre);
2654       bound = se.expr;
2655     }
2656   else
2657     {
2658       /* No upper bound was specified, so use the bound of the array.  */
2659       bound = gfc_conv_array_ubound (desc, dim);
2660     }
2661
2662   return bound;
2663 }
2664
2665
2666 /* Calculate the lower bound of an array section.  */
2667
2668 static void
2669 gfc_conv_section_startstride (gfc_loopinfo * loop, gfc_ss * ss, int n)
2670 {
2671   gfc_expr *start;
2672   gfc_expr *end;
2673   gfc_expr *stride;
2674   tree desc;
2675   gfc_se se;
2676   gfc_ss_info *info;
2677   int dim;
2678
2679   gcc_assert (ss->type == GFC_SS_SECTION);
2680
2681   info = &ss->data.info;
2682   dim = info->dim[n];
2683
2684   if (info->ref->u.ar.dimen_type[dim] == DIMEN_VECTOR)
2685     {
2686       /* We use a zero-based index to access the vector.  */
2687       info->start[n] = gfc_index_zero_node;
2688       info->end[n] = gfc_index_zero_node;
2689       info->stride[n] = gfc_index_one_node;
2690       return;
2691     }
2692
2693   gcc_assert (info->ref->u.ar.dimen_type[dim] == DIMEN_RANGE);
2694   desc = info->descriptor;
2695   start = info->ref->u.ar.start[dim];
2696   end = info->ref->u.ar.end[dim];
2697   stride = info->ref->u.ar.stride[dim];
2698
2699   /* Calculate the start of the range.  For vector subscripts this will
2700      be the range of the vector.  */
2701   if (start)
2702     {
2703       /* Specified section start.  */
2704       gfc_init_se (&se, NULL);
2705       gfc_conv_expr_type (&se, start, gfc_array_index_type);
2706       gfc_add_block_to_block (&loop->pre, &se.pre);
2707       info->start[n] = se.expr;
2708     }
2709   else
2710     {
2711       /* No lower bound specified so use the bound of the array.  */
2712       info->start[n] = gfc_conv_array_lbound (desc, dim);
2713     }
2714   info->start[n] = gfc_evaluate_now (info->start[n], &loop->pre);
2715
2716   /* Similarly calculate the end.  Although this is not used in the
2717      scalarizer, it is needed when checking bounds and where the end
2718      is an expression with side-effects.  */
2719   if (end)
2720     {
2721       /* Specified section start.  */
2722       gfc_init_se (&se, NULL);
2723       gfc_conv_expr_type (&se, end, gfc_array_index_type);
2724       gfc_add_block_to_block (&loop->pre, &se.pre);
2725       info->end[n] = se.expr;
2726     }
2727   else
2728     {
2729       /* No upper bound specified so use the bound of the array.  */
2730       info->end[n] = gfc_conv_array_ubound (desc, dim);
2731     }
2732   info->end[n] = gfc_evaluate_now (info->end[n], &loop->pre);
2733
2734   /* Calculate the stride.  */
2735   if (stride == NULL)
2736     info->stride[n] = gfc_index_one_node;
2737   else
2738     {
2739       gfc_init_se (&se, NULL);
2740       gfc_conv_expr_type (&se, stride, gfc_array_index_type);
2741       gfc_add_block_to_block (&loop->pre, &se.pre);
2742       info->stride[n] = gfc_evaluate_now (se.expr, &loop->pre);
2743     }
2744 }
2745
2746
2747 /* Calculates the range start and stride for a SS chain.  Also gets the
2748    descriptor and data pointer.  The range of vector subscripts is the size
2749    of the vector.  Array bounds are also checked.  */
2750
2751 void
2752 gfc_conv_ss_startstride (gfc_loopinfo * loop)
2753 {
2754   int n;
2755   tree tmp;
2756   gfc_ss *ss;
2757   tree desc;
2758
2759   loop->dimen = 0;
2760   /* Determine the rank of the loop.  */
2761   for (ss = loop->ss;
2762        ss != gfc_ss_terminator && loop->dimen == 0; ss = ss->loop_chain)
2763     {
2764       switch (ss->type)
2765         {
2766         case GFC_SS_SECTION:
2767         case GFC_SS_CONSTRUCTOR:
2768         case GFC_SS_FUNCTION:
2769         case GFC_SS_COMPONENT:
2770           loop->dimen = ss->data.info.dimen;
2771           break;
2772
2773         /* As usual, lbound and ubound are exceptions!.  */
2774         case GFC_SS_INTRINSIC:
2775           switch (ss->expr->value.function.isym->id)
2776             {
2777             case GFC_ISYM_LBOUND:
2778             case GFC_ISYM_UBOUND:
2779               loop->dimen = ss->data.info.dimen;
2780
2781             default:
2782               break;
2783             }
2784
2785         default:
2786           break;
2787         }
2788     }
2789
2790   if (loop->dimen == 0)
2791     gfc_todo_error ("Unable to determine rank of expression");
2792
2793
2794   /* Loop over all the SS in the chain.  */
2795   for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
2796     {
2797       if (ss->expr && ss->expr->shape && !ss->shape)
2798         ss->shape = ss->expr->shape;
2799
2800       switch (ss->type)
2801         {
2802         case GFC_SS_SECTION:
2803           /* Get the descriptor for the array.  */
2804           gfc_conv_ss_descriptor (&loop->pre, ss, !loop->array_parameter);
2805
2806           for (n = 0; n < ss->data.info.dimen; n++)
2807             gfc_conv_section_startstride (loop, ss, n);
2808           break;
2809
2810         case GFC_SS_INTRINSIC:
2811           switch (ss->expr->value.function.isym->id)
2812             {
2813             /* Fall through to supply start and stride.  */
2814             case GFC_ISYM_LBOUND:
2815             case GFC_ISYM_UBOUND:
2816               break;
2817             default:
2818               continue;
2819             }
2820
2821         case GFC_SS_CONSTRUCTOR:
2822         case GFC_SS_FUNCTION:
2823           for (n = 0; n < ss->data.info.dimen; n++)
2824             {
2825               ss->data.info.start[n] = gfc_index_zero_node;
2826               ss->data.info.end[n] = gfc_index_zero_node;
2827               ss->data.info.stride[n] = gfc_index_one_node;
2828             }
2829           break;
2830
2831         default:
2832           break;
2833         }
2834     }
2835
2836   /* The rest is just runtime bound checking.  */
2837   if (flag_bounds_check)
2838     {
2839       stmtblock_t block;
2840       tree lbound, ubound;
2841       tree end;
2842       tree size[GFC_MAX_DIMENSIONS];
2843       tree stride_pos, stride_neg, non_zerosized, tmp2;
2844       gfc_ss_info *info;
2845       char *msg;
2846       int dim;
2847
2848       gfc_start_block (&block);
2849
2850       for (n = 0; n < loop->dimen; n++)
2851         size[n] = NULL_TREE;
2852
2853       for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
2854         {
2855           if (ss->type != GFC_SS_SECTION)
2856             continue;
2857
2858           /* TODO: range checking for mapped dimensions.  */
2859           info = &ss->data.info;
2860
2861           /* This code only checks ranges.  Elemental and vector
2862              dimensions are checked later.  */
2863           for (n = 0; n < loop->dimen; n++)
2864             {
2865               bool check_upper;
2866
2867               dim = info->dim[n];
2868               if (info->ref->u.ar.dimen_type[dim] != DIMEN_RANGE)
2869                 continue;
2870
2871               if (n == info->ref->u.ar.dimen - 1
2872                   && (info->ref->u.ar.as->type == AS_ASSUMED_SIZE
2873                       || info->ref->u.ar.as->cp_was_assumed))
2874                 check_upper = false;
2875               else
2876                 check_upper = true;
2877
2878               /* Zero stride is not allowed.  */
2879               tmp = fold_build2 (EQ_EXPR, boolean_type_node, info->stride[n],
2880                                  gfc_index_zero_node);
2881               asprintf (&msg, "Zero stride is not allowed, for dimension %d "
2882                         "of array '%s'", info->dim[n]+1,
2883                         ss->expr->symtree->name);
2884               gfc_trans_runtime_check (tmp, &block, &ss->expr->where, msg);
2885               gfc_free (msg);
2886
2887               desc = ss->data.info.descriptor;
2888
2889               /* This is the run-time equivalent of resolve.c's
2890                  check_dimension().  The logical is more readable there
2891                  than it is here, with all the trees.  */
2892               lbound = gfc_conv_array_lbound (desc, dim);
2893               end = info->end[n];
2894               if (check_upper)
2895                 ubound = gfc_conv_array_ubound (desc, dim);
2896               else
2897                 ubound = NULL;
2898
2899               /* non_zerosized is true when the selected range is not
2900                  empty.  */
2901               stride_pos = fold_build2 (GT_EXPR, boolean_type_node,
2902                                         info->stride[n], gfc_index_zero_node);
2903               tmp = fold_build2 (LE_EXPR, boolean_type_node, info->start[n],
2904                                  end);
2905               stride_pos = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
2906                                         stride_pos, tmp);
2907
2908               stride_neg = fold_build2 (LT_EXPR, boolean_type_node,
2909                                         info->stride[n], gfc_index_zero_node);
2910               tmp = fold_build2 (GE_EXPR, boolean_type_node, info->start[n],
2911                                  end);
2912               stride_neg = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
2913                                         stride_neg, tmp);
2914               non_zerosized = fold_build2 (TRUTH_OR_EXPR, boolean_type_node,
2915                                            stride_pos, stride_neg);
2916
2917               /* Check the start of the range against the lower and upper
2918                  bounds of the array, if the range is not empty.  */
2919               tmp = fold_build2 (LT_EXPR, boolean_type_node, info->start[n],
2920                                  lbound);
2921               tmp = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
2922                                  non_zerosized, tmp);
2923               asprintf (&msg, "%s, lower bound of dimension %d of array '%s'"
2924                         " exceeded, %%ld is smaller than %%ld", gfc_msg_fault,
2925                         info->dim[n]+1, ss->expr->symtree->name);
2926               gfc_trans_runtime_check (tmp, &block, &ss->expr->where, msg,
2927                                        fold_convert (long_integer_type_node,
2928                                                      info->start[n]),
2929                                        fold_convert (long_integer_type_node,
2930                                                      lbound));
2931               gfc_free (msg);
2932
2933               if (check_upper)
2934                 {
2935                   tmp = fold_build2 (GT_EXPR, boolean_type_node,
2936                                      info->start[n], ubound);
2937                   tmp = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
2938                                      non_zerosized, tmp);
2939                   asprintf (&msg, "%s, upper bound of dimension %d of array "
2940                             "'%s' exceeded, %%ld is greater than %%ld",
2941                             gfc_msg_fault, info->dim[n]+1,
2942                             ss->expr->symtree->name);
2943                   gfc_trans_runtime_check (tmp, &block, &ss->expr->where, msg,
2944                         fold_convert (long_integer_type_node, info->start[n]),
2945                         fold_convert (long_integer_type_node, ubound));
2946                   gfc_free (msg);
2947                 }
2948
2949               /* Compute the last element of the range, which is not
2950                  necessarily "end" (think 0:5:3, which doesn't contain 5)
2951                  and check it against both lower and upper bounds.  */
2952               tmp2 = fold_build2 (MINUS_EXPR, gfc_array_index_type, end,
2953                                   info->start[n]);
2954               tmp2 = fold_build2 (TRUNC_MOD_EXPR, gfc_array_index_type, tmp2,
2955                                   info->stride[n]);
2956               tmp2 = fold_build2 (MINUS_EXPR, gfc_array_index_type, end,
2957                                   tmp2);
2958
2959               tmp = fold_build2 (LT_EXPR, boolean_type_node, tmp2, lbound);
2960               tmp = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
2961                                  non_zerosized, tmp);
2962               asprintf (&msg, "%s, lower bound of dimension %d of array '%s'"
2963                         " exceeded, %%ld is smaller than %%ld", gfc_msg_fault,
2964                         info->dim[n]+1, ss->expr->symtree->name);
2965               gfc_trans_runtime_check (tmp, &block, &ss->expr->where, msg,
2966                                        fold_convert (long_integer_type_node,
2967                                                      tmp2),
2968                                        fold_convert (long_integer_type_node,
2969                                                      lbound));
2970               gfc_free (msg);
2971
2972               if (check_upper)
2973                 {
2974                   tmp = fold_build2 (GT_EXPR, boolean_type_node, tmp2, ubound);
2975                   tmp = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
2976                                      non_zerosized, tmp);
2977                   asprintf (&msg, "%s, upper bound of dimension %d of array "
2978                             "'%s' exceeded, %%ld is greater than %%ld",
2979                             gfc_msg_fault, info->dim[n]+1,
2980                             ss->expr->symtree->name);
2981                   gfc_trans_runtime_check (tmp, &block, &ss->expr->where, msg,
2982                         fold_convert (long_integer_type_node, tmp2),
2983                         fold_convert (long_integer_type_node, ubound));
2984                   gfc_free (msg);
2985                 }
2986
2987               /* Check the section sizes match.  */
2988               tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type, end,
2989                                  info->start[n]);
2990               tmp = fold_build2 (FLOOR_DIV_EXPR, gfc_array_index_type, tmp,
2991                                  info->stride[n]);
2992               /* We remember the size of the first section, and check all the
2993                  others against this.  */
2994               if (size[n])
2995                 {
2996                   tree tmp3
2997                     = fold_build2 (NE_EXPR, boolean_type_node, tmp, size[n]);
2998                   asprintf (&msg, "%s, size mismatch for dimension %d "
2999                             "of array '%s' (%%ld/%%ld)", gfc_msg_bounds,
3000                             info->dim[n]+1, ss->expr->symtree->name);
3001                   gfc_trans_runtime_check (tmp3, &block, &ss->expr->where, msg,
3002                         fold_convert (long_integer_type_node, tmp),
3003                         fold_convert (long_integer_type_node, size[n]));
3004                   gfc_free (msg);
3005                 }
3006               else
3007                 size[n] = gfc_evaluate_now (tmp, &block);
3008             }
3009         }
3010
3011       tmp = gfc_finish_block (&block);
3012       gfc_add_expr_to_block (&loop->pre, tmp);
3013     }
3014 }
3015
3016
3017 /* Return true if the two SS could be aliased, i.e. both point to the same data
3018    object.  */
3019 /* TODO: resolve aliases based on frontend expressions.  */
3020
3021 static int
3022 gfc_could_be_alias (gfc_ss * lss, gfc_ss * rss)
3023 {
3024   gfc_ref *lref;
3025   gfc_ref *rref;
3026   gfc_symbol *lsym;
3027   gfc_symbol *rsym;
3028
3029   lsym = lss->expr->symtree->n.sym;
3030   rsym = rss->expr->symtree->n.sym;
3031   if (gfc_symbols_could_alias (lsym, rsym))
3032     return 1;
3033
3034   if (rsym->ts.type != BT_DERIVED
3035       && lsym->ts.type != BT_DERIVED)
3036     return 0;
3037
3038   /* For derived types we must check all the component types.  We can ignore
3039      array references as these will have the same base type as the previous
3040      component ref.  */
3041   for (lref = lss->expr->ref; lref != lss->data.info.ref; lref = lref->next)
3042     {
3043       if (lref->type != REF_COMPONENT)
3044         continue;
3045
3046       if (gfc_symbols_could_alias (lref->u.c.sym, rsym))
3047         return 1;
3048
3049       for (rref = rss->expr->ref; rref != rss->data.info.ref;
3050            rref = rref->next)
3051         {
3052           if (rref->type != REF_COMPONENT)
3053             continue;
3054
3055           if (gfc_symbols_could_alias (lref->u.c.sym, rref->u.c.sym))
3056             return 1;
3057         }
3058     }
3059
3060   for (rref = rss->expr->ref; rref != rss->data.info.ref; rref = rref->next)
3061     {
3062       if (rref->type != REF_COMPONENT)
3063         break;
3064
3065       if (gfc_symbols_could_alias (rref->u.c.sym, lsym))
3066         return 1;
3067     }
3068
3069   return 0;
3070 }
3071
3072
3073 /* Resolve array data dependencies.  Creates a temporary if required.  */
3074 /* TODO: Calc dependencies with gfc_expr rather than gfc_ss, and move to
3075    dependency.c.  */
3076
3077 void
3078 gfc_conv_resolve_dependencies (gfc_loopinfo * loop, gfc_ss * dest,
3079                                gfc_ss * rss)
3080 {
3081   gfc_ss *ss;
3082   gfc_ref *lref;
3083   gfc_ref *rref;
3084   gfc_ref *aref;
3085   int nDepend = 0;
3086   int temp_dim = 0;
3087
3088   loop->temp_ss = NULL;
3089   aref = dest->data.info.ref;
3090   temp_dim = 0;
3091
3092   for (ss = rss; ss != gfc_ss_terminator; ss = ss->next)
3093     {
3094       if (ss->type != GFC_SS_SECTION)
3095         continue;
3096
3097       if (gfc_could_be_alias (dest, ss)
3098             || gfc_are_equivalenced_arrays (dest->expr, ss->expr))
3099         {
3100           nDepend = 1;
3101           break;
3102         }
3103
3104       if (dest->expr->symtree->n.sym == ss->expr->symtree->n.sym)
3105         {
3106           lref = dest->expr->ref;
3107           rref = ss->expr->ref;
3108
3109           nDepend = gfc_dep_resolver (lref, rref);
3110           if (nDepend == 1)
3111             break;
3112 #if 0
3113           /* TODO : loop shifting.  */
3114           if (nDepend == 1)
3115             {
3116               /* Mark the dimensions for LOOP SHIFTING */
3117               for (n = 0; n < loop->dimen; n++)
3118                 {
3119                   int dim = dest->data.info.dim[n];
3120
3121                   if (lref->u.ar.dimen_type[dim] == DIMEN_VECTOR)
3122                     depends[n] = 2;
3123                   else if (! gfc_is_same_range (&lref->u.ar,
3124                                                 &rref->u.ar, dim, 0))
3125                     depends[n] = 1;
3126                  }
3127
3128               /* Put all the dimensions with dependencies in the
3129                  innermost loops.  */
3130               dim = 0;
3131               for (n = 0; n < loop->dimen; n++)
3132                 {
3133                   gcc_assert (loop->order[n] == n);
3134                   if (depends[n])
3135                   loop->order[dim++] = n;
3136                 }
3137               temp_dim = dim;
3138               for (n = 0; n < loop->dimen; n++)
3139                 {
3140                   if (! depends[n])
3141                   loop->order[dim++] = n;
3142                 }
3143
3144               gcc_assert (dim == loop->dimen);
3145               break;
3146             }
3147 #endif
3148         }
3149     }
3150
3151   if (nDepend == 1)
3152     {
3153       tree base_type = gfc_typenode_for_spec (&dest->expr->ts);
3154       if (GFC_ARRAY_TYPE_P (base_type)
3155           || GFC_DESCRIPTOR_TYPE_P (base_type))
3156         base_type = gfc_get_element_type (base_type);
3157       loop->temp_ss = gfc_get_ss ();
3158       loop->temp_ss->type = GFC_SS_TEMP;
3159       loop->temp_ss->data.temp.type = base_type;
3160       loop->temp_ss->string_length = dest->string_length;
3161       loop->temp_ss->data.temp.dimen = loop->dimen;
3162       loop->temp_ss->next = gfc_ss_terminator;
3163       gfc_add_ss_to_loop (loop, loop->temp_ss);
3164     }
3165   else
3166     loop->temp_ss = NULL;
3167 }
3168
3169
3170 /* Initialize the scalarization loop.  Creates the loop variables.  Determines
3171    the range of the loop variables.  Creates a temporary if required.
3172    Calculates how to transform from loop variables to array indices for each
3173    expression.  Also generates code for scalar expressions which have been
3174    moved outside the loop.  */
3175
3176 void
3177 gfc_conv_loop_setup (gfc_loopinfo * loop)
3178 {
3179   int n;
3180   int dim;
3181   gfc_ss_info *info;
3182   gfc_ss_info *specinfo;
3183   gfc_ss *ss;
3184   tree tmp;
3185   tree len;
3186   gfc_ss *loopspec[GFC_MAX_DIMENSIONS];
3187   bool dynamic[GFC_MAX_DIMENSIONS];
3188   gfc_constructor *c;
3189   mpz_t *cshape;
3190   mpz_t i;
3191
3192   mpz_init (i);
3193   for (n = 0; n < loop->dimen; n++)
3194     {
3195       loopspec[n] = NULL;
3196       dynamic[n] = false;
3197       /* We use one SS term, and use that to determine the bounds of the
3198          loop for this dimension.  We try to pick the simplest term.  */
3199       for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
3200         {
3201           if (ss->shape)
3202             {
3203               /* The frontend has worked out the size for us.  */
3204               loopspec[n] = ss;
3205               continue;
3206             }
3207
3208           if (ss->type == GFC_SS_CONSTRUCTOR)
3209             {
3210               /* An unknown size constructor will always be rank one.
3211                  Higher rank constructors will either have known shape,
3212                  or still be wrapped in a call to reshape.  */
3213               gcc_assert (loop->dimen == 1);
3214
3215               /* Always prefer to use the constructor bounds if the size
3216                  can be determined at compile time.  Prefer not to otherwise,
3217                  since the general case involves realloc, and it's better to
3218                  avoid that overhead if possible.  */
3219               c = ss->expr->value.constructor;
3220               dynamic[n] = gfc_get_array_constructor_size (&i, c);
3221               if (!dynamic[n] || !loopspec[n])
3222                 loopspec[n] = ss;
3223               continue;
3224             }
3225
3226           /* TODO: Pick the best bound if we have a choice between a
3227              function and something else.  */
3228           if (ss->type == GFC_SS_FUNCTION)
3229             {
3230               loopspec[n] = ss;
3231               continue;
3232             }
3233
3234           if (ss->type != GFC_SS_SECTION)
3235             continue;
3236
3237           if (loopspec[n])
3238             specinfo = &loopspec[n]->data.info;
3239           else
3240             specinfo = NULL;
3241           info = &ss->data.info;
3242
3243           if (!specinfo)
3244             loopspec[n] = ss;
3245           /* Criteria for choosing a loop specifier (most important first):
3246              doesn't need realloc
3247              stride of one
3248              known stride
3249              known lower bound
3250              known upper bound
3251            */
3252           else if (loopspec[n]->type == GFC_SS_CONSTRUCTOR && dynamic[n])
3253             loopspec[n] = ss;
3254           else if (integer_onep (info->stride[n])
3255                    && !integer_onep (specinfo->stride[n]))
3256             loopspec[n] = ss;
3257           else if (INTEGER_CST_P (info->stride[n])
3258                    && !INTEGER_CST_P (specinfo->stride[n]))
3259             loopspec[n] = ss;
3260           else if (INTEGER_CST_P (info->start[n])
3261                    && !INTEGER_CST_P (specinfo->start[n]))
3262             loopspec[n] = ss;
3263           /* We don't work out the upper bound.
3264              else if (INTEGER_CST_P (info->finish[n])
3265              && ! INTEGER_CST_P (specinfo->finish[n]))
3266              loopspec[n] = ss; */
3267         }
3268
3269       if (!loopspec[n])
3270         gfc_todo_error ("Unable to find scalarization loop specifier");
3271
3272       info = &loopspec[n]->data.info;
3273
3274       /* Set the extents of this range.  */
3275       cshape = loopspec[n]->shape;
3276       if (cshape && INTEGER_CST_P (info->start[n])
3277           && INTEGER_CST_P (info->stride[n]))
3278         {
3279           loop->from[n] = info->start[n];
3280           mpz_set (i, cshape[n]);
3281           mpz_sub_ui (i, i, 1);
3282           /* To = from + (size - 1) * stride.  */
3283           tmp = gfc_conv_mpz_to_tree (i, gfc_index_integer_kind);
3284           if (!integer_onep (info->stride[n]))
3285             tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
3286                                tmp, info->stride[n]);
3287           loop->to[n] = fold_build2 (PLUS_EXPR, gfc_array_index_type,
3288                                      loop->from[n], tmp);
3289         }
3290       else
3291         {
3292           loop->from[n] = info->start[n];
3293           switch (loopspec[n]->type)
3294             {
3295             case GFC_SS_CONSTRUCTOR:
3296               /* The upper bound is calculated when we expand the
3297                  constructor.  */
3298               gcc_assert (loop->to[n] == NULL_TREE);
3299               break;
3300
3301             case GFC_SS_SECTION:
3302               loop->to[n] = gfc_conv_section_upper_bound (loopspec[n], n,
3303                                                           &loop->pre);
3304               break;
3305
3306             case GFC_SS_FUNCTION:
3307               /* The loop bound will be set when we generate the call.  */
3308               gcc_assert (loop->to[n] == NULL_TREE);
3309               break;
3310
3311             default:
3312               gcc_unreachable ();
3313             }
3314         }
3315
3316       /* Transform everything so we have a simple incrementing variable.  */
3317       if (integer_onep (info->stride[n]))
3318         info->delta[n] = gfc_index_zero_node;
3319       else
3320         {
3321           /* Set the delta for this section.  */
3322           info->delta[n] = gfc_evaluate_now (loop->from[n], &loop->pre);
3323           /* Number of iterations is (end - start + step) / step.
3324              with start = 0, this simplifies to
3325              last = end / step;
3326              for (i = 0; i<=last; i++){...};  */
3327           tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
3328                              loop->to[n], loop->from[n]);
3329           tmp = fold_build2 (TRUNC_DIV_EXPR, gfc_array_index_type, 
3330                              tmp, info->stride[n]);
3331           loop->to[n] = gfc_evaluate_now (tmp, &loop->pre);
3332           /* Make the loop variable start at 0.  */
3333           loop->from[n] = gfc_index_zero_node;
3334         }
3335     }
3336
3337   /* Add all the scalar code that can be taken out of the loops.
3338      This may include calculating the loop bounds, so do it before
3339      allocating the temporary.  */
3340   gfc_add_loop_ss_code (loop, loop->ss, false);
3341
3342   /* If we want a temporary then create it.  */
3343   if (loop->temp_ss != NULL)
3344     {
3345       gcc_assert (loop->temp_ss->type == GFC_SS_TEMP);
3346       tmp = loop->temp_ss->data.temp.type;
3347       len = loop->temp_ss->string_length;
3348       n = loop->temp_ss->data.temp.dimen;
3349       memset (&loop->temp_ss->data.info, 0, sizeof (gfc_ss_info));
3350       loop->temp_ss->type = GFC_SS_SECTION;
3351       loop->temp_ss->data.info.dimen = n;
3352       gfc_trans_create_temp_array (&loop->pre, &loop->post, loop,
3353                                    &loop->temp_ss->data.info, tmp, false, true,
3354                                    false);
3355     }
3356
3357   for (n = 0; n < loop->temp_dim; n++)
3358     loopspec[loop->order[n]] = NULL;
3359
3360   mpz_clear (i);
3361
3362   /* For array parameters we don't have loop variables, so don't calculate the
3363      translations.  */
3364   if (loop->array_parameter)
3365     return;
3366
3367   /* Calculate the translation from loop variables to array indices.  */
3368   for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
3369     {
3370       if (ss->type != GFC_SS_SECTION && ss->type != GFC_SS_COMPONENT)
3371         continue;
3372
3373       info = &ss->data.info;
3374
3375       for (n = 0; n < info->dimen; n++)
3376         {
3377           dim = info->dim[n];
3378
3379           /* If we are specifying the range the delta is already set.  */
3380           if (loopspec[n] != ss)
3381             {
3382               /* Calculate the offset relative to the loop variable.
3383                  First multiply by the stride.  */
3384               tmp = loop->from[n];
3385               if (!integer_onep (info->stride[n]))
3386                 tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
3387                                    tmp, info->stride[n]);
3388
3389               /* Then subtract this from our starting value.  */
3390               tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
3391                                  info->start[n], tmp);
3392
3393               info->delta[n] = gfc_evaluate_now (tmp, &loop->pre);
3394             }
3395         }
3396     }
3397 }
3398
3399
3400 /* Fills in an array descriptor, and returns the size of the array.  The size
3401    will be a simple_val, ie a variable or a constant.  Also calculates the
3402    offset of the base.  Returns the size of the array.
3403    {
3404     stride = 1;
3405     offset = 0;
3406     for (n = 0; n < rank; n++)
3407       {
3408         a.lbound[n] = specified_lower_bound;
3409         offset = offset + a.lbond[n] * stride;
3410         size = 1 - lbound;
3411         a.ubound[n] = specified_upper_bound;
3412         a.stride[n] = stride;
3413         size = ubound + size; //size = ubound + 1 - lbound
3414         stride = stride * size;
3415       }
3416     return (stride);
3417    }  */
3418 /*GCC ARRAYS*/
3419
3420 static tree
3421 gfc_array_init_size (tree descriptor, int rank, tree * poffset,
3422                      gfc_expr ** lower, gfc_expr ** upper,
3423                      stmtblock_t * pblock)
3424 {
3425   tree type;
3426   tree tmp;
3427   tree size;
3428   tree offset;
3429   tree stride;
3430   tree cond;
3431   tree or_expr;
3432   tree thencase;
3433   tree elsecase;
3434   tree var;
3435   stmtblock_t thenblock;
3436   stmtblock_t elseblock;
3437   gfc_expr *ubound;
3438   gfc_se se;
3439   int n;
3440
3441   type = TREE_TYPE (descriptor);
3442
3443   stride = gfc_index_one_node;
3444   offset = gfc_index_zero_node;
3445
3446   /* Set the dtype.  */
3447   tmp = gfc_conv_descriptor_dtype (descriptor);
3448   gfc_add_modify_expr (pblock, tmp, gfc_get_dtype (TREE_TYPE (descriptor)));
3449
3450   or_expr = NULL_TREE;
3451
3452   for (n = 0; n < rank; n++)
3453     {
3454       /* We have 3 possibilities for determining the size of the array:
3455          lower == NULL    => lbound = 1, ubound = upper[n]
3456          upper[n] = NULL  => lbound = 1, ubound = lower[n]
3457          upper[n] != NULL => lbound = lower[n], ubound = upper[n]  */
3458       ubound = upper[n];
3459
3460       /* Set lower bound.  */
3461       gfc_init_se (&se, NULL);
3462       if (lower == NULL)
3463         se.expr = gfc_index_one_node;
3464       else
3465         {
3466           gcc_assert (lower[n]);
3467           if (ubound)
3468             {
3469               gfc_conv_expr_type (&se, lower[n], gfc_array_index_type);
3470               gfc_add_block_to_block (pblock, &se.pre);
3471             }
3472           else
3473             {
3474               se.expr = gfc_index_one_node;
3475               ubound = lower[n];
3476             }
3477         }
3478       tmp = gfc_conv_descriptor_lbound (descriptor, gfc_rank_cst[n]);
3479       gfc_add_modify_expr (pblock, tmp, se.expr);
3480
3481       /* Work out the offset for this component.  */
3482       tmp = fold_build2 (MULT_EXPR, gfc_array_index_type, se.expr, stride);
3483       offset = fold_build2 (MINUS_EXPR, gfc_array_index_type, offset, tmp);
3484
3485       /* Start the calculation for the size of this dimension.  */
3486       size = build2 (MINUS_EXPR, gfc_array_index_type,
3487                      gfc_index_one_node, se.expr);
3488
3489       /* Set upper bound.  */
3490       gfc_init_se (&se, NULL);
3491       gcc_assert (ubound);
3492       gfc_conv_expr_type (&se, ubound, gfc_array_index_type);
3493       gfc_add_block_to_block (pblock, &se.pre);
3494
3495       tmp = gfc_conv_descriptor_ubound (descriptor, gfc_rank_cst[n]);
3496       gfc_add_modify_expr (pblock, tmp, se.expr);
3497
3498       /* Store the stride.  */
3499       tmp = gfc_conv_descriptor_stride (descriptor, gfc_rank_cst[n]);
3500       gfc_add_modify_expr (pblock, tmp, stride);
3501
3502       /* Calculate the size of this dimension.  */
3503       size = fold_build2 (PLUS_EXPR, gfc_array_index_type, se.expr, size);
3504
3505       /* Check whether the size for this dimension is negative.  */
3506       cond = fold_build2 (LE_EXPR, boolean_type_node, size,
3507                           gfc_index_zero_node);
3508       if (n == 0)
3509         or_expr = cond;
3510       else
3511         or_expr = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, or_expr, cond);
3512
3513       /* Multiply the stride by the number of elements in this dimension.  */
3514       stride = fold_build2 (MULT_EXPR, gfc_array_index_type, stride, size);
3515       stride = gfc_evaluate_now (stride, pblock);
3516     }
3517
3518   /* The stride is the number of elements in the array, so multiply by the
3519      size of an element to get the total size.  */
3520   tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type));
3521   size = fold_build2 (MULT_EXPR, gfc_array_index_type, stride,
3522                       fold_convert (gfc_array_index_type, tmp));
3523
3524   if (poffset != NULL)
3525     {
3526       offset = gfc_evaluate_now (offset, pblock);
3527       *poffset = offset;
3528     }
3529
3530   if (integer_zerop (or_expr))
3531     return size;
3532   if (integer_onep (or_expr))
3533     return gfc_index_zero_node;
3534
3535   var = gfc_create_var (TREE_TYPE (size), "size");
3536   gfc_start_block (&thenblock);
3537   gfc_add_modify_expr (&thenblock, var, gfc_index_zero_node);
3538   thencase = gfc_finish_block (&thenblock);
3539
3540   gfc_start_block (&elseblock);
3541   gfc_add_modify_expr (&elseblock, var, size);
3542   elsecase = gfc_finish_block (&elseblock);
3543
3544   tmp = gfc_evaluate_now (or_expr, pblock);
3545   tmp = build3_v (COND_EXPR, tmp, thencase, elsecase);
3546   gfc_add_expr_to_block (pblock, tmp);
3547
3548   return var;
3549 }
3550
3551
3552 /* Initializes the descriptor and generates a call to _gfor_allocate.  Does
3553    the work for an ALLOCATE statement.  */
3554 /*GCC ARRAYS*/
3555
3556 bool
3557 gfc_array_allocate (gfc_se * se, gfc_expr * expr, tree pstat)
3558 {
3559   tree tmp;
3560   tree pointer;
3561   tree offset;
3562   tree size;
3563   gfc_expr **lower;
3564   gfc_expr **upper;
3565   gfc_ref *ref, *prev_ref = NULL;
3566   bool allocatable_array;
3567
3568   ref = expr->ref;
3569
3570   /* Find the last reference in the chain.  */
3571   while (ref && ref->next != NULL)
3572     {
3573       gcc_assert (ref->type != REF_ARRAY || ref->u.ar.type == AR_ELEMENT);
3574       prev_ref = ref;
3575       ref = ref->next;
3576     }
3577
3578   if (ref == NULL || ref->type != REF_ARRAY)
3579     return false;
3580
3581   if (!prev_ref)
3582     allocatable_array = expr->symtree->n.sym->attr.allocatable;
3583   else
3584     allocatable_array = prev_ref->u.c.component->allocatable;
3585
3586   /* Figure out the size of the array.  */
3587   switch (ref->u.ar.type)
3588     {
3589     case AR_ELEMENT:
3590       lower = NULL;
3591       upper = ref->u.ar.start;
3592       break;
3593
3594     case AR_FULL:
3595       gcc_assert (ref->u.ar.as->type == AS_EXPLICIT);
3596
3597       lower = ref->u.ar.as->lower;
3598       upper = ref->u.ar.as->upper;
3599       break;
3600
3601     case AR_SECTION:
3602       lower = ref->u.ar.start;
3603       upper = ref->u.ar.end;
3604       break;
3605
3606     default:
3607       gcc_unreachable ();
3608       break;
3609     }
3610
3611   size = gfc_array_init_size (se->expr, ref->u.ar.as->rank, &offset,
3612                               lower, upper, &se->pre);
3613
3614   /* Allocate memory to store the data.  */
3615   pointer = gfc_conv_descriptor_data_get (se->expr);
3616   STRIP_NOPS (pointer);
3617
3618   /* The allocate_array variants take the old pointer as first argument.  */
3619   if (allocatable_array)
3620     tmp = gfc_allocate_array_with_status (&se->pre, pointer, size, pstat);
3621   else
3622     tmp = gfc_allocate_with_status (&se->pre, size, pstat);
3623   tmp = build2 (MODIFY_EXPR, void_type_node, pointer, tmp);
3624   gfc_add_expr_to_block (&se->pre, tmp);
3625
3626   tmp = gfc_conv_descriptor_offset (se->expr);
3627   gfc_add_modify_expr (&se->pre, tmp, offset);
3628
3629   if (expr->ts.type == BT_DERIVED
3630         && expr->ts.derived->attr.alloc_comp)
3631     {
3632       tmp = gfc_nullify_alloc_comp (expr->ts.derived, se->expr,
3633                                     ref->u.ar.as->rank);
3634       gfc_add_expr_to_block (&se->pre, tmp);
3635     }
3636
3637   return true;
3638 }
3639
3640
3641 /* Deallocate an array variable.  Also used when an allocated variable goes
3642    out of scope.  */
3643 /*GCC ARRAYS*/
3644
3645 tree
3646 gfc_array_deallocate (tree descriptor, tree pstat)
3647 {
3648   tree var;
3649   tree tmp;
3650   stmtblock_t block;
3651
3652   gfc_start_block (&block);
3653   /* Get a pointer to the data.  */
3654   var = gfc_conv_descriptor_data_get (descriptor);
3655   STRIP_NOPS (var);
3656
3657   /* Parameter is the address of the data component.  */
3658   tmp = gfc_deallocate_with_status (var, pstat, false);
3659   gfc_add_expr_to_block (&block, tmp);
3660
3661   /* Zero the data pointer.  */
3662   tmp = build2 (MODIFY_EXPR, void_type_node,
3663                 var, build_int_cst (TREE_TYPE (var), 0));
3664   gfc_add_expr_to_block (&block, tmp);
3665
3666   return gfc_finish_block (&block);
3667 }
3668
3669
3670 /* Create an array constructor from an initialization expression.
3671    We assume the frontend already did any expansions and conversions.  */
3672
3673 tree
3674 gfc_conv_array_initializer (tree type, gfc_expr * expr)
3675 {
3676   gfc_constructor *c;
3677   tree tmp;
3678   mpz_t maxval;
3679   gfc_se se;
3680   HOST_WIDE_INT hi;
3681   unsigned HOST_WIDE_INT lo;
3682   tree index, range;
3683   VEC(constructor_elt,gc) *v = NULL;
3684
3685   switch (expr->expr_type)
3686     {
3687     case EXPR_CONSTANT:
3688     case EXPR_STRUCTURE:
3689       /* A single scalar or derived type value.  Create an array with all
3690          elements equal to that value.  */
3691       gfc_init_se (&se, NULL);
3692       
3693       if (expr->expr_type == EXPR_CONSTANT)
3694         gfc_conv_constant (&se, expr);
3695       else
3696         gfc_conv_structure (&se, expr, 1);
3697
3698       tmp = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
3699       gcc_assert (tmp && INTEGER_CST_P (tmp));
3700       hi = TREE_INT_CST_HIGH (tmp);
3701       lo = TREE_INT_CST_LOW (tmp);
3702       lo++;
3703       if (lo == 0)
3704         hi++;
3705       /* This will probably eat buckets of memory for large arrays.  */
3706       while (hi != 0 || lo != 0)
3707         {
3708           CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, se.expr);
3709           if (lo == 0)
3710             hi--;
3711           lo--;
3712         }
3713       break;
3714
3715     case EXPR_ARRAY:
3716       /* Create a vector of all the elements.  */
3717       for (c = expr->value.constructor; c; c = c->next)
3718         {
3719           if (c->iterator)
3720             {
3721               /* Problems occur when we get something like
3722                  integer :: a(lots) = (/(i, i=1,lots)/)  */
3723               /* TODO: Unexpanded array initializers.  */
3724               internal_error
3725                 ("Possible frontend bug: array constructor not expanded");
3726             }
3727           if (mpz_cmp_si (c->n.offset, 0) != 0)
3728             index = gfc_conv_mpz_to_tree (c->n.offset, gfc_index_integer_kind);
3729           else
3730             index = NULL_TREE;
3731           mpz_init (maxval);
3732           if (mpz_cmp_si (c->repeat, 0) != 0)
3733             {
3734               tree tmp1, tmp2;
3735
3736               mpz_set (maxval, c->repeat);
3737               mpz_add (maxval, c->n.offset, maxval);
3738               mpz_sub_ui (maxval, maxval, 1);
3739               tmp2 = gfc_conv_mpz_to_tree (maxval, gfc_index_integer_kind);
3740               if (mpz_cmp_si (c->n.offset, 0) != 0)
3741                 {
3742                   mpz_add_ui (maxval, c->n.offset, 1);
3743                   tmp1 = gfc_conv_mpz_to_tree (maxval, gfc_index_integer_kind);
3744                 }
3745               else
3746                 tmp1 = gfc_conv_mpz_to_tree (c->n.offset, gfc_index_integer_kind);
3747
3748               range = build2 (RANGE_EXPR, integer_type_node, tmp1, tmp2);
3749             }
3750           else
3751             range = NULL;
3752           mpz_clear (maxval);
3753
3754           gfc_init_se (&se, NULL);
3755           switch (c->expr->expr_type)
3756             {
3757             case EXPR_CONSTANT:
3758               gfc_conv_constant (&se, c->expr);
3759               if (range == NULL_TREE)
3760                 CONSTRUCTOR_APPEND_ELT (v, index, se.expr);
3761               else
3762                 {
3763                   if (index != NULL_TREE)
3764                     CONSTRUCTOR_APPEND_ELT (v, index, se.expr);
3765                   CONSTRUCTOR_APPEND_ELT (v, range, se.expr);
3766                 }
3767               break;
3768
3769             case EXPR_STRUCTURE:
3770               gfc_conv_structure (&se, c->expr, 1);
3771               CONSTRUCTOR_APPEND_ELT (v, index, se.expr);
3772               break;
3773
3774             default:
3775               gcc_unreachable ();
3776             }
3777         }
3778       break;
3779
3780     case EXPR_NULL:
3781       return gfc_build_null_descriptor (type);
3782
3783     default:
3784       gcc_unreachable ();
3785     }
3786
3787   /* Create a constructor from the list of elements.  */
3788   tmp = build_constructor (type, v);
3789   TREE_CONSTANT (tmp) = 1;
3790   TREE_INVARIANT (tmp) = 1;
3791   return tmp;
3792 }
3793
3794
3795 /* Generate code to evaluate non-constant array bounds.  Sets *poffset and
3796    returns the size (in elements) of the array.  */
3797
3798 static tree
3799 gfc_trans_array_bounds (tree type, gfc_symbol * sym, tree * poffset,
3800                         stmtblock_t * pblock)
3801 {
3802   gfc_array_spec *as;
3803   tree size;
3804   tree stride;
3805   tree offset;
3806   tree ubound;
3807   tree lbound;
3808   tree tmp;
3809   gfc_se se;
3810
3811   int dim;
3812
3813   as = sym->as;
3814
3815   size = gfc_index_one_node;
3816   offset = gfc_index_zero_node;
3817   for (dim = 0; dim < as->rank; dim++)
3818     {
3819       /* Evaluate non-constant array bound expressions.  */
3820       lbound = GFC_TYPE_ARRAY_LBOUND (type, dim);
3821       if (as->lower[dim] && !INTEGER_CST_P (lbound))
3822         {
3823           gfc_init_se (&se, NULL);
3824           gfc_conv_expr_type (&se, as->lower[dim], gfc_array_index_type);
3825           gfc_add_block_to_block (pblock, &se.pre);
3826           gfc_add_modify_expr (pblock, lbound, se.expr);
3827         }
3828       ubound = GFC_TYPE_ARRAY_UBOUND (type, dim);
3829       if (as->upper[dim] && !INTEGER_CST_P (ubound))
3830         {
3831           gfc_init_se (&se, NULL);
3832           gfc_conv_expr_type (&se, as->upper[dim], gfc_array_index_type);
3833           gfc_add_block_to_block (pblock, &se.pre);
3834           gfc_add_modify_expr (pblock, ubound, se.expr);
3835         }
3836       /* The offset of this dimension.  offset = offset - lbound * stride.  */
3837       tmp = fold_build2 (MULT_EXPR, gfc_array_index_type, lbound, size);
3838       offset = fold_build2 (MINUS_EXPR, gfc_array_index_type, offset, tmp);
3839
3840       /* The size of this dimension, and the stride of the next.  */
3841       if (dim + 1 < as->rank)
3842         stride = GFC_TYPE_ARRAY_STRIDE (type, dim + 1);
3843       else
3844         stride = GFC_TYPE_ARRAY_SIZE (type);
3845
3846       if (ubound != NULL_TREE && !(stride && INTEGER_CST_P (stride)))
3847         {
3848           /* Calculate stride = size * (ubound + 1 - lbound).  */
3849           tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
3850                              gfc_index_one_node, lbound);
3851           tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type, ubound, tmp);
3852           tmp = fold_build2 (MULT_EXPR, gfc_array_index_type, size, tmp);
3853           if (stride)
3854             gfc_add_modify_expr (pblock, stride, tmp);
3855           else
3856             stride = gfc_evaluate_now (tmp, pblock);
3857
3858           /* Make sure that negative size arrays are translated
3859              to being zero size.  */
3860           tmp = build2 (GE_EXPR, boolean_type_node,
3861                         stride, gfc_index_zero_node);
3862           tmp = build3 (COND_EXPR, gfc_array_index_type, tmp,
3863                         stride, gfc_index_zero_node);
3864           gfc_add_modify_expr (pblock, stride, tmp);
3865         }
3866
3867       size = stride;
3868     }
3869
3870   gfc_trans_vla_type_sizes (sym, pblock);
3871
3872   *poffset = offset;
3873   return size;
3874 }
3875
3876
3877 /* Generate code to initialize/allocate an array variable.  */
3878
3879 tree
3880 gfc_trans_auto_array_allocation (tree decl, gfc_symbol * sym, tree fnbody)
3881 {
3882   stmtblock_t block;
3883   tree type;
3884   tree tmp;
3885   tree size;
3886   tree offset;
3887   bool onstack;
3888
3889   gcc_assert (!(sym->attr.pointer || sym->attr.allocatable));
3890
3891   /* Do nothing for USEd variables.  */
3892   if (sym->attr.use_assoc)
3893     return fnbody;
3894
3895   type = TREE_TYPE (decl);
3896   gcc_assert (GFC_ARRAY_TYPE_P (type));
3897   onstack = TREE_CODE (type) != POINTER_TYPE;
3898
3899   gfc_start_block (&block);
3900
3901   /* Evaluate character string length.  */
3902   if (sym->ts.type == BT_CHARACTER
3903       && onstack && !INTEGER_CST_P (sym->ts.cl->backend_decl))
3904     {
3905       gfc_conv_string_length (sym->ts.cl, &block);
3906
3907       gfc_trans_vla_type_sizes (sym, &block);
3908
3909       /* Emit a DECL_EXPR for this variable, which will cause the
3910          gimplifier to allocate storage, and all that good stuff.  */
3911       tmp = build1 (DECL_EXPR, TREE_TYPE (decl), decl);
3912       gfc_add_expr_to_block (&block, tmp);
3913     }
3914
3915   if (onstack)
3916     {
3917       gfc_add_expr_to_block (&block, fnbody);
3918       return gfc_finish_block (&block);
3919     }
3920
3921   type = TREE_TYPE (type);
3922
3923   gcc_assert (!sym->attr.use_assoc);
3924   gcc_assert (!TREE_STATIC (decl));
3925   gcc_assert (!sym->module);
3926
3927   if (sym->ts.type == BT_CHARACTER
3928       && !INTEGER_CST_P (sym->ts.cl->backend_decl))
3929     gfc_conv_string_length (sym->ts.cl, &block);
3930
3931   size = gfc_trans_array_bounds (type, sym, &offset, &block);
3932
3933   /* Don't actually allocate space for Cray Pointees.  */
3934   if (sym->attr.cray_pointee)
3935     {
3936       if (TREE_CODE (GFC_TYPE_ARRAY_OFFSET (type)) == VAR_DECL)
3937         gfc_add_modify_expr (&block, GFC_TYPE_ARRAY_OFFSET (type), offset);
3938       gfc_add_expr_to_block (&block, fnbody);
3939       return gfc_finish_block (&block);
3940     }
3941
3942   /* The size is the number of elements in the array, so multiply by the
3943      size of an element to get the total size.  */
3944   tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type));
3945   size = fold_build2 (MULT_EXPR, gfc_array_index_type, size,
3946                       fold_convert (gfc_array_index_type, tmp));
3947
3948   /* Allocate memory to hold the data.  */
3949   tmp = gfc_call_malloc (&block, TREE_TYPE (decl), size);
3950   gfc_add_modify_expr (&block, decl, tmp);
3951
3952   /* Set offset of the array.  */
3953   if (TREE_CODE (GFC_TYPE_ARRAY_OFFSET (type)) == VAR_DECL)
3954     gfc_add_modify_expr (&block, GFC_TYPE_ARRAY_OFFSET (type), offset);
3955
3956
3957   /* Automatic arrays should not have initializers.  */
3958   gcc_assert (!sym->value);
3959
3960   gfc_add_expr_to_block (&block, fnbody);
3961
3962   /* Free the temporary.  */
3963   tmp = gfc_call_free (convert (pvoid_type_node, decl));
3964   gfc_add_expr_to_block (&block, tmp);
3965
3966   return gfc_finish_block (&block);
3967 }
3968
3969
3970 /* Generate entry and exit code for g77 calling convention arrays.  */
3971
3972 tree
3973 gfc_trans_g77_array (gfc_symbol * sym, tree body)
3974 {
3975   tree parm;
3976   tree type;
3977   locus loc;
3978   tree offset;
3979   tree tmp;
3980   tree stmt;  
3981   stmtblock_t block;
3982
3983   gfc_get_backend_locus (&loc);
3984   gfc_set_backend_locus (&sym->declared_at);
3985
3986   /* Descriptor type.  */
3987   parm = sym->backend_decl;
3988   type = TREE_TYPE (parm);
3989   gcc_assert (GFC_ARRAY_TYPE_P (type));
3990
3991   gfc_start_block (&block);
3992
3993   if (sym->ts.type == BT_CHARACTER
3994       && TREE_CODE (sym->ts.cl->backend_decl) == VAR_DECL)
3995     gfc_conv_string_length (sym->ts.cl, &block);
3996
3997   /* Evaluate the bounds of the array.  */
3998   gfc_trans_array_bounds (type, sym, &offset, &block);
3999
4000   /* Set the offset.  */
4001   if (TREE_CODE (GFC_TYPE_ARRAY_OFFSET (type)) == VAR_DECL)
4002     gfc_add_modify_expr (&block, GFC_TYPE_ARRAY_OFFSET (type), offset);
4003
4004   /* Set the pointer itself if we aren't using the parameter directly.  */
4005   if (TREE_CODE (parm) != PARM_DECL)
4006     {
4007       tmp = convert (TREE_TYPE (parm), GFC_DECL_SAVED_DESCRIPTOR (parm));
4008       gfc_add_modify_expr (&block, parm, tmp);
4009     }
4010   stmt = gfc_finish_block (&block);
4011
4012   gfc_set_backend_locus (&loc);
4013
4014   gfc_start_block (&block);
4015
4016   /* Add the initialization code to the start of the function.  */
4017
4018   if (sym->attr.optional || sym->attr.not_always_present)
4019     {
4020       tmp = gfc_conv_expr_present (sym);
4021       stmt = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt ());
4022     }
4023   
4024   gfc_add_expr_to_block (&block, stmt);
4025   gfc_add_expr_to_block (&block, body);
4026
4027   return gfc_finish_block (&block);
4028 }
4029
4030
4031 /* Modify the descriptor of an array parameter so that it has the
4032    correct lower bound.  Also move the upper bound accordingly.
4033    If the array is not packed, it will be copied into a temporary.
4034    For each dimension we set the new lower and upper bounds.  Then we copy the
4035    stride and calculate the offset for this dimension.  We also work out
4036    what the stride of a packed array would be, and see it the two match.
4037    If the array need repacking, we set the stride to the values we just
4038    calculated, recalculate the offset and copy the array data.
4039    Code is also added to copy the data back at the end of the function.
4040    */
4041
4042 tree
4043 gfc_trans_dummy_array_bias (gfc_symbol * sym, tree tmpdesc, tree body)
4044 {
4045   tree size;
4046   tree type;
4047   tree offset;
4048   locus loc;
4049   stmtblock_t block;
4050   stmtblock_t cleanup;
4051   tree lbound;
4052   tree ubound;
4053   tree dubound;
4054   tree dlbound;
4055   tree dumdesc;
4056   tree tmp;
4057   tree stmt;
4058   tree stride, stride2;
4059   tree stmt_packed;
4060   tree stmt_unpacked;
4061   tree partial;
4062   gfc_se se;
4063   int n;
4064   int checkparm;
4065   int no_repack;
4066   bool optional_arg;
4067
4068   /* Do nothing for pointer and allocatable arrays.  */
4069   if (sym->attr.pointer || sym->attr.allocatable)
4070     return body;
4071
4072   if (sym->attr.dummy && gfc_is_nodesc_array (sym))
4073     return gfc_trans_g77_array (sym, body);
4074
4075   gfc_get_backend_locus (&loc);
4076   gfc_set_backend_locus (&sym->declared_at);
4077
4078   /* Descriptor type.  */
4079   type = TREE_TYPE (tmpdesc);
4080   gcc_assert (GFC_ARRAY_TYPE_P (type));
4081   dumdesc = GFC_DECL_SAVED_DESCRIPTOR (tmpdesc);
4082   dumdesc = build_fold_indirect_ref (dumdesc);
4083   gfc_start_block (&block);
4084
4085   if (sym->ts.type == BT_CHARACTER
4086       && TREE_CODE (sym->ts.cl->backend_decl) == VAR_DECL)
4087     gfc_conv_string_length (sym->ts.cl, &block);
4088
4089   checkparm = (sym->as->type == AS_EXPLICIT && flag_bounds_check);
4090
4091   no_repack = !(GFC_DECL_PACKED_ARRAY (tmpdesc)
4092                 || GFC_DECL_PARTIAL_PACKED_ARRAY (tmpdesc));
4093
4094   if (GFC_DECL_PARTIAL_PACKED_ARRAY (tmpdesc))
4095     {
4096       /* For non-constant shape arrays we only check if the first dimension
4097          is contiguous.  Repacking higher dimensions wouldn't gain us
4098          anything as we still don't know the array stride.  */
4099       partial = gfc_create_var (boolean_type_node, "partial");
4100       TREE_USED (partial) = 1;
4101       tmp = gfc_conv_descriptor_stride (dumdesc, gfc_rank_cst[0]);
4102       tmp = fold_build2 (EQ_EXPR, boolean_type_node, tmp, gfc_index_one_node);
4103       gfc_add_modify_expr (&block, partial, tmp);
4104     }
4105   else
4106     {
4107       partial = NULL_TREE;
4108     }
4109
4110   /* The naming of stmt_unpacked and stmt_packed may be counter-intuitive
4111      here, however I think it does the right thing.  */
4112   if (no_repack)
4113     {
4114       /* Set the first stride.  */
4115       stride = gfc_conv_descriptor_stride (dumdesc, gfc_rank_cst[0]);
4116       stride = gfc_evaluate_now (stride, &block);
4117
4118       tmp = build2 (EQ_EXPR, boolean_type_node, stride, gfc_index_zero_node);
4119       tmp = build3 (COND_EXPR, gfc_array_index_type, tmp,
4120                     gfc_index_one_node, stride);
4121       stride = GFC_TYPE_ARRAY_STRIDE (type, 0);
4122       gfc_add_modify_expr (&block, stride, tmp);
4123
4124       /* Allow the user to disable array repacking.  */
4125       stmt_unpacked = NULL_TREE;
4126     }
4127   else
4128     {
4129       gcc_assert (integer_onep (GFC_TYPE_ARRAY_STRIDE (type, 0)));
4130       /* A library call to repack the array if necessary.  */
4131       tmp = GFC_DECL_SAVED_DESCRIPTOR (tmpdesc);
4132       stmt_unpacked = build_call_expr (gfor_fndecl_in_pack, 1, tmp);
4133
4134       stride = gfc_index_one_node;
4135     }
4136
4137   /* This is for the case where the array data is used directly without
4138      calling the repack function.  */
4139   if (no_repack || partial != NULL_TREE)
4140     stmt_packed = gfc_conv_descriptor_data_get (dumdesc);
4141   else
4142     stmt_packed = NULL_TREE;
4143
4144   /* Assign the data pointer.  */
4145   if (stmt_packed != NULL_TREE && stmt_unpacked != NULL_TREE)
4146     {
4147       /* Don't repack unknown shape arrays when the first stride is 1.  */
4148       tmp = build3 (COND_EXPR, TREE_TYPE (stmt_packed), partial,
4149                     stmt_packed, stmt_unpacked);
4150     }
4151   else
4152     tmp = stmt_packed != NULL_TREE ? stmt_packed : stmt_unpacked;
4153   gfc_add_modify_expr (&block, tmpdesc, fold_convert (type, tmp));
4154
4155   offset = gfc_index_zero_node;
4156   size = gfc_index_one_node;
4157
4158   /* Evaluate the bounds of the array.  */
4159   for (n = 0; n < sym->as->rank; n++)
4160     {
4161       if (checkparm || !sym->as->upper[n])
4162         {
4163           /* Get the bounds of the actual parameter.  */
4164           dubound = gfc_conv_descriptor_ubound (dumdesc, gfc_rank_cst[n]);
4165           dlbound = gfc_conv_descriptor_lbound (dumdesc, gfc_rank_cst[n]);
4166         }
4167       else
4168         {
4169           dubound = NULL_TREE;
4170           dlbound = NULL_TREE;
4171         }
4172
4173       lbound = GFC_TYPE_ARRAY_LBOUND (type, n);
4174       if (!INTEGER_CST_P (lbound))
4175         {
4176           gfc_init_se (&se, NULL);
4177           gfc_conv_expr_type (&se, sym->as->lower[n],
4178                               gfc_array_index_type);
4179           gfc_add_block_to_block (&block, &se.pre);
4180           gfc_add_modify_expr (&block, lbound, se.expr);
4181         }
4182
4183       ubound = GFC_TYPE_ARRAY_UBOUND (type, n);
4184       /* Set the desired upper bound.  */
4185       if (sym->as->upper[n])
4186         {
4187           /* We know what we want the upper bound to be.  */
4188           if (!INTEGER_CST_P (ubound))
4189             {
4190               gfc_init_se (&se, NULL);
4191               gfc_conv_expr_type (&se, sym->as->upper[n],
4192                                   gfc_array_index_type);
4193               gfc_add_block_to_block (&block, &se.pre);
4194               gfc_add_modify_expr (&block, ubound, se.expr);
4195             }
4196
4197           /* Check the sizes match.  */
4198           if (checkparm)
4199             {
4200               /* Check (ubound(a) - lbound(a) == ubound(b) - lbound(b)).  */
4201               char * msg;
4202
4203               tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
4204                                  ubound, lbound);
4205               stride2 = build2 (MINUS_EXPR, gfc_array_index_type,
4206                                dubound, dlbound);
4207               tmp = fold_build2 (NE_EXPR, gfc_array_index_type, tmp, stride2);
4208               asprintf (&msg, "%s for dimension %d of array '%s'",
4209                         gfc_msg_bounds, n+1, sym->name);
4210               gfc_trans_runtime_check (tmp, &block, &loc, msg);
4211               gfc_free (msg);
4212             }
4213         }
4214       else
4215         {
4216           /* For assumed shape arrays move the upper bound by the same amount
4217              as the lower bound.  */
4218           tmp = build2 (MINUS_EXPR, gfc_array_index_type, dubound, dlbound);
4219           tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type, tmp, lbound);
4220           gfc_add_modify_expr (&block, ubound, tmp);
4221         }
4222       /* The offset of this dimension.  offset = offset - lbound * stride.  */
4223       tmp = fold_build2 (MULT_EXPR, gfc_array_index_type, lbound, stride);
4224       offset = fold_build2 (MINUS_EXPR, gfc_array_index_type, offset, tmp);
4225
4226       /* The size of this dimension, and the stride of the next.  */
4227       if (n + 1 < sym->as->rank)
4228         {
4229           stride = GFC_TYPE_ARRAY_STRIDE (type, n + 1);
4230
4231           if (no_repack || partial != NULL_TREE)
4232             {
4233               stmt_unpacked =
4234                 gfc_conv_descriptor_stride (dumdesc, gfc_rank_cst[n+1]);
4235             }
4236
4237           /* Figure out the stride if not a known constant.  */
4238           if (!INTEGER_CST_P (stride))
4239             {
4240               if (no_repack)
4241                 stmt_packed = NULL_TREE;
4242               else
4243                 {
4244                   /* Calculate stride = size * (ubound + 1 - lbound).  */
4245                   tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
4246                                      gfc_index_one_node, lbound);
4247                   tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
4248                                      ubound, tmp);
4249                   size = fold_build2 (MULT_EXPR, gfc_array_index_type,
4250                                       size, tmp);
4251                   stmt_packed = size;
4252                 }
4253
4254               /* Assign the stride.  */
4255               if (stmt_packed != NULL_TREE && stmt_unpacked != NULL_TREE)
4256                 tmp = build3 (COND_EXPR, gfc_array_index_type, partial,
4257                               stmt_unpacked, stmt_packed);
4258               else
4259                 tmp = (stmt_packed != NULL_TREE) ? stmt_packed : stmt_unpacked;
4260               gfc_add_modify_expr (&block, stride, tmp);
4261             }
4262         }
4263       else
4264         {
4265           stride = GFC_TYPE_ARRAY_SIZE (type);
4266
4267           if (stride && !INTEGER_CST_P (stride))
4268             {
4269               /* Calculate size = stride * (ubound + 1 - lbound).  */
4270               tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
4271                                  gfc_index_one_node, lbound);
4272               tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
4273                                  ubound, tmp);
4274               tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
4275                                  GFC_TYPE_ARRAY_STRIDE (type, n), tmp);
4276               gfc_add_modify_expr (&block, stride, tmp);
4277             }
4278         }
4279     }
4280
4281   /* Set the offset.  */
4282   if (TREE_CODE (GFC_TYPE_ARRAY_OFFSET (type)) == VAR_DECL)
4283     gfc_add_modify_expr (&block, GFC_TYPE_ARRAY_OFFSET (type), offset);
4284
4285   gfc_trans_vla_type_sizes (sym, &block);
4286
4287   stmt = gfc_finish_block (&block);
4288
4289   gfc_start_block (&block);
4290
4291   /* Only do the entry/initialization code if the arg is present.  */
4292   dumdesc = GFC_DECL_SAVED_DESCRIPTOR (tmpdesc);
4293   optional_arg = (sym->attr.optional
4294                   || (sym->ns->proc_name->attr.entry_master
4295                       && sym->attr.dummy));
4296   if (optional_arg)
4297     {
4298       tmp = gfc_conv_expr_present (sym);
4299       stmt = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt ());
4300     }
4301   gfc_add_expr_to_block (&block, stmt);
4302
4303   /* Add the main function body.  */
4304   gfc_add_expr_to_block (&block, body);
4305
4306   /* Cleanup code.  */
4307   if (!no_repack)
4308     {
4309       gfc_start_block (&cleanup);
4310       
4311       if (sym->attr.intent != INTENT_IN)
4312         {
4313           /* Copy the data back.  */
4314           tmp = build_call_expr (gfor_fndecl_in_unpack, 2, dumdesc, tmpdesc);
4315           gfc_add_expr_to_block (&cleanup, tmp);
4316         }
4317
4318       /* Free the temporary.  */
4319       tmp = gfc_call_free (tmpdesc);
4320       gfc_add_expr_to_block (&cleanup, tmp);
4321
4322       stmt = gfc_finish_block (&cleanup);
4323         
4324       /* Only do the cleanup if the array was repacked.  */
4325       tmp = build_fold_indirect_ref (dumdesc);
4326       tmp = gfc_conv_descriptor_data_get (tmp);
4327       tmp = build2 (NE_EXPR, boolean_type_node, tmp, tmpdesc);
4328       stmt = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt ());
4329
4330       if (optional_arg)
4331         {
4332           tmp = gfc_conv_expr_present (sym);
4333           stmt = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt ());
4334         }
4335       gfc_add_expr_to_block (&block, stmt);
4336     }
4337   /* We don't need to free any memory allocated by internal_pack as it will
4338      be freed at the end of the function by pop_context.  */
4339   return gfc_finish_block (&block);
4340 }
4341
4342
4343 /* Calculate the overall offset, including subreferences.  */
4344 static void
4345 gfc_get_dataptr_offset (stmtblock_t *block, tree parm, tree desc, tree offset,
4346                         bool subref, gfc_expr *expr)
4347 {
4348   tree tmp;
4349   tree field;
4350   tree stride;
4351   tree index;
4352   gfc_ref *ref;
4353   gfc_se start;
4354   int n;
4355
4356   /* If offset is NULL and this is not a subreferenced array, there is
4357      nothing to do.  */
4358   if (offset == NULL_TREE)
4359     {
4360       if (subref)
4361         offset = gfc_index_zero_node;
4362       else
4363         return;
4364     }
4365
4366   tmp = gfc_conv_array_data (desc);
4367   tmp = build_fold_indirect_ref (tmp);
4368   tmp = gfc_build_array_ref (tmp, offset, NULL);
4369
4370   /* Offset the data pointer for pointer assignments from arrays with
4371      subreferences; eg. my_integer => my_type(:)%integer_component.  */
4372   if (subref)
4373     {
4374       /* Go past the array reference.  */
4375       for (ref = expr->ref; ref; ref = ref->next)
4376         if (ref->type == REF_ARRAY &&
4377               ref->u.ar.type != AR_ELEMENT)
4378           {
4379             ref = ref->next;
4380             break;
4381           }
4382
4383       /* Calculate the offset for each subsequent subreference.  */
4384       for (; ref; ref = ref->next)
4385         {
4386           switch (ref->type)
4387             {
4388             case REF_COMPONENT:
4389               field = ref->u.c.component->backend_decl;
4390               gcc_assert (field && TREE_CODE (field) == FIELD_DECL);
4391               tmp = build3 (COMPONENT_REF, TREE_TYPE (field), tmp, field, NULL_TREE);
4392               break;
4393
4394             case REF_SUBSTRING:
4395               gcc_assert (TREE_CODE (TREE_TYPE (tmp)) == ARRAY_TYPE);
4396               gfc_init_se (&start, NULL);
4397               gfc_conv_expr_type (&start, ref->u.ss.start, gfc_charlen_type_node);
4398               gfc_add_block_to_block (block, &start.pre);
4399               tmp = gfc_build_array_ref (tmp, start.expr, NULL);
4400               break;
4401
4402             case REF_ARRAY:
4403               gcc_assert (TREE_CODE (TREE_TYPE (tmp)) == ARRAY_TYPE
4404                             && ref->u.ar.type == AR_ELEMENT);
4405
4406               /* TODO - Add bounds checking.  */
4407               stride = gfc_index_one_node;
4408               index = gfc_index_zero_node;
4409               for (n = 0; n < ref->u.ar.dimen; n++)
4410                 {
4411                   tree itmp;
4412                   tree jtmp;
4413
4414                   /* Update the index.  */
4415                   gfc_init_se (&start, NULL);
4416                   gfc_conv_expr_type (&start, ref->u.ar.start[n], gfc_array_index_type);
4417                   itmp = gfc_evaluate_now (start.expr, block);
4418                   gfc_init_se (&start, NULL);
4419                   gfc_conv_expr_type (&start, ref->u.ar.as->lower[n], gfc_array_index_type);
4420                   jtmp = gfc_evaluate_now (start.expr, block);
4421                   itmp = fold_build2 (MINUS_EXPR, gfc_array_index_type, itmp, jtmp);
4422                   itmp = fold_build2 (MULT_EXPR, gfc_array_index_type, itmp, stride);
4423                   index = fold_build2 (PLUS_EXPR, gfc_array_index_type, itmp, index);
4424                   index = gfc_evaluate_now (index, block);
4425
4426                   /* Update the stride.  */
4427                   gfc_init_se (&start, NULL);
4428                   gfc_conv_expr_type (&start, ref->u.ar.as->upper[n], gfc_array_index_type);
4429                   itmp =  fold_build2 (MINUS_EXPR, gfc_array_index_type, start.expr, jtmp);
4430                   itmp =  fold_build2 (PLUS_EXPR, gfc_array_index_type,
4431                                        gfc_index_one_node, itmp);
4432                   stride =  fold_build2 (MULT_EXPR, gfc_array_index_type, stride, itmp);
4433                   stride = gfc_evaluate_now (stride, block);
4434                 }
4435
4436               /* Apply the index to obtain the array element.  */
4437               tmp = gfc_build_array_ref (tmp, index, NULL);
4438               break;
4439
4440             default:
4441               gcc_unreachable ();
4442               break;
4443             }
4444         }
4445     }
4446
4447   /* Set the target data pointer.  */
4448   offset = gfc_build_addr_expr (gfc_array_dataptr_type (desc), tmp);
4449   gfc_conv_descriptor_data_set (block, parm, offset);
4450 }
4451
4452
4453 /* Convert an array for passing as an actual argument.  Expressions and
4454    vector subscripts are evaluated and stored in a temporary, which is then
4455    passed.  For whole arrays the descriptor is passed.  For array sections
4456    a modified copy of the descriptor is passed, but using the original data.
4457
4458    This function is also used for array pointer assignments, and there
4459    are three cases:
4460
4461      - se->want_pointer && !se->direct_byref
4462          EXPR is an actual argument.  On exit, se->expr contains a
4463          pointer to the array descriptor.
4464
4465      - !se->want_pointer && !se->direct_byref
4466          EXPR is an actual argument to an intrinsic function or the
4467          left-hand side of a pointer assignment.  On exit, se->expr
4468          contains the descriptor for EXPR.
4469
4470      - !se->want_pointer && se->direct_byref
4471          EXPR is the right-hand side of a pointer assignment and
4472          se->expr is the descriptor for the previously-evaluated
4473          left-hand side.  The function creates an assignment from
4474          EXPR to se->expr.  */
4475
4476 void
4477 gfc_conv_expr_descriptor (gfc_se * se, gfc_expr * expr, gfc_ss * ss)
4478 {
4479   gfc_loopinfo loop;
4480   gfc_ss *secss;
4481   gfc_ss_info *info;
4482   int need_tmp;
4483   int n;
4484   tree tmp;
4485   tree desc;
4486   stmtblock_t block;
4487   tree start;
4488   tree offset;
4489   int full;
4490   bool subref_array_target = false;
4491
4492   gcc_assert (ss != gfc_ss_terminator);
4493
4494   /* Special case things we know we can pass easily.  */
4495   switch (expr->expr_type)
4496     {
4497     case EXPR_VARIABLE:
4498       /* If we have a linear array section, we can pass it directly.
4499          Otherwise we need to copy it into a temporary.  */
4500
4501       /* Find the SS for the array section.  */
4502       secss = ss;
4503       while (secss != gfc_ss_terminator && secss->type != GFC_SS_SECTION)
4504         secss = secss->next;
4505
4506       gcc_assert (secss != gfc_ss_terminator);
4507       info = &secss->data.info;
4508
4509       /* Get the descriptor for the array.  */
4510       gfc_conv_ss_descriptor (&se->pre, secss, 0);
4511       desc = info->descriptor;
4512
4513       subref_array_target = se->direct_byref && is_subref_array (expr);
4514       need_tmp = gfc_ref_needs_temporary_p (expr->ref)
4515                         && !subref_array_target;
4516
4517       if (need_tmp)
4518         full = 0;
4519       else if (GFC_ARRAY_TYPE_P (TREE_TYPE (desc)))
4520         {
4521           /* Create a new descriptor if the array doesn't have one.  */
4522           full = 0;
4523         }
4524       else if (info->ref->u.ar.type == AR_FULL)
4525         full = 1;
4526       else if (se->direct_byref)
4527         full = 0;
4528       else
4529         full = gfc_full_array_ref_p (info->ref);
4530
4531       if (full)
4532         {
4533           if (se->direct_byref)
4534             {
4535               /* Copy the descriptor for pointer assignments.  */
4536               gfc_add_modify_expr (&se->pre, se->expr, desc);
4537
4538               /* Add any offsets from subreferences.  */
4539               gfc_get_dataptr_offset (&se->pre, se->expr, desc, NULL_TREE,
4540                                       subref_array_target, expr);
4541             }
4542           else if (se->want_pointer)
4543             {
4544               /* We pass full arrays directly.  This means that pointers and
4545                  allocatable arrays should also work.  */
4546               se->expr = build_fold_addr_expr (desc);
4547             }
4548           else
4549             {
4550               se->expr = desc;
4551             }
4552
4553           if (expr->ts.type == BT_CHARACTER)
4554             se->string_length = gfc_get_expr_charlen (expr);
4555
4556           return;
4557         }
4558       break;
4559       
4560     case EXPR_FUNCTION:
4561       /* A transformational function return value will be a temporary
4562          array descriptor.  We still need to go through the scalarizer
4563          to create the descriptor.  Elemental functions ar handled as
4564          arbitrary expressions, i.e. copy to a temporary.  */
4565       secss = ss;
4566       /* Look for the SS for this function.  */
4567       while (secss != gfc_ss_terminator
4568              && (secss->type != GFC_SS_FUNCTION || secss->expr != expr))
4569         secss = secss->next;
4570
4571       if (se->direct_byref)
4572         {
4573           gcc_assert (secss != gfc_ss_terminator);
4574
4575           /* For pointer assignments pass the descriptor directly.  */
4576           se->ss = secss;
4577           se->expr = build_fold_addr_expr (se->expr);
4578           gfc_conv_expr (se, expr);
4579           return;
4580         }
4581
4582       if (secss == gfc_ss_terminator)
4583         {
4584           /* Elemental function.  */
4585           need_tmp = 1;
4586           info = NULL;
4587         }
4588       else
4589         {
4590           /* Transformational function.  */
4591           info = &secss->data.info;
4592           need_tmp = 0;
4593         }
4594       break;
4595
4596     case EXPR_ARRAY:
4597       /* Constant array constructors don't need a temporary.  */
4598       if (ss->type == GFC_SS_CONSTRUCTOR
4599           && expr->ts.type != BT_CHARACTER
4600           && gfc_constant_array_constructor_p (expr->value.constructor))
4601         {
4602           need_tmp = 0;
4603           info = &ss->data.info;
4604           secss = ss;
4605         }
4606       else
4607         {
4608           need_tmp = 1;
4609           secss = NULL;
4610           info = NULL;
4611         }
4612       break;
4613
4614     default:
4615       /* Something complicated.  Copy it into a temporary.  */
4616       need_tmp = 1;
4617       secss = NULL;
4618       info = NULL;
4619       break;
4620     }
4621
4622
4623   gfc_init_loopinfo (&loop);
4624
4625   /* Associate the SS with the loop.  */
4626   gfc_add_ss_to_loop (&loop, ss);
4627
4628   /* Tell the scalarizer not to bother creating loop variables, etc.  */
4629   if (!need_tmp)
4630     loop.array_parameter = 1;
4631   else
4632     /* The right-hand side of a pointer assignment mustn't use a temporary.  */
4633     gcc_assert (!se->direct_byref);
4634
4635   /* Setup the scalarizing loops and bounds.  */
4636   gfc_conv_ss_startstride (&loop);
4637
4638   if (need_tmp)
4639     {
4640       /* Tell the scalarizer to make a temporary.  */
4641       loop.temp_ss = gfc_get_ss ();
4642       loop.temp_ss->type = GFC_SS_TEMP;
4643       loop.temp_ss->next = gfc_ss_terminator;
4644
4645       if (expr->ts.type == BT_CHARACTER && !expr->ts.cl->backend_decl)
4646         gfc_conv_string_length (expr->ts.cl, &se->pre);
4647
4648       loop.temp_ss->data.temp.type = gfc_typenode_for_spec (&expr->ts);
4649
4650       if (expr->ts.type == BT_CHARACTER)
4651         loop.temp_ss->string_length = expr->ts.cl->backend_decl;
4652       else
4653         loop.temp_ss->string_length = NULL;
4654
4655       se->string_length = loop.temp_ss->string_length;
4656       loop.temp_ss->data.temp.dimen = loop.dimen;
4657       gfc_add_ss_to_loop (&loop, loop.temp_ss);
4658     }
4659
4660   gfc_conv_loop_setup (&loop);
4661
4662   if (need_tmp)
4663     {
4664       /* Copy into a temporary and pass that.  We don't need to copy the data
4665          back because expressions and vector subscripts must be INTENT_IN.  */
4666       /* TODO: Optimize passing function return values.  */
4667       gfc_se lse;
4668       gfc_se rse;
4669
4670       /* Start the copying loops.  */
4671       gfc_mark_ss_chain_used (loop.temp_ss, 1);
4672       gfc_mark_ss_chain_used (ss, 1);
4673       gfc_start_scalarized_body (&loop, &block);
4674
4675       /* Copy each data element.  */
4676       gfc_init_se (&lse, NULL);
4677       gfc_copy_loopinfo_to_se (&lse, &loop);
4678       gfc_init_se (&rse, NULL);
4679       gfc_copy_loopinfo_to_se (&rse, &loop);
4680
4681       lse.ss = loop.temp_ss;
4682       rse.ss = ss;
4683
4684       gfc_conv_scalarized_array_ref (&lse, NULL);
4685       if (expr->ts.type == BT_CHARACTER)
4686         {
4687           gfc_conv_expr (&rse, expr);
4688           if (POINTER_TYPE_P (TREE_TYPE (rse.expr)))
4689             rse.expr = build_fold_indirect_ref (rse.expr);
4690         }
4691       else
4692         gfc_conv_expr_val (&rse, expr);
4693
4694       gfc_add_block_to_block (&block, &rse.pre);
4695       gfc_add_block_to_block (&block, &lse.pre);
4696
4697       gfc_add_modify_expr (&block, lse.expr, rse.expr);
4698
4699       /* Finish the copying loops.  */
4700       gfc_trans_scalarizing_loops (&loop, &block);
4701
4702       desc = loop.temp_ss->data.info.descriptor;
4703
4704       gcc_assert (is_gimple_lvalue (desc));
4705     }
4706   else if (expr->expr_type == EXPR_FUNCTION)
4707     {
4708       desc = info->descriptor;
4709       se->string_length = ss->string_length;
4710     }
4711   else
4712     {
4713       /* We pass sections without copying to a temporary.  Make a new
4714          descriptor and point it at the section we want.  The loop variable
4715          limits will be the limits of the section.
4716          A function may decide to repack the array to speed up access, but
4717          we're not bothered about that here.  */
4718       int dim, ndim;
4719       tree parm;
4720       tree parmtype;
4721       tree stride;
4722       tree from;
4723       tree to;
4724       tree base;
4725
4726       /* Set the string_length for a character array.  */
4727       if (expr->ts.type == BT_CHARACTER)
4728         se->string_length =  gfc_get_expr_charlen (expr);
4729
4730       desc = info->descriptor;
4731       gcc_assert (secss && secss != gfc_ss_terminator);
4732       if (se->direct_byref)
4733         {
4734           /* For pointer assignments we fill in the destination.  */
4735           parm = se->expr;
4736           parmtype = TREE_TYPE (parm);
4737         }
4738       else
4739         {
4740           /* Otherwise make a new one.  */
4741           parmtype = gfc_get_element_type (TREE_TYPE (desc));
4742           parmtype = gfc_get_array_type_bounds (parmtype, loop.dimen,
4743                                                 loop.from, loop.to, 0);
4744           parm = gfc_create_var (parmtype, "parm");
4745         }
4746
4747       offset = gfc_index_zero_node;
4748       dim = 0;
4749
4750       /* The following can be somewhat confusing.  We have two
4751          descriptors, a new one and the original array.
4752          {parm, parmtype, dim} refer to the new one.
4753          {desc, type, n, secss, loop} refer to the original, which maybe
4754          a descriptorless array.
4755          The bounds of the scalarization are the bounds of the section.
4756          We don't have to worry about numeric overflows when calculating
4757          the offsets because all elements are within the array data.  */
4758
4759       /* Set the dtype.  */
4760       tmp = gfc_conv_descriptor_dtype (parm);
4761       gfc_add_modify_expr (&loop.pre, tmp, gfc_get_dtype (parmtype));
4762
4763       /* Set offset for assignments to pointer only to zero if it is not
4764          the full array.  */
4765       if (se->direct_byref
4766           && info->ref && info->ref->u.ar.type != AR_FULL)
4767         base = gfc_index_zero_node;
4768       else if (GFC_ARRAY_TYPE_P (TREE_TYPE (desc)))
4769         base = gfc_evaluate_now (gfc_conv_array_offset (desc), &loop.pre);
4770       else
4771         base = NULL_TREE;
4772
4773       ndim = info->ref ? info->ref->u.ar.dimen : info->dimen;
4774       for (n = 0; n < ndim; n++)
4775         {
4776           stride = gfc_conv_array_stride (desc, n);
4777
4778           /* Work out the offset.  */
4779           if (info->ref
4780               && info->ref->u.ar.dimen_type[n] == DIMEN_ELEMENT)
4781             {
4782               gcc_assert (info->subscript[n]
4783                       && info->subscript[n]->type == GFC_SS_SCALAR);
4784               start = info->subscript[n]->data.scalar.expr;
4785             }
4786           else
4787             {
4788               /* Check we haven't somehow got out of sync.  */
4789               gcc_assert (info->dim[dim] == n);
4790
4791               /* Evaluate and remember the start of the section.  */
4792               start = info->start[dim];
4793               stride = gfc_evaluate_now (stride, &loop.pre);
4794             }
4795
4796           tmp = gfc_conv_array_lbound (desc, n);
4797           tmp = fold_build2 (MINUS_EXPR, TREE_TYPE (tmp), start, tmp);
4798
4799           tmp = fold_build2 (MULT_EXPR, TREE_TYPE (tmp), tmp, stride);
4800           offset = fold_build2 (PLUS_EXPR, TREE_TYPE (tmp), offset, tmp);
4801
4802           if (info->ref
4803               && info->ref->u.ar.dimen_type[n] == DIMEN_ELEMENT)
4804             {
4805               /* For elemental dimensions, we only need the offset.  */
4806               continue;
4807             }
4808
4809           /* Vector subscripts need copying and are handled elsewhere.  */
4810           if (info->ref)
4811             gcc_assert (info->ref->u.ar.dimen_type[n] == DIMEN_RANGE);
4812
4813           /* Set the new lower bound.  */
4814           from = loop.from[dim];
4815           to = loop.to[dim];
4816
4817           /* If we have an array section or are assigning make sure that
4818              the lower bound is 1.  References to the full
4819              array should otherwise keep the original bounds.  */
4820           if ((!info->ref
4821                   || info->ref->u.ar.type != AR_FULL)
4822               && !integer_onep (from))
4823             {
4824               tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
4825                                  gfc_index_one_node, from);
4826               to = fold_build2 (PLUS_EXPR, gfc_array_index_type, to, tmp);
4827               from = gfc_index_one_node;
4828             }
4829           tmp = gfc_conv_descriptor_lbound (parm, gfc_rank_cst[dim]);
4830           gfc_add_modify_expr (&loop.pre, tmp, from);
4831
4832           /* Set the new upper bound.  */
4833           tmp = gfc_conv_descriptor_ubound (parm, gfc_rank_cst[dim]);
4834           gfc_add_modify_expr (&loop.pre, tmp, to);
4835
4836           /* Multiply the stride by the section stride to get the
4837              total stride.  */
4838           stride = fold_build2 (MULT_EXPR, gfc_array_index_type,
4839                                 stride, info->stride[dim]);
4840
4841           if (se->direct_byref && info->ref && info->ref->u.ar.type != AR_FULL)
4842             {
4843               base = fold_build2 (MINUS_EXPR, TREE_TYPE (base),
4844                                   base, stride);
4845             }
4846           else if (GFC_ARRAY_TYPE_P (TREE_TYPE (desc)))
4847             {
4848               tmp = gfc_conv_array_lbound (desc, n);
4849               tmp = fold_build2 (MINUS_EXPR, TREE_TYPE (base),
4850                                  tmp, loop.from[dim]);
4851               tmp = fold_build2 (MULT_EXPR, TREE_TYPE (base),
4852                                  tmp, gfc_conv_array_stride (desc, n));
4853               base = fold_build2 (PLUS_EXPR, TREE_TYPE (base),
4854                                   tmp, base);
4855             }
4856
4857           /* Store the new stride.  */
4858           tmp = gfc_conv_descriptor_stride (parm, gfc_rank_cst[dim]);
4859           gfc_add_modify_expr (&loop.pre, tmp, stride);
4860
4861           dim++;
4862         }
4863
4864       if (se->data_not_needed)
4865         gfc_conv_descriptor_data_set (&loop.pre, parm, gfc_index_zero_node);
4866       else
4867         /* Point the data pointer at the first element in the section.  */
4868         gfc_get_dataptr_offset (&loop.pre, parm, desc, offset,
4869                                 subref_array_target, expr);
4870
4871       if ((se->direct_byref || GFC_ARRAY_TYPE_P (TREE_TYPE (desc)))
4872           && !se->data_not_needed)
4873         {
4874           /* Set the offset.  */
4875           tmp = gfc_conv_descriptor_offset (parm);
4876           gfc_add_modify_expr (&loop.pre, tmp, base);
4877         }
4878       else
4879         {
4880           /* Only the callee knows what the correct offset it, so just set
4881              it to zero here.  */
4882           tmp = gfc_conv_descriptor_offset (parm);
4883           gfc_add_modify_expr (&loop.pre, tmp, gfc_index_zero_node);
4884         }
4885       desc = parm;
4886     }
4887
4888   if (!se->direct_byref)
4889     {
4890       /* Get a pointer to the new descriptor.  */
4891       if (se->want_pointer)
4892         se->expr = build_fold_addr_expr (desc);
4893       else
4894         se->expr = desc;
4895     }
4896
4897   gfc_add_block_to_block (&se->pre, &loop.pre);
4898   gfc_add_block_to_block (&se->post, &loop.post);
4899
4900   /* Cleanup the scalarizer.  */
4901   gfc_cleanup_loop (&loop);
4902 }
4903
4904
4905 /* Convert an array for passing as an actual parameter.  */
4906 /* TODO: Optimize passing g77 arrays.  */
4907
4908 void
4909 gfc_conv_array_parameter (gfc_se * se, gfc_expr * expr, gfc_ss * ss, int g77)
4910 {
4911   tree ptr;
4912   tree desc;
4913   tree tmp = NULL_TREE;
4914   tree stmt;
4915   tree parent = DECL_CONTEXT (current_function_decl);
4916   bool full_array_var, this_array_result;
4917   gfc_symbol *sym;
4918   stmtblock_t block;
4919
4920   full_array_var = (expr->expr_type == EXPR_VARIABLE
4921                       && expr->ref->u.ar.type == AR_FULL);
4922   sym = full_array_var ? expr->symtree->n.sym : NULL;
4923
4924   if (expr->expr_type == EXPR_ARRAY && expr->ts.type == BT_CHARACTER)
4925     {
4926       get_array_ctor_strlen (&se->pre, expr->value.constructor, &tmp);
4927       expr->ts.cl->backend_decl = gfc_evaluate_now (tmp, &se->pre);
4928       se->string_length = expr->ts.cl->backend_decl;
4929     }
4930
4931   /* Is this the result of the enclosing procedure?  */
4932   this_array_result = (full_array_var && sym->attr.flavor == FL_PROCEDURE);
4933   if (this_array_result
4934         && (sym->backend_decl != current_function_decl)
4935         && (sym->backend_decl != parent))
4936     this_array_result = false;
4937
4938   /* Passing address of the array if it is not pointer or assumed-shape.  */
4939   if (full_array_var && g77 && !this_array_result)
4940     {
4941       tmp = gfc_get_symbol_decl (sym);
4942
4943       if (sym->ts.type == BT_CHARACTER)
4944         se->string_length = sym->ts.cl->backend_decl;
4945       if (!sym->attr.pointer && sym->as->type != AS_ASSUMED_SHAPE 
4946           && !sym->attr.allocatable)
4947         {
4948           /* Some variables are declared directly, others are declared as
4949              pointers and allocated on the heap.  */
4950           if (sym->attr.dummy || POINTER_TYPE_P (TREE_TYPE (tmp)))
4951             se->expr = tmp;
4952           else
4953             se->expr = build_fold_addr_expr (tmp);
4954           return;
4955         }
4956       if (sym->attr.allocatable)
4957         {
4958           if (sym->attr.dummy)
4959             {
4960               gfc_conv_expr_descriptor (se, expr, ss);
4961               se->expr = gfc_conv_array_data (se->expr);
4962             }
4963           else
4964             se->expr = gfc_conv_array_data (tmp);
4965           return;
4966         }
4967     }
4968
4969   if (this_array_result)
4970     {
4971       /* Result of the enclosing function.  */
4972       gfc_conv_expr_descriptor (se, expr, ss);
4973       se->expr = build_fold_addr_expr (se->expr);
4974
4975       if (g77 && TREE_TYPE (TREE_TYPE (se->expr)) != NULL_TREE
4976               && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (TREE_TYPE (se->expr))))
4977         se->expr = gfc_conv_array_data (build_fold_indirect_ref (se->expr));
4978
4979       return;
4980     }
4981   else
4982     {
4983       /* Every other type of array.  */
4984       se->want_pointer = 1;
4985       gfc_conv_expr_descriptor (se, expr, ss);
4986     }
4987
4988
4989   /* Deallocate the allocatable components of structures that are
4990      not variable.  */
4991   if (expr->ts.type == BT_DERIVED
4992         && expr->ts.derived->attr.alloc_comp
4993         && expr->expr_type != EXPR_VARIABLE)
4994     {
4995       tmp = build_fold_indirect_ref (se->expr);
4996       tmp = gfc_deallocate_alloc_comp (expr->ts.derived, tmp, expr->rank);
4997       gfc_add_expr_to_block (&se->post, tmp);
4998     }
4999
5000   if (g77)
5001     {
5002       desc = se->expr;
5003       /* Repack the array.  */
5004       ptr = build_call_expr (gfor_fndecl_in_pack, 1, desc);
5005       ptr = gfc_evaluate_now (ptr, &se->pre);
5006       se->expr = ptr;
5007
5008       gfc_start_block (&block);
5009
5010       /* Copy the data back.  */
5011       tmp = build_call_expr (gfor_fndecl_in_unpack, 2, desc, ptr);
5012       gfc_add_expr_to_block (&block, tmp);
5013
5014       /* Free the temporary.  */
5015       tmp = gfc_call_free (convert (pvoid_type_node, ptr));
5016       gfc_add_expr_to_block (&block, tmp);
5017
5018       stmt = gfc_finish_block (&block);
5019
5020       gfc_init_block (&block);
5021       /* Only if it was repacked.  This code needs to be executed before the
5022          loop cleanup code.  */
5023       tmp = build_fold_indirect_ref (desc);
5024       tmp = gfc_conv_array_data (tmp);
5025       tmp = build2 (NE_EXPR, boolean_type_node,
5026                     fold_convert (TREE_TYPE (tmp), ptr), tmp);
5027       tmp = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt ());
5028
5029       gfc_add_expr_to_block (&block, tmp);
5030       gfc_add_block_to_block (&block, &se->post);
5031
5032       gfc_init_block (&se->post);
5033       gfc_add_block_to_block (&se->post, &block);
5034     }
5035 }
5036
5037
5038 /* Generate code to deallocate an array, if it is allocated.  */
5039
5040 tree
5041 gfc_trans_dealloc_allocated (tree descriptor)
5042
5043   tree tmp;
5044   tree var;
5045   stmtblock_t block;
5046
5047   gfc_start_block (&block);
5048
5049   var = gfc_conv_descriptor_data_get (descriptor);
5050   STRIP_NOPS (var);
5051
5052   /* Call array_deallocate with an int * present in the second argument.
5053      Although it is ignored here, it's presence ensures that arrays that
5054      are already deallocated are ignored.  */
5055   tmp = gfc_deallocate_with_status (var, NULL_TREE, true);
5056   gfc_add_expr_to_block (&block, tmp);
5057
5058   /* Zero the data pointer.  */
5059   tmp = build2 (MODIFY_EXPR, void_type_node,
5060                 var, build_int_cst (TREE_TYPE (var), 0));
5061   gfc_add_expr_to_block (&block, tmp);
5062
5063   return gfc_finish_block (&block);
5064 }
5065
5066
5067 /* This helper function calculates the size in words of a full array.  */
5068
5069 static tree
5070 get_full_array_size (stmtblock_t *block, tree decl, int rank)
5071 {
5072   tree idx;
5073   tree nelems;
5074   tree tmp;
5075   idx = gfc_rank_cst[rank - 1];
5076   nelems = gfc_conv_descriptor_ubound (decl, idx);
5077   tmp = gfc_conv_descriptor_lbound (decl, idx);
5078   tmp = build2 (MINUS_EXPR, gfc_array_index_type, nelems, tmp);
5079   tmp = build2 (PLUS_EXPR, gfc_array_index_type,
5080                 tmp, gfc_index_one_node);
5081   tmp = gfc_evaluate_now (tmp, block);
5082
5083   nelems = gfc_conv_descriptor_stride (decl, idx);
5084   tmp = build2 (MULT_EXPR, gfc_array_index_type, nelems, tmp);
5085   return gfc_evaluate_now (tmp, block);
5086 }
5087
5088
5089 /* Allocate dest to the same size as src, and copy src -> dest.  */
5090
5091 tree
5092 gfc_duplicate_allocatable(tree dest, tree src, tree type, int rank)
5093 {
5094   tree tmp;
5095   tree size;
5096   tree nelems;
5097   tree null_cond;
5098   tree null_data;
5099   stmtblock_t block;
5100
5101   /* If the source is null, set the destination to null.  */
5102   gfc_init_block (&block);
5103   gfc_conv_descriptor_data_set (&block, dest, null_pointer_node);
5104   null_data = gfc_finish_block (&block);
5105
5106   gfc_init_block (&block);
5107
5108   nelems = get_full_array_size (&block, src, rank);
5109   size = fold_build2 (MULT_EXPR, gfc_array_index_type, nelems,
5110                       fold_convert (gfc_array_index_type,
5111                                     TYPE_SIZE_UNIT (gfc_get_element_type (type))));
5112
5113   /* Allocate memory to the destination.  */
5114   tmp = gfc_call_malloc (&block, TREE_TYPE (gfc_conv_descriptor_data_get (src)),
5115                          size);
5116   gfc_conv_descriptor_data_set (&block, dest, tmp);
5117
5118   /* We know the temporary and the value will be the same length,
5119      so can use memcpy.  */
5120   tmp = built_in_decls[BUILT_IN_MEMCPY];
5121   tmp = build_call_expr (tmp, 3, gfc_conv_descriptor_data_get (dest),
5122                          gfc_conv_descriptor_data_get (src), size);
5123   gfc_add_expr_to_block (&block, tmp);
5124   tmp = gfc_finish_block (&block);
5125
5126   /* Null the destination if the source is null; otherwise do
5127      the allocate and copy.  */
5128   null_cond = gfc_conv_descriptor_data_get (src);
5129   null_cond = convert (pvoid_type_node, null_cond);
5130   null_cond = build2 (NE_EXPR, boolean_type_node, null_cond,
5131                       null_pointer_node);
5132   return build3_v (COND_EXPR, null_cond, tmp, null_data);
5133 }
5134
5135
5136 /* Recursively traverse an object of derived type, generating code to
5137    deallocate, nullify or copy allocatable components.  This is the work horse
5138    function for the functions named in this enum.  */
5139
5140 enum {DEALLOCATE_ALLOC_COMP = 1, NULLIFY_ALLOC_COMP, COPY_ALLOC_COMP};
5141
5142 static tree
5143 structure_alloc_comps (gfc_symbol * der_type, tree decl,
5144                        tree dest, int rank, int purpose)
5145 {
5146   gfc_component *c;
5147   gfc_loopinfo loop;
5148   stmtblock_t fnblock;
5149   stmtblock_t loopbody;
5150   tree tmp;
5151   tree comp;
5152   tree dcmp;
5153   tree nelems;
5154   tree index;
5155   tree var;
5156   tree cdecl;
5157   tree ctype;
5158   tree vref, dref;
5159   tree null_cond = NULL_TREE;
5160
5161   gfc_init_block (&fnblock);
5162
5163   if (POINTER_TYPE_P (TREE_TYPE (decl)))
5164     decl = build_fold_indirect_ref (decl);
5165
5166   /* If this an array of derived types with allocatable components
5167      build a loop and recursively call this function.  */
5168   if (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE
5169         || GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl)))
5170     {
5171       tmp = gfc_conv_array_data (decl);
5172       var = build_fold_indirect_ref (tmp);
5173         
5174       /* Get the number of elements - 1 and set the counter.  */
5175       if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl)))
5176         {
5177           /* Use the descriptor for an allocatable array.  Since this
5178              is a full array reference, we only need the descriptor
5179              information from dimension = rank.  */
5180           tmp = get_full_array_size (&fnblock, decl, rank);
5181           tmp = build2 (MINUS_EXPR, gfc_array_index_type,
5182                         tmp, gfc_index_one_node);
5183
5184           null_cond = gfc_conv_descriptor_data_get (decl);
5185           null_cond = build2 (NE_EXPR, boolean_type_node, null_cond,
5186                               build_int_cst (TREE_TYPE (null_cond), 0));
5187         }
5188       else
5189         {
5190           /*  Otherwise use the TYPE_DOMAIN information.  */
5191           tmp =  array_type_nelts (TREE_TYPE (decl));
5192           tmp = fold_convert (gfc_array_index_type, tmp);
5193         }
5194
5195       /* Remember that this is, in fact, the no. of elements - 1.  */
5196       nelems = gfc_evaluate_now (tmp, &fnblock);
5197       index = gfc_create_var (gfc_array_index_type, "S");
5198
5199       /* Build the body of the loop.  */
5200       gfc_init_block (&loopbody);
5201
5202       vref = gfc_build_array_ref (var, index, NULL);
5203
5204       if (purpose == COPY_ALLOC_COMP)
5205         {
5206           tmp = gfc_duplicate_allocatable (dest, decl, TREE_TYPE(decl), rank);
5207           gfc_add_expr_to_block (&fnblock, tmp);
5208
5209           tmp = build_fold_indirect_ref (gfc_conv_descriptor_data_get (dest));
5210           dref = gfc_build_array_ref (tmp, index, NULL);
5211           tmp = structure_alloc_comps (der_type, vref, dref, rank, purpose);
5212         }
5213       else
5214         tmp = structure_alloc_comps (der_type, vref, NULL_TREE, rank, purpose);
5215
5216       gfc_add_expr_to_block (&loopbody, tmp);
5217
5218       /* Build the loop and return.  */
5219       gfc_init_loopinfo (&loop);
5220       loop.dimen = 1;
5221       loop.from[0] = gfc_index_zero_node;
5222       loop.loopvar[0] = index;
5223       loop.to[0] = nelems;
5224       gfc_trans_scalarizing_loops (&loop, &loopbody);
5225       gfc_add_block_to_block (&fnblock, &loop.pre);
5226
5227       tmp = gfc_finish_block (&fnblock);
5228       if (null_cond != NULL_TREE)
5229         tmp = build3_v (COND_EXPR, null_cond, tmp, build_empty_stmt ());
5230
5231       return tmp;
5232     }
5233
5234   /* Otherwise, act on the components or recursively call self to
5235      act on a chain of components.  */
5236   for (c = der_type->components; c; c = c->next)
5237     {
5238       bool cmp_has_alloc_comps = (c->ts.type == BT_DERIVED)
5239                                     && c->ts.derived->attr.alloc_comp;
5240       cdecl = c->backend_decl;
5241       ctype = TREE_TYPE (cdecl);
5242
5243       switch (purpose)
5244         {
5245         case DEALLOCATE_ALLOC_COMP:
5246           /* Do not deallocate the components of ultimate pointer
5247              components.  */
5248           if (cmp_has_alloc_comps && !c->pointer)
5249             {
5250               comp = build3 (COMPONENT_REF, ctype, decl, cdecl, NULL_TREE);
5251               rank = c->as ? c->as->rank : 0;
5252               tmp = structure_alloc_comps (c->ts.derived, comp, NULL_TREE,
5253                                            rank, purpose);
5254               gfc_add_expr_to_block (&fnblock, tmp);
5255             }
5256
5257           if (c->allocatable)
5258             {
5259               comp = build3 (COMPONENT_REF, ctype, decl, cdecl, NULL_TREE);
5260               tmp = gfc_trans_dealloc_allocated (comp);
5261               gfc_add_expr_to_block (&fnblock, tmp);
5262             }
5263           break;
5264
5265         case NULLIFY_ALLOC_COMP:
5266           if (c->pointer)
5267             continue;
5268           else if (c->allocatable)
5269             {
5270               comp = build3 (COMPONENT_REF, ctype, decl, cdecl, NULL_TREE);
5271               gfc_conv_descriptor_data_set (&fnblock, comp, null_pointer_node);
5272             }
5273           else if (cmp_has_alloc_comps)
5274             {
5275               comp = build3 (COMPONENT_REF, ctype, decl, cdecl, NULL_TREE);
5276               rank = c->as ? c->as->rank : 0;
5277               tmp = structure_alloc_comps (c->ts.derived, comp, NULL_TREE,
5278                                            rank, purpose);
5279               gfc_add_expr_to_block (&fnblock, tmp);
5280             }
5281           break;
5282
5283         case COPY_ALLOC_COMP:
5284           if (c->pointer)
5285             continue;
5286
5287           /* We need source and destination components.  */
5288           comp = build3 (COMPONENT_REF, ctype, decl, cdecl, NULL_TREE);
5289           dcmp = build3 (COMPONENT_REF, ctype, dest, cdecl, NULL_TREE);
5290           dcmp = fold_convert (TREE_TYPE (comp), dcmp);
5291
5292           if (c->allocatable && !cmp_has_alloc_comps)
5293             {
5294               tmp = gfc_duplicate_allocatable(dcmp, comp, ctype, c->as->rank);
5295               gfc_add_expr_to_block (&fnblock, tmp);
5296             }
5297
5298           if (cmp_has_alloc_comps)
5299             {
5300               rank = c->as ? c->as->rank : 0;
5301               tmp = fold_convert (TREE_TYPE (dcmp), comp);
5302               gfc_add_modify_expr (&fnblock, dcmp, tmp);
5303               tmp = structure_alloc_comps (c->ts.derived, comp, dcmp,
5304                                            rank, purpose);
5305               gfc_add_expr_to_block (&fnblock, tmp);
5306             }
5307           break;
5308
5309         default:
5310           gcc_unreachable ();
5311           break;
5312         }
5313     }
5314
5315   return gfc_finish_block (&fnblock);
5316 }
5317
5318 /* Recursively traverse an object of derived type, generating code to
5319    nullify allocatable components.  */
5320
5321 tree
5322 gfc_nullify_alloc_comp (gfc_symbol * der_type, tree decl, int rank)
5323 {
5324   return structure_alloc_comps (der_type, decl, NULL_TREE, rank,
5325                                 NULLIFY_ALLOC_COMP);
5326 }
5327
5328
5329 /* Recursively traverse an object of derived type, generating code to
5330    deallocate allocatable components.  */
5331
5332 tree
5333 gfc_deallocate_alloc_comp (gfc_symbol * der_type, tree decl, int rank)
5334 {
5335   return structure_alloc_comps (der_type, decl, NULL_TREE, rank,
5336                                 DEALLOCATE_ALLOC_COMP);
5337 }
5338
5339
5340 /* Recursively traverse an object of derived type, generating code to
5341    copy its allocatable components.  */
5342
5343 tree
5344 gfc_copy_alloc_comp (gfc_symbol * der_type, tree decl, tree dest, int rank)
5345 {
5346   return structure_alloc_comps (der_type, decl, dest, rank, COPY_ALLOC_COMP);
5347 }
5348
5349
5350 /* NULLIFY an allocatable/pointer array on function entry, free it on exit.
5351    Do likewise, recursively if necessary, with the allocatable components of
5352    derived types.  */
5353
5354 tree
5355 gfc_trans_deferred_array (gfc_symbol * sym, tree body)
5356 {
5357   tree type;
5358   tree tmp;
5359   tree descriptor;
5360   stmtblock_t fnblock;
5361   locus loc;
5362   int rank;
5363   bool sym_has_alloc_comp;
5364
5365   sym_has_alloc_comp = (sym->ts.type == BT_DERIVED)
5366                           && sym->ts.derived->attr.alloc_comp;
5367
5368   /* Make sure the frontend gets these right.  */
5369   if (!(sym->attr.pointer || sym->attr.allocatable || sym_has_alloc_comp))
5370     fatal_error ("Possible frontend bug: Deferred array size without pointer, "
5371                  "allocatable attribute or derived type without allocatable "
5372                  "components.");
5373
5374   gfc_init_block (&fnblock);
5375
5376   gcc_assert (TREE_CODE (sym->backend_decl) == VAR_DECL
5377                 || TREE_CODE (sym->backend_decl) == PARM_DECL);
5378
5379   if (sym->ts.type == BT_CHARACTER
5380       && !INTEGER_CST_P (sym->ts.cl->backend_decl))
5381     {
5382       gfc_conv_string_length (sym->ts.cl, &fnblock);
5383       gfc_trans_vla_type_sizes (sym, &fnblock);
5384     }
5385
5386   /* Dummy and use associated variables don't need anything special.  */
5387   if (sym->attr.dummy || sym->attr.use_assoc)
5388     {
5389       gfc_add_expr_to_block (&fnblock, body);
5390
5391       return gfc_finish_block (&fnblock);
5392     }
5393
5394   gfc_get_backend_locus (&loc);
5395   gfc_set_backend_locus (&sym->declared_at);
5396   descriptor = sym->backend_decl;
5397
5398   /* Although static, derived types with default initializers and
5399      allocatable components must not be nulled wholesale; instead they
5400      are treated component by component.  */
5401   if (TREE_STATIC (descriptor) && !sym_has_alloc_comp)
5402     {
5403       /* SAVEd variables are not freed on exit.  */
5404       gfc_trans_static_array_pointer (sym);
5405       return body;
5406     }
5407
5408   /* Get the descriptor type.  */
5409   type = TREE_TYPE (sym->backend_decl);
5410     
5411   if (sym_has_alloc_comp && !(sym->attr.pointer || sym->attr.allocatable))
5412     {
5413       if (!sym->attr.save)
5414         {
5415           rank = sym->as ? sym->as->rank : 0;
5416           tmp = gfc_nullify_alloc_comp (sym->ts.derived, descriptor, rank);
5417           gfc_add_expr_to_block (&fnblock, tmp);
5418         }
5419     }
5420   else if (!GFC_DESCRIPTOR_TYPE_P (type))
5421     {
5422       /* If the backend_decl is not a descriptor, we must have a pointer
5423          to one.  */
5424       descriptor = build_fold_indirect_ref (sym->backend_decl);
5425       type = TREE_TYPE (descriptor);
5426     }
5427   
5428   /* NULLIFY the data pointer.  */
5429   if (GFC_DESCRIPTOR_TYPE_P (type))
5430     gfc_conv_descriptor_data_set (&fnblock, descriptor, null_pointer_node);
5431
5432   gfc_add_expr_to_block (&fnblock, body);
5433
5434   gfc_set_backend_locus (&loc);
5435
5436   /* Allocatable arrays need to be freed when they go out of scope.
5437      The allocatable components of pointers must not be touched.  */
5438   if (sym_has_alloc_comp && !(sym->attr.function || sym->attr.result)
5439       && !sym->attr.pointer && !sym->attr.save)
5440     {
5441       int rank;
5442       rank = sym->as ? sym->as->rank : 0;
5443       tmp = gfc_deallocate_alloc_comp (sym->ts.derived, descriptor, rank);
5444       gfc_add_expr_to_block (&fnblock, tmp);
5445     }
5446
5447   if (sym->attr.allocatable)
5448     {
5449       tmp = gfc_trans_dealloc_allocated (sym->backend_decl);
5450       gfc_add_expr_to_block (&fnblock, tmp);
5451     }
5452
5453   return gfc_finish_block (&fnblock);
5454 }
5455
5456 /************ Expression Walking Functions ******************/
5457
5458 /* Walk a variable reference.
5459
5460    Possible extension - multiple component subscripts.
5461     x(:,:) = foo%a(:)%b(:)
5462    Transforms to
5463     forall (i=..., j=...)
5464       x(i,j) = foo%a(j)%b(i)
5465     end forall
5466    This adds a fair amount of complexity because you need to deal with more
5467    than one ref.  Maybe handle in a similar manner to vector subscripts.
5468    Maybe not worth the effort.  */
5469
5470
5471 static gfc_ss *
5472 gfc_walk_variable_expr (gfc_ss * ss, gfc_expr * expr)
5473 {
5474   gfc_ref *ref;
5475   gfc_array_ref *ar;
5476   gfc_ss *newss;
5477   gfc_ss *head;
5478   int n;
5479
5480   for (ref = expr->ref; ref; ref = ref->next)
5481     if (ref->type == REF_ARRAY && ref->u.ar.type != AR_ELEMENT)
5482       break;
5483
5484   for (; ref; ref = ref->next)
5485     {
5486       if (ref->type == REF_SUBSTRING)
5487         {
5488           newss = gfc_get_ss ();
5489           newss->type = GFC_SS_SCALAR;
5490           newss->expr = ref->u.ss.start;
5491           newss->next = ss;
5492           ss = newss;
5493
5494           newss = gfc_get_ss ();
5495           newss->type = GFC_SS_SCALAR;
5496           newss->expr = ref->u.ss.end;
5497           newss->next = ss;
5498           ss = newss;
5499         }
5500
5501       /* We're only interested in array sections from now on.  */
5502       if (ref->type != REF_ARRAY)
5503         continue;
5504
5505       ar = &ref->u.ar;
5506       switch (ar->type)
5507         {
5508         case AR_ELEMENT:
5509           for (n = 0; n < ar->dimen; n++)
5510             {
5511               newss = gfc_get_ss ();
5512               newss->type = GFC_SS_SCALAR;
5513               newss->expr = ar->start[n];
5514               newss->next = ss;
5515               ss = newss;
5516             }
5517           break;
5518
5519         case AR_FULL:
5520           newss = gfc_get_ss ();
5521           newss->type = GFC_SS_SECTION;
5522           newss->expr = expr;
5523           newss->next = ss;
5524           newss->data.info.dimen = ar->as->rank;
5525           newss->data.info.ref = ref;
5526
5527           /* Make sure array is the same as array(:,:), this way
5528              we don't need to special case all the time.  */
5529           ar->dimen = ar->as->rank;
5530           for (n = 0; n < ar->dimen; n++)
5531             {
5532               newss->data.info.dim[n] = n;
5533               ar->dimen_type[n] = DIMEN_RANGE;
5534
5535               gcc_assert (ar->start[n] == NULL);
5536               gcc_assert (ar->end[n] == NULL);
5537               gcc_assert (ar->stride[n] == NULL);
5538             }
5539           ss = newss;
5540           break;
5541
5542         case AR_SECTION:
5543           newss = gfc_get_ss ();
5544           newss->type = GFC_SS_SECTION;
5545           newss->expr = expr;
5546           newss->next = ss;
5547           newss->data.info.dimen = 0;
5548           newss->data.info.ref = ref;
5549
5550           head = newss;
5551
5552           /* We add SS chains for all the subscripts in the section.  */
5553           for (n = 0; n < ar->dimen; n++)
5554             {
5555               gfc_ss *indexss;
5556
5557               switch (ar->dimen_type[n])
5558                 {
5559                 case DIMEN_ELEMENT:
5560                   /* Add SS for elemental (scalar) subscripts.  */
5561                   gcc_assert (ar->start[n]);
5562                   indexss = gfc_get_ss ();
5563                   indexss->type = GFC_SS_SCALAR;
5564                   indexss->expr = ar->start[n];
5565                   indexss->next = gfc_ss_terminator;
5566                   indexss->loop_chain = gfc_ss_terminator;
5567                   newss->data.info.subscript[n] = indexss;
5568                   break;
5569
5570                 case DIMEN_RANGE:
5571                   /* We don't add anything for sections, just remember this
5572                      dimension for later.  */
5573                   newss->data.info.dim[newss->data.info.dimen] = n;
5574                   newss->data.info.dimen++;
5575                   break;
5576
5577                 case DIMEN_VECTOR:
5578                   /* Create a GFC_SS_VECTOR index in which we can store
5579                      the vector's descriptor.  */
5580                   indexss = gfc_get_ss ();
5581                   indexss->type = GFC_SS_VECTOR;
5582                   indexss->expr = ar->start[n];
5583                   indexss->next = gfc_ss_terminator;
5584                   indexss->loop_chain = gfc_ss_terminator;
5585                   newss->data.info.subscript[n] = indexss;
5586                   newss->data.info.dim[newss->data.info.dimen] = n;
5587                   newss->data.info.dimen++;
5588                   break;
5589
5590                 default:
5591                   /* We should know what sort of section it is by now.  */
5592                   gcc_unreachable ();
5593                 }
5594             }
5595           /* We should have at least one non-elemental dimension.  */
5596           gcc_assert (newss->data.info.dimen > 0);
5597           ss = newss;
5598           break;
5599
5600         default:
5601           /* We should know what sort of section it is by now.  */
5602           gcc_unreachable ();
5603         }
5604
5605     }
5606   return ss;
5607 }
5608
5609
5610 /* Walk an expression operator. If only one operand of a binary expression is
5611    scalar, we must also add the scalar term to the SS chain.  */
5612
5613 static gfc_ss *
5614 gfc_walk_op_expr (gfc_ss * ss, gfc_expr * expr)
5615 {
5616   gfc_ss *head;
5617   gfc_ss *head2;
5618   gfc_ss *newss;
5619
5620   head = gfc_walk_subexpr (ss, expr->value.op.op1);
5621   if (expr->value.op.op2 == NULL)
5622     head2 = head;
5623   else
5624     head2 = gfc_walk_subexpr (head, expr->value.op.op2);
5625
5626   /* All operands are scalar.  Pass back and let the caller deal with it.  */
5627   if (head2 == ss)
5628     return head2;
5629
5630   /* All operands require scalarization.  */
5631   if (head != ss && (expr->value.op.op2 == NULL || head2 != head))
5632     return head2;
5633
5634   /* One of the operands needs scalarization, the other is scalar.
5635      Create a gfc_ss for the scalar expression.  */
5636   newss = gfc_get_ss ();
5637   newss->type = GFC_SS_SCALAR;
5638   if (head == ss)
5639     {
5640       /* First operand is scalar.  We build the chain in reverse order, so
5641          add the scarar SS after the second operand.  */
5642       head = head2;
5643       while (head && head->next != ss)
5644         head = head->next;
5645       /* Check we haven't somehow broken the chain.  */
5646       gcc_assert (head);
5647       newss->next = ss;
5648       head->next = newss;
5649       newss->expr = expr->value.op.op1;
5650     }
5651   else                          /* head2 == head */
5652     {
5653       gcc_assert (head2 == head);
5654       /* Second operand is scalar.  */
5655       newss->next = head2;
5656       head2 = newss;
5657       newss->expr = expr->value.op.op2;
5658     }
5659
5660   return head2;
5661 }
5662
5663
5664 /* Reverse a SS chain.  */
5665
5666 gfc_ss *
5667 gfc_reverse_ss (gfc_ss * ss)
5668 {
5669   gfc_ss *next;
5670   gfc_ss *head;
5671
5672   gcc_assert (ss != NULL);
5673
5674   head = gfc_ss_terminator;
5675   while (ss != gfc_ss_terminator)
5676     {
5677       next = ss->next;
5678       /* Check we didn't somehow break the chain.  */
5679       gcc_assert (next != NULL);
5680       ss->next = head;
5681       head = ss;
5682       ss = next;
5683     }
5684
5685   return (head);
5686 }
5687
5688
5689 /* Walk the arguments of an elemental function.  */
5690
5691 gfc_ss *
5692 gfc_walk_elemental_function_args (gfc_ss * ss, gfc_actual_arglist *arg,
5693                                   gfc_ss_type type)
5694 {
5695   int scalar;
5696   gfc_ss *head;
5697   gfc_ss *tail;
5698   gfc_ss *newss;
5699
5700   head = gfc_ss_terminator;
5701   tail = NULL;
5702   scalar = 1;
5703   for (; arg; arg = arg->next)
5704     {
5705       if (!arg->expr)
5706         continue;
5707
5708       newss = gfc_walk_subexpr (head, arg->expr);
5709       if (newss == head)
5710         {
5711           /* Scalar argument.  */
5712           newss = gfc_get_ss ();
5713           newss->type = type;
5714           newss->expr = arg->expr;
5715           newss->next = head;
5716         }
5717       else
5718         scalar = 0;
5719
5720       head = newss;
5721       if (!tail)
5722         {
5723           tail = head;
5724           while (tail->next != gfc_ss_terminator)
5725             tail = tail->next;
5726         }
5727     }
5728
5729   if (scalar)
5730     {
5731       /* If all the arguments are scalar we don't need the argument SS.  */
5732       gfc_free_ss_chain (head);
5733       /* Pass it back.  */
5734       return ss;
5735     }
5736
5737   /* Add it onto the existing chain.  */
5738   tail->next = ss;
5739   return head;
5740 }
5741
5742
5743 /* Walk a function call.  Scalar functions are passed back, and taken out of
5744    scalarization loops.  For elemental functions we walk their arguments.
5745    The result of functions returning arrays is stored in a temporary outside
5746    the loop, so that the function is only called once.  Hence we do not need
5747    to walk their arguments.  */
5748
5749 static gfc_ss *
5750 gfc_walk_function_expr (gfc_ss * ss, gfc_expr * expr)
5751 {
5752   gfc_ss *newss;
5753   gfc_intrinsic_sym *isym;
5754   gfc_symbol *sym;
5755
5756   isym = expr->value.function.isym;
5757
5758   /* Handle intrinsic functions separately.  */
5759   if (isym)
5760     return gfc_walk_intrinsic_function (ss, expr, isym);
5761
5762   sym = expr->value.function.esym;
5763   if (!sym)
5764       sym = expr->symtree->n.sym;
5765
5766   /* A function that returns arrays.  */
5767   if (gfc_return_by_reference (sym) && sym->result->attr.dimension)
5768     {
5769       newss = gfc_get_ss ();
5770       newss->type = GFC_SS_FUNCTION;
5771       newss->expr = expr;
5772       newss->next = ss;
5773       newss->data.info.dimen = expr->rank;
5774       return newss;
5775     }
5776
5777   /* Walk the parameters of an elemental function.  For now we always pass
5778      by reference.  */
5779   if (sym->attr.elemental)
5780     return gfc_walk_elemental_function_args (ss, expr->value.function.actual,
5781                                              GFC_SS_REFERENCE);
5782
5783   /* Scalar functions are OK as these are evaluated outside the scalarization
5784      loop.  Pass back and let the caller deal with it.  */
5785   return ss;
5786 }
5787
5788
5789 /* An array temporary is constructed for array constructors.  */
5790
5791 static gfc_ss *
5792 gfc_walk_array_constructor (gfc_ss * ss, gfc_expr * expr)
5793 {
5794   gfc_ss *newss;
5795   int n;
5796
5797   newss = gfc_get_ss ();
5798   newss->type = GFC_SS_CONSTRUCTOR;
5799   newss->expr = expr;
5800   newss->next = ss;
5801   newss->data.info.dimen = expr->rank;
5802   for (n = 0; n < expr->rank; n++)
5803     newss->data.info.dim[n] = n;
5804
5805   return newss;
5806 }
5807
5808
5809 /* Walk an expression.  Add walked expressions to the head of the SS chain.
5810    A wholly scalar expression will not be added.  */
5811
5812 static gfc_ss *
5813 gfc_walk_subexpr (gfc_ss * ss, gfc_expr * expr)
5814 {
5815   gfc_ss *head;
5816
5817   switch (expr->expr_type)
5818     {
5819     case EXPR_VARIABLE:
5820       head = gfc_walk_variable_expr (ss, expr);
5821       return head;
5822
5823     case EXPR_OP:
5824       head = gfc_walk_op_expr (ss, expr);
5825       return head;
5826
5827     case EXPR_FUNCTION:
5828       head = gfc_walk_function_expr (ss, expr);
5829       return head;
5830
5831     case EXPR_CONSTANT:
5832     case EXPR_NULL:
5833     case EXPR_STRUCTURE:
5834       /* Pass back and let the caller deal with it.  */
5835       break;
5836
5837     case EXPR_ARRAY:
5838       head = gfc_walk_array_constructor (ss, expr);
5839       return head;
5840
5841     case EXPR_SUBSTRING:
5842       /* Pass back and let the caller deal with it.  */
5843       break;
5844
5845     default:
5846       internal_error ("bad expression type during walk (%d)",
5847                       expr->expr_type);
5848     }
5849   return ss;
5850 }
5851
5852
5853 /* Entry point for expression walking.
5854    A return value equal to the passed chain means this is
5855    a scalar expression.  It is up to the caller to take whatever action is
5856    necessary to translate these.  */
5857
5858 gfc_ss *
5859 gfc_walk_expr (gfc_expr * expr)
5860 {
5861   gfc_ss *res;
5862
5863   res = gfc_walk_subexpr (gfc_ss_terminator, expr);
5864   return gfc_reverse_ss (res);
5865 }