OSDN Git Service

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