OSDN Git Service

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