OSDN Git Service

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