OSDN Git Service

a39f664758ef7962b0536120ecc6ab40407d2776
[pf3gnuchains/gcc-fork.git] / gcc / fortran / trans-array.c
1 /* Array translation routines
2    Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007
3    Free Software Foundation, Inc.
4    Contributed by Paul Brook <paul@nowt.org>
5    and Steven Bosscher <s.bosscher@student.tudelft.nl>
6
7 This file is part of GCC.
8
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 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 unsigned HOST_WIDE_INT
1471 gfc_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 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 determine 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 = gfc_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   /* Special case things we know we can pass easily.  */
4310   switch (expr->expr_type)
4311     {
4312     case EXPR_VARIABLE:
4313       /* If we have a linear array section, we can pass it directly.
4314          Otherwise we need to copy it into a temporary.  */
4315
4316       /* Find the SS for the array section.  */
4317       secss = ss;
4318       while (secss != gfc_ss_terminator && secss->type != GFC_SS_SECTION)
4319         secss = secss->next;
4320
4321       gcc_assert (secss != gfc_ss_terminator);
4322       info = &secss->data.info;
4323
4324       /* Get the descriptor for the array.  */
4325       gfc_conv_ss_descriptor (&se->pre, secss, 0);
4326       desc = info->descriptor;
4327
4328       need_tmp = gfc_ref_needs_temporary_p (expr->ref);
4329       if (need_tmp)
4330         full = 0;
4331       else if (GFC_ARRAY_TYPE_P (TREE_TYPE (desc)))
4332         {
4333           /* Create a new descriptor if the array doesn't have one.  */
4334           full = 0;
4335         }
4336       else if (info->ref->u.ar.type == AR_FULL)
4337         full = 1;
4338       else if (se->direct_byref)
4339         full = 0;
4340       else
4341         full = gfc_full_array_ref_p (info->ref);
4342
4343       if (full)
4344         {
4345           if (se->direct_byref)
4346             {
4347               /* Copy the descriptor for pointer assignments.  */
4348               gfc_add_modify_expr (&se->pre, se->expr, desc);
4349             }
4350           else if (se->want_pointer)
4351             {
4352               /* We pass full arrays directly.  This means that pointers and
4353                  allocatable arrays should also work.  */
4354               se->expr = build_fold_addr_expr (desc);
4355             }
4356           else
4357             {
4358               se->expr = desc;
4359             }
4360
4361           if (expr->ts.type == BT_CHARACTER)
4362             se->string_length = gfc_get_expr_charlen (expr);
4363
4364           return;
4365         }
4366       break;
4367       
4368     case EXPR_FUNCTION:
4369       /* A transformational function return value will be a temporary
4370          array descriptor.  We still need to go through the scalarizer
4371          to create the descriptor.  Elemental functions ar handled as
4372          arbitrary expressions, i.e. copy to a temporary.  */
4373       secss = ss;
4374       /* Look for the SS for this function.  */
4375       while (secss != gfc_ss_terminator
4376              && (secss->type != GFC_SS_FUNCTION || secss->expr != expr))
4377         secss = secss->next;
4378
4379       if (se->direct_byref)
4380         {
4381           gcc_assert (secss != gfc_ss_terminator);
4382
4383           /* For pointer assignments pass the descriptor directly.  */
4384           se->ss = secss;
4385           se->expr = build_fold_addr_expr (se->expr);
4386           gfc_conv_expr (se, expr);
4387           return;
4388         }
4389
4390       if (secss == gfc_ss_terminator)
4391         {
4392           /* Elemental function.  */
4393           need_tmp = 1;
4394           info = NULL;
4395         }
4396       else
4397         {
4398           /* Transformational function.  */
4399           info = &secss->data.info;
4400           need_tmp = 0;
4401         }
4402       break;
4403
4404     case EXPR_ARRAY:
4405       /* Constant array constructors don't need a temporary.  */
4406       if (ss->type == GFC_SS_CONSTRUCTOR
4407           && expr->ts.type != BT_CHARACTER
4408           && gfc_constant_array_constructor_p (expr->value.constructor))
4409         {
4410           need_tmp = 0;
4411           info = &ss->data.info;
4412           secss = ss;
4413         }
4414       else
4415         {
4416           need_tmp = 1;
4417           secss = NULL;
4418           info = NULL;
4419         }
4420       break;
4421
4422     default:
4423       /* Something complicated.  Copy it into a temporary.  */
4424       need_tmp = 1;
4425       secss = NULL;
4426       info = NULL;
4427       break;
4428     }
4429
4430
4431   gfc_init_loopinfo (&loop);
4432
4433   /* Associate the SS with the loop.  */
4434   gfc_add_ss_to_loop (&loop, ss);
4435
4436   /* Tell the scalarizer not to bother creating loop variables, etc.  */
4437   if (!need_tmp)
4438     loop.array_parameter = 1;
4439   else
4440     /* The right-hand side of a pointer assignment mustn't use a temporary.  */
4441     gcc_assert (!se->direct_byref);
4442
4443   /* Setup the scalarizing loops and bounds.  */
4444   gfc_conv_ss_startstride (&loop);
4445
4446   if (need_tmp)
4447     {
4448       /* Tell the scalarizer to make a temporary.  */
4449       loop.temp_ss = gfc_get_ss ();
4450       loop.temp_ss->type = GFC_SS_TEMP;
4451       loop.temp_ss->next = gfc_ss_terminator;
4452       if (expr->ts.type == BT_CHARACTER)
4453         {
4454           if (expr->ts.cl == NULL)
4455             {
4456               /* This had better be a substring reference!  */
4457               gfc_ref *char_ref = expr->ref;
4458               for (; char_ref; char_ref = char_ref->next)
4459                 if (char_ref->type == REF_SUBSTRING)
4460                   {
4461                     mpz_t char_len;
4462                     expr->ts.cl = gfc_get_charlen ();
4463                     expr->ts.cl->next = char_ref->u.ss.length->next;
4464                     char_ref->u.ss.length->next = expr->ts.cl;
4465
4466                     mpz_init_set_ui (char_len, 1);
4467                     mpz_add (char_len, char_len,
4468                              char_ref->u.ss.end->value.integer);
4469                     mpz_sub (char_len, char_len,
4470                              char_ref->u.ss.start->value.integer);
4471                     expr->ts.cl->backend_decl
4472                         = gfc_conv_mpz_to_tree (char_len,
4473                                         gfc_default_character_kind);
4474                     /* Cast is necessary for *-charlen refs.  */
4475                     expr->ts.cl->backend_decl
4476                         = convert (gfc_charlen_type_node,
4477                                    expr->ts.cl->backend_decl);
4478                     mpz_clear (char_len);
4479                       break;
4480                   }
4481               gcc_assert (char_ref != NULL);
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           else if (expr->ts.cl->length
4487                      && expr->ts.cl->length->expr_type == EXPR_CONSTANT)
4488             {
4489               expr->ts.cl->backend_decl
4490                 = gfc_conv_mpz_to_tree (expr->ts.cl->length->value.integer,
4491                                         expr->ts.cl->length->ts.kind);
4492               loop.temp_ss->data.temp.type
4493                 = gfc_typenode_for_spec (&expr->ts);
4494               loop.temp_ss->string_length
4495                 = TYPE_SIZE_UNIT (loop.temp_ss->data.temp.type);
4496             }
4497           else
4498             {
4499               loop.temp_ss->data.temp.type
4500                 = gfc_typenode_for_spec (&expr->ts);
4501               loop.temp_ss->string_length = expr->ts.cl->backend_decl;
4502             }
4503           se->string_length = loop.temp_ss->string_length;
4504         }
4505       else
4506         {
4507           loop.temp_ss->data.temp.type
4508             = gfc_typenode_for_spec (&expr->ts);
4509           loop.temp_ss->string_length = NULL;
4510         }
4511       loop.temp_ss->data.temp.dimen = loop.dimen;
4512       gfc_add_ss_to_loop (&loop, loop.temp_ss);
4513     }
4514
4515   gfc_conv_loop_setup (&loop);
4516
4517   if (need_tmp)
4518     {
4519       /* Copy into a temporary and pass that.  We don't need to copy the data
4520          back because expressions and vector subscripts must be INTENT_IN.  */
4521       /* TODO: Optimize passing function return values.  */
4522       gfc_se lse;
4523       gfc_se rse;
4524
4525       /* Start the copying loops.  */
4526       gfc_mark_ss_chain_used (loop.temp_ss, 1);
4527       gfc_mark_ss_chain_used (ss, 1);
4528       gfc_start_scalarized_body (&loop, &block);
4529
4530       /* Copy each data element.  */
4531       gfc_init_se (&lse, NULL);
4532       gfc_copy_loopinfo_to_se (&lse, &loop);
4533       gfc_init_se (&rse, NULL);
4534       gfc_copy_loopinfo_to_se (&rse, &loop);
4535
4536       lse.ss = loop.temp_ss;
4537       rse.ss = ss;
4538
4539       gfc_conv_scalarized_array_ref (&lse, NULL);
4540       if (expr->ts.type == BT_CHARACTER)
4541         {
4542           gfc_conv_expr (&rse, expr);
4543           if (POINTER_TYPE_P (TREE_TYPE (rse.expr)))
4544             rse.expr = build_fold_indirect_ref (rse.expr);
4545         }
4546       else
4547         gfc_conv_expr_val (&rse, expr);
4548
4549       gfc_add_block_to_block (&block, &rse.pre);
4550       gfc_add_block_to_block (&block, &lse.pre);
4551
4552       gfc_add_modify_expr (&block, lse.expr, rse.expr);
4553
4554       /* Finish the copying loops.  */
4555       gfc_trans_scalarizing_loops (&loop, &block);
4556
4557       desc = loop.temp_ss->data.info.descriptor;
4558
4559       gcc_assert (is_gimple_lvalue (desc));
4560     }
4561   else if (expr->expr_type == EXPR_FUNCTION)
4562     {
4563       desc = info->descriptor;
4564       se->string_length = ss->string_length;
4565     }
4566   else
4567     {
4568       /* We pass sections without copying to a temporary.  Make a new
4569          descriptor and point it at the section we want.  The loop variable
4570          limits will be the limits of the section.
4571          A function may decide to repack the array to speed up access, but
4572          we're not bothered about that here.  */
4573       int dim, ndim;
4574       tree parm;
4575       tree parmtype;
4576       tree stride;
4577       tree from;
4578       tree to;
4579       tree base;
4580
4581       /* Set the string_length for a character array.  */
4582       if (expr->ts.type == BT_CHARACTER)
4583         se->string_length =  gfc_get_expr_charlen (expr);
4584
4585       desc = info->descriptor;
4586       gcc_assert (secss && secss != gfc_ss_terminator);
4587       if (se->direct_byref)
4588         {
4589           /* For pointer assignments we fill in the destination.  */
4590           parm = se->expr;
4591           parmtype = TREE_TYPE (parm);
4592         }
4593       else
4594         {
4595           /* Otherwise make a new one.  */
4596           parmtype = gfc_get_element_type (TREE_TYPE (desc));
4597           parmtype = gfc_get_array_type_bounds (parmtype, loop.dimen,
4598                                                 loop.from, loop.to, 0);
4599           parm = gfc_create_var (parmtype, "parm");
4600         }
4601
4602       offset = gfc_index_zero_node;
4603       dim = 0;
4604
4605       /* The following can be somewhat confusing.  We have two
4606          descriptors, a new one and the original array.
4607          {parm, parmtype, dim} refer to the new one.
4608          {desc, type, n, secss, loop} refer to the original, which maybe
4609          a descriptorless array.
4610          The bounds of the scalarization are the bounds of the section.
4611          We don't have to worry about numeric overflows when calculating
4612          the offsets because all elements are within the array data.  */
4613
4614       /* Set the dtype.  */
4615       tmp = gfc_conv_descriptor_dtype (parm);
4616       gfc_add_modify_expr (&loop.pre, tmp, gfc_get_dtype (parmtype));
4617
4618       if (se->direct_byref)
4619         base = gfc_index_zero_node;
4620       else
4621         base = NULL_TREE;
4622
4623       ndim = info->ref ? info->ref->u.ar.dimen : info->dimen;
4624       for (n = 0; n < ndim; n++)
4625         {
4626           stride = gfc_conv_array_stride (desc, n);
4627
4628           /* Work out the offset.  */
4629           if (info->ref
4630               && info->ref->u.ar.dimen_type[n] == DIMEN_ELEMENT)
4631             {
4632               gcc_assert (info->subscript[n]
4633                       && info->subscript[n]->type == GFC_SS_SCALAR);
4634               start = info->subscript[n]->data.scalar.expr;
4635             }
4636           else
4637             {
4638               /* Check we haven't somehow got out of sync.  */
4639               gcc_assert (info->dim[dim] == n);
4640
4641               /* Evaluate and remember the start of the section.  */
4642               start = info->start[dim];
4643               stride = gfc_evaluate_now (stride, &loop.pre);
4644             }
4645
4646           tmp = gfc_conv_array_lbound (desc, n);
4647           tmp = fold_build2 (MINUS_EXPR, TREE_TYPE (tmp), start, tmp);
4648
4649           tmp = fold_build2 (MULT_EXPR, TREE_TYPE (tmp), tmp, stride);
4650           offset = fold_build2 (PLUS_EXPR, TREE_TYPE (tmp), offset, tmp);
4651
4652           if (info->ref
4653               && info->ref->u.ar.dimen_type[n] == DIMEN_ELEMENT)
4654             {
4655               /* For elemental dimensions, we only need the offset.  */
4656               continue;
4657             }
4658
4659           /* Vector subscripts need copying and are handled elsewhere.  */
4660           if (info->ref)
4661             gcc_assert (info->ref->u.ar.dimen_type[n] == DIMEN_RANGE);
4662
4663           /* Set the new lower bound.  */
4664           from = loop.from[dim];
4665           to = loop.to[dim];
4666
4667           /* If we have an array section or are assigning to a pointer,
4668              make sure that the lower bound is 1.  References to the full
4669              array should otherwise keep the original bounds.  */
4670           if ((!info->ref
4671                || info->ref->u.ar.type != AR_FULL
4672                || se->direct_byref)
4673               && !integer_onep (from))
4674             {
4675               tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
4676                                  gfc_index_one_node, from);
4677               to = fold_build2 (PLUS_EXPR, gfc_array_index_type, to, tmp);
4678               from = gfc_index_one_node;
4679             }
4680           tmp = gfc_conv_descriptor_lbound (parm, gfc_rank_cst[dim]);
4681           gfc_add_modify_expr (&loop.pre, tmp, from);
4682
4683           /* Set the new upper bound.  */
4684           tmp = gfc_conv_descriptor_ubound (parm, gfc_rank_cst[dim]);
4685           gfc_add_modify_expr (&loop.pre, tmp, to);
4686
4687           /* Multiply the stride by the section stride to get the
4688              total stride.  */
4689           stride = fold_build2 (MULT_EXPR, gfc_array_index_type,
4690                                 stride, info->stride[dim]);
4691
4692           if (se->direct_byref)
4693             base = fold_build2 (MINUS_EXPR, TREE_TYPE (base),
4694                                 base, stride);
4695
4696           /* Store the new stride.  */
4697           tmp = gfc_conv_descriptor_stride (parm, gfc_rank_cst[dim]);
4698           gfc_add_modify_expr (&loop.pre, tmp, stride);
4699
4700           dim++;
4701         }
4702
4703       if (se->data_not_needed)
4704         gfc_conv_descriptor_data_set (&loop.pre, parm, gfc_index_zero_node);
4705       else
4706         {
4707           /* Point the data pointer at the first element in the section.  */
4708           tmp = gfc_conv_array_data (desc);
4709           tmp = build_fold_indirect_ref (tmp);
4710           tmp = gfc_build_array_ref (tmp, offset);
4711           offset = gfc_build_addr_expr (gfc_array_dataptr_type (desc), tmp);
4712           gfc_conv_descriptor_data_set (&loop.pre, parm, offset);
4713         }
4714
4715       if (se->direct_byref && !se->data_not_needed)
4716         {
4717           /* Set the offset.  */
4718           tmp = gfc_conv_descriptor_offset (parm);
4719           gfc_add_modify_expr (&loop.pre, tmp, base);
4720         }
4721       else
4722         {
4723           /* Only the callee knows what the correct offset it, so just set
4724              it to zero here.  */
4725           tmp = gfc_conv_descriptor_offset (parm);
4726           gfc_add_modify_expr (&loop.pre, tmp, gfc_index_zero_node);
4727         }
4728       desc = parm;
4729     }
4730
4731   if (!se->direct_byref)
4732     {
4733       /* Get a pointer to the new descriptor.  */
4734       if (se->want_pointer)
4735         se->expr = build_fold_addr_expr (desc);
4736       else
4737         se->expr = desc;
4738     }
4739
4740   gfc_add_block_to_block (&se->pre, &loop.pre);
4741   gfc_add_block_to_block (&se->post, &loop.post);
4742
4743   /* Cleanup the scalarizer.  */
4744   gfc_cleanup_loop (&loop);
4745 }
4746
4747
4748 /* Convert an array for passing as an actual parameter.  */
4749 /* TODO: Optimize passing g77 arrays.  */
4750
4751 void
4752 gfc_conv_array_parameter (gfc_se * se, gfc_expr * expr, gfc_ss * ss, int g77)
4753 {
4754   tree ptr;
4755   tree desc;
4756   tree tmp;
4757   tree stmt;
4758   gfc_symbol *sym;
4759   stmtblock_t block;
4760
4761   /* Passing address of the array if it is not pointer or assumed-shape.  */
4762   if (expr->expr_type == EXPR_VARIABLE
4763        && expr->ref->u.ar.type == AR_FULL && g77)
4764     {
4765       sym = expr->symtree->n.sym;
4766       tmp = gfc_get_symbol_decl (sym);
4767
4768       if (sym->ts.type == BT_CHARACTER)
4769         se->string_length = sym->ts.cl->backend_decl;
4770       if (!sym->attr.pointer && sym->as->type != AS_ASSUMED_SHAPE 
4771           && !sym->attr.allocatable)
4772         {
4773           /* Some variables are declared directly, others are declared as
4774              pointers and allocated on the heap.  */
4775           if (sym->attr.dummy || POINTER_TYPE_P (TREE_TYPE (tmp)))
4776             se->expr = tmp;
4777           else
4778             se->expr = build_fold_addr_expr (tmp);
4779           return;
4780         }
4781       if (sym->attr.allocatable)
4782         {
4783           if (sym->attr.dummy)
4784             {
4785               gfc_conv_expr_descriptor (se, expr, ss);
4786               se->expr = gfc_conv_array_data (se->expr);
4787             }
4788           else
4789             se->expr = gfc_conv_array_data (tmp);
4790           return;
4791         }
4792     }
4793
4794   se->want_pointer = 1;
4795   gfc_conv_expr_descriptor (se, expr, ss);
4796
4797   /* Deallocate the allocatable components of structures that are
4798      not variable.  */
4799   if (expr->ts.type == BT_DERIVED
4800         && expr->ts.derived->attr.alloc_comp
4801         && expr->expr_type != EXPR_VARIABLE)
4802     {
4803       tmp = build_fold_indirect_ref (se->expr);
4804       tmp = gfc_deallocate_alloc_comp (expr->ts.derived, tmp, expr->rank);
4805       gfc_add_expr_to_block (&se->post, tmp);
4806     }
4807
4808   if (g77)
4809     {
4810       desc = se->expr;
4811       /* Repack the array.  */
4812       tmp = gfc_chainon_list (NULL_TREE, desc);
4813       ptr = build_function_call_expr (gfor_fndecl_in_pack, tmp);
4814       ptr = gfc_evaluate_now (ptr, &se->pre);
4815       se->expr = ptr;
4816
4817       gfc_start_block (&block);
4818
4819       /* Copy the data back.  */
4820       tmp = gfc_chainon_list (NULL_TREE, desc);
4821       tmp = gfc_chainon_list (tmp, ptr);
4822       tmp = build_function_call_expr (gfor_fndecl_in_unpack, tmp);
4823       gfc_add_expr_to_block (&block, tmp);
4824
4825       /* Free the temporary.  */
4826       tmp = convert (pvoid_type_node, ptr);
4827       tmp = gfc_chainon_list (NULL_TREE, tmp);
4828       tmp = build_function_call_expr (gfor_fndecl_internal_free, tmp);
4829       gfc_add_expr_to_block (&block, tmp);
4830
4831       stmt = gfc_finish_block (&block);
4832
4833       gfc_init_block (&block);
4834       /* Only if it was repacked.  This code needs to be executed before the
4835          loop cleanup code.  */
4836       tmp = build_fold_indirect_ref (desc);
4837       tmp = gfc_conv_array_data (tmp);
4838       tmp = build2 (NE_EXPR, boolean_type_node, ptr, tmp);
4839       tmp = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt ());
4840
4841       gfc_add_expr_to_block (&block, tmp);
4842       gfc_add_block_to_block (&block, &se->post);
4843
4844       gfc_init_block (&se->post);
4845       gfc_add_block_to_block (&se->post, &block);
4846     }
4847 }
4848
4849
4850 /* Generate code to deallocate an array, if it is allocated.  */
4851
4852 tree
4853 gfc_trans_dealloc_allocated (tree descriptor)
4854
4855   tree tmp;
4856   tree ptr;
4857   tree var;
4858   stmtblock_t block;
4859
4860   gfc_start_block (&block);
4861
4862   var = gfc_conv_descriptor_data_get (descriptor);
4863   STRIP_NOPS (var);
4864   tmp = gfc_create_var (gfc_array_index_type, NULL);
4865   ptr = build_fold_addr_expr (tmp);
4866
4867   /* Call array_deallocate with an int* present in the second argument.
4868      Although it is ignored here, it's presence ensures that arrays that
4869      are already deallocated are ignored.  */
4870   tmp = gfc_chainon_list (NULL_TREE, var);
4871   tmp = gfc_chainon_list (tmp, ptr);
4872   tmp = build_function_call_expr (gfor_fndecl_deallocate, tmp);
4873   gfc_add_expr_to_block (&block, tmp);
4874
4875   /* Zero the data pointer.  */
4876   tmp = build2 (MODIFY_EXPR, void_type_node,
4877                 var, build_int_cst (TREE_TYPE (var), 0));
4878   gfc_add_expr_to_block (&block, tmp);
4879
4880   return gfc_finish_block (&block);
4881 }
4882
4883
4884 /* This helper function calculates the size in words of a full array.  */
4885
4886 static tree
4887 get_full_array_size (stmtblock_t *block, tree decl, int rank)
4888 {
4889   tree idx;
4890   tree nelems;
4891   tree tmp;
4892   idx = gfc_rank_cst[rank - 1];
4893   nelems = gfc_conv_descriptor_ubound (decl, idx);
4894   tmp = gfc_conv_descriptor_lbound (decl, idx);
4895   tmp = build2 (MINUS_EXPR, gfc_array_index_type, nelems, tmp);
4896   tmp = build2 (PLUS_EXPR, gfc_array_index_type,
4897                 tmp, gfc_index_one_node);
4898   tmp = gfc_evaluate_now (tmp, block);
4899
4900   nelems = gfc_conv_descriptor_stride (decl, idx);
4901   tmp = build2 (MULT_EXPR, gfc_array_index_type, nelems, tmp);
4902   return gfc_evaluate_now (tmp, block);
4903 }
4904
4905
4906 /* Allocate dest to the same size as src, and copy src -> dest.  */
4907
4908 tree
4909 gfc_duplicate_allocatable(tree dest, tree src, tree type, int rank)
4910 {
4911   tree tmp;
4912   tree size;
4913   tree nelems;
4914   tree args;
4915   tree null_cond;
4916   tree null_data;
4917   stmtblock_t block;
4918
4919   /* If the source is null, set the destination to null. */
4920   gfc_init_block (&block);
4921   gfc_conv_descriptor_data_set (&block, dest, null_pointer_node);
4922   null_data = gfc_finish_block (&block);
4923
4924   gfc_init_block (&block);
4925
4926   nelems = get_full_array_size (&block, src, rank);
4927   size = fold_build2 (MULT_EXPR, gfc_array_index_type, nelems,
4928                       TYPE_SIZE_UNIT (gfc_get_element_type (type)));
4929
4930   /* Allocate memory to the destination.  */
4931   tmp = gfc_chainon_list (NULL_TREE, size);
4932   if (gfc_index_integer_kind == 4)
4933     tmp = build_function_call_expr (gfor_fndecl_internal_malloc, tmp);
4934   else if (gfc_index_integer_kind == 8)
4935     tmp = build_function_call_expr (gfor_fndecl_internal_malloc64, tmp);
4936   else
4937     gcc_unreachable ();
4938   tmp = fold (convert (TREE_TYPE (gfc_conv_descriptor_data_get (src)),
4939               tmp));
4940   gfc_conv_descriptor_data_set (&block, dest, tmp);
4941
4942   /* We know the temporary and the value will be the same length,
4943      so can use memcpy.  */
4944   tmp = gfc_conv_descriptor_data_get (dest);
4945   args = gfc_chainon_list (NULL_TREE, tmp);
4946   tmp = gfc_conv_descriptor_data_get (src);
4947   args = gfc_chainon_list (args, tmp);
4948   args = gfc_chainon_list (args, size);
4949   tmp = built_in_decls[BUILT_IN_MEMCPY];
4950   tmp = build_function_call_expr (tmp, args);
4951   gfc_add_expr_to_block (&block, tmp);
4952   tmp = gfc_finish_block (&block);
4953
4954   /* Null the destination if the source is null; otherwise do
4955      the allocate and copy.  */
4956   null_cond = gfc_conv_descriptor_data_get (src);
4957   null_cond = convert (pvoid_type_node, null_cond);
4958   null_cond = build2 (NE_EXPR, boolean_type_node, null_cond,
4959                       null_pointer_node);
4960   return build3_v (COND_EXPR, null_cond, tmp, null_data);
4961 }
4962
4963
4964 /* Recursively traverse an object of derived type, generating code to
4965    deallocate, nullify or copy allocatable components.  This is the work horse
4966    function for the functions named in this enum.  */
4967
4968 enum {DEALLOCATE_ALLOC_COMP = 1, NULLIFY_ALLOC_COMP, COPY_ALLOC_COMP};
4969
4970 static tree
4971 structure_alloc_comps (gfc_symbol * der_type, tree decl,
4972                        tree dest, int rank, int purpose)
4973 {
4974   gfc_component *c;
4975   gfc_loopinfo loop;
4976   stmtblock_t fnblock;
4977   stmtblock_t loopbody;
4978   tree tmp;
4979   tree comp;
4980   tree dcmp;
4981   tree nelems;
4982   tree index;
4983   tree var;
4984   tree cdecl;
4985   tree ctype;
4986   tree vref, dref;
4987   tree null_cond = NULL_TREE;
4988
4989   gfc_init_block (&fnblock);
4990
4991   if (POINTER_TYPE_P (TREE_TYPE (decl)))
4992     decl = build_fold_indirect_ref (decl);
4993
4994   /* If this an array of derived types with allocatable components
4995      build a loop and recursively call this function.  */
4996   if (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE
4997         || GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl)))
4998     {
4999       tmp = gfc_conv_array_data (decl);
5000       var = build_fold_indirect_ref (tmp);
5001         
5002       /* Get the number of elements - 1 and set the counter.  */
5003       if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl)))
5004         {
5005           /* Use the descriptor for an allocatable array.  Since this
5006              is a full array reference, we only need the descriptor
5007              information from dimension = rank.  */
5008           tmp = get_full_array_size (&fnblock, decl, rank);
5009           tmp = build2 (MINUS_EXPR, gfc_array_index_type,
5010                         tmp, gfc_index_one_node);
5011
5012           null_cond = gfc_conv_descriptor_data_get (decl);
5013           null_cond = build2 (NE_EXPR, boolean_type_node, null_cond,
5014                               build_int_cst (TREE_TYPE (tmp), 0));
5015         }
5016       else
5017         {
5018           /*  Otherwise use the TYPE_DOMAIN information.  */
5019           tmp =  array_type_nelts (TREE_TYPE (decl));
5020           tmp = fold_convert (gfc_array_index_type, tmp);
5021         }
5022
5023       /* Remember that this is, in fact, the no. of elements - 1.  */
5024       nelems = gfc_evaluate_now (tmp, &fnblock);
5025       index = gfc_create_var (gfc_array_index_type, "S");
5026
5027       /* Build the body of the loop.  */
5028       gfc_init_block (&loopbody);
5029
5030       vref = gfc_build_array_ref (var, index);
5031
5032       if (purpose == COPY_ALLOC_COMP)
5033         {
5034           tmp = gfc_duplicate_allocatable (dest, decl, TREE_TYPE(decl), rank);
5035           gfc_add_expr_to_block (&fnblock, tmp);
5036
5037           tmp = build_fold_indirect_ref (gfc_conv_descriptor_data_get (dest));
5038           dref = gfc_build_array_ref (tmp, index);
5039           tmp = structure_alloc_comps (der_type, vref, dref, rank, purpose);
5040         }
5041       else
5042         tmp = structure_alloc_comps (der_type, vref, NULL_TREE, rank, purpose);
5043
5044       gfc_add_expr_to_block (&loopbody, tmp);
5045
5046       /* Build the loop and return. */
5047       gfc_init_loopinfo (&loop);
5048       loop.dimen = 1;
5049       loop.from[0] = gfc_index_zero_node;
5050       loop.loopvar[0] = index;
5051       loop.to[0] = nelems;
5052       gfc_trans_scalarizing_loops (&loop, &loopbody);
5053       gfc_add_block_to_block (&fnblock, &loop.pre);
5054
5055       tmp = gfc_finish_block (&fnblock);
5056       if (null_cond != NULL_TREE)
5057         tmp = build3_v (COND_EXPR, null_cond, tmp, build_empty_stmt ());
5058
5059       return tmp;
5060     }
5061
5062   /* Otherwise, act on the components or recursively call self to
5063      act on a chain of components. */
5064   for (c = der_type->components; c; c = c->next)
5065     {
5066       bool cmp_has_alloc_comps = (c->ts.type == BT_DERIVED)
5067                                     && c->ts.derived->attr.alloc_comp;
5068       cdecl = c->backend_decl;
5069       ctype = TREE_TYPE (cdecl);
5070
5071       switch (purpose)
5072         {
5073         case DEALLOCATE_ALLOC_COMP:
5074           /* Do not deallocate the components of ultimate pointer
5075              components.  */
5076           if (cmp_has_alloc_comps && !c->pointer)
5077             {
5078               comp = build3 (COMPONENT_REF, ctype, decl, cdecl, NULL_TREE);
5079               rank = c->as ? c->as->rank : 0;
5080               tmp = structure_alloc_comps (c->ts.derived, comp, NULL_TREE,
5081                                            rank, purpose);
5082               gfc_add_expr_to_block (&fnblock, tmp);
5083             }
5084
5085           if (c->allocatable)
5086             {
5087               comp = build3 (COMPONENT_REF, ctype, decl, cdecl, NULL_TREE);
5088               tmp = gfc_trans_dealloc_allocated (comp);
5089               gfc_add_expr_to_block (&fnblock, tmp);
5090             }
5091           break;
5092
5093         case NULLIFY_ALLOC_COMP:
5094           if (c->pointer)
5095             continue;
5096           else if (c->allocatable)
5097             {
5098               comp = build3 (COMPONENT_REF, ctype, decl, cdecl, NULL_TREE);
5099               gfc_conv_descriptor_data_set (&fnblock, comp, null_pointer_node);
5100             }
5101           else if (cmp_has_alloc_comps)
5102             {
5103               comp = build3 (COMPONENT_REF, ctype, decl, cdecl, NULL_TREE);
5104               rank = c->as ? c->as->rank : 0;
5105               tmp = structure_alloc_comps (c->ts.derived, comp, NULL_TREE,
5106                                            rank, purpose);
5107               gfc_add_expr_to_block (&fnblock, tmp);
5108             }
5109           break;
5110
5111         case COPY_ALLOC_COMP:
5112           if (c->pointer)
5113             continue;
5114
5115           /* We need source and destination components.  */
5116           comp = build3 (COMPONENT_REF, ctype, decl, cdecl, NULL_TREE);
5117           dcmp = build3 (COMPONENT_REF, ctype, dest, cdecl, NULL_TREE);
5118           dcmp = fold_convert (TREE_TYPE (comp), dcmp);
5119
5120           if (c->allocatable && !cmp_has_alloc_comps)
5121             {
5122               tmp = gfc_duplicate_allocatable(dcmp, comp, ctype, c->as->rank);
5123               gfc_add_expr_to_block (&fnblock, tmp);
5124             }
5125
5126           if (cmp_has_alloc_comps)
5127             {
5128               rank = c->as ? c->as->rank : 0;
5129               tmp = fold_convert (TREE_TYPE (dcmp), comp);
5130               gfc_add_modify_expr (&fnblock, dcmp, tmp);
5131               tmp = structure_alloc_comps (c->ts.derived, comp, dcmp,
5132                                            rank, purpose);
5133               gfc_add_expr_to_block (&fnblock, tmp);
5134             }
5135           break;
5136
5137         default:
5138           gcc_unreachable ();
5139           break;
5140         }
5141     }
5142
5143   return gfc_finish_block (&fnblock);
5144 }
5145
5146 /* Recursively traverse an object of derived type, generating code to
5147    nullify allocatable components.  */
5148
5149 tree
5150 gfc_nullify_alloc_comp (gfc_symbol * der_type, tree decl, int rank)
5151 {
5152   return structure_alloc_comps (der_type, decl, NULL_TREE, rank,
5153                                 NULLIFY_ALLOC_COMP);
5154 }
5155
5156
5157 /* Recursively traverse an object of derived type, generating code to
5158    deallocate allocatable components.  */
5159
5160 tree
5161 gfc_deallocate_alloc_comp (gfc_symbol * der_type, tree decl, int rank)
5162 {
5163   return structure_alloc_comps (der_type, decl, NULL_TREE, rank,
5164                                 DEALLOCATE_ALLOC_COMP);
5165 }
5166
5167
5168 /* Recursively traverse an object of derived type, generating code to
5169    copy its allocatable components.  */
5170
5171 tree
5172 gfc_copy_alloc_comp (gfc_symbol * der_type, tree decl, tree dest, int rank)
5173 {
5174   return structure_alloc_comps (der_type, decl, dest, rank, COPY_ALLOC_COMP);
5175 }
5176
5177
5178 /* NULLIFY an allocatable/pointer array on function entry, free it on exit.
5179    Do likewise, recursively if necessary, with the allocatable components of
5180    derived types.  */
5181
5182 tree
5183 gfc_trans_deferred_array (gfc_symbol * sym, tree body)
5184 {
5185   tree type;
5186   tree tmp;
5187   tree descriptor;
5188   stmtblock_t fnblock;
5189   locus loc;
5190   int rank;
5191   bool sym_has_alloc_comp;
5192
5193   sym_has_alloc_comp = (sym->ts.type == BT_DERIVED)
5194                           && sym->ts.derived->attr.alloc_comp;
5195
5196   /* Make sure the frontend gets these right.  */
5197   if (!(sym->attr.pointer || sym->attr.allocatable || sym_has_alloc_comp))
5198     fatal_error ("Possible frontend bug: Deferred array size without pointer, "
5199                  "allocatable attribute or derived type without allocatable "
5200                  "components.");
5201
5202   gfc_init_block (&fnblock);
5203
5204   gcc_assert (TREE_CODE (sym->backend_decl) == VAR_DECL
5205                 || TREE_CODE (sym->backend_decl) == PARM_DECL);
5206
5207   if (sym->ts.type == BT_CHARACTER
5208       && !INTEGER_CST_P (sym->ts.cl->backend_decl))
5209     {
5210       gfc_trans_init_string_length (sym->ts.cl, &fnblock);
5211       gfc_trans_vla_type_sizes (sym, &fnblock);
5212     }
5213
5214   /* Dummy and use associated variables don't need anything special.  */
5215   if (sym->attr.dummy || sym->attr.use_assoc)
5216     {
5217       gfc_add_expr_to_block (&fnblock, body);
5218
5219       return gfc_finish_block (&fnblock);
5220     }
5221
5222   gfc_get_backend_locus (&loc);
5223   gfc_set_backend_locus (&sym->declared_at);
5224   descriptor = sym->backend_decl;
5225
5226   /* Although static, derived types with default initializers and
5227      allocatable components must not be nulled wholesale; instead they
5228      are treated component by component.  */
5229   if (TREE_STATIC (descriptor) && !sym_has_alloc_comp)
5230     {
5231       /* SAVEd variables are not freed on exit.  */
5232       gfc_trans_static_array_pointer (sym);
5233       return body;
5234     }
5235
5236   /* Get the descriptor type.  */
5237   type = TREE_TYPE (sym->backend_decl);
5238     
5239   if (sym_has_alloc_comp && !(sym->attr.pointer || sym->attr.allocatable))
5240     {
5241       rank = sym->as ? sym->as->rank : 0;
5242       tmp = gfc_nullify_alloc_comp (sym->ts.derived, descriptor, rank);
5243       gfc_add_expr_to_block (&fnblock, tmp);
5244     }
5245   else if (!GFC_DESCRIPTOR_TYPE_P (type))
5246     {
5247       /* If the backend_decl is not a descriptor, we must have a pointer
5248          to one.  */
5249       descriptor = build_fold_indirect_ref (sym->backend_decl);
5250       type = TREE_TYPE (descriptor);
5251     }
5252   
5253   /* NULLIFY the data pointer.  */
5254   if (GFC_DESCRIPTOR_TYPE_P (type))
5255     gfc_conv_descriptor_data_set (&fnblock, descriptor, null_pointer_node);
5256
5257   gfc_add_expr_to_block (&fnblock, body);
5258
5259   gfc_set_backend_locus (&loc);
5260
5261   /* Allocatable arrays need to be freed when they go out of scope.
5262      The allocatable components of pointers must not be touched.  */
5263   if (sym_has_alloc_comp && !(sym->attr.function || sym->attr.result)
5264       && !sym->attr.pointer)
5265     {
5266       int rank;
5267       rank = sym->as ? sym->as->rank : 0;
5268       tmp = gfc_deallocate_alloc_comp (sym->ts.derived, descriptor, rank);
5269       gfc_add_expr_to_block (&fnblock, tmp);
5270     }
5271
5272   if (sym->attr.allocatable)
5273     {
5274       tmp = gfc_trans_dealloc_allocated (sym->backend_decl);
5275       gfc_add_expr_to_block (&fnblock, tmp);
5276     }
5277
5278   return gfc_finish_block (&fnblock);
5279 }
5280
5281 /************ Expression Walking Functions ******************/
5282
5283 /* Walk a variable reference.
5284
5285    Possible extension - multiple component subscripts.
5286     x(:,:) = foo%a(:)%b(:)
5287    Transforms to
5288     forall (i=..., j=...)
5289       x(i,j) = foo%a(j)%b(i)
5290     end forall
5291    This adds a fair amount of complexity because you need to deal with more
5292    than one ref.  Maybe handle in a similar manner to vector subscripts.
5293    Maybe not worth the effort.  */
5294
5295
5296 static gfc_ss *
5297 gfc_walk_variable_expr (gfc_ss * ss, gfc_expr * expr)
5298 {
5299   gfc_ref *ref;
5300   gfc_array_ref *ar;
5301   gfc_ss *newss;
5302   gfc_ss *head;
5303   int n;
5304
5305   for (ref = expr->ref; ref; ref = ref->next)
5306     if (ref->type == REF_ARRAY && ref->u.ar.type != AR_ELEMENT)
5307       break;
5308
5309   for (; ref; ref = ref->next)
5310     {
5311       if (ref->type == REF_SUBSTRING)
5312         {
5313           newss = gfc_get_ss ();
5314           newss->type = GFC_SS_SCALAR;
5315           newss->expr = ref->u.ss.start;
5316           newss->next = ss;
5317           ss = newss;
5318
5319           newss = gfc_get_ss ();
5320           newss->type = GFC_SS_SCALAR;
5321           newss->expr = ref->u.ss.end;
5322           newss->next = ss;
5323           ss = newss;
5324         }
5325
5326       /* We're only interested in array sections from now on.  */
5327       if (ref->type != REF_ARRAY)
5328         continue;
5329
5330       ar = &ref->u.ar;
5331       switch (ar->type)
5332         {
5333         case AR_ELEMENT:
5334           for (n = 0; n < ar->dimen; n++)
5335             {
5336               newss = gfc_get_ss ();
5337               newss->type = GFC_SS_SCALAR;
5338               newss->expr = ar->start[n];
5339               newss->next = ss;
5340               ss = newss;
5341             }
5342           break;
5343
5344         case AR_FULL:
5345           newss = gfc_get_ss ();
5346           newss->type = GFC_SS_SECTION;
5347           newss->expr = expr;
5348           newss->next = ss;
5349           newss->data.info.dimen = ar->as->rank;
5350           newss->data.info.ref = ref;
5351
5352           /* Make sure array is the same as array(:,:), this way
5353              we don't need to special case all the time.  */
5354           ar->dimen = ar->as->rank;
5355           for (n = 0; n < ar->dimen; n++)
5356             {
5357               newss->data.info.dim[n] = n;
5358               ar->dimen_type[n] = DIMEN_RANGE;
5359
5360               gcc_assert (ar->start[n] == NULL);
5361               gcc_assert (ar->end[n] == NULL);
5362               gcc_assert (ar->stride[n] == NULL);
5363             }
5364           ss = newss;
5365           break;
5366
5367         case AR_SECTION:
5368           newss = gfc_get_ss ();
5369           newss->type = GFC_SS_SECTION;
5370           newss->expr = expr;
5371           newss->next = ss;
5372           newss->data.info.dimen = 0;
5373           newss->data.info.ref = ref;
5374
5375           head = newss;
5376
5377           /* We add SS chains for all the subscripts in the section.  */
5378           for (n = 0; n < ar->dimen; n++)
5379             {
5380               gfc_ss *indexss;
5381
5382               switch (ar->dimen_type[n])
5383                 {
5384                 case DIMEN_ELEMENT:
5385                   /* Add SS for elemental (scalar) subscripts.  */
5386                   gcc_assert (ar->start[n]);
5387                   indexss = gfc_get_ss ();
5388                   indexss->type = GFC_SS_SCALAR;
5389                   indexss->expr = ar->start[n];
5390                   indexss->next = gfc_ss_terminator;
5391                   indexss->loop_chain = gfc_ss_terminator;
5392                   newss->data.info.subscript[n] = indexss;
5393                   break;
5394
5395                 case DIMEN_RANGE:
5396                   /* We don't add anything for sections, just remember this
5397                      dimension for later.  */
5398                   newss->data.info.dim[newss->data.info.dimen] = n;
5399                   newss->data.info.dimen++;
5400                   break;
5401
5402                 case DIMEN_VECTOR:
5403                   /* Create a GFC_SS_VECTOR index in which we can store
5404                      the vector's descriptor.  */
5405                   indexss = gfc_get_ss ();
5406                   indexss->type = GFC_SS_VECTOR;
5407                   indexss->expr = ar->start[n];
5408                   indexss->next = gfc_ss_terminator;
5409                   indexss->loop_chain = gfc_ss_terminator;
5410                   newss->data.info.subscript[n] = indexss;
5411                   newss->data.info.dim[newss->data.info.dimen] = n;
5412                   newss->data.info.dimen++;
5413                   break;
5414
5415                 default:
5416                   /* We should know what sort of section it is by now.  */
5417                   gcc_unreachable ();
5418                 }
5419             }
5420           /* We should have at least one non-elemental dimension.  */
5421           gcc_assert (newss->data.info.dimen > 0);
5422           ss = newss;
5423           break;
5424
5425         default:
5426           /* We should know what sort of section it is by now.  */
5427           gcc_unreachable ();
5428         }
5429
5430     }
5431   return ss;
5432 }
5433
5434
5435 /* Walk an expression operator. If only one operand of a binary expression is
5436    scalar, we must also add the scalar term to the SS chain.  */
5437
5438 static gfc_ss *
5439 gfc_walk_op_expr (gfc_ss * ss, gfc_expr * expr)
5440 {
5441   gfc_ss *head;
5442   gfc_ss *head2;
5443   gfc_ss *newss;
5444
5445   head = gfc_walk_subexpr (ss, expr->value.op.op1);
5446   if (expr->value.op.op2 == NULL)
5447     head2 = head;
5448   else
5449     head2 = gfc_walk_subexpr (head, expr->value.op.op2);
5450
5451   /* All operands are scalar.  Pass back and let the caller deal with it.  */
5452   if (head2 == ss)
5453     return head2;
5454
5455   /* All operands require scalarization.  */
5456   if (head != ss && (expr->value.op.op2 == NULL || head2 != head))
5457     return head2;
5458
5459   /* One of the operands needs scalarization, the other is scalar.
5460      Create a gfc_ss for the scalar expression.  */
5461   newss = gfc_get_ss ();
5462   newss->type = GFC_SS_SCALAR;
5463   if (head == ss)
5464     {
5465       /* First operand is scalar.  We build the chain in reverse order, so
5466          add the scarar SS after the second operand.  */
5467       head = head2;
5468       while (head && head->next != ss)
5469         head = head->next;
5470       /* Check we haven't somehow broken the chain.  */
5471       gcc_assert (head);
5472       newss->next = ss;
5473       head->next = newss;
5474       newss->expr = expr->value.op.op1;
5475     }
5476   else                          /* head2 == head */
5477     {
5478       gcc_assert (head2 == head);
5479       /* Second operand is scalar.  */
5480       newss->next = head2;
5481       head2 = newss;
5482       newss->expr = expr->value.op.op2;
5483     }
5484
5485   return head2;
5486 }
5487
5488
5489 /* Reverse a SS chain.  */
5490
5491 gfc_ss *
5492 gfc_reverse_ss (gfc_ss * ss)
5493 {
5494   gfc_ss *next;
5495   gfc_ss *head;
5496
5497   gcc_assert (ss != NULL);
5498
5499   head = gfc_ss_terminator;
5500   while (ss != gfc_ss_terminator)
5501     {
5502       next = ss->next;
5503       /* Check we didn't somehow break the chain.  */
5504       gcc_assert (next != NULL);
5505       ss->next = head;
5506       head = ss;
5507       ss = next;
5508     }
5509
5510   return (head);
5511 }
5512
5513
5514 /* Walk the arguments of an elemental function.  */
5515
5516 gfc_ss *
5517 gfc_walk_elemental_function_args (gfc_ss * ss, gfc_actual_arglist *arg,
5518                                   gfc_ss_type type)
5519 {
5520   int scalar;
5521   gfc_ss *head;
5522   gfc_ss *tail;
5523   gfc_ss *newss;
5524
5525   head = gfc_ss_terminator;
5526   tail = NULL;
5527   scalar = 1;
5528   for (; arg; arg = arg->next)
5529     {
5530       if (!arg->expr)
5531         continue;
5532
5533       newss = gfc_walk_subexpr (head, arg->expr);
5534       if (newss == head)
5535         {
5536           /* Scalar argument.  */
5537           newss = gfc_get_ss ();
5538           newss->type = type;
5539           newss->expr = arg->expr;
5540           newss->next = head;
5541         }
5542       else
5543         scalar = 0;
5544
5545       head = newss;
5546       if (!tail)
5547         {
5548           tail = head;
5549           while (tail->next != gfc_ss_terminator)
5550             tail = tail->next;
5551         }
5552     }
5553
5554   if (scalar)
5555     {
5556       /* If all the arguments are scalar we don't need the argument SS.  */
5557       gfc_free_ss_chain (head);
5558       /* Pass it back.  */
5559       return ss;
5560     }
5561
5562   /* Add it onto the existing chain.  */
5563   tail->next = ss;
5564   return head;
5565 }
5566
5567
5568 /* Walk a function call.  Scalar functions are passed back, and taken out of
5569    scalarization loops.  For elemental functions we walk their arguments.
5570    The result of functions returning arrays is stored in a temporary outside
5571    the loop, so that the function is only called once.  Hence we do not need
5572    to walk their arguments.  */
5573
5574 static gfc_ss *
5575 gfc_walk_function_expr (gfc_ss * ss, gfc_expr * expr)
5576 {
5577   gfc_ss *newss;
5578   gfc_intrinsic_sym *isym;
5579   gfc_symbol *sym;
5580
5581   isym = expr->value.function.isym;
5582
5583   /* Handle intrinsic functions separately.  */
5584   if (isym)
5585     return gfc_walk_intrinsic_function (ss, expr, isym);
5586
5587   sym = expr->value.function.esym;
5588   if (!sym)
5589       sym = expr->symtree->n.sym;
5590
5591   /* A function that returns arrays.  */
5592   if (gfc_return_by_reference (sym) && sym->result->attr.dimension)
5593     {
5594       newss = gfc_get_ss ();
5595       newss->type = GFC_SS_FUNCTION;
5596       newss->expr = expr;
5597       newss->next = ss;
5598       newss->data.info.dimen = expr->rank;
5599       return newss;
5600     }
5601
5602   /* Walk the parameters of an elemental function.  For now we always pass
5603      by reference.  */
5604   if (sym->attr.elemental)
5605     return gfc_walk_elemental_function_args (ss, expr->value.function.actual,
5606                                              GFC_SS_REFERENCE);
5607
5608   /* Scalar functions are OK as these are evaluated outside the scalarization
5609      loop.  Pass back and let the caller deal with it.  */
5610   return ss;
5611 }
5612
5613
5614 /* An array temporary is constructed for array constructors.  */
5615
5616 static gfc_ss *
5617 gfc_walk_array_constructor (gfc_ss * ss, gfc_expr * expr)
5618 {
5619   gfc_ss *newss;
5620   int n;
5621
5622   newss = gfc_get_ss ();
5623   newss->type = GFC_SS_CONSTRUCTOR;
5624   newss->expr = expr;
5625   newss->next = ss;
5626   newss->data.info.dimen = expr->rank;
5627   for (n = 0; n < expr->rank; n++)
5628     newss->data.info.dim[n] = n;
5629
5630   return newss;
5631 }
5632
5633
5634 /* Walk an expression.  Add walked expressions to the head of the SS chain.
5635    A wholly scalar expression will not be added.  */
5636
5637 static gfc_ss *
5638 gfc_walk_subexpr (gfc_ss * ss, gfc_expr * expr)
5639 {
5640   gfc_ss *head;
5641
5642   switch (expr->expr_type)
5643     {
5644     case EXPR_VARIABLE:
5645       head = gfc_walk_variable_expr (ss, expr);
5646       return head;
5647
5648     case EXPR_OP:
5649       head = gfc_walk_op_expr (ss, expr);
5650       return head;
5651
5652     case EXPR_FUNCTION:
5653       head = gfc_walk_function_expr (ss, expr);
5654       return head;
5655
5656     case EXPR_CONSTANT:
5657     case EXPR_NULL:
5658     case EXPR_STRUCTURE:
5659       /* Pass back and let the caller deal with it.  */
5660       break;
5661
5662     case EXPR_ARRAY:
5663       head = gfc_walk_array_constructor (ss, expr);
5664       return head;
5665
5666     case EXPR_SUBSTRING:
5667       /* Pass back and let the caller deal with it.  */
5668       break;
5669
5670     default:
5671       internal_error ("bad expression type during walk (%d)",
5672                       expr->expr_type);
5673     }
5674   return ss;
5675 }
5676
5677
5678 /* Entry point for expression walking.
5679    A return value equal to the passed chain means this is
5680    a scalar expression.  It is up to the caller to take whatever action is
5681    necessary to translate these.  */
5682
5683 gfc_ss *
5684 gfc_walk_expr (gfc_expr * expr)
5685 {
5686   gfc_ss *res;
5687
5688   res = gfc_walk_subexpr (gfc_ss_terminator, expr);
5689   return gfc_reverse_ss (res);
5690 }