OSDN Git Service

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