OSDN Git Service

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