OSDN Git Service

2010-09-09 Mikael Morin <mikael@gcc.gnu.org>
[pf3gnuchains/gcc-fork.git] / gcc / fortran / trans-array.c
1 /* Array translation routines
2    Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
3    Free Software Foundation, Inc.
4    Contributed by Paul Brook <paul@nowt.org>
5    and Steven Bosscher <s.bosscher@student.tudelft.nl>
6
7 This file is part of GCC.
8
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 3, or (at your option) any later
12 version.
13
14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
17 for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3.  If not see
21 <http://www.gnu.org/licenses/>.  */
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 subscripts 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 "diagnostic-core.h"    /* For internal_error/fatal_error.  */
84 #include "flags.h"
85 #include "gfortran.h"
86 #include "constructor.h"
87 #include "trans.h"
88 #include "trans-stmt.h"
89 #include "trans-types.h"
90 #include "trans-array.h"
91 #include "trans-const.h"
92 #include "dependency.h"
93
94 static gfc_ss *gfc_walk_subexpr (gfc_ss *, gfc_expr *);
95 static bool gfc_get_array_constructor_size (mpz_t *, gfc_constructor_base);
96
97 /* The contents of this structure aren't actually used, just the address.  */
98 static gfc_ss gfc_ss_terminator_var;
99 gfc_ss * const gfc_ss_terminator = &gfc_ss_terminator_var;
100
101
102 static tree
103 gfc_array_dataptr_type (tree desc)
104 {
105   return (GFC_TYPE_ARRAY_DATAPTR_TYPE (TREE_TYPE (desc)));
106 }
107
108
109 /* Build expressions to access the members of an array descriptor.
110    It's surprisingly easy to mess up here, so never access
111    an array descriptor by "brute force", always use these
112    functions.  This also avoids problems if we change the format
113    of an array descriptor.
114
115    To understand these magic numbers, look at the comments
116    before gfc_build_array_type() in trans-types.c.
117
118    The code within these defines should be the only code which knows the format
119    of an array descriptor.
120
121    Any code just needing to read obtain the bounds of an array should use
122    gfc_conv_array_* rather than the following functions as these will return
123    know constant values, and work with arrays which do not have descriptors.
124
125    Don't forget to #undef these!  */
126
127 #define DATA_FIELD 0
128 #define OFFSET_FIELD 1
129 #define DTYPE_FIELD 2
130 #define DIMENSION_FIELD 3
131
132 #define STRIDE_SUBFIELD 0
133 #define LBOUND_SUBFIELD 1
134 #define UBOUND_SUBFIELD 2
135
136 /* This provides READ-ONLY access to the data field.  The field itself
137    doesn't have the proper type.  */
138
139 tree
140 gfc_conv_descriptor_data_get (tree desc)
141 {
142   tree field, type, t;
143
144   type = TREE_TYPE (desc);
145   gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
146
147   field = TYPE_FIELDS (type);
148   gcc_assert (DATA_FIELD == 0);
149
150   t = fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field), desc,
151                        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    TUPLES_P is true if we are generating tuples.
160    
161    This function gets called through the following macros:
162      gfc_conv_descriptor_data_set
163      gfc_conv_descriptor_data_set.  */
164
165 void
166 gfc_conv_descriptor_data_set (stmtblock_t *block, tree desc, tree value)
167 {
168   tree field, type, t;
169
170   type = TREE_TYPE (desc);
171   gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
172
173   field = TYPE_FIELDS (type);
174   gcc_assert (DATA_FIELD == 0);
175
176   t = fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field), desc,
177                        field, NULL_TREE);
178   gfc_add_modify (block, t, fold_convert (TREE_TYPE (field), value));
179 }
180
181
182 /* This provides address access to the data field.  This should only be
183    used by array allocation, passing this on to the runtime.  */
184
185 tree
186 gfc_conv_descriptor_data_addr (tree desc)
187 {
188   tree field, type, t;
189
190   type = TREE_TYPE (desc);
191   gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
192
193   field = TYPE_FIELDS (type);
194   gcc_assert (DATA_FIELD == 0);
195
196   t = fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field), desc,
197                        field, NULL_TREE);
198   return gfc_build_addr_expr (NULL_TREE, t);
199 }
200
201 static tree
202 gfc_conv_descriptor_offset (tree desc)
203 {
204   tree type;
205   tree field;
206
207   type = TREE_TYPE (desc);
208   gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
209
210   field = gfc_advance_chain (TYPE_FIELDS (type), OFFSET_FIELD);
211   gcc_assert (field != NULL_TREE && TREE_TYPE (field) == gfc_array_index_type);
212
213   return fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field),
214                           desc, field, NULL_TREE);
215 }
216
217 tree
218 gfc_conv_descriptor_offset_get (tree desc)
219 {
220   return gfc_conv_descriptor_offset (desc);
221 }
222
223 void
224 gfc_conv_descriptor_offset_set (stmtblock_t *block, tree desc,
225                                 tree value)
226 {
227   tree t = gfc_conv_descriptor_offset (desc);
228   gfc_add_modify (block, t, fold_convert (TREE_TYPE (t), value));
229 }
230
231
232 tree
233 gfc_conv_descriptor_dtype (tree desc)
234 {
235   tree field;
236   tree type;
237
238   type = TREE_TYPE (desc);
239   gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
240
241   field = gfc_advance_chain (TYPE_FIELDS (type), DTYPE_FIELD);
242   gcc_assert (field != NULL_TREE && TREE_TYPE (field) == gfc_array_index_type);
243
244   return fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field),
245                           desc, field, NULL_TREE);
246 }
247
248 static tree
249 gfc_conv_descriptor_dimension (tree desc, tree dim)
250 {
251   tree field;
252   tree type;
253   tree tmp;
254
255   type = TREE_TYPE (desc);
256   gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
257
258   field = gfc_advance_chain (TYPE_FIELDS (type), DIMENSION_FIELD);
259   gcc_assert (field != NULL_TREE
260           && TREE_CODE (TREE_TYPE (field)) == ARRAY_TYPE
261           && TREE_CODE (TREE_TYPE (TREE_TYPE (field))) == RECORD_TYPE);
262
263   tmp = fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field),
264                          desc, field, NULL_TREE);
265   tmp = gfc_build_array_ref (tmp, dim, NULL);
266   return tmp;
267 }
268
269 static tree
270 gfc_conv_descriptor_stride (tree desc, tree dim)
271 {
272   tree tmp;
273   tree field;
274
275   tmp = gfc_conv_descriptor_dimension (desc, dim);
276   field = TYPE_FIELDS (TREE_TYPE (tmp));
277   field = gfc_advance_chain (field, STRIDE_SUBFIELD);
278   gcc_assert (field != NULL_TREE && TREE_TYPE (field) == gfc_array_index_type);
279
280   tmp = fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field),
281                          tmp, field, NULL_TREE);
282   return tmp;
283 }
284
285 tree
286 gfc_conv_descriptor_stride_get (tree desc, tree dim)
287 {
288   tree type = TREE_TYPE (desc);
289   gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
290   if (integer_zerop (dim)
291       && (GFC_TYPE_ARRAY_AKIND (type) == GFC_ARRAY_ALLOCATABLE
292           ||GFC_TYPE_ARRAY_AKIND (type) == GFC_ARRAY_ASSUMED_SHAPE_CONT
293           ||GFC_TYPE_ARRAY_AKIND (type) == GFC_ARRAY_POINTER_CONT))
294     return gfc_index_one_node;
295
296   return gfc_conv_descriptor_stride (desc, dim);
297 }
298
299 void
300 gfc_conv_descriptor_stride_set (stmtblock_t *block, tree desc,
301                                 tree dim, tree value)
302 {
303   tree t = gfc_conv_descriptor_stride (desc, dim);
304   gfc_add_modify (block, t, fold_convert (TREE_TYPE (t), value));
305 }
306
307 static tree
308 gfc_conv_descriptor_lbound (tree desc, tree dim)
309 {
310   tree tmp;
311   tree field;
312
313   tmp = gfc_conv_descriptor_dimension (desc, dim);
314   field = TYPE_FIELDS (TREE_TYPE (tmp));
315   field = gfc_advance_chain (field, LBOUND_SUBFIELD);
316   gcc_assert (field != NULL_TREE && TREE_TYPE (field) == gfc_array_index_type);
317
318   tmp = fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field),
319                          tmp, field, NULL_TREE);
320   return tmp;
321 }
322
323 tree
324 gfc_conv_descriptor_lbound_get (tree desc, tree dim)
325 {
326   return gfc_conv_descriptor_lbound (desc, dim);
327 }
328
329 void
330 gfc_conv_descriptor_lbound_set (stmtblock_t *block, tree desc,
331                                 tree dim, tree value)
332 {
333   tree t = gfc_conv_descriptor_lbound (desc, dim);
334   gfc_add_modify (block, t, fold_convert (TREE_TYPE (t), value));
335 }
336
337 static tree
338 gfc_conv_descriptor_ubound (tree desc, tree dim)
339 {
340   tree tmp;
341   tree field;
342
343   tmp = gfc_conv_descriptor_dimension (desc, dim);
344   field = TYPE_FIELDS (TREE_TYPE (tmp));
345   field = gfc_advance_chain (field, UBOUND_SUBFIELD);
346   gcc_assert (field != NULL_TREE && TREE_TYPE (field) == gfc_array_index_type);
347
348   tmp = fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field),
349                          tmp, field, NULL_TREE);
350   return tmp;
351 }
352
353 tree
354 gfc_conv_descriptor_ubound_get (tree desc, tree dim)
355 {
356   return gfc_conv_descriptor_ubound (desc, dim);
357 }
358
359 void
360 gfc_conv_descriptor_ubound_set (stmtblock_t *block, tree desc,
361                                 tree dim, tree value)
362 {
363   tree t = gfc_conv_descriptor_ubound (desc, dim);
364   gfc_add_modify (block, t, fold_convert (TREE_TYPE (t), value));
365 }
366
367 /* Build a null array descriptor constructor.  */
368
369 tree
370 gfc_build_null_descriptor (tree type)
371 {
372   tree field;
373   tree tmp;
374
375   gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
376   gcc_assert (DATA_FIELD == 0);
377   field = TYPE_FIELDS (type);
378
379   /* Set a NULL data pointer.  */
380   tmp = build_constructor_single (type, field, null_pointer_node);
381   TREE_CONSTANT (tmp) = 1;
382   /* All other fields are ignored.  */
383
384   return tmp;
385 }
386
387
388 /* Modify a descriptor such that the lbound of a given dimension is the value
389    specified.  This also updates ubound and offset accordingly.  */
390
391 void
392 gfc_conv_shift_descriptor_lbound (stmtblock_t* block, tree desc,
393                                   int dim, tree new_lbound)
394 {
395   tree offs, ubound, lbound, stride;
396   tree diff, offs_diff;
397
398   new_lbound = fold_convert (gfc_array_index_type, new_lbound);
399
400   offs = gfc_conv_descriptor_offset_get (desc);
401   lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[dim]);
402   ubound = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[dim]);
403   stride = gfc_conv_descriptor_stride_get (desc, gfc_rank_cst[dim]);
404
405   /* Get difference (new - old) by which to shift stuff.  */
406   diff = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
407                           new_lbound, lbound);
408
409   /* Shift ubound and offset accordingly.  This has to be done before
410      updating the lbound, as they depend on the lbound expression!  */
411   ubound = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
412                             ubound, diff);
413   gfc_conv_descriptor_ubound_set (block, desc, gfc_rank_cst[dim], ubound);
414   offs_diff = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
415                                diff, stride);
416   offs = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
417                           offs, offs_diff);
418   gfc_conv_descriptor_offset_set (block, desc, offs);
419
420   /* Finally set lbound to value we want.  */
421   gfc_conv_descriptor_lbound_set (block, desc, gfc_rank_cst[dim], new_lbound);
422 }
423
424
425 /* Cleanup those #defines.  */
426
427 #undef DATA_FIELD
428 #undef OFFSET_FIELD
429 #undef DTYPE_FIELD
430 #undef DIMENSION_FIELD
431 #undef STRIDE_SUBFIELD
432 #undef LBOUND_SUBFIELD
433 #undef UBOUND_SUBFIELD
434
435
436 /* Mark a SS chain as used.  Flags specifies in which loops the SS is used.
437    flags & 1 = Main loop body.
438    flags & 2 = temp copy loop.  */
439
440 void
441 gfc_mark_ss_chain_used (gfc_ss * ss, unsigned flags)
442 {
443   for (; ss != gfc_ss_terminator; ss = ss->next)
444     ss->useflags = flags;
445 }
446
447 static void gfc_free_ss (gfc_ss *);
448
449
450 /* Free a gfc_ss chain.  */
451
452 static void
453 gfc_free_ss_chain (gfc_ss * ss)
454 {
455   gfc_ss *next;
456
457   while (ss != gfc_ss_terminator)
458     {
459       gcc_assert (ss != NULL);
460       next = ss->next;
461       gfc_free_ss (ss);
462       ss = next;
463     }
464 }
465
466
467 /* Free a SS.  */
468
469 static void
470 gfc_free_ss (gfc_ss * ss)
471 {
472   int n;
473
474   switch (ss->type)
475     {
476     case GFC_SS_SECTION:
477       for (n = 0; n < ss->data.info.dimen; n++)
478         {
479           if (ss->data.info.subscript[ss->data.info.dim[n]])
480             gfc_free_ss_chain (ss->data.info.subscript[ss->data.info.dim[n]]);
481         }
482       break;
483
484     default:
485       break;
486     }
487
488   gfc_free (ss);
489 }
490
491
492 /* Free all the SS associated with a loop.  */
493
494 void
495 gfc_cleanup_loop (gfc_loopinfo * loop)
496 {
497   gfc_ss *ss;
498   gfc_ss *next;
499
500   ss = loop->ss;
501   while (ss != gfc_ss_terminator)
502     {
503       gcc_assert (ss != NULL);
504       next = ss->loop_chain;
505       gfc_free_ss (ss);
506       ss = next;
507     }
508 }
509
510
511 /* Associate a SS chain with a loop.  */
512
513 void
514 gfc_add_ss_to_loop (gfc_loopinfo * loop, gfc_ss * head)
515 {
516   gfc_ss *ss;
517
518   if (head == gfc_ss_terminator)
519     return;
520
521   ss = head;
522   for (; ss && ss != gfc_ss_terminator; ss = ss->next)
523     {
524       if (ss->next == gfc_ss_terminator)
525         ss->loop_chain = loop->ss;
526       else
527         ss->loop_chain = ss->next;
528     }
529   gcc_assert (ss == gfc_ss_terminator);
530   loop->ss = head;
531 }
532
533
534 /* Generate an initializer for a static pointer or allocatable array.  */
535
536 void
537 gfc_trans_static_array_pointer (gfc_symbol * sym)
538 {
539   tree type;
540
541   gcc_assert (TREE_STATIC (sym->backend_decl));
542   /* Just zero the data member.  */
543   type = TREE_TYPE (sym->backend_decl);
544   DECL_INITIAL (sym->backend_decl) = gfc_build_null_descriptor (type);
545 }
546
547
548 /* If the bounds of SE's loop have not yet been set, see if they can be
549    determined from array spec AS, which is the array spec of a called
550    function.  MAPPING maps the callee's dummy arguments to the values
551    that the caller is passing.  Add any initialization and finalization
552    code to SE.  */
553
554 void
555 gfc_set_loop_bounds_from_array_spec (gfc_interface_mapping * mapping,
556                                      gfc_se * se, gfc_array_spec * as)
557 {
558   int n, dim;
559   gfc_se tmpse;
560   tree lower;
561   tree upper;
562   tree tmp;
563
564   if (as && as->type == AS_EXPLICIT)
565     for (n = 0; n < se->loop->dimen; n++)
566       {
567         dim = se->ss->data.info.dim[n];
568         gcc_assert (dim < as->rank);
569         gcc_assert (se->loop->dimen == as->rank);
570         if (se->loop->to[n] == NULL_TREE)
571           {
572             /* Evaluate the lower bound.  */
573             gfc_init_se (&tmpse, NULL);
574             gfc_apply_interface_mapping (mapping, &tmpse, as->lower[dim]);
575             gfc_add_block_to_block (&se->pre, &tmpse.pre);
576             gfc_add_block_to_block (&se->post, &tmpse.post);
577             lower = fold_convert (gfc_array_index_type, tmpse.expr);
578
579             /* ...and the upper bound.  */
580             gfc_init_se (&tmpse, NULL);
581             gfc_apply_interface_mapping (mapping, &tmpse, as->upper[dim]);
582             gfc_add_block_to_block (&se->pre, &tmpse.pre);
583             gfc_add_block_to_block (&se->post, &tmpse.post);
584             upper = fold_convert (gfc_array_index_type, tmpse.expr);
585
586             /* Set the upper bound of the loop to UPPER - LOWER.  */
587             tmp = fold_build2_loc (input_location, MINUS_EXPR,
588                                    gfc_array_index_type, upper, lower);
589             tmp = gfc_evaluate_now (tmp, &se->pre);
590             se->loop->to[n] = tmp;
591           }
592       }
593 }
594
595
596 /* Generate code to allocate an array temporary, or create a variable to
597    hold the data.  If size is NULL, zero the descriptor so that the
598    callee will allocate the array.  If DEALLOC is true, also generate code to
599    free the array afterwards.
600
601    If INITIAL is not NULL, it is packed using internal_pack and the result used
602    as data instead of allocating a fresh, unitialized area of memory.
603
604    Initialization code is added to PRE and finalization code to POST.
605    DYNAMIC is true if the caller may want to extend the array later
606    using realloc.  This prevents us from putting the array on the stack.  */
607
608 static void
609 gfc_trans_allocate_array_storage (stmtblock_t * pre, stmtblock_t * post,
610                                   gfc_ss_info * info, tree size, tree nelem,
611                                   tree initial, bool dynamic, bool dealloc)
612 {
613   tree tmp;
614   tree desc;
615   bool onstack;
616
617   desc = info->descriptor;
618   info->offset = gfc_index_zero_node;
619   if (size == NULL_TREE || integer_zerop (size))
620     {
621       /* A callee allocated array.  */
622       gfc_conv_descriptor_data_set (pre, desc, null_pointer_node);
623       onstack = FALSE;
624     }
625   else
626     {
627       /* Allocate the temporary.  */
628       onstack = !dynamic && initial == NULL_TREE
629                          && gfc_can_put_var_on_stack (size);
630
631       if (onstack)
632         {
633           /* Make a temporary variable to hold the data.  */
634           tmp = fold_build2_loc (input_location, MINUS_EXPR, TREE_TYPE (nelem),
635                                  nelem, gfc_index_one_node);
636           tmp = build_range_type (gfc_array_index_type, gfc_index_zero_node,
637                                   tmp);
638           tmp = build_array_type (gfc_get_element_type (TREE_TYPE (desc)),
639                                   tmp);
640           tmp = gfc_create_var (tmp, "A");
641           tmp = gfc_build_addr_expr (NULL_TREE, tmp);
642           gfc_conv_descriptor_data_set (pre, desc, tmp);
643         }
644       else
645         {
646           /* Allocate memory to hold the data or call internal_pack.  */
647           if (initial == NULL_TREE)
648             {
649               tmp = gfc_call_malloc (pre, NULL, size);
650               tmp = gfc_evaluate_now (tmp, pre);
651             }
652           else
653             {
654               tree packed;
655               tree source_data;
656               tree was_packed;
657               stmtblock_t do_copying;
658
659               tmp = TREE_TYPE (initial); /* Pointer to descriptor.  */
660               gcc_assert (TREE_CODE (tmp) == POINTER_TYPE);
661               tmp = TREE_TYPE (tmp); /* The descriptor itself.  */
662               tmp = gfc_get_element_type (tmp);
663               gcc_assert (tmp == gfc_get_element_type (TREE_TYPE (desc)));
664               packed = gfc_create_var (build_pointer_type (tmp), "data");
665
666               tmp = build_call_expr_loc (input_location,
667                                      gfor_fndecl_in_pack, 1, initial);
668               tmp = fold_convert (TREE_TYPE (packed), tmp);
669               gfc_add_modify (pre, packed, tmp);
670
671               tmp = build_fold_indirect_ref_loc (input_location,
672                                              initial);
673               source_data = gfc_conv_descriptor_data_get (tmp);
674
675               /* internal_pack may return source->data without any allocation
676                  or copying if it is already packed.  If that's the case, we
677                  need to allocate and copy manually.  */
678
679               gfc_start_block (&do_copying);
680               tmp = gfc_call_malloc (&do_copying, NULL, size);
681               tmp = fold_convert (TREE_TYPE (packed), tmp);
682               gfc_add_modify (&do_copying, packed, tmp);
683               tmp = gfc_build_memcpy_call (packed, source_data, size);
684               gfc_add_expr_to_block (&do_copying, tmp);
685
686               was_packed = fold_build2_loc (input_location, EQ_EXPR,
687                                             boolean_type_node, packed,
688                                             source_data);
689               tmp = gfc_finish_block (&do_copying);
690               tmp = build3_v (COND_EXPR, was_packed, tmp,
691                               build_empty_stmt (input_location));
692               gfc_add_expr_to_block (pre, tmp);
693
694               tmp = fold_convert (pvoid_type_node, packed);
695             }
696
697           gfc_conv_descriptor_data_set (pre, desc, tmp);
698         }
699     }
700   info->data = gfc_conv_descriptor_data_get (desc);
701
702   /* The offset is zero because we create temporaries with a zero
703      lower bound.  */
704   gfc_conv_descriptor_offset_set (pre, desc, gfc_index_zero_node);
705
706   if (dealloc && !onstack)
707     {
708       /* Free the temporary.  */
709       tmp = gfc_conv_descriptor_data_get (desc);
710       tmp = gfc_call_free (fold_convert (pvoid_type_node, tmp));
711       gfc_add_expr_to_block (post, tmp);
712     }
713 }
714
715
716 /* Get the array reference dimension corresponding to the given loop dimension.
717    It is different from the true array dimension given by the dim array in
718    the case of a partial array reference
719    It is different from the loop dimension in the case of a transposed array.
720    */
721
722 static int
723 get_array_ref_dim (gfc_ss_info *info, int loop_dim)
724 {
725   int n, array_dim, array_ref_dim;
726
727   array_ref_dim = 0;
728   array_dim = info->dim[loop_dim];
729
730   for (n = 0; n < info->dimen; n++)
731     if (n != loop_dim && info->dim[n] < array_dim)
732       array_ref_dim++;
733
734   return array_ref_dim;
735 }
736
737
738 /* Generate code to create and initialize the descriptor for a temporary
739    array.  This is used for both temporaries needed by the scalarizer, and
740    functions returning arrays.  Adjusts the loop variables to be
741    zero-based, and calculates the loop bounds for callee allocated arrays.
742    Allocate the array unless it's callee allocated (we have a callee
743    allocated array if 'callee_alloc' is true, or if loop->to[n] is
744    NULL_TREE for any n).  Also fills in the descriptor, data and offset
745    fields of info if known.  Returns the size of the array, or NULL for a
746    callee allocated array.
747
748    PRE, POST, INITIAL, DYNAMIC and DEALLOC are as for
749    gfc_trans_allocate_array_storage.
750  */
751
752 tree
753 gfc_trans_create_temp_array (stmtblock_t * pre, stmtblock_t * post,
754                              gfc_loopinfo * loop, gfc_ss_info * info,
755                              tree eltype, tree initial, bool dynamic,
756                              bool dealloc, bool callee_alloc, locus * where)
757 {
758   tree from[GFC_MAX_DIMENSIONS], to[GFC_MAX_DIMENSIONS];
759   tree type;
760   tree desc;
761   tree tmp;
762   tree size;
763   tree nelem;
764   tree cond;
765   tree or_expr;
766   int n, dim, tmp_dim;
767
768   memset (from, 0, sizeof (from));
769   memset (to, 0, sizeof (to));
770
771   gcc_assert (info->dimen > 0);
772   gcc_assert (loop->dimen == info->dimen);
773
774   if (gfc_option.warn_array_temp && where)
775     gfc_warning ("Creating array temporary at %L", where);
776
777   /* Set the lower bound to zero.  */
778   for (n = 0; n < loop->dimen; n++)
779     {
780       dim = info->dim[n];
781
782       /* Callee allocated arrays may not have a known bound yet.  */
783       if (loop->to[n])
784         loop->to[n] = gfc_evaluate_now (
785                         fold_build2_loc (input_location, MINUS_EXPR,
786                                          gfc_array_index_type,
787                                          loop->to[n], loop->from[n]),
788                         pre);
789       loop->from[n] = gfc_index_zero_node;
790
791       /* We are constructing the temporary's descriptor based on the loop
792          dimensions. As the dimensions may be accessed in arbitrary order
793          (think of transpose) the size taken from the n'th loop may not map
794          to the n'th dimension of the array. We need to reconstruct loop infos
795          in the right order before using it to set the descriptor
796          bounds.  */
797       tmp_dim = get_array_ref_dim (info, n);
798       from[tmp_dim] = loop->from[n];
799       to[tmp_dim] = loop->to[n];
800
801       info->delta[dim] = gfc_index_zero_node;
802       info->start[dim] = gfc_index_zero_node;
803       info->end[dim] = gfc_index_zero_node;
804       info->stride[dim] = gfc_index_one_node;
805     }
806
807   /* Initialize the descriptor.  */
808   type =
809     gfc_get_array_type_bounds (eltype, info->dimen, 0, from, to, 1,
810                                GFC_ARRAY_UNKNOWN, true);
811   desc = gfc_create_var (type, "atmp");
812   GFC_DECL_PACKED_ARRAY (desc) = 1;
813
814   info->descriptor = desc;
815   size = gfc_index_one_node;
816
817   /* Fill in the array dtype.  */
818   tmp = gfc_conv_descriptor_dtype (desc);
819   gfc_add_modify (pre, tmp, gfc_get_dtype (TREE_TYPE (desc)));
820
821   /*
822      Fill in the bounds and stride.  This is a packed array, so:
823
824      size = 1;
825      for (n = 0; n < rank; n++)
826        {
827          stride[n] = size
828          delta = ubound[n] + 1 - lbound[n];
829          size = size * delta;
830        }
831      size = size * sizeof(element);
832   */
833
834   or_expr = NULL_TREE;
835
836   /* If there is at least one null loop->to[n], it is a callee allocated
837      array.  */
838   for (n = 0; n < loop->dimen; n++)
839     if (loop->to[n] == NULL_TREE)
840       {
841         size = NULL_TREE;
842         break;
843       }
844
845   for (n = 0; n < loop->dimen; n++)
846     {
847       dim = info->dim[n];
848
849       if (size == NULL_TREE)
850         {
851           /* For a callee allocated array express the loop bounds in terms
852              of the descriptor fields.  */
853           tmp = fold_build2_loc (input_location,
854                 MINUS_EXPR, gfc_array_index_type,
855                 gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[n]),
856                 gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[n]));
857           loop->to[n] = tmp;
858           continue;
859         }
860         
861       /* Store the stride and bound components in the descriptor.  */
862       gfc_conv_descriptor_stride_set (pre, desc, gfc_rank_cst[n], size);
863
864       gfc_conv_descriptor_lbound_set (pre, desc, gfc_rank_cst[n],
865                                       gfc_index_zero_node);
866
867       gfc_conv_descriptor_ubound_set (pre, desc, gfc_rank_cst[n],
868                                       to[n]);
869
870       tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
871                              to[n], gfc_index_one_node);
872
873       /* Check whether the size for this dimension is negative.  */
874       cond = fold_build2_loc (input_location, LE_EXPR, boolean_type_node, tmp,
875                               gfc_index_zero_node);
876       cond = gfc_evaluate_now (cond, pre);
877
878       if (n == 0)
879         or_expr = cond;
880       else
881         or_expr = fold_build2_loc (input_location, TRUTH_OR_EXPR,
882                                    boolean_type_node, or_expr, cond);
883
884       size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
885                               size, tmp);
886       size = gfc_evaluate_now (size, pre);
887     }
888
889   /* Get the size of the array.  */
890
891   if (size && !callee_alloc)
892     {
893       /* If or_expr is true, then the extent in at least one
894          dimension is zero and the size is set to zero.  */
895       size = fold_build3_loc (input_location, COND_EXPR, gfc_array_index_type,
896                               or_expr, gfc_index_zero_node, size);
897
898       nelem = size;
899       size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
900                 size,
901                 fold_convert (gfc_array_index_type,
902                               TYPE_SIZE_UNIT (gfc_get_element_type (type))));
903     }
904   else
905     {
906       nelem = size;
907       size = NULL_TREE;
908     }
909
910   gfc_trans_allocate_array_storage (pre, post, info, size, nelem, initial,
911                                     dynamic, dealloc);
912
913   if (info->dimen > loop->temp_dim)
914     loop->temp_dim = info->dimen;
915
916   return size;
917 }
918
919
920 /* Generate code to transpose array EXPR by creating a new descriptor
921    in which the dimension specifications have been reversed.  */
922
923 void
924 gfc_conv_array_transpose (gfc_se * se, gfc_expr * expr)
925 {
926   tree dest, src, dest_index, src_index;
927   gfc_loopinfo *loop;
928   gfc_ss_info *dest_info;
929   gfc_ss *dest_ss, *src_ss;
930   gfc_se src_se;
931   int n;
932
933   loop = se->loop;
934
935   src_ss = gfc_walk_expr (expr);
936   dest_ss = se->ss;
937
938   dest_info = &dest_ss->data.info;
939   gcc_assert (dest_info->dimen == 2);
940
941   /* Get a descriptor for EXPR.  */
942   gfc_init_se (&src_se, NULL);
943   gfc_conv_expr_descriptor (&src_se, expr, src_ss);
944   gfc_add_block_to_block (&se->pre, &src_se.pre);
945   gfc_add_block_to_block (&se->post, &src_se.post);
946   src = src_se.expr;
947
948   /* Allocate a new descriptor for the return value.  */
949   dest = gfc_create_var (TREE_TYPE (src), "transp");
950   dest_info->descriptor = dest;
951   se->expr = dest;
952
953   /* Copy across the dtype field.  */
954   gfc_add_modify (&se->pre,
955                        gfc_conv_descriptor_dtype (dest),
956                        gfc_conv_descriptor_dtype (src));
957
958   /* Copy the dimension information, renumbering dimension 1 to 0 and
959      0 to 1.  */
960   for (n = 0; n < 2; n++)
961     {
962       dest_info->delta[n] = gfc_index_zero_node;
963       dest_info->start[n] = gfc_index_zero_node;
964       dest_info->end[n] = gfc_index_zero_node;
965       dest_info->stride[n] = gfc_index_one_node;
966       dest_info->dim[n] = n;
967
968       dest_index = gfc_rank_cst[n];
969       src_index = gfc_rank_cst[1 - n];
970
971       gfc_conv_descriptor_stride_set (&se->pre, dest, dest_index,
972                            gfc_conv_descriptor_stride_get (src, src_index));
973
974       gfc_conv_descriptor_lbound_set (&se->pre, dest, dest_index,
975                            gfc_conv_descriptor_lbound_get (src, src_index));
976
977       gfc_conv_descriptor_ubound_set (&se->pre, dest, dest_index,
978                            gfc_conv_descriptor_ubound_get (src, src_index));
979
980       if (!loop->to[n])
981         {
982           gcc_assert (integer_zerop (loop->from[n]));
983           loop->to[n] =
984             fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
985                          gfc_conv_descriptor_ubound_get (dest, dest_index),
986                          gfc_conv_descriptor_lbound_get (dest, dest_index));
987         }
988     }
989
990   /* Copy the data pointer.  */
991   dest_info->data = gfc_conv_descriptor_data_get (src);
992   gfc_conv_descriptor_data_set (&se->pre, dest, dest_info->data);
993
994   /* Copy the offset.  This is not changed by transposition; the top-left
995      element is still at the same offset as before, except where the loop
996      starts at zero.  */
997   if (!integer_zerop (loop->from[0]))
998     dest_info->offset = gfc_conv_descriptor_offset_get (src);
999   else
1000     dest_info->offset = gfc_index_zero_node;
1001
1002   gfc_conv_descriptor_offset_set (&se->pre, dest,
1003                                   dest_info->offset);
1004           
1005   if (dest_info->dimen > loop->temp_dim)
1006     loop->temp_dim = dest_info->dimen;
1007 }
1008
1009
1010 /* Return the number of iterations in a loop that starts at START,
1011    ends at END, and has step STEP.  */
1012
1013 static tree
1014 gfc_get_iteration_count (tree start, tree end, tree step)
1015 {
1016   tree tmp;
1017   tree type;
1018
1019   type = TREE_TYPE (step);
1020   tmp = fold_build2_loc (input_location, MINUS_EXPR, type, end, start);
1021   tmp = fold_build2_loc (input_location, FLOOR_DIV_EXPR, type, tmp, step);
1022   tmp = fold_build2_loc (input_location, PLUS_EXPR, type, tmp,
1023                          build_int_cst (type, 1));
1024   tmp = fold_build2_loc (input_location, MAX_EXPR, type, tmp,
1025                          build_int_cst (type, 0));
1026   return fold_convert (gfc_array_index_type, tmp);
1027 }
1028
1029
1030 /* Extend the data in array DESC by EXTRA elements.  */
1031
1032 static void
1033 gfc_grow_array (stmtblock_t * pblock, tree desc, tree extra)
1034 {
1035   tree arg0, arg1;
1036   tree tmp;
1037   tree size;
1038   tree ubound;
1039
1040   if (integer_zerop (extra))
1041     return;
1042
1043   ubound = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[0]);
1044
1045   /* Add EXTRA to the upper bound.  */
1046   tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
1047                          ubound, extra);
1048   gfc_conv_descriptor_ubound_set (pblock, desc, gfc_rank_cst[0], tmp);
1049
1050   /* Get the value of the current data pointer.  */
1051   arg0 = gfc_conv_descriptor_data_get (desc);
1052
1053   /* Calculate the new array size.  */
1054   size = TYPE_SIZE_UNIT (gfc_get_element_type (TREE_TYPE (desc)));
1055   tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
1056                          ubound, gfc_index_one_node);
1057   arg1 = fold_build2_loc (input_location, MULT_EXPR, size_type_node,
1058                           fold_convert (size_type_node, tmp),
1059                           fold_convert (size_type_node, size));
1060
1061   /* Call the realloc() function.  */
1062   tmp = gfc_call_realloc (pblock, arg0, arg1);
1063   gfc_conv_descriptor_data_set (pblock, desc, tmp);
1064 }
1065
1066
1067 /* Return true if the bounds of iterator I can only be determined
1068    at run time.  */
1069
1070 static inline bool
1071 gfc_iterator_has_dynamic_bounds (gfc_iterator * i)
1072 {
1073   return (i->start->expr_type != EXPR_CONSTANT
1074           || i->end->expr_type != EXPR_CONSTANT
1075           || i->step->expr_type != EXPR_CONSTANT);
1076 }
1077
1078
1079 /* Split the size of constructor element EXPR into the sum of two terms,
1080    one of which can be determined at compile time and one of which must
1081    be calculated at run time.  Set *SIZE to the former and return true
1082    if the latter might be nonzero.  */
1083
1084 static bool
1085 gfc_get_array_constructor_element_size (mpz_t * size, gfc_expr * expr)
1086 {
1087   if (expr->expr_type == EXPR_ARRAY)
1088     return gfc_get_array_constructor_size (size, expr->value.constructor);
1089   else if (expr->rank > 0)
1090     {
1091       /* Calculate everything at run time.  */
1092       mpz_set_ui (*size, 0);
1093       return true;
1094     }
1095   else
1096     {
1097       /* A single element.  */
1098       mpz_set_ui (*size, 1);
1099       return false;
1100     }
1101 }
1102
1103
1104 /* Like gfc_get_array_constructor_element_size, but applied to the whole
1105    of array constructor C.  */
1106
1107 static bool
1108 gfc_get_array_constructor_size (mpz_t * size, gfc_constructor_base base)
1109 {
1110   gfc_constructor *c;
1111   gfc_iterator *i;
1112   mpz_t val;
1113   mpz_t len;
1114   bool dynamic;
1115
1116   mpz_set_ui (*size, 0);
1117   mpz_init (len);
1118   mpz_init (val);
1119
1120   dynamic = false;
1121   for (c = gfc_constructor_first (base); c; c = gfc_constructor_next (c))
1122     {
1123       i = c->iterator;
1124       if (i && gfc_iterator_has_dynamic_bounds (i))
1125         dynamic = true;
1126       else
1127         {
1128           dynamic |= gfc_get_array_constructor_element_size (&len, c->expr);
1129           if (i)
1130             {
1131               /* Multiply the static part of the element size by the
1132                  number of iterations.  */
1133               mpz_sub (val, i->end->value.integer, i->start->value.integer);
1134               mpz_fdiv_q (val, val, i->step->value.integer);
1135               mpz_add_ui (val, val, 1);
1136               if (mpz_sgn (val) > 0)
1137                 mpz_mul (len, len, val);
1138               else
1139                 mpz_set_ui (len, 0);
1140             }
1141           mpz_add (*size, *size, len);
1142         }
1143     }
1144   mpz_clear (len);
1145   mpz_clear (val);
1146   return dynamic;
1147 }
1148
1149
1150 /* Make sure offset is a variable.  */
1151
1152 static void
1153 gfc_put_offset_into_var (stmtblock_t * pblock, tree * poffset,
1154                          tree * offsetvar)
1155 {
1156   /* We should have already created the offset variable.  We cannot
1157      create it here because we may be in an inner scope.  */
1158   gcc_assert (*offsetvar != NULL_TREE);
1159   gfc_add_modify (pblock, *offsetvar, *poffset);
1160   *poffset = *offsetvar;
1161   TREE_USED (*offsetvar) = 1;
1162 }
1163
1164
1165 /* Variables needed for bounds-checking.  */
1166 static bool first_len;
1167 static tree first_len_val; 
1168 static bool typespec_chararray_ctor;
1169
1170 static void
1171 gfc_trans_array_ctor_element (stmtblock_t * pblock, tree desc,
1172                               tree offset, gfc_se * se, gfc_expr * expr)
1173 {
1174   tree tmp;
1175
1176   gfc_conv_expr (se, expr);
1177
1178   /* Store the value.  */
1179   tmp = build_fold_indirect_ref_loc (input_location,
1180                                  gfc_conv_descriptor_data_get (desc));
1181   tmp = gfc_build_array_ref (tmp, offset, NULL);
1182
1183   if (expr->ts.type == BT_CHARACTER)
1184     {
1185       int i = gfc_validate_kind (BT_CHARACTER, expr->ts.kind, false);
1186       tree esize;
1187
1188       esize = size_in_bytes (gfc_get_element_type (TREE_TYPE (desc)));
1189       esize = fold_convert (gfc_charlen_type_node, esize);
1190       esize = fold_build2_loc (input_location, TRUNC_DIV_EXPR,
1191                            gfc_charlen_type_node, esize,
1192                            build_int_cst (gfc_charlen_type_node,
1193                                           gfc_character_kinds[i].bit_size / 8));
1194
1195       gfc_conv_string_parameter (se);
1196       if (POINTER_TYPE_P (TREE_TYPE (tmp)))
1197         {
1198           /* The temporary is an array of pointers.  */
1199           se->expr = fold_convert (TREE_TYPE (tmp), se->expr);
1200           gfc_add_modify (&se->pre, tmp, se->expr);
1201         }
1202       else
1203         {
1204           /* The temporary is an array of string values.  */
1205           tmp = gfc_build_addr_expr (gfc_get_pchar_type (expr->ts.kind), tmp);
1206           /* We know the temporary and the value will be the same length,
1207              so can use memcpy.  */
1208           gfc_trans_string_copy (&se->pre, esize, tmp, expr->ts.kind,
1209                                  se->string_length, se->expr, expr->ts.kind);
1210         }
1211       if ((gfc_option.rtcheck & GFC_RTCHECK_BOUNDS) && !typespec_chararray_ctor)
1212         {
1213           if (first_len)
1214             {
1215               gfc_add_modify (&se->pre, first_len_val,
1216                                    se->string_length);
1217               first_len = false;
1218             }
1219           else
1220             {
1221               /* Verify that all constructor elements are of the same
1222                  length.  */
1223               tree cond = fold_build2_loc (input_location, NE_EXPR,
1224                                            boolean_type_node, first_len_val,
1225                                            se->string_length);
1226               gfc_trans_runtime_check
1227                 (true, false, cond, &se->pre, &expr->where,
1228                  "Different CHARACTER lengths (%ld/%ld) in array constructor",
1229                  fold_convert (long_integer_type_node, first_len_val),
1230                  fold_convert (long_integer_type_node, se->string_length));
1231             }
1232         }
1233     }
1234   else
1235     {
1236       /* TODO: Should the frontend already have done this conversion?  */
1237       se->expr = fold_convert (TREE_TYPE (tmp), se->expr);
1238       gfc_add_modify (&se->pre, tmp, se->expr);
1239     }
1240
1241   gfc_add_block_to_block (pblock, &se->pre);
1242   gfc_add_block_to_block (pblock, &se->post);
1243 }
1244
1245
1246 /* Add the contents of an array to the constructor.  DYNAMIC is as for
1247    gfc_trans_array_constructor_value.  */
1248
1249 static void
1250 gfc_trans_array_constructor_subarray (stmtblock_t * pblock,
1251                                       tree type ATTRIBUTE_UNUSED,
1252                                       tree desc, gfc_expr * expr,
1253                                       tree * poffset, tree * offsetvar,
1254                                       bool dynamic)
1255 {
1256   gfc_se se;
1257   gfc_ss *ss;
1258   gfc_loopinfo loop;
1259   stmtblock_t body;
1260   tree tmp;
1261   tree size;
1262   int n;
1263
1264   /* We need this to be a variable so we can increment it.  */
1265   gfc_put_offset_into_var (pblock, poffset, offsetvar);
1266
1267   gfc_init_se (&se, NULL);
1268
1269   /* Walk the array expression.  */
1270   ss = gfc_walk_expr (expr);
1271   gcc_assert (ss != gfc_ss_terminator);
1272
1273   /* Initialize the scalarizer.  */
1274   gfc_init_loopinfo (&loop);
1275   gfc_add_ss_to_loop (&loop, ss);
1276
1277   /* Initialize the loop.  */
1278   gfc_conv_ss_startstride (&loop);
1279   gfc_conv_loop_setup (&loop, &expr->where);
1280
1281   /* Make sure the constructed array has room for the new data.  */
1282   if (dynamic)
1283     {
1284       /* Set SIZE to the total number of elements in the subarray.  */
1285       size = gfc_index_one_node;
1286       for (n = 0; n < loop.dimen; n++)
1287         {
1288           tmp = gfc_get_iteration_count (loop.from[n], loop.to[n],
1289                                          gfc_index_one_node);
1290           size = fold_build2_loc (input_location, MULT_EXPR,
1291                                   gfc_array_index_type, size, tmp);
1292         }
1293
1294       /* Grow the constructed array by SIZE elements.  */
1295       gfc_grow_array (&loop.pre, desc, size);
1296     }
1297
1298   /* Make the loop body.  */
1299   gfc_mark_ss_chain_used (ss, 1);
1300   gfc_start_scalarized_body (&loop, &body);
1301   gfc_copy_loopinfo_to_se (&se, &loop);
1302   se.ss = ss;
1303
1304   gfc_trans_array_ctor_element (&body, desc, *poffset, &se, expr);
1305   gcc_assert (se.ss == gfc_ss_terminator);
1306
1307   /* Increment the offset.  */
1308   tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
1309                          *poffset, gfc_index_one_node);
1310   gfc_add_modify (&body, *poffset, tmp);
1311
1312   /* Finish the loop.  */
1313   gfc_trans_scalarizing_loops (&loop, &body);
1314   gfc_add_block_to_block (&loop.pre, &loop.post);
1315   tmp = gfc_finish_block (&loop.pre);
1316   gfc_add_expr_to_block (pblock, tmp);
1317
1318   gfc_cleanup_loop (&loop);
1319 }
1320
1321
1322 /* Assign the values to the elements of an array constructor.  DYNAMIC
1323    is true if descriptor DESC only contains enough data for the static
1324    size calculated by gfc_get_array_constructor_size.  When true, memory
1325    for the dynamic parts must be allocated using realloc.  */
1326
1327 static void
1328 gfc_trans_array_constructor_value (stmtblock_t * pblock, tree type,
1329                                    tree desc, gfc_constructor_base base,
1330                                    tree * poffset, tree * offsetvar,
1331                                    bool dynamic)
1332 {
1333   tree tmp;
1334   stmtblock_t body;
1335   gfc_se se;
1336   mpz_t size;
1337   gfc_constructor *c;
1338
1339   tree shadow_loopvar = NULL_TREE;
1340   gfc_saved_var saved_loopvar;
1341
1342   mpz_init (size);
1343   for (c = gfc_constructor_first (base); c; c = gfc_constructor_next (c))
1344     {
1345       /* If this is an iterator or an array, the offset must be a variable.  */
1346       if ((c->iterator || c->expr->rank > 0) && INTEGER_CST_P (*poffset))
1347         gfc_put_offset_into_var (pblock, poffset, offsetvar);
1348
1349       /* Shadowing the iterator avoids changing its value and saves us from
1350          keeping track of it. Further, it makes sure that there's always a
1351          backend-decl for the symbol, even if there wasn't one before,
1352          e.g. in the case of an iterator that appears in a specification
1353          expression in an interface mapping.  */
1354       if (c->iterator)
1355         {
1356           gfc_symbol *sym = c->iterator->var->symtree->n.sym;
1357           tree type = gfc_typenode_for_spec (&sym->ts);
1358
1359           shadow_loopvar = gfc_create_var (type, "shadow_loopvar");
1360           gfc_shadow_sym (sym, shadow_loopvar, &saved_loopvar);
1361         }
1362
1363       gfc_start_block (&body);
1364
1365       if (c->expr->expr_type == EXPR_ARRAY)
1366         {
1367           /* Array constructors can be nested.  */
1368           gfc_trans_array_constructor_value (&body, type, desc,
1369                                              c->expr->value.constructor,
1370                                              poffset, offsetvar, dynamic);
1371         }
1372       else if (c->expr->rank > 0)
1373         {
1374           gfc_trans_array_constructor_subarray (&body, type, desc, c->expr,
1375                                                 poffset, offsetvar, dynamic);
1376         }
1377       else
1378         {
1379           /* This code really upsets the gimplifier so don't bother for now.  */
1380           gfc_constructor *p;
1381           HOST_WIDE_INT n;
1382           HOST_WIDE_INT size;
1383
1384           p = c;
1385           n = 0;
1386           while (p && !(p->iterator || p->expr->expr_type != EXPR_CONSTANT))
1387             {
1388               p = gfc_constructor_next (p);
1389               n++;
1390             }
1391           if (n < 4)
1392             {
1393               /* Scalar values.  */
1394               gfc_init_se (&se, NULL);
1395               gfc_trans_array_ctor_element (&body, desc, *poffset,
1396                                             &se, c->expr);
1397
1398               *poffset = fold_build2_loc (input_location, PLUS_EXPR,
1399                                           gfc_array_index_type,
1400                                           *poffset, gfc_index_one_node);
1401             }
1402           else
1403             {
1404               /* Collect multiple scalar constants into a constructor.  */
1405               VEC(constructor_elt,gc) *v = NULL;
1406               tree init;
1407               tree bound;
1408               tree tmptype;
1409               HOST_WIDE_INT idx = 0;
1410
1411               p = c;
1412               /* Count the number of consecutive scalar constants.  */
1413               while (p && !(p->iterator
1414                             || p->expr->expr_type != EXPR_CONSTANT))
1415                 {
1416                   gfc_init_se (&se, NULL);
1417                   gfc_conv_constant (&se, p->expr);
1418
1419                   if (c->expr->ts.type != BT_CHARACTER)
1420                     se.expr = fold_convert (type, se.expr);
1421                   /* For constant character array constructors we build
1422                      an array of pointers.  */
1423                   else if (POINTER_TYPE_P (type))
1424                     se.expr = gfc_build_addr_expr
1425                                 (gfc_get_pchar_type (p->expr->ts.kind),
1426                                  se.expr);
1427
1428                   CONSTRUCTOR_APPEND_ELT (v,
1429                                           build_int_cst (gfc_array_index_type,
1430                                                          idx++),
1431                                           se.expr);
1432                   c = p;
1433                   p = gfc_constructor_next (p);
1434                 }
1435
1436               bound = build_int_cst (NULL_TREE, n - 1);
1437               /* Create an array type to hold them.  */
1438               tmptype = build_range_type (gfc_array_index_type,
1439                                           gfc_index_zero_node, bound);
1440               tmptype = build_array_type (type, tmptype);
1441
1442               init = build_constructor (tmptype, v);
1443               TREE_CONSTANT (init) = 1;
1444               TREE_STATIC (init) = 1;
1445               /* Create a static variable to hold the data.  */
1446               tmp = gfc_create_var (tmptype, "data");
1447               TREE_STATIC (tmp) = 1;
1448               TREE_CONSTANT (tmp) = 1;
1449               TREE_READONLY (tmp) = 1;
1450               DECL_INITIAL (tmp) = init;
1451               init = tmp;
1452
1453               /* Use BUILTIN_MEMCPY to assign the values.  */
1454               tmp = gfc_conv_descriptor_data_get (desc);
1455               tmp = build_fold_indirect_ref_loc (input_location,
1456                                              tmp);
1457               tmp = gfc_build_array_ref (tmp, *poffset, NULL);
1458               tmp = gfc_build_addr_expr (NULL_TREE, tmp);
1459               init = gfc_build_addr_expr (NULL_TREE, init);
1460
1461               size = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (type));
1462               bound = build_int_cst (NULL_TREE, n * size);
1463               tmp = build_call_expr_loc (input_location,
1464                                      built_in_decls[BUILT_IN_MEMCPY], 3,
1465                                      tmp, init, bound);
1466               gfc_add_expr_to_block (&body, tmp);
1467
1468               *poffset = fold_build2_loc (input_location, PLUS_EXPR,
1469                                       gfc_array_index_type, *poffset,
1470                                       build_int_cst (gfc_array_index_type, n));
1471             }
1472           if (!INTEGER_CST_P (*poffset))
1473             {
1474               gfc_add_modify (&body, *offsetvar, *poffset);
1475               *poffset = *offsetvar;
1476             }
1477         }
1478
1479       /* The frontend should already have done any expansions
1480          at compile-time.  */
1481       if (!c->iterator)
1482         {
1483           /* Pass the code as is.  */
1484           tmp = gfc_finish_block (&body);
1485           gfc_add_expr_to_block (pblock, tmp);
1486         }
1487       else
1488         {
1489           /* Build the implied do-loop.  */
1490           stmtblock_t implied_do_block;
1491           tree cond;
1492           tree end;
1493           tree step;
1494           tree exit_label;
1495           tree loopbody;
1496           tree tmp2;
1497
1498           loopbody = gfc_finish_block (&body);
1499
1500           /* Create a new block that holds the implied-do loop. A temporary
1501              loop-variable is used.  */
1502           gfc_start_block(&implied_do_block);
1503
1504           /* Initialize the loop.  */
1505           gfc_init_se (&se, NULL);
1506           gfc_conv_expr_val (&se, c->iterator->start);
1507           gfc_add_block_to_block (&implied_do_block, &se.pre);
1508           gfc_add_modify (&implied_do_block, shadow_loopvar, se.expr);
1509
1510           gfc_init_se (&se, NULL);
1511           gfc_conv_expr_val (&se, c->iterator->end);
1512           gfc_add_block_to_block (&implied_do_block, &se.pre);
1513           end = gfc_evaluate_now (se.expr, &implied_do_block);
1514
1515           gfc_init_se (&se, NULL);
1516           gfc_conv_expr_val (&se, c->iterator->step);
1517           gfc_add_block_to_block (&implied_do_block, &se.pre);
1518           step = gfc_evaluate_now (se.expr, &implied_do_block);
1519
1520           /* If this array expands dynamically, and the number of iterations
1521              is not constant, we won't have allocated space for the static
1522              part of C->EXPR's size.  Do that now.  */
1523           if (dynamic && gfc_iterator_has_dynamic_bounds (c->iterator))
1524             {
1525               /* Get the number of iterations.  */
1526               tmp = gfc_get_iteration_count (shadow_loopvar, end, step);
1527
1528               /* Get the static part of C->EXPR's size.  */
1529               gfc_get_array_constructor_element_size (&size, c->expr);
1530               tmp2 = gfc_conv_mpz_to_tree (size, gfc_index_integer_kind);
1531
1532               /* Grow the array by TMP * TMP2 elements.  */
1533               tmp = fold_build2_loc (input_location, MULT_EXPR,
1534                                      gfc_array_index_type, tmp, tmp2);
1535               gfc_grow_array (&implied_do_block, desc, tmp);
1536             }
1537
1538           /* Generate the loop body.  */
1539           exit_label = gfc_build_label_decl (NULL_TREE);
1540           gfc_start_block (&body);
1541
1542           /* Generate the exit condition.  Depending on the sign of
1543              the step variable we have to generate the correct
1544              comparison.  */
1545           tmp = fold_build2_loc (input_location, GT_EXPR, boolean_type_node,
1546                                  step, build_int_cst (TREE_TYPE (step), 0));
1547           cond = fold_build3_loc (input_location, COND_EXPR,
1548                       boolean_type_node, tmp,
1549                       fold_build2_loc (input_location, GT_EXPR,
1550                                        boolean_type_node, shadow_loopvar, end),
1551                       fold_build2_loc (input_location, LT_EXPR,
1552                                        boolean_type_node, shadow_loopvar, end));
1553           tmp = build1_v (GOTO_EXPR, exit_label);
1554           TREE_USED (exit_label) = 1;
1555           tmp = build3_v (COND_EXPR, cond, tmp,
1556                           build_empty_stmt (input_location));
1557           gfc_add_expr_to_block (&body, tmp);
1558
1559           /* The main loop body.  */
1560           gfc_add_expr_to_block (&body, loopbody);
1561
1562           /* Increase loop variable by step.  */
1563           tmp = fold_build2_loc (input_location, PLUS_EXPR,
1564                                  TREE_TYPE (shadow_loopvar), shadow_loopvar,
1565                                  step);
1566           gfc_add_modify (&body, shadow_loopvar, tmp);
1567
1568           /* Finish the loop.  */
1569           tmp = gfc_finish_block (&body);
1570           tmp = build1_v (LOOP_EXPR, tmp);
1571           gfc_add_expr_to_block (&implied_do_block, tmp);
1572
1573           /* Add the exit label.  */
1574           tmp = build1_v (LABEL_EXPR, exit_label);
1575           gfc_add_expr_to_block (&implied_do_block, tmp);
1576
1577           /* Finishe the implied-do loop.  */
1578           tmp = gfc_finish_block(&implied_do_block);
1579           gfc_add_expr_to_block(pblock, tmp);
1580
1581           gfc_restore_sym (c->iterator->var->symtree->n.sym, &saved_loopvar);
1582         }
1583     }
1584   mpz_clear (size);
1585 }
1586
1587
1588 /* Figure out the string length of a variable reference expression.
1589    Used by get_array_ctor_strlen.  */
1590
1591 static void
1592 get_array_ctor_var_strlen (gfc_expr * expr, tree * len)
1593 {
1594   gfc_ref *ref;
1595   gfc_typespec *ts;
1596   mpz_t char_len;
1597
1598   /* Don't bother if we already know the length is a constant.  */
1599   if (*len && INTEGER_CST_P (*len))
1600     return;
1601
1602   ts = &expr->symtree->n.sym->ts;
1603   for (ref = expr->ref; ref; ref = ref->next)
1604     {
1605       switch (ref->type)
1606         {
1607         case REF_ARRAY:
1608           /* Array references don't change the string length.  */
1609           break;
1610
1611         case REF_COMPONENT:
1612           /* Use the length of the component.  */
1613           ts = &ref->u.c.component->ts;
1614           break;
1615
1616         case REF_SUBSTRING:
1617           if (ref->u.ss.start->expr_type != EXPR_CONSTANT
1618               || ref->u.ss.end->expr_type != EXPR_CONSTANT)
1619             break;
1620           mpz_init_set_ui (char_len, 1);
1621           mpz_add (char_len, char_len, ref->u.ss.end->value.integer);
1622           mpz_sub (char_len, char_len, ref->u.ss.start->value.integer);
1623           *len = gfc_conv_mpz_to_tree (char_len, gfc_default_integer_kind);
1624           *len = convert (gfc_charlen_type_node, *len);
1625           mpz_clear (char_len);
1626           return;
1627
1628         default:
1629           /* TODO: Substrings are tricky because we can't evaluate the
1630              expression more than once.  For now we just give up, and hope
1631              we can figure it out elsewhere.  */
1632           return;
1633         }
1634     }
1635
1636   *len = ts->u.cl->backend_decl;
1637 }
1638
1639
1640 /* A catch-all to obtain the string length for anything that is not a
1641    constant, array or variable.  */
1642 static void
1643 get_array_ctor_all_strlen (stmtblock_t *block, gfc_expr *e, tree *len)
1644 {
1645   gfc_se se;
1646   gfc_ss *ss;
1647
1648   /* Don't bother if we already know the length is a constant.  */
1649   if (*len && INTEGER_CST_P (*len))
1650     return;
1651
1652   if (!e->ref && e->ts.u.cl && e->ts.u.cl->length
1653         && e->ts.u.cl->length->expr_type == EXPR_CONSTANT)
1654     {
1655       /* This is easy.  */
1656       gfc_conv_const_charlen (e->ts.u.cl);
1657       *len = e->ts.u.cl->backend_decl;
1658     }
1659   else
1660     {
1661       /* Otherwise, be brutal even if inefficient.  */
1662       ss = gfc_walk_expr (e);
1663       gfc_init_se (&se, NULL);
1664
1665       /* No function call, in case of side effects.  */
1666       se.no_function_call = 1;
1667       if (ss == gfc_ss_terminator)
1668         gfc_conv_expr (&se, e);
1669       else
1670         gfc_conv_expr_descriptor (&se, e, ss);
1671
1672       /* Fix the value.  */
1673       *len = gfc_evaluate_now (se.string_length, &se.pre);
1674
1675       gfc_add_block_to_block (block, &se.pre);
1676       gfc_add_block_to_block (block, &se.post);
1677
1678       e->ts.u.cl->backend_decl = *len;
1679     }
1680 }
1681
1682
1683 /* Figure out the string length of a character array constructor.
1684    If len is NULL, don't calculate the length; this happens for recursive calls
1685    when a sub-array-constructor is an element but not at the first position,
1686    so when we're not interested in the length.
1687    Returns TRUE if all elements are character constants.  */
1688
1689 bool
1690 get_array_ctor_strlen (stmtblock_t *block, gfc_constructor_base base, tree * len)
1691 {
1692   gfc_constructor *c;
1693   bool is_const;
1694
1695   is_const = TRUE;
1696
1697   if (gfc_constructor_first (base) == NULL)
1698     {
1699       if (len)
1700         *len = build_int_cstu (gfc_charlen_type_node, 0);
1701       return is_const;
1702     }
1703
1704   /* Loop over all constructor elements to find out is_const, but in len we
1705      want to store the length of the first, not the last, element.  We can
1706      of course exit the loop as soon as is_const is found to be false.  */
1707   for (c = gfc_constructor_first (base);
1708        c && is_const; c = gfc_constructor_next (c))
1709     {
1710       switch (c->expr->expr_type)
1711         {
1712         case EXPR_CONSTANT:
1713           if (len && !(*len && INTEGER_CST_P (*len)))
1714             *len = build_int_cstu (gfc_charlen_type_node,
1715                                    c->expr->value.character.length);
1716           break;
1717
1718         case EXPR_ARRAY:
1719           if (!get_array_ctor_strlen (block, c->expr->value.constructor, len))
1720             is_const = false;
1721           break;
1722
1723         case EXPR_VARIABLE:
1724           is_const = false;
1725           if (len)
1726             get_array_ctor_var_strlen (c->expr, len);
1727           break;
1728
1729         default:
1730           is_const = false;
1731           if (len)
1732             get_array_ctor_all_strlen (block, c->expr, len);
1733           break;
1734         }
1735
1736       /* After the first iteration, we don't want the length modified.  */
1737       len = NULL;
1738     }
1739
1740   return is_const;
1741 }
1742
1743 /* Check whether the array constructor C consists entirely of constant
1744    elements, and if so returns the number of those elements, otherwise
1745    return zero.  Note, an empty or NULL array constructor returns zero.  */
1746
1747 unsigned HOST_WIDE_INT
1748 gfc_constant_array_constructor_p (gfc_constructor_base base)
1749 {
1750   unsigned HOST_WIDE_INT nelem = 0;
1751
1752   gfc_constructor *c = gfc_constructor_first (base);
1753   while (c)
1754     {
1755       if (c->iterator
1756           || c->expr->rank > 0
1757           || c->expr->expr_type != EXPR_CONSTANT)
1758         return 0;
1759       c = gfc_constructor_next (c);
1760       nelem++;
1761     }
1762   return nelem;
1763 }
1764
1765
1766 /* Given EXPR, the constant array constructor specified by an EXPR_ARRAY,
1767    and the tree type of it's elements, TYPE, return a static constant
1768    variable that is compile-time initialized.  */
1769
1770 tree
1771 gfc_build_constant_array_constructor (gfc_expr * expr, tree type)
1772 {
1773   tree tmptype, init, tmp;
1774   HOST_WIDE_INT nelem;
1775   gfc_constructor *c;
1776   gfc_array_spec as;
1777   gfc_se se;
1778   int i;
1779   VEC(constructor_elt,gc) *v = NULL;
1780
1781   /* First traverse the constructor list, converting the constants
1782      to tree to build an initializer.  */
1783   nelem = 0;
1784   c = gfc_constructor_first (expr->value.constructor);
1785   while (c)
1786     {
1787       gfc_init_se (&se, NULL);
1788       gfc_conv_constant (&se, c->expr);
1789       if (c->expr->ts.type != BT_CHARACTER)
1790         se.expr = fold_convert (type, se.expr);
1791       else if (POINTER_TYPE_P (type))
1792         se.expr = gfc_build_addr_expr (gfc_get_pchar_type (c->expr->ts.kind),
1793                                        se.expr);
1794       CONSTRUCTOR_APPEND_ELT (v, build_int_cst (gfc_array_index_type, nelem),
1795                               se.expr);
1796       c = gfc_constructor_next (c);
1797       nelem++;
1798     }
1799
1800   /* Next determine the tree type for the array.  We use the gfortran
1801      front-end's gfc_get_nodesc_array_type in order to create a suitable
1802      GFC_ARRAY_TYPE_P that may be used by the scalarizer.  */
1803
1804   memset (&as, 0, sizeof (gfc_array_spec));
1805
1806   as.rank = expr->rank;
1807   as.type = AS_EXPLICIT;
1808   if (!expr->shape)
1809     {
1810       as.lower[0] = gfc_get_int_expr (gfc_default_integer_kind, NULL, 0);
1811       as.upper[0] = gfc_get_int_expr (gfc_default_integer_kind,
1812                                       NULL, nelem - 1);
1813     }
1814   else
1815     for (i = 0; i < expr->rank; i++)
1816       {
1817         int tmp = (int) mpz_get_si (expr->shape[i]);
1818         as.lower[i] = gfc_get_int_expr (gfc_default_integer_kind, NULL, 0);
1819         as.upper[i] = gfc_get_int_expr (gfc_default_integer_kind,
1820                                         NULL, tmp - 1);
1821       }
1822
1823   tmptype = gfc_get_nodesc_array_type (type, &as, PACKED_STATIC, true);
1824
1825   init = build_constructor (tmptype, v);
1826
1827   TREE_CONSTANT (init) = 1;
1828   TREE_STATIC (init) = 1;
1829
1830   tmp = gfc_create_var (tmptype, "A");
1831   TREE_STATIC (tmp) = 1;
1832   TREE_CONSTANT (tmp) = 1;
1833   TREE_READONLY (tmp) = 1;
1834   DECL_INITIAL (tmp) = init;
1835
1836   return tmp;
1837 }
1838
1839
1840 /* Translate a constant EXPR_ARRAY array constructor for the scalarizer.
1841    This mostly initializes the scalarizer state info structure with the
1842    appropriate values to directly use the array created by the function
1843    gfc_build_constant_array_constructor.  */
1844
1845 static void
1846 gfc_trans_constant_array_constructor (gfc_loopinfo * loop,
1847                                       gfc_ss * ss, tree type)
1848 {
1849   gfc_ss_info *info;
1850   tree tmp;
1851   int i;
1852
1853   tmp = gfc_build_constant_array_constructor (ss->expr, type);
1854
1855   info = &ss->data.info;
1856
1857   info->descriptor = tmp;
1858   info->data = gfc_build_addr_expr (NULL_TREE, tmp);
1859   info->offset = gfc_index_zero_node;
1860
1861   for (i = 0; i < info->dimen; i++)
1862     {
1863       info->delta[i] = gfc_index_zero_node;
1864       info->start[i] = gfc_index_zero_node;
1865       info->end[i] = gfc_index_zero_node;
1866       info->stride[i] = gfc_index_one_node;
1867       info->dim[i] = i;
1868     }
1869
1870   if (info->dimen > loop->temp_dim)
1871     loop->temp_dim = info->dimen;
1872 }
1873
1874 /* Helper routine of gfc_trans_array_constructor to determine if the
1875    bounds of the loop specified by LOOP are constant and simple enough
1876    to use with gfc_trans_constant_array_constructor.  Returns the
1877    iteration count of the loop if suitable, and NULL_TREE otherwise.  */
1878
1879 static tree
1880 constant_array_constructor_loop_size (gfc_loopinfo * loop)
1881 {
1882   tree size = gfc_index_one_node;
1883   tree tmp;
1884   int i;
1885
1886   for (i = 0; i < loop->dimen; i++)
1887     {
1888       /* If the bounds aren't constant, return NULL_TREE.  */
1889       if (!INTEGER_CST_P (loop->from[i]) || !INTEGER_CST_P (loop->to[i]))
1890         return NULL_TREE;
1891       if (!integer_zerop (loop->from[i]))
1892         {
1893           /* Only allow nonzero "from" in one-dimensional arrays.  */
1894           if (loop->dimen != 1)
1895             return NULL_TREE;
1896           tmp = fold_build2_loc (input_location, MINUS_EXPR,
1897                                  gfc_array_index_type,
1898                                  loop->to[i], loop->from[i]);
1899         }
1900       else
1901         tmp = loop->to[i];
1902       tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
1903                              tmp, gfc_index_one_node);
1904       size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
1905                               size, tmp);
1906     }
1907
1908   return size;
1909 }
1910
1911
1912 /* Array constructors are handled by constructing a temporary, then using that
1913    within the scalarization loop.  This is not optimal, but seems by far the
1914    simplest method.  */
1915
1916 static void
1917 gfc_trans_array_constructor (gfc_loopinfo * loop, gfc_ss * ss, locus * where)
1918 {
1919   gfc_constructor_base c;
1920   tree offset;
1921   tree offsetvar;
1922   tree desc;
1923   tree type;
1924   bool dynamic;
1925   bool old_first_len, old_typespec_chararray_ctor;
1926   tree old_first_len_val;
1927
1928   /* Save the old values for nested checking.  */
1929   old_first_len = first_len;
1930   old_first_len_val = first_len_val;
1931   old_typespec_chararray_ctor = typespec_chararray_ctor;
1932
1933   /* Do bounds-checking here and in gfc_trans_array_ctor_element only if no
1934      typespec was given for the array constructor.  */
1935   typespec_chararray_ctor = (ss->expr->ts.u.cl
1936                              && ss->expr->ts.u.cl->length_from_typespec);
1937
1938   if ((gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
1939       && ss->expr->ts.type == BT_CHARACTER && !typespec_chararray_ctor)
1940     {  
1941       first_len_val = gfc_create_var (gfc_charlen_type_node, "len");
1942       first_len = true;
1943     }
1944
1945   ss->data.info.dimen = loop->dimen;
1946
1947   c = ss->expr->value.constructor;
1948   if (ss->expr->ts.type == BT_CHARACTER)
1949     {
1950       bool const_string;
1951       
1952       /* get_array_ctor_strlen walks the elements of the constructor, if a
1953          typespec was given, we already know the string length and want the one
1954          specified there.  */
1955       if (typespec_chararray_ctor && ss->expr->ts.u.cl->length
1956           && ss->expr->ts.u.cl->length->expr_type != EXPR_CONSTANT)
1957         {
1958           gfc_se length_se;
1959
1960           const_string = false;
1961           gfc_init_se (&length_se, NULL);
1962           gfc_conv_expr_type (&length_se, ss->expr->ts.u.cl->length,
1963                               gfc_charlen_type_node);
1964           ss->string_length = length_se.expr;
1965           gfc_add_block_to_block (&loop->pre, &length_se.pre);
1966           gfc_add_block_to_block (&loop->post, &length_se.post);
1967         }
1968       else
1969         const_string = get_array_ctor_strlen (&loop->pre, c,
1970                                               &ss->string_length);
1971
1972       /* Complex character array constructors should have been taken care of
1973          and not end up here.  */
1974       gcc_assert (ss->string_length);
1975
1976       ss->expr->ts.u.cl->backend_decl = ss->string_length;
1977
1978       type = gfc_get_character_type_len (ss->expr->ts.kind, ss->string_length);
1979       if (const_string)
1980         type = build_pointer_type (type);
1981     }
1982   else
1983     type = gfc_typenode_for_spec (&ss->expr->ts);
1984
1985   /* See if the constructor determines the loop bounds.  */
1986   dynamic = false;
1987
1988   if (ss->expr->shape && loop->dimen > 1 && loop->to[0] == NULL_TREE)
1989     {
1990       /* We have a multidimensional parameter.  */
1991       int n;
1992       for (n = 0; n < ss->expr->rank; n++)
1993       {
1994         loop->from[n] = gfc_index_zero_node;
1995         loop->to[n] = gfc_conv_mpz_to_tree (ss->expr->shape [n],
1996                                             gfc_index_integer_kind);
1997         loop->to[n] = fold_build2_loc (input_location, MINUS_EXPR,
1998                                        gfc_array_index_type,
1999                                        loop->to[n], gfc_index_one_node);
2000       }
2001     }
2002
2003   if (loop->to[0] == NULL_TREE)
2004     {
2005       mpz_t size;
2006
2007       /* We should have a 1-dimensional, zero-based loop.  */
2008       gcc_assert (loop->dimen == 1);
2009       gcc_assert (integer_zerop (loop->from[0]));
2010
2011       /* Split the constructor size into a static part and a dynamic part.
2012          Allocate the static size up-front and record whether the dynamic
2013          size might be nonzero.  */
2014       mpz_init (size);
2015       dynamic = gfc_get_array_constructor_size (&size, c);
2016       mpz_sub_ui (size, size, 1);
2017       loop->to[0] = gfc_conv_mpz_to_tree (size, gfc_index_integer_kind);
2018       mpz_clear (size);
2019     }
2020
2021   /* Special case constant array constructors.  */
2022   if (!dynamic)
2023     {
2024       unsigned HOST_WIDE_INT nelem = gfc_constant_array_constructor_p (c);
2025       if (nelem > 0)
2026         {
2027           tree size = constant_array_constructor_loop_size (loop);
2028           if (size && compare_tree_int (size, nelem) == 0)
2029             {
2030               gfc_trans_constant_array_constructor (loop, ss, type);
2031               goto finish;
2032             }
2033         }
2034     }
2035
2036   gfc_trans_create_temp_array (&loop->pre, &loop->post, loop, &ss->data.info,
2037                                type, NULL_TREE, dynamic, true, false, where);
2038
2039   desc = ss->data.info.descriptor;
2040   offset = gfc_index_zero_node;
2041   offsetvar = gfc_create_var_np (gfc_array_index_type, "offset");
2042   TREE_NO_WARNING (offsetvar) = 1;
2043   TREE_USED (offsetvar) = 0;
2044   gfc_trans_array_constructor_value (&loop->pre, type, desc, c,
2045                                      &offset, &offsetvar, dynamic);
2046
2047   /* If the array grows dynamically, the upper bound of the loop variable
2048      is determined by the array's final upper bound.  */
2049   if (dynamic)
2050     loop->to[0] = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[0]);
2051
2052   if (TREE_USED (offsetvar))
2053     pushdecl (offsetvar);
2054   else
2055     gcc_assert (INTEGER_CST_P (offset));
2056 #if 0
2057   /* Disable bound checking for now because it's probably broken.  */
2058   if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
2059     {
2060       gcc_unreachable ();
2061     }
2062 #endif
2063
2064 finish:
2065   /* Restore old values of globals.  */
2066   first_len = old_first_len;
2067   first_len_val = old_first_len_val;
2068   typespec_chararray_ctor = old_typespec_chararray_ctor;
2069 }
2070
2071
2072 /* INFO describes a GFC_SS_SECTION in loop LOOP, and this function is
2073    called after evaluating all of INFO's vector dimensions.  Go through
2074    each such vector dimension and see if we can now fill in any missing
2075    loop bounds.  */
2076
2077 static void
2078 gfc_set_vector_loop_bounds (gfc_loopinfo * loop, gfc_ss_info * info)
2079 {
2080   gfc_se se;
2081   tree tmp;
2082   tree desc;
2083   tree zero;
2084   int n;
2085   int dim;
2086
2087   for (n = 0; n < loop->dimen; n++)
2088     {
2089       dim = info->dim[n];
2090       if (info->ref->u.ar.dimen_type[dim] == DIMEN_VECTOR
2091           && loop->to[n] == NULL)
2092         {
2093           /* Loop variable N indexes vector dimension DIM, and we don't
2094              yet know the upper bound of loop variable N.  Set it to the
2095              difference between the vector's upper and lower bounds.  */
2096           gcc_assert (loop->from[n] == gfc_index_zero_node);
2097           gcc_assert (info->subscript[dim]
2098                       && info->subscript[dim]->type == GFC_SS_VECTOR);
2099
2100           gfc_init_se (&se, NULL);
2101           desc = info->subscript[dim]->data.info.descriptor;
2102           zero = gfc_rank_cst[0];
2103           tmp = fold_build2_loc (input_location, MINUS_EXPR,
2104                              gfc_array_index_type,
2105                              gfc_conv_descriptor_ubound_get (desc, zero),
2106                              gfc_conv_descriptor_lbound_get (desc, zero));
2107           tmp = gfc_evaluate_now (tmp, &loop->pre);
2108           loop->to[n] = tmp;
2109         }
2110     }
2111 }
2112
2113
2114 /* Add the pre and post chains for all the scalar expressions in a SS chain
2115    to loop.  This is called after the loop parameters have been calculated,
2116    but before the actual scalarizing loops.  */
2117
2118 static void
2119 gfc_add_loop_ss_code (gfc_loopinfo * loop, gfc_ss * ss, bool subscript,
2120                       locus * where)
2121 {
2122   gfc_se se;
2123   int n;
2124
2125   /* TODO: This can generate bad code if there are ordering dependencies,
2126      e.g., a callee allocated function and an unknown size constructor.  */
2127   gcc_assert (ss != NULL);
2128
2129   for (; ss != gfc_ss_terminator; ss = ss->loop_chain)
2130     {
2131       gcc_assert (ss);
2132
2133       switch (ss->type)
2134         {
2135         case GFC_SS_SCALAR:
2136           /* Scalar expression.  Evaluate this now.  This includes elemental
2137              dimension indices, but not array section bounds.  */
2138           gfc_init_se (&se, NULL);
2139           gfc_conv_expr (&se, ss->expr);
2140           gfc_add_block_to_block (&loop->pre, &se.pre);
2141
2142           if (ss->expr->ts.type != BT_CHARACTER)
2143             {
2144               /* Move the evaluation of scalar expressions outside the
2145                  scalarization loop, except for WHERE assignments.  */
2146               if (subscript)
2147                 se.expr = convert(gfc_array_index_type, se.expr);
2148               if (!ss->where)
2149                 se.expr = gfc_evaluate_now (se.expr, &loop->pre);
2150               gfc_add_block_to_block (&loop->pre, &se.post);
2151             }
2152           else
2153             gfc_add_block_to_block (&loop->post, &se.post);
2154
2155           ss->data.scalar.expr = se.expr;
2156           ss->string_length = se.string_length;
2157           break;
2158
2159         case GFC_SS_REFERENCE:
2160           /* Scalar argument to elemental procedure.  Evaluate this
2161              now.  */
2162           gfc_init_se (&se, NULL);
2163           gfc_conv_expr (&se, ss->expr);
2164           gfc_add_block_to_block (&loop->pre, &se.pre);
2165           gfc_add_block_to_block (&loop->post, &se.post);
2166
2167           ss->data.scalar.expr = gfc_evaluate_now (se.expr, &loop->pre);
2168           ss->string_length = se.string_length;
2169           break;
2170
2171         case GFC_SS_SECTION:
2172           /* Add the expressions for scalar and vector subscripts.  */
2173           for (n = 0; n < GFC_MAX_DIMENSIONS; n++)
2174             if (ss->data.info.subscript[n])
2175               gfc_add_loop_ss_code (loop, ss->data.info.subscript[n], true,
2176                                     where);
2177
2178           gfc_set_vector_loop_bounds (loop, &ss->data.info);
2179           break;
2180
2181         case GFC_SS_VECTOR:
2182           /* Get the vector's descriptor and store it in SS.  */
2183           gfc_init_se (&se, NULL);
2184           gfc_conv_expr_descriptor (&se, ss->expr, gfc_walk_expr (ss->expr));
2185           gfc_add_block_to_block (&loop->pre, &se.pre);
2186           gfc_add_block_to_block (&loop->post, &se.post);
2187           ss->data.info.descriptor = se.expr;
2188           break;
2189
2190         case GFC_SS_INTRINSIC:
2191           gfc_add_intrinsic_ss_code (loop, ss);
2192           break;
2193
2194         case GFC_SS_FUNCTION:
2195           /* Array function return value.  We call the function and save its
2196              result in a temporary for use inside the loop.  */
2197           gfc_init_se (&se, NULL);
2198           se.loop = loop;
2199           se.ss = ss;
2200           gfc_conv_expr (&se, ss->expr);
2201           gfc_add_block_to_block (&loop->pre, &se.pre);
2202           gfc_add_block_to_block (&loop->post, &se.post);
2203           ss->string_length = se.string_length;
2204           break;
2205
2206         case GFC_SS_CONSTRUCTOR:
2207           if (ss->expr->ts.type == BT_CHARACTER
2208                 && ss->string_length == NULL
2209                 && ss->expr->ts.u.cl
2210                 && ss->expr->ts.u.cl->length)
2211             {
2212               gfc_init_se (&se, NULL);
2213               gfc_conv_expr_type (&se, ss->expr->ts.u.cl->length,
2214                                   gfc_charlen_type_node);
2215               ss->string_length = se.expr;
2216               gfc_add_block_to_block (&loop->pre, &se.pre);
2217               gfc_add_block_to_block (&loop->post, &se.post);
2218             }
2219           gfc_trans_array_constructor (loop, ss, where);
2220           break;
2221
2222         case GFC_SS_TEMP:
2223         case GFC_SS_COMPONENT:
2224           /* Do nothing.  These are handled elsewhere.  */
2225           break;
2226
2227         default:
2228           gcc_unreachable ();
2229         }
2230     }
2231 }
2232
2233
2234 /* Translate expressions for the descriptor and data pointer of a SS.  */
2235 /*GCC ARRAYS*/
2236
2237 static void
2238 gfc_conv_ss_descriptor (stmtblock_t * block, gfc_ss * ss, int base)
2239 {
2240   gfc_se se;
2241   tree tmp;
2242
2243   /* Get the descriptor for the array to be scalarized.  */
2244   gcc_assert (ss->expr->expr_type == EXPR_VARIABLE);
2245   gfc_init_se (&se, NULL);
2246   se.descriptor_only = 1;
2247   gfc_conv_expr_lhs (&se, ss->expr);
2248   gfc_add_block_to_block (block, &se.pre);
2249   ss->data.info.descriptor = se.expr;
2250   ss->string_length = se.string_length;
2251
2252   if (base)
2253     {
2254       /* Also the data pointer.  */
2255       tmp = gfc_conv_array_data (se.expr);
2256       /* If this is a variable or address of a variable we use it directly.
2257          Otherwise we must evaluate it now to avoid breaking dependency
2258          analysis by pulling the expressions for elemental array indices
2259          inside the loop.  */
2260       if (!(DECL_P (tmp)
2261             || (TREE_CODE (tmp) == ADDR_EXPR
2262                 && DECL_P (TREE_OPERAND (tmp, 0)))))
2263         tmp = gfc_evaluate_now (tmp, block);
2264       ss->data.info.data = tmp;
2265
2266       tmp = gfc_conv_array_offset (se.expr);
2267       ss->data.info.offset = gfc_evaluate_now (tmp, block);
2268     }
2269 }
2270
2271
2272 /* Initialize a gfc_loopinfo structure.  */
2273
2274 void
2275 gfc_init_loopinfo (gfc_loopinfo * loop)
2276 {
2277   int n;
2278
2279   memset (loop, 0, sizeof (gfc_loopinfo));
2280   gfc_init_block (&loop->pre);
2281   gfc_init_block (&loop->post);
2282
2283   /* Initially scalarize in order and default to no loop reversal.  */
2284   for (n = 0; n < GFC_MAX_DIMENSIONS; n++)
2285     {
2286       loop->order[n] = n;
2287       loop->reverse[n] = GFC_CANNOT_REVERSE;
2288     }
2289
2290   loop->ss = gfc_ss_terminator;
2291 }
2292
2293
2294 /* Copies the loop variable info to a gfc_se structure. Does not copy the SS
2295    chain.  */
2296
2297 void
2298 gfc_copy_loopinfo_to_se (gfc_se * se, gfc_loopinfo * loop)
2299 {
2300   se->loop = loop;
2301 }
2302
2303
2304 /* Return an expression for the data pointer of an array.  */
2305
2306 tree
2307 gfc_conv_array_data (tree descriptor)
2308 {
2309   tree type;
2310
2311   type = TREE_TYPE (descriptor);
2312   if (GFC_ARRAY_TYPE_P (type))
2313     {
2314       if (TREE_CODE (type) == POINTER_TYPE)
2315         return descriptor;
2316       else
2317         {
2318           /* Descriptorless arrays.  */
2319           return gfc_build_addr_expr (NULL_TREE, descriptor);
2320         }
2321     }
2322   else
2323     return gfc_conv_descriptor_data_get (descriptor);
2324 }
2325
2326
2327 /* Return an expression for the base offset of an array.  */
2328
2329 tree
2330 gfc_conv_array_offset (tree descriptor)
2331 {
2332   tree type;
2333
2334   type = TREE_TYPE (descriptor);
2335   if (GFC_ARRAY_TYPE_P (type))
2336     return GFC_TYPE_ARRAY_OFFSET (type);
2337   else
2338     return gfc_conv_descriptor_offset_get (descriptor);
2339 }
2340
2341
2342 /* Get an expression for the array stride.  */
2343
2344 tree
2345 gfc_conv_array_stride (tree descriptor, int dim)
2346 {
2347   tree tmp;
2348   tree type;
2349
2350   type = TREE_TYPE (descriptor);
2351
2352   /* For descriptorless arrays use the array size.  */
2353   tmp = GFC_TYPE_ARRAY_STRIDE (type, dim);
2354   if (tmp != NULL_TREE)
2355     return tmp;
2356
2357   tmp = gfc_conv_descriptor_stride_get (descriptor, gfc_rank_cst[dim]);
2358   return tmp;
2359 }
2360
2361
2362 /* Like gfc_conv_array_stride, but for the lower bound.  */
2363
2364 tree
2365 gfc_conv_array_lbound (tree descriptor, int dim)
2366 {
2367   tree tmp;
2368   tree type;
2369
2370   type = TREE_TYPE (descriptor);
2371
2372   tmp = GFC_TYPE_ARRAY_LBOUND (type, dim);
2373   if (tmp != NULL_TREE)
2374     return tmp;
2375
2376   tmp = gfc_conv_descriptor_lbound_get (descriptor, gfc_rank_cst[dim]);
2377   return tmp;
2378 }
2379
2380
2381 /* Like gfc_conv_array_stride, but for the upper bound.  */
2382
2383 tree
2384 gfc_conv_array_ubound (tree descriptor, int dim)
2385 {
2386   tree tmp;
2387   tree type;
2388
2389   type = TREE_TYPE (descriptor);
2390
2391   tmp = GFC_TYPE_ARRAY_UBOUND (type, dim);
2392   if (tmp != NULL_TREE)
2393     return tmp;
2394
2395   /* This should only ever happen when passing an assumed shape array
2396      as an actual parameter.  The value will never be used.  */
2397   if (GFC_ARRAY_TYPE_P (TREE_TYPE (descriptor)))
2398     return gfc_index_zero_node;
2399
2400   tmp = gfc_conv_descriptor_ubound_get (descriptor, gfc_rank_cst[dim]);
2401   return tmp;
2402 }
2403
2404
2405 /* Generate code to perform an array index bound check.  */
2406
2407 static tree
2408 gfc_trans_array_bound_check (gfc_se * se, tree descriptor, tree index, int n,
2409                              locus * where, bool check_upper)
2410 {
2411   tree fault;
2412   tree tmp_lo, tmp_up;
2413   char *msg;
2414   const char * name = NULL;
2415
2416   if (!(gfc_option.rtcheck & GFC_RTCHECK_BOUNDS))
2417     return index;
2418
2419   index = gfc_evaluate_now (index, &se->pre);
2420
2421   /* We find a name for the error message.  */
2422   if (se->ss)
2423     name = se->ss->expr->symtree->name;
2424
2425   if (!name && se->loop && se->loop->ss && se->loop->ss->expr
2426       && se->loop->ss->expr->symtree)
2427     name = se->loop->ss->expr->symtree->name;
2428
2429   if (!name && se->loop && se->loop->ss && se->loop->ss->loop_chain
2430       && se->loop->ss->loop_chain->expr
2431       && se->loop->ss->loop_chain->expr->symtree)
2432     name = se->loop->ss->loop_chain->expr->symtree->name;
2433
2434   if (!name && se->loop && se->loop->ss && se->loop->ss->expr)
2435     {
2436       if (se->loop->ss->expr->expr_type == EXPR_FUNCTION
2437           && se->loop->ss->expr->value.function.name)
2438         name = se->loop->ss->expr->value.function.name;
2439       else
2440         if (se->loop->ss->type == GFC_SS_CONSTRUCTOR
2441             || se->loop->ss->type == GFC_SS_SCALAR)
2442           name = "unnamed constant";
2443     }
2444
2445   if (TREE_CODE (descriptor) == VAR_DECL)
2446     name = IDENTIFIER_POINTER (DECL_NAME (descriptor));
2447
2448   /* If upper bound is present, include both bounds in the error message.  */
2449   if (check_upper)
2450     {
2451       tmp_lo = gfc_conv_array_lbound (descriptor, n);
2452       tmp_up = gfc_conv_array_ubound (descriptor, n);
2453
2454       if (name)
2455         asprintf (&msg, "Index '%%ld' of dimension %d of array '%s' "
2456                   "outside of expected range (%%ld:%%ld)", n+1, name);
2457       else
2458         asprintf (&msg, "Index '%%ld' of dimension %d "
2459                   "outside of expected range (%%ld:%%ld)", n+1);
2460
2461       fault = fold_build2_loc (input_location, LT_EXPR, boolean_type_node,
2462                                index, tmp_lo);
2463       gfc_trans_runtime_check (true, false, fault, &se->pre, where, msg,
2464                                fold_convert (long_integer_type_node, index),
2465                                fold_convert (long_integer_type_node, tmp_lo),
2466                                fold_convert (long_integer_type_node, tmp_up));
2467       fault = fold_build2_loc (input_location, GT_EXPR, boolean_type_node,
2468                                index, tmp_up);
2469       gfc_trans_runtime_check (true, false, fault, &se->pre, where, msg,
2470                                fold_convert (long_integer_type_node, index),
2471                                fold_convert (long_integer_type_node, tmp_lo),
2472                                fold_convert (long_integer_type_node, tmp_up));
2473       gfc_free (msg);
2474     }
2475   else
2476     {
2477       tmp_lo = gfc_conv_array_lbound (descriptor, n);
2478
2479       if (name)
2480         asprintf (&msg, "Index '%%ld' of dimension %d of array '%s' "
2481                   "below lower bound of %%ld", n+1, name);
2482       else
2483         asprintf (&msg, "Index '%%ld' of dimension %d "
2484                   "below lower bound of %%ld", n+1);
2485
2486       fault = fold_build2_loc (input_location, LT_EXPR, boolean_type_node,
2487                                index, tmp_lo);
2488       gfc_trans_runtime_check (true, false, fault, &se->pre, where, msg,
2489                                fold_convert (long_integer_type_node, index),
2490                                fold_convert (long_integer_type_node, tmp_lo));
2491       gfc_free (msg);
2492     }
2493
2494   return index;
2495 }
2496
2497
2498 /* Return the offset for an index.  Performs bound checking for elemental
2499    dimensions.  Single element references are processed separately.
2500    DIM is the array dimension, I is the loop dimension.  */
2501
2502 static tree
2503 gfc_conv_array_index_offset (gfc_se * se, gfc_ss_info * info, int dim, int i,
2504                              gfc_array_ref * ar, tree stride)
2505 {
2506   tree index;
2507   tree desc;
2508   tree data;
2509
2510   /* Get the index into the array for this dimension.  */
2511   if (ar)
2512     {
2513       gcc_assert (ar->type != AR_ELEMENT);
2514       switch (ar->dimen_type[dim])
2515         {
2516         case DIMEN_ELEMENT:
2517           /* Elemental dimension.  */
2518           gcc_assert (info->subscript[dim]
2519                       && info->subscript[dim]->type == GFC_SS_SCALAR);
2520           /* We've already translated this value outside the loop.  */
2521           index = info->subscript[dim]->data.scalar.expr;
2522
2523           index = gfc_trans_array_bound_check (se, info->descriptor,
2524                         index, dim, &ar->where,
2525                         ar->as->type != AS_ASSUMED_SIZE
2526                         || dim < ar->dimen - 1);
2527           break;
2528
2529         case DIMEN_VECTOR:
2530           gcc_assert (info && se->loop);
2531           gcc_assert (info->subscript[dim]
2532                       && info->subscript[dim]->type == GFC_SS_VECTOR);
2533           desc = info->subscript[dim]->data.info.descriptor;
2534
2535           /* Get a zero-based index into the vector.  */
2536           index = fold_build2_loc (input_location, MINUS_EXPR,
2537                                    gfc_array_index_type,
2538                                    se->loop->loopvar[i], se->loop->from[i]);
2539
2540           /* Multiply the index by the stride.  */
2541           index = fold_build2_loc (input_location, MULT_EXPR,
2542                                    gfc_array_index_type,
2543                                    index, gfc_conv_array_stride (desc, 0));
2544
2545           /* Read the vector to get an index into info->descriptor.  */
2546           data = build_fold_indirect_ref_loc (input_location,
2547                                           gfc_conv_array_data (desc));
2548           index = gfc_build_array_ref (data, index, NULL);
2549           index = gfc_evaluate_now (index, &se->pre);
2550           index = fold_convert (gfc_array_index_type, index);
2551
2552           /* Do any bounds checking on the final info->descriptor index.  */
2553           index = gfc_trans_array_bound_check (se, info->descriptor,
2554                         index, dim, &ar->where,
2555                         ar->as->type != AS_ASSUMED_SIZE
2556                         || dim < ar->dimen - 1);
2557           break;
2558
2559         case DIMEN_RANGE:
2560           /* Scalarized dimension.  */
2561           gcc_assert (info && se->loop);
2562
2563           /* Multiply the loop variable by the stride and delta.  */
2564           index = se->loop->loopvar[i];
2565           if (!integer_onep (info->stride[dim]))
2566             index = fold_build2_loc (input_location, MULT_EXPR,
2567                                      gfc_array_index_type, index,
2568                                      info->stride[dim]);
2569           if (!integer_zerop (info->delta[dim]))
2570             index = fold_build2_loc (input_location, PLUS_EXPR,
2571                                      gfc_array_index_type, index,
2572                                      info->delta[dim]);
2573           break;
2574
2575         default:
2576           gcc_unreachable ();
2577         }
2578     }
2579   else
2580     {
2581       /* Temporary array or derived type component.  */
2582       gcc_assert (se->loop);
2583       index = se->loop->loopvar[se->loop->order[i]];
2584       if (!integer_zerop (info->delta[dim]))
2585         index = fold_build2_loc (input_location, PLUS_EXPR,
2586                                  gfc_array_index_type, index, info->delta[dim]);
2587     }
2588
2589   /* Multiply by the stride.  */
2590   if (!integer_onep (stride))
2591     index = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
2592                              index, stride);
2593
2594   return index;
2595 }
2596
2597
2598 /* Build a scalarized reference to an array.  */
2599
2600 static void
2601 gfc_conv_scalarized_array_ref (gfc_se * se, gfc_array_ref * ar)
2602 {
2603   gfc_ss_info *info;
2604   tree decl = NULL_TREE;
2605   tree index;
2606   tree tmp;
2607   int n;
2608
2609   info = &se->ss->data.info;
2610   if (ar)
2611     n = se->loop->order[0];
2612   else
2613     n = 0;
2614
2615   index = gfc_conv_array_index_offset (se, info, info->dim[n], n, ar,
2616                                        info->stride0);
2617   /* Add the offset for this dimension to the stored offset for all other
2618      dimensions.  */
2619   if (!integer_zerop (info->offset))
2620     index = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
2621                              index, info->offset);
2622
2623   if (se->ss->expr && is_subref_array (se->ss->expr))
2624     decl = se->ss->expr->symtree->n.sym->backend_decl;
2625
2626   tmp = build_fold_indirect_ref_loc (input_location,
2627                                  info->data);
2628   se->expr = gfc_build_array_ref (tmp, index, decl);
2629 }
2630
2631
2632 /* Translate access of temporary array.  */
2633
2634 void
2635 gfc_conv_tmp_array_ref (gfc_se * se)
2636 {
2637   se->string_length = se->ss->string_length;
2638   gfc_conv_scalarized_array_ref (se, NULL);
2639 }
2640
2641
2642 /* Build an array reference.  se->expr already holds the array descriptor.
2643    This should be either a variable, indirect variable reference or component
2644    reference.  For arrays which do not have a descriptor, se->expr will be
2645    the data pointer.
2646    a(i, j, k) = base[offset + i * stride[0] + j * stride[1] + k * stride[2]]*/
2647
2648 void
2649 gfc_conv_array_ref (gfc_se * se, gfc_array_ref * ar, gfc_symbol * sym,
2650                     locus * where)
2651 {
2652   int n;
2653   tree index;
2654   tree tmp;
2655   tree stride;
2656   gfc_se indexse;
2657   gfc_se tmpse;
2658
2659   if (ar->dimen == 0)
2660     return;
2661
2662   /* Handle scalarized references separately.  */
2663   if (ar->type != AR_ELEMENT)
2664     {
2665       gfc_conv_scalarized_array_ref (se, ar);
2666       gfc_advance_se_ss_chain (se);
2667       return;
2668     }
2669
2670   index = gfc_index_zero_node;
2671
2672   /* Calculate the offsets from all the dimensions.  */
2673   for (n = 0; n < ar->dimen; n++)
2674     {
2675       /* Calculate the index for this dimension.  */
2676       gfc_init_se (&indexse, se);
2677       gfc_conv_expr_type (&indexse, ar->start[n], gfc_array_index_type);
2678       gfc_add_block_to_block (&se->pre, &indexse.pre);
2679
2680       if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
2681         {
2682           /* Check array bounds.  */
2683           tree cond;
2684           char *msg;
2685
2686           /* Evaluate the indexse.expr only once.  */
2687           indexse.expr = save_expr (indexse.expr);
2688
2689           /* Lower bound.  */
2690           tmp = gfc_conv_array_lbound (se->expr, n);
2691           if (sym->attr.temporary)
2692             {
2693               gfc_init_se (&tmpse, se);
2694               gfc_conv_expr_type (&tmpse, ar->as->lower[n],
2695                                   gfc_array_index_type);
2696               gfc_add_block_to_block (&se->pre, &tmpse.pre);
2697               tmp = tmpse.expr;
2698             }
2699
2700           cond = fold_build2_loc (input_location, LT_EXPR, boolean_type_node, 
2701                                   indexse.expr, tmp);
2702           asprintf (&msg, "Index '%%ld' of dimension %d of array '%s' "
2703                     "below lower bound of %%ld", n+1, sym->name);
2704           gfc_trans_runtime_check (true, false, cond, &se->pre, where, msg,
2705                                    fold_convert (long_integer_type_node,
2706                                                  indexse.expr),
2707                                    fold_convert (long_integer_type_node, tmp));
2708           gfc_free (msg);
2709
2710           /* Upper bound, but not for the last dimension of assumed-size
2711              arrays.  */
2712           if (n < ar->dimen - 1 || ar->as->type != AS_ASSUMED_SIZE)
2713             {
2714               tmp = gfc_conv_array_ubound (se->expr, n);
2715               if (sym->attr.temporary)
2716                 {
2717                   gfc_init_se (&tmpse, se);
2718                   gfc_conv_expr_type (&tmpse, ar->as->upper[n],
2719                                       gfc_array_index_type);
2720                   gfc_add_block_to_block (&se->pre, &tmpse.pre);
2721                   tmp = tmpse.expr;
2722                 }
2723
2724               cond = fold_build2_loc (input_location, GT_EXPR,
2725                                       boolean_type_node, indexse.expr, tmp);
2726               asprintf (&msg, "Index '%%ld' of dimension %d of array '%s' "
2727                         "above upper bound of %%ld", n+1, sym->name);
2728               gfc_trans_runtime_check (true, false, cond, &se->pre, where, msg,
2729                                    fold_convert (long_integer_type_node,
2730                                                  indexse.expr),
2731                                    fold_convert (long_integer_type_node, tmp));
2732               gfc_free (msg);
2733             }
2734         }
2735
2736       /* Multiply the index by the stride.  */
2737       stride = gfc_conv_array_stride (se->expr, n);
2738       tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
2739                              indexse.expr, stride);
2740
2741       /* And add it to the total.  */
2742       index = fold_build2_loc (input_location, PLUS_EXPR,
2743                                gfc_array_index_type, index, tmp);
2744     }
2745
2746   tmp = gfc_conv_array_offset (se->expr);
2747   if (!integer_zerop (tmp))
2748     index = fold_build2_loc (input_location, PLUS_EXPR,
2749                              gfc_array_index_type, index, tmp);
2750
2751   /* Access the calculated element.  */
2752   tmp = gfc_conv_array_data (se->expr);
2753   tmp = build_fold_indirect_ref (tmp);
2754   se->expr = gfc_build_array_ref (tmp, index, sym->backend_decl);
2755 }
2756
2757
2758 /* Generate the code to be executed immediately before entering a
2759    scalarization loop.  */
2760
2761 static void
2762 gfc_trans_preloop_setup (gfc_loopinfo * loop, int dim, int flag,
2763                          stmtblock_t * pblock)
2764 {
2765   tree index;
2766   tree stride;
2767   gfc_ss_info *info;
2768   gfc_ss *ss;
2769   gfc_se se;
2770   int i;
2771
2772   /* This code will be executed before entering the scalarization loop
2773      for this dimension.  */
2774   for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
2775     {
2776       if ((ss->useflags & flag) == 0)
2777         continue;
2778
2779       if (ss->type != GFC_SS_SECTION
2780           && ss->type != GFC_SS_FUNCTION && ss->type != GFC_SS_CONSTRUCTOR
2781           && ss->type != GFC_SS_COMPONENT)
2782         continue;
2783
2784       info = &ss->data.info;
2785
2786       if (dim >= info->dimen)
2787         continue;
2788
2789       if (dim == info->dimen - 1)
2790         {
2791           /* For the outermost loop calculate the offset due to any
2792              elemental dimensions.  It will have been initialized with the
2793              base offset of the array.  */
2794           if (info->ref)
2795             {
2796               for (i = 0; i < info->ref->u.ar.dimen; i++)
2797                 {
2798                   if (info->ref->u.ar.dimen_type[i] != DIMEN_ELEMENT)
2799                     continue;
2800
2801                   gfc_init_se (&se, NULL);
2802                   se.loop = loop;
2803                   se.expr = info->descriptor;
2804                   stride = gfc_conv_array_stride (info->descriptor, i);
2805                   index = gfc_conv_array_index_offset (&se, info, i, -1,
2806                                                        &info->ref->u.ar,
2807                                                        stride);
2808                   gfc_add_block_to_block (pblock, &se.pre);
2809
2810                   info->offset = fold_build2_loc (input_location, PLUS_EXPR,
2811                                                   gfc_array_index_type,
2812                                                   info->offset, index);
2813                   info->offset = gfc_evaluate_now (info->offset, pblock);
2814                 }
2815             }
2816
2817           i = loop->order[0];
2818           /* For the time being, the innermost loop is unconditionally on
2819              the first dimension of the scalarization loop.  */
2820           gcc_assert (i == 0);
2821           stride = gfc_conv_array_stride (info->descriptor, info->dim[i]);
2822
2823           /* Calculate the stride of the innermost loop.  Hopefully this will
2824              allow the backend optimizers to do their stuff more effectively.
2825            */
2826           info->stride0 = gfc_evaluate_now (stride, pblock);
2827         }
2828       else
2829         {
2830           /* Add the offset for the previous loop dimension.  */
2831           gfc_array_ref *ar;
2832
2833           if (info->ref)
2834             {
2835               ar = &info->ref->u.ar;
2836               i = loop->order[dim + 1];
2837             }
2838           else
2839             {
2840               ar = NULL;
2841               i = dim + 1;
2842             }
2843
2844           gfc_init_se (&se, NULL);
2845           se.loop = loop;
2846           se.expr = info->descriptor;
2847           stride = gfc_conv_array_stride (info->descriptor, info->dim[i]);
2848           index = gfc_conv_array_index_offset (&se, info, info->dim[i], i,
2849                                                ar, stride);
2850           gfc_add_block_to_block (pblock, &se.pre);
2851           info->offset = fold_build2_loc (input_location, PLUS_EXPR,
2852                                           gfc_array_index_type, info->offset,
2853                                           index);
2854           info->offset = gfc_evaluate_now (info->offset, pblock);
2855         }
2856
2857       /* Remember this offset for the second loop.  */
2858       if (dim == loop->temp_dim - 1)
2859         info->saved_offset = info->offset;
2860     }
2861 }
2862
2863
2864 /* Start a scalarized expression.  Creates a scope and declares loop
2865    variables.  */
2866
2867 void
2868 gfc_start_scalarized_body (gfc_loopinfo * loop, stmtblock_t * pbody)
2869 {
2870   int dim;
2871   int n;
2872   int flags;
2873
2874   gcc_assert (!loop->array_parameter);
2875
2876   for (dim = loop->dimen - 1; dim >= 0; dim--)
2877     {
2878       n = loop->order[dim];
2879
2880       gfc_start_block (&loop->code[n]);
2881
2882       /* Create the loop variable.  */
2883       loop->loopvar[n] = gfc_create_var (gfc_array_index_type, "S");
2884
2885       if (dim < loop->temp_dim)
2886         flags = 3;
2887       else
2888         flags = 1;
2889       /* Calculate values that will be constant within this loop.  */
2890       gfc_trans_preloop_setup (loop, dim, flags, &loop->code[n]);
2891     }
2892   gfc_start_block (pbody);
2893 }
2894
2895
2896 /* Generates the actual loop code for a scalarization loop.  */
2897
2898 void
2899 gfc_trans_scalarized_loop_end (gfc_loopinfo * loop, int n,
2900                                stmtblock_t * pbody)
2901 {
2902   stmtblock_t block;
2903   tree cond;
2904   tree tmp;
2905   tree loopbody;
2906   tree exit_label;
2907   tree stmt;
2908   tree init;
2909   tree incr;
2910
2911   if ((ompws_flags & (OMPWS_WORKSHARE_FLAG | OMPWS_SCALARIZER_WS))
2912       == (OMPWS_WORKSHARE_FLAG | OMPWS_SCALARIZER_WS)
2913       && n == loop->dimen - 1)
2914     {
2915       /* We create an OMP_FOR construct for the outermost scalarized loop.  */
2916       init = make_tree_vec (1);
2917       cond = make_tree_vec (1);
2918       incr = make_tree_vec (1);
2919
2920       /* Cycle statement is implemented with a goto.  Exit statement must not
2921          be present for this loop.  */
2922       exit_label = gfc_build_label_decl (NULL_TREE);
2923       TREE_USED (exit_label) = 1;
2924
2925       /* Label for cycle statements (if needed).  */
2926       tmp = build1_v (LABEL_EXPR, exit_label);
2927       gfc_add_expr_to_block (pbody, tmp);
2928
2929       stmt = make_node (OMP_FOR);
2930
2931       TREE_TYPE (stmt) = void_type_node;
2932       OMP_FOR_BODY (stmt) = loopbody = gfc_finish_block (pbody);
2933
2934       OMP_FOR_CLAUSES (stmt) = build_omp_clause (input_location,
2935                                                  OMP_CLAUSE_SCHEDULE);
2936       OMP_CLAUSE_SCHEDULE_KIND (OMP_FOR_CLAUSES (stmt))
2937         = OMP_CLAUSE_SCHEDULE_STATIC;
2938       if (ompws_flags & OMPWS_NOWAIT)
2939         OMP_CLAUSE_CHAIN (OMP_FOR_CLAUSES (stmt))
2940           = build_omp_clause (input_location, OMP_CLAUSE_NOWAIT);
2941
2942       /* Initialize the loopvar.  */
2943       TREE_VEC_ELT (init, 0) = build2_v (MODIFY_EXPR, loop->loopvar[n],
2944                                          loop->from[n]);
2945       OMP_FOR_INIT (stmt) = init;
2946       /* The exit condition.  */
2947       TREE_VEC_ELT (cond, 0) = build2 (LE_EXPR, boolean_type_node,
2948                                        loop->loopvar[n], loop->to[n]);
2949       OMP_FOR_COND (stmt) = cond;
2950       /* Increment the loopvar.  */
2951       tmp = build2 (PLUS_EXPR, gfc_array_index_type,
2952           loop->loopvar[n], gfc_index_one_node);
2953       TREE_VEC_ELT (incr, 0) = fold_build2_loc (input_location, MODIFY_EXPR,
2954           void_type_node, loop->loopvar[n], tmp);
2955       OMP_FOR_INCR (stmt) = incr;
2956
2957       ompws_flags &= ~OMPWS_CURR_SINGLEUNIT;
2958       gfc_add_expr_to_block (&loop->code[n], stmt);
2959     }
2960   else
2961     {
2962       bool reverse_loop = (loop->reverse[n] == GFC_REVERSE_SET)
2963                              && (loop->temp_ss == NULL);
2964
2965       loopbody = gfc_finish_block (pbody);
2966
2967       if (reverse_loop)
2968         {
2969           tmp = loop->from[n];
2970           loop->from[n] = loop->to[n];
2971           loop->to[n] = tmp;
2972         }
2973
2974       /* Initialize the loopvar.  */
2975       if (loop->loopvar[n] != loop->from[n])
2976         gfc_add_modify (&loop->code[n], loop->loopvar[n], loop->from[n]);
2977
2978       exit_label = gfc_build_label_decl (NULL_TREE);
2979
2980       /* Generate the loop body.  */
2981       gfc_init_block (&block);
2982
2983       /* The exit condition.  */
2984       cond = fold_build2_loc (input_location, reverse_loop ? LT_EXPR : GT_EXPR,
2985                           boolean_type_node, loop->loopvar[n], loop->to[n]);
2986       tmp = build1_v (GOTO_EXPR, exit_label);
2987       TREE_USED (exit_label) = 1;
2988       tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt (input_location));
2989       gfc_add_expr_to_block (&block, tmp);
2990
2991       /* The main body.  */
2992       gfc_add_expr_to_block (&block, loopbody);
2993
2994       /* Increment the loopvar.  */
2995       tmp = fold_build2_loc (input_location,
2996                              reverse_loop ? MINUS_EXPR : PLUS_EXPR,
2997                              gfc_array_index_type, loop->loopvar[n],
2998                              gfc_index_one_node);
2999
3000       gfc_add_modify (&block, loop->loopvar[n], tmp);
3001
3002       /* Build the loop.  */
3003       tmp = gfc_finish_block (&block);
3004       tmp = build1_v (LOOP_EXPR, tmp);
3005       gfc_add_expr_to_block (&loop->code[n], tmp);
3006
3007       /* Add the exit label.  */
3008       tmp = build1_v (LABEL_EXPR, exit_label);
3009       gfc_add_expr_to_block (&loop->code[n], tmp);
3010     }
3011
3012 }
3013
3014
3015 /* Finishes and generates the loops for a scalarized expression.  */
3016
3017 void
3018 gfc_trans_scalarizing_loops (gfc_loopinfo * loop, stmtblock_t * body)
3019 {
3020   int dim;
3021   int n;
3022   gfc_ss *ss;
3023   stmtblock_t *pblock;
3024   tree tmp;
3025
3026   pblock = body;
3027   /* Generate the loops.  */
3028   for (dim = 0; dim < loop->dimen; dim++)
3029     {
3030       n = loop->order[dim];
3031       gfc_trans_scalarized_loop_end (loop, n, pblock);
3032       loop->loopvar[n] = NULL_TREE;
3033       pblock = &loop->code[n];
3034     }
3035
3036   tmp = gfc_finish_block (pblock);
3037   gfc_add_expr_to_block (&loop->pre, tmp);
3038
3039   /* Clear all the used flags.  */
3040   for (ss = loop->ss; ss; ss = ss->loop_chain)
3041     ss->useflags = 0;
3042 }
3043
3044
3045 /* Finish the main body of a scalarized expression, and start the secondary
3046    copying body.  */
3047
3048 void
3049 gfc_trans_scalarized_loop_boundary (gfc_loopinfo * loop, stmtblock_t * body)
3050 {
3051   int dim;
3052   int n;
3053   stmtblock_t *pblock;
3054   gfc_ss *ss;
3055
3056   pblock = body;
3057   /* We finish as many loops as are used by the temporary.  */
3058   for (dim = 0; dim < loop->temp_dim - 1; dim++)
3059     {
3060       n = loop->order[dim];
3061       gfc_trans_scalarized_loop_end (loop, n, pblock);
3062       loop->loopvar[n] = NULL_TREE;
3063       pblock = &loop->code[n];
3064     }
3065
3066   /* We don't want to finish the outermost loop entirely.  */
3067   n = loop->order[loop->temp_dim - 1];
3068   gfc_trans_scalarized_loop_end (loop, n, pblock);
3069
3070   /* Restore the initial offsets.  */
3071   for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
3072     {
3073       if ((ss->useflags & 2) == 0)
3074         continue;
3075
3076       if (ss->type != GFC_SS_SECTION
3077           && ss->type != GFC_SS_FUNCTION && ss->type != GFC_SS_CONSTRUCTOR
3078           && ss->type != GFC_SS_COMPONENT)
3079         continue;
3080
3081       ss->data.info.offset = ss->data.info.saved_offset;
3082     }
3083
3084   /* Restart all the inner loops we just finished.  */
3085   for (dim = loop->temp_dim - 2; dim >= 0; dim--)
3086     {
3087       n = loop->order[dim];
3088
3089       gfc_start_block (&loop->code[n]);
3090
3091       loop->loopvar[n] = gfc_create_var (gfc_array_index_type, "Q");
3092
3093       gfc_trans_preloop_setup (loop, dim, 2, &loop->code[n]);
3094     }
3095
3096   /* Start a block for the secondary copying code.  */
3097   gfc_start_block (body);
3098 }
3099
3100
3101 /* Calculate the lower bound of an array section.  */
3102
3103 static void
3104 gfc_conv_section_startstride (gfc_loopinfo * loop, gfc_ss * ss, int dim)
3105 {
3106   gfc_expr *start;
3107   gfc_expr *end;
3108   gfc_expr *stride;
3109   tree desc;
3110   gfc_se se;
3111   gfc_ss_info *info;
3112
3113   gcc_assert (ss->type == GFC_SS_SECTION);
3114
3115   info = &ss->data.info;
3116
3117   if (info->ref->u.ar.dimen_type[dim] == DIMEN_VECTOR)
3118     {
3119       /* We use a zero-based index to access the vector.  */
3120       info->start[dim] = gfc_index_zero_node;
3121       info->stride[dim] = gfc_index_one_node;
3122       info->end[dim] = NULL;
3123       return;
3124     }
3125
3126   gcc_assert (info->ref->u.ar.dimen_type[dim] == DIMEN_RANGE);
3127   desc = info->descriptor;
3128   start = info->ref->u.ar.start[dim];
3129   end = info->ref->u.ar.end[dim];
3130   stride = info->ref->u.ar.stride[dim];
3131
3132   /* Calculate the start of the range.  For vector subscripts this will
3133      be the range of the vector.  */
3134   if (start)
3135     {
3136       /* Specified section start.  */
3137       gfc_init_se (&se, NULL);
3138       gfc_conv_expr_type (&se, start, gfc_array_index_type);
3139       gfc_add_block_to_block (&loop->pre, &se.pre);
3140       info->start[dim] = se.expr;
3141     }
3142   else
3143     {
3144       /* No lower bound specified so use the bound of the array.  */
3145       info->start[dim] = gfc_conv_array_lbound (desc, dim);
3146     }
3147   info->start[dim] = gfc_evaluate_now (info->start[dim], &loop->pre);
3148
3149   /* Similarly calculate the end.  Although this is not used in the
3150      scalarizer, it is needed when checking bounds and where the end
3151      is an expression with side-effects.  */
3152   if (end)
3153     {
3154       /* Specified section start.  */
3155       gfc_init_se (&se, NULL);
3156       gfc_conv_expr_type (&se, end, gfc_array_index_type);
3157       gfc_add_block_to_block (&loop->pre, &se.pre);
3158       info->end[dim] = se.expr;
3159     }
3160   else
3161     {
3162       /* No upper bound specified so use the bound of the array.  */
3163       info->end[dim] = gfc_conv_array_ubound (desc, dim);
3164     }
3165   info->end[dim] = gfc_evaluate_now (info->end[dim], &loop->pre);
3166
3167   /* Calculate the stride.  */
3168   if (stride == NULL)
3169     info->stride[dim] = gfc_index_one_node;
3170   else
3171     {
3172       gfc_init_se (&se, NULL);
3173       gfc_conv_expr_type (&se, stride, gfc_array_index_type);
3174       gfc_add_block_to_block (&loop->pre, &se.pre);
3175       info->stride[dim] = gfc_evaluate_now (se.expr, &loop->pre);
3176     }
3177 }
3178
3179
3180 /* Calculates the range start and stride for a SS chain.  Also gets the
3181    descriptor and data pointer.  The range of vector subscripts is the size
3182    of the vector.  Array bounds are also checked.  */
3183
3184 void
3185 gfc_conv_ss_startstride (gfc_loopinfo * loop)
3186 {
3187   int n;
3188   tree tmp;
3189   gfc_ss *ss;
3190   tree desc;
3191
3192   loop->dimen = 0;
3193   /* Determine the rank of the loop.  */
3194   for (ss = loop->ss;
3195        ss != gfc_ss_terminator && loop->dimen == 0; ss = ss->loop_chain)
3196     {
3197       switch (ss->type)
3198         {
3199         case GFC_SS_SECTION:
3200         case GFC_SS_CONSTRUCTOR:
3201         case GFC_SS_FUNCTION:
3202         case GFC_SS_COMPONENT:
3203           loop->dimen = ss->data.info.dimen;
3204           break;
3205
3206         /* As usual, lbound and ubound are exceptions!.  */
3207         case GFC_SS_INTRINSIC:
3208           switch (ss->expr->value.function.isym->id)
3209             {
3210             case GFC_ISYM_LBOUND:
3211             case GFC_ISYM_UBOUND:
3212               loop->dimen = ss->data.info.dimen;
3213
3214             default:
3215               break;
3216             }
3217
3218         default:
3219           break;
3220         }
3221     }
3222
3223   /* We should have determined the rank of the expression by now.  If
3224      not, that's bad news.  */
3225   gcc_assert (loop->dimen != 0);
3226
3227   /* Loop over all the SS in the chain.  */
3228   for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
3229     {
3230       if (ss->expr && ss->expr->shape && !ss->shape)
3231         ss->shape = ss->expr->shape;
3232
3233       switch (ss->type)
3234         {
3235         case GFC_SS_SECTION:
3236           /* Get the descriptor for the array.  */
3237           gfc_conv_ss_descriptor (&loop->pre, ss, !loop->array_parameter);
3238
3239           for (n = 0; n < ss->data.info.dimen; n++)
3240             gfc_conv_section_startstride (loop, ss, ss->data.info.dim[n]);
3241           break;
3242
3243         case GFC_SS_INTRINSIC:
3244           switch (ss->expr->value.function.isym->id)
3245             {
3246             /* Fall through to supply start and stride.  */
3247             case GFC_ISYM_LBOUND:
3248             case GFC_ISYM_UBOUND:
3249               break;
3250             default:
3251               continue;
3252             }
3253
3254         case GFC_SS_CONSTRUCTOR:
3255         case GFC_SS_FUNCTION:
3256           for (n = 0; n < ss->data.info.dimen; n++)
3257             {
3258               ss->data.info.start[n] = gfc_index_zero_node;
3259               ss->data.info.end[n] = gfc_index_zero_node;
3260               ss->data.info.stride[n] = gfc_index_one_node;
3261             }
3262           break;
3263
3264         default:
3265           break;
3266         }
3267     }
3268
3269   /* The rest is just runtime bound checking.  */
3270   if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
3271     {
3272       stmtblock_t block;
3273       tree lbound, ubound;
3274       tree end;
3275       tree size[GFC_MAX_DIMENSIONS];
3276       tree stride_pos, stride_neg, non_zerosized, tmp2, tmp3;
3277       gfc_ss_info *info;
3278       char *msg;
3279       int dim;
3280
3281       gfc_start_block (&block);
3282
3283       for (n = 0; n < loop->dimen; n++)
3284         size[n] = NULL_TREE;
3285
3286       for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
3287         {
3288           stmtblock_t inner;
3289
3290           if (ss->type != GFC_SS_SECTION)
3291             continue;
3292
3293           gfc_start_block (&inner);
3294
3295           /* TODO: range checking for mapped dimensions.  */
3296           info = &ss->data.info;
3297
3298           /* This code only checks ranges.  Elemental and vector
3299              dimensions are checked later.  */
3300           for (n = 0; n < loop->dimen; n++)
3301             {
3302               bool check_upper;
3303
3304               dim = info->dim[n];
3305               if (info->ref->u.ar.dimen_type[dim] != DIMEN_RANGE)
3306                 continue;
3307
3308               if (dim == info->ref->u.ar.dimen - 1
3309                   && info->ref->u.ar.as->type == AS_ASSUMED_SIZE)
3310                 check_upper = false;
3311               else
3312                 check_upper = true;
3313
3314               /* Zero stride is not allowed.  */
3315               tmp = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
3316                                      info->stride[dim], gfc_index_zero_node);
3317               asprintf (&msg, "Zero stride is not allowed, for dimension %d "
3318                         "of array '%s'", dim + 1, ss->expr->symtree->name);
3319               gfc_trans_runtime_check (true, false, tmp, &inner,
3320                                        &ss->expr->where, msg);
3321               gfc_free (msg);
3322
3323               desc = ss->data.info.descriptor;
3324
3325               /* This is the run-time equivalent of resolve.c's
3326                  check_dimension().  The logical is more readable there
3327                  than it is here, with all the trees.  */
3328               lbound = gfc_conv_array_lbound (desc, dim);
3329               end = info->end[dim];
3330               if (check_upper)
3331                 ubound = gfc_conv_array_ubound (desc, dim);
3332               else
3333                 ubound = NULL;
3334
3335               /* non_zerosized is true when the selected range is not
3336                  empty.  */
3337               stride_pos = fold_build2_loc (input_location, GT_EXPR,
3338                                         boolean_type_node, info->stride[dim],
3339                                         gfc_index_zero_node);
3340               tmp = fold_build2_loc (input_location, LE_EXPR, boolean_type_node,
3341                                      info->start[dim], end);
3342               stride_pos = fold_build2_loc (input_location, TRUTH_AND_EXPR,
3343                                             boolean_type_node, stride_pos, tmp);
3344
3345               stride_neg = fold_build2_loc (input_location, LT_EXPR,
3346                                      boolean_type_node,
3347                                      info->stride[dim], gfc_index_zero_node);
3348               tmp = fold_build2_loc (input_location, GE_EXPR, boolean_type_node,
3349                                      info->start[dim], end);
3350               stride_neg = fold_build2_loc (input_location, TRUTH_AND_EXPR,
3351                                             boolean_type_node,
3352                                             stride_neg, tmp);
3353               non_zerosized = fold_build2_loc (input_location, TRUTH_OR_EXPR,
3354                                                boolean_type_node,
3355                                                stride_pos, stride_neg);
3356
3357               /* Check the start of the range against the lower and upper
3358                  bounds of the array, if the range is not empty. 
3359                  If upper bound is present, include both bounds in the 
3360                  error message.  */
3361               if (check_upper)
3362                 {
3363                   tmp = fold_build2_loc (input_location, LT_EXPR,
3364                                          boolean_type_node,
3365                                          info->start[dim], lbound);
3366                   tmp = fold_build2_loc (input_location, TRUTH_AND_EXPR,
3367                                          boolean_type_node,
3368                                          non_zerosized, tmp);
3369                   tmp2 = fold_build2_loc (input_location, GT_EXPR,
3370                                           boolean_type_node,
3371                                           info->start[dim], ubound);
3372                   tmp2 = fold_build2_loc (input_location, TRUTH_AND_EXPR,
3373                                           boolean_type_node,
3374                                           non_zerosized, tmp2);
3375                   asprintf (&msg, "Index '%%ld' of dimension %d of array '%s' "
3376                             "outside of expected range (%%ld:%%ld)",
3377                             dim + 1, ss->expr->symtree->name);
3378                   gfc_trans_runtime_check (true, false, tmp, &inner,
3379                                            &ss->expr->where, msg,
3380                      fold_convert (long_integer_type_node, info->start[dim]),
3381                      fold_convert (long_integer_type_node, lbound),
3382                      fold_convert (long_integer_type_node, ubound));
3383                   gfc_trans_runtime_check (true, false, tmp2, &inner,
3384                                            &ss->expr->where, msg,
3385                      fold_convert (long_integer_type_node, info->start[dim]),
3386                      fold_convert (long_integer_type_node, lbound),
3387                      fold_convert (long_integer_type_node, ubound));
3388                   gfc_free (msg);
3389                 }
3390               else
3391                 {
3392                   tmp = fold_build2_loc (input_location, LT_EXPR,
3393                                          boolean_type_node,
3394                                          info->start[dim], lbound);
3395                   tmp = fold_build2_loc (input_location, TRUTH_AND_EXPR,
3396                                          boolean_type_node, non_zerosized, tmp);
3397                   asprintf (&msg, "Index '%%ld' of dimension %d of array '%s' "
3398                             "below lower bound of %%ld",
3399                             dim + 1, ss->expr->symtree->name);
3400                   gfc_trans_runtime_check (true, false, tmp, &inner,
3401                                            &ss->expr->where, msg,
3402                      fold_convert (long_integer_type_node, info->start[dim]),
3403                      fold_convert (long_integer_type_node, lbound));
3404                   gfc_free (msg);
3405                 }
3406               
3407               /* Compute the last element of the range, which is not
3408                  necessarily "end" (think 0:5:3, which doesn't contain 5)
3409                  and check it against both lower and upper bounds.  */
3410
3411               tmp = fold_build2_loc (input_location, MINUS_EXPR,
3412                                      gfc_array_index_type, end,
3413                                      info->start[dim]);
3414               tmp = fold_build2_loc (input_location, TRUNC_MOD_EXPR,
3415                                      gfc_array_index_type, tmp,
3416                                      info->stride[dim]);
3417               tmp = fold_build2_loc (input_location, MINUS_EXPR,
3418                                      gfc_array_index_type, end, tmp);
3419               tmp2 = fold_build2_loc (input_location, LT_EXPR,
3420                                       boolean_type_node, tmp, lbound);
3421               tmp2 = fold_build2_loc (input_location, TRUTH_AND_EXPR,
3422                                       boolean_type_node, non_zerosized, tmp2);
3423               if (check_upper)
3424                 {
3425                   tmp3 = fold_build2_loc (input_location, GT_EXPR,
3426                                           boolean_type_node, tmp, ubound);
3427                   tmp3 = fold_build2_loc (input_location, TRUTH_AND_EXPR,
3428                                           boolean_type_node, non_zerosized, tmp3);
3429                   asprintf (&msg, "Index '%%ld' of dimension %d of array '%s' "
3430                             "outside of expected range (%%ld:%%ld)",
3431                             dim + 1, ss->expr->symtree->name);
3432                   gfc_trans_runtime_check (true, false, tmp2, &inner,
3433                                            &ss->expr->where, msg,
3434                      fold_convert (long_integer_type_node, tmp),
3435                      fold_convert (long_integer_type_node, ubound), 
3436                      fold_convert (long_integer_type_node, lbound));
3437                   gfc_trans_runtime_check (true, false, tmp3, &inner,
3438                                            &ss->expr->where, msg,
3439                      fold_convert (long_integer_type_node, tmp),
3440                      fold_convert (long_integer_type_node, ubound), 
3441                      fold_convert (long_integer_type_node, lbound));
3442                   gfc_free (msg);
3443                 }
3444               else
3445                 {
3446                   asprintf (&msg, "Index '%%ld' of dimension %d of array '%s' "
3447                             "below lower bound of %%ld",
3448                             dim + 1, ss->expr->symtree->name);
3449                   gfc_trans_runtime_check (true, false, tmp2, &inner,
3450                                            &ss->expr->where, msg,
3451                      fold_convert (long_integer_type_node, tmp),
3452                      fold_convert (long_integer_type_node, lbound));
3453                   gfc_free (msg);
3454                 }
3455
3456               /* Check the section sizes match.  */
3457               tmp = fold_build2_loc (input_location, MINUS_EXPR,
3458                                      gfc_array_index_type, end,
3459                                      info->start[dim]);
3460               tmp = fold_build2_loc (input_location, FLOOR_DIV_EXPR,
3461                                      gfc_array_index_type, tmp,
3462                                      info->stride[dim]);
3463               tmp = fold_build2_loc (input_location, PLUS_EXPR,
3464                                      gfc_array_index_type,
3465                                      gfc_index_one_node, tmp);
3466               tmp = fold_build2_loc (input_location, MAX_EXPR,
3467                                      gfc_array_index_type, tmp,
3468                                      build_int_cst (gfc_array_index_type, 0));
3469               /* We remember the size of the first section, and check all the
3470                  others against this.  */
3471               if (size[n])
3472                 {
3473                   tmp3 = fold_build2_loc (input_location, NE_EXPR,
3474                                           boolean_type_node, tmp, size[n]);
3475                   asprintf (&msg, "Array bound mismatch for dimension %d "
3476                             "of array '%s' (%%ld/%%ld)",
3477                             dim + 1, ss->expr->symtree->name);
3478
3479                   gfc_trans_runtime_check (true, false, tmp3, &inner,
3480                                            &ss->expr->where, msg,
3481                         fold_convert (long_integer_type_node, tmp),
3482                         fold_convert (long_integer_type_node, size[n]));
3483
3484                   gfc_free (msg);
3485                 }
3486               else
3487                 size[n] = gfc_evaluate_now (tmp, &inner);
3488             }
3489
3490           tmp = gfc_finish_block (&inner);
3491
3492           /* For optional arguments, only check bounds if the argument is
3493              present.  */
3494           if (ss->expr->symtree->n.sym->attr.optional
3495               || ss->expr->symtree->n.sym->attr.not_always_present)
3496             tmp = build3_v (COND_EXPR,
3497                             gfc_conv_expr_present (ss->expr->symtree->n.sym),
3498                             tmp, build_empty_stmt (input_location));
3499
3500           gfc_add_expr_to_block (&block, tmp);
3501
3502         }
3503
3504       tmp = gfc_finish_block (&block);
3505       gfc_add_expr_to_block (&loop->pre, tmp);
3506     }
3507 }
3508
3509
3510 /* Return true if the two SS could be aliased, i.e. both point to the same data
3511    object.  */
3512 /* TODO: resolve aliases based on frontend expressions.  */
3513
3514 static int
3515 gfc_could_be_alias (gfc_ss * lss, gfc_ss * rss)
3516 {
3517   gfc_ref *lref;
3518   gfc_ref *rref;
3519   gfc_symbol *lsym;
3520   gfc_symbol *rsym;
3521
3522   lsym = lss->expr->symtree->n.sym;
3523   rsym = rss->expr->symtree->n.sym;
3524   if (gfc_symbols_could_alias (lsym, rsym))
3525     return 1;
3526
3527   if (rsym->ts.type != BT_DERIVED
3528       && lsym->ts.type != BT_DERIVED)
3529     return 0;
3530
3531   /* For derived types we must check all the component types.  We can ignore
3532      array references as these will have the same base type as the previous
3533      component ref.  */
3534   for (lref = lss->expr->ref; lref != lss->data.info.ref; lref = lref->next)
3535     {
3536       if (lref->type != REF_COMPONENT)
3537         continue;
3538
3539       if (gfc_symbols_could_alias (lref->u.c.sym, rsym))
3540         return 1;
3541
3542       for (rref = rss->expr->ref; rref != rss->data.info.ref;
3543            rref = rref->next)
3544         {
3545           if (rref->type != REF_COMPONENT)
3546             continue;
3547
3548           if (gfc_symbols_could_alias (lref->u.c.sym, rref->u.c.sym))
3549             return 1;
3550         }
3551     }
3552
3553   for (rref = rss->expr->ref; rref != rss->data.info.ref; rref = rref->next)
3554     {
3555       if (rref->type != REF_COMPONENT)
3556         break;
3557
3558       if (gfc_symbols_could_alias (rref->u.c.sym, lsym))
3559         return 1;
3560     }
3561
3562   return 0;
3563 }
3564
3565
3566 /* Resolve array data dependencies.  Creates a temporary if required.  */
3567 /* TODO: Calc dependencies with gfc_expr rather than gfc_ss, and move to
3568    dependency.c.  */
3569
3570 void
3571 gfc_conv_resolve_dependencies (gfc_loopinfo * loop, gfc_ss * dest,
3572                                gfc_ss * rss)
3573 {
3574   gfc_ss *ss;
3575   gfc_ref *lref;
3576   gfc_ref *rref;
3577   int nDepend = 0;
3578
3579   loop->temp_ss = NULL;
3580
3581   for (ss = rss; ss != gfc_ss_terminator; ss = ss->next)
3582     {
3583       if (ss->type != GFC_SS_SECTION)
3584         continue;
3585
3586       if (dest->expr->symtree->n.sym != ss->expr->symtree->n.sym)
3587         {
3588           if (gfc_could_be_alias (dest, ss)
3589                 || gfc_are_equivalenced_arrays (dest->expr, ss->expr))
3590             {
3591               nDepend = 1;
3592               break;
3593             }
3594         }
3595       else
3596         {
3597           lref = dest->expr->ref;
3598           rref = ss->expr->ref;
3599
3600           nDepend = gfc_dep_resolver (lref, rref, &loop->reverse[0]);
3601
3602           if (nDepend == 1)
3603             break;
3604 #if 0
3605           /* TODO : loop shifting.  */
3606           if (nDepend == 1)
3607             {
3608               /* Mark the dimensions for LOOP SHIFTING */
3609               for (n = 0; n < loop->dimen; n++)
3610                 {
3611                   int dim = dest->data.info.dim[n];
3612
3613                   if (lref->u.ar.dimen_type[dim] == DIMEN_VECTOR)
3614                     depends[n] = 2;
3615                   else if (! gfc_is_same_range (&lref->u.ar,
3616                                                 &rref->u.ar, dim, 0))
3617                     depends[n] = 1;
3618                  }
3619
3620               /* Put all the dimensions with dependencies in the
3621                  innermost loops.  */
3622               dim = 0;
3623               for (n = 0; n < loop->dimen; n++)
3624                 {
3625                   gcc_assert (loop->order[n] == n);
3626                   if (depends[n])
3627                   loop->order[dim++] = n;
3628                 }
3629               for (n = 0; n < loop->dimen; n++)
3630                 {
3631                   if (! depends[n])
3632                   loop->order[dim++] = n;
3633                 }
3634
3635               gcc_assert (dim == loop->dimen);
3636               break;
3637             }
3638 #endif
3639         }
3640     }
3641
3642   if (nDepend == 1)
3643     {
3644       tree base_type = gfc_typenode_for_spec (&dest->expr->ts);
3645       if (GFC_ARRAY_TYPE_P (base_type)
3646           || GFC_DESCRIPTOR_TYPE_P (base_type))
3647         base_type = gfc_get_element_type (base_type);
3648       loop->temp_ss = gfc_get_ss ();
3649       loop->temp_ss->type = GFC_SS_TEMP;
3650       loop->temp_ss->data.temp.type = base_type;
3651       loop->temp_ss->string_length = dest->string_length;
3652       loop->temp_ss->data.temp.dimen = loop->dimen;
3653       loop->temp_ss->next = gfc_ss_terminator;
3654       gfc_add_ss_to_loop (loop, loop->temp_ss);
3655     }
3656   else
3657     loop->temp_ss = NULL;
3658 }
3659
3660
3661 /* Initialize the scalarization loop.  Creates the loop variables.  Determines
3662    the range of the loop variables.  Creates a temporary if required.
3663    Calculates how to transform from loop variables to array indices for each
3664    expression.  Also generates code for scalar expressions which have been
3665    moved outside the loop.  */
3666
3667 void
3668 gfc_conv_loop_setup (gfc_loopinfo * loop, locus * where)
3669 {
3670   int n, dim, spec_dim;
3671   gfc_ss_info *info;
3672   gfc_ss_info *specinfo;
3673   gfc_ss *ss;
3674   tree tmp;
3675   gfc_ss *loopspec[GFC_MAX_DIMENSIONS];
3676   bool dynamic[GFC_MAX_DIMENSIONS];
3677   mpz_t *cshape;
3678   mpz_t i;
3679
3680   mpz_init (i);
3681   for (n = 0; n < loop->dimen; n++)
3682     {
3683       loopspec[n] = NULL;
3684       dynamic[n] = false;
3685       /* We use one SS term, and use that to determine the bounds of the
3686          loop for this dimension.  We try to pick the simplest term.  */
3687       for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
3688         {
3689           if (ss->type == GFC_SS_SCALAR || ss->type == GFC_SS_REFERENCE)
3690             continue;
3691
3692           info = &ss->data.info;
3693           dim = info->dim[n];
3694
3695           if (loopspec[n] != NULL)
3696             {
3697               specinfo = &loopspec[n]->data.info;
3698               spec_dim = specinfo->dim[n];
3699             }
3700           else
3701             {
3702               /* Silence unitialized warnings.  */
3703               specinfo = NULL;
3704               spec_dim = 0;
3705             }
3706
3707           if (ss->shape)
3708             {
3709               gcc_assert (ss->shape[dim]);
3710               /* The frontend has worked out the size for us.  */
3711               if (!loopspec[n]
3712                   || !loopspec[n]->shape
3713                   || !integer_zerop (specinfo->start[spec_dim]))
3714                 /* Prefer zero-based descriptors if possible.  */
3715                 loopspec[n] = ss;
3716               continue;
3717             }
3718
3719           if (ss->type == GFC_SS_CONSTRUCTOR)
3720             {
3721               gfc_constructor_base base;
3722               /* An unknown size constructor will always be rank one.
3723                  Higher rank constructors will either have known shape,
3724                  or still be wrapped in a call to reshape.  */
3725               gcc_assert (loop->dimen == 1);
3726
3727               /* Always prefer to use the constructor bounds if the size
3728                  can be determined at compile time.  Prefer not to otherwise,
3729                  since the general case involves realloc, and it's better to
3730                  avoid that overhead if possible.  */
3731               base = ss->expr->value.constructor;
3732               dynamic[n] = gfc_get_array_constructor_size (&i, base);
3733               if (!dynamic[n] || !loopspec[n])
3734                 loopspec[n] = ss;
3735               continue;
3736             }
3737
3738           /* TODO: Pick the best bound if we have a choice between a
3739              function and something else.  */
3740           if (ss->type == GFC_SS_FUNCTION)
3741             {
3742               loopspec[n] = ss;
3743               continue;
3744             }
3745
3746           if (ss->type != GFC_SS_SECTION)
3747             continue;
3748
3749           if (!loopspec[n])
3750             loopspec[n] = ss;
3751           /* Criteria for choosing a loop specifier (most important first):
3752              doesn't need realloc
3753              stride of one
3754              known stride
3755              known lower bound
3756              known upper bound
3757            */
3758           else if (loopspec[n]->type == GFC_SS_CONSTRUCTOR && dynamic[n])
3759             loopspec[n] = ss;
3760           else if (integer_onep (info->stride[dim])
3761                    && !integer_onep (specinfo->stride[spec_dim]))
3762             loopspec[n] = ss;
3763           else if (INTEGER_CST_P (info->stride[dim])
3764                    && !INTEGER_CST_P (specinfo->stride[spec_dim]))
3765             loopspec[n] = ss;
3766           else if (INTEGER_CST_P (info->start[dim])
3767                    && !INTEGER_CST_P (specinfo->start[spec_dim]))
3768             loopspec[n] = ss;
3769           /* We don't work out the upper bound.
3770              else if (INTEGER_CST_P (info->finish[n])
3771              && ! INTEGER_CST_P (specinfo->finish[n]))
3772              loopspec[n] = ss; */
3773         }
3774
3775       /* We should have found the scalarization loop specifier.  If not,
3776          that's bad news.  */
3777       gcc_assert (loopspec[n]);
3778
3779       info = &loopspec[n]->data.info;
3780       dim = info->dim[n];
3781
3782       /* Set the extents of this range.  */
3783       cshape = loopspec[n]->shape;
3784       if (cshape && INTEGER_CST_P (info->start[dim])
3785           && INTEGER_CST_P (info->stride[dim]))
3786         {
3787           loop->from[n] = info->start[dim];
3788           mpz_set (i, cshape[n]);
3789           mpz_sub_ui (i, i, 1);
3790           /* To = from + (size - 1) * stride.  */
3791           tmp = gfc_conv_mpz_to_tree (i, gfc_index_integer_kind);
3792           if (!integer_onep (info->stride[dim]))
3793             tmp = fold_build2_loc (input_location, MULT_EXPR,
3794                                    gfc_array_index_type, tmp,
3795                                    info->stride[dim]);
3796           loop->to[n] = fold_build2_loc (input_location, PLUS_EXPR,
3797                                          gfc_array_index_type,
3798                                          loop->from[n], tmp);
3799         }
3800       else
3801         {
3802           loop->from[n] = info->start[dim];
3803           switch (loopspec[n]->type)
3804             {
3805             case GFC_SS_CONSTRUCTOR:
3806               /* The upper bound is calculated when we expand the
3807                  constructor.  */
3808               gcc_assert (loop->to[n] == NULL_TREE);
3809               break;
3810
3811             case GFC_SS_SECTION:
3812               /* Use the end expression if it exists and is not constant,
3813                  so that it is only evaluated once.  */
3814               loop->to[n] = info->end[dim];
3815               break;
3816
3817             case GFC_SS_FUNCTION:
3818               /* The loop bound will be set when we generate the call.  */
3819               gcc_assert (loop->to[n] == NULL_TREE);
3820               break;
3821
3822             default:
3823               gcc_unreachable ();
3824             }
3825         }
3826
3827       /* Transform everything so we have a simple incrementing variable.  */
3828       if (integer_onep (info->stride[dim]))
3829         info->delta[dim] = gfc_index_zero_node;
3830       else
3831         {
3832           /* Set the delta for this section.  */
3833           info->delta[dim] = gfc_evaluate_now (loop->from[n], &loop->pre);
3834           /* Number of iterations is (end - start + step) / step.
3835              with start = 0, this simplifies to
3836              last = end / step;
3837              for (i = 0; i<=last; i++){...};  */
3838           tmp = fold_build2_loc (input_location, MINUS_EXPR,
3839                                  gfc_array_index_type, loop->to[n],
3840                                  loop->from[n]);
3841           tmp = fold_build2_loc (input_location, FLOOR_DIV_EXPR,
3842                                  gfc_array_index_type, tmp, info->stride[dim]);
3843           tmp = fold_build2_loc (input_location, MAX_EXPR, gfc_array_index_type,
3844                                  tmp, build_int_cst (gfc_array_index_type, -1));
3845           loop->to[n] = gfc_evaluate_now (tmp, &loop->pre);
3846           /* Make the loop variable start at 0.  */
3847           loop->from[n] = gfc_index_zero_node;
3848         }
3849     }
3850
3851   /* Add all the scalar code that can be taken out of the loops.
3852      This may include calculating the loop bounds, so do it before
3853      allocating the temporary.  */
3854   gfc_add_loop_ss_code (loop, loop->ss, false, where);
3855
3856   /* If we want a temporary then create it.  */
3857   if (loop->temp_ss != NULL)
3858     {
3859       gcc_assert (loop->temp_ss->type == GFC_SS_TEMP);
3860
3861       /* Make absolutely sure that this is a complete type.  */
3862       if (loop->temp_ss->string_length)
3863         loop->temp_ss->data.temp.type
3864                 = gfc_get_character_type_len_for_eltype
3865                         (TREE_TYPE (loop->temp_ss->data.temp.type),
3866                          loop->temp_ss->string_length);
3867
3868       tmp = loop->temp_ss->data.temp.type;
3869       n = loop->temp_ss->data.temp.dimen;
3870       memset (&loop->temp_ss->data.info, 0, sizeof (gfc_ss_info));
3871       loop->temp_ss->type = GFC_SS_SECTION;
3872       loop->temp_ss->data.info.dimen = n;
3873
3874       gcc_assert (loop->temp_ss->data.info.dimen != 0);
3875       for (n = 0; n < loop->temp_ss->data.info.dimen; n++)
3876         loop->temp_ss->data.info.dim[n] = n;
3877
3878       gfc_trans_create_temp_array (&loop->pre, &loop->post, loop,
3879                                    &loop->temp_ss->data.info, tmp, NULL_TREE,
3880                                    false, true, false, where);
3881     }
3882
3883   for (n = 0; n < loop->temp_dim; n++)
3884     loopspec[loop->order[n]] = NULL;
3885
3886   mpz_clear (i);
3887
3888   /* For array parameters we don't have loop variables, so don't calculate the
3889      translations.  */
3890   if (loop->array_parameter)
3891     return;
3892
3893   /* Calculate the translation from loop variables to array indices.  */
3894   for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
3895     {
3896       if (ss->type != GFC_SS_SECTION && ss->type != GFC_SS_COMPONENT
3897             && ss->type != GFC_SS_CONSTRUCTOR)
3898
3899         continue;
3900
3901       info = &ss->data.info;
3902
3903       for (n = 0; n < info->dimen; n++)
3904         {
3905           /* If we are specifying the range the delta is already set.  */
3906           if (loopspec[n] != ss)
3907             {
3908               dim = ss->data.info.dim[n];
3909
3910               /* Calculate the offset relative to the loop variable.
3911                  First multiply by the stride.  */
3912               tmp = loop->from[n];
3913               if (!integer_onep (info->stride[dim]))
3914                 tmp = fold_build2_loc (input_location, MULT_EXPR,
3915                                        gfc_array_index_type,
3916                                        tmp, info->stride[dim]);
3917
3918               /* Then subtract this from our starting value.  */
3919               tmp = fold_build2_loc (input_location, MINUS_EXPR,
3920                                      gfc_array_index_type,
3921                                      info->start[dim], tmp);
3922
3923               info->delta[dim] = gfc_evaluate_now (tmp, &loop->pre);
3924             }
3925         }
3926     }
3927 }
3928
3929
3930 /* Calculate the size of a given array dimension from the bounds.  This
3931    is simply (ubound - lbound + 1) if this expression is positive
3932    or 0 if it is negative (pick either one if it is zero).  Optionally
3933    (if or_expr is present) OR the (expression != 0) condition to it.  */
3934
3935 tree
3936 gfc_conv_array_extent_dim (tree lbound, tree ubound, tree* or_expr)
3937 {
3938   tree res;
3939   tree cond;
3940
3941   /* Calculate (ubound - lbound + 1).  */
3942   res = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
3943                          ubound, lbound);
3944   res = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type, res,
3945                          gfc_index_one_node);
3946
3947   /* Check whether the size for this dimension is negative.  */
3948   cond = fold_build2_loc (input_location, LE_EXPR, boolean_type_node, res,
3949                           gfc_index_zero_node);
3950   res = fold_build3_loc (input_location, COND_EXPR, gfc_array_index_type, cond,
3951                          gfc_index_zero_node, res);
3952
3953   /* Build OR expression.  */
3954   if (or_expr)
3955     *or_expr = fold_build2_loc (input_location, TRUTH_OR_EXPR,
3956                                 boolean_type_node, *or_expr, cond);
3957
3958   return res;
3959 }
3960
3961
3962 /* For an array descriptor, get the total number of elements.  This is just
3963    the product of the extents along all dimensions.  */
3964
3965 tree
3966 gfc_conv_descriptor_size (tree desc, int rank)
3967 {
3968   tree res;
3969   int dim;
3970
3971   res = gfc_index_one_node;
3972
3973   for (dim = 0; dim < rank; ++dim)
3974     {
3975       tree lbound;
3976       tree ubound;
3977       tree extent;
3978
3979       lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[dim]);
3980       ubound = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[dim]);
3981
3982       extent = gfc_conv_array_extent_dim (lbound, ubound, NULL);
3983       res = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
3984                              res, extent);
3985     }
3986
3987   return res;
3988 }
3989
3990
3991 /* Fills in an array descriptor, and returns the size of the array.  The size
3992    will be a simple_val, ie a variable or a constant.  Also calculates the
3993    offset of the base.  Returns the size of the array.
3994    {
3995     stride = 1;
3996     offset = 0;
3997     for (n = 0; n < rank; n++)
3998       {
3999         a.lbound[n] = specified_lower_bound;
4000         offset = offset + a.lbond[n] * stride;
4001         size = 1 - lbound;
4002         a.ubound[n] = specified_upper_bound;
4003         a.stride[n] = stride;
4004         size = siz >= 0 ? ubound + size : 0; //size = ubound + 1 - lbound
4005         stride = stride * size;
4006       }
4007     return (stride);
4008    }  */
4009 /*GCC ARRAYS*/
4010
4011 static tree
4012 gfc_array_init_size (tree descriptor, int rank, int corank, tree * poffset,
4013                      gfc_expr ** lower, gfc_expr ** upper,
4014                      stmtblock_t * pblock)
4015 {
4016   tree type;
4017   tree tmp;
4018   tree size;
4019   tree offset;
4020   tree stride;
4021   tree or_expr;
4022   tree thencase;
4023   tree elsecase;
4024   tree var;
4025   stmtblock_t thenblock;
4026   stmtblock_t elseblock;
4027   gfc_expr *ubound;
4028   gfc_se se;
4029   int n;
4030
4031   type = TREE_TYPE (descriptor);
4032
4033   stride = gfc_index_one_node;
4034   offset = gfc_index_zero_node;
4035
4036   /* Set the dtype.  */
4037   tmp = gfc_conv_descriptor_dtype (descriptor);
4038   gfc_add_modify (pblock, tmp, gfc_get_dtype (TREE_TYPE (descriptor)));
4039
4040   or_expr = boolean_false_node;
4041
4042   for (n = 0; n < rank; n++)
4043     {
4044       tree conv_lbound;
4045       tree conv_ubound;
4046
4047       /* We have 3 possibilities for determining the size of the array:
4048          lower == NULL    => lbound = 1, ubound = upper[n]
4049          upper[n] = NULL  => lbound = 1, ubound = lower[n]
4050          upper[n] != NULL => lbound = lower[n], ubound = upper[n]  */
4051       ubound = upper[n];
4052
4053       /* Set lower bound.  */
4054       gfc_init_se (&se, NULL);
4055       if (lower == NULL)
4056         se.expr = gfc_index_one_node;
4057       else
4058         {
4059           gcc_assert (lower[n]);
4060           if (ubound)
4061             {
4062               gfc_conv_expr_type (&se, lower[n], gfc_array_index_type);
4063               gfc_add_block_to_block (pblock, &se.pre);
4064             }
4065           else
4066             {
4067               se.expr = gfc_index_one_node;
4068               ubound = lower[n];
4069             }
4070         }
4071       gfc_conv_descriptor_lbound_set (pblock, descriptor, gfc_rank_cst[n],
4072                                       se.expr);
4073       conv_lbound = se.expr;
4074
4075       /* Work out the offset for this component.  */
4076       tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
4077                              se.expr, stride);
4078       offset = fold_build2_loc (input_location, MINUS_EXPR,
4079                                 gfc_array_index_type, offset, tmp);
4080
4081       /* Set upper bound.  */
4082       gfc_init_se (&se, NULL);
4083       gcc_assert (ubound);
4084       gfc_conv_expr_type (&se, ubound, gfc_array_index_type);
4085       gfc_add_block_to_block (pblock, &se.pre);
4086
4087       gfc_conv_descriptor_ubound_set (pblock, descriptor,
4088                                       gfc_rank_cst[n], se.expr);
4089       conv_ubound = se.expr;
4090
4091       /* Store the stride.  */
4092       gfc_conv_descriptor_stride_set (pblock, descriptor,
4093                                       gfc_rank_cst[n], stride);
4094
4095       /* Calculate size and check whether extent is negative.  */
4096       size = gfc_conv_array_extent_dim (conv_lbound, conv_ubound, &or_expr);
4097
4098       /* Multiply the stride by the number of elements in this dimension.  */
4099       stride = fold_build2_loc (input_location, MULT_EXPR,
4100                                 gfc_array_index_type, stride, size);
4101       stride = gfc_evaluate_now (stride, pblock);
4102     }
4103
4104   for (n = rank; n < rank + corank; n++)
4105     {
4106       ubound = upper[n];
4107
4108       /* Set lower bound.  */
4109       gfc_init_se (&se, NULL);
4110       if (lower == NULL || lower[n] == NULL)
4111         {
4112           gcc_assert (n == rank + corank - 1);
4113           se.expr = gfc_index_one_node;
4114         }
4115       else
4116         {
4117           if (ubound || n == rank + corank - 1)
4118             {
4119               gfc_conv_expr_type (&se, lower[n], gfc_array_index_type);
4120               gfc_add_block_to_block (pblock, &se.pre);
4121             }
4122           else
4123             {
4124               se.expr = gfc_index_one_node;
4125               ubound = lower[n];
4126             }
4127         }
4128       gfc_conv_descriptor_lbound_set (pblock, descriptor, gfc_rank_cst[n],
4129                                       se.expr);
4130
4131       if (n < rank + corank - 1)
4132         {
4133           gfc_init_se (&se, NULL);
4134           gcc_assert (ubound);
4135           gfc_conv_expr_type (&se, ubound, gfc_array_index_type);
4136           gfc_add_block_to_block (pblock, &se.pre);
4137           gfc_conv_descriptor_ubound_set (pblock, descriptor,
4138                                           gfc_rank_cst[n], se.expr);
4139         }
4140     }
4141
4142   /* The stride is the number of elements in the array, so multiply by the
4143      size of an element to get the total size.  */
4144   tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type));
4145   size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
4146                           stride, fold_convert (gfc_array_index_type, tmp));
4147
4148   if (poffset != NULL)
4149     {
4150       offset = gfc_evaluate_now (offset, pblock);
4151       *poffset = offset;
4152     }
4153
4154   if (integer_zerop (or_expr))
4155     return size;
4156   if (integer_onep (or_expr))
4157     return gfc_index_zero_node;
4158
4159   var = gfc_create_var (TREE_TYPE (size), "size");
4160   gfc_start_block (&thenblock);
4161   gfc_add_modify (&thenblock, var, gfc_index_zero_node);
4162   thencase = gfc_finish_block (&thenblock);
4163
4164   gfc_start_block (&elseblock);
4165   gfc_add_modify (&elseblock, var, size);
4166   elsecase = gfc_finish_block (&elseblock);
4167
4168   tmp = gfc_evaluate_now (or_expr, pblock);
4169   tmp = build3_v (COND_EXPR, tmp, thencase, elsecase);
4170   gfc_add_expr_to_block (pblock, tmp);
4171
4172   return var;
4173 }
4174
4175
4176 /* Initializes the descriptor and generates a call to _gfor_allocate.  Does
4177    the work for an ALLOCATE statement.  */
4178 /*GCC ARRAYS*/
4179
4180 bool
4181 gfc_array_allocate (gfc_se * se, gfc_expr * expr, tree pstat)
4182 {
4183   tree tmp;
4184   tree pointer;
4185   tree offset;
4186   tree size;
4187   gfc_expr **lower;
4188   gfc_expr **upper;
4189   gfc_ref *ref, *prev_ref = NULL;
4190   bool allocatable_array, coarray;
4191
4192   ref = expr->ref;
4193
4194   /* Find the last reference in the chain.  */
4195   while (ref && ref->next != NULL)
4196     {
4197       gcc_assert (ref->type != REF_ARRAY || ref->u.ar.type == AR_ELEMENT
4198                   || (ref->u.ar.dimen == 0 && ref->u.ar.codimen > 0));
4199       prev_ref = ref;
4200       ref = ref->next;
4201     }
4202
4203   if (ref == NULL || ref->type != REF_ARRAY)
4204     return false;
4205
4206   if (!prev_ref)
4207     {
4208       allocatable_array = expr->symtree->n.sym->attr.allocatable;
4209       coarray = expr->symtree->n.sym->attr.codimension;
4210     }
4211   else
4212     {
4213       allocatable_array = prev_ref->u.c.component->attr.allocatable;
4214       coarray = prev_ref->u.c.component->attr.codimension;
4215     }
4216
4217   /* Return if this is a scalar coarray.  */
4218   if ((!prev_ref && !expr->symtree->n.sym->attr.dimension)
4219       || (prev_ref && !prev_ref->u.c.component->attr.dimension))
4220     {
4221       gcc_assert (coarray);
4222       return false;
4223     }
4224
4225   /* Figure out the size of the array.  */
4226   switch (ref->u.ar.type)
4227     {
4228     case AR_ELEMENT:
4229       if (!coarray)
4230         {
4231           lower = NULL;
4232           upper = ref->u.ar.start;
4233           break;
4234         }
4235       /* Fall through.  */
4236
4237     case AR_SECTION:
4238       lower = ref->u.ar.start;
4239       upper = ref->u.ar.end;
4240       break;
4241
4242     case AR_FULL:
4243       gcc_assert (ref->u.ar.as->type == AS_EXPLICIT);
4244
4245       lower = ref->u.ar.as->lower;
4246       upper = ref->u.ar.as->upper;
4247       break;
4248
4249     default:
4250       gcc_unreachable ();
4251       break;
4252     }
4253
4254   size = gfc_array_init_size (se->expr, ref->u.ar.as->rank,
4255                               ref->u.ar.as->corank, &offset, lower, upper,
4256                               &se->pre);
4257
4258   /* Allocate memory to store the data.  */
4259   pointer = gfc_conv_descriptor_data_get (se->expr);
4260   STRIP_NOPS (pointer);
4261
4262   /* The allocate_array variants take the old pointer as first argument.  */
4263   if (allocatable_array)
4264     tmp = gfc_allocate_array_with_status (&se->pre, pointer, size, pstat, expr);
4265   else
4266     tmp = gfc_allocate_with_status (&se->pre, size, pstat);
4267   tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node, pointer,
4268                          tmp);
4269   gfc_add_expr_to_block (&se->pre, tmp);
4270
4271   gfc_conv_descriptor_offset_set (&se->pre, se->expr, offset);
4272
4273   if (expr->ts.type == BT_DERIVED
4274         && expr->ts.u.derived->attr.alloc_comp)
4275     {
4276       tmp = gfc_nullify_alloc_comp (expr->ts.u.derived, se->expr,
4277                                     ref->u.ar.as->rank);
4278       gfc_add_expr_to_block (&se->pre, tmp);
4279     }
4280
4281   return true;
4282 }
4283
4284
4285 /* Deallocate an array variable.  Also used when an allocated variable goes
4286    out of scope.  */
4287 /*GCC ARRAYS*/
4288
4289 tree
4290 gfc_array_deallocate (tree descriptor, tree pstat, gfc_expr* expr)
4291 {
4292   tree var;
4293   tree tmp;
4294   stmtblock_t block;
4295
4296   gfc_start_block (&block);
4297   /* Get a pointer to the data.  */
4298   var = gfc_conv_descriptor_data_get (descriptor);
4299   STRIP_NOPS (var);
4300
4301   /* Parameter is the address of the data component.  */
4302   tmp = gfc_deallocate_with_status (var, pstat, false, expr);
4303   gfc_add_expr_to_block (&block, tmp);
4304
4305   /* Zero the data pointer.  */
4306   tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node,
4307                          var, build_int_cst (TREE_TYPE (var), 0));
4308   gfc_add_expr_to_block (&block, tmp);
4309
4310   return gfc_finish_block (&block);
4311 }
4312
4313
4314 /* Create an array constructor from an initialization expression.
4315    We assume the frontend already did any expansions and conversions.  */
4316
4317 tree
4318 gfc_conv_array_initializer (tree type, gfc_expr * expr)
4319 {
4320   gfc_constructor *c;
4321   tree tmp;
4322   gfc_se se;
4323   HOST_WIDE_INT hi;
4324   unsigned HOST_WIDE_INT lo;
4325   tree index;
4326   VEC(constructor_elt,gc) *v = NULL;
4327
4328   switch (expr->expr_type)
4329     {
4330     case EXPR_CONSTANT:
4331     case EXPR_STRUCTURE:
4332       /* A single scalar or derived type value.  Create an array with all
4333          elements equal to that value.  */
4334       gfc_init_se (&se, NULL);
4335       
4336       if (expr->expr_type == EXPR_CONSTANT)
4337         gfc_conv_constant (&se, expr);
4338       else
4339         gfc_conv_structure (&se, expr, 1);
4340
4341       tmp = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
4342       gcc_assert (tmp && INTEGER_CST_P (tmp));
4343       hi = TREE_INT_CST_HIGH (tmp);
4344       lo = TREE_INT_CST_LOW (tmp);
4345       lo++;
4346       if (lo == 0)
4347         hi++;
4348       /* This will probably eat buckets of memory for large arrays.  */
4349       while (hi != 0 || lo != 0)
4350         {
4351           CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, se.expr);
4352           if (lo == 0)
4353             hi--;
4354           lo--;
4355         }
4356       break;
4357
4358     case EXPR_ARRAY:
4359       /* Create a vector of all the elements.  */
4360       for (c = gfc_constructor_first (expr->value.constructor);
4361            c; c = gfc_constructor_next (c))
4362         {
4363           if (c->iterator)
4364             {
4365               /* Problems occur when we get something like
4366                  integer :: a(lots) = (/(i, i=1, lots)/)  */
4367               gfc_fatal_error ("The number of elements in the array constructor "
4368                                "at %L requires an increase of the allowed %d "
4369                                "upper limit.   See -fmax-array-constructor "
4370                                "option", &expr->where,
4371                                gfc_option.flag_max_array_constructor);
4372               return NULL_TREE;
4373             }
4374           if (mpz_cmp_si (c->offset, 0) != 0)
4375             index = gfc_conv_mpz_to_tree (c->offset, gfc_index_integer_kind);
4376           else
4377             index = NULL_TREE;
4378
4379           gfc_init_se (&se, NULL);
4380           switch (c->expr->expr_type)
4381             {
4382             case EXPR_CONSTANT:
4383               gfc_conv_constant (&se, c->expr);
4384               CONSTRUCTOR_APPEND_ELT (v, index, se.expr);
4385               break;
4386
4387             case EXPR_STRUCTURE:
4388               gfc_conv_structure (&se, c->expr, 1);
4389               CONSTRUCTOR_APPEND_ELT (v, index, se.expr);
4390               break;
4391
4392
4393             default:
4394               /* Catch those occasional beasts that do not simplify
4395                  for one reason or another, assuming that if they are
4396                  standard defying the frontend will catch them.  */
4397               gfc_conv_expr (&se, c->expr);
4398               CONSTRUCTOR_APPEND_ELT (v, index, se.expr);
4399               break;
4400             }
4401         }
4402       break;
4403
4404     case EXPR_NULL:
4405       return gfc_build_null_descriptor (type);
4406
4407     default:
4408       gcc_unreachable ();
4409     }
4410
4411   /* Create a constructor from the list of elements.  */
4412   tmp = build_constructor (type, v);
4413   TREE_CONSTANT (tmp) = 1;
4414   return tmp;
4415 }
4416
4417
4418 /* Generate code to evaluate non-constant array bounds.  Sets *poffset and
4419    returns the size (in elements) of the array.  */
4420
4421 static tree
4422 gfc_trans_array_bounds (tree type, gfc_symbol * sym, tree * poffset,
4423                         stmtblock_t * pblock)
4424 {
4425   gfc_array_spec *as;
4426   tree size;
4427   tree stride;
4428   tree offset;
4429   tree ubound;
4430   tree lbound;
4431   tree tmp;
4432   gfc_se se;
4433
4434   int dim;
4435
4436   as = sym->as;
4437
4438   size = gfc_index_one_node;
4439   offset = gfc_index_zero_node;
4440   for (dim = 0; dim < as->rank; dim++)
4441     {
4442       /* Evaluate non-constant array bound expressions.  */
4443       lbound = GFC_TYPE_ARRAY_LBOUND (type, dim);
4444       if (as->lower[dim] && !INTEGER_CST_P (lbound))
4445         {
4446           gfc_init_se (&se, NULL);
4447           gfc_conv_expr_type (&se, as->lower[dim], gfc_array_index_type);
4448           gfc_add_block_to_block (pblock, &se.pre);
4449           gfc_add_modify (pblock, lbound, se.expr);
4450         }
4451       ubound = GFC_TYPE_ARRAY_UBOUND (type, dim);
4452       if (as->upper[dim] && !INTEGER_CST_P (ubound))
4453         {
4454           gfc_init_se (&se, NULL);
4455           gfc_conv_expr_type (&se, as->upper[dim], gfc_array_index_type);
4456           gfc_add_block_to_block (pblock, &se.pre);
4457           gfc_add_modify (pblock, ubound, se.expr);
4458         }
4459       /* The offset of this dimension.  offset = offset - lbound * stride.  */
4460       tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
4461                              lbound, size);
4462       offset = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
4463                                 offset, tmp);
4464
4465       /* The size of this dimension, and the stride of the next.  */
4466       if (dim + 1 < as->rank)
4467         stride = GFC_TYPE_ARRAY_STRIDE (type, dim + 1);
4468       else
4469         stride = GFC_TYPE_ARRAY_SIZE (type);
4470
4471       if (ubound != NULL_TREE && !(stride && INTEGER_CST_P (stride)))
4472         {
4473           /* Calculate stride = size * (ubound + 1 - lbound).  */
4474           tmp = fold_build2_loc (input_location, MINUS_EXPR,
4475                                  gfc_array_index_type,
4476                                  gfc_index_one_node, lbound);
4477           tmp = fold_build2_loc (input_location, PLUS_EXPR,
4478                                  gfc_array_index_type, ubound, tmp);
4479           tmp = fold_build2_loc (input_location, MULT_EXPR,
4480                                  gfc_array_index_type, size, tmp);
4481           if (stride)
4482             gfc_add_modify (pblock, stride, tmp);
4483           else
4484             stride = gfc_evaluate_now (tmp, pblock);
4485
4486           /* Make sure that negative size arrays are translated
4487              to being zero size.  */
4488           tmp = fold_build2_loc (input_location, GE_EXPR, boolean_type_node,
4489                                  stride, gfc_index_zero_node);
4490           tmp = fold_build3_loc (input_location, COND_EXPR,
4491                                  gfc_array_index_type, tmp,
4492                                  stride, gfc_index_zero_node);
4493           gfc_add_modify (pblock, stride, tmp);
4494         }
4495
4496       size = stride;
4497     }
4498
4499   gfc_trans_vla_type_sizes (sym, pblock);
4500
4501   *poffset = offset;
4502   return size;
4503 }
4504
4505
4506 /* Generate code to initialize/allocate an array variable.  */
4507
4508 void
4509 gfc_trans_auto_array_allocation (tree decl, gfc_symbol * sym,
4510                                  gfc_wrapped_block * block)
4511 {
4512   stmtblock_t init;
4513   tree type;
4514   tree tmp;
4515   tree size;
4516   tree offset;
4517   bool onstack;
4518
4519   gcc_assert (!(sym->attr.pointer || sym->attr.allocatable));
4520
4521   /* Do nothing for USEd variables.  */
4522   if (sym->attr.use_assoc)
4523     return;
4524
4525   type = TREE_TYPE (decl);
4526   gcc_assert (GFC_ARRAY_TYPE_P (type));
4527   onstack = TREE_CODE (type) != POINTER_TYPE;
4528
4529   gfc_start_block (&init);
4530
4531   /* Evaluate character string length.  */
4532   if (sym->ts.type == BT_CHARACTER
4533       && onstack && !INTEGER_CST_P (sym->ts.u.cl->backend_decl))
4534     {
4535       gfc_conv_string_length (sym->ts.u.cl, NULL, &init);
4536
4537       gfc_trans_vla_type_sizes (sym, &init);
4538
4539       /* Emit a DECL_EXPR for this variable, which will cause the
4540          gimplifier to allocate storage, and all that good stuff.  */
4541       tmp = fold_build1_loc (input_location, DECL_EXPR, TREE_TYPE (decl), decl);
4542       gfc_add_expr_to_block (&init, tmp);
4543     }
4544
4545   if (onstack)
4546     {
4547       gfc_add_init_cleanup (block, gfc_finish_block (&init), NULL_TREE);
4548       return;
4549     }
4550
4551   type = TREE_TYPE (type);
4552
4553   gcc_assert (!sym->attr.use_assoc);
4554   gcc_assert (!TREE_STATIC (decl));
4555   gcc_assert (!sym->module);
4556
4557   if (sym->ts.type == BT_CHARACTER
4558       && !INTEGER_CST_P (sym->ts.u.cl->backend_decl))
4559     gfc_conv_string_length (sym->ts.u.cl, NULL, &init);
4560
4561   size = gfc_trans_array_bounds (type, sym, &offset, &init);
4562
4563   /* Don't actually allocate space for Cray Pointees.  */
4564   if (sym->attr.cray_pointee)
4565     {
4566       if (TREE_CODE (GFC_TYPE_ARRAY_OFFSET (type)) == VAR_DECL)
4567         gfc_add_modify (&init, GFC_TYPE_ARRAY_OFFSET (type), offset);
4568
4569       gfc_add_init_cleanup (block, gfc_finish_block (&init), NULL_TREE);
4570       return;
4571     }
4572
4573   /* The size is the number of elements in the array, so multiply by the
4574      size of an element to get the total size.  */
4575   tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type));
4576   size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
4577                           size, fold_convert (gfc_array_index_type, tmp));
4578
4579   /* Allocate memory to hold the data.  */
4580   tmp = gfc_call_malloc (&init, TREE_TYPE (decl), size);
4581   gfc_add_modify (&init, decl, tmp);
4582
4583   /* Set offset of the array.  */
4584   if (TREE_CODE (GFC_TYPE_ARRAY_OFFSET (type)) == VAR_DECL)
4585     gfc_add_modify (&init, GFC_TYPE_ARRAY_OFFSET (type), offset);
4586
4587   /* Automatic arrays should not have initializers.  */
4588   gcc_assert (!sym->value);
4589
4590   /* Free the temporary.  */
4591   tmp = gfc_call_free (convert (pvoid_type_node, decl));
4592
4593   gfc_add_init_cleanup (block, gfc_finish_block (&init), tmp);
4594 }
4595
4596
4597 /* Generate entry and exit code for g77 calling convention arrays.  */
4598
4599 void
4600 gfc_trans_g77_array (gfc_symbol * sym, gfc_wrapped_block * block)
4601 {
4602   tree parm;
4603   tree type;
4604   locus loc;
4605   tree offset;
4606   tree tmp;
4607   tree stmt;  
4608   stmtblock_t init;
4609
4610   gfc_get_backend_locus (&loc);
4611   gfc_set_backend_locus (&sym->declared_at);
4612
4613   /* Descriptor type.  */
4614   parm = sym->backend_decl;
4615   type = TREE_TYPE (parm);
4616   gcc_assert (GFC_ARRAY_TYPE_P (type));
4617
4618   gfc_start_block (&init);
4619
4620   if (sym->ts.type == BT_CHARACTER
4621       && TREE_CODE (sym->ts.u.cl->backend_decl) == VAR_DECL)
4622     gfc_conv_string_length (sym->ts.u.cl, NULL, &init);
4623
4624   /* Evaluate the bounds of the array.  */
4625   gfc_trans_array_bounds (type, sym, &offset, &init);
4626
4627   /* Set the offset.  */
4628   if (TREE_CODE (GFC_TYPE_ARRAY_OFFSET (type)) == VAR_DECL)
4629     gfc_add_modify (&init, GFC_TYPE_ARRAY_OFFSET (type), offset);
4630
4631   /* Set the pointer itself if we aren't using the parameter directly.  */
4632   if (TREE_CODE (parm) != PARM_DECL)
4633     {
4634       tmp = convert (TREE_TYPE (parm), GFC_DECL_SAVED_DESCRIPTOR (parm));
4635       gfc_add_modify (&init, parm, tmp);
4636     }
4637   stmt = gfc_finish_block (&init);
4638
4639   gfc_set_backend_locus (&loc);
4640
4641   /* Add the initialization code to the start of the function.  */
4642
4643   if (sym->attr.optional || sym->attr.not_always_present)
4644     {
4645       tmp = gfc_conv_expr_present (sym);
4646       stmt = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt (input_location));
4647     }
4648   
4649   gfc_add_init_cleanup (block, stmt, NULL_TREE);
4650 }
4651
4652
4653 /* Modify the descriptor of an array parameter so that it has the
4654    correct lower bound.  Also move the upper bound accordingly.
4655    If the array is not packed, it will be copied into a temporary.
4656    For each dimension we set the new lower and upper bounds.  Then we copy the
4657    stride and calculate the offset for this dimension.  We also work out
4658    what the stride of a packed array would be, and see it the two match.
4659    If the array need repacking, we set the stride to the values we just
4660    calculated, recalculate the offset and copy the array data.
4661    Code is also added to copy the data back at the end of the function.
4662    */
4663
4664 void
4665 gfc_trans_dummy_array_bias (gfc_symbol * sym, tree tmpdesc,
4666                             gfc_wrapped_block * block)
4667 {
4668   tree size;
4669   tree type;
4670   tree offset;
4671   locus loc;
4672   stmtblock_t init;
4673   tree stmtInit, stmtCleanup;
4674   tree lbound;
4675   tree ubound;
4676   tree dubound;
4677   tree dlbound;
4678   tree dumdesc;
4679   tree tmp;
4680   tree stride, stride2;
4681   tree stmt_packed;
4682   tree stmt_unpacked;
4683   tree partial;
4684   gfc_se se;
4685   int n;
4686   int checkparm;
4687   int no_repack;
4688   bool optional_arg;
4689
4690   /* Do nothing for pointer and allocatable arrays.  */
4691   if (sym->attr.pointer || sym->attr.allocatable)
4692     return;
4693
4694   if (sym->attr.dummy && gfc_is_nodesc_array (sym))
4695     {
4696       gfc_trans_g77_array (sym, block);
4697       return;
4698     }
4699
4700   gfc_get_backend_locus (&loc);
4701   gfc_set_backend_locus (&sym->declared_at);
4702
4703   /* Descriptor type.  */
4704   type = TREE_TYPE (tmpdesc);
4705   gcc_assert (GFC_ARRAY_TYPE_P (type));
4706   dumdesc = GFC_DECL_SAVED_DESCRIPTOR (tmpdesc);
4707   dumdesc = build_fold_indirect_ref_loc (input_location, dumdesc);
4708   gfc_start_block (&init);
4709
4710   if (sym->ts.type == BT_CHARACTER
4711       && TREE_CODE (sym->ts.u.cl->backend_decl) == VAR_DECL)
4712     gfc_conv_string_length (sym->ts.u.cl, NULL, &init);
4713
4714   checkparm = (sym->as->type == AS_EXPLICIT
4715                && (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS));
4716
4717   no_repack = !(GFC_DECL_PACKED_ARRAY (tmpdesc)
4718                 || GFC_DECL_PARTIAL_PACKED_ARRAY (tmpdesc));
4719
4720   if (GFC_DECL_PARTIAL_PACKED_ARRAY (tmpdesc))
4721     {
4722       /* For non-constant shape arrays we only check if the first dimension
4723          is contiguous.  Repacking higher dimensions wouldn't gain us
4724          anything as we still don't know the array stride.  */
4725       partial = gfc_create_var (boolean_type_node, "partial");
4726       TREE_USED (partial) = 1;
4727       tmp = gfc_conv_descriptor_stride_get (dumdesc, gfc_rank_cst[0]);
4728       tmp = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, tmp,
4729                              gfc_index_one_node);
4730       gfc_add_modify (&init, partial, tmp);
4731     }
4732   else
4733     partial = NULL_TREE;
4734
4735   /* The naming of stmt_unpacked and stmt_packed may be counter-intuitive
4736      here, however I think it does the right thing.  */
4737   if (no_repack)
4738     {
4739       /* Set the first stride.  */
4740       stride = gfc_conv_descriptor_stride_get (dumdesc, gfc_rank_cst[0]);
4741       stride = gfc_evaluate_now (stride, &init);
4742
4743       tmp = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
4744                              stride, gfc_index_zero_node);
4745       tmp = fold_build3_loc (input_location, COND_EXPR, gfc_array_index_type,
4746                              tmp, gfc_index_one_node, stride);
4747       stride = GFC_TYPE_ARRAY_STRIDE (type, 0);
4748       gfc_add_modify (&init, stride, tmp);
4749
4750       /* Allow the user to disable array repacking.  */
4751       stmt_unpacked = NULL_TREE;
4752     }
4753   else
4754     {
4755       gcc_assert (integer_onep (GFC_TYPE_ARRAY_STRIDE (type, 0)));
4756       /* A library call to repack the array if necessary.  */
4757       tmp = GFC_DECL_SAVED_DESCRIPTOR (tmpdesc);
4758       stmt_unpacked = build_call_expr_loc (input_location,
4759                                        gfor_fndecl_in_pack, 1, tmp);
4760
4761       stride = gfc_index_one_node;
4762
4763       if (gfc_option.warn_array_temp)
4764         gfc_warning ("Creating array temporary at %L", &loc);
4765     }
4766
4767   /* This is for the case where the array data is used directly without
4768      calling the repack function.  */
4769   if (no_repack || partial != NULL_TREE)
4770     stmt_packed = gfc_conv_descriptor_data_get (dumdesc);
4771   else
4772     stmt_packed = NULL_TREE;
4773
4774   /* Assign the data pointer.  */
4775   if (stmt_packed != NULL_TREE && stmt_unpacked != NULL_TREE)
4776     {
4777       /* Don't repack unknown shape arrays when the first stride is 1.  */
4778       tmp = fold_build3_loc (input_location, COND_EXPR, TREE_TYPE (stmt_packed),
4779                              partial, stmt_packed, stmt_unpacked);
4780     }
4781   else
4782     tmp = stmt_packed != NULL_TREE ? stmt_packed : stmt_unpacked;
4783   gfc_add_modify (&init, tmpdesc, fold_convert (type, tmp));
4784
4785   offset = gfc_index_zero_node;
4786   size = gfc_index_one_node;
4787
4788   /* Evaluate the bounds of the array.  */
4789   for (n = 0; n < sym->as->rank; n++)
4790     {
4791       if (checkparm || !sym->as->upper[n])
4792         {
4793           /* Get the bounds of the actual parameter.  */
4794           dubound = gfc_conv_descriptor_ubound_get (dumdesc, gfc_rank_cst[n]);
4795           dlbound = gfc_conv_descriptor_lbound_get (dumdesc, gfc_rank_cst[n]);
4796         }
4797       else
4798         {
4799           dubound = NULL_TREE;
4800           dlbound = NULL_TREE;
4801         }
4802
4803       lbound = GFC_TYPE_ARRAY_LBOUND (type, n);
4804       if (!INTEGER_CST_P (lbound))
4805         {
4806           gfc_init_se (&se, NULL);
4807           gfc_conv_expr_type (&se, sym->as->lower[n],
4808                               gfc_array_index_type);
4809           gfc_add_block_to_block (&init, &se.pre);
4810           gfc_add_modify (&init, lbound, se.expr);
4811         }
4812
4813       ubound = GFC_TYPE_ARRAY_UBOUND (type, n);
4814       /* Set the desired upper bound.  */
4815       if (sym->as->upper[n])
4816         {
4817           /* We know what we want the upper bound to be.  */
4818           if (!INTEGER_CST_P (ubound))
4819             {
4820               gfc_init_se (&se, NULL);
4821               gfc_conv_expr_type (&se, sym->as->upper[n],
4822                                   gfc_array_index_type);
4823               gfc_add_block_to_block (&init, &se.pre);
4824               gfc_add_modify (&init, ubound, se.expr);
4825             }
4826
4827           /* Check the sizes match.  */
4828           if (checkparm)
4829             {
4830               /* Check (ubound(a) - lbound(a) == ubound(b) - lbound(b)).  */
4831               char * msg;
4832               tree temp;
4833
4834               temp = fold_build2_loc (input_location, MINUS_EXPR,
4835                                       gfc_array_index_type, ubound, lbound);
4836               temp = fold_build2_loc (input_location, PLUS_EXPR,
4837                                       gfc_array_index_type,
4838                                       gfc_index_one_node, temp);
4839               stride2 = fold_build2_loc (input_location, MINUS_EXPR,
4840                                          gfc_array_index_type, dubound,
4841                                          dlbound);
4842               stride2 = fold_build2_loc (input_location, PLUS_EXPR,
4843                                          gfc_array_index_type,
4844                                          gfc_index_one_node, stride2);
4845               tmp = fold_build2_loc (input_location, NE_EXPR,
4846                                      gfc_array_index_type, temp, stride2);
4847               asprintf (&msg, "Dimension %d of array '%s' has extent "
4848                         "%%ld instead of %%ld", n+1, sym->name);
4849
4850               gfc_trans_runtime_check (true, false, tmp, &init, &loc, msg, 
4851                         fold_convert (long_integer_type_node, temp),
4852                         fold_convert (long_integer_type_node, stride2));
4853
4854               gfc_free (msg);
4855             }
4856         }
4857       else
4858         {
4859           /* For assumed shape arrays move the upper bound by the same amount
4860              as the lower bound.  */
4861           tmp = fold_build2_loc (input_location, MINUS_EXPR,
4862                                  gfc_array_index_type, dubound, dlbound);
4863           tmp = fold_build2_loc (input_location, PLUS_EXPR,
4864                                  gfc_array_index_type, tmp, lbound);
4865           gfc_add_modify (&init, ubound, tmp);
4866         }
4867       /* The offset of this dimension.  offset = offset - lbound * stride.  */
4868       tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
4869                              lbound, stride);
4870       offset = fold_build2_loc (input_location, MINUS_EXPR,
4871                                 gfc_array_index_type, offset, tmp);
4872
4873       /* The size of this dimension, and the stride of the next.  */
4874       if (n + 1 < sym->as->rank)
4875         {
4876           stride = GFC_TYPE_ARRAY_STRIDE (type, n + 1);
4877
4878           if (no_repack || partial != NULL_TREE)
4879             stmt_unpacked =
4880               gfc_conv_descriptor_stride_get (dumdesc, gfc_rank_cst[n+1]);
4881
4882           /* Figure out the stride if not a known constant.  */
4883           if (!INTEGER_CST_P (stride))
4884             {
4885               if (no_repack)
4886                 stmt_packed = NULL_TREE;
4887               else
4888                 {
4889                   /* Calculate stride = size * (ubound + 1 - lbound).  */
4890                   tmp = fold_build2_loc (input_location, MINUS_EXPR,
4891                                          gfc_array_index_type,
4892                                          gfc_index_one_node, lbound);
4893                   tmp = fold_build2_loc (input_location, PLUS_EXPR,
4894                                          gfc_array_index_type, ubound, tmp);
4895                   size = fold_build2_loc (input_location, MULT_EXPR,
4896                                           gfc_array_index_type, size, tmp);
4897                   stmt_packed = size;
4898                 }
4899
4900               /* Assign the stride.  */
4901               if (stmt_packed != NULL_TREE && stmt_unpacked != NULL_TREE)
4902                 tmp = fold_build3_loc (input_location, COND_EXPR,
4903                                        gfc_array_index_type, partial,
4904                                        stmt_unpacked, stmt_packed);
4905               else
4906                 tmp = (stmt_packed != NULL_TREE) ? stmt_packed : stmt_unpacked;
4907               gfc_add_modify (&init, stride, tmp);
4908             }
4909         }
4910       else
4911         {
4912           stride = GFC_TYPE_ARRAY_SIZE (type);
4913
4914           if (stride && !INTEGER_CST_P (stride))
4915             {
4916               /* Calculate size = stride * (ubound + 1 - lbound).  */
4917               tmp = fold_build2_loc (input_location, MINUS_EXPR,
4918                                      gfc_array_index_type,
4919                                      gfc_index_one_node, lbound);
4920               tmp = fold_build2_loc (input_location, PLUS_EXPR,
4921                                      gfc_array_index_type,
4922                                      ubound, tmp);
4923               tmp = fold_build2_loc (input_location, MULT_EXPR,
4924                                      gfc_array_index_type,
4925                                      GFC_TYPE_ARRAY_STRIDE (type, n), tmp);
4926               gfc_add_modify (&init, stride, tmp);
4927             }
4928         }
4929     }
4930
4931   /* Set the offset.  */
4932   if (TREE_CODE (GFC_TYPE_ARRAY_OFFSET (type)) == VAR_DECL)
4933     gfc_add_modify (&init, GFC_TYPE_ARRAY_OFFSET (type), offset);
4934
4935   gfc_trans_vla_type_sizes (sym, &init);
4936
4937   stmtInit = gfc_finish_block (&init);
4938
4939   /* Only do the entry/initialization code if the arg is present.  */
4940   dumdesc = GFC_DECL_SAVED_DESCRIPTOR (tmpdesc);
4941   optional_arg = (sym->attr.optional
4942                   || (sym->ns->proc_name->attr.entry_master
4943                       && sym->attr.dummy));
4944   if (optional_arg)
4945     {
4946       tmp = gfc_conv_expr_present (sym);
4947       stmtInit = build3_v (COND_EXPR, tmp, stmtInit,
4948                            build_empty_stmt (input_location));
4949     }
4950
4951   /* Cleanup code.  */
4952   if (no_repack)
4953     stmtCleanup = NULL_TREE;
4954   else
4955     {
4956       stmtblock_t cleanup;
4957       gfc_start_block (&cleanup);
4958
4959       if (sym->attr.intent != INTENT_IN)
4960         {
4961           /* Copy the data back.  */
4962           tmp = build_call_expr_loc (input_location,
4963                                  gfor_fndecl_in_unpack, 2, dumdesc, tmpdesc);
4964           gfc_add_expr_to_block (&cleanup, tmp);
4965         }
4966
4967       /* Free the temporary.  */
4968       tmp = gfc_call_free (tmpdesc);
4969       gfc_add_expr_to_block (&cleanup, tmp);
4970
4971       stmtCleanup = gfc_finish_block (&cleanup);
4972         
4973       /* Only do the cleanup if the array was repacked.  */
4974       tmp = build_fold_indirect_ref_loc (input_location, dumdesc);
4975       tmp = gfc_conv_descriptor_data_get (tmp);
4976       tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
4977                              tmp, tmpdesc);
4978       stmtCleanup = build3_v (COND_EXPR, tmp, stmtCleanup,
4979                               build_empty_stmt (input_location));
4980
4981       if (optional_arg)
4982         {
4983           tmp = gfc_conv_expr_present (sym);
4984           stmtCleanup = build3_v (COND_EXPR, tmp, stmtCleanup,
4985                                   build_empty_stmt (input_location));
4986         }
4987     }
4988
4989   /* We don't need to free any memory allocated by internal_pack as it will
4990      be freed at the end of the function by pop_context.  */
4991   gfc_add_init_cleanup (block, stmtInit, stmtCleanup);
4992 }
4993
4994
4995 /* Calculate the overall offset, including subreferences.  */
4996 static void
4997 gfc_get_dataptr_offset (stmtblock_t *block, tree parm, tree desc, tree offset,
4998                         bool subref, gfc_expr *expr)
4999 {
5000   tree tmp;
5001   tree field;
5002   tree stride;
5003   tree index;
5004   gfc_ref *ref;
5005   gfc_se start;
5006   int n;
5007
5008   /* If offset is NULL and this is not a subreferenced array, there is
5009      nothing to do.  */
5010   if (offset == NULL_TREE)
5011     {
5012       if (subref)
5013         offset = gfc_index_zero_node;
5014       else
5015         return;
5016     }
5017
5018   tmp = gfc_conv_array_data (desc);
5019   tmp = build_fold_indirect_ref_loc (input_location,
5020                                  tmp);
5021   tmp = gfc_build_array_ref (tmp, offset, NULL);
5022
5023   /* Offset the data pointer for pointer assignments from arrays with
5024      subreferences; e.g. my_integer => my_type(:)%integer_component.  */
5025   if (subref)
5026     {
5027       /* Go past the array reference.  */
5028       for (ref = expr->ref; ref; ref = ref->next)
5029         if (ref->type == REF_ARRAY &&
5030               ref->u.ar.type != AR_ELEMENT)
5031           {
5032             ref = ref->next;
5033             break;
5034           }
5035
5036       /* Calculate the offset for each subsequent subreference.  */
5037       for (; ref; ref = ref->next)
5038         {
5039           switch (ref->type)
5040             {
5041             case REF_COMPONENT:
5042               field = ref->u.c.component->backend_decl;
5043               gcc_assert (field && TREE_CODE (field) == FIELD_DECL);
5044               tmp = fold_build3_loc (input_location, COMPONENT_REF,
5045                                      TREE_TYPE (field),
5046                                      tmp, field, NULL_TREE);
5047               break;
5048
5049             case REF_SUBSTRING:
5050               gcc_assert (TREE_CODE (TREE_TYPE (tmp)) == ARRAY_TYPE);
5051               gfc_init_se (&start, NULL);
5052               gfc_conv_expr_type (&start, ref->u.ss.start, gfc_charlen_type_node);
5053               gfc_add_block_to_block (block, &start.pre);
5054               tmp = gfc_build_array_ref (tmp, start.expr, NULL);
5055               break;
5056
5057             case REF_ARRAY:
5058               gcc_assert (TREE_CODE (TREE_TYPE (tmp)) == ARRAY_TYPE
5059                             && ref->u.ar.type == AR_ELEMENT);
5060
5061               /* TODO - Add bounds checking.  */
5062               stride = gfc_index_one_node;
5063               index = gfc_index_zero_node;
5064               for (n = 0; n < ref->u.ar.dimen; n++)
5065                 {
5066                   tree itmp;
5067                   tree jtmp;
5068
5069                   /* Update the index.  */
5070                   gfc_init_se (&start, NULL);
5071                   gfc_conv_expr_type (&start, ref->u.ar.start[n], gfc_array_index_type);
5072                   itmp = gfc_evaluate_now (start.expr, block);
5073                   gfc_init_se (&start, NULL);
5074                   gfc_conv_expr_type (&start, ref->u.ar.as->lower[n], gfc_array_index_type);
5075                   jtmp = gfc_evaluate_now (start.expr, block);
5076                   itmp = fold_build2_loc (input_location, MINUS_EXPR,
5077                                           gfc_array_index_type, itmp, jtmp);
5078                   itmp = fold_build2_loc (input_location, MULT_EXPR,
5079                                           gfc_array_index_type, itmp, stride);
5080                   index = fold_build2_loc (input_location, PLUS_EXPR,
5081                                           gfc_array_index_type, itmp, index);
5082                   index = gfc_evaluate_now (index, block);
5083
5084                   /* Update the stride.  */
5085                   gfc_init_se (&start, NULL);
5086                   gfc_conv_expr_type (&start, ref->u.ar.as->upper[n], gfc_array_index_type);
5087                   itmp =  fold_build2_loc (input_location, MINUS_EXPR,
5088                                            gfc_array_index_type, start.expr,
5089                                            jtmp);
5090                   itmp =  fold_build2_loc (input_location, PLUS_EXPR,
5091                                            gfc_array_index_type,
5092                                            gfc_index_one_node, itmp);
5093                   stride =  fold_build2_loc (input_location, MULT_EXPR,
5094                                              gfc_array_index_type, stride, itmp);
5095                   stride = gfc_evaluate_now (stride, block);
5096                 }
5097
5098               /* Apply the index to obtain the array element.  */
5099               tmp = gfc_build_array_ref (tmp, index, NULL);
5100               break;
5101
5102             default:
5103               gcc_unreachable ();
5104               break;
5105             }
5106         }
5107     }
5108
5109   /* Set the target data pointer.  */
5110   offset = gfc_build_addr_expr (gfc_array_dataptr_type (desc), tmp);
5111   gfc_conv_descriptor_data_set (block, parm, offset);
5112 }
5113
5114
5115 /* gfc_conv_expr_descriptor needs the string length an expression
5116    so that the size of the temporary can be obtained.  This is done
5117    by adding up the string lengths of all the elements in the
5118    expression.  Function with non-constant expressions have their
5119    string lengths mapped onto the actual arguments using the
5120    interface mapping machinery in trans-expr.c.  */
5121 static void
5122 get_array_charlen (gfc_expr *expr, gfc_se *se)
5123 {
5124   gfc_interface_mapping mapping;
5125   gfc_formal_arglist *formal;
5126   gfc_actual_arglist *arg;
5127   gfc_se tse;
5128
5129   if (expr->ts.u.cl->length
5130         && gfc_is_constant_expr (expr->ts.u.cl->length))
5131     {
5132       if (!expr->ts.u.cl->backend_decl)
5133         gfc_conv_string_length (expr->ts.u.cl, expr, &se->pre);
5134       return;
5135     }
5136
5137   switch (expr->expr_type)
5138     {
5139     case EXPR_OP:
5140       get_array_charlen (expr->value.op.op1, se);
5141
5142       /* For parentheses the expression ts.u.cl is identical.  */
5143       if (expr->value.op.op == INTRINSIC_PARENTHESES)
5144         return;
5145
5146      expr->ts.u.cl->backend_decl =
5147                 gfc_create_var (gfc_charlen_type_node, "sln");
5148
5149       if (expr->value.op.op2)
5150         {
5151           get_array_charlen (expr->value.op.op2, se);
5152
5153           gcc_assert (expr->value.op.op == INTRINSIC_CONCAT);
5154
5155           /* Add the string lengths and assign them to the expression
5156              string length backend declaration.  */
5157           gfc_add_modify (&se->pre, expr->ts.u.cl->backend_decl,
5158                           fold_build2_loc (input_location, PLUS_EXPR,
5159                                 gfc_charlen_type_node,
5160                                 expr->value.op.op1->ts.u.cl->backend_decl,
5161                                 expr->value.op.op2->ts.u.cl->backend_decl));
5162         }
5163       else
5164         gfc_add_modify (&se->pre, expr->ts.u.cl->backend_decl,
5165                         expr->value.op.op1->ts.u.cl->backend_decl);
5166       break;
5167
5168     case EXPR_FUNCTION:
5169       if (expr->value.function.esym == NULL
5170             || expr->ts.u.cl->length->expr_type == EXPR_CONSTANT)
5171         {
5172           gfc_conv_string_length (expr->ts.u.cl, expr, &se->pre);
5173           break;
5174         }
5175
5176       /* Map expressions involving the dummy arguments onto the actual
5177          argument expressions.  */
5178       gfc_init_interface_mapping (&mapping);
5179       formal = expr->symtree->n.sym->formal;
5180       arg = expr->value.function.actual;
5181
5182       /* Set se = NULL in the calls to the interface mapping, to suppress any
5183          backend stuff.  */
5184       for (; arg != NULL; arg = arg->next, formal = formal ? formal->next : NULL)
5185         {
5186           if (!arg->expr)
5187             continue;
5188           if (formal->sym)
5189           gfc_add_interface_mapping (&mapping, formal->sym, NULL, arg->expr);
5190         }
5191
5192       gfc_init_se (&tse, NULL);
5193
5194       /* Build the expression for the character length and convert it.  */
5195       gfc_apply_interface_mapping (&mapping, &tse, expr->ts.u.cl->length);
5196
5197       gfc_add_block_to_block (&se->pre, &tse.pre);
5198       gfc_add_block_to_block (&se->post, &tse.post);
5199       tse.expr = fold_convert (gfc_charlen_type_node, tse.expr);
5200       tse.expr = fold_build2_loc (input_location, MAX_EXPR,
5201                                   gfc_charlen_type_node, tse.expr,
5202                                   build_int_cst (gfc_charlen_type_node, 0));
5203       expr->ts.u.cl->backend_decl = tse.expr;
5204       gfc_free_interface_mapping (&mapping);
5205       break;
5206
5207     default:
5208       gfc_conv_string_length (expr->ts.u.cl, expr, &se->pre);
5209       break;
5210     }
5211 }
5212
5213
5214
5215 /* Convert an array for passing as an actual argument.  Expressions and
5216    vector subscripts are evaluated and stored in a temporary, which is then
5217    passed.  For whole arrays the descriptor is passed.  For array sections
5218    a modified copy of the descriptor is passed, but using the original data.
5219
5220    This function is also used for array pointer assignments, and there
5221    are three cases:
5222
5223      - se->want_pointer && !se->direct_byref
5224          EXPR is an actual argument.  On exit, se->expr contains a
5225          pointer to the array descriptor.
5226
5227      - !se->want_pointer && !se->direct_byref
5228          EXPR is an actual argument to an intrinsic function or the
5229          left-hand side of a pointer assignment.  On exit, se->expr
5230          contains the descriptor for EXPR.
5231
5232      - !se->want_pointer && se->direct_byref
5233          EXPR is the right-hand side of a pointer assignment and
5234          se->expr is the descriptor for the previously-evaluated
5235          left-hand side.  The function creates an assignment from
5236          EXPR to se->expr.  */
5237
5238 void
5239 gfc_conv_expr_descriptor (gfc_se * se, gfc_expr * expr, gfc_ss * ss)
5240 {
5241   gfc_loopinfo loop;
5242   gfc_ss *secss;
5243   gfc_ss_info *info;
5244   int need_tmp;
5245   int n;
5246   tree tmp;
5247   tree desc;
5248   stmtblock_t block;
5249   tree start;
5250   tree offset;
5251   int full;
5252   bool subref_array_target = false;
5253
5254   gcc_assert (ss != gfc_ss_terminator);
5255
5256   /* Special case things we know we can pass easily.  */
5257   switch (expr->expr_type)
5258     {
5259     case EXPR_VARIABLE:
5260       /* If we have a linear array section, we can pass it directly.
5261          Otherwise we need to copy it into a temporary.  */
5262
5263       /* Find the SS for the array section.  */
5264       secss = ss;
5265       while (secss != gfc_ss_terminator && secss->type != GFC_SS_SECTION)
5266         secss = secss->next;
5267
5268       gcc_assert (secss != gfc_ss_terminator);
5269       info = &secss->data.info;
5270
5271       /* Get the descriptor for the array.  */
5272       gfc_conv_ss_descriptor (&se->pre, secss, 0);
5273       desc = info->descriptor;
5274
5275       subref_array_target = se->direct_byref && is_subref_array (expr);
5276       need_tmp = gfc_ref_needs_temporary_p (expr->ref)
5277                         && !subref_array_target;
5278
5279       if (need_tmp)
5280         full = 0;
5281       else if (GFC_ARRAY_TYPE_P (TREE_TYPE (desc)))
5282         {
5283           /* Create a new descriptor if the array doesn't have one.  */
5284           full = 0;
5285         }
5286       else if (info->ref->u.ar.type == AR_FULL)
5287         full = 1;
5288       else if (se->direct_byref)
5289         full = 0;
5290       else
5291         full = gfc_full_array_ref_p (info->ref, NULL);
5292
5293       if (full)
5294         {
5295           if (se->direct_byref && !se->byref_noassign)
5296             {
5297               /* Copy the descriptor for pointer assignments.  */
5298               gfc_add_modify (&se->pre, se->expr, desc);
5299
5300               /* Add any offsets from subreferences.  */
5301               gfc_get_dataptr_offset (&se->pre, se->expr, desc, NULL_TREE,
5302                                       subref_array_target, expr);
5303             }
5304           else if (se->want_pointer)
5305             {
5306               /* We pass full arrays directly.  This means that pointers and
5307                  allocatable arrays should also work.  */
5308               se->expr = gfc_build_addr_expr (NULL_TREE, desc);
5309             }
5310           else
5311             {
5312               se->expr = desc;
5313             }
5314
5315           if (expr->ts.type == BT_CHARACTER)
5316             se->string_length = gfc_get_expr_charlen (expr);
5317
5318           return;
5319         }
5320       break;
5321       
5322     case EXPR_FUNCTION:
5323       /* A transformational function return value will be a temporary
5324          array descriptor.  We still need to go through the scalarizer
5325          to create the descriptor.  Elemental functions ar handled as
5326          arbitrary expressions, i.e. copy to a temporary.  */
5327       secss = ss;
5328       /* Look for the SS for this function.  */
5329       while (secss != gfc_ss_terminator
5330              && (secss->type != GFC_SS_FUNCTION || secss->expr != expr))
5331         secss = secss->next;
5332
5333       if (se->direct_byref)
5334         {
5335           gcc_assert (secss != gfc_ss_terminator);
5336
5337           /* For pointer assignments pass the descriptor directly.  */
5338           se->ss = secss;
5339           se->expr = gfc_build_addr_expr (NULL_TREE, se->expr);
5340           gfc_conv_expr (se, expr);
5341           return;
5342         }
5343
5344       if (secss == gfc_ss_terminator)
5345         {
5346           /* Elemental function.  */
5347           need_tmp = 1;
5348           if (expr->ts.type == BT_CHARACTER
5349                 && expr->ts.u.cl->length->expr_type != EXPR_CONSTANT)
5350             get_array_charlen (expr, se);
5351
5352           info = NULL;
5353         }
5354       else
5355         {
5356           /* Transformational function.  */
5357           info = &secss->data.info;
5358           need_tmp = 0;
5359         }
5360       break;
5361
5362     case EXPR_ARRAY:
5363       /* Constant array constructors don't need a temporary.  */
5364       if (ss->type == GFC_SS_CONSTRUCTOR
5365           && expr->ts.type != BT_CHARACTER
5366           && gfc_constant_array_constructor_p (expr->value.constructor))
5367         {
5368           need_tmp = 0;
5369           info = &ss->data.info;
5370           secss = ss;
5371         }
5372       else
5373         {
5374           need_tmp = 1;
5375           secss = NULL;
5376           info = NULL;
5377         }
5378       break;
5379
5380     default:
5381       /* Something complicated.  Copy it into a temporary.  */
5382       need_tmp = 1;
5383       secss = NULL;
5384       info = NULL;
5385       break;
5386     }
5387
5388   gfc_init_loopinfo (&loop);
5389
5390   /* Associate the SS with the loop.  */
5391   gfc_add_ss_to_loop (&loop, ss);
5392
5393   /* Tell the scalarizer not to bother creating loop variables, etc.  */
5394   if (!need_tmp)
5395     loop.array_parameter = 1;
5396   else
5397     /* The right-hand side of a pointer assignment mustn't use a temporary.  */
5398     gcc_assert (!se->direct_byref);
5399
5400   /* Setup the scalarizing loops and bounds.  */
5401   gfc_conv_ss_startstride (&loop);
5402
5403   if (need_tmp)
5404     {
5405       /* Tell the scalarizer to make a temporary.  */
5406       loop.temp_ss = gfc_get_ss ();
5407       loop.temp_ss->type = GFC_SS_TEMP;
5408       loop.temp_ss->next = gfc_ss_terminator;
5409
5410       if (expr->ts.type == BT_CHARACTER
5411             && !expr->ts.u.cl->backend_decl)
5412         get_array_charlen (expr, se);
5413
5414       loop.temp_ss->data.temp.type = gfc_typenode_for_spec (&expr->ts);
5415
5416       if (expr->ts.type == BT_CHARACTER)
5417         loop.temp_ss->string_length = expr->ts.u.cl->backend_decl;
5418       else
5419         loop.temp_ss->string_length = NULL;
5420
5421       se->string_length = loop.temp_ss->string_length;
5422       loop.temp_ss->data.temp.dimen = loop.dimen;
5423       gfc_add_ss_to_loop (&loop, loop.temp_ss);
5424     }
5425
5426   gfc_conv_loop_setup (&loop, & expr->where);
5427
5428   if (need_tmp)
5429     {
5430       /* Copy into a temporary and pass that.  We don't need to copy the data
5431          back because expressions and vector subscripts must be INTENT_IN.  */
5432       /* TODO: Optimize passing function return values.  */
5433       gfc_se lse;
5434       gfc_se rse;
5435
5436       /* Start the copying loops.  */
5437       gfc_mark_ss_chain_used (loop.temp_ss, 1);
5438       gfc_mark_ss_chain_used (ss, 1);
5439       gfc_start_scalarized_body (&loop, &block);
5440
5441       /* Copy each data element.  */
5442       gfc_init_se (&lse, NULL);
5443       gfc_copy_loopinfo_to_se (&lse, &loop);
5444       gfc_init_se (&rse, NULL);
5445       gfc_copy_loopinfo_to_se (&rse, &loop);
5446
5447       lse.ss = loop.temp_ss;
5448       rse.ss = ss;
5449
5450       gfc_conv_scalarized_array_ref (&lse, NULL);
5451       if (expr->ts.type == BT_CHARACTER)
5452         {
5453           gfc_conv_expr (&rse, expr);
5454           if (POINTER_TYPE_P (TREE_TYPE (rse.expr)))
5455             rse.expr = build_fold_indirect_ref_loc (input_location,
5456                                                 rse.expr);
5457         }
5458       else
5459         gfc_conv_expr_val (&rse, expr);
5460
5461       gfc_add_block_to_block (&block, &rse.pre);
5462       gfc_add_block_to_block (&block, &lse.pre);
5463
5464       lse.string_length = rse.string_length;
5465       tmp = gfc_trans_scalar_assign (&lse, &rse, expr->ts, true,
5466                                      expr->expr_type == EXPR_VARIABLE, true);
5467       gfc_add_expr_to_block (&block, tmp);
5468
5469       /* Finish the copying loops.  */
5470       gfc_trans_scalarizing_loops (&loop, &block);
5471
5472       desc = loop.temp_ss->data.info.descriptor;
5473     }
5474   else if (expr->expr_type == EXPR_FUNCTION)
5475     {
5476       desc = info->descriptor;
5477       se->string_length = ss->string_length;
5478     }
5479   else
5480     {
5481       /* We pass sections without copying to a temporary.  Make a new
5482          descriptor and point it at the section we want.  The loop variable
5483          limits will be the limits of the section.
5484          A function may decide to repack the array to speed up access, but
5485          we're not bothered about that here.  */
5486       int dim, ndim;
5487       tree parm;
5488       tree parmtype;
5489       tree stride;
5490       tree from;
5491       tree to;
5492       tree base;
5493
5494       /* Set the string_length for a character array.  */
5495       if (expr->ts.type == BT_CHARACTER)
5496         se->string_length =  gfc_get_expr_charlen (expr);
5497
5498       desc = info->descriptor;
5499       gcc_assert (secss && secss != gfc_ss_terminator);
5500       if (se->direct_byref && !se->byref_noassign)
5501         {
5502           /* For pointer assignments we fill in the destination.  */
5503           parm = se->expr;
5504           parmtype = TREE_TYPE (parm);
5505         }
5506       else
5507         {
5508           /* Otherwise make a new one.  */
5509           parmtype = gfc_get_element_type (TREE_TYPE (desc));
5510           parmtype = gfc_get_array_type_bounds (parmtype, loop.dimen, 0,
5511                                                 loop.from, loop.to, 0,
5512                                                 GFC_ARRAY_UNKNOWN, false);
5513           parm = gfc_create_var (parmtype, "parm");
5514         }
5515
5516       offset = gfc_index_zero_node;
5517       dim = 0;
5518
5519       /* The following can be somewhat confusing.  We have two
5520          descriptors, a new one and the original array.
5521          {parm, parmtype, dim} refer to the new one.
5522          {desc, type, n, secss, loop} refer to the original, which maybe
5523          a descriptorless array.
5524          The bounds of the scalarization are the bounds of the section.
5525          We don't have to worry about numeric overflows when calculating
5526          the offsets because all elements are within the array data.  */
5527
5528       /* Set the dtype.  */
5529       tmp = gfc_conv_descriptor_dtype (parm);
5530       gfc_add_modify (&loop.pre, tmp, gfc_get_dtype (parmtype));
5531
5532       /* Set offset for assignments to pointer only to zero if it is not
5533          the full array.  */
5534       if (se->direct_byref
5535           && info->ref && info->ref->u.ar.type != AR_FULL)
5536         base = gfc_index_zero_node;
5537       else if (GFC_ARRAY_TYPE_P (TREE_TYPE (desc)))
5538         base = gfc_evaluate_now (gfc_conv_array_offset (desc), &loop.pre);
5539       else
5540         base = NULL_TREE;
5541
5542       ndim = info->ref ? info->ref->u.ar.dimen : info->dimen;
5543       for (n = 0; n < ndim; n++)
5544         {
5545           stride = gfc_conv_array_stride (desc, n);
5546
5547           /* Work out the offset.  */
5548           if (info->ref
5549               && info->ref->u.ar.dimen_type[n] == DIMEN_ELEMENT)
5550             {
5551               gcc_assert (info->subscript[n]
5552                       && info->subscript[n]->type == GFC_SS_SCALAR);
5553               start = info->subscript[n]->data.scalar.expr;
5554             }
5555           else
5556             {
5557               /* Check we haven't somehow got out of sync.  */
5558               gcc_assert (info->dim[dim] == n);
5559
5560               /* Evaluate and remember the start of the section.  */
5561               start = info->start[n];
5562               stride = gfc_evaluate_now (stride, &loop.pre);
5563             }
5564
5565           tmp = gfc_conv_array_lbound (desc, n);
5566           tmp = fold_build2_loc (input_location, MINUS_EXPR, TREE_TYPE (tmp),
5567                                  start, tmp);
5568           tmp = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (tmp),
5569                                  tmp, stride);
5570           offset = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (tmp),
5571                                     offset, tmp);
5572
5573           if (info->ref
5574               && info->ref->u.ar.dimen_type[n] == DIMEN_ELEMENT)
5575             {
5576               /* For elemental dimensions, we only need the offset.  */
5577               continue;
5578             }
5579
5580           /* Vector subscripts need copying and are handled elsewhere.  */
5581           if (info->ref)
5582             gcc_assert (info->ref->u.ar.dimen_type[n] == DIMEN_RANGE);
5583
5584           /* Set the new lower bound.  */
5585           from = loop.from[dim];
5586           to = loop.to[dim];
5587
5588           /* If we have an array section or are assigning make sure that
5589              the lower bound is 1.  References to the full
5590              array should otherwise keep the original bounds.  */
5591           if ((!info->ref
5592                   || info->ref->u.ar.type != AR_FULL)
5593               && !integer_onep (from))
5594             {
5595               tmp = fold_build2_loc (input_location, MINUS_EXPR,
5596                                      gfc_array_index_type, gfc_index_one_node,
5597                                      from);
5598               to = fold_build2_loc (input_location, PLUS_EXPR,
5599                                     gfc_array_index_type, to, tmp);
5600               from = gfc_index_one_node;
5601             }
5602           gfc_conv_descriptor_lbound_set (&loop.pre, parm,
5603                                           gfc_rank_cst[dim], from);
5604
5605           /* Set the new upper bound.  */
5606           gfc_conv_descriptor_ubound_set (&loop.pre, parm,
5607                                           gfc_rank_cst[dim], to);
5608
5609           /* Multiply the stride by the section stride to get the
5610              total stride.  */
5611           stride = fold_build2_loc (input_location, MULT_EXPR,
5612                                     gfc_array_index_type,
5613                                     stride, info->stride[n]);
5614
5615           if (se->direct_byref
5616               && info->ref
5617               && info->ref->u.ar.type != AR_FULL)
5618             {
5619               base = fold_build2_loc (input_location, MINUS_EXPR,
5620                                       TREE_TYPE (base), base, stride);
5621             }
5622           else if (GFC_ARRAY_TYPE_P (TREE_TYPE (desc)))
5623             {
5624               tmp = gfc_conv_array_lbound (desc, n);
5625               tmp = fold_build2_loc (input_location, MINUS_EXPR,
5626                                      TREE_TYPE (base), tmp, loop.from[dim]);
5627               tmp = fold_build2_loc (input_location, MULT_EXPR,
5628                                      TREE_TYPE (base), tmp,
5629                                      gfc_conv_array_stride (desc, n));
5630               base = fold_build2_loc (input_location, PLUS_EXPR,
5631                                      TREE_TYPE (base), tmp, base);
5632             }
5633
5634           /* Store the new stride.  */
5635           gfc_conv_descriptor_stride_set (&loop.pre, parm,
5636                                           gfc_rank_cst[dim], stride);
5637
5638           dim++;
5639         }
5640
5641       if (se->data_not_needed)
5642         gfc_conv_descriptor_data_set (&loop.pre, parm,
5643                                       gfc_index_zero_node);
5644       else
5645         /* Point the data pointer at the 1st element in the section.  */
5646         gfc_get_dataptr_offset (&loop.pre, parm, desc, offset,
5647                                 subref_array_target, expr);
5648
5649       if ((se->direct_byref || GFC_ARRAY_TYPE_P (TREE_TYPE (desc)))
5650           && !se->data_not_needed)
5651         {
5652           /* Set the offset.  */
5653           gfc_conv_descriptor_offset_set (&loop.pre, parm, base);
5654         }
5655       else
5656         {
5657           /* Only the callee knows what the correct offset it, so just set
5658              it to zero here.  */
5659           gfc_conv_descriptor_offset_set (&loop.pre, parm, gfc_index_zero_node);
5660         }
5661       desc = parm;
5662     }
5663
5664   if (!se->direct_byref || se->byref_noassign)
5665     {
5666       /* Get a pointer to the new descriptor.  */
5667       if (se->want_pointer)
5668         se->expr = gfc_build_addr_expr (NULL_TREE, desc);
5669       else
5670         se->expr = desc;
5671     }
5672
5673   gfc_add_block_to_block (&se->pre, &loop.pre);
5674   gfc_add_block_to_block (&se->post, &loop.post);
5675
5676   /* Cleanup the scalarizer.  */
5677   gfc_cleanup_loop (&loop);
5678 }
5679
5680 /* Helper function for gfc_conv_array_parameter if array size needs to be
5681    computed.  */
5682
5683 static void
5684 array_parameter_size (tree desc, gfc_expr *expr, tree *size)
5685 {
5686   tree elem;
5687   if (GFC_ARRAY_TYPE_P (TREE_TYPE (desc)))
5688     *size = GFC_TYPE_ARRAY_SIZE (TREE_TYPE (desc));
5689   else if (expr->rank > 1)
5690     *size = build_call_expr_loc (input_location,
5691                              gfor_fndecl_size0, 1,
5692                              gfc_build_addr_expr (NULL, desc));
5693   else
5694     {
5695       tree ubound = gfc_conv_descriptor_ubound_get (desc, gfc_index_zero_node);
5696       tree lbound = gfc_conv_descriptor_lbound_get (desc, gfc_index_zero_node);
5697
5698       *size = fold_build2_loc (input_location, MINUS_EXPR,
5699                                gfc_array_index_type, ubound, lbound);
5700       *size = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
5701                                *size, gfc_index_one_node);
5702       *size = fold_build2_loc (input_location, MAX_EXPR, gfc_array_index_type,
5703                                *size, gfc_index_zero_node);
5704     }
5705   elem = TYPE_SIZE_UNIT (gfc_get_element_type (TREE_TYPE (desc)));
5706   *size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
5707                            *size, fold_convert (gfc_array_index_type, elem));
5708 }
5709
5710 /* Convert an array for passing as an actual parameter.  */
5711 /* TODO: Optimize passing g77 arrays.  */
5712
5713 void
5714 gfc_conv_array_parameter (gfc_se * se, gfc_expr * expr, gfc_ss * ss, bool g77,
5715                           const gfc_symbol *fsym, const char *proc_name,
5716                           tree *size)
5717 {
5718   tree ptr;
5719   tree desc;
5720   tree tmp = NULL_TREE;
5721   tree stmt;
5722   tree parent = DECL_CONTEXT (current_function_decl);
5723   bool full_array_var;
5724   bool this_array_result;
5725   bool contiguous;
5726   bool no_pack;
5727   bool array_constructor;
5728   bool good_allocatable;
5729   bool ultimate_ptr_comp;
5730   bool ultimate_alloc_comp;
5731   gfc_symbol *sym;
5732   stmtblock_t block;
5733   gfc_ref *ref;
5734
5735   ultimate_ptr_comp = false;
5736   ultimate_alloc_comp = false;
5737
5738   for (ref = expr->ref; ref; ref = ref->next)
5739     {
5740       if (ref->next == NULL)
5741         break;
5742
5743       if (ref->type == REF_COMPONENT)
5744         {
5745           ultimate_ptr_comp = ref->u.c.component->attr.pointer;
5746           ultimate_alloc_comp = ref->u.c.component->attr.allocatable;
5747         }
5748     }
5749
5750   full_array_var = false;
5751   contiguous = false;
5752
5753   if (expr->expr_type == EXPR_VARIABLE && ref && !ultimate_ptr_comp)
5754     full_array_var = gfc_full_array_ref_p (ref, &contiguous);
5755
5756   sym = full_array_var ? expr->symtree->n.sym : NULL;
5757
5758   /* The symbol should have an array specification.  */
5759   gcc_assert (!sym || sym->as || ref->u.ar.as);
5760
5761   if (expr->expr_type == EXPR_ARRAY && expr->ts.type == BT_CHARACTER)
5762     {
5763       get_array_ctor_strlen (&se->pre, expr->value.constructor, &tmp);
5764       expr->ts.u.cl->backend_decl = tmp;
5765       se->string_length = tmp;
5766     }
5767
5768   /* Is this the result of the enclosing procedure?  */
5769   this_array_result = (full_array_var && sym->attr.flavor == FL_PROCEDURE);
5770   if (this_array_result
5771         && (sym->backend_decl != current_function_decl)
5772         && (sym->backend_decl != parent))
5773     this_array_result = false;
5774
5775   /* Passing address of the array if it is not pointer or assumed-shape.  */
5776   if (full_array_var && g77 && !this_array_result)
5777     {
5778       tmp = gfc_get_symbol_decl (sym);
5779
5780       if (sym->ts.type == BT_CHARACTER)
5781         se->string_length = sym->ts.u.cl->backend_decl;
5782
5783       if (sym->ts.type == BT_DERIVED)
5784         {
5785           gfc_conv_expr_descriptor (se, expr, ss);
5786           se->expr = gfc_conv_array_data (se->expr);
5787           return;
5788         }
5789
5790       if (!sym->attr.pointer
5791             && sym->as
5792             && sym->as->type != AS_ASSUMED_SHAPE 
5793             && !sym->attr.allocatable)
5794         {
5795           /* Some variables are declared directly, others are declared as
5796              pointers and allocated on the heap.  */
5797           if (sym->attr.dummy || POINTER_TYPE_P (TREE_TYPE (tmp)))
5798             se->expr = tmp;
5799           else
5800             se->expr = gfc_build_addr_expr (NULL_TREE, tmp);
5801           if (size)
5802             array_parameter_size (tmp, expr, size);
5803           return;
5804         }
5805
5806       if (sym->attr.allocatable)
5807         {
5808           if (sym->attr.dummy || sym->attr.result)
5809             {
5810               gfc_conv_expr_descriptor (se, expr, ss);
5811               tmp = se->expr;
5812             }
5813           if (size)
5814             array_parameter_size (tmp, expr, size);
5815           se->expr = gfc_conv_array_data (tmp);
5816           return;
5817         }
5818     }
5819
5820   /* A convenient reduction in scope.  */
5821   contiguous = g77 && !this_array_result && contiguous;
5822
5823   /* There is no need to pack and unpack the array, if it is contiguous
5824      and not a deferred- or assumed-shape array, or if it is simply
5825      contiguous.  */
5826   no_pack = ((sym && sym->as
5827                   && !sym->attr.pointer
5828                   && sym->as->type != AS_DEFERRED
5829                   && sym->as->type != AS_ASSUMED_SHAPE)
5830                       ||
5831              (ref && ref->u.ar.as
5832                   && ref->u.ar.as->type != AS_DEFERRED
5833                   && ref->u.ar.as->type != AS_ASSUMED_SHAPE)
5834                       ||
5835              gfc_is_simply_contiguous (expr, false));
5836
5837   no_pack = contiguous && no_pack;
5838
5839   /* Array constructors are always contiguous and do not need packing.  */
5840   array_constructor = g77 && !this_array_result && expr->expr_type == EXPR_ARRAY;
5841
5842   /* Same is true of contiguous sections from allocatable variables.  */
5843   good_allocatable = contiguous
5844                        && expr->symtree
5845                        && expr->symtree->n.sym->attr.allocatable;
5846
5847   /* Or ultimate allocatable components.  */
5848   ultimate_alloc_comp = contiguous && ultimate_alloc_comp; 
5849
5850   if (no_pack || array_constructor || good_allocatable || ultimate_alloc_comp)
5851     {
5852       gfc_conv_expr_descriptor (se, expr, ss);
5853       if (expr->ts.type == BT_CHARACTER)
5854         se->string_length = expr->ts.u.cl->backend_decl;
5855       if (size)
5856         array_parameter_size (se->expr, expr, size);
5857       se->expr = gfc_conv_array_data (se->expr);
5858       return;
5859     }
5860
5861   if (this_array_result)
5862     {
5863       /* Result of the enclosing function.  */
5864       gfc_conv_expr_descriptor (se, expr, ss);
5865       if (size)
5866         array_parameter_size (se->expr, expr, size);
5867       se->expr = gfc_build_addr_expr (NULL_TREE, se->expr);
5868
5869       if (g77 && TREE_TYPE (TREE_TYPE (se->expr)) != NULL_TREE
5870               && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (TREE_TYPE (se->expr))))
5871         se->expr = gfc_conv_array_data (build_fold_indirect_ref_loc (input_location,
5872                                                                  se->expr));
5873
5874       return;
5875     }
5876   else
5877     {
5878       /* Every other type of array.  */
5879       se->want_pointer = 1;
5880       gfc_conv_expr_descriptor (se, expr, ss);
5881       if (size)
5882         array_parameter_size (build_fold_indirect_ref_loc (input_location,
5883                                                        se->expr),
5884                                   expr, size);
5885     }
5886
5887   /* Deallocate the allocatable components of structures that are
5888      not variable.  */
5889   if (expr->ts.type == BT_DERIVED
5890         && expr->ts.u.derived->attr.alloc_comp
5891         && expr->expr_type != EXPR_VARIABLE)
5892     {
5893       tmp = build_fold_indirect_ref_loc (input_location,
5894                                      se->expr);
5895       tmp = gfc_deallocate_alloc_comp (expr->ts.u.derived, tmp, expr->rank);
5896       gfc_add_expr_to_block (&se->post, tmp);
5897     }
5898
5899   if (g77 || (fsym && fsym->attr.contiguous
5900               && !gfc_is_simply_contiguous (expr, false)))
5901     {
5902       tree origptr = NULL_TREE;
5903
5904       desc = se->expr;
5905
5906       /* For contiguous arrays, save the original value of the descriptor.  */
5907       if (!g77)
5908         {
5909           origptr = gfc_create_var (pvoid_type_node, "origptr");
5910           tmp = build_fold_indirect_ref_loc (input_location, desc);
5911           tmp = gfc_conv_array_data (tmp);
5912           tmp = fold_build2_loc (input_location, MODIFY_EXPR,
5913                                  TREE_TYPE (origptr), origptr,
5914                                  fold_convert (TREE_TYPE (origptr), tmp));
5915           gfc_add_expr_to_block (&se->pre, tmp);
5916         }
5917
5918       /* Repack the array.  */
5919       if (gfc_option.warn_array_temp)
5920         {
5921           if (fsym)
5922             gfc_warning ("Creating array temporary at %L for argument '%s'",
5923                          &expr->where, fsym->name);
5924           else
5925             gfc_warning ("Creating array temporary at %L", &expr->where);
5926         }
5927
5928       ptr = build_call_expr_loc (input_location,
5929                              gfor_fndecl_in_pack, 1, desc);
5930
5931       if (fsym && fsym->attr.optional && sym && sym->attr.optional)
5932         {
5933           tmp = gfc_conv_expr_present (sym);
5934           ptr = build3 (COND_EXPR, TREE_TYPE (se->expr), tmp,
5935                         fold_convert (TREE_TYPE (se->expr), ptr),
5936                         fold_convert (TREE_TYPE (se->expr), null_pointer_node));
5937         }
5938
5939       ptr = gfc_evaluate_now (ptr, &se->pre);
5940
5941       /* Use the packed data for the actual argument, except for contiguous arrays,
5942          where the descriptor's data component is set.  */
5943       if (g77)
5944         se->expr = ptr;
5945       else
5946         {
5947           tmp = build_fold_indirect_ref_loc (input_location, desc);
5948           gfc_conv_descriptor_data_set (&se->pre, tmp, ptr);
5949         }
5950
5951       if (gfc_option.rtcheck & GFC_RTCHECK_ARRAY_TEMPS)
5952         {
5953           char * msg;
5954
5955           if (fsym && proc_name)
5956             asprintf (&msg, "An array temporary was created for argument "
5957                       "'%s' of procedure '%s'", fsym->name, proc_name);
5958           else
5959             asprintf (&msg, "An array temporary was created");
5960
5961           tmp = build_fold_indirect_ref_loc (input_location,
5962                                          desc);
5963           tmp = gfc_conv_array_data (tmp);
5964           tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
5965                                  fold_convert (TREE_TYPE (tmp), ptr), tmp);
5966
5967           if (fsym && fsym->attr.optional && sym && sym->attr.optional)
5968             tmp = fold_build2_loc (input_location, TRUTH_AND_EXPR,
5969                                    boolean_type_node,
5970                                    gfc_conv_expr_present (sym), tmp);
5971
5972           gfc_trans_runtime_check (false, true, tmp, &se->pre,
5973                                    &expr->where, msg);
5974           gfc_free (msg);
5975         }
5976
5977       gfc_start_block (&block);
5978
5979       /* Copy the data back.  */
5980       if (fsym == NULL || fsym->attr.intent != INTENT_IN)
5981         {
5982           tmp = build_call_expr_loc (input_location,
5983                                  gfor_fndecl_in_unpack, 2, desc, ptr);
5984           gfc_add_expr_to_block (&block, tmp);
5985         }
5986
5987       /* Free the temporary.  */
5988       tmp = gfc_call_free (convert (pvoid_type_node, ptr));
5989       gfc_add_expr_to_block (&block, tmp);
5990
5991       stmt = gfc_finish_block (&block);
5992
5993       gfc_init_block (&block);
5994       /* Only if it was repacked.  This code needs to be executed before the
5995          loop cleanup code.  */
5996       tmp = build_fold_indirect_ref_loc (input_location,
5997                                      desc);
5998       tmp = gfc_conv_array_data (tmp);
5999       tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
6000                              fold_convert (TREE_TYPE (tmp), ptr), tmp);
6001
6002       if (fsym && fsym->attr.optional && sym && sym->attr.optional)
6003         tmp = fold_build2_loc (input_location, TRUTH_AND_EXPR,
6004                                boolean_type_node,
6005                                gfc_conv_expr_present (sym), tmp);
6006
6007       tmp = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt (input_location));
6008
6009       gfc_add_expr_to_block (&block, tmp);
6010       gfc_add_block_to_block (&block, &se->post);
6011
6012       gfc_init_block (&se->post);
6013
6014       /* Reset the descriptor pointer.  */
6015       if (!g77)
6016         {
6017           tmp = build_fold_indirect_ref_loc (input_location, desc);
6018           gfc_conv_descriptor_data_set (&se->post, tmp, origptr);
6019         }
6020
6021       gfc_add_block_to_block (&se->post, &block);
6022     }
6023 }
6024
6025
6026 /* Generate code to deallocate an array, if it is allocated.  */
6027
6028 tree
6029 gfc_trans_dealloc_allocated (tree descriptor)
6030
6031   tree tmp;
6032   tree var;
6033   stmtblock_t block;
6034
6035   gfc_start_block (&block);
6036
6037   var = gfc_conv_descriptor_data_get (descriptor);
6038   STRIP_NOPS (var);
6039
6040   /* Call array_deallocate with an int * present in the second argument.
6041      Although it is ignored here, it's presence ensures that arrays that
6042      are already deallocated are ignored.  */
6043   tmp = gfc_deallocate_with_status (var, NULL_TREE, true, NULL);
6044   gfc_add_expr_to_block (&block, tmp);
6045
6046   /* Zero the data pointer.  */
6047   tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node,
6048                          var, build_int_cst (TREE_TYPE (var), 0));
6049   gfc_add_expr_to_block (&block, tmp);
6050
6051   return gfc_finish_block (&block);
6052 }
6053
6054
6055 /* This helper function calculates the size in words of a full array.  */
6056
6057 static tree
6058 get_full_array_size (stmtblock_t *block, tree decl, int rank)
6059 {
6060   tree idx;
6061   tree nelems;
6062   tree tmp;
6063   idx = gfc_rank_cst[rank - 1];
6064   nelems = gfc_conv_descriptor_ubound_get (decl, idx);
6065   tmp = gfc_conv_descriptor_lbound_get (decl, idx);
6066   tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
6067                          nelems, tmp);
6068   tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
6069                          tmp, gfc_index_one_node);
6070   tmp = gfc_evaluate_now (tmp, block);
6071
6072   nelems = gfc_conv_descriptor_stride_get (decl, idx);
6073   tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
6074                          nelems, tmp);
6075   return gfc_evaluate_now (tmp, block);
6076 }
6077
6078
6079 /* Allocate dest to the same size as src, and copy src -> dest.
6080    If no_malloc is set, only the copy is done.  */
6081
6082 static tree
6083 duplicate_allocatable (tree dest, tree src, tree type, int rank,
6084                        bool no_malloc)
6085 {
6086   tree tmp;
6087   tree size;
6088   tree nelems;
6089   tree null_cond;
6090   tree null_data;
6091   stmtblock_t block;
6092
6093   /* If the source is null, set the destination to null.  Then,
6094      allocate memory to the destination.  */
6095   gfc_init_block (&block);
6096
6097   if (rank == 0)
6098     {
6099       tmp = null_pointer_node;
6100       tmp = fold_build2_loc (input_location, MODIFY_EXPR, type, dest, tmp);
6101       gfc_add_expr_to_block (&block, tmp);
6102       null_data = gfc_finish_block (&block);
6103
6104       gfc_init_block (&block);
6105       size = TYPE_SIZE_UNIT (type);
6106       if (!no_malloc)
6107         {
6108           tmp = gfc_call_malloc (&block, type, size);
6109           tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node,
6110                                  dest, fold_convert (type, tmp));
6111           gfc_add_expr_to_block (&block, tmp);
6112         }
6113
6114       tmp = built_in_decls[BUILT_IN_MEMCPY];
6115       tmp = build_call_expr_loc (input_location, tmp, 3,
6116                                  dest, src, size);
6117     }
6118   else
6119     {
6120       gfc_conv_descriptor_data_set (&block, dest, null_pointer_node);
6121       null_data = gfc_finish_block (&block);
6122
6123       gfc_init_block (&block);
6124       nelems = get_full_array_size (&block, src, rank);
6125       tmp = fold_convert (gfc_array_index_type,
6126                           TYPE_SIZE_UNIT (gfc_get_element_type (type)));
6127       size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
6128                               nelems, tmp);
6129       if (!no_malloc)
6130         {
6131           tmp = TREE_TYPE (gfc_conv_descriptor_data_get (src));
6132           tmp = gfc_call_malloc (&block, tmp, size);
6133           gfc_conv_descriptor_data_set (&block, dest, tmp);
6134         }
6135
6136       /* We know the temporary and the value will be the same length,
6137          so can use memcpy.  */
6138       tmp = built_in_decls[BUILT_IN_MEMCPY];
6139       tmp = build_call_expr_loc (input_location,
6140                         tmp, 3, gfc_conv_descriptor_data_get (dest),
6141                         gfc_conv_descriptor_data_get (src), size);
6142     }
6143
6144   gfc_add_expr_to_block (&block, tmp);
6145   tmp = gfc_finish_block (&block);
6146
6147   /* Null the destination if the source is null; otherwise do
6148      the allocate and copy.  */
6149   if (rank == 0)
6150     null_cond = src;
6151   else
6152     null_cond = gfc_conv_descriptor_data_get (src);
6153
6154   null_cond = convert (pvoid_type_node, null_cond);
6155   null_cond = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
6156                                null_cond, null_pointer_node);
6157   return build3_v (COND_EXPR, null_cond, tmp, null_data);
6158 }
6159
6160
6161 /* Allocate dest to the same size as src, and copy data src -> dest.  */
6162
6163 tree
6164 gfc_duplicate_allocatable (tree dest, tree src, tree type, int rank)
6165 {
6166   return duplicate_allocatable (dest, src, type, rank, false);
6167 }
6168
6169
6170 /* Copy data src -> dest.  */
6171
6172 tree
6173 gfc_copy_allocatable_data (tree dest, tree src, tree type, int rank)
6174 {
6175   return duplicate_allocatable (dest, src, type, rank, true);
6176 }
6177
6178
6179 /* Recursively traverse an object of derived type, generating code to
6180    deallocate, nullify or copy allocatable components.  This is the work horse
6181    function for the functions named in this enum.  */
6182
6183 enum {DEALLOCATE_ALLOC_COMP = 1, NULLIFY_ALLOC_COMP, COPY_ALLOC_COMP,
6184       COPY_ONLY_ALLOC_COMP};
6185
6186 static tree
6187 structure_alloc_comps (gfc_symbol * der_type, tree decl,
6188                        tree dest, int rank, int purpose)
6189 {
6190   gfc_component *c;
6191   gfc_loopinfo loop;
6192   stmtblock_t fnblock;
6193   stmtblock_t loopbody;
6194   tree decl_type;
6195   tree tmp;
6196   tree comp;
6197   tree dcmp;
6198   tree nelems;
6199   tree index;
6200   tree var;
6201   tree cdecl;
6202   tree ctype;
6203   tree vref, dref;
6204   tree null_cond = NULL_TREE;
6205
6206   gfc_init_block (&fnblock);
6207
6208   decl_type = TREE_TYPE (decl);
6209
6210   if ((POINTER_TYPE_P (decl_type) && rank != 0)
6211         || (TREE_CODE (decl_type) == REFERENCE_TYPE && rank == 0))
6212
6213     decl = build_fold_indirect_ref_loc (input_location,
6214                                     decl);
6215
6216   /* Just in case in gets dereferenced.  */
6217   decl_type = TREE_TYPE (decl);
6218
6219   /* If this an array of derived types with allocatable components
6220      build a loop and recursively call this function.  */
6221   if (TREE_CODE (decl_type) == ARRAY_TYPE
6222         || GFC_DESCRIPTOR_TYPE_P (decl_type))
6223     {
6224       tmp = gfc_conv_array_data (decl);
6225       var = build_fold_indirect_ref_loc (input_location,
6226                                      tmp);
6227         
6228       /* Get the number of elements - 1 and set the counter.  */
6229       if (GFC_DESCRIPTOR_TYPE_P (decl_type))
6230         {
6231           /* Use the descriptor for an allocatable array.  Since this
6232              is a full array reference, we only need the descriptor
6233              information from dimension = rank.  */
6234           tmp = get_full_array_size (&fnblock, decl, rank);
6235           tmp = fold_build2_loc (input_location, MINUS_EXPR,
6236                                  gfc_array_index_type, tmp,
6237                                  gfc_index_one_node);
6238
6239           null_cond = gfc_conv_descriptor_data_get (decl);
6240           null_cond = fold_build2_loc (input_location, NE_EXPR,
6241                                        boolean_type_node, null_cond,
6242                                        build_int_cst (TREE_TYPE (null_cond), 0));
6243         }
6244       else
6245         {
6246           /*  Otherwise use the TYPE_DOMAIN information.  */
6247           tmp =  array_type_nelts (decl_type);
6248           tmp = fold_convert (gfc_array_index_type, tmp);
6249         }
6250
6251       /* Remember that this is, in fact, the no. of elements - 1.  */
6252       nelems = gfc_evaluate_now (tmp, &fnblock);
6253       index = gfc_create_var (gfc_array_index_type, "S");
6254
6255       /* Build the body of the loop.  */
6256       gfc_init_block (&loopbody);
6257
6258       vref = gfc_build_array_ref (var, index, NULL);
6259
6260       if (purpose == COPY_ALLOC_COMP)
6261         {
6262           if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (dest)))
6263             {
6264               tmp = gfc_duplicate_allocatable (dest, decl, decl_type, rank);
6265               gfc_add_expr_to_block (&fnblock, tmp);
6266             }
6267           tmp = build_fold_indirect_ref_loc (input_location,
6268                                          gfc_conv_array_data (dest));
6269           dref = gfc_build_array_ref (tmp, index, NULL);
6270           tmp = structure_alloc_comps (der_type, vref, dref, rank, purpose);
6271         }
6272       else if (purpose == COPY_ONLY_ALLOC_COMP)
6273         {
6274           tmp = build_fold_indirect_ref_loc (input_location,
6275                                          gfc_conv_array_data (dest));
6276           dref = gfc_build_array_ref (tmp, index, NULL);
6277           tmp = structure_alloc_comps (der_type, vref, dref, rank,
6278                                        COPY_ALLOC_COMP);
6279         }
6280       else
6281         tmp = structure_alloc_comps (der_type, vref, NULL_TREE, rank, purpose);
6282
6283       gfc_add_expr_to_block (&loopbody, tmp);
6284
6285       /* Build the loop and return.  */
6286       gfc_init_loopinfo (&loop);
6287       loop.dimen = 1;
6288       loop.from[0] = gfc_index_zero_node;
6289       loop.loopvar[0] = index;
6290       loop.to[0] = nelems;
6291       gfc_trans_scalarizing_loops (&loop, &loopbody);
6292       gfc_add_block_to_block (&fnblock, &loop.pre);
6293
6294       tmp = gfc_finish_block (&fnblock);
6295       if (null_cond != NULL_TREE)
6296         tmp = build3_v (COND_EXPR, null_cond, tmp,
6297                         build_empty_stmt (input_location));
6298
6299       return tmp;
6300     }
6301
6302   /* Otherwise, act on the components or recursively call self to
6303      act on a chain of components.  */
6304   for (c = der_type->components; c; c = c->next)
6305     {
6306       bool cmp_has_alloc_comps = (c->ts.type == BT_DERIVED)
6307                                     && c->ts.u.derived->attr.alloc_comp;
6308       cdecl = c->backend_decl;
6309       ctype = TREE_TYPE (cdecl);
6310
6311       switch (purpose)
6312         {
6313         case DEALLOCATE_ALLOC_COMP:
6314           /* Do not deallocate the components of ultimate pointer
6315              components.  */
6316           if (cmp_has_alloc_comps && !c->attr.pointer)
6317             {
6318               comp = fold_build3_loc (input_location, COMPONENT_REF, ctype,
6319                                       decl, cdecl, NULL_TREE);
6320               rank = c->as ? c->as->rank : 0;
6321               tmp = structure_alloc_comps (c->ts.u.derived, comp, NULL_TREE,
6322                                            rank, purpose);
6323               gfc_add_expr_to_block (&fnblock, tmp);
6324             }
6325
6326           if (c->attr.allocatable && c->attr.dimension)
6327             {
6328               comp = fold_build3_loc (input_location, COMPONENT_REF, ctype,
6329                                       decl, cdecl, NULL_TREE);
6330               tmp = gfc_trans_dealloc_allocated (comp);
6331               gfc_add_expr_to_block (&fnblock, tmp);
6332             }
6333           else if (c->attr.allocatable)
6334             {
6335               /* Allocatable scalar components.  */
6336               comp = fold_build3_loc (input_location, COMPONENT_REF, ctype,
6337                                       decl, cdecl, NULL_TREE);
6338
6339               tmp = gfc_deallocate_with_status (comp, NULL_TREE, true, NULL);
6340               gfc_add_expr_to_block (&fnblock, tmp);
6341
6342               tmp = fold_build2_loc (input_location, MODIFY_EXPR,
6343                                      void_type_node, comp,
6344                                      build_int_cst (TREE_TYPE (comp), 0));
6345               gfc_add_expr_to_block (&fnblock, tmp);
6346             }
6347           else if (c->ts.type == BT_CLASS && CLASS_DATA (c)->attr.allocatable)
6348             {
6349               /* Allocatable scalar CLASS components.  */
6350               comp = fold_build3_loc (input_location, COMPONENT_REF, ctype,
6351                                       decl, cdecl, NULL_TREE);
6352               
6353               /* Add reference to '$data' component.  */
6354               tmp = CLASS_DATA (c)->backend_decl;
6355               comp = fold_build3_loc (input_location, COMPONENT_REF,
6356                                       TREE_TYPE (tmp), comp, tmp, NULL_TREE);
6357
6358               tmp = gfc_deallocate_with_status (comp, NULL_TREE, true, NULL);
6359               gfc_add_expr_to_block (&fnblock, tmp);
6360
6361               tmp = fold_build2_loc (input_location, MODIFY_EXPR,
6362                                      void_type_node, comp,
6363                                      build_int_cst (TREE_TYPE (comp), 0));
6364               gfc_add_expr_to_block (&fnblock, tmp);
6365             }
6366           break;
6367
6368         case NULLIFY_ALLOC_COMP:
6369           if (c->attr.pointer)
6370             continue;
6371           else if (c->attr.allocatable && c->attr.dimension)
6372             {
6373               comp = fold_build3_loc (input_location, COMPONENT_REF, ctype,
6374                                       decl, cdecl, NULL_TREE);
6375               gfc_conv_descriptor_data_set (&fnblock, comp, null_pointer_node);
6376             }
6377           else if (c->attr.allocatable)
6378             {
6379               /* Allocatable scalar components.  */
6380               comp = fold_build3_loc (input_location, COMPONENT_REF, ctype,
6381                                       decl, cdecl, NULL_TREE);
6382               tmp = fold_build2_loc (input_location, MODIFY_EXPR,
6383                                      void_type_node, comp,
6384                                      build_int_cst (TREE_TYPE (comp), 0));
6385               gfc_add_expr_to_block (&fnblock, tmp);
6386             }
6387           else if (c->ts.type == BT_CLASS && CLASS_DATA (c)->attr.allocatable)
6388             {
6389               /* Allocatable scalar CLASS components.  */
6390               comp = fold_build3_loc (input_location, COMPONENT_REF, ctype,
6391                                       decl, cdecl, NULL_TREE);
6392               /* Add reference to '$data' component.  */
6393               tmp = CLASS_DATA (c)->backend_decl;
6394               comp = fold_build3_loc (input_location, COMPONENT_REF,
6395                                       TREE_TYPE (tmp), comp, tmp, NULL_TREE);
6396               tmp = fold_build2_loc (input_location, MODIFY_EXPR,
6397                                      void_type_node, comp,
6398                                      build_int_cst (TREE_TYPE (comp), 0));
6399               gfc_add_expr_to_block (&fnblock, tmp);
6400             }
6401           else if (cmp_has_alloc_comps)
6402             {
6403               comp = fold_build3_loc (input_location, COMPONENT_REF, ctype,
6404                                       decl, cdecl, NULL_TREE);
6405               rank = c->as ? c->as->rank : 0;
6406               tmp = structure_alloc_comps (c->ts.u.derived, comp, NULL_TREE,
6407                                            rank, purpose);
6408               gfc_add_expr_to_block (&fnblock, tmp);
6409             }
6410           break;
6411
6412         case COPY_ALLOC_COMP:
6413           if (c->attr.pointer)
6414             continue;
6415
6416           /* We need source and destination components.  */
6417           comp = fold_build3_loc (input_location, COMPONENT_REF, ctype, decl,
6418                                   cdecl, NULL_TREE);
6419           dcmp = fold_build3_loc (input_location, COMPONENT_REF, ctype, dest,
6420                                   cdecl, NULL_TREE);
6421           dcmp = fold_convert (TREE_TYPE (comp), dcmp);
6422
6423           if (c->attr.allocatable && !cmp_has_alloc_comps)
6424             {
6425               rank = c->as ? c->as->rank : 0;
6426               tmp = gfc_duplicate_allocatable (dcmp, comp, ctype, rank);
6427               gfc_add_expr_to_block (&fnblock, tmp);
6428             }
6429
6430           if (cmp_has_alloc_comps)
6431             {
6432               rank = c->as ? c->as->rank : 0;
6433               tmp = fold_convert (TREE_TYPE (dcmp), comp);
6434               gfc_add_modify (&fnblock, dcmp, tmp);
6435               tmp = structure_alloc_comps (c->ts.u.derived, comp, dcmp,
6436                                            rank, purpose);
6437               gfc_add_expr_to_block (&fnblock, tmp);
6438             }
6439           break;
6440
6441         default:
6442           gcc_unreachable ();
6443           break;
6444         }
6445     }
6446
6447   return gfc_finish_block (&fnblock);
6448 }
6449
6450 /* Recursively traverse an object of derived type, generating code to
6451    nullify allocatable components.  */
6452
6453 tree
6454 gfc_nullify_alloc_comp (gfc_symbol * der_type, tree decl, int rank)
6455 {
6456   return structure_alloc_comps (der_type, decl, NULL_TREE, rank,
6457                                 NULLIFY_ALLOC_COMP);
6458 }
6459
6460
6461 /* Recursively traverse an object of derived type, generating code to
6462    deallocate allocatable components.  */
6463
6464 tree
6465 gfc_deallocate_alloc_comp (gfc_symbol * der_type, tree decl, int rank)
6466 {
6467   return structure_alloc_comps (der_type, decl, NULL_TREE, rank,
6468                                 DEALLOCATE_ALLOC_COMP);
6469 }
6470
6471
6472 /* Recursively traverse an object of derived type, generating code to
6473    copy it and its allocatable components.  */
6474
6475 tree
6476 gfc_copy_alloc_comp (gfc_symbol * der_type, tree decl, tree dest, int rank)
6477 {
6478   return structure_alloc_comps (der_type, decl, dest, rank, COPY_ALLOC_COMP);
6479 }
6480
6481
6482 /* Recursively traverse an object of derived type, generating code to
6483    copy only its allocatable components.  */
6484
6485 tree
6486 gfc_copy_only_alloc_comp (gfc_symbol * der_type, tree decl, tree dest, int rank)
6487 {
6488   return structure_alloc_comps (der_type, decl, dest, rank, COPY_ONLY_ALLOC_COMP);
6489 }
6490
6491
6492 /* NULLIFY an allocatable/pointer array on function entry, free it on exit.
6493    Do likewise, recursively if necessary, with the allocatable components of
6494    derived types.  */
6495
6496 void
6497 gfc_trans_deferred_array (gfc_symbol * sym, gfc_wrapped_block * block)
6498 {
6499   tree type;
6500   tree tmp;
6501   tree descriptor;
6502   stmtblock_t init;
6503   stmtblock_t cleanup;
6504   locus loc;
6505   int rank;
6506   bool sym_has_alloc_comp;
6507
6508   sym_has_alloc_comp = (sym->ts.type == BT_DERIVED)
6509                           && sym->ts.u.derived->attr.alloc_comp;
6510
6511   /* Make sure the frontend gets these right.  */
6512   if (!(sym->attr.pointer || sym->attr.allocatable || sym_has_alloc_comp))
6513     fatal_error ("Possible frontend bug: Deferred array size without pointer, "
6514                  "allocatable attribute or derived type without allocatable "
6515                  "components.");
6516
6517   gfc_init_block (&init);
6518
6519   gcc_assert (TREE_CODE (sym->backend_decl) == VAR_DECL
6520                 || TREE_CODE (sym->backend_decl) == PARM_DECL);
6521
6522   if (sym->ts.type == BT_CHARACTER
6523       && !INTEGER_CST_P (sym->ts.u.cl->backend_decl))
6524     {
6525       gfc_conv_string_length (sym->ts.u.cl, NULL, &init);
6526       gfc_trans_vla_type_sizes (sym, &init);
6527     }
6528
6529   /* Dummy, use associated and result variables don't need anything special.  */
6530   if (sym->attr.dummy || sym->attr.use_assoc || sym->attr.result)
6531     {
6532       gfc_add_init_cleanup (block, gfc_finish_block (&init), NULL_TREE);
6533       return;
6534     }
6535
6536   gfc_get_backend_locus (&loc);
6537   gfc_set_backend_locus (&sym->declared_at);
6538   descriptor = sym->backend_decl;
6539
6540   /* Although static, derived types with default initializers and
6541      allocatable components must not be nulled wholesale; instead they
6542      are treated component by component.  */
6543   if (TREE_STATIC (descriptor) && !sym_has_alloc_comp)
6544     {
6545       /* SAVEd variables are not freed on exit.  */
6546       gfc_trans_static_array_pointer (sym);
6547
6548       gfc_add_init_cleanup (block, gfc_finish_block (&init), NULL_TREE);
6549       return;
6550     }
6551
6552   /* Get the descriptor type.  */
6553   type = TREE_TYPE (sym->backend_decl);
6554
6555   if (sym_has_alloc_comp && !(sym->attr.pointer || sym->attr.allocatable))
6556     {
6557       if (!sym->attr.save
6558           && !(TREE_STATIC (sym->backend_decl) && sym->attr.is_main_program))
6559         {
6560           if (sym->value == NULL
6561               || !gfc_has_default_initializer (sym->ts.u.derived))
6562             {
6563               rank = sym->as ? sym->as->rank : 0;
6564               tmp = gfc_nullify_alloc_comp (sym->ts.u.derived,
6565                                             descriptor, rank);
6566               gfc_add_expr_to_block (&init, tmp);
6567             }
6568           else
6569             gfc_init_default_dt (sym, &init, false);
6570         }
6571     }
6572   else if (!GFC_DESCRIPTOR_TYPE_P (type))
6573     {
6574       /* If the backend_decl is not a descriptor, we must have a pointer
6575          to one.  */
6576       descriptor = build_fold_indirect_ref_loc (input_location,
6577                                                 sym->backend_decl);
6578       type = TREE_TYPE (descriptor);
6579     }
6580   
6581   /* NULLIFY the data pointer.  */
6582   if (GFC_DESCRIPTOR_TYPE_P (type) && !sym->attr.save)
6583     gfc_conv_descriptor_data_set (&init, descriptor, null_pointer_node);
6584
6585   gfc_init_block (&cleanup);
6586   gfc_set_backend_locus (&loc);
6587
6588   /* Allocatable arrays need to be freed when they go out of scope.
6589      The allocatable components of pointers must not be touched.  */
6590   if (sym_has_alloc_comp && !(sym->attr.function || sym->attr.result)
6591       && !sym->attr.pointer && !sym->attr.save)
6592     {
6593       int rank;
6594       rank = sym->as ? sym->as->rank : 0;
6595       tmp = gfc_deallocate_alloc_comp (sym->ts.u.derived, descriptor, rank);
6596       gfc_add_expr_to_block (&cleanup, tmp);
6597     }
6598
6599   if (sym->attr.allocatable && sym->attr.dimension
6600       && !sym->attr.save && !sym->attr.result)
6601     {
6602       tmp = gfc_trans_dealloc_allocated (sym->backend_decl);
6603       gfc_add_expr_to_block (&cleanup, tmp);
6604     }
6605
6606   gfc_add_init_cleanup (block, gfc_finish_block (&init),
6607                         gfc_finish_block (&cleanup));
6608 }
6609
6610 /************ Expression Walking Functions ******************/
6611
6612 /* Walk a variable reference.
6613
6614    Possible extension - multiple component subscripts.
6615     x(:,:) = foo%a(:)%b(:)
6616    Transforms to
6617     forall (i=..., j=...)
6618       x(i,j) = foo%a(j)%b(i)
6619     end forall
6620    This adds a fair amount of complexity because you need to deal with more
6621    than one ref.  Maybe handle in a similar manner to vector subscripts.
6622    Maybe not worth the effort.  */
6623
6624
6625 static gfc_ss *
6626 gfc_walk_variable_expr (gfc_ss * ss, gfc_expr * expr)
6627 {
6628   gfc_ref *ref;
6629   gfc_array_ref *ar;
6630   gfc_ss *newss;
6631   int n;
6632
6633   for (ref = expr->ref; ref; ref = ref->next)
6634     if (ref->type == REF_ARRAY && ref->u.ar.type != AR_ELEMENT)
6635       break;
6636
6637   for (; ref; ref = ref->next)
6638     {
6639       if (ref->type == REF_SUBSTRING)
6640         {
6641           newss = gfc_get_ss ();
6642           newss->type = GFC_SS_SCALAR;
6643           newss->expr = ref->u.ss.start;
6644           newss->next = ss;
6645           ss = newss;
6646
6647           newss = gfc_get_ss ();
6648           newss->type = GFC_SS_SCALAR;
6649           newss->expr = ref->u.ss.end;
6650           newss->next = ss;
6651           ss = newss;
6652         }
6653
6654       /* We're only interested in array sections from now on.  */
6655       if (ref->type != REF_ARRAY)
6656         continue;
6657
6658       ar = &ref->u.ar;
6659
6660       if (ar->as->rank == 0)
6661         {
6662           /* Scalar coarray.  */
6663           continue;
6664         }
6665
6666       switch (ar->type)
6667         {
6668         case AR_ELEMENT:
6669           for (n = 0; n < ar->dimen; n++)
6670             {
6671               newss = gfc_get_ss ();
6672               newss->type = GFC_SS_SCALAR;
6673               newss->expr = ar->start[n];
6674               newss->next = ss;
6675               ss = newss;
6676             }
6677           break;
6678
6679         case AR_FULL:
6680           newss = gfc_get_ss ();
6681           newss->type = GFC_SS_SECTION;
6682           newss->expr = expr;
6683           newss->next = ss;
6684           newss->data.info.dimen = ar->as->rank;
6685           newss->data.info.ref = ref;
6686
6687           /* Make sure array is the same as array(:,:), this way
6688              we don't need to special case all the time.  */
6689           ar->dimen = ar->as->rank;
6690           for (n = 0; n < ar->dimen; n++)
6691             {
6692               newss->data.info.dim[n] = n;
6693               ar->dimen_type[n] = DIMEN_RANGE;
6694
6695               gcc_assert (ar->start[n] == NULL);
6696               gcc_assert (ar->end[n] == NULL);
6697               gcc_assert (ar->stride[n] == NULL);
6698             }
6699           ss = newss;
6700           break;
6701
6702         case AR_SECTION:
6703           newss = gfc_get_ss ();
6704           newss->type = GFC_SS_SECTION;
6705           newss->expr = expr;
6706           newss->next = ss;
6707           newss->data.info.dimen = 0;
6708           newss->data.info.ref = ref;
6709
6710           /* We add SS chains for all the subscripts in the section.  */
6711           for (n = 0; n < ar->dimen; n++)
6712             {
6713               gfc_ss *indexss;
6714
6715               switch (ar->dimen_type[n])
6716                 {
6717                 case DIMEN_ELEMENT:
6718                   /* Add SS for elemental (scalar) subscripts.  */
6719                   gcc_assert (ar->start[n]);
6720                   indexss = gfc_get_ss ();
6721                   indexss->type = GFC_SS_SCALAR;
6722                   indexss->expr = ar->start[n];
6723                   indexss->next = gfc_ss_terminator;
6724                   indexss->loop_chain = gfc_ss_terminator;
6725                   newss->data.info.subscript[n] = indexss;
6726                   break;
6727
6728                 case DIMEN_RANGE:
6729                   /* We don't add anything for sections, just remember this
6730                      dimension for later.  */
6731                   newss->data.info.dim[newss->data.info.dimen] = n;
6732                   newss->data.info.dimen++;
6733                   break;
6734
6735                 case DIMEN_VECTOR:
6736                   /* Create a GFC_SS_VECTOR index in which we can store
6737                      the vector's descriptor.  */
6738                   indexss = gfc_get_ss ();
6739                   indexss->type = GFC_SS_VECTOR;
6740                   indexss->expr = ar->start[n];
6741                   indexss->next = gfc_ss_terminator;
6742                   indexss->loop_chain = gfc_ss_terminator;
6743                   newss->data.info.subscript[n] = indexss;
6744                   newss->data.info.dim[newss->data.info.dimen] = n;
6745                   newss->data.info.dimen++;
6746                   break;
6747
6748                 default:
6749                   /* We should know what sort of section it is by now.  */
6750                   gcc_unreachable ();
6751                 }
6752             }
6753           /* We should have at least one non-elemental dimension.  */
6754           gcc_assert (newss->data.info.dimen > 0);
6755           ss = newss;
6756           break;
6757
6758         default:
6759           /* We should know what sort of section it is by now.  */
6760           gcc_unreachable ();
6761         }
6762
6763     }
6764   return ss;
6765 }
6766
6767
6768 /* Walk an expression operator. If only one operand of a binary expression is
6769    scalar, we must also add the scalar term to the SS chain.  */
6770
6771 static gfc_ss *
6772 gfc_walk_op_expr (gfc_ss * ss, gfc_expr * expr)
6773 {
6774   gfc_ss *head;
6775   gfc_ss *head2;
6776   gfc_ss *newss;
6777
6778   head = gfc_walk_subexpr (ss, expr->value.op.op1);
6779   if (expr->value.op.op2 == NULL)
6780     head2 = head;
6781   else
6782     head2 = gfc_walk_subexpr (head, expr->value.op.op2);
6783
6784   /* All operands are scalar.  Pass back and let the caller deal with it.  */
6785   if (head2 == ss)
6786     return head2;
6787
6788   /* All operands require scalarization.  */
6789   if (head != ss && (expr->value.op.op2 == NULL || head2 != head))
6790     return head2;
6791
6792   /* One of the operands needs scalarization, the other is scalar.
6793      Create a gfc_ss for the scalar expression.  */
6794   newss = gfc_get_ss ();
6795   newss->type = GFC_SS_SCALAR;
6796   if (head == ss)
6797     {
6798       /* First operand is scalar.  We build the chain in reverse order, so
6799          add the scalar SS after the second operand.  */
6800       head = head2;
6801       while (head && head->next != ss)
6802         head = head->next;
6803       /* Check we haven't somehow broken the chain.  */
6804       gcc_assert (head);
6805       newss->next = ss;
6806       head->next = newss;
6807       newss->expr = expr->value.op.op1;
6808     }
6809   else                          /* head2 == head */
6810     {
6811       gcc_assert (head2 == head);
6812       /* Second operand is scalar.  */
6813       newss->next = head2;
6814       head2 = newss;
6815       newss->expr = expr->value.op.op2;
6816     }
6817
6818   return head2;
6819 }
6820
6821
6822 /* Reverse a SS chain.  */
6823
6824 gfc_ss *
6825 gfc_reverse_ss (gfc_ss * ss)
6826 {
6827   gfc_ss *next;
6828   gfc_ss *head;
6829
6830   gcc_assert (ss != NULL);
6831
6832   head = gfc_ss_terminator;
6833   while (ss != gfc_ss_terminator)
6834     {
6835       next = ss->next;
6836       /* Check we didn't somehow break the chain.  */
6837       gcc_assert (next != NULL);
6838       ss->next = head;
6839       head = ss;
6840       ss = next;
6841     }
6842
6843   return (head);
6844 }
6845
6846
6847 /* Walk the arguments of an elemental function.  */
6848
6849 gfc_ss *
6850 gfc_walk_elemental_function_args (gfc_ss * ss, gfc_actual_arglist *arg,
6851                                   gfc_ss_type type)
6852 {
6853   int scalar;
6854   gfc_ss *head;
6855   gfc_ss *tail;
6856   gfc_ss *newss;
6857
6858   head = gfc_ss_terminator;
6859   tail = NULL;
6860   scalar = 1;
6861   for (; arg; arg = arg->next)
6862     {
6863       if (!arg->expr)
6864         continue;
6865
6866       newss = gfc_walk_subexpr (head, arg->expr);
6867       if (newss == head)
6868         {
6869           /* Scalar argument.  */
6870           newss = gfc_get_ss ();
6871           newss->type = type;
6872           newss->expr = arg->expr;
6873           newss->next = head;
6874         }
6875       else
6876         scalar = 0;
6877
6878       head = newss;
6879       if (!tail)
6880         {
6881           tail = head;
6882           while (tail->next != gfc_ss_terminator)
6883             tail = tail->next;
6884         }
6885     }
6886
6887   if (scalar)
6888     {
6889       /* If all the arguments are scalar we don't need the argument SS.  */
6890       gfc_free_ss_chain (head);
6891       /* Pass it back.  */
6892       return ss;
6893     }
6894
6895   /* Add it onto the existing chain.  */
6896   tail->next = ss;
6897   return head;
6898 }
6899
6900
6901 /* Walk a function call.  Scalar functions are passed back, and taken out of
6902    scalarization loops.  For elemental functions we walk their arguments.
6903    The result of functions returning arrays is stored in a temporary outside
6904    the loop, so that the function is only called once.  Hence we do not need
6905    to walk their arguments.  */
6906
6907 static gfc_ss *
6908 gfc_walk_function_expr (gfc_ss * ss, gfc_expr * expr)
6909 {
6910   gfc_ss *newss;
6911   gfc_intrinsic_sym *isym;
6912   gfc_symbol *sym;
6913   gfc_component *comp = NULL;
6914   int n;
6915
6916   isym = expr->value.function.isym;
6917
6918   /* Handle intrinsic functions separately.  */
6919   if (isym)
6920     return gfc_walk_intrinsic_function (ss, expr, isym);
6921
6922   sym = expr->value.function.esym;
6923   if (!sym)
6924       sym = expr->symtree->n.sym;
6925
6926   /* A function that returns arrays.  */
6927   gfc_is_proc_ptr_comp (expr, &comp);
6928   if ((!comp && gfc_return_by_reference (sym) && sym->result->attr.dimension)
6929       || (comp && comp->attr.dimension))
6930     {
6931       newss = gfc_get_ss ();
6932       newss->type = GFC_SS_FUNCTION;
6933       newss->expr = expr;
6934       newss->next = ss;
6935       newss->data.info.dimen = expr->rank;
6936       for (n = 0; n < newss->data.info.dimen; n++)
6937         newss->data.info.dim[n] = n;
6938       return newss;
6939     }
6940
6941   /* Walk the parameters of an elemental function.  For now we always pass
6942      by reference.  */
6943   if (sym->attr.elemental)
6944     return gfc_walk_elemental_function_args (ss, expr->value.function.actual,
6945                                              GFC_SS_REFERENCE);
6946
6947   /* Scalar functions are OK as these are evaluated outside the scalarization
6948      loop.  Pass back and let the caller deal with it.  */
6949   return ss;
6950 }
6951
6952
6953 /* An array temporary is constructed for array constructors.  */
6954
6955 static gfc_ss *
6956 gfc_walk_array_constructor (gfc_ss * ss, gfc_expr * expr)
6957 {
6958   gfc_ss *newss;
6959   int n;
6960
6961   newss = gfc_get_ss ();
6962   newss->type = GFC_SS_CONSTRUCTOR;
6963   newss->expr = expr;
6964   newss->next = ss;
6965   newss->data.info.dimen = expr->rank;
6966   for (n = 0; n < expr->rank; n++)
6967     newss->data.info.dim[n] = n;
6968
6969   return newss;
6970 }
6971
6972
6973 /* Walk an expression.  Add walked expressions to the head of the SS chain.
6974    A wholly scalar expression will not be added.  */
6975
6976 static gfc_ss *
6977 gfc_walk_subexpr (gfc_ss * ss, gfc_expr * expr)
6978 {
6979   gfc_ss *head;
6980
6981   switch (expr->expr_type)
6982     {
6983     case EXPR_VARIABLE:
6984       head = gfc_walk_variable_expr (ss, expr);
6985       return head;
6986
6987     case EXPR_OP:
6988       head = gfc_walk_op_expr (ss, expr);
6989       return head;
6990
6991     case EXPR_FUNCTION:
6992       head = gfc_walk_function_expr (ss, expr);
6993       return head;
6994
6995     case EXPR_CONSTANT:
6996     case EXPR_NULL:
6997     case EXPR_STRUCTURE:
6998       /* Pass back and let the caller deal with it.  */
6999       break;
7000
7001     case EXPR_ARRAY:
7002       head = gfc_walk_array_constructor (ss, expr);
7003       return head;
7004
7005     case EXPR_SUBSTRING:
7006       /* Pass back and let the caller deal with it.  */
7007       break;
7008
7009     default:
7010       internal_error ("bad expression type during walk (%d)",
7011                       expr->expr_type);
7012     }
7013   return ss;
7014 }
7015
7016
7017 /* Entry point for expression walking.
7018    A return value equal to the passed chain means this is
7019    a scalar expression.  It is up to the caller to take whatever action is
7020    necessary to translate these.  */
7021
7022 gfc_ss *
7023 gfc_walk_expr (gfc_expr * expr)
7024 {
7025   gfc_ss *res;
7026
7027   res = gfc_walk_subexpr (gfc_ss_terminator, expr);
7028   return gfc_reverse_ss (res);
7029 }