OSDN Git Service

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