OSDN Git Service

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