OSDN Git Service

2007-09-20 Christopher D. Rickett <crickett@lanl.gov>
[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
2998                   tmp3 = fold_build2 (NE_EXPR, boolean_type_node, tmp, size[n]);
2999
3000                   /* For optional arguments, only check bounds if the
3001                      argument is present.  */
3002                   if (ss->expr->symtree->n.sym->attr.optional
3003                       || ss->expr->symtree->n.sym->attr.not_always_present)
3004                     {
3005                       tree cond;
3006
3007                       cond = gfc_conv_expr_present (ss->expr->symtree->n.sym);
3008                       tmp3 = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
3009                                           cond, tmp3);
3010                     }
3011
3012                   asprintf (&msg, "%s, size mismatch for dimension %d "
3013                             "of array '%s' (%%ld/%%ld)", gfc_msg_bounds,
3014                             info->dim[n]+1, ss->expr->symtree->name);
3015                   gfc_trans_runtime_check (tmp3, &block, &ss->expr->where, msg,
3016                         fold_convert (long_integer_type_node, tmp),
3017                         fold_convert (long_integer_type_node, size[n]));
3018                   gfc_free (msg);
3019                 }
3020               else
3021                 size[n] = gfc_evaluate_now (tmp, &block);
3022             }
3023         }
3024
3025       tmp = gfc_finish_block (&block);
3026       gfc_add_expr_to_block (&loop->pre, tmp);
3027     }
3028 }
3029
3030
3031 /* Return true if the two SS could be aliased, i.e. both point to the same data
3032    object.  */
3033 /* TODO: resolve aliases based on frontend expressions.  */
3034
3035 static int
3036 gfc_could_be_alias (gfc_ss * lss, gfc_ss * rss)
3037 {
3038   gfc_ref *lref;
3039   gfc_ref *rref;
3040   gfc_symbol *lsym;
3041   gfc_symbol *rsym;
3042
3043   lsym = lss->expr->symtree->n.sym;
3044   rsym = rss->expr->symtree->n.sym;
3045   if (gfc_symbols_could_alias (lsym, rsym))
3046     return 1;
3047
3048   if (rsym->ts.type != BT_DERIVED
3049       && lsym->ts.type != BT_DERIVED)
3050     return 0;
3051
3052   /* For derived types we must check all the component types.  We can ignore
3053      array references as these will have the same base type as the previous
3054      component ref.  */
3055   for (lref = lss->expr->ref; lref != lss->data.info.ref; lref = lref->next)
3056     {
3057       if (lref->type != REF_COMPONENT)
3058         continue;
3059
3060       if (gfc_symbols_could_alias (lref->u.c.sym, rsym))
3061         return 1;
3062
3063       for (rref = rss->expr->ref; rref != rss->data.info.ref;
3064            rref = rref->next)
3065         {
3066           if (rref->type != REF_COMPONENT)
3067             continue;
3068
3069           if (gfc_symbols_could_alias (lref->u.c.sym, rref->u.c.sym))
3070             return 1;
3071         }
3072     }
3073
3074   for (rref = rss->expr->ref; rref != rss->data.info.ref; rref = rref->next)
3075     {
3076       if (rref->type != REF_COMPONENT)
3077         break;
3078
3079       if (gfc_symbols_could_alias (rref->u.c.sym, lsym))
3080         return 1;
3081     }
3082
3083   return 0;
3084 }
3085
3086
3087 /* Resolve array data dependencies.  Creates a temporary if required.  */
3088 /* TODO: Calc dependencies with gfc_expr rather than gfc_ss, and move to
3089    dependency.c.  */
3090
3091 void
3092 gfc_conv_resolve_dependencies (gfc_loopinfo * loop, gfc_ss * dest,
3093                                gfc_ss * rss)
3094 {
3095   gfc_ss *ss;
3096   gfc_ref *lref;
3097   gfc_ref *rref;
3098   gfc_ref *aref;
3099   int nDepend = 0;
3100   int temp_dim = 0;
3101
3102   loop->temp_ss = NULL;
3103   aref = dest->data.info.ref;
3104   temp_dim = 0;
3105
3106   for (ss = rss; ss != gfc_ss_terminator; ss = ss->next)
3107     {
3108       if (ss->type != GFC_SS_SECTION)
3109         continue;
3110
3111       if (gfc_could_be_alias (dest, ss)
3112             || gfc_are_equivalenced_arrays (dest->expr, ss->expr))
3113         {
3114           nDepend = 1;
3115           break;
3116         }
3117
3118       if (dest->expr->symtree->n.sym == ss->expr->symtree->n.sym)
3119         {
3120           lref = dest->expr->ref;
3121           rref = ss->expr->ref;
3122
3123           nDepend = gfc_dep_resolver (lref, rref);
3124           if (nDepend == 1)
3125             break;
3126 #if 0
3127           /* TODO : loop shifting.  */
3128           if (nDepend == 1)
3129             {
3130               /* Mark the dimensions for LOOP SHIFTING */
3131               for (n = 0; n < loop->dimen; n++)
3132                 {
3133                   int dim = dest->data.info.dim[n];
3134
3135                   if (lref->u.ar.dimen_type[dim] == DIMEN_VECTOR)
3136                     depends[n] = 2;
3137                   else if (! gfc_is_same_range (&lref->u.ar,
3138                                                 &rref->u.ar, dim, 0))
3139                     depends[n] = 1;
3140                  }
3141
3142               /* Put all the dimensions with dependencies in the
3143                  innermost loops.  */
3144               dim = 0;
3145               for (n = 0; n < loop->dimen; n++)
3146                 {
3147                   gcc_assert (loop->order[n] == n);
3148                   if (depends[n])
3149                   loop->order[dim++] = n;
3150                 }
3151               temp_dim = dim;
3152               for (n = 0; n < loop->dimen; n++)
3153                 {
3154                   if (! depends[n])
3155                   loop->order[dim++] = n;
3156                 }
3157
3158               gcc_assert (dim == loop->dimen);
3159               break;
3160             }
3161 #endif
3162         }
3163     }
3164
3165   if (nDepend == 1)
3166     {
3167       tree base_type = gfc_typenode_for_spec (&dest->expr->ts);
3168       if (GFC_ARRAY_TYPE_P (base_type)
3169           || GFC_DESCRIPTOR_TYPE_P (base_type))
3170         base_type = gfc_get_element_type (base_type);
3171       loop->temp_ss = gfc_get_ss ();
3172       loop->temp_ss->type = GFC_SS_TEMP;
3173       loop->temp_ss->data.temp.type = base_type;
3174       loop->temp_ss->string_length = dest->string_length;
3175       loop->temp_ss->data.temp.dimen = loop->dimen;
3176       loop->temp_ss->next = gfc_ss_terminator;
3177       gfc_add_ss_to_loop (loop, loop->temp_ss);
3178     }
3179   else
3180     loop->temp_ss = NULL;
3181 }
3182
3183
3184 /* Initialize the scalarization loop.  Creates the loop variables.  Determines
3185    the range of the loop variables.  Creates a temporary if required.
3186    Calculates how to transform from loop variables to array indices for each
3187    expression.  Also generates code for scalar expressions which have been
3188    moved outside the loop.  */
3189
3190 void
3191 gfc_conv_loop_setup (gfc_loopinfo * loop)
3192 {
3193   int n;
3194   int dim;
3195   gfc_ss_info *info;
3196   gfc_ss_info *specinfo;
3197   gfc_ss *ss;
3198   tree tmp;
3199   tree len;
3200   gfc_ss *loopspec[GFC_MAX_DIMENSIONS];
3201   bool dynamic[GFC_MAX_DIMENSIONS];
3202   gfc_constructor *c;
3203   mpz_t *cshape;
3204   mpz_t i;
3205
3206   mpz_init (i);
3207   for (n = 0; n < loop->dimen; n++)
3208     {
3209       loopspec[n] = NULL;
3210       dynamic[n] = false;
3211       /* We use one SS term, and use that to determine the bounds of the
3212          loop for this dimension.  We try to pick the simplest term.  */
3213       for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
3214         {
3215           if (ss->shape)
3216             {
3217               /* The frontend has worked out the size for us.  */
3218               loopspec[n] = ss;
3219               continue;
3220             }
3221
3222           if (ss->type == GFC_SS_CONSTRUCTOR)
3223             {
3224               /* An unknown size constructor will always be rank one.
3225                  Higher rank constructors will either have known shape,
3226                  or still be wrapped in a call to reshape.  */
3227               gcc_assert (loop->dimen == 1);
3228
3229               /* Always prefer to use the constructor bounds if the size
3230                  can be determined at compile time.  Prefer not to otherwise,
3231                  since the general case involves realloc, and it's better to
3232                  avoid that overhead if possible.  */
3233               c = ss->expr->value.constructor;
3234               dynamic[n] = gfc_get_array_constructor_size (&i, c);
3235               if (!dynamic[n] || !loopspec[n])
3236                 loopspec[n] = ss;
3237               continue;
3238             }
3239
3240           /* TODO: Pick the best bound if we have a choice between a
3241              function and something else.  */
3242           if (ss->type == GFC_SS_FUNCTION)
3243             {
3244               loopspec[n] = ss;
3245               continue;
3246             }
3247
3248           if (ss->type != GFC_SS_SECTION)
3249             continue;
3250
3251           if (loopspec[n])
3252             specinfo = &loopspec[n]->data.info;
3253           else
3254             specinfo = NULL;
3255           info = &ss->data.info;
3256
3257           if (!specinfo)
3258             loopspec[n] = ss;
3259           /* Criteria for choosing a loop specifier (most important first):
3260              doesn't need realloc
3261              stride of one
3262              known stride
3263              known lower bound
3264              known upper bound
3265            */
3266           else if (loopspec[n]->type == GFC_SS_CONSTRUCTOR && dynamic[n])
3267             loopspec[n] = ss;
3268           else if (integer_onep (info->stride[n])
3269                    && !integer_onep (specinfo->stride[n]))
3270             loopspec[n] = ss;
3271           else if (INTEGER_CST_P (info->stride[n])
3272                    && !INTEGER_CST_P (specinfo->stride[n]))
3273             loopspec[n] = ss;
3274           else if (INTEGER_CST_P (info->start[n])
3275                    && !INTEGER_CST_P (specinfo->start[n]))
3276             loopspec[n] = ss;
3277           /* We don't work out the upper bound.
3278              else if (INTEGER_CST_P (info->finish[n])
3279              && ! INTEGER_CST_P (specinfo->finish[n]))
3280              loopspec[n] = ss; */
3281         }
3282
3283       if (!loopspec[n])
3284         gfc_todo_error ("Unable to find scalarization loop specifier");
3285
3286       info = &loopspec[n]->data.info;
3287
3288       /* Set the extents of this range.  */
3289       cshape = loopspec[n]->shape;
3290       if (cshape && INTEGER_CST_P (info->start[n])
3291           && INTEGER_CST_P (info->stride[n]))
3292         {
3293           loop->from[n] = info->start[n];
3294           mpz_set (i, cshape[n]);
3295           mpz_sub_ui (i, i, 1);
3296           /* To = from + (size - 1) * stride.  */
3297           tmp = gfc_conv_mpz_to_tree (i, gfc_index_integer_kind);
3298           if (!integer_onep (info->stride[n]))
3299             tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
3300                                tmp, info->stride[n]);
3301           loop->to[n] = fold_build2 (PLUS_EXPR, gfc_array_index_type,
3302                                      loop->from[n], tmp);
3303         }
3304       else
3305         {
3306           loop->from[n] = info->start[n];
3307           switch (loopspec[n]->type)
3308             {
3309             case GFC_SS_CONSTRUCTOR:
3310               /* The upper bound is calculated when we expand the
3311                  constructor.  */
3312               gcc_assert (loop->to[n] == NULL_TREE);
3313               break;
3314
3315             case GFC_SS_SECTION:
3316               loop->to[n] = gfc_conv_section_upper_bound (loopspec[n], n,
3317                                                           &loop->pre);
3318               break;
3319
3320             case GFC_SS_FUNCTION:
3321               /* The loop bound will be set when we generate the call.  */
3322               gcc_assert (loop->to[n] == NULL_TREE);
3323               break;
3324
3325             default:
3326               gcc_unreachable ();
3327             }
3328         }
3329
3330       /* Transform everything so we have a simple incrementing variable.  */
3331       if (integer_onep (info->stride[n]))
3332         info->delta[n] = gfc_index_zero_node;
3333       else
3334         {
3335           /* Set the delta for this section.  */
3336           info->delta[n] = gfc_evaluate_now (loop->from[n], &loop->pre);
3337           /* Number of iterations is (end - start + step) / step.
3338              with start = 0, this simplifies to
3339              last = end / step;
3340              for (i = 0; i<=last; i++){...};  */
3341           tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
3342                              loop->to[n], loop->from[n]);
3343           tmp = fold_build2 (TRUNC_DIV_EXPR, gfc_array_index_type, 
3344                              tmp, info->stride[n]);
3345           loop->to[n] = gfc_evaluate_now (tmp, &loop->pre);
3346           /* Make the loop variable start at 0.  */
3347           loop->from[n] = gfc_index_zero_node;
3348         }
3349     }
3350
3351   /* Add all the scalar code that can be taken out of the loops.
3352      This may include calculating the loop bounds, so do it before
3353      allocating the temporary.  */
3354   gfc_add_loop_ss_code (loop, loop->ss, false);
3355
3356   /* If we want a temporary then create it.  */
3357   if (loop->temp_ss != NULL)
3358     {
3359       gcc_assert (loop->temp_ss->type == GFC_SS_TEMP);
3360       tmp = loop->temp_ss->data.temp.type;
3361       len = loop->temp_ss->string_length;
3362       n = loop->temp_ss->data.temp.dimen;
3363       memset (&loop->temp_ss->data.info, 0, sizeof (gfc_ss_info));
3364       loop->temp_ss->type = GFC_SS_SECTION;
3365       loop->temp_ss->data.info.dimen = n;
3366       gfc_trans_create_temp_array (&loop->pre, &loop->post, loop,
3367                                    &loop->temp_ss->data.info, tmp, false, true,
3368                                    false);
3369     }
3370
3371   for (n = 0; n < loop->temp_dim; n++)
3372     loopspec[loop->order[n]] = NULL;
3373
3374   mpz_clear (i);
3375
3376   /* For array parameters we don't have loop variables, so don't calculate the
3377      translations.  */
3378   if (loop->array_parameter)
3379     return;
3380
3381   /* Calculate the translation from loop variables to array indices.  */
3382   for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
3383     {
3384       if (ss->type != GFC_SS_SECTION && ss->type != GFC_SS_COMPONENT)
3385         continue;
3386
3387       info = &ss->data.info;
3388
3389       for (n = 0; n < info->dimen; n++)
3390         {
3391           dim = info->dim[n];
3392
3393           /* If we are specifying the range the delta is already set.  */
3394           if (loopspec[n] != ss)
3395             {
3396               /* Calculate the offset relative to the loop variable.
3397                  First multiply by the stride.  */
3398               tmp = loop->from[n];
3399               if (!integer_onep (info->stride[n]))
3400                 tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
3401                                    tmp, info->stride[n]);
3402
3403               /* Then subtract this from our starting value.  */
3404               tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
3405                                  info->start[n], tmp);
3406
3407               info->delta[n] = gfc_evaluate_now (tmp, &loop->pre);
3408             }
3409         }
3410     }
3411 }
3412
3413
3414 /* Fills in an array descriptor, and returns the size of the array.  The size
3415    will be a simple_val, ie a variable or a constant.  Also calculates the
3416    offset of the base.  Returns the size of the array.
3417    {
3418     stride = 1;
3419     offset = 0;
3420     for (n = 0; n < rank; n++)
3421       {
3422         a.lbound[n] = specified_lower_bound;
3423         offset = offset + a.lbond[n] * stride;
3424         size = 1 - lbound;
3425         a.ubound[n] = specified_upper_bound;
3426         a.stride[n] = stride;
3427         size = ubound + size; //size = ubound + 1 - lbound
3428         stride = stride * size;
3429       }
3430     return (stride);
3431    }  */
3432 /*GCC ARRAYS*/
3433
3434 static tree
3435 gfc_array_init_size (tree descriptor, int rank, tree * poffset,
3436                      gfc_expr ** lower, gfc_expr ** upper,
3437                      stmtblock_t * pblock)
3438 {
3439   tree type;
3440   tree tmp;
3441   tree size;
3442   tree offset;
3443   tree stride;
3444   tree cond;
3445   tree or_expr;
3446   tree thencase;
3447   tree elsecase;
3448   tree var;
3449   stmtblock_t thenblock;
3450   stmtblock_t elseblock;
3451   gfc_expr *ubound;
3452   gfc_se se;
3453   int n;
3454
3455   type = TREE_TYPE (descriptor);
3456
3457   stride = gfc_index_one_node;
3458   offset = gfc_index_zero_node;
3459
3460   /* Set the dtype.  */
3461   tmp = gfc_conv_descriptor_dtype (descriptor);
3462   gfc_add_modify_expr (pblock, tmp, gfc_get_dtype (TREE_TYPE (descriptor)));
3463
3464   or_expr = NULL_TREE;
3465
3466   for (n = 0; n < rank; n++)
3467     {
3468       /* We have 3 possibilities for determining the size of the array:
3469          lower == NULL    => lbound = 1, ubound = upper[n]
3470          upper[n] = NULL  => lbound = 1, ubound = lower[n]
3471          upper[n] != NULL => lbound = lower[n], ubound = upper[n]  */
3472       ubound = upper[n];
3473
3474       /* Set lower bound.  */
3475       gfc_init_se (&se, NULL);
3476       if (lower == NULL)
3477         se.expr = gfc_index_one_node;
3478       else
3479         {
3480           gcc_assert (lower[n]);
3481           if (ubound)
3482             {
3483               gfc_conv_expr_type (&se, lower[n], gfc_array_index_type);
3484               gfc_add_block_to_block (pblock, &se.pre);
3485             }
3486           else
3487             {
3488               se.expr = gfc_index_one_node;
3489               ubound = lower[n];
3490             }
3491         }
3492       tmp = gfc_conv_descriptor_lbound (descriptor, gfc_rank_cst[n]);
3493       gfc_add_modify_expr (pblock, tmp, se.expr);
3494
3495       /* Work out the offset for this component.  */
3496       tmp = fold_build2 (MULT_EXPR, gfc_array_index_type, se.expr, stride);
3497       offset = fold_build2 (MINUS_EXPR, gfc_array_index_type, offset, tmp);
3498
3499       /* Start the calculation for the size of this dimension.  */
3500       size = build2 (MINUS_EXPR, gfc_array_index_type,
3501                      gfc_index_one_node, se.expr);
3502
3503       /* Set upper bound.  */
3504       gfc_init_se (&se, NULL);
3505       gcc_assert (ubound);
3506       gfc_conv_expr_type (&se, ubound, gfc_array_index_type);
3507       gfc_add_block_to_block (pblock, &se.pre);
3508
3509       tmp = gfc_conv_descriptor_ubound (descriptor, gfc_rank_cst[n]);
3510       gfc_add_modify_expr (pblock, tmp, se.expr);
3511
3512       /* Store the stride.  */
3513       tmp = gfc_conv_descriptor_stride (descriptor, gfc_rank_cst[n]);
3514       gfc_add_modify_expr (pblock, tmp, stride);
3515
3516       /* Calculate the size of this dimension.  */
3517       size = fold_build2 (PLUS_EXPR, gfc_array_index_type, se.expr, size);
3518
3519       /* Check whether the size for this dimension is negative.  */
3520       cond = fold_build2 (LE_EXPR, boolean_type_node, size,
3521                           gfc_index_zero_node);
3522       if (n == 0)
3523         or_expr = cond;
3524       else
3525         or_expr = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, or_expr, cond);
3526
3527       /* Multiply the stride by the number of elements in this dimension.  */
3528       stride = fold_build2 (MULT_EXPR, gfc_array_index_type, stride, size);
3529       stride = gfc_evaluate_now (stride, pblock);
3530     }
3531
3532   /* The stride is the number of elements in the array, so multiply by the
3533      size of an element to get the total size.  */
3534   tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type));
3535   size = fold_build2 (MULT_EXPR, gfc_array_index_type, stride,
3536                       fold_convert (gfc_array_index_type, tmp));
3537
3538   if (poffset != NULL)
3539     {
3540       offset = gfc_evaluate_now (offset, pblock);
3541       *poffset = offset;
3542     }
3543
3544   if (integer_zerop (or_expr))
3545     return size;
3546   if (integer_onep (or_expr))
3547     return gfc_index_zero_node;
3548
3549   var = gfc_create_var (TREE_TYPE (size), "size");
3550   gfc_start_block (&thenblock);
3551   gfc_add_modify_expr (&thenblock, var, gfc_index_zero_node);
3552   thencase = gfc_finish_block (&thenblock);
3553
3554   gfc_start_block (&elseblock);
3555   gfc_add_modify_expr (&elseblock, var, size);
3556   elsecase = gfc_finish_block (&elseblock);
3557
3558   tmp = gfc_evaluate_now (or_expr, pblock);
3559   tmp = build3_v (COND_EXPR, tmp, thencase, elsecase);
3560   gfc_add_expr_to_block (pblock, tmp);
3561
3562   return var;
3563 }
3564
3565
3566 /* Initializes the descriptor and generates a call to _gfor_allocate.  Does
3567    the work for an ALLOCATE statement.  */
3568 /*GCC ARRAYS*/
3569
3570 bool
3571 gfc_array_allocate (gfc_se * se, gfc_expr * expr, tree pstat)
3572 {
3573   tree tmp;
3574   tree pointer;
3575   tree offset;
3576   tree size;
3577   gfc_expr **lower;
3578   gfc_expr **upper;
3579   gfc_ref *ref, *prev_ref = NULL;
3580   bool allocatable_array;
3581
3582   ref = expr->ref;
3583
3584   /* Find the last reference in the chain.  */
3585   while (ref && ref->next != NULL)
3586     {
3587       gcc_assert (ref->type != REF_ARRAY || ref->u.ar.type == AR_ELEMENT);
3588       prev_ref = ref;
3589       ref = ref->next;
3590     }
3591
3592   if (ref == NULL || ref->type != REF_ARRAY)
3593     return false;
3594
3595   if (!prev_ref)
3596     allocatable_array = expr->symtree->n.sym->attr.allocatable;
3597   else
3598     allocatable_array = prev_ref->u.c.component->allocatable;
3599
3600   /* Figure out the size of the array.  */
3601   switch (ref->u.ar.type)
3602     {
3603     case AR_ELEMENT:
3604       lower = NULL;
3605       upper = ref->u.ar.start;
3606       break;
3607
3608     case AR_FULL:
3609       gcc_assert (ref->u.ar.as->type == AS_EXPLICIT);
3610
3611       lower = ref->u.ar.as->lower;
3612       upper = ref->u.ar.as->upper;
3613       break;
3614
3615     case AR_SECTION:
3616       lower = ref->u.ar.start;
3617       upper = ref->u.ar.end;
3618       break;
3619
3620     default:
3621       gcc_unreachable ();
3622       break;
3623     }
3624
3625   size = gfc_array_init_size (se->expr, ref->u.ar.as->rank, &offset,
3626                               lower, upper, &se->pre);
3627
3628   /* Allocate memory to store the data.  */
3629   pointer = gfc_conv_descriptor_data_get (se->expr);
3630   STRIP_NOPS (pointer);
3631
3632   /* The allocate_array variants take the old pointer as first argument.  */
3633   if (allocatable_array)
3634     tmp = gfc_allocate_array_with_status (&se->pre, pointer, size, pstat);
3635   else
3636     tmp = gfc_allocate_with_status (&se->pre, size, pstat);
3637   tmp = build2 (MODIFY_EXPR, void_type_node, pointer, tmp);
3638   gfc_add_expr_to_block (&se->pre, tmp);
3639
3640   tmp = gfc_conv_descriptor_offset (se->expr);
3641   gfc_add_modify_expr (&se->pre, tmp, offset);
3642
3643   if (expr->ts.type == BT_DERIVED
3644         && expr->ts.derived->attr.alloc_comp)
3645     {
3646       tmp = gfc_nullify_alloc_comp (expr->ts.derived, se->expr,
3647                                     ref->u.ar.as->rank);
3648       gfc_add_expr_to_block (&se->pre, tmp);
3649     }
3650
3651   return true;
3652 }
3653
3654
3655 /* Deallocate an array variable.  Also used when an allocated variable goes
3656    out of scope.  */
3657 /*GCC ARRAYS*/
3658
3659 tree
3660 gfc_array_deallocate (tree descriptor, tree pstat)
3661 {
3662   tree var;
3663   tree tmp;
3664   stmtblock_t block;
3665
3666   gfc_start_block (&block);
3667   /* Get a pointer to the data.  */
3668   var = gfc_conv_descriptor_data_get (descriptor);
3669   STRIP_NOPS (var);
3670
3671   /* Parameter is the address of the data component.  */
3672   tmp = gfc_deallocate_with_status (var, pstat, false);
3673   gfc_add_expr_to_block (&block, tmp);
3674
3675   /* Zero the data pointer.  */
3676   tmp = build2 (MODIFY_EXPR, void_type_node,
3677                 var, build_int_cst (TREE_TYPE (var), 0));
3678   gfc_add_expr_to_block (&block, tmp);
3679
3680   return gfc_finish_block (&block);
3681 }
3682
3683
3684 /* Create an array constructor from an initialization expression.
3685    We assume the frontend already did any expansions and conversions.  */
3686
3687 tree
3688 gfc_conv_array_initializer (tree type, gfc_expr * expr)
3689 {
3690   gfc_constructor *c;
3691   tree tmp;
3692   mpz_t maxval;
3693   gfc_se se;
3694   HOST_WIDE_INT hi;
3695   unsigned HOST_WIDE_INT lo;
3696   tree index, range;
3697   VEC(constructor_elt,gc) *v = NULL;
3698
3699   switch (expr->expr_type)
3700     {
3701     case EXPR_CONSTANT:
3702     case EXPR_STRUCTURE:
3703       /* A single scalar or derived type value.  Create an array with all
3704          elements equal to that value.  */
3705       gfc_init_se (&se, NULL);
3706       
3707       if (expr->expr_type == EXPR_CONSTANT)
3708         gfc_conv_constant (&se, expr);
3709       else
3710         gfc_conv_structure (&se, expr, 1);
3711
3712       tmp = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
3713       gcc_assert (tmp && INTEGER_CST_P (tmp));
3714       hi = TREE_INT_CST_HIGH (tmp);
3715       lo = TREE_INT_CST_LOW (tmp);
3716       lo++;
3717       if (lo == 0)
3718         hi++;
3719       /* This will probably eat buckets of memory for large arrays.  */
3720       while (hi != 0 || lo != 0)
3721         {
3722           CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, se.expr);
3723           if (lo == 0)
3724             hi--;
3725           lo--;
3726         }
3727       break;
3728
3729     case EXPR_ARRAY:
3730       /* Create a vector of all the elements.  */
3731       for (c = expr->value.constructor; c; c = c->next)
3732         {
3733           if (c->iterator)
3734             {
3735               /* Problems occur when we get something like
3736                  integer :: a(lots) = (/(i, i=1,lots)/)  */
3737               /* TODO: Unexpanded array initializers.  */
3738               internal_error
3739                 ("Possible frontend bug: array constructor not expanded");
3740             }
3741           if (mpz_cmp_si (c->n.offset, 0) != 0)
3742             index = gfc_conv_mpz_to_tree (c->n.offset, gfc_index_integer_kind);
3743           else
3744             index = NULL_TREE;
3745           mpz_init (maxval);
3746           if (mpz_cmp_si (c->repeat, 0) != 0)
3747             {
3748               tree tmp1, tmp2;
3749
3750               mpz_set (maxval, c->repeat);
3751               mpz_add (maxval, c->n.offset, maxval);
3752               mpz_sub_ui (maxval, maxval, 1);
3753               tmp2 = gfc_conv_mpz_to_tree (maxval, gfc_index_integer_kind);
3754               if (mpz_cmp_si (c->n.offset, 0) != 0)
3755                 {
3756                   mpz_add_ui (maxval, c->n.offset, 1);
3757                   tmp1 = gfc_conv_mpz_to_tree (maxval, gfc_index_integer_kind);
3758                 }
3759               else
3760                 tmp1 = gfc_conv_mpz_to_tree (c->n.offset, gfc_index_integer_kind);
3761
3762               range = build2 (RANGE_EXPR, integer_type_node, tmp1, tmp2);
3763             }
3764           else
3765             range = NULL;
3766           mpz_clear (maxval);
3767
3768           gfc_init_se (&se, NULL);
3769           switch (c->expr->expr_type)
3770             {
3771             case EXPR_CONSTANT:
3772               gfc_conv_constant (&se, c->expr);
3773               if (range == NULL_TREE)
3774                 CONSTRUCTOR_APPEND_ELT (v, index, se.expr);
3775               else
3776                 {
3777                   if (index != NULL_TREE)
3778                     CONSTRUCTOR_APPEND_ELT (v, index, se.expr);
3779                   CONSTRUCTOR_APPEND_ELT (v, range, se.expr);
3780                 }
3781               break;
3782
3783             case EXPR_STRUCTURE:
3784               gfc_conv_structure (&se, c->expr, 1);
3785               CONSTRUCTOR_APPEND_ELT (v, index, se.expr);
3786               break;
3787
3788             default:
3789               gcc_unreachable ();
3790             }
3791         }
3792       break;
3793
3794     case EXPR_NULL:
3795       return gfc_build_null_descriptor (type);
3796
3797     default:
3798       gcc_unreachable ();
3799     }
3800
3801   /* Create a constructor from the list of elements.  */
3802   tmp = build_constructor (type, v);
3803   TREE_CONSTANT (tmp) = 1;
3804   TREE_INVARIANT (tmp) = 1;
3805   return tmp;
3806 }
3807
3808
3809 /* Generate code to evaluate non-constant array bounds.  Sets *poffset and
3810    returns the size (in elements) of the array.  */
3811
3812 static tree
3813 gfc_trans_array_bounds (tree type, gfc_symbol * sym, tree * poffset,
3814                         stmtblock_t * pblock)
3815 {
3816   gfc_array_spec *as;
3817   tree size;
3818   tree stride;
3819   tree offset;
3820   tree ubound;
3821   tree lbound;
3822   tree tmp;
3823   gfc_se se;
3824
3825   int dim;
3826
3827   as = sym->as;
3828
3829   size = gfc_index_one_node;
3830   offset = gfc_index_zero_node;
3831   for (dim = 0; dim < as->rank; dim++)
3832     {
3833       /* Evaluate non-constant array bound expressions.  */
3834       lbound = GFC_TYPE_ARRAY_LBOUND (type, dim);
3835       if (as->lower[dim] && !INTEGER_CST_P (lbound))
3836         {
3837           gfc_init_se (&se, NULL);
3838           gfc_conv_expr_type (&se, as->lower[dim], gfc_array_index_type);
3839           gfc_add_block_to_block (pblock, &se.pre);
3840           gfc_add_modify_expr (pblock, lbound, se.expr);
3841         }
3842       ubound = GFC_TYPE_ARRAY_UBOUND (type, dim);
3843       if (as->upper[dim] && !INTEGER_CST_P (ubound))
3844         {
3845           gfc_init_se (&se, NULL);
3846           gfc_conv_expr_type (&se, as->upper[dim], gfc_array_index_type);
3847           gfc_add_block_to_block (pblock, &se.pre);
3848           gfc_add_modify_expr (pblock, ubound, se.expr);
3849         }
3850       /* The offset of this dimension.  offset = offset - lbound * stride.  */
3851       tmp = fold_build2 (MULT_EXPR, gfc_array_index_type, lbound, size);
3852       offset = fold_build2 (MINUS_EXPR, gfc_array_index_type, offset, tmp);
3853
3854       /* The size of this dimension, and the stride of the next.  */
3855       if (dim + 1 < as->rank)
3856         stride = GFC_TYPE_ARRAY_STRIDE (type, dim + 1);
3857       else
3858         stride = GFC_TYPE_ARRAY_SIZE (type);
3859
3860       if (ubound != NULL_TREE && !(stride && INTEGER_CST_P (stride)))
3861         {
3862           /* Calculate stride = size * (ubound + 1 - lbound).  */
3863           tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
3864                              gfc_index_one_node, lbound);
3865           tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type, ubound, tmp);
3866           tmp = fold_build2 (MULT_EXPR, gfc_array_index_type, size, tmp);
3867           if (stride)
3868             gfc_add_modify_expr (pblock, stride, tmp);
3869           else
3870             stride = gfc_evaluate_now (tmp, pblock);
3871
3872           /* Make sure that negative size arrays are translated
3873              to being zero size.  */
3874           tmp = build2 (GE_EXPR, boolean_type_node,
3875                         stride, gfc_index_zero_node);
3876           tmp = build3 (COND_EXPR, gfc_array_index_type, tmp,
3877                         stride, gfc_index_zero_node);
3878           gfc_add_modify_expr (pblock, stride, tmp);
3879         }
3880
3881       size = stride;
3882     }
3883
3884   gfc_trans_vla_type_sizes (sym, pblock);
3885
3886   *poffset = offset;
3887   return size;
3888 }
3889
3890
3891 /* Generate code to initialize/allocate an array variable.  */
3892
3893 tree
3894 gfc_trans_auto_array_allocation (tree decl, gfc_symbol * sym, tree fnbody)
3895 {
3896   stmtblock_t block;
3897   tree type;
3898   tree tmp;
3899   tree size;
3900   tree offset;
3901   bool onstack;
3902
3903   gcc_assert (!(sym->attr.pointer || sym->attr.allocatable));
3904
3905   /* Do nothing for USEd variables.  */
3906   if (sym->attr.use_assoc)
3907     return fnbody;
3908
3909   type = TREE_TYPE (decl);
3910   gcc_assert (GFC_ARRAY_TYPE_P (type));
3911   onstack = TREE_CODE (type) != POINTER_TYPE;
3912
3913   gfc_start_block (&block);
3914
3915   /* Evaluate character string length.  */
3916   if (sym->ts.type == BT_CHARACTER
3917       && onstack && !INTEGER_CST_P (sym->ts.cl->backend_decl))
3918     {
3919       gfc_conv_string_length (sym->ts.cl, &block);
3920
3921       gfc_trans_vla_type_sizes (sym, &block);
3922
3923       /* Emit a DECL_EXPR for this variable, which will cause the
3924          gimplifier to allocate storage, and all that good stuff.  */
3925       tmp = build1 (DECL_EXPR, TREE_TYPE (decl), decl);
3926       gfc_add_expr_to_block (&block, tmp);
3927     }
3928
3929   if (onstack)
3930     {
3931       gfc_add_expr_to_block (&block, fnbody);
3932       return gfc_finish_block (&block);
3933     }
3934
3935   type = TREE_TYPE (type);
3936
3937   gcc_assert (!sym->attr.use_assoc);
3938   gcc_assert (!TREE_STATIC (decl));
3939   gcc_assert (!sym->module);
3940
3941   if (sym->ts.type == BT_CHARACTER
3942       && !INTEGER_CST_P (sym->ts.cl->backend_decl))
3943     gfc_conv_string_length (sym->ts.cl, &block);
3944
3945   size = gfc_trans_array_bounds (type, sym, &offset, &block);
3946
3947   /* Don't actually allocate space for Cray Pointees.  */
3948   if (sym->attr.cray_pointee)
3949     {
3950       if (TREE_CODE (GFC_TYPE_ARRAY_OFFSET (type)) == VAR_DECL)
3951         gfc_add_modify_expr (&block, GFC_TYPE_ARRAY_OFFSET (type), offset);
3952       gfc_add_expr_to_block (&block, fnbody);
3953       return gfc_finish_block (&block);
3954     }
3955
3956   /* The size is the number of elements in the array, so multiply by the
3957      size of an element to get the total size.  */
3958   tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type));
3959   size = fold_build2 (MULT_EXPR, gfc_array_index_type, size,
3960                       fold_convert (gfc_array_index_type, tmp));
3961
3962   /* Allocate memory to hold the data.  */
3963   tmp = gfc_call_malloc (&block, TREE_TYPE (decl), size);
3964   gfc_add_modify_expr (&block, decl, tmp);
3965
3966   /* Set offset of the array.  */
3967   if (TREE_CODE (GFC_TYPE_ARRAY_OFFSET (type)) == VAR_DECL)
3968     gfc_add_modify_expr (&block, GFC_TYPE_ARRAY_OFFSET (type), offset);
3969
3970
3971   /* Automatic arrays should not have initializers.  */
3972   gcc_assert (!sym->value);
3973
3974   gfc_add_expr_to_block (&block, fnbody);
3975
3976   /* Free the temporary.  */
3977   tmp = gfc_call_free (convert (pvoid_type_node, decl));
3978   gfc_add_expr_to_block (&block, tmp);
3979
3980   return gfc_finish_block (&block);
3981 }
3982
3983
3984 /* Generate entry and exit code for g77 calling convention arrays.  */
3985
3986 tree
3987 gfc_trans_g77_array (gfc_symbol * sym, tree body)
3988 {
3989   tree parm;
3990   tree type;
3991   locus loc;
3992   tree offset;
3993   tree tmp;
3994   tree stmt;  
3995   stmtblock_t block;
3996
3997   gfc_get_backend_locus (&loc);
3998   gfc_set_backend_locus (&sym->declared_at);
3999
4000   /* Descriptor type.  */
4001   parm = sym->backend_decl;
4002   type = TREE_TYPE (parm);
4003   gcc_assert (GFC_ARRAY_TYPE_P (type));
4004
4005   gfc_start_block (&block);
4006
4007   if (sym->ts.type == BT_CHARACTER
4008       && TREE_CODE (sym->ts.cl->backend_decl) == VAR_DECL)
4009     gfc_conv_string_length (sym->ts.cl, &block);
4010
4011   /* Evaluate the bounds of the array.  */
4012   gfc_trans_array_bounds (type, sym, &offset, &block);
4013
4014   /* Set the offset.  */
4015   if (TREE_CODE (GFC_TYPE_ARRAY_OFFSET (type)) == VAR_DECL)
4016     gfc_add_modify_expr (&block, GFC_TYPE_ARRAY_OFFSET (type), offset);
4017
4018   /* Set the pointer itself if we aren't using the parameter directly.  */
4019   if (TREE_CODE (parm) != PARM_DECL)
4020     {
4021       tmp = convert (TREE_TYPE (parm), GFC_DECL_SAVED_DESCRIPTOR (parm));
4022       gfc_add_modify_expr (&block, parm, tmp);
4023     }
4024   stmt = gfc_finish_block (&block);
4025
4026   gfc_set_backend_locus (&loc);
4027
4028   gfc_start_block (&block);
4029
4030   /* Add the initialization code to the start of the function.  */
4031
4032   if (sym->attr.optional || sym->attr.not_always_present)
4033     {
4034       tmp = gfc_conv_expr_present (sym);
4035       stmt = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt ());
4036     }
4037   
4038   gfc_add_expr_to_block (&block, stmt);
4039   gfc_add_expr_to_block (&block, body);
4040
4041   return gfc_finish_block (&block);
4042 }
4043
4044
4045 /* Modify the descriptor of an array parameter so that it has the
4046    correct lower bound.  Also move the upper bound accordingly.
4047    If the array is not packed, it will be copied into a temporary.
4048    For each dimension we set the new lower and upper bounds.  Then we copy the
4049    stride and calculate the offset for this dimension.  We also work out
4050    what the stride of a packed array would be, and see it the two match.
4051    If the array need repacking, we set the stride to the values we just
4052    calculated, recalculate the offset and copy the array data.
4053    Code is also added to copy the data back at the end of the function.
4054    */
4055
4056 tree
4057 gfc_trans_dummy_array_bias (gfc_symbol * sym, tree tmpdesc, tree body)
4058 {
4059   tree size;
4060   tree type;
4061   tree offset;
4062   locus loc;
4063   stmtblock_t block;
4064   stmtblock_t cleanup;
4065   tree lbound;
4066   tree ubound;
4067   tree dubound;
4068   tree dlbound;
4069   tree dumdesc;
4070   tree tmp;
4071   tree stmt;
4072   tree stride, stride2;
4073   tree stmt_packed;
4074   tree stmt_unpacked;
4075   tree partial;
4076   gfc_se se;
4077   int n;
4078   int checkparm;
4079   int no_repack;
4080   bool optional_arg;
4081
4082   /* Do nothing for pointer and allocatable arrays.  */
4083   if (sym->attr.pointer || sym->attr.allocatable)
4084     return body;
4085
4086   if (sym->attr.dummy && gfc_is_nodesc_array (sym))
4087     return gfc_trans_g77_array (sym, body);
4088
4089   gfc_get_backend_locus (&loc);
4090   gfc_set_backend_locus (&sym->declared_at);
4091
4092   /* Descriptor type.  */
4093   type = TREE_TYPE (tmpdesc);
4094   gcc_assert (GFC_ARRAY_TYPE_P (type));
4095   dumdesc = GFC_DECL_SAVED_DESCRIPTOR (tmpdesc);
4096   dumdesc = build_fold_indirect_ref (dumdesc);
4097   gfc_start_block (&block);
4098
4099   if (sym->ts.type == BT_CHARACTER
4100       && TREE_CODE (sym->ts.cl->backend_decl) == VAR_DECL)
4101     gfc_conv_string_length (sym->ts.cl, &block);
4102
4103   checkparm = (sym->as->type == AS_EXPLICIT && flag_bounds_check);
4104
4105   no_repack = !(GFC_DECL_PACKED_ARRAY (tmpdesc)
4106                 || GFC_DECL_PARTIAL_PACKED_ARRAY (tmpdesc));
4107
4108   if (GFC_DECL_PARTIAL_PACKED_ARRAY (tmpdesc))
4109     {
4110       /* For non-constant shape arrays we only check if the first dimension
4111          is contiguous.  Repacking higher dimensions wouldn't gain us
4112          anything as we still don't know the array stride.  */
4113       partial = gfc_create_var (boolean_type_node, "partial");
4114       TREE_USED (partial) = 1;
4115       tmp = gfc_conv_descriptor_stride (dumdesc, gfc_rank_cst[0]);
4116       tmp = fold_build2 (EQ_EXPR, boolean_type_node, tmp, gfc_index_one_node);
4117       gfc_add_modify_expr (&block, partial, tmp);
4118     }
4119   else
4120     {
4121       partial = NULL_TREE;
4122     }
4123
4124   /* The naming of stmt_unpacked and stmt_packed may be counter-intuitive
4125      here, however I think it does the right thing.  */
4126   if (no_repack)
4127     {
4128       /* Set the first stride.  */
4129       stride = gfc_conv_descriptor_stride (dumdesc, gfc_rank_cst[0]);
4130       stride = gfc_evaluate_now (stride, &block);
4131
4132       tmp = build2 (EQ_EXPR, boolean_type_node, stride, gfc_index_zero_node);
4133       tmp = build3 (COND_EXPR, gfc_array_index_type, tmp,
4134                     gfc_index_one_node, stride);
4135       stride = GFC_TYPE_ARRAY_STRIDE (type, 0);
4136       gfc_add_modify_expr (&block, stride, tmp);
4137
4138       /* Allow the user to disable array repacking.  */
4139       stmt_unpacked = NULL_TREE;
4140     }
4141   else
4142     {
4143       gcc_assert (integer_onep (GFC_TYPE_ARRAY_STRIDE (type, 0)));
4144       /* A library call to repack the array if necessary.  */
4145       tmp = GFC_DECL_SAVED_DESCRIPTOR (tmpdesc);
4146       stmt_unpacked = build_call_expr (gfor_fndecl_in_pack, 1, tmp);
4147
4148       stride = gfc_index_one_node;
4149     }
4150
4151   /* This is for the case where the array data is used directly without
4152      calling the repack function.  */
4153   if (no_repack || partial != NULL_TREE)
4154     stmt_packed = gfc_conv_descriptor_data_get (dumdesc);
4155   else
4156     stmt_packed = NULL_TREE;
4157
4158   /* Assign the data pointer.  */
4159   if (stmt_packed != NULL_TREE && stmt_unpacked != NULL_TREE)
4160     {
4161       /* Don't repack unknown shape arrays when the first stride is 1.  */
4162       tmp = build3 (COND_EXPR, TREE_TYPE (stmt_packed), partial,
4163                     stmt_packed, stmt_unpacked);
4164     }
4165   else
4166     tmp = stmt_packed != NULL_TREE ? stmt_packed : stmt_unpacked;
4167   gfc_add_modify_expr (&block, tmpdesc, fold_convert (type, tmp));
4168
4169   offset = gfc_index_zero_node;
4170   size = gfc_index_one_node;
4171
4172   /* Evaluate the bounds of the array.  */
4173   for (n = 0; n < sym->as->rank; n++)
4174     {
4175       if (checkparm || !sym->as->upper[n])
4176         {
4177           /* Get the bounds of the actual parameter.  */
4178           dubound = gfc_conv_descriptor_ubound (dumdesc, gfc_rank_cst[n]);
4179           dlbound = gfc_conv_descriptor_lbound (dumdesc, gfc_rank_cst[n]);
4180         }
4181       else
4182         {
4183           dubound = NULL_TREE;
4184           dlbound = NULL_TREE;
4185         }
4186
4187       lbound = GFC_TYPE_ARRAY_LBOUND (type, n);
4188       if (!INTEGER_CST_P (lbound))
4189         {
4190           gfc_init_se (&se, NULL);
4191           gfc_conv_expr_type (&se, sym->as->lower[n],
4192                               gfc_array_index_type);
4193           gfc_add_block_to_block (&block, &se.pre);
4194           gfc_add_modify_expr (&block, lbound, se.expr);
4195         }
4196
4197       ubound = GFC_TYPE_ARRAY_UBOUND (type, n);
4198       /* Set the desired upper bound.  */
4199       if (sym->as->upper[n])
4200         {
4201           /* We know what we want the upper bound to be.  */
4202           if (!INTEGER_CST_P (ubound))
4203             {
4204               gfc_init_se (&se, NULL);
4205               gfc_conv_expr_type (&se, sym->as->upper[n],
4206                                   gfc_array_index_type);
4207               gfc_add_block_to_block (&block, &se.pre);
4208               gfc_add_modify_expr (&block, ubound, se.expr);
4209             }
4210
4211           /* Check the sizes match.  */
4212           if (checkparm)
4213             {
4214               /* Check (ubound(a) - lbound(a) == ubound(b) - lbound(b)).  */
4215               char * msg;
4216
4217               tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
4218                                  ubound, lbound);
4219               stride2 = build2 (MINUS_EXPR, gfc_array_index_type,
4220                                dubound, dlbound);
4221               tmp = fold_build2 (NE_EXPR, gfc_array_index_type, tmp, stride2);
4222               asprintf (&msg, "%s for dimension %d of array '%s'",
4223                         gfc_msg_bounds, n+1, sym->name);
4224               gfc_trans_runtime_check (tmp, &block, &loc, msg);
4225               gfc_free (msg);
4226             }
4227         }
4228       else
4229         {
4230           /* For assumed shape arrays move the upper bound by the same amount
4231              as the lower bound.  */
4232           tmp = build2 (MINUS_EXPR, gfc_array_index_type, dubound, dlbound);
4233           tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type, tmp, lbound);
4234           gfc_add_modify_expr (&block, ubound, tmp);
4235         }
4236       /* The offset of this dimension.  offset = offset - lbound * stride.  */
4237       tmp = fold_build2 (MULT_EXPR, gfc_array_index_type, lbound, stride);
4238       offset = fold_build2 (MINUS_EXPR, gfc_array_index_type, offset, tmp);
4239
4240       /* The size of this dimension, and the stride of the next.  */
4241       if (n + 1 < sym->as->rank)
4242         {
4243           stride = GFC_TYPE_ARRAY_STRIDE (type, n + 1);
4244
4245           if (no_repack || partial != NULL_TREE)
4246             {
4247               stmt_unpacked =
4248                 gfc_conv_descriptor_stride (dumdesc, gfc_rank_cst[n+1]);
4249             }
4250
4251           /* Figure out the stride if not a known constant.  */
4252           if (!INTEGER_CST_P (stride))
4253             {
4254               if (no_repack)
4255                 stmt_packed = NULL_TREE;
4256               else
4257                 {
4258                   /* Calculate stride = size * (ubound + 1 - lbound).  */
4259                   tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
4260                                      gfc_index_one_node, lbound);
4261                   tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
4262                                      ubound, tmp);
4263                   size = fold_build2 (MULT_EXPR, gfc_array_index_type,
4264                                       size, tmp);
4265                   stmt_packed = size;
4266                 }
4267
4268               /* Assign the stride.  */
4269               if (stmt_packed != NULL_TREE && stmt_unpacked != NULL_TREE)
4270                 tmp = build3 (COND_EXPR, gfc_array_index_type, partial,
4271                               stmt_unpacked, stmt_packed);
4272               else
4273                 tmp = (stmt_packed != NULL_TREE) ? stmt_packed : stmt_unpacked;
4274               gfc_add_modify_expr (&block, stride, tmp);
4275             }
4276         }
4277       else
4278         {
4279           stride = GFC_TYPE_ARRAY_SIZE (type);
4280
4281           if (stride && !INTEGER_CST_P (stride))
4282             {
4283               /* Calculate size = stride * (ubound + 1 - lbound).  */
4284               tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
4285                                  gfc_index_one_node, lbound);
4286               tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
4287                                  ubound, tmp);
4288               tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
4289                                  GFC_TYPE_ARRAY_STRIDE (type, n), tmp);
4290               gfc_add_modify_expr (&block, stride, tmp);
4291             }
4292         }
4293     }
4294
4295   /* Set the offset.  */
4296   if (TREE_CODE (GFC_TYPE_ARRAY_OFFSET (type)) == VAR_DECL)
4297     gfc_add_modify_expr (&block, GFC_TYPE_ARRAY_OFFSET (type), offset);
4298
4299   gfc_trans_vla_type_sizes (sym, &block);
4300
4301   stmt = gfc_finish_block (&block);
4302
4303   gfc_start_block (&block);
4304
4305   /* Only do the entry/initialization code if the arg is present.  */
4306   dumdesc = GFC_DECL_SAVED_DESCRIPTOR (tmpdesc);
4307   optional_arg = (sym->attr.optional
4308                   || (sym->ns->proc_name->attr.entry_master
4309                       && sym->attr.dummy));
4310   if (optional_arg)
4311     {
4312       tmp = gfc_conv_expr_present (sym);
4313       stmt = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt ());
4314     }
4315   gfc_add_expr_to_block (&block, stmt);
4316
4317   /* Add the main function body.  */
4318   gfc_add_expr_to_block (&block, body);
4319
4320   /* Cleanup code.  */
4321   if (!no_repack)
4322     {
4323       gfc_start_block (&cleanup);
4324       
4325       if (sym->attr.intent != INTENT_IN)
4326         {
4327           /* Copy the data back.  */
4328           tmp = build_call_expr (gfor_fndecl_in_unpack, 2, dumdesc, tmpdesc);
4329           gfc_add_expr_to_block (&cleanup, tmp);
4330         }
4331
4332       /* Free the temporary.  */
4333       tmp = gfc_call_free (tmpdesc);
4334       gfc_add_expr_to_block (&cleanup, tmp);
4335
4336       stmt = gfc_finish_block (&cleanup);
4337         
4338       /* Only do the cleanup if the array was repacked.  */
4339       tmp = build_fold_indirect_ref (dumdesc);
4340       tmp = gfc_conv_descriptor_data_get (tmp);
4341       tmp = build2 (NE_EXPR, boolean_type_node, tmp, tmpdesc);
4342       stmt = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt ());
4343
4344       if (optional_arg)
4345         {
4346           tmp = gfc_conv_expr_present (sym);
4347           stmt = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt ());
4348         }
4349       gfc_add_expr_to_block (&block, stmt);
4350     }
4351   /* We don't need to free any memory allocated by internal_pack as it will
4352      be freed at the end of the function by pop_context.  */
4353   return gfc_finish_block (&block);
4354 }
4355
4356
4357 /* Calculate the overall offset, including subreferences.  */
4358 static void
4359 gfc_get_dataptr_offset (stmtblock_t *block, tree parm, tree desc, tree offset,
4360                         bool subref, gfc_expr *expr)
4361 {
4362   tree tmp;
4363   tree field;
4364   tree stride;
4365   tree index;
4366   gfc_ref *ref;
4367   gfc_se start;
4368   int n;
4369
4370   /* If offset is NULL and this is not a subreferenced array, there is
4371      nothing to do.  */
4372   if (offset == NULL_TREE)
4373     {
4374       if (subref)
4375         offset = gfc_index_zero_node;
4376       else
4377         return;
4378     }
4379
4380   tmp = gfc_conv_array_data (desc);
4381   tmp = build_fold_indirect_ref (tmp);
4382   tmp = gfc_build_array_ref (tmp, offset, NULL);
4383
4384   /* Offset the data pointer for pointer assignments from arrays with
4385      subreferences; eg. my_integer => my_type(:)%integer_component.  */
4386   if (subref)
4387     {
4388       /* Go past the array reference.  */
4389       for (ref = expr->ref; ref; ref = ref->next)
4390         if (ref->type == REF_ARRAY &&
4391               ref->u.ar.type != AR_ELEMENT)
4392           {
4393             ref = ref->next;
4394             break;
4395           }
4396
4397       /* Calculate the offset for each subsequent subreference.  */
4398       for (; ref; ref = ref->next)
4399         {
4400           switch (ref->type)
4401             {
4402             case REF_COMPONENT:
4403               field = ref->u.c.component->backend_decl;
4404               gcc_assert (field && TREE_CODE (field) == FIELD_DECL);
4405               tmp = build3 (COMPONENT_REF, TREE_TYPE (field), tmp, field, NULL_TREE);
4406               break;
4407
4408             case REF_SUBSTRING:
4409               gcc_assert (TREE_CODE (TREE_TYPE (tmp)) == ARRAY_TYPE);
4410               gfc_init_se (&start, NULL);
4411               gfc_conv_expr_type (&start, ref->u.ss.start, gfc_charlen_type_node);
4412               gfc_add_block_to_block (block, &start.pre);
4413               tmp = gfc_build_array_ref (tmp, start.expr, NULL);
4414               break;
4415
4416             case REF_ARRAY:
4417               gcc_assert (TREE_CODE (TREE_TYPE (tmp)) == ARRAY_TYPE
4418                             && ref->u.ar.type == AR_ELEMENT);
4419
4420               /* TODO - Add bounds checking.  */
4421               stride = gfc_index_one_node;
4422               index = gfc_index_zero_node;
4423               for (n = 0; n < ref->u.ar.dimen; n++)
4424                 {
4425                   tree itmp;
4426                   tree jtmp;
4427
4428                   /* Update the index.  */
4429                   gfc_init_se (&start, NULL);
4430                   gfc_conv_expr_type (&start, ref->u.ar.start[n], gfc_array_index_type);
4431                   itmp = gfc_evaluate_now (start.expr, block);
4432                   gfc_init_se (&start, NULL);
4433                   gfc_conv_expr_type (&start, ref->u.ar.as->lower[n], gfc_array_index_type);
4434                   jtmp = gfc_evaluate_now (start.expr, block);
4435                   itmp = fold_build2 (MINUS_EXPR, gfc_array_index_type, itmp, jtmp);
4436                   itmp = fold_build2 (MULT_EXPR, gfc_array_index_type, itmp, stride);
4437                   index = fold_build2 (PLUS_EXPR, gfc_array_index_type, itmp, index);
4438                   index = gfc_evaluate_now (index, block);
4439
4440                   /* Update the stride.  */
4441                   gfc_init_se (&start, NULL);
4442                   gfc_conv_expr_type (&start, ref->u.ar.as->upper[n], gfc_array_index_type);
4443                   itmp =  fold_build2 (MINUS_EXPR, gfc_array_index_type, start.expr, jtmp);
4444                   itmp =  fold_build2 (PLUS_EXPR, gfc_array_index_type,
4445                                        gfc_index_one_node, itmp);
4446                   stride =  fold_build2 (MULT_EXPR, gfc_array_index_type, stride, itmp);
4447                   stride = gfc_evaluate_now (stride, block);
4448                 }
4449
4450               /* Apply the index to obtain the array element.  */
4451               tmp = gfc_build_array_ref (tmp, index, NULL);
4452               break;
4453
4454             default:
4455               gcc_unreachable ();
4456               break;
4457             }
4458         }
4459     }
4460
4461   /* Set the target data pointer.  */
4462   offset = gfc_build_addr_expr (gfc_array_dataptr_type (desc), tmp);
4463   gfc_conv_descriptor_data_set (block, parm, offset);
4464 }
4465
4466
4467 /* Convert an array for passing as an actual argument.  Expressions and
4468    vector subscripts are evaluated and stored in a temporary, which is then
4469    passed.  For whole arrays the descriptor is passed.  For array sections
4470    a modified copy of the descriptor is passed, but using the original data.
4471
4472    This function is also used for array pointer assignments, and there
4473    are three cases:
4474
4475      - se->want_pointer && !se->direct_byref
4476          EXPR is an actual argument.  On exit, se->expr contains a
4477          pointer to the array descriptor.
4478
4479      - !se->want_pointer && !se->direct_byref
4480          EXPR is an actual argument to an intrinsic function or the
4481          left-hand side of a pointer assignment.  On exit, se->expr
4482          contains the descriptor for EXPR.
4483
4484      - !se->want_pointer && se->direct_byref
4485          EXPR is the right-hand side of a pointer assignment and
4486          se->expr is the descriptor for the previously-evaluated
4487          left-hand side.  The function creates an assignment from
4488          EXPR to se->expr.  */
4489
4490 void
4491 gfc_conv_expr_descriptor (gfc_se * se, gfc_expr * expr, gfc_ss * ss)
4492 {
4493   gfc_loopinfo loop;
4494   gfc_ss *secss;
4495   gfc_ss_info *info;
4496   int need_tmp;
4497   int n;
4498   tree tmp;
4499   tree desc;
4500   stmtblock_t block;
4501   tree start;
4502   tree offset;
4503   int full;
4504   bool subref_array_target = false;
4505
4506   gcc_assert (ss != gfc_ss_terminator);
4507
4508   /* Special case things we know we can pass easily.  */
4509   switch (expr->expr_type)
4510     {
4511     case EXPR_VARIABLE:
4512       /* If we have a linear array section, we can pass it directly.
4513          Otherwise we need to copy it into a temporary.  */
4514
4515       /* Find the SS for the array section.  */
4516       secss = ss;
4517       while (secss != gfc_ss_terminator && secss->type != GFC_SS_SECTION)
4518         secss = secss->next;
4519
4520       gcc_assert (secss != gfc_ss_terminator);
4521       info = &secss->data.info;
4522
4523       /* Get the descriptor for the array.  */
4524       gfc_conv_ss_descriptor (&se->pre, secss, 0);
4525       desc = info->descriptor;
4526
4527       subref_array_target = se->direct_byref && is_subref_array (expr);
4528       need_tmp = gfc_ref_needs_temporary_p (expr->ref)
4529                         && !subref_array_target;
4530
4531       if (need_tmp)
4532         full = 0;
4533       else if (GFC_ARRAY_TYPE_P (TREE_TYPE (desc)))
4534         {
4535           /* Create a new descriptor if the array doesn't have one.  */
4536           full = 0;
4537         }
4538       else if (info->ref->u.ar.type == AR_FULL)
4539         full = 1;
4540       else if (se->direct_byref)
4541         full = 0;
4542       else
4543         full = gfc_full_array_ref_p (info->ref);
4544
4545       if (full)
4546         {
4547           if (se->direct_byref)
4548             {
4549               /* Copy the descriptor for pointer assignments.  */
4550               gfc_add_modify_expr (&se->pre, se->expr, desc);
4551
4552               /* Add any offsets from subreferences.  */
4553               gfc_get_dataptr_offset (&se->pre, se->expr, desc, NULL_TREE,
4554                                       subref_array_target, expr);
4555             }
4556           else if (se->want_pointer)
4557             {
4558               /* We pass full arrays directly.  This means that pointers and
4559                  allocatable arrays should also work.  */
4560               se->expr = build_fold_addr_expr (desc);
4561             }
4562           else
4563             {
4564               se->expr = desc;
4565             }
4566
4567           if (expr->ts.type == BT_CHARACTER)
4568             se->string_length = gfc_get_expr_charlen (expr);
4569
4570           return;
4571         }
4572       break;
4573       
4574     case EXPR_FUNCTION:
4575       /* A transformational function return value will be a temporary
4576          array descriptor.  We still need to go through the scalarizer
4577          to create the descriptor.  Elemental functions ar handled as
4578          arbitrary expressions, i.e. copy to a temporary.  */
4579       secss = ss;
4580       /* Look for the SS for this function.  */
4581       while (secss != gfc_ss_terminator
4582              && (secss->type != GFC_SS_FUNCTION || secss->expr != expr))
4583         secss = secss->next;
4584
4585       if (se->direct_byref)
4586         {
4587           gcc_assert (secss != gfc_ss_terminator);
4588
4589           /* For pointer assignments pass the descriptor directly.  */
4590           se->ss = secss;
4591           se->expr = build_fold_addr_expr (se->expr);
4592           gfc_conv_expr (se, expr);
4593           return;
4594         }
4595
4596       if (secss == gfc_ss_terminator)
4597         {
4598           /* Elemental function.  */
4599           need_tmp = 1;
4600           info = NULL;
4601         }
4602       else
4603         {
4604           /* Transformational function.  */
4605           info = &secss->data.info;
4606           need_tmp = 0;
4607         }
4608       break;
4609
4610     case EXPR_ARRAY:
4611       /* Constant array constructors don't need a temporary.  */
4612       if (ss->type == GFC_SS_CONSTRUCTOR
4613           && expr->ts.type != BT_CHARACTER
4614           && gfc_constant_array_constructor_p (expr->value.constructor))
4615         {
4616           need_tmp = 0;
4617           info = &ss->data.info;
4618           secss = ss;
4619         }
4620       else
4621         {
4622           need_tmp = 1;
4623           secss = NULL;
4624           info = NULL;
4625         }
4626       break;
4627
4628     default:
4629       /* Something complicated.  Copy it into a temporary.  */
4630       need_tmp = 1;
4631       secss = NULL;
4632       info = NULL;
4633       break;
4634     }
4635
4636
4637   gfc_init_loopinfo (&loop);
4638
4639   /* Associate the SS with the loop.  */
4640   gfc_add_ss_to_loop (&loop, ss);
4641
4642   /* Tell the scalarizer not to bother creating loop variables, etc.  */
4643   if (!need_tmp)
4644     loop.array_parameter = 1;
4645   else
4646     /* The right-hand side of a pointer assignment mustn't use a temporary.  */
4647     gcc_assert (!se->direct_byref);
4648
4649   /* Setup the scalarizing loops and bounds.  */
4650   gfc_conv_ss_startstride (&loop);
4651
4652   if (need_tmp)
4653     {
4654       /* Tell the scalarizer to make a temporary.  */
4655       loop.temp_ss = gfc_get_ss ();
4656       loop.temp_ss->type = GFC_SS_TEMP;
4657       loop.temp_ss->next = gfc_ss_terminator;
4658
4659       if (expr->ts.type == BT_CHARACTER && !expr->ts.cl->backend_decl)
4660         gfc_conv_string_length (expr->ts.cl, &se->pre);
4661
4662       loop.temp_ss->data.temp.type = gfc_typenode_for_spec (&expr->ts);
4663
4664       if (expr->ts.type == BT_CHARACTER)
4665         loop.temp_ss->string_length = expr->ts.cl->backend_decl;
4666       else
4667         loop.temp_ss->string_length = NULL;
4668
4669       se->string_length = loop.temp_ss->string_length;
4670       loop.temp_ss->data.temp.dimen = loop.dimen;
4671       gfc_add_ss_to_loop (&loop, loop.temp_ss);
4672     }
4673
4674   gfc_conv_loop_setup (&loop);
4675
4676   if (need_tmp)
4677     {
4678       /* Copy into a temporary and pass that.  We don't need to copy the data
4679          back because expressions and vector subscripts must be INTENT_IN.  */
4680       /* TODO: Optimize passing function return values.  */
4681       gfc_se lse;
4682       gfc_se rse;
4683
4684       /* Start the copying loops.  */
4685       gfc_mark_ss_chain_used (loop.temp_ss, 1);
4686       gfc_mark_ss_chain_used (ss, 1);
4687       gfc_start_scalarized_body (&loop, &block);
4688
4689       /* Copy each data element.  */
4690       gfc_init_se (&lse, NULL);
4691       gfc_copy_loopinfo_to_se (&lse, &loop);
4692       gfc_init_se (&rse, NULL);
4693       gfc_copy_loopinfo_to_se (&rse, &loop);
4694
4695       lse.ss = loop.temp_ss;
4696       rse.ss = ss;
4697
4698       gfc_conv_scalarized_array_ref (&lse, NULL);
4699       if (expr->ts.type == BT_CHARACTER)
4700         {
4701           gfc_conv_expr (&rse, expr);
4702           if (POINTER_TYPE_P (TREE_TYPE (rse.expr)))
4703             rse.expr = build_fold_indirect_ref (rse.expr);
4704         }
4705       else
4706         gfc_conv_expr_val (&rse, expr);
4707
4708       gfc_add_block_to_block (&block, &rse.pre);
4709       gfc_add_block_to_block (&block, &lse.pre);
4710
4711       gfc_add_modify_expr (&block, lse.expr, rse.expr);
4712
4713       /* Finish the copying loops.  */
4714       gfc_trans_scalarizing_loops (&loop, &block);
4715
4716       desc = loop.temp_ss->data.info.descriptor;
4717
4718       gcc_assert (is_gimple_lvalue (desc));
4719     }
4720   else if (expr->expr_type == EXPR_FUNCTION)
4721     {
4722       desc = info->descriptor;
4723       se->string_length = ss->string_length;
4724     }
4725   else
4726     {
4727       /* We pass sections without copying to a temporary.  Make a new
4728          descriptor and point it at the section we want.  The loop variable
4729          limits will be the limits of the section.
4730          A function may decide to repack the array to speed up access, but
4731          we're not bothered about that here.  */
4732       int dim, ndim;
4733       tree parm;
4734       tree parmtype;
4735       tree stride;
4736       tree from;
4737       tree to;
4738       tree base;
4739
4740       /* Set the string_length for a character array.  */
4741       if (expr->ts.type == BT_CHARACTER)
4742         se->string_length =  gfc_get_expr_charlen (expr);
4743
4744       desc = info->descriptor;
4745       gcc_assert (secss && secss != gfc_ss_terminator);
4746       if (se->direct_byref)
4747         {
4748           /* For pointer assignments we fill in the destination.  */
4749           parm = se->expr;
4750           parmtype = TREE_TYPE (parm);
4751         }
4752       else
4753         {
4754           /* Otherwise make a new one.  */
4755           parmtype = gfc_get_element_type (TREE_TYPE (desc));
4756           parmtype = gfc_get_array_type_bounds (parmtype, loop.dimen,
4757                                                 loop.from, loop.to, 0);
4758           parm = gfc_create_var (parmtype, "parm");
4759         }
4760
4761       offset = gfc_index_zero_node;
4762       dim = 0;
4763
4764       /* The following can be somewhat confusing.  We have two
4765          descriptors, a new one and the original array.
4766          {parm, parmtype, dim} refer to the new one.
4767          {desc, type, n, secss, loop} refer to the original, which maybe
4768          a descriptorless array.
4769          The bounds of the scalarization are the bounds of the section.
4770          We don't have to worry about numeric overflows when calculating
4771          the offsets because all elements are within the array data.  */
4772
4773       /* Set the dtype.  */
4774       tmp = gfc_conv_descriptor_dtype (parm);
4775       gfc_add_modify_expr (&loop.pre, tmp, gfc_get_dtype (parmtype));
4776
4777       /* Set offset for assignments to pointer only to zero if it is not
4778          the full array.  */
4779       if (se->direct_byref
4780           && info->ref && info->ref->u.ar.type != AR_FULL)
4781         base = gfc_index_zero_node;
4782       else if (GFC_ARRAY_TYPE_P (TREE_TYPE (desc)))
4783         base = gfc_evaluate_now (gfc_conv_array_offset (desc), &loop.pre);
4784       else
4785         base = NULL_TREE;
4786
4787       ndim = info->ref ? info->ref->u.ar.dimen : info->dimen;
4788       for (n = 0; n < ndim; n++)
4789         {
4790           stride = gfc_conv_array_stride (desc, n);
4791
4792           /* Work out the offset.  */
4793           if (info->ref
4794               && info->ref->u.ar.dimen_type[n] == DIMEN_ELEMENT)
4795             {
4796               gcc_assert (info->subscript[n]
4797                       && info->subscript[n]->type == GFC_SS_SCALAR);
4798               start = info->subscript[n]->data.scalar.expr;
4799             }
4800           else
4801             {
4802               /* Check we haven't somehow got out of sync.  */
4803               gcc_assert (info->dim[dim] == n);
4804
4805               /* Evaluate and remember the start of the section.  */
4806               start = info->start[dim];
4807               stride = gfc_evaluate_now (stride, &loop.pre);
4808             }
4809
4810           tmp = gfc_conv_array_lbound (desc, n);
4811           tmp = fold_build2 (MINUS_EXPR, TREE_TYPE (tmp), start, tmp);
4812
4813           tmp = fold_build2 (MULT_EXPR, TREE_TYPE (tmp), tmp, stride);
4814           offset = fold_build2 (PLUS_EXPR, TREE_TYPE (tmp), offset, tmp);
4815
4816           if (info->ref
4817               && info->ref->u.ar.dimen_type[n] == DIMEN_ELEMENT)
4818             {
4819               /* For elemental dimensions, we only need the offset.  */
4820               continue;
4821             }
4822
4823           /* Vector subscripts need copying and are handled elsewhere.  */
4824           if (info->ref)
4825             gcc_assert (info->ref->u.ar.dimen_type[n] == DIMEN_RANGE);
4826
4827           /* Set the new lower bound.  */
4828           from = loop.from[dim];
4829           to = loop.to[dim];
4830
4831           /* If we have an array section or are assigning make sure that
4832              the lower bound is 1.  References to the full
4833              array should otherwise keep the original bounds.  */
4834           if ((!info->ref
4835                   || info->ref->u.ar.type != AR_FULL)
4836               && !integer_onep (from))
4837             {
4838               tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
4839                                  gfc_index_one_node, from);
4840               to = fold_build2 (PLUS_EXPR, gfc_array_index_type, to, tmp);
4841               from = gfc_index_one_node;
4842             }
4843           tmp = gfc_conv_descriptor_lbound (parm, gfc_rank_cst[dim]);
4844           gfc_add_modify_expr (&loop.pre, tmp, from);
4845
4846           /* Set the new upper bound.  */
4847           tmp = gfc_conv_descriptor_ubound (parm, gfc_rank_cst[dim]);
4848           gfc_add_modify_expr (&loop.pre, tmp, to);
4849
4850           /* Multiply the stride by the section stride to get the
4851              total stride.  */
4852           stride = fold_build2 (MULT_EXPR, gfc_array_index_type,
4853                                 stride, info->stride[dim]);
4854
4855           if (se->direct_byref && info->ref && info->ref->u.ar.type != AR_FULL)
4856             {
4857               base = fold_build2 (MINUS_EXPR, TREE_TYPE (base),
4858                                   base, stride);
4859             }
4860           else if (GFC_ARRAY_TYPE_P (TREE_TYPE (desc)))
4861             {
4862               tmp = gfc_conv_array_lbound (desc, n);
4863               tmp = fold_build2 (MINUS_EXPR, TREE_TYPE (base),
4864                                  tmp, loop.from[dim]);
4865               tmp = fold_build2 (MULT_EXPR, TREE_TYPE (base),
4866                                  tmp, gfc_conv_array_stride (desc, n));
4867               base = fold_build2 (PLUS_EXPR, TREE_TYPE (base),
4868                                   tmp, base);
4869             }
4870
4871           /* Store the new stride.  */
4872           tmp = gfc_conv_descriptor_stride (parm, gfc_rank_cst[dim]);
4873           gfc_add_modify_expr (&loop.pre, tmp, stride);
4874
4875           dim++;
4876         }
4877
4878       if (se->data_not_needed)
4879         gfc_conv_descriptor_data_set (&loop.pre, parm, gfc_index_zero_node);
4880       else
4881         /* Point the data pointer at the first element in the section.  */
4882         gfc_get_dataptr_offset (&loop.pre, parm, desc, offset,
4883                                 subref_array_target, expr);
4884
4885       if ((se->direct_byref || GFC_ARRAY_TYPE_P (TREE_TYPE (desc)))
4886           && !se->data_not_needed)
4887         {
4888           /* Set the offset.  */
4889           tmp = gfc_conv_descriptor_offset (parm);
4890           gfc_add_modify_expr (&loop.pre, tmp, base);
4891         }
4892       else
4893         {
4894           /* Only the callee knows what the correct offset it, so just set
4895              it to zero here.  */
4896           tmp = gfc_conv_descriptor_offset (parm);
4897           gfc_add_modify_expr (&loop.pre, tmp, gfc_index_zero_node);
4898         }
4899       desc = parm;
4900     }
4901
4902   if (!se->direct_byref)
4903     {
4904       /* Get a pointer to the new descriptor.  */
4905       if (se->want_pointer)
4906         se->expr = build_fold_addr_expr (desc);
4907       else
4908         se->expr = desc;
4909     }
4910
4911   gfc_add_block_to_block (&se->pre, &loop.pre);
4912   gfc_add_block_to_block (&se->post, &loop.post);
4913
4914   /* Cleanup the scalarizer.  */
4915   gfc_cleanup_loop (&loop);
4916 }
4917
4918
4919 /* Convert an array for passing as an actual parameter.  */
4920 /* TODO: Optimize passing g77 arrays.  */
4921
4922 void
4923 gfc_conv_array_parameter (gfc_se * se, gfc_expr * expr, gfc_ss * ss, int g77)
4924 {
4925   tree ptr;
4926   tree desc;
4927   tree tmp = NULL_TREE;
4928   tree stmt;
4929   tree parent = DECL_CONTEXT (current_function_decl);
4930   bool full_array_var, this_array_result;
4931   gfc_symbol *sym;
4932   stmtblock_t block;
4933
4934   full_array_var = (expr->expr_type == EXPR_VARIABLE
4935                       && expr->ref->u.ar.type == AR_FULL);
4936   sym = full_array_var ? expr->symtree->n.sym : NULL;
4937
4938   if (expr->expr_type == EXPR_ARRAY && expr->ts.type == BT_CHARACTER)
4939     {
4940       get_array_ctor_strlen (&se->pre, expr->value.constructor, &tmp);
4941       expr->ts.cl->backend_decl = gfc_evaluate_now (tmp, &se->pre);
4942       se->string_length = expr->ts.cl->backend_decl;
4943     }
4944
4945   /* Is this the result of the enclosing procedure?  */
4946   this_array_result = (full_array_var && sym->attr.flavor == FL_PROCEDURE);
4947   if (this_array_result
4948         && (sym->backend_decl != current_function_decl)
4949         && (sym->backend_decl != parent))
4950     this_array_result = false;
4951
4952   /* Passing address of the array if it is not pointer or assumed-shape.  */
4953   if (full_array_var && g77 && !this_array_result)
4954     {
4955       tmp = gfc_get_symbol_decl (sym);
4956
4957       if (sym->ts.type == BT_CHARACTER)
4958         se->string_length = sym->ts.cl->backend_decl;
4959       if (!sym->attr.pointer && sym->as->type != AS_ASSUMED_SHAPE 
4960           && !sym->attr.allocatable)
4961         {
4962           /* Some variables are declared directly, others are declared as
4963              pointers and allocated on the heap.  */
4964           if (sym->attr.dummy || POINTER_TYPE_P (TREE_TYPE (tmp)))
4965             se->expr = tmp;
4966           else
4967             se->expr = build_fold_addr_expr (tmp);
4968           return;
4969         }
4970       if (sym->attr.allocatable)
4971         {
4972           if (sym->attr.dummy)
4973             {
4974               gfc_conv_expr_descriptor (se, expr, ss);
4975               se->expr = gfc_conv_array_data (se->expr);
4976             }
4977           else
4978             se->expr = gfc_conv_array_data (tmp);
4979           return;
4980         }
4981     }
4982
4983   if (this_array_result)
4984     {
4985       /* Result of the enclosing function.  */
4986       gfc_conv_expr_descriptor (se, expr, ss);
4987       se->expr = build_fold_addr_expr (se->expr);
4988
4989       if (g77 && TREE_TYPE (TREE_TYPE (se->expr)) != NULL_TREE
4990               && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (TREE_TYPE (se->expr))))
4991         se->expr = gfc_conv_array_data (build_fold_indirect_ref (se->expr));
4992
4993       return;
4994     }
4995   else
4996     {
4997       /* Every other type of array.  */
4998       se->want_pointer = 1;
4999       gfc_conv_expr_descriptor (se, expr, ss);
5000     }
5001
5002
5003   /* Deallocate the allocatable components of structures that are
5004      not variable.  */
5005   if (expr->ts.type == BT_DERIVED
5006         && expr->ts.derived->attr.alloc_comp
5007         && expr->expr_type != EXPR_VARIABLE)
5008     {
5009       tmp = build_fold_indirect_ref (se->expr);
5010       tmp = gfc_deallocate_alloc_comp (expr->ts.derived, tmp, expr->rank);
5011       gfc_add_expr_to_block (&se->post, tmp);
5012     }
5013
5014   if (g77)
5015     {
5016       desc = se->expr;
5017       /* Repack the array.  */
5018       ptr = build_call_expr (gfor_fndecl_in_pack, 1, desc);
5019       ptr = gfc_evaluate_now (ptr, &se->pre);
5020       se->expr = ptr;
5021
5022       gfc_start_block (&block);
5023
5024       /* Copy the data back.  */
5025       tmp = build_call_expr (gfor_fndecl_in_unpack, 2, desc, ptr);
5026       gfc_add_expr_to_block (&block, tmp);
5027
5028       /* Free the temporary.  */
5029       tmp = gfc_call_free (convert (pvoid_type_node, ptr));
5030       gfc_add_expr_to_block (&block, tmp);
5031
5032       stmt = gfc_finish_block (&block);
5033
5034       gfc_init_block (&block);
5035       /* Only if it was repacked.  This code needs to be executed before the
5036          loop cleanup code.  */
5037       tmp = build_fold_indirect_ref (desc);
5038       tmp = gfc_conv_array_data (tmp);
5039       tmp = build2 (NE_EXPR, boolean_type_node,
5040                     fold_convert (TREE_TYPE (tmp), ptr), tmp);
5041       tmp = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt ());
5042
5043       gfc_add_expr_to_block (&block, tmp);
5044       gfc_add_block_to_block (&block, &se->post);
5045
5046       gfc_init_block (&se->post);
5047       gfc_add_block_to_block (&se->post, &block);
5048     }
5049 }
5050
5051
5052 /* Generate code to deallocate an array, if it is allocated.  */
5053
5054 tree
5055 gfc_trans_dealloc_allocated (tree descriptor)
5056
5057   tree tmp;
5058   tree var;
5059   stmtblock_t block;
5060
5061   gfc_start_block (&block);
5062
5063   var = gfc_conv_descriptor_data_get (descriptor);
5064   STRIP_NOPS (var);
5065
5066   /* Call array_deallocate with an int * present in the second argument.
5067      Although it is ignored here, it's presence ensures that arrays that
5068      are already deallocated are ignored.  */
5069   tmp = gfc_deallocate_with_status (var, NULL_TREE, true);
5070   gfc_add_expr_to_block (&block, tmp);
5071
5072   /* Zero the data pointer.  */
5073   tmp = build2 (MODIFY_EXPR, void_type_node,
5074                 var, build_int_cst (TREE_TYPE (var), 0));
5075   gfc_add_expr_to_block (&block, tmp);
5076
5077   return gfc_finish_block (&block);
5078 }
5079
5080
5081 /* This helper function calculates the size in words of a full array.  */
5082
5083 static tree
5084 get_full_array_size (stmtblock_t *block, tree decl, int rank)
5085 {
5086   tree idx;
5087   tree nelems;
5088   tree tmp;
5089   idx = gfc_rank_cst[rank - 1];
5090   nelems = gfc_conv_descriptor_ubound (decl, idx);
5091   tmp = gfc_conv_descriptor_lbound (decl, idx);
5092   tmp = build2 (MINUS_EXPR, gfc_array_index_type, nelems, tmp);
5093   tmp = build2 (PLUS_EXPR, gfc_array_index_type,
5094                 tmp, gfc_index_one_node);
5095   tmp = gfc_evaluate_now (tmp, block);
5096
5097   nelems = gfc_conv_descriptor_stride (decl, idx);
5098   tmp = build2 (MULT_EXPR, gfc_array_index_type, nelems, tmp);
5099   return gfc_evaluate_now (tmp, block);
5100 }
5101
5102
5103 /* Allocate dest to the same size as src, and copy src -> dest.  */
5104
5105 tree
5106 gfc_duplicate_allocatable(tree dest, tree src, tree type, int rank)
5107 {
5108   tree tmp;
5109   tree size;
5110   tree nelems;
5111   tree null_cond;
5112   tree null_data;
5113   stmtblock_t block;
5114
5115   /* If the source is null, set the destination to null.  */
5116   gfc_init_block (&block);
5117   gfc_conv_descriptor_data_set (&block, dest, null_pointer_node);
5118   null_data = gfc_finish_block (&block);
5119
5120   gfc_init_block (&block);
5121
5122   nelems = get_full_array_size (&block, src, rank);
5123   size = fold_build2 (MULT_EXPR, gfc_array_index_type, nelems,
5124                       fold_convert (gfc_array_index_type,
5125                                     TYPE_SIZE_UNIT (gfc_get_element_type (type))));
5126
5127   /* Allocate memory to the destination.  */
5128   tmp = gfc_call_malloc (&block, TREE_TYPE (gfc_conv_descriptor_data_get (src)),
5129                          size);
5130   gfc_conv_descriptor_data_set (&block, dest, tmp);
5131
5132   /* We know the temporary and the value will be the same length,
5133      so can use memcpy.  */
5134   tmp = built_in_decls[BUILT_IN_MEMCPY];
5135   tmp = build_call_expr (tmp, 3, gfc_conv_descriptor_data_get (dest),
5136                          gfc_conv_descriptor_data_get (src), size);
5137   gfc_add_expr_to_block (&block, tmp);
5138   tmp = gfc_finish_block (&block);
5139
5140   /* Null the destination if the source is null; otherwise do
5141      the allocate and copy.  */
5142   null_cond = gfc_conv_descriptor_data_get (src);
5143   null_cond = convert (pvoid_type_node, null_cond);
5144   null_cond = build2 (NE_EXPR, boolean_type_node, null_cond,
5145                       null_pointer_node);
5146   return build3_v (COND_EXPR, null_cond, tmp, null_data);
5147 }
5148
5149
5150 /* Recursively traverse an object of derived type, generating code to
5151    deallocate, nullify or copy allocatable components.  This is the work horse
5152    function for the functions named in this enum.  */
5153
5154 enum {DEALLOCATE_ALLOC_COMP = 1, NULLIFY_ALLOC_COMP, COPY_ALLOC_COMP};
5155
5156 static tree
5157 structure_alloc_comps (gfc_symbol * der_type, tree decl,
5158                        tree dest, int rank, int purpose)
5159 {
5160   gfc_component *c;
5161   gfc_loopinfo loop;
5162   stmtblock_t fnblock;
5163   stmtblock_t loopbody;
5164   tree tmp;
5165   tree comp;
5166   tree dcmp;
5167   tree nelems;
5168   tree index;
5169   tree var;
5170   tree cdecl;
5171   tree ctype;
5172   tree vref, dref;
5173   tree null_cond = NULL_TREE;
5174
5175   gfc_init_block (&fnblock);
5176
5177   if (POINTER_TYPE_P (TREE_TYPE (decl)))
5178     decl = build_fold_indirect_ref (decl);
5179
5180   /* If this an array of derived types with allocatable components
5181      build a loop and recursively call this function.  */
5182   if (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE
5183         || GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl)))
5184     {
5185       tmp = gfc_conv_array_data (decl);
5186       var = build_fold_indirect_ref (tmp);
5187         
5188       /* Get the number of elements - 1 and set the counter.  */
5189       if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl)))
5190         {
5191           /* Use the descriptor for an allocatable array.  Since this
5192              is a full array reference, we only need the descriptor
5193              information from dimension = rank.  */
5194           tmp = get_full_array_size (&fnblock, decl, rank);
5195           tmp = build2 (MINUS_EXPR, gfc_array_index_type,
5196                         tmp, gfc_index_one_node);
5197
5198           null_cond = gfc_conv_descriptor_data_get (decl);
5199           null_cond = build2 (NE_EXPR, boolean_type_node, null_cond,
5200                               build_int_cst (TREE_TYPE (null_cond), 0));
5201         }
5202       else
5203         {
5204           /*  Otherwise use the TYPE_DOMAIN information.  */
5205           tmp =  array_type_nelts (TREE_TYPE (decl));
5206           tmp = fold_convert (gfc_array_index_type, tmp);
5207         }
5208
5209       /* Remember that this is, in fact, the no. of elements - 1.  */
5210       nelems = gfc_evaluate_now (tmp, &fnblock);
5211       index = gfc_create_var (gfc_array_index_type, "S");
5212
5213       /* Build the body of the loop.  */
5214       gfc_init_block (&loopbody);
5215
5216       vref = gfc_build_array_ref (var, index, NULL);
5217
5218       if (purpose == COPY_ALLOC_COMP)
5219         {
5220           tmp = gfc_duplicate_allocatable (dest, decl, TREE_TYPE(decl), rank);
5221           gfc_add_expr_to_block (&fnblock, tmp);
5222
5223           tmp = build_fold_indirect_ref (gfc_conv_descriptor_data_get (dest));
5224           dref = gfc_build_array_ref (tmp, index, NULL);
5225           tmp = structure_alloc_comps (der_type, vref, dref, rank, purpose);
5226         }
5227       else
5228         tmp = structure_alloc_comps (der_type, vref, NULL_TREE, rank, purpose);
5229
5230       gfc_add_expr_to_block (&loopbody, tmp);
5231
5232       /* Build the loop and return.  */
5233       gfc_init_loopinfo (&loop);
5234       loop.dimen = 1;
5235       loop.from[0] = gfc_index_zero_node;
5236       loop.loopvar[0] = index;
5237       loop.to[0] = nelems;
5238       gfc_trans_scalarizing_loops (&loop, &loopbody);
5239       gfc_add_block_to_block (&fnblock, &loop.pre);
5240
5241       tmp = gfc_finish_block (&fnblock);
5242       if (null_cond != NULL_TREE)
5243         tmp = build3_v (COND_EXPR, null_cond, tmp, build_empty_stmt ());
5244
5245       return tmp;
5246     }
5247
5248   /* Otherwise, act on the components or recursively call self to
5249      act on a chain of components.  */
5250   for (c = der_type->components; c; c = c->next)
5251     {
5252       bool cmp_has_alloc_comps = (c->ts.type == BT_DERIVED)
5253                                     && c->ts.derived->attr.alloc_comp;
5254       cdecl = c->backend_decl;
5255       ctype = TREE_TYPE (cdecl);
5256
5257       switch (purpose)
5258         {
5259         case DEALLOCATE_ALLOC_COMP:
5260           /* Do not deallocate the components of ultimate pointer
5261              components.  */
5262           if (cmp_has_alloc_comps && !c->pointer)
5263             {
5264               comp = build3 (COMPONENT_REF, ctype, decl, cdecl, NULL_TREE);
5265               rank = c->as ? c->as->rank : 0;
5266               tmp = structure_alloc_comps (c->ts.derived, comp, NULL_TREE,
5267                                            rank, purpose);
5268               gfc_add_expr_to_block (&fnblock, tmp);
5269             }
5270
5271           if (c->allocatable)
5272             {
5273               comp = build3 (COMPONENT_REF, ctype, decl, cdecl, NULL_TREE);
5274               tmp = gfc_trans_dealloc_allocated (comp);
5275               gfc_add_expr_to_block (&fnblock, tmp);
5276             }
5277           break;
5278
5279         case NULLIFY_ALLOC_COMP:
5280           if (c->pointer)
5281             continue;
5282           else if (c->allocatable)
5283             {
5284               comp = build3 (COMPONENT_REF, ctype, decl, cdecl, NULL_TREE);
5285               gfc_conv_descriptor_data_set (&fnblock, comp, null_pointer_node);
5286             }
5287           else if (cmp_has_alloc_comps)
5288             {
5289               comp = build3 (COMPONENT_REF, ctype, decl, cdecl, NULL_TREE);
5290               rank = c->as ? c->as->rank : 0;
5291               tmp = structure_alloc_comps (c->ts.derived, comp, NULL_TREE,
5292                                            rank, purpose);
5293               gfc_add_expr_to_block (&fnblock, tmp);
5294             }
5295           break;
5296
5297         case COPY_ALLOC_COMP:
5298           if (c->pointer)
5299             continue;
5300
5301           /* We need source and destination components.  */
5302           comp = build3 (COMPONENT_REF, ctype, decl, cdecl, NULL_TREE);
5303           dcmp = build3 (COMPONENT_REF, ctype, dest, cdecl, NULL_TREE);
5304           dcmp = fold_convert (TREE_TYPE (comp), dcmp);
5305
5306           if (c->allocatable && !cmp_has_alloc_comps)
5307             {
5308               tmp = gfc_duplicate_allocatable(dcmp, comp, ctype, c->as->rank);
5309               gfc_add_expr_to_block (&fnblock, tmp);
5310             }
5311
5312           if (cmp_has_alloc_comps)
5313             {
5314               rank = c->as ? c->as->rank : 0;
5315               tmp = fold_convert (TREE_TYPE (dcmp), comp);
5316               gfc_add_modify_expr (&fnblock, dcmp, tmp);
5317               tmp = structure_alloc_comps (c->ts.derived, comp, dcmp,
5318                                            rank, purpose);
5319               gfc_add_expr_to_block (&fnblock, tmp);
5320             }
5321           break;
5322
5323         default:
5324           gcc_unreachable ();
5325           break;
5326         }
5327     }
5328
5329   return gfc_finish_block (&fnblock);
5330 }
5331
5332 /* Recursively traverse an object of derived type, generating code to
5333    nullify allocatable components.  */
5334
5335 tree
5336 gfc_nullify_alloc_comp (gfc_symbol * der_type, tree decl, int rank)
5337 {
5338   return structure_alloc_comps (der_type, decl, NULL_TREE, rank,
5339                                 NULLIFY_ALLOC_COMP);
5340 }
5341
5342
5343 /* Recursively traverse an object of derived type, generating code to
5344    deallocate allocatable components.  */
5345
5346 tree
5347 gfc_deallocate_alloc_comp (gfc_symbol * der_type, tree decl, int rank)
5348 {
5349   return structure_alloc_comps (der_type, decl, NULL_TREE, rank,
5350                                 DEALLOCATE_ALLOC_COMP);
5351 }
5352
5353
5354 /* Recursively traverse an object of derived type, generating code to
5355    copy its allocatable components.  */
5356
5357 tree
5358 gfc_copy_alloc_comp (gfc_symbol * der_type, tree decl, tree dest, int rank)
5359 {
5360   return structure_alloc_comps (der_type, decl, dest, rank, COPY_ALLOC_COMP);
5361 }
5362
5363
5364 /* NULLIFY an allocatable/pointer array on function entry, free it on exit.
5365    Do likewise, recursively if necessary, with the allocatable components of
5366    derived types.  */
5367
5368 tree
5369 gfc_trans_deferred_array (gfc_symbol * sym, tree body)
5370 {
5371   tree type;
5372   tree tmp;
5373   tree descriptor;
5374   stmtblock_t fnblock;
5375   locus loc;
5376   int rank;
5377   bool sym_has_alloc_comp;
5378
5379   sym_has_alloc_comp = (sym->ts.type == BT_DERIVED)
5380                           && sym->ts.derived->attr.alloc_comp;
5381
5382   /* Make sure the frontend gets these right.  */
5383   if (!(sym->attr.pointer || sym->attr.allocatable || sym_has_alloc_comp))
5384     fatal_error ("Possible frontend bug: Deferred array size without pointer, "
5385                  "allocatable attribute or derived type without allocatable "
5386                  "components.");
5387
5388   gfc_init_block (&fnblock);
5389
5390   gcc_assert (TREE_CODE (sym->backend_decl) == VAR_DECL
5391                 || TREE_CODE (sym->backend_decl) == PARM_DECL);
5392
5393   if (sym->ts.type == BT_CHARACTER
5394       && !INTEGER_CST_P (sym->ts.cl->backend_decl))
5395     {
5396       gfc_conv_string_length (sym->ts.cl, &fnblock);
5397       gfc_trans_vla_type_sizes (sym, &fnblock);
5398     }
5399
5400   /* Dummy and use associated variables don't need anything special.  */
5401   if (sym->attr.dummy || sym->attr.use_assoc)
5402     {
5403       gfc_add_expr_to_block (&fnblock, body);
5404
5405       return gfc_finish_block (&fnblock);
5406     }
5407
5408   gfc_get_backend_locus (&loc);
5409   gfc_set_backend_locus (&sym->declared_at);
5410   descriptor = sym->backend_decl;
5411
5412   /* Although static, derived types with default initializers and
5413      allocatable components must not be nulled wholesale; instead they
5414      are treated component by component.  */
5415   if (TREE_STATIC (descriptor) && !sym_has_alloc_comp)
5416     {
5417       /* SAVEd variables are not freed on exit.  */
5418       gfc_trans_static_array_pointer (sym);
5419       return body;
5420     }
5421
5422   /* Get the descriptor type.  */
5423   type = TREE_TYPE (sym->backend_decl);
5424     
5425   if (sym_has_alloc_comp && !(sym->attr.pointer || sym->attr.allocatable))
5426     {
5427       if (!sym->attr.save)
5428         {
5429           rank = sym->as ? sym->as->rank : 0;
5430           tmp = gfc_nullify_alloc_comp (sym->ts.derived, descriptor, rank);
5431           gfc_add_expr_to_block (&fnblock, tmp);
5432         }
5433     }
5434   else if (!GFC_DESCRIPTOR_TYPE_P (type))
5435     {
5436       /* If the backend_decl is not a descriptor, we must have a pointer
5437          to one.  */
5438       descriptor = build_fold_indirect_ref (sym->backend_decl);
5439       type = TREE_TYPE (descriptor);
5440     }
5441   
5442   /* NULLIFY the data pointer.  */
5443   if (GFC_DESCRIPTOR_TYPE_P (type))
5444     gfc_conv_descriptor_data_set (&fnblock, descriptor, null_pointer_node);
5445
5446   gfc_add_expr_to_block (&fnblock, body);
5447
5448   gfc_set_backend_locus (&loc);
5449
5450   /* Allocatable arrays need to be freed when they go out of scope.
5451      The allocatable components of pointers must not be touched.  */
5452   if (sym_has_alloc_comp && !(sym->attr.function || sym->attr.result)
5453       && !sym->attr.pointer && !sym->attr.save)
5454     {
5455       int rank;
5456       rank = sym->as ? sym->as->rank : 0;
5457       tmp = gfc_deallocate_alloc_comp (sym->ts.derived, descriptor, rank);
5458       gfc_add_expr_to_block (&fnblock, tmp);
5459     }
5460
5461   if (sym->attr.allocatable)
5462     {
5463       tmp = gfc_trans_dealloc_allocated (sym->backend_decl);
5464       gfc_add_expr_to_block (&fnblock, tmp);
5465     }
5466
5467   return gfc_finish_block (&fnblock);
5468 }
5469
5470 /************ Expression Walking Functions ******************/
5471
5472 /* Walk a variable reference.
5473
5474    Possible extension - multiple component subscripts.
5475     x(:,:) = foo%a(:)%b(:)
5476    Transforms to
5477     forall (i=..., j=...)
5478       x(i,j) = foo%a(j)%b(i)
5479     end forall
5480    This adds a fair amount of complexity because you need to deal with more
5481    than one ref.  Maybe handle in a similar manner to vector subscripts.
5482    Maybe not worth the effort.  */
5483
5484
5485 static gfc_ss *
5486 gfc_walk_variable_expr (gfc_ss * ss, gfc_expr * expr)
5487 {
5488   gfc_ref *ref;
5489   gfc_array_ref *ar;
5490   gfc_ss *newss;
5491   gfc_ss *head;
5492   int n;
5493
5494   for (ref = expr->ref; ref; ref = ref->next)
5495     if (ref->type == REF_ARRAY && ref->u.ar.type != AR_ELEMENT)
5496       break;
5497
5498   for (; ref; ref = ref->next)
5499     {
5500       if (ref->type == REF_SUBSTRING)
5501         {
5502           newss = gfc_get_ss ();
5503           newss->type = GFC_SS_SCALAR;
5504           newss->expr = ref->u.ss.start;
5505           newss->next = ss;
5506           ss = newss;
5507
5508           newss = gfc_get_ss ();
5509           newss->type = GFC_SS_SCALAR;
5510           newss->expr = ref->u.ss.end;
5511           newss->next = ss;
5512           ss = newss;
5513         }
5514
5515       /* We're only interested in array sections from now on.  */
5516       if (ref->type != REF_ARRAY)
5517         continue;
5518
5519       ar = &ref->u.ar;
5520       switch (ar->type)
5521         {
5522         case AR_ELEMENT:
5523           for (n = 0; n < ar->dimen; n++)
5524             {
5525               newss = gfc_get_ss ();
5526               newss->type = GFC_SS_SCALAR;
5527               newss->expr = ar->start[n];
5528               newss->next = ss;
5529               ss = newss;
5530             }
5531           break;
5532
5533         case AR_FULL:
5534           newss = gfc_get_ss ();
5535           newss->type = GFC_SS_SECTION;
5536           newss->expr = expr;
5537           newss->next = ss;
5538           newss->data.info.dimen = ar->as->rank;
5539           newss->data.info.ref = ref;
5540
5541           /* Make sure array is the same as array(:,:), this way
5542              we don't need to special case all the time.  */
5543           ar->dimen = ar->as->rank;
5544           for (n = 0; n < ar->dimen; n++)
5545             {
5546               newss->data.info.dim[n] = n;
5547               ar->dimen_type[n] = DIMEN_RANGE;
5548
5549               gcc_assert (ar->start[n] == NULL);
5550               gcc_assert (ar->end[n] == NULL);
5551               gcc_assert (ar->stride[n] == NULL);
5552             }
5553           ss = newss;
5554           break;
5555
5556         case AR_SECTION:
5557           newss = gfc_get_ss ();
5558           newss->type = GFC_SS_SECTION;
5559           newss->expr = expr;
5560           newss->next = ss;
5561           newss->data.info.dimen = 0;
5562           newss->data.info.ref = ref;
5563
5564           head = newss;
5565
5566           /* We add SS chains for all the subscripts in the section.  */
5567           for (n = 0; n < ar->dimen; n++)
5568             {
5569               gfc_ss *indexss;
5570
5571               switch (ar->dimen_type[n])
5572                 {
5573                 case DIMEN_ELEMENT:
5574                   /* Add SS for elemental (scalar) subscripts.  */
5575                   gcc_assert (ar->start[n]);
5576                   indexss = gfc_get_ss ();
5577                   indexss->type = GFC_SS_SCALAR;
5578                   indexss->expr = ar->start[n];
5579                   indexss->next = gfc_ss_terminator;
5580                   indexss->loop_chain = gfc_ss_terminator;
5581                   newss->data.info.subscript[n] = indexss;
5582                   break;
5583
5584                 case DIMEN_RANGE:
5585                   /* We don't add anything for sections, just remember this
5586                      dimension for later.  */
5587                   newss->data.info.dim[newss->data.info.dimen] = n;
5588                   newss->data.info.dimen++;
5589                   break;
5590
5591                 case DIMEN_VECTOR:
5592                   /* Create a GFC_SS_VECTOR index in which we can store
5593                      the vector's descriptor.  */
5594                   indexss = gfc_get_ss ();
5595                   indexss->type = GFC_SS_VECTOR;
5596                   indexss->expr = ar->start[n];
5597                   indexss->next = gfc_ss_terminator;
5598                   indexss->loop_chain = gfc_ss_terminator;
5599                   newss->data.info.subscript[n] = indexss;
5600                   newss->data.info.dim[newss->data.info.dimen] = n;
5601                   newss->data.info.dimen++;
5602                   break;
5603
5604                 default:
5605                   /* We should know what sort of section it is by now.  */
5606                   gcc_unreachable ();
5607                 }
5608             }
5609           /* We should have at least one non-elemental dimension.  */
5610           gcc_assert (newss->data.info.dimen > 0);
5611           ss = newss;
5612           break;
5613
5614         default:
5615           /* We should know what sort of section it is by now.  */
5616           gcc_unreachable ();
5617         }
5618
5619     }
5620   return ss;
5621 }
5622
5623
5624 /* Walk an expression operator. If only one operand of a binary expression is
5625    scalar, we must also add the scalar term to the SS chain.  */
5626
5627 static gfc_ss *
5628 gfc_walk_op_expr (gfc_ss * ss, gfc_expr * expr)
5629 {
5630   gfc_ss *head;
5631   gfc_ss *head2;
5632   gfc_ss *newss;
5633
5634   head = gfc_walk_subexpr (ss, expr->value.op.op1);
5635   if (expr->value.op.op2 == NULL)
5636     head2 = head;
5637   else
5638     head2 = gfc_walk_subexpr (head, expr->value.op.op2);
5639
5640   /* All operands are scalar.  Pass back and let the caller deal with it.  */
5641   if (head2 == ss)
5642     return head2;
5643
5644   /* All operands require scalarization.  */
5645   if (head != ss && (expr->value.op.op2 == NULL || head2 != head))
5646     return head2;
5647
5648   /* One of the operands needs scalarization, the other is scalar.
5649      Create a gfc_ss for the scalar expression.  */
5650   newss = gfc_get_ss ();
5651   newss->type = GFC_SS_SCALAR;
5652   if (head == ss)
5653     {
5654       /* First operand is scalar.  We build the chain in reverse order, so
5655          add the scarar SS after the second operand.  */
5656       head = head2;
5657       while (head && head->next != ss)
5658         head = head->next;
5659       /* Check we haven't somehow broken the chain.  */
5660       gcc_assert (head);
5661       newss->next = ss;
5662       head->next = newss;
5663       newss->expr = expr->value.op.op1;
5664     }
5665   else                          /* head2 == head */
5666     {
5667       gcc_assert (head2 == head);
5668       /* Second operand is scalar.  */
5669       newss->next = head2;
5670       head2 = newss;
5671       newss->expr = expr->value.op.op2;
5672     }
5673
5674   return head2;
5675 }
5676
5677
5678 /* Reverse a SS chain.  */
5679
5680 gfc_ss *
5681 gfc_reverse_ss (gfc_ss * ss)
5682 {
5683   gfc_ss *next;
5684   gfc_ss *head;
5685
5686   gcc_assert (ss != NULL);
5687
5688   head = gfc_ss_terminator;
5689   while (ss != gfc_ss_terminator)
5690     {
5691       next = ss->next;
5692       /* Check we didn't somehow break the chain.  */
5693       gcc_assert (next != NULL);
5694       ss->next = head;
5695       head = ss;
5696       ss = next;
5697     }
5698
5699   return (head);
5700 }
5701
5702
5703 /* Walk the arguments of an elemental function.  */
5704
5705 gfc_ss *
5706 gfc_walk_elemental_function_args (gfc_ss * ss, gfc_actual_arglist *arg,
5707                                   gfc_ss_type type)
5708 {
5709   int scalar;
5710   gfc_ss *head;
5711   gfc_ss *tail;
5712   gfc_ss *newss;
5713
5714   head = gfc_ss_terminator;
5715   tail = NULL;
5716   scalar = 1;
5717   for (; arg; arg = arg->next)
5718     {
5719       if (!arg->expr)
5720         continue;
5721
5722       newss = gfc_walk_subexpr (head, arg->expr);
5723       if (newss == head)
5724         {
5725           /* Scalar argument.  */
5726           newss = gfc_get_ss ();
5727           newss->type = type;
5728           newss->expr = arg->expr;
5729           newss->next = head;
5730         }
5731       else
5732         scalar = 0;
5733
5734       head = newss;
5735       if (!tail)
5736         {
5737           tail = head;
5738           while (tail->next != gfc_ss_terminator)
5739             tail = tail->next;
5740         }
5741     }
5742
5743   if (scalar)
5744     {
5745       /* If all the arguments are scalar we don't need the argument SS.  */
5746       gfc_free_ss_chain (head);
5747       /* Pass it back.  */
5748       return ss;
5749     }
5750
5751   /* Add it onto the existing chain.  */
5752   tail->next = ss;
5753   return head;
5754 }
5755
5756
5757 /* Walk a function call.  Scalar functions are passed back, and taken out of
5758    scalarization loops.  For elemental functions we walk their arguments.
5759    The result of functions returning arrays is stored in a temporary outside
5760    the loop, so that the function is only called once.  Hence we do not need
5761    to walk their arguments.  */
5762
5763 static gfc_ss *
5764 gfc_walk_function_expr (gfc_ss * ss, gfc_expr * expr)
5765 {
5766   gfc_ss *newss;
5767   gfc_intrinsic_sym *isym;
5768   gfc_symbol *sym;
5769
5770   isym = expr->value.function.isym;
5771
5772   /* Handle intrinsic functions separately.  */
5773   if (isym)
5774     return gfc_walk_intrinsic_function (ss, expr, isym);
5775
5776   sym = expr->value.function.esym;
5777   if (!sym)
5778       sym = expr->symtree->n.sym;
5779
5780   /* A function that returns arrays.  */
5781   if (gfc_return_by_reference (sym) && sym->result->attr.dimension)
5782     {
5783       newss = gfc_get_ss ();
5784       newss->type = GFC_SS_FUNCTION;
5785       newss->expr = expr;
5786       newss->next = ss;
5787       newss->data.info.dimen = expr->rank;
5788       return newss;
5789     }
5790
5791   /* Walk the parameters of an elemental function.  For now we always pass
5792      by reference.  */
5793   if (sym->attr.elemental)
5794     return gfc_walk_elemental_function_args (ss, expr->value.function.actual,
5795                                              GFC_SS_REFERENCE);
5796
5797   /* Scalar functions are OK as these are evaluated outside the scalarization
5798      loop.  Pass back and let the caller deal with it.  */
5799   return ss;
5800 }
5801
5802
5803 /* An array temporary is constructed for array constructors.  */
5804
5805 static gfc_ss *
5806 gfc_walk_array_constructor (gfc_ss * ss, gfc_expr * expr)
5807 {
5808   gfc_ss *newss;
5809   int n;
5810
5811   newss = gfc_get_ss ();
5812   newss->type = GFC_SS_CONSTRUCTOR;
5813   newss->expr = expr;
5814   newss->next = ss;
5815   newss->data.info.dimen = expr->rank;
5816   for (n = 0; n < expr->rank; n++)
5817     newss->data.info.dim[n] = n;
5818
5819   return newss;
5820 }
5821
5822
5823 /* Walk an expression.  Add walked expressions to the head of the SS chain.
5824    A wholly scalar expression will not be added.  */
5825
5826 static gfc_ss *
5827 gfc_walk_subexpr (gfc_ss * ss, gfc_expr * expr)
5828 {
5829   gfc_ss *head;
5830
5831   switch (expr->expr_type)
5832     {
5833     case EXPR_VARIABLE:
5834       head = gfc_walk_variable_expr (ss, expr);
5835       return head;
5836
5837     case EXPR_OP:
5838       head = gfc_walk_op_expr (ss, expr);
5839       return head;
5840
5841     case EXPR_FUNCTION:
5842       head = gfc_walk_function_expr (ss, expr);
5843       return head;
5844
5845     case EXPR_CONSTANT:
5846     case EXPR_NULL:
5847     case EXPR_STRUCTURE:
5848       /* Pass back and let the caller deal with it.  */
5849       break;
5850
5851     case EXPR_ARRAY:
5852       head = gfc_walk_array_constructor (ss, expr);
5853       return head;
5854
5855     case EXPR_SUBSTRING:
5856       /* Pass back and let the caller deal with it.  */
5857       break;
5858
5859     default:
5860       internal_error ("bad expression type during walk (%d)",
5861                       expr->expr_type);
5862     }
5863   return ss;
5864 }
5865
5866
5867 /* Entry point for expression walking.
5868    A return value equal to the passed chain means this is
5869    a scalar expression.  It is up to the caller to take whatever action is
5870    necessary to translate these.  */
5871
5872 gfc_ss *
5873 gfc_walk_expr (gfc_expr * expr)
5874 {
5875   gfc_ss *res;
5876
5877   res = gfc_walk_subexpr (gfc_ss_terminator, expr);
5878   return gfc_reverse_ss (res);
5879 }