OSDN Git Service

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