OSDN Git Service

In gcc/objc/:
[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 static 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   init = build_constructor (tmptype, v);
1735
1736   TREE_CONSTANT (init) = 1;
1737   TREE_STATIC (init) = 1;
1738
1739   tmp = gfc_create_var (tmptype, "A");
1740   TREE_STATIC (tmp) = 1;
1741   TREE_CONSTANT (tmp) = 1;
1742   TREE_READONLY (tmp) = 1;
1743   DECL_INITIAL (tmp) = init;
1744
1745   return tmp;
1746 }
1747
1748
1749 /* Translate a constant EXPR_ARRAY array constructor for the scalarizer.
1750    This mostly initializes the scalarizer state info structure with the
1751    appropriate values to directly use the array created by the function
1752    gfc_build_constant_array_constructor.  */
1753
1754 static void
1755 gfc_trans_constant_array_constructor (gfc_loopinfo * loop,
1756                                       gfc_ss * ss, tree type)
1757 {
1758   gfc_ss_info *info;
1759   tree tmp;
1760   int i;
1761
1762   tmp = gfc_build_constant_array_constructor (ss->expr, type);
1763
1764   info = &ss->data.info;
1765
1766   info->descriptor = tmp;
1767   info->data = gfc_build_addr_expr (NULL_TREE, tmp);
1768   info->offset = gfc_index_zero_node;
1769
1770   for (i = 0; i < info->dimen; i++)
1771     {
1772       info->delta[i] = gfc_index_zero_node;
1773       info->start[i] = gfc_index_zero_node;
1774       info->end[i] = gfc_index_zero_node;
1775       info->stride[i] = gfc_index_one_node;
1776       info->dim[i] = i;
1777     }
1778
1779   if (info->dimen > loop->temp_dim)
1780     loop->temp_dim = info->dimen;
1781 }
1782
1783 /* Helper routine of gfc_trans_array_constructor to determine if the
1784    bounds of the loop specified by LOOP are constant and simple enough
1785    to use with gfc_trans_constant_array_constructor.  Returns the
1786    iteration count of the loop if suitable, and NULL_TREE otherwise.  */
1787
1788 static tree
1789 constant_array_constructor_loop_size (gfc_loopinfo * loop)
1790 {
1791   tree size = gfc_index_one_node;
1792   tree tmp;
1793   int i;
1794
1795   for (i = 0; i < loop->dimen; i++)
1796     {
1797       /* If the bounds aren't constant, return NULL_TREE.  */
1798       if (!INTEGER_CST_P (loop->from[i]) || !INTEGER_CST_P (loop->to[i]))
1799         return NULL_TREE;
1800       if (!integer_zerop (loop->from[i]))
1801         {
1802           /* Only allow nonzero "from" in one-dimensional arrays.  */
1803           if (loop->dimen != 1)
1804             return NULL_TREE;
1805           tmp = fold_build2_loc (input_location, MINUS_EXPR,
1806                                  gfc_array_index_type,
1807                                  loop->to[i], loop->from[i]);
1808         }
1809       else
1810         tmp = loop->to[i];
1811       tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
1812                              tmp, gfc_index_one_node);
1813       size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
1814                               size, tmp);
1815     }
1816
1817   return size;
1818 }
1819
1820
1821 /* Array constructors are handled by constructing a temporary, then using that
1822    within the scalarization loop.  This is not optimal, but seems by far the
1823    simplest method.  */
1824
1825 static void
1826 gfc_trans_array_constructor (gfc_loopinfo * loop, gfc_ss * ss, locus * where)
1827 {
1828   gfc_constructor_base c;
1829   tree offset;
1830   tree offsetvar;
1831   tree desc;
1832   tree type;
1833   bool dynamic;
1834   bool old_first_len, old_typespec_chararray_ctor;
1835   tree old_first_len_val;
1836
1837   /* Save the old values for nested checking.  */
1838   old_first_len = first_len;
1839   old_first_len_val = first_len_val;
1840   old_typespec_chararray_ctor = typespec_chararray_ctor;
1841
1842   /* Do bounds-checking here and in gfc_trans_array_ctor_element only if no
1843      typespec was given for the array constructor.  */
1844   typespec_chararray_ctor = (ss->expr->ts.u.cl
1845                              && ss->expr->ts.u.cl->length_from_typespec);
1846
1847   if ((gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
1848       && ss->expr->ts.type == BT_CHARACTER && !typespec_chararray_ctor)
1849     {  
1850       first_len_val = gfc_create_var (gfc_charlen_type_node, "len");
1851       first_len = true;
1852     }
1853
1854   ss->data.info.dimen = loop->dimen;
1855
1856   c = ss->expr->value.constructor;
1857   if (ss->expr->ts.type == BT_CHARACTER)
1858     {
1859       bool const_string;
1860       
1861       /* get_array_ctor_strlen walks the elements of the constructor, if a
1862          typespec was given, we already know the string length and want the one
1863          specified there.  */
1864       if (typespec_chararray_ctor && ss->expr->ts.u.cl->length
1865           && ss->expr->ts.u.cl->length->expr_type != EXPR_CONSTANT)
1866         {
1867           gfc_se length_se;
1868
1869           const_string = false;
1870           gfc_init_se (&length_se, NULL);
1871           gfc_conv_expr_type (&length_se, ss->expr->ts.u.cl->length,
1872                               gfc_charlen_type_node);
1873           ss->string_length = length_se.expr;
1874           gfc_add_block_to_block (&loop->pre, &length_se.pre);
1875           gfc_add_block_to_block (&loop->post, &length_se.post);
1876         }
1877       else
1878         const_string = get_array_ctor_strlen (&loop->pre, c,
1879                                               &ss->string_length);
1880
1881       /* Complex character array constructors should have been taken care of
1882          and not end up here.  */
1883       gcc_assert (ss->string_length);
1884
1885       ss->expr->ts.u.cl->backend_decl = ss->string_length;
1886
1887       type = gfc_get_character_type_len (ss->expr->ts.kind, ss->string_length);
1888       if (const_string)
1889         type = build_pointer_type (type);
1890     }
1891   else
1892     type = gfc_typenode_for_spec (&ss->expr->ts);
1893
1894   /* See if the constructor determines the loop bounds.  */
1895   dynamic = false;
1896
1897   if (ss->expr->shape && loop->dimen > 1 && loop->to[0] == NULL_TREE)
1898     {
1899       /* We have a multidimensional parameter.  */
1900       int n;
1901       for (n = 0; n < ss->expr->rank; n++)
1902       {
1903         loop->from[n] = gfc_index_zero_node;
1904         loop->to[n] = gfc_conv_mpz_to_tree (ss->expr->shape [n],
1905                                             gfc_index_integer_kind);
1906         loop->to[n] = fold_build2_loc (input_location, MINUS_EXPR,
1907                                        gfc_array_index_type,
1908                                        loop->to[n], gfc_index_one_node);
1909       }
1910     }
1911
1912   if (loop->to[0] == NULL_TREE)
1913     {
1914       mpz_t size;
1915
1916       /* We should have a 1-dimensional, zero-based loop.  */
1917       gcc_assert (loop->dimen == 1);
1918       gcc_assert (integer_zerop (loop->from[0]));
1919
1920       /* Split the constructor size into a static part and a dynamic part.
1921          Allocate the static size up-front and record whether the dynamic
1922          size might be nonzero.  */
1923       mpz_init (size);
1924       dynamic = gfc_get_array_constructor_size (&size, c);
1925       mpz_sub_ui (size, size, 1);
1926       loop->to[0] = gfc_conv_mpz_to_tree (size, gfc_index_integer_kind);
1927       mpz_clear (size);
1928     }
1929
1930   /* Special case constant array constructors.  */
1931   if (!dynamic)
1932     {
1933       unsigned HOST_WIDE_INT nelem = gfc_constant_array_constructor_p (c);
1934       if (nelem > 0)
1935         {
1936           tree size = constant_array_constructor_loop_size (loop);
1937           if (size && compare_tree_int (size, nelem) == 0)
1938             {
1939               gfc_trans_constant_array_constructor (loop, ss, type);
1940               goto finish;
1941             }
1942         }
1943     }
1944
1945   gfc_trans_create_temp_array (&loop->pre, &loop->post, loop, &ss->data.info,
1946                                type, NULL_TREE, dynamic, true, false, where);
1947
1948   desc = ss->data.info.descriptor;
1949   offset = gfc_index_zero_node;
1950   offsetvar = gfc_create_var_np (gfc_array_index_type, "offset");
1951   TREE_NO_WARNING (offsetvar) = 1;
1952   TREE_USED (offsetvar) = 0;
1953   gfc_trans_array_constructor_value (&loop->pre, type, desc, c,
1954                                      &offset, &offsetvar, dynamic);
1955
1956   /* If the array grows dynamically, the upper bound of the loop variable
1957      is determined by the array's final upper bound.  */
1958   if (dynamic)
1959     loop->to[0] = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[0]);
1960
1961   if (TREE_USED (offsetvar))
1962     pushdecl (offsetvar);
1963   else
1964     gcc_assert (INTEGER_CST_P (offset));
1965 #if 0
1966   /* Disable bound checking for now because it's probably broken.  */
1967   if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
1968     {
1969       gcc_unreachable ();
1970     }
1971 #endif
1972
1973 finish:
1974   /* Restore old values of globals.  */
1975   first_len = old_first_len;
1976   first_len_val = old_first_len_val;
1977   typespec_chararray_ctor = old_typespec_chararray_ctor;
1978 }
1979
1980
1981 /* INFO describes a GFC_SS_SECTION in loop LOOP, and this function is
1982    called after evaluating all of INFO's vector dimensions.  Go through
1983    each such vector dimension and see if we can now fill in any missing
1984    loop bounds.  */
1985
1986 static void
1987 gfc_set_vector_loop_bounds (gfc_loopinfo * loop, gfc_ss_info * info)
1988 {
1989   gfc_se se;
1990   tree tmp;
1991   tree desc;
1992   tree zero;
1993   int n;
1994   int dim;
1995
1996   for (n = 0; n < loop->dimen; n++)
1997     {
1998       dim = info->dim[n];
1999       if (info->ref->u.ar.dimen_type[dim] == DIMEN_VECTOR
2000           && loop->to[n] == NULL)
2001         {
2002           /* Loop variable N indexes vector dimension DIM, and we don't
2003              yet know the upper bound of loop variable N.  Set it to the
2004              difference between the vector's upper and lower bounds.  */
2005           gcc_assert (loop->from[n] == gfc_index_zero_node);
2006           gcc_assert (info->subscript[dim]
2007                       && info->subscript[dim]->type == GFC_SS_VECTOR);
2008
2009           gfc_init_se (&se, NULL);
2010           desc = info->subscript[dim]->data.info.descriptor;
2011           zero = gfc_rank_cst[0];
2012           tmp = fold_build2_loc (input_location, MINUS_EXPR,
2013                              gfc_array_index_type,
2014                              gfc_conv_descriptor_ubound_get (desc, zero),
2015                              gfc_conv_descriptor_lbound_get (desc, zero));
2016           tmp = gfc_evaluate_now (tmp, &loop->pre);
2017           loop->to[n] = tmp;
2018         }
2019     }
2020 }
2021
2022
2023 /* Add the pre and post chains for all the scalar expressions in a SS chain
2024    to loop.  This is called after the loop parameters have been calculated,
2025    but before the actual scalarizing loops.  */
2026
2027 static void
2028 gfc_add_loop_ss_code (gfc_loopinfo * loop, gfc_ss * ss, bool subscript,
2029                       locus * where)
2030 {
2031   gfc_se se;
2032   int n;
2033
2034   /* TODO: This can generate bad code if there are ordering dependencies,
2035      e.g., a callee allocated function and an unknown size constructor.  */
2036   gcc_assert (ss != NULL);
2037
2038   for (; ss != gfc_ss_terminator; ss = ss->loop_chain)
2039     {
2040       gcc_assert (ss);
2041
2042       switch (ss->type)
2043         {
2044         case GFC_SS_SCALAR:
2045           /* Scalar expression.  Evaluate this now.  This includes elemental
2046              dimension indices, but not array section bounds.  */
2047           gfc_init_se (&se, NULL);
2048           gfc_conv_expr (&se, ss->expr);
2049           gfc_add_block_to_block (&loop->pre, &se.pre);
2050
2051           if (ss->expr->ts.type != BT_CHARACTER)
2052             {
2053               /* Move the evaluation of scalar expressions outside the
2054                  scalarization loop, except for WHERE assignments.  */
2055               if (subscript)
2056                 se.expr = convert(gfc_array_index_type, se.expr);
2057               if (!ss->where)
2058                 se.expr = gfc_evaluate_now (se.expr, &loop->pre);
2059               gfc_add_block_to_block (&loop->pre, &se.post);
2060             }
2061           else
2062             gfc_add_block_to_block (&loop->post, &se.post);
2063
2064           ss->data.scalar.expr = se.expr;
2065           ss->string_length = se.string_length;
2066           break;
2067
2068         case GFC_SS_REFERENCE:
2069           /* Scalar argument to elemental procedure.  Evaluate this
2070              now.  */
2071           gfc_init_se (&se, NULL);
2072           gfc_conv_expr (&se, ss->expr);
2073           gfc_add_block_to_block (&loop->pre, &se.pre);
2074           gfc_add_block_to_block (&loop->post, &se.post);
2075
2076           ss->data.scalar.expr = gfc_evaluate_now (se.expr, &loop->pre);
2077           ss->string_length = se.string_length;
2078           break;
2079
2080         case GFC_SS_SECTION:
2081           /* Add the expressions for scalar and vector subscripts.  */
2082           for (n = 0; n < GFC_MAX_DIMENSIONS; n++)
2083             if (ss->data.info.subscript[n])
2084               gfc_add_loop_ss_code (loop, ss->data.info.subscript[n], true,
2085                                     where);
2086
2087           gfc_set_vector_loop_bounds (loop, &ss->data.info);
2088           break;
2089
2090         case GFC_SS_VECTOR:
2091           /* Get the vector's descriptor and store it in SS.  */
2092           gfc_init_se (&se, NULL);
2093           gfc_conv_expr_descriptor (&se, ss->expr, gfc_walk_expr (ss->expr));
2094           gfc_add_block_to_block (&loop->pre, &se.pre);
2095           gfc_add_block_to_block (&loop->post, &se.post);
2096           ss->data.info.descriptor = se.expr;
2097           break;
2098
2099         case GFC_SS_INTRINSIC:
2100           gfc_add_intrinsic_ss_code (loop, ss);
2101           break;
2102
2103         case GFC_SS_FUNCTION:
2104           /* Array function return value.  We call the function and save its
2105              result in a temporary for use inside the loop.  */
2106           gfc_init_se (&se, NULL);
2107           se.loop = loop;
2108           se.ss = ss;
2109           gfc_conv_expr (&se, ss->expr);
2110           gfc_add_block_to_block (&loop->pre, &se.pre);
2111           gfc_add_block_to_block (&loop->post, &se.post);
2112           ss->string_length = se.string_length;
2113           break;
2114
2115         case GFC_SS_CONSTRUCTOR:
2116           if (ss->expr->ts.type == BT_CHARACTER
2117                 && ss->string_length == NULL
2118                 && ss->expr->ts.u.cl
2119                 && ss->expr->ts.u.cl->length)
2120             {
2121               gfc_init_se (&se, NULL);
2122               gfc_conv_expr_type (&se, ss->expr->ts.u.cl->length,
2123                                   gfc_charlen_type_node);
2124               ss->string_length = se.expr;
2125               gfc_add_block_to_block (&loop->pre, &se.pre);
2126               gfc_add_block_to_block (&loop->post, &se.post);
2127             }
2128           gfc_trans_array_constructor (loop, ss, where);
2129           break;
2130
2131         case GFC_SS_TEMP:
2132         case GFC_SS_COMPONENT:
2133           /* Do nothing.  These are handled elsewhere.  */
2134           break;
2135
2136         default:
2137           gcc_unreachable ();
2138         }
2139     }
2140 }
2141
2142
2143 /* Translate expressions for the descriptor and data pointer of a SS.  */
2144 /*GCC ARRAYS*/
2145
2146 static void
2147 gfc_conv_ss_descriptor (stmtblock_t * block, gfc_ss * ss, int base)
2148 {
2149   gfc_se se;
2150   tree tmp;
2151
2152   /* Get the descriptor for the array to be scalarized.  */
2153   gcc_assert (ss->expr->expr_type == EXPR_VARIABLE);
2154   gfc_init_se (&se, NULL);
2155   se.descriptor_only = 1;
2156   gfc_conv_expr_lhs (&se, ss->expr);
2157   gfc_add_block_to_block (block, &se.pre);
2158   ss->data.info.descriptor = se.expr;
2159   ss->string_length = se.string_length;
2160
2161   if (base)
2162     {
2163       /* Also the data pointer.  */
2164       tmp = gfc_conv_array_data (se.expr);
2165       /* If this is a variable or address of a variable we use it directly.
2166          Otherwise we must evaluate it now to avoid breaking dependency
2167          analysis by pulling the expressions for elemental array indices
2168          inside the loop.  */
2169       if (!(DECL_P (tmp)
2170             || (TREE_CODE (tmp) == ADDR_EXPR
2171                 && DECL_P (TREE_OPERAND (tmp, 0)))))
2172         tmp = gfc_evaluate_now (tmp, block);
2173       ss->data.info.data = tmp;
2174
2175       tmp = gfc_conv_array_offset (se.expr);
2176       ss->data.info.offset = gfc_evaluate_now (tmp, block);
2177     }
2178 }
2179
2180
2181 /* Initialize a gfc_loopinfo structure.  */
2182
2183 void
2184 gfc_init_loopinfo (gfc_loopinfo * loop)
2185 {
2186   int n;
2187
2188   memset (loop, 0, sizeof (gfc_loopinfo));
2189   gfc_init_block (&loop->pre);
2190   gfc_init_block (&loop->post);
2191
2192   /* Initially scalarize in order and default to no loop reversal.  */
2193   for (n = 0; n < GFC_MAX_DIMENSIONS; n++)
2194     {
2195       loop->order[n] = n;
2196       loop->reverse[n] = GFC_CANNOT_REVERSE;
2197     }
2198
2199   loop->ss = gfc_ss_terminator;
2200 }
2201
2202
2203 /* Copies the loop variable info to a gfc_se structure. Does not copy the SS
2204    chain.  */
2205
2206 void
2207 gfc_copy_loopinfo_to_se (gfc_se * se, gfc_loopinfo * loop)
2208 {
2209   se->loop = loop;
2210 }
2211
2212
2213 /* Return an expression for the data pointer of an array.  */
2214
2215 tree
2216 gfc_conv_array_data (tree descriptor)
2217 {
2218   tree type;
2219
2220   type = TREE_TYPE (descriptor);
2221   if (GFC_ARRAY_TYPE_P (type))
2222     {
2223       if (TREE_CODE (type) == POINTER_TYPE)
2224         return descriptor;
2225       else
2226         {
2227           /* Descriptorless arrays.  */
2228           return gfc_build_addr_expr (NULL_TREE, descriptor);
2229         }
2230     }
2231   else
2232     return gfc_conv_descriptor_data_get (descriptor);
2233 }
2234
2235
2236 /* Return an expression for the base offset of an array.  */
2237
2238 tree
2239 gfc_conv_array_offset (tree descriptor)
2240 {
2241   tree type;
2242
2243   type = TREE_TYPE (descriptor);
2244   if (GFC_ARRAY_TYPE_P (type))
2245     return GFC_TYPE_ARRAY_OFFSET (type);
2246   else
2247     return gfc_conv_descriptor_offset_get (descriptor);
2248 }
2249
2250
2251 /* Get an expression for the array stride.  */
2252
2253 tree
2254 gfc_conv_array_stride (tree descriptor, int dim)
2255 {
2256   tree tmp;
2257   tree type;
2258
2259   type = TREE_TYPE (descriptor);
2260
2261   /* For descriptorless arrays use the array size.  */
2262   tmp = GFC_TYPE_ARRAY_STRIDE (type, dim);
2263   if (tmp != NULL_TREE)
2264     return tmp;
2265
2266   tmp = gfc_conv_descriptor_stride_get (descriptor, gfc_rank_cst[dim]);
2267   return tmp;
2268 }
2269
2270
2271 /* Like gfc_conv_array_stride, but for the lower bound.  */
2272
2273 tree
2274 gfc_conv_array_lbound (tree descriptor, int dim)
2275 {
2276   tree tmp;
2277   tree type;
2278
2279   type = TREE_TYPE (descriptor);
2280
2281   tmp = GFC_TYPE_ARRAY_LBOUND (type, dim);
2282   if (tmp != NULL_TREE)
2283     return tmp;
2284
2285   tmp = gfc_conv_descriptor_lbound_get (descriptor, gfc_rank_cst[dim]);
2286   return tmp;
2287 }
2288
2289
2290 /* Like gfc_conv_array_stride, but for the upper bound.  */
2291
2292 tree
2293 gfc_conv_array_ubound (tree descriptor, int dim)
2294 {
2295   tree tmp;
2296   tree type;
2297
2298   type = TREE_TYPE (descriptor);
2299
2300   tmp = GFC_TYPE_ARRAY_UBOUND (type, dim);
2301   if (tmp != NULL_TREE)
2302     return tmp;
2303
2304   /* This should only ever happen when passing an assumed shape array
2305      as an actual parameter.  The value will never be used.  */
2306   if (GFC_ARRAY_TYPE_P (TREE_TYPE (descriptor)))
2307     return gfc_index_zero_node;
2308
2309   tmp = gfc_conv_descriptor_ubound_get (descriptor, gfc_rank_cst[dim]);
2310   return tmp;
2311 }
2312
2313
2314 /* Generate code to perform an array index bound check.  */
2315
2316 static tree
2317 gfc_trans_array_bound_check (gfc_se * se, tree descriptor, tree index, int n,
2318                              locus * where, bool check_upper)
2319 {
2320   tree fault;
2321   tree tmp_lo, tmp_up;
2322   char *msg;
2323   const char * name = NULL;
2324
2325   if (!(gfc_option.rtcheck & GFC_RTCHECK_BOUNDS))
2326     return index;
2327
2328   index = gfc_evaluate_now (index, &se->pre);
2329
2330   /* We find a name for the error message.  */
2331   if (se->ss)
2332     name = se->ss->expr->symtree->name;
2333
2334   if (!name && se->loop && se->loop->ss && se->loop->ss->expr
2335       && se->loop->ss->expr->symtree)
2336     name = se->loop->ss->expr->symtree->name;
2337
2338   if (!name && se->loop && se->loop->ss && se->loop->ss->loop_chain
2339       && se->loop->ss->loop_chain->expr
2340       && se->loop->ss->loop_chain->expr->symtree)
2341     name = se->loop->ss->loop_chain->expr->symtree->name;
2342
2343   if (!name && se->loop && se->loop->ss && se->loop->ss->expr)
2344     {
2345       if (se->loop->ss->expr->expr_type == EXPR_FUNCTION
2346           && se->loop->ss->expr->value.function.name)
2347         name = se->loop->ss->expr->value.function.name;
2348       else
2349         if (se->loop->ss->type == GFC_SS_CONSTRUCTOR
2350             || se->loop->ss->type == GFC_SS_SCALAR)
2351           name = "unnamed constant";
2352     }
2353
2354   if (TREE_CODE (descriptor) == VAR_DECL)
2355     name = IDENTIFIER_POINTER (DECL_NAME (descriptor));
2356
2357   /* If upper bound is present, include both bounds in the error message.  */
2358   if (check_upper)
2359     {
2360       tmp_lo = gfc_conv_array_lbound (descriptor, n);
2361       tmp_up = gfc_conv_array_ubound (descriptor, n);
2362
2363       if (name)
2364         asprintf (&msg, "Index '%%ld' of dimension %d of array '%s' "
2365                   "outside of expected range (%%ld:%%ld)", n+1, name);
2366       else
2367         asprintf (&msg, "Index '%%ld' of dimension %d "
2368                   "outside of expected range (%%ld:%%ld)", n+1);
2369
2370       fault = fold_build2_loc (input_location, LT_EXPR, boolean_type_node,
2371                                index, tmp_lo);
2372       gfc_trans_runtime_check (true, false, fault, &se->pre, where, msg,
2373                                fold_convert (long_integer_type_node, index),
2374                                fold_convert (long_integer_type_node, tmp_lo),
2375                                fold_convert (long_integer_type_node, tmp_up));
2376       fault = fold_build2_loc (input_location, GT_EXPR, boolean_type_node,
2377                                index, tmp_up);
2378       gfc_trans_runtime_check (true, false, fault, &se->pre, where, msg,
2379                                fold_convert (long_integer_type_node, index),
2380                                fold_convert (long_integer_type_node, tmp_lo),
2381                                fold_convert (long_integer_type_node, tmp_up));
2382       gfc_free (msg);
2383     }
2384   else
2385     {
2386       tmp_lo = gfc_conv_array_lbound (descriptor, n);
2387
2388       if (name)
2389         asprintf (&msg, "Index '%%ld' of dimension %d of array '%s' "
2390                   "below lower bound of %%ld", n+1, name);
2391       else
2392         asprintf (&msg, "Index '%%ld' of dimension %d "
2393                   "below lower bound of %%ld", n+1);
2394
2395       fault = fold_build2_loc (input_location, LT_EXPR, boolean_type_node,
2396                                index, tmp_lo);
2397       gfc_trans_runtime_check (true, false, fault, &se->pre, where, msg,
2398                                fold_convert (long_integer_type_node, index),
2399                                fold_convert (long_integer_type_node, tmp_lo));
2400       gfc_free (msg);
2401     }
2402
2403   return index;
2404 }
2405
2406
2407 /* Return the offset for an index.  Performs bound checking for elemental
2408    dimensions.  Single element references are processed separately.
2409    DIM is the array dimension, I is the loop dimension.  */
2410
2411 static tree
2412 gfc_conv_array_index_offset (gfc_se * se, gfc_ss_info * info, int dim, int i,
2413                              gfc_array_ref * ar, tree stride)
2414 {
2415   tree index;
2416   tree desc;
2417   tree data;
2418
2419   /* Get the index into the array for this dimension.  */
2420   if (ar)
2421     {
2422       gcc_assert (ar->type != AR_ELEMENT);
2423       switch (ar->dimen_type[dim])
2424         {
2425         case DIMEN_ELEMENT:
2426           /* Elemental dimension.  */
2427           gcc_assert (info->subscript[dim]
2428                       && info->subscript[dim]->type == GFC_SS_SCALAR);
2429           /* We've already translated this value outside the loop.  */
2430           index = info->subscript[dim]->data.scalar.expr;
2431
2432           index = gfc_trans_array_bound_check (se, info->descriptor,
2433                         index, dim, &ar->where,
2434                         ar->as->type != AS_ASSUMED_SIZE
2435                         || dim < ar->dimen - 1);
2436           break;
2437
2438         case DIMEN_VECTOR:
2439           gcc_assert (info && se->loop);
2440           gcc_assert (info->subscript[dim]
2441                       && info->subscript[dim]->type == GFC_SS_VECTOR);
2442           desc = info->subscript[dim]->data.info.descriptor;
2443
2444           /* Get a zero-based index into the vector.  */
2445           index = fold_build2_loc (input_location, MINUS_EXPR,
2446                                    gfc_array_index_type,
2447                                    se->loop->loopvar[i], se->loop->from[i]);
2448
2449           /* Multiply the index by the stride.  */
2450           index = fold_build2_loc (input_location, MULT_EXPR,
2451                                    gfc_array_index_type,
2452                                    index, gfc_conv_array_stride (desc, 0));
2453
2454           /* Read the vector to get an index into info->descriptor.  */
2455           data = build_fold_indirect_ref_loc (input_location,
2456                                           gfc_conv_array_data (desc));
2457           index = gfc_build_array_ref (data, index, NULL);
2458           index = gfc_evaluate_now (index, &se->pre);
2459           index = fold_convert (gfc_array_index_type, index);
2460
2461           /* Do any bounds checking on the final info->descriptor index.  */
2462           index = gfc_trans_array_bound_check (se, info->descriptor,
2463                         index, dim, &ar->where,
2464                         ar->as->type != AS_ASSUMED_SIZE
2465                         || dim < ar->dimen - 1);
2466           break;
2467
2468         case DIMEN_RANGE:
2469           /* Scalarized dimension.  */
2470           gcc_assert (info && se->loop);
2471
2472           /* Multiply the loop variable by the stride and delta.  */
2473           index = se->loop->loopvar[i];
2474           if (!integer_onep (info->stride[dim]))
2475             index = fold_build2_loc (input_location, MULT_EXPR,
2476                                      gfc_array_index_type, index,
2477                                      info->stride[dim]);
2478           if (!integer_zerop (info->delta[dim]))
2479             index = fold_build2_loc (input_location, PLUS_EXPR,
2480                                      gfc_array_index_type, index,
2481                                      info->delta[dim]);
2482           break;
2483
2484         default:
2485           gcc_unreachable ();
2486         }
2487     }
2488   else
2489     {
2490       /* Temporary array or derived type component.  */
2491       gcc_assert (se->loop);
2492       index = se->loop->loopvar[se->loop->order[i]];
2493       if (!integer_zerop (info->delta[dim]))
2494         index = fold_build2_loc (input_location, PLUS_EXPR,
2495                                  gfc_array_index_type, index, info->delta[dim]);
2496     }
2497
2498   /* Multiply by the stride.  */
2499   if (!integer_onep (stride))
2500     index = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
2501                              index, stride);
2502
2503   return index;
2504 }
2505
2506
2507 /* Build a scalarized reference to an array.  */
2508
2509 static void
2510 gfc_conv_scalarized_array_ref (gfc_se * se, gfc_array_ref * ar)
2511 {
2512   gfc_ss_info *info;
2513   tree decl = NULL_TREE;
2514   tree index;
2515   tree tmp;
2516   int n;
2517
2518   info = &se->ss->data.info;
2519   if (ar)
2520     n = se->loop->order[0];
2521   else
2522     n = 0;
2523
2524   index = gfc_conv_array_index_offset (se, info, info->dim[n], n, ar,
2525                                        info->stride0);
2526   /* Add the offset for this dimension to the stored offset for all other
2527      dimensions.  */
2528   if (!integer_zerop (info->offset))
2529     index = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
2530                              index, info->offset);
2531
2532   if (se->ss->expr && is_subref_array (se->ss->expr))
2533     decl = se->ss->expr->symtree->n.sym->backend_decl;
2534
2535   tmp = build_fold_indirect_ref_loc (input_location,
2536                                  info->data);
2537   se->expr = gfc_build_array_ref (tmp, index, decl);
2538 }
2539
2540
2541 /* Translate access of temporary array.  */
2542
2543 void
2544 gfc_conv_tmp_array_ref (gfc_se * se)
2545 {
2546   se->string_length = se->ss->string_length;
2547   gfc_conv_scalarized_array_ref (se, NULL);
2548 }
2549
2550
2551 /* Build an array reference.  se->expr already holds the array descriptor.
2552    This should be either a variable, indirect variable reference or component
2553    reference.  For arrays which do not have a descriptor, se->expr will be
2554    the data pointer.
2555    a(i, j, k) = base[offset + i * stride[0] + j * stride[1] + k * stride[2]]*/
2556
2557 void
2558 gfc_conv_array_ref (gfc_se * se, gfc_array_ref * ar, gfc_symbol * sym,
2559                     locus * where)
2560 {
2561   int n;
2562   tree index;
2563   tree tmp;
2564   tree stride;
2565   gfc_se indexse;
2566   gfc_se tmpse;
2567
2568   if (ar->dimen == 0)
2569     return;
2570
2571   /* Handle scalarized references separately.  */
2572   if (ar->type != AR_ELEMENT)
2573     {
2574       gfc_conv_scalarized_array_ref (se, ar);
2575       gfc_advance_se_ss_chain (se);
2576       return;
2577     }
2578
2579   index = gfc_index_zero_node;
2580
2581   /* Calculate the offsets from all the dimensions.  */
2582   for (n = 0; n < ar->dimen; n++)
2583     {
2584       /* Calculate the index for this dimension.  */
2585       gfc_init_se (&indexse, se);
2586       gfc_conv_expr_type (&indexse, ar->start[n], gfc_array_index_type);
2587       gfc_add_block_to_block (&se->pre, &indexse.pre);
2588
2589       if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
2590         {
2591           /* Check array bounds.  */
2592           tree cond;
2593           char *msg;
2594
2595           /* Evaluate the indexse.expr only once.  */
2596           indexse.expr = save_expr (indexse.expr);
2597
2598           /* Lower bound.  */
2599           tmp = gfc_conv_array_lbound (se->expr, n);
2600           if (sym->attr.temporary)
2601             {
2602               gfc_init_se (&tmpse, se);
2603               gfc_conv_expr_type (&tmpse, ar->as->lower[n],
2604                                   gfc_array_index_type);
2605               gfc_add_block_to_block (&se->pre, &tmpse.pre);
2606               tmp = tmpse.expr;
2607             }
2608
2609           cond = fold_build2_loc (input_location, LT_EXPR, boolean_type_node, 
2610                                   indexse.expr, tmp);
2611           asprintf (&msg, "Index '%%ld' of dimension %d of array '%s' "
2612                     "below lower bound of %%ld", n+1, sym->name);
2613           gfc_trans_runtime_check (true, false, cond, &se->pre, where, msg,
2614                                    fold_convert (long_integer_type_node,
2615                                                  indexse.expr),
2616                                    fold_convert (long_integer_type_node, tmp));
2617           gfc_free (msg);
2618
2619           /* Upper bound, but not for the last dimension of assumed-size
2620              arrays.  */
2621           if (n < ar->dimen - 1 || ar->as->type != AS_ASSUMED_SIZE)
2622             {
2623               tmp = gfc_conv_array_ubound (se->expr, n);
2624               if (sym->attr.temporary)
2625                 {
2626                   gfc_init_se (&tmpse, se);
2627                   gfc_conv_expr_type (&tmpse, ar->as->upper[n],
2628                                       gfc_array_index_type);
2629                   gfc_add_block_to_block (&se->pre, &tmpse.pre);
2630                   tmp = tmpse.expr;
2631                 }
2632
2633               cond = fold_build2_loc (input_location, GT_EXPR,
2634                                       boolean_type_node, indexse.expr, tmp);
2635               asprintf (&msg, "Index '%%ld' of dimension %d of array '%s' "
2636                         "above upper bound of %%ld", n+1, sym->name);
2637               gfc_trans_runtime_check (true, false, cond, &se->pre, where, msg,
2638                                    fold_convert (long_integer_type_node,
2639                                                  indexse.expr),
2640                                    fold_convert (long_integer_type_node, tmp));
2641               gfc_free (msg);
2642             }
2643         }
2644
2645       /* Multiply the index by the stride.  */
2646       stride = gfc_conv_array_stride (se->expr, n);
2647       tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
2648                              indexse.expr, stride);
2649
2650       /* And add it to the total.  */
2651       index = fold_build2_loc (input_location, PLUS_EXPR,
2652                                gfc_array_index_type, index, tmp);
2653     }
2654
2655   tmp = gfc_conv_array_offset (se->expr);
2656   if (!integer_zerop (tmp))
2657     index = fold_build2_loc (input_location, PLUS_EXPR,
2658                              gfc_array_index_type, index, tmp);
2659
2660   /* Access the calculated element.  */
2661   tmp = gfc_conv_array_data (se->expr);
2662   tmp = build_fold_indirect_ref (tmp);
2663   se->expr = gfc_build_array_ref (tmp, index, sym->backend_decl);
2664 }
2665
2666
2667 /* Generate the code to be executed immediately before entering a
2668    scalarization loop.  */
2669
2670 static void
2671 gfc_trans_preloop_setup (gfc_loopinfo * loop, int dim, int flag,
2672                          stmtblock_t * pblock)
2673 {
2674   tree index;
2675   tree stride;
2676   gfc_ss_info *info;
2677   gfc_ss *ss;
2678   gfc_se se;
2679   int i;
2680
2681   /* This code will be executed before entering the scalarization loop
2682      for this dimension.  */
2683   for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
2684     {
2685       if ((ss->useflags & flag) == 0)
2686         continue;
2687
2688       if (ss->type != GFC_SS_SECTION
2689           && ss->type != GFC_SS_FUNCTION && ss->type != GFC_SS_CONSTRUCTOR
2690           && ss->type != GFC_SS_COMPONENT)
2691         continue;
2692
2693       info = &ss->data.info;
2694
2695       if (dim >= info->dimen)
2696         continue;
2697
2698       if (dim == info->dimen - 1)
2699         {
2700           /* For the outermost loop calculate the offset due to any
2701              elemental dimensions.  It will have been initialized with the
2702              base offset of the array.  */
2703           if (info->ref)
2704             {
2705               for (i = 0; i < info->ref->u.ar.dimen; i++)
2706                 {
2707                   if (info->ref->u.ar.dimen_type[i] != DIMEN_ELEMENT)
2708                     continue;
2709
2710                   gfc_init_se (&se, NULL);
2711                   se.loop = loop;
2712                   se.expr = info->descriptor;
2713                   stride = gfc_conv_array_stride (info->descriptor, i);
2714                   index = gfc_conv_array_index_offset (&se, info, i, -1,
2715                                                        &info->ref->u.ar,
2716                                                        stride);
2717                   gfc_add_block_to_block (pblock, &se.pre);
2718
2719                   info->offset = fold_build2_loc (input_location, PLUS_EXPR,
2720                                                   gfc_array_index_type,
2721                                                   info->offset, index);
2722                   info->offset = gfc_evaluate_now (info->offset, pblock);
2723                 }
2724             }
2725
2726           i = loop->order[0];
2727           /* For the time being, the innermost loop is unconditionally on
2728              the first dimension of the scalarization loop.  */
2729           gcc_assert (i == 0);
2730           stride = gfc_conv_array_stride (info->descriptor, info->dim[i]);
2731
2732           /* Calculate the stride of the innermost loop.  Hopefully this will
2733              allow the backend optimizers to do their stuff more effectively.
2734            */
2735           info->stride0 = gfc_evaluate_now (stride, pblock);
2736         }
2737       else
2738         {
2739           /* Add the offset for the previous loop dimension.  */
2740           gfc_array_ref *ar;
2741
2742           if (info->ref)
2743             {
2744               ar = &info->ref->u.ar;
2745               i = loop->order[dim + 1];
2746             }
2747           else
2748             {
2749               ar = NULL;
2750               i = dim + 1;
2751             }
2752
2753           gfc_init_se (&se, NULL);
2754           se.loop = loop;
2755           se.expr = info->descriptor;
2756           stride = gfc_conv_array_stride (info->descriptor, info->dim[i]);
2757           index = gfc_conv_array_index_offset (&se, info, info->dim[i], i,
2758                                                ar, stride);
2759           gfc_add_block_to_block (pblock, &se.pre);
2760           info->offset = fold_build2_loc (input_location, PLUS_EXPR,
2761                                           gfc_array_index_type, info->offset,
2762                                           index);
2763           info->offset = gfc_evaluate_now (info->offset, pblock);
2764         }
2765
2766       /* Remember this offset for the second loop.  */
2767       if (dim == loop->temp_dim - 1)
2768         info->saved_offset = info->offset;
2769     }
2770 }
2771
2772
2773 /* Start a scalarized expression.  Creates a scope and declares loop
2774    variables.  */
2775
2776 void
2777 gfc_start_scalarized_body (gfc_loopinfo * loop, stmtblock_t * pbody)
2778 {
2779   int dim;
2780   int n;
2781   int flags;
2782
2783   gcc_assert (!loop->array_parameter);
2784
2785   for (dim = loop->dimen - 1; dim >= 0; dim--)
2786     {
2787       n = loop->order[dim];
2788
2789       gfc_start_block (&loop->code[n]);
2790
2791       /* Create the loop variable.  */
2792       loop->loopvar[n] = gfc_create_var (gfc_array_index_type, "S");
2793
2794       if (dim < loop->temp_dim)
2795         flags = 3;
2796       else
2797         flags = 1;
2798       /* Calculate values that will be constant within this loop.  */
2799       gfc_trans_preloop_setup (loop, dim, flags, &loop->code[n]);
2800     }
2801   gfc_start_block (pbody);
2802 }
2803
2804
2805 /* Generates the actual loop code for a scalarization loop.  */
2806
2807 void
2808 gfc_trans_scalarized_loop_end (gfc_loopinfo * loop, int n,
2809                                stmtblock_t * pbody)
2810 {
2811   stmtblock_t block;
2812   tree cond;
2813   tree tmp;
2814   tree loopbody;
2815   tree exit_label;
2816   tree stmt;
2817   tree init;
2818   tree incr;
2819
2820   if ((ompws_flags & (OMPWS_WORKSHARE_FLAG | OMPWS_SCALARIZER_WS))
2821       == (OMPWS_WORKSHARE_FLAG | OMPWS_SCALARIZER_WS)
2822       && n == loop->dimen - 1)
2823     {
2824       /* We create an OMP_FOR construct for the outermost scalarized loop.  */
2825       init = make_tree_vec (1);
2826       cond = make_tree_vec (1);
2827       incr = make_tree_vec (1);
2828
2829       /* Cycle statement is implemented with a goto.  Exit statement must not
2830          be present for this loop.  */
2831       exit_label = gfc_build_label_decl (NULL_TREE);
2832       TREE_USED (exit_label) = 1;
2833
2834       /* Label for cycle statements (if needed).  */
2835       tmp = build1_v (LABEL_EXPR, exit_label);
2836       gfc_add_expr_to_block (pbody, tmp);
2837
2838       stmt = make_node (OMP_FOR);
2839
2840       TREE_TYPE (stmt) = void_type_node;
2841       OMP_FOR_BODY (stmt) = loopbody = gfc_finish_block (pbody);
2842
2843       OMP_FOR_CLAUSES (stmt) = build_omp_clause (input_location,
2844                                                  OMP_CLAUSE_SCHEDULE);
2845       OMP_CLAUSE_SCHEDULE_KIND (OMP_FOR_CLAUSES (stmt))
2846         = OMP_CLAUSE_SCHEDULE_STATIC;
2847       if (ompws_flags & OMPWS_NOWAIT)
2848         OMP_CLAUSE_CHAIN (OMP_FOR_CLAUSES (stmt))
2849           = build_omp_clause (input_location, OMP_CLAUSE_NOWAIT);
2850
2851       /* Initialize the loopvar.  */
2852       TREE_VEC_ELT (init, 0) = build2_v (MODIFY_EXPR, loop->loopvar[n],
2853                                          loop->from[n]);
2854       OMP_FOR_INIT (stmt) = init;
2855       /* The exit condition.  */
2856       TREE_VEC_ELT (cond, 0) = build2_loc (input_location, LE_EXPR,
2857                                            boolean_type_node,
2858                                            loop->loopvar[n], loop->to[n]);
2859       SET_EXPR_LOCATION (TREE_VEC_ELT (cond, 0), input_location);
2860       OMP_FOR_COND (stmt) = cond;
2861       /* Increment the loopvar.  */
2862       tmp = build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
2863                         loop->loopvar[n], gfc_index_one_node);
2864       TREE_VEC_ELT (incr, 0) = fold_build2_loc (input_location, MODIFY_EXPR,
2865           void_type_node, loop->loopvar[n], tmp);
2866       OMP_FOR_INCR (stmt) = incr;
2867
2868       ompws_flags &= ~OMPWS_CURR_SINGLEUNIT;
2869       gfc_add_expr_to_block (&loop->code[n], stmt);
2870     }
2871   else
2872     {
2873       bool reverse_loop = (loop->reverse[n] == GFC_REVERSE_SET)
2874                              && (loop->temp_ss == NULL);
2875
2876       loopbody = gfc_finish_block (pbody);
2877
2878       if (reverse_loop)
2879         {
2880           tmp = loop->from[n];
2881           loop->from[n] = loop->to[n];
2882           loop->to[n] = tmp;
2883         }
2884
2885       /* Initialize the loopvar.  */
2886       if (loop->loopvar[n] != loop->from[n])
2887         gfc_add_modify (&loop->code[n], loop->loopvar[n], loop->from[n]);
2888
2889       exit_label = gfc_build_label_decl (NULL_TREE);
2890
2891       /* Generate the loop body.  */
2892       gfc_init_block (&block);
2893
2894       /* The exit condition.  */
2895       cond = fold_build2_loc (input_location, reverse_loop ? LT_EXPR : GT_EXPR,
2896                           boolean_type_node, loop->loopvar[n], loop->to[n]);
2897       tmp = build1_v (GOTO_EXPR, exit_label);
2898       TREE_USED (exit_label) = 1;
2899       tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt (input_location));
2900       gfc_add_expr_to_block (&block, tmp);
2901
2902       /* The main body.  */
2903       gfc_add_expr_to_block (&block, loopbody);
2904
2905       /* Increment the loopvar.  */
2906       tmp = fold_build2_loc (input_location,
2907                              reverse_loop ? MINUS_EXPR : PLUS_EXPR,
2908                              gfc_array_index_type, loop->loopvar[n],
2909                              gfc_index_one_node);
2910
2911       gfc_add_modify (&block, loop->loopvar[n], tmp);
2912
2913       /* Build the loop.  */
2914       tmp = gfc_finish_block (&block);
2915       tmp = build1_v (LOOP_EXPR, tmp);
2916       gfc_add_expr_to_block (&loop->code[n], tmp);
2917
2918       /* Add the exit label.  */
2919       tmp = build1_v (LABEL_EXPR, exit_label);
2920       gfc_add_expr_to_block (&loop->code[n], tmp);
2921     }
2922
2923 }
2924
2925
2926 /* Finishes and generates the loops for a scalarized expression.  */
2927
2928 void
2929 gfc_trans_scalarizing_loops (gfc_loopinfo * loop, stmtblock_t * body)
2930 {
2931   int dim;
2932   int n;
2933   gfc_ss *ss;
2934   stmtblock_t *pblock;
2935   tree tmp;
2936
2937   pblock = body;
2938   /* Generate the loops.  */
2939   for (dim = 0; dim < loop->dimen; dim++)
2940     {
2941       n = loop->order[dim];
2942       gfc_trans_scalarized_loop_end (loop, n, pblock);
2943       loop->loopvar[n] = NULL_TREE;
2944       pblock = &loop->code[n];
2945     }
2946
2947   tmp = gfc_finish_block (pblock);
2948   gfc_add_expr_to_block (&loop->pre, tmp);
2949
2950   /* Clear all the used flags.  */
2951   for (ss = loop->ss; ss; ss = ss->loop_chain)
2952     ss->useflags = 0;
2953 }
2954
2955
2956 /* Finish the main body of a scalarized expression, and start the secondary
2957    copying body.  */
2958
2959 void
2960 gfc_trans_scalarized_loop_boundary (gfc_loopinfo * loop, stmtblock_t * body)
2961 {
2962   int dim;
2963   int n;
2964   stmtblock_t *pblock;
2965   gfc_ss *ss;
2966
2967   pblock = body;
2968   /* We finish as many loops as are used by the temporary.  */
2969   for (dim = 0; dim < loop->temp_dim - 1; dim++)
2970     {
2971       n = loop->order[dim];
2972       gfc_trans_scalarized_loop_end (loop, n, pblock);
2973       loop->loopvar[n] = NULL_TREE;
2974       pblock = &loop->code[n];
2975     }
2976
2977   /* We don't want to finish the outermost loop entirely.  */
2978   n = loop->order[loop->temp_dim - 1];
2979   gfc_trans_scalarized_loop_end (loop, n, pblock);
2980
2981   /* Restore the initial offsets.  */
2982   for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
2983     {
2984       if ((ss->useflags & 2) == 0)
2985         continue;
2986
2987       if (ss->type != GFC_SS_SECTION
2988           && ss->type != GFC_SS_FUNCTION && ss->type != GFC_SS_CONSTRUCTOR
2989           && ss->type != GFC_SS_COMPONENT)
2990         continue;
2991
2992       ss->data.info.offset = ss->data.info.saved_offset;
2993     }
2994
2995   /* Restart all the inner loops we just finished.  */
2996   for (dim = loop->temp_dim - 2; dim >= 0; dim--)
2997     {
2998       n = loop->order[dim];
2999
3000       gfc_start_block (&loop->code[n]);
3001
3002       loop->loopvar[n] = gfc_create_var (gfc_array_index_type, "Q");
3003
3004       gfc_trans_preloop_setup (loop, dim, 2, &loop->code[n]);
3005     }
3006
3007   /* Start a block for the secondary copying code.  */
3008   gfc_start_block (body);
3009 }
3010
3011
3012 /* Calculate the lower bound of an array section.  */
3013
3014 static void
3015 gfc_conv_section_startstride (gfc_loopinfo * loop, gfc_ss * ss, int dim)
3016 {
3017   gfc_expr *start;
3018   gfc_expr *end;
3019   gfc_expr *stride;
3020   tree desc;
3021   gfc_se se;
3022   gfc_ss_info *info;
3023
3024   gcc_assert (ss->type == GFC_SS_SECTION);
3025
3026   info = &ss->data.info;
3027
3028   if (info->ref->u.ar.dimen_type[dim] == DIMEN_VECTOR)
3029     {
3030       /* We use a zero-based index to access the vector.  */
3031       info->start[dim] = gfc_index_zero_node;
3032       info->stride[dim] = gfc_index_one_node;
3033       info->end[dim] = NULL;
3034       return;
3035     }
3036
3037   gcc_assert (info->ref->u.ar.dimen_type[dim] == DIMEN_RANGE);
3038   desc = info->descriptor;
3039   start = info->ref->u.ar.start[dim];
3040   end = info->ref->u.ar.end[dim];
3041   stride = info->ref->u.ar.stride[dim];
3042
3043   /* Calculate the start of the range.  For vector subscripts this will
3044      be the range of the vector.  */
3045   if (start)
3046     {
3047       /* Specified section start.  */
3048       gfc_init_se (&se, NULL);
3049       gfc_conv_expr_type (&se, start, gfc_array_index_type);
3050       gfc_add_block_to_block (&loop->pre, &se.pre);
3051       info->start[dim] = se.expr;
3052     }
3053   else
3054     {
3055       /* No lower bound specified so use the bound of the array.  */
3056       info->start[dim] = gfc_conv_array_lbound (desc, dim);
3057     }
3058   info->start[dim] = gfc_evaluate_now (info->start[dim], &loop->pre);
3059
3060   /* Similarly calculate the end.  Although this is not used in the
3061      scalarizer, it is needed when checking bounds and where the end
3062      is an expression with side-effects.  */
3063   if (end)
3064     {
3065       /* Specified section start.  */
3066       gfc_init_se (&se, NULL);
3067       gfc_conv_expr_type (&se, end, gfc_array_index_type);
3068       gfc_add_block_to_block (&loop->pre, &se.pre);
3069       info->end[dim] = se.expr;
3070     }
3071   else
3072     {
3073       /* No upper bound specified so use the bound of the array.  */
3074       info->end[dim] = gfc_conv_array_ubound (desc, dim);
3075     }
3076   info->end[dim] = gfc_evaluate_now (info->end[dim], &loop->pre);
3077
3078   /* Calculate the stride.  */
3079   if (stride == NULL)
3080     info->stride[dim] = gfc_index_one_node;
3081   else
3082     {
3083       gfc_init_se (&se, NULL);
3084       gfc_conv_expr_type (&se, stride, gfc_array_index_type);
3085       gfc_add_block_to_block (&loop->pre, &se.pre);
3086       info->stride[dim] = gfc_evaluate_now (se.expr, &loop->pre);
3087     }
3088 }
3089
3090
3091 /* Calculates the range start and stride for a SS chain.  Also gets the
3092    descriptor and data pointer.  The range of vector subscripts is the size
3093    of the vector.  Array bounds are also checked.  */
3094
3095 void
3096 gfc_conv_ss_startstride (gfc_loopinfo * loop)
3097 {
3098   int n;
3099   tree tmp;
3100   gfc_ss *ss;
3101   tree desc;
3102
3103   loop->dimen = 0;
3104   /* Determine the rank of the loop.  */
3105   for (ss = loop->ss;
3106        ss != gfc_ss_terminator && loop->dimen == 0; ss = ss->loop_chain)
3107     {
3108       switch (ss->type)
3109         {
3110         case GFC_SS_SECTION:
3111         case GFC_SS_CONSTRUCTOR:
3112         case GFC_SS_FUNCTION:
3113         case GFC_SS_COMPONENT:
3114           loop->dimen = ss->data.info.dimen;
3115           break;
3116
3117         /* As usual, lbound and ubound are exceptions!.  */
3118         case GFC_SS_INTRINSIC:
3119           switch (ss->expr->value.function.isym->id)
3120             {
3121             case GFC_ISYM_LBOUND:
3122             case GFC_ISYM_UBOUND:
3123               loop->dimen = ss->data.info.dimen;
3124
3125             default:
3126               break;
3127             }
3128
3129         default:
3130           break;
3131         }
3132     }
3133
3134   /* We should have determined the rank of the expression by now.  If
3135      not, that's bad news.  */
3136   gcc_assert (loop->dimen != 0);
3137
3138   /* Loop over all the SS in the chain.  */
3139   for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
3140     {
3141       if (ss->expr && ss->expr->shape && !ss->shape)
3142         ss->shape = ss->expr->shape;
3143
3144       switch (ss->type)
3145         {
3146         case GFC_SS_SECTION:
3147           /* Get the descriptor for the array.  */
3148           gfc_conv_ss_descriptor (&loop->pre, ss, !loop->array_parameter);
3149
3150           for (n = 0; n < ss->data.info.dimen; n++)
3151             gfc_conv_section_startstride (loop, ss, ss->data.info.dim[n]);
3152           break;
3153
3154         case GFC_SS_INTRINSIC:
3155           switch (ss->expr->value.function.isym->id)
3156             {
3157             /* Fall through to supply start and stride.  */
3158             case GFC_ISYM_LBOUND:
3159             case GFC_ISYM_UBOUND:
3160               break;
3161             default:
3162               continue;
3163             }
3164
3165         case GFC_SS_CONSTRUCTOR:
3166         case GFC_SS_FUNCTION:
3167           for (n = 0; n < ss->data.info.dimen; n++)
3168             {
3169               ss->data.info.start[n] = gfc_index_zero_node;
3170               ss->data.info.end[n] = gfc_index_zero_node;
3171               ss->data.info.stride[n] = gfc_index_one_node;
3172             }
3173           break;
3174
3175         default:
3176           break;
3177         }
3178     }
3179
3180   /* The rest is just runtime bound checking.  */
3181   if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
3182     {
3183       stmtblock_t block;
3184       tree lbound, ubound;
3185       tree end;
3186       tree size[GFC_MAX_DIMENSIONS];
3187       tree stride_pos, stride_neg, non_zerosized, tmp2, tmp3;
3188       gfc_ss_info *info;
3189       char *msg;
3190       int dim;
3191
3192       gfc_start_block (&block);
3193
3194       for (n = 0; n < loop->dimen; n++)
3195         size[n] = NULL_TREE;
3196
3197       for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
3198         {
3199           stmtblock_t inner;
3200
3201           if (ss->type != GFC_SS_SECTION)
3202             continue;
3203
3204           gfc_start_block (&inner);
3205
3206           /* TODO: range checking for mapped dimensions.  */
3207           info = &ss->data.info;
3208
3209           /* This code only checks ranges.  Elemental and vector
3210              dimensions are checked later.  */
3211           for (n = 0; n < loop->dimen; n++)
3212             {
3213               bool check_upper;
3214
3215               dim = info->dim[n];
3216               if (info->ref->u.ar.dimen_type[dim] != DIMEN_RANGE)
3217                 continue;
3218
3219               if (dim == info->ref->u.ar.dimen - 1
3220                   && info->ref->u.ar.as->type == AS_ASSUMED_SIZE)
3221                 check_upper = false;
3222               else
3223                 check_upper = true;
3224
3225               /* Zero stride is not allowed.  */
3226               tmp = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
3227                                      info->stride[dim], gfc_index_zero_node);
3228               asprintf (&msg, "Zero stride is not allowed, for dimension %d "
3229                         "of array '%s'", dim + 1, ss->expr->symtree->name);
3230               gfc_trans_runtime_check (true, false, tmp, &inner,
3231                                        &ss->expr->where, msg);
3232               gfc_free (msg);
3233
3234               desc = ss->data.info.descriptor;
3235
3236               /* This is the run-time equivalent of resolve.c's
3237                  check_dimension().  The logical is more readable there
3238                  than it is here, with all the trees.  */
3239               lbound = gfc_conv_array_lbound (desc, dim);
3240               end = info->end[dim];
3241               if (check_upper)
3242                 ubound = gfc_conv_array_ubound (desc, dim);
3243               else
3244                 ubound = NULL;
3245
3246               /* non_zerosized is true when the selected range is not
3247                  empty.  */
3248               stride_pos = fold_build2_loc (input_location, GT_EXPR,
3249                                         boolean_type_node, info->stride[dim],
3250                                         gfc_index_zero_node);
3251               tmp = fold_build2_loc (input_location, LE_EXPR, boolean_type_node,
3252                                      info->start[dim], end);
3253               stride_pos = fold_build2_loc (input_location, TRUTH_AND_EXPR,
3254                                             boolean_type_node, stride_pos, tmp);
3255
3256               stride_neg = fold_build2_loc (input_location, LT_EXPR,
3257                                      boolean_type_node,
3258                                      info->stride[dim], gfc_index_zero_node);
3259               tmp = fold_build2_loc (input_location, GE_EXPR, boolean_type_node,
3260                                      info->start[dim], end);
3261               stride_neg = fold_build2_loc (input_location, TRUTH_AND_EXPR,
3262                                             boolean_type_node,
3263                                             stride_neg, tmp);
3264               non_zerosized = fold_build2_loc (input_location, TRUTH_OR_EXPR,
3265                                                boolean_type_node,
3266                                                stride_pos, stride_neg);
3267
3268               /* Check the start of the range against the lower and upper
3269                  bounds of the array, if the range is not empty. 
3270                  If upper bound is present, include both bounds in the 
3271                  error message.  */
3272               if (check_upper)
3273                 {
3274                   tmp = fold_build2_loc (input_location, LT_EXPR,
3275                                          boolean_type_node,
3276                                          info->start[dim], lbound);
3277                   tmp = fold_build2_loc (input_location, TRUTH_AND_EXPR,
3278                                          boolean_type_node,
3279                                          non_zerosized, tmp);
3280                   tmp2 = fold_build2_loc (input_location, GT_EXPR,
3281                                           boolean_type_node,
3282                                           info->start[dim], ubound);
3283                   tmp2 = fold_build2_loc (input_location, TRUTH_AND_EXPR,
3284                                           boolean_type_node,
3285                                           non_zerosized, tmp2);
3286                   asprintf (&msg, "Index '%%ld' of dimension %d of array '%s' "
3287                             "outside of expected range (%%ld:%%ld)",
3288                             dim + 1, ss->expr->symtree->name);
3289                   gfc_trans_runtime_check (true, false, tmp, &inner,
3290                                            &ss->expr->where, msg,
3291                      fold_convert (long_integer_type_node, info->start[dim]),
3292                      fold_convert (long_integer_type_node, lbound),
3293                      fold_convert (long_integer_type_node, ubound));
3294                   gfc_trans_runtime_check (true, false, tmp2, &inner,
3295                                            &ss->expr->where, msg,
3296                      fold_convert (long_integer_type_node, info->start[dim]),
3297                      fold_convert (long_integer_type_node, lbound),
3298                      fold_convert (long_integer_type_node, ubound));
3299                   gfc_free (msg);
3300                 }
3301               else
3302                 {
3303                   tmp = fold_build2_loc (input_location, LT_EXPR,
3304                                          boolean_type_node,
3305                                          info->start[dim], lbound);
3306                   tmp = fold_build2_loc (input_location, TRUTH_AND_EXPR,
3307                                          boolean_type_node, non_zerosized, tmp);
3308                   asprintf (&msg, "Index '%%ld' of dimension %d of array '%s' "
3309                             "below lower bound of %%ld",
3310                             dim + 1, ss->expr->symtree->name);
3311                   gfc_trans_runtime_check (true, false, tmp, &inner,
3312                                            &ss->expr->where, msg,
3313                      fold_convert (long_integer_type_node, info->start[dim]),
3314                      fold_convert (long_integer_type_node, lbound));
3315                   gfc_free (msg);
3316                 }
3317               
3318               /* Compute the last element of the range, which is not
3319                  necessarily "end" (think 0:5:3, which doesn't contain 5)
3320                  and check it against both lower and upper bounds.  */
3321
3322               tmp = fold_build2_loc (input_location, MINUS_EXPR,
3323                                      gfc_array_index_type, end,
3324                                      info->start[dim]);
3325               tmp = fold_build2_loc (input_location, TRUNC_MOD_EXPR,
3326                                      gfc_array_index_type, tmp,
3327                                      info->stride[dim]);
3328               tmp = fold_build2_loc (input_location, MINUS_EXPR,
3329                                      gfc_array_index_type, end, tmp);
3330               tmp2 = fold_build2_loc (input_location, LT_EXPR,
3331                                       boolean_type_node, tmp, lbound);
3332               tmp2 = fold_build2_loc (input_location, TRUTH_AND_EXPR,
3333                                       boolean_type_node, non_zerosized, tmp2);
3334               if (check_upper)
3335                 {
3336                   tmp3 = fold_build2_loc (input_location, GT_EXPR,
3337                                           boolean_type_node, tmp, ubound);
3338                   tmp3 = fold_build2_loc (input_location, TRUTH_AND_EXPR,
3339                                           boolean_type_node, non_zerosized, tmp3);
3340                   asprintf (&msg, "Index '%%ld' of dimension %d of array '%s' "
3341                             "outside of expected range (%%ld:%%ld)",
3342                             dim + 1, ss->expr->symtree->name);
3343                   gfc_trans_runtime_check (true, false, tmp2, &inner,
3344                                            &ss->expr->where, msg,
3345                      fold_convert (long_integer_type_node, tmp),
3346                      fold_convert (long_integer_type_node, ubound), 
3347                      fold_convert (long_integer_type_node, lbound));
3348                   gfc_trans_runtime_check (true, false, tmp3, &inner,
3349                                            &ss->expr->where, msg,
3350                      fold_convert (long_integer_type_node, tmp),
3351                      fold_convert (long_integer_type_node, ubound), 
3352                      fold_convert (long_integer_type_node, lbound));
3353                   gfc_free (msg);
3354                 }
3355               else
3356                 {
3357                   asprintf (&msg, "Index '%%ld' of dimension %d of array '%s' "
3358                             "below lower bound of %%ld",
3359                             dim + 1, ss->expr->symtree->name);
3360                   gfc_trans_runtime_check (true, false, tmp2, &inner,
3361                                            &ss->expr->where, msg,
3362                      fold_convert (long_integer_type_node, tmp),
3363                      fold_convert (long_integer_type_node, lbound));
3364                   gfc_free (msg);
3365                 }
3366
3367               /* Check the section sizes match.  */
3368               tmp = fold_build2_loc (input_location, MINUS_EXPR,
3369                                      gfc_array_index_type, end,
3370                                      info->start[dim]);
3371               tmp = fold_build2_loc (input_location, FLOOR_DIV_EXPR,
3372                                      gfc_array_index_type, tmp,
3373                                      info->stride[dim]);
3374               tmp = fold_build2_loc (input_location, PLUS_EXPR,
3375                                      gfc_array_index_type,
3376                                      gfc_index_one_node, tmp);
3377               tmp = fold_build2_loc (input_location, MAX_EXPR,
3378                                      gfc_array_index_type, tmp,
3379                                      build_int_cst (gfc_array_index_type, 0));
3380               /* We remember the size of the first section, and check all the
3381                  others against this.  */
3382               if (size[n])
3383                 {
3384                   tmp3 = fold_build2_loc (input_location, NE_EXPR,
3385                                           boolean_type_node, tmp, size[n]);
3386                   asprintf (&msg, "Array bound mismatch for dimension %d "
3387                             "of array '%s' (%%ld/%%ld)",
3388                             dim + 1, ss->expr->symtree->name);
3389
3390                   gfc_trans_runtime_check (true, false, tmp3, &inner,
3391                                            &ss->expr->where, msg,
3392                         fold_convert (long_integer_type_node, tmp),
3393                         fold_convert (long_integer_type_node, size[n]));
3394
3395                   gfc_free (msg);
3396                 }
3397               else
3398                 size[n] = gfc_evaluate_now (tmp, &inner);
3399             }
3400
3401           tmp = gfc_finish_block (&inner);
3402
3403           /* For optional arguments, only check bounds if the argument is
3404              present.  */
3405           if (ss->expr->symtree->n.sym->attr.optional
3406               || ss->expr->symtree->n.sym->attr.not_always_present)
3407             tmp = build3_v (COND_EXPR,
3408                             gfc_conv_expr_present (ss->expr->symtree->n.sym),
3409                             tmp, build_empty_stmt (input_location));
3410
3411           gfc_add_expr_to_block (&block, tmp);
3412
3413         }
3414
3415       tmp = gfc_finish_block (&block);
3416       gfc_add_expr_to_block (&loop->pre, tmp);
3417     }
3418 }
3419
3420
3421 /* Return true if the two SS could be aliased, i.e. both point to the same data
3422    object.  */
3423 /* TODO: resolve aliases based on frontend expressions.  */
3424
3425 static int
3426 gfc_could_be_alias (gfc_ss * lss, gfc_ss * rss)
3427 {
3428   gfc_ref *lref;
3429   gfc_ref *rref;
3430   gfc_symbol *lsym;
3431   gfc_symbol *rsym;
3432
3433   lsym = lss->expr->symtree->n.sym;
3434   rsym = rss->expr->symtree->n.sym;
3435   if (gfc_symbols_could_alias (lsym, rsym))
3436     return 1;
3437
3438   if (rsym->ts.type != BT_DERIVED
3439       && lsym->ts.type != BT_DERIVED)
3440     return 0;
3441
3442   /* For derived types we must check all the component types.  We can ignore
3443      array references as these will have the same base type as the previous
3444      component ref.  */
3445   for (lref = lss->expr->ref; lref != lss->data.info.ref; lref = lref->next)
3446     {
3447       if (lref->type != REF_COMPONENT)
3448         continue;
3449
3450       if (gfc_symbols_could_alias (lref->u.c.sym, rsym))
3451         return 1;
3452
3453       for (rref = rss->expr->ref; rref != rss->data.info.ref;
3454            rref = rref->next)
3455         {
3456           if (rref->type != REF_COMPONENT)
3457             continue;
3458
3459           if (gfc_symbols_could_alias (lref->u.c.sym, rref->u.c.sym))
3460             return 1;
3461         }
3462     }
3463
3464   for (rref = rss->expr->ref; rref != rss->data.info.ref; rref = rref->next)
3465     {
3466       if (rref->type != REF_COMPONENT)
3467         break;
3468
3469       if (gfc_symbols_could_alias (rref->u.c.sym, lsym))
3470         return 1;
3471     }
3472
3473   return 0;
3474 }
3475
3476
3477 /* Resolve array data dependencies.  Creates a temporary if required.  */
3478 /* TODO: Calc dependencies with gfc_expr rather than gfc_ss, and move to
3479    dependency.c.  */
3480
3481 void
3482 gfc_conv_resolve_dependencies (gfc_loopinfo * loop, gfc_ss * dest,
3483                                gfc_ss * rss)
3484 {
3485   gfc_ss *ss;
3486   gfc_ref *lref;
3487   gfc_ref *rref;
3488   int nDepend = 0;
3489   int i, j;
3490
3491   loop->temp_ss = NULL;
3492
3493   for (ss = rss; ss != gfc_ss_terminator; ss = ss->next)
3494     {
3495       if (ss->type != GFC_SS_SECTION)
3496         continue;
3497
3498       if (dest->expr->symtree->n.sym != ss->expr->symtree->n.sym)
3499         {
3500           if (gfc_could_be_alias (dest, ss)
3501                 || gfc_are_equivalenced_arrays (dest->expr, ss->expr))
3502             {
3503               nDepend = 1;
3504               break;
3505             }
3506         }
3507       else
3508         {
3509           lref = dest->expr->ref;
3510           rref = ss->expr->ref;
3511
3512           nDepend = gfc_dep_resolver (lref, rref, &loop->reverse[0]);
3513
3514           if (nDepend == 1)
3515             break;
3516
3517           for (i = 0; i < dest->data.info.dimen; i++)
3518             for (j = 0; j < ss->data.info.dimen; j++)
3519               if (i != j
3520                   && dest->data.info.dim[i] == ss->data.info.dim[j])
3521                 {
3522                   /* If we don't access array elements in the same order,
3523                      there is a dependency.  */
3524                   nDepend = 1;
3525                   goto temporary;
3526                 }
3527 #if 0
3528           /* TODO : loop shifting.  */
3529           if (nDepend == 1)
3530             {
3531               /* Mark the dimensions for LOOP SHIFTING */
3532               for (n = 0; n < loop->dimen; n++)
3533                 {
3534                   int dim = dest->data.info.dim[n];
3535
3536                   if (lref->u.ar.dimen_type[dim] == DIMEN_VECTOR)
3537                     depends[n] = 2;
3538                   else if (! gfc_is_same_range (&lref->u.ar,
3539                                                 &rref->u.ar, dim, 0))
3540                     depends[n] = 1;
3541                  }
3542
3543               /* Put all the dimensions with dependencies in the
3544                  innermost loops.  */
3545               dim = 0;
3546               for (n = 0; n < loop->dimen; n++)
3547                 {
3548                   gcc_assert (loop->order[n] == n);
3549                   if (depends[n])
3550                   loop->order[dim++] = n;
3551                 }
3552               for (n = 0; n < loop->dimen; n++)
3553                 {
3554                   if (! depends[n])
3555                   loop->order[dim++] = n;
3556                 }
3557
3558               gcc_assert (dim == loop->dimen);
3559               break;
3560             }
3561 #endif
3562         }
3563     }
3564
3565 temporary:
3566
3567   if (nDepend == 1)
3568     {
3569       tree base_type = gfc_typenode_for_spec (&dest->expr->ts);
3570       if (GFC_ARRAY_TYPE_P (base_type)
3571           || GFC_DESCRIPTOR_TYPE_P (base_type))
3572         base_type = gfc_get_element_type (base_type);
3573       loop->temp_ss = gfc_get_ss ();
3574       loop->temp_ss->type = GFC_SS_TEMP;
3575       loop->temp_ss->data.temp.type = base_type;
3576       loop->temp_ss->string_length = dest->string_length;
3577       loop->temp_ss->data.temp.dimen = loop->dimen;
3578       loop->temp_ss->next = gfc_ss_terminator;
3579       gfc_add_ss_to_loop (loop, loop->temp_ss);
3580     }
3581   else
3582     loop->temp_ss = NULL;
3583 }
3584
3585
3586 /* Initialize the scalarization loop.  Creates the loop variables.  Determines
3587    the range of the loop variables.  Creates a temporary if required.
3588    Calculates how to transform from loop variables to array indices for each
3589    expression.  Also generates code for scalar expressions which have been
3590    moved outside the loop.  */
3591
3592 void
3593 gfc_conv_loop_setup (gfc_loopinfo * loop, locus * where)
3594 {
3595   int n, dim, spec_dim;
3596   gfc_ss_info *info;
3597   gfc_ss_info *specinfo;
3598   gfc_ss *ss;
3599   tree tmp;
3600   gfc_ss *loopspec[GFC_MAX_DIMENSIONS];
3601   bool dynamic[GFC_MAX_DIMENSIONS];
3602   mpz_t *cshape;
3603   mpz_t i;
3604
3605   mpz_init (i);
3606   for (n = 0; n < loop->dimen; n++)
3607     {
3608       loopspec[n] = NULL;
3609       dynamic[n] = false;
3610       /* We use one SS term, and use that to determine the bounds of the
3611          loop for this dimension.  We try to pick the simplest term.  */
3612       for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
3613         {
3614           if (ss->type == GFC_SS_SCALAR || ss->type == GFC_SS_REFERENCE)
3615             continue;
3616
3617           info = &ss->data.info;
3618           dim = info->dim[n];
3619
3620           if (loopspec[n] != NULL)
3621             {
3622               specinfo = &loopspec[n]->data.info;
3623               spec_dim = specinfo->dim[n];
3624             }
3625           else
3626             {
3627               /* Silence unitialized warnings.  */
3628               specinfo = NULL;
3629               spec_dim = 0;
3630             }
3631
3632           if (ss->shape)
3633             {
3634               gcc_assert (ss->shape[dim]);
3635               /* The frontend has worked out the size for us.  */
3636               if (!loopspec[n]
3637                   || !loopspec[n]->shape
3638                   || !integer_zerop (specinfo->start[spec_dim]))
3639                 /* Prefer zero-based descriptors if possible.  */
3640                 loopspec[n] = ss;
3641               continue;
3642             }
3643
3644           if (ss->type == GFC_SS_CONSTRUCTOR)
3645             {
3646               gfc_constructor_base base;
3647               /* An unknown size constructor will always be rank one.
3648                  Higher rank constructors will either have known shape,
3649                  or still be wrapped in a call to reshape.  */
3650               gcc_assert (loop->dimen == 1);
3651
3652               /* Always prefer to use the constructor bounds if the size
3653                  can be determined at compile time.  Prefer not to otherwise,
3654                  since the general case involves realloc, and it's better to
3655                  avoid that overhead if possible.  */
3656               base = ss->expr->value.constructor;
3657               dynamic[n] = gfc_get_array_constructor_size (&i, base);
3658               if (!dynamic[n] || !loopspec[n])
3659                 loopspec[n] = ss;
3660               continue;
3661             }
3662
3663           /* TODO: Pick the best bound if we have a choice between a
3664              function and something else.  */
3665           if (ss->type == GFC_SS_FUNCTION)
3666             {
3667               loopspec[n] = ss;
3668               continue;
3669             }
3670
3671           if (ss->type != GFC_SS_SECTION)
3672             continue;
3673
3674           if (!loopspec[n])
3675             loopspec[n] = ss;
3676           /* Criteria for choosing a loop specifier (most important first):
3677              doesn't need realloc
3678              stride of one
3679              known stride
3680              known lower bound
3681              known upper bound
3682            */
3683           else if (loopspec[n]->type == GFC_SS_CONSTRUCTOR && dynamic[n])
3684             loopspec[n] = ss;
3685           else if (integer_onep (info->stride[dim])
3686                    && !integer_onep (specinfo->stride[spec_dim]))
3687             loopspec[n] = ss;
3688           else if (INTEGER_CST_P (info->stride[dim])
3689                    && !INTEGER_CST_P (specinfo->stride[spec_dim]))
3690             loopspec[n] = ss;
3691           else if (INTEGER_CST_P (info->start[dim])
3692                    && !INTEGER_CST_P (specinfo->start[spec_dim]))
3693             loopspec[n] = ss;
3694           /* We don't work out the upper bound.
3695              else if (INTEGER_CST_P (info->finish[n])
3696              && ! INTEGER_CST_P (specinfo->finish[n]))
3697              loopspec[n] = ss; */
3698         }
3699
3700       /* We should have found the scalarization loop specifier.  If not,
3701          that's bad news.  */
3702       gcc_assert (loopspec[n]);
3703
3704       info = &loopspec[n]->data.info;
3705       dim = info->dim[n];
3706
3707       /* Set the extents of this range.  */
3708       cshape = loopspec[n]->shape;
3709       if (cshape && INTEGER_CST_P (info->start[dim])
3710           && INTEGER_CST_P (info->stride[dim]))
3711         {
3712           loop->from[n] = info->start[dim];
3713           mpz_set (i, cshape[get_array_ref_dim (info, n)]);
3714           mpz_sub_ui (i, i, 1);
3715           /* To = from + (size - 1) * stride.  */
3716           tmp = gfc_conv_mpz_to_tree (i, gfc_index_integer_kind);
3717           if (!integer_onep (info->stride[dim]))
3718             tmp = fold_build2_loc (input_location, MULT_EXPR,
3719                                    gfc_array_index_type, tmp,
3720                                    info->stride[dim]);
3721           loop->to[n] = fold_build2_loc (input_location, PLUS_EXPR,
3722                                          gfc_array_index_type,
3723                                          loop->from[n], tmp);
3724         }
3725       else
3726         {
3727           loop->from[n] = info->start[dim];
3728           switch (loopspec[n]->type)
3729             {
3730             case GFC_SS_CONSTRUCTOR:
3731               /* The upper bound is calculated when we expand the
3732                  constructor.  */
3733               gcc_assert (loop->to[n] == NULL_TREE);
3734               break;
3735
3736             case GFC_SS_SECTION:
3737               /* Use the end expression if it exists and is not constant,
3738                  so that it is only evaluated once.  */
3739               loop->to[n] = info->end[dim];
3740               break;
3741
3742             case GFC_SS_FUNCTION:
3743               /* The loop bound will be set when we generate the call.  */
3744               gcc_assert (loop->to[n] == NULL_TREE);
3745               break;
3746
3747             default:
3748               gcc_unreachable ();
3749             }
3750         }
3751
3752       /* Transform everything so we have a simple incrementing variable.  */
3753       if (integer_onep (info->stride[dim]))
3754         info->delta[dim] = gfc_index_zero_node;
3755       else
3756         {
3757           /* Set the delta for this section.  */
3758           info->delta[dim] = gfc_evaluate_now (loop->from[n], &loop->pre);
3759           /* Number of iterations is (end - start + step) / step.
3760              with start = 0, this simplifies to
3761              last = end / step;
3762              for (i = 0; i<=last; i++){...};  */
3763           tmp = fold_build2_loc (input_location, MINUS_EXPR,
3764                                  gfc_array_index_type, loop->to[n],
3765                                  loop->from[n]);
3766           tmp = fold_build2_loc (input_location, FLOOR_DIV_EXPR,
3767                                  gfc_array_index_type, tmp, info->stride[dim]);
3768           tmp = fold_build2_loc (input_location, MAX_EXPR, gfc_array_index_type,
3769                                  tmp, build_int_cst (gfc_array_index_type, -1));
3770           loop->to[n] = gfc_evaluate_now (tmp, &loop->pre);
3771           /* Make the loop variable start at 0.  */
3772           loop->from[n] = gfc_index_zero_node;
3773         }
3774     }
3775
3776   /* Add all the scalar code that can be taken out of the loops.
3777      This may include calculating the loop bounds, so do it before
3778      allocating the temporary.  */
3779   gfc_add_loop_ss_code (loop, loop->ss, false, where);
3780
3781   /* If we want a temporary then create it.  */
3782   if (loop->temp_ss != NULL)
3783     {
3784       gcc_assert (loop->temp_ss->type == GFC_SS_TEMP);
3785
3786       /* Make absolutely sure that this is a complete type.  */
3787       if (loop->temp_ss->string_length)
3788         loop->temp_ss->data.temp.type
3789                 = gfc_get_character_type_len_for_eltype
3790                         (TREE_TYPE (loop->temp_ss->data.temp.type),
3791                          loop->temp_ss->string_length);
3792
3793       tmp = loop->temp_ss->data.temp.type;
3794       n = loop->temp_ss->data.temp.dimen;
3795       memset (&loop->temp_ss->data.info, 0, sizeof (gfc_ss_info));
3796       loop->temp_ss->type = GFC_SS_SECTION;
3797       loop->temp_ss->data.info.dimen = n;
3798
3799       gcc_assert (loop->temp_ss->data.info.dimen != 0);
3800       for (n = 0; n < loop->temp_ss->data.info.dimen; n++)
3801         loop->temp_ss->data.info.dim[n] = n;
3802
3803       gfc_trans_create_temp_array (&loop->pre, &loop->post, loop,
3804                                    &loop->temp_ss->data.info, tmp, NULL_TREE,
3805                                    false, true, false, where);
3806     }
3807
3808   for (n = 0; n < loop->temp_dim; n++)
3809     loopspec[loop->order[n]] = NULL;
3810
3811   mpz_clear (i);
3812
3813   /* For array parameters we don't have loop variables, so don't calculate the
3814      translations.  */
3815   if (loop->array_parameter)
3816     return;
3817
3818   /* Calculate the translation from loop variables to array indices.  */
3819   for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
3820     {
3821       if (ss->type != GFC_SS_SECTION && ss->type != GFC_SS_COMPONENT
3822             && ss->type != GFC_SS_CONSTRUCTOR)
3823
3824         continue;
3825
3826       info = &ss->data.info;
3827
3828       for (n = 0; n < info->dimen; n++)
3829         {
3830           /* If we are specifying the range the delta is already set.  */
3831           if (loopspec[n] != ss)
3832             {
3833               dim = ss->data.info.dim[n];
3834
3835               /* Calculate the offset relative to the loop variable.
3836                  First multiply by the stride.  */
3837               tmp = loop->from[n];
3838               if (!integer_onep (info->stride[dim]))
3839                 tmp = fold_build2_loc (input_location, MULT_EXPR,
3840                                        gfc_array_index_type,
3841                                        tmp, info->stride[dim]);
3842
3843               /* Then subtract this from our starting value.  */
3844               tmp = fold_build2_loc (input_location, MINUS_EXPR,
3845                                      gfc_array_index_type,
3846                                      info->start[dim], tmp);
3847
3848               info->delta[dim] = gfc_evaluate_now (tmp, &loop->pre);
3849             }
3850         }
3851     }
3852 }
3853
3854
3855 /* Calculate the size of a given array dimension from the bounds.  This
3856    is simply (ubound - lbound + 1) if this expression is positive
3857    or 0 if it is negative (pick either one if it is zero).  Optionally
3858    (if or_expr is present) OR the (expression != 0) condition to it.  */
3859
3860 tree
3861 gfc_conv_array_extent_dim (tree lbound, tree ubound, tree* or_expr)
3862 {
3863   tree res;
3864   tree cond;
3865
3866   /* Calculate (ubound - lbound + 1).  */
3867   res = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
3868                          ubound, lbound);
3869   res = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type, res,
3870                          gfc_index_one_node);
3871
3872   /* Check whether the size for this dimension is negative.  */
3873   cond = fold_build2_loc (input_location, LE_EXPR, boolean_type_node, res,
3874                           gfc_index_zero_node);
3875   res = fold_build3_loc (input_location, COND_EXPR, gfc_array_index_type, cond,
3876                          gfc_index_zero_node, res);
3877
3878   /* Build OR expression.  */
3879   if (or_expr)
3880     *or_expr = fold_build2_loc (input_location, TRUTH_OR_EXPR,
3881                                 boolean_type_node, *or_expr, cond);
3882
3883   return res;
3884 }
3885
3886
3887 /* For an array descriptor, get the total number of elements.  This is just
3888    the product of the extents along all dimensions.  */
3889
3890 tree
3891 gfc_conv_descriptor_size (tree desc, int rank)
3892 {
3893   tree res;
3894   int dim;
3895
3896   res = gfc_index_one_node;
3897
3898   for (dim = 0; dim < rank; ++dim)
3899     {
3900       tree lbound;
3901       tree ubound;
3902       tree extent;
3903
3904       lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[dim]);
3905       ubound = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[dim]);
3906
3907       extent = gfc_conv_array_extent_dim (lbound, ubound, NULL);
3908       res = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
3909                              res, extent);
3910     }
3911
3912   return res;
3913 }
3914
3915
3916 /* Fills in an array descriptor, and returns the size of the array.  The size
3917    will be a simple_val, ie a variable or a constant.  Also calculates the
3918    offset of the base.  Returns the size of the array.
3919    {
3920     stride = 1;
3921     offset = 0;
3922     for (n = 0; n < rank; n++)
3923       {
3924         a.lbound[n] = specified_lower_bound;
3925         offset = offset + a.lbond[n] * stride;
3926         size = 1 - lbound;
3927         a.ubound[n] = specified_upper_bound;
3928         a.stride[n] = stride;
3929         size = siz >= 0 ? ubound + size : 0; //size = ubound + 1 - lbound
3930         stride = stride * size;
3931       }
3932     return (stride);
3933    }  */
3934 /*GCC ARRAYS*/
3935
3936 static tree
3937 gfc_array_init_size (tree descriptor, int rank, int corank, tree * poffset,
3938                      gfc_expr ** lower, gfc_expr ** upper,
3939                      stmtblock_t * pblock)
3940 {
3941   tree type;
3942   tree tmp;
3943   tree size;
3944   tree offset;
3945   tree stride;
3946   tree or_expr;
3947   tree thencase;
3948   tree elsecase;
3949   tree var;
3950   stmtblock_t thenblock;
3951   stmtblock_t elseblock;
3952   gfc_expr *ubound;
3953   gfc_se se;
3954   int n;
3955
3956   type = TREE_TYPE (descriptor);
3957
3958   stride = gfc_index_one_node;
3959   offset = gfc_index_zero_node;
3960
3961   /* Set the dtype.  */
3962   tmp = gfc_conv_descriptor_dtype (descriptor);
3963   gfc_add_modify (pblock, tmp, gfc_get_dtype (TREE_TYPE (descriptor)));
3964
3965   or_expr = boolean_false_node;
3966
3967   for (n = 0; n < rank; n++)
3968     {
3969       tree conv_lbound;
3970       tree conv_ubound;
3971
3972       /* We have 3 possibilities for determining the size of the array:
3973          lower == NULL    => lbound = 1, ubound = upper[n]
3974          upper[n] = NULL  => lbound = 1, ubound = lower[n]
3975          upper[n] != NULL => lbound = lower[n], ubound = upper[n]  */
3976       ubound = upper[n];
3977
3978       /* Set lower bound.  */
3979       gfc_init_se (&se, NULL);
3980       if (lower == NULL)
3981         se.expr = gfc_index_one_node;
3982       else
3983         {
3984           gcc_assert (lower[n]);
3985           if (ubound)
3986             {
3987               gfc_conv_expr_type (&se, lower[n], gfc_array_index_type);
3988               gfc_add_block_to_block (pblock, &se.pre);
3989             }
3990           else
3991             {
3992               se.expr = gfc_index_one_node;
3993               ubound = lower[n];
3994             }
3995         }
3996       gfc_conv_descriptor_lbound_set (pblock, descriptor, gfc_rank_cst[n],
3997                                       se.expr);
3998       conv_lbound = se.expr;
3999
4000       /* Work out the offset for this component.  */
4001       tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
4002                              se.expr, stride);
4003       offset = fold_build2_loc (input_location, MINUS_EXPR,
4004                                 gfc_array_index_type, offset, tmp);
4005
4006       /* Set upper bound.  */
4007       gfc_init_se (&se, NULL);
4008       gcc_assert (ubound);
4009       gfc_conv_expr_type (&se, ubound, gfc_array_index_type);
4010       gfc_add_block_to_block (pblock, &se.pre);
4011
4012       gfc_conv_descriptor_ubound_set (pblock, descriptor,
4013                                       gfc_rank_cst[n], se.expr);
4014       conv_ubound = se.expr;
4015
4016       /* Store the stride.  */
4017       gfc_conv_descriptor_stride_set (pblock, descriptor,
4018                                       gfc_rank_cst[n], stride);
4019
4020       /* Calculate size and check whether extent is negative.  */
4021       size = gfc_conv_array_extent_dim (conv_lbound, conv_ubound, &or_expr);
4022
4023       /* Multiply the stride by the number of elements in this dimension.  */
4024       stride = fold_build2_loc (input_location, MULT_EXPR,
4025                                 gfc_array_index_type, stride, size);
4026       stride = gfc_evaluate_now (stride, pblock);
4027     }
4028
4029   for (n = rank; n < rank + corank; n++)
4030     {
4031       ubound = upper[n];
4032
4033       /* Set lower bound.  */
4034       gfc_init_se (&se, NULL);
4035       if (lower == NULL || lower[n] == NULL)
4036         {
4037           gcc_assert (n == rank + corank - 1);
4038           se.expr = gfc_index_one_node;
4039         }
4040       else
4041         {
4042           if (ubound || n == rank + corank - 1)
4043             {
4044               gfc_conv_expr_type (&se, lower[n], gfc_array_index_type);
4045               gfc_add_block_to_block (pblock, &se.pre);
4046             }
4047           else
4048             {
4049               se.expr = gfc_index_one_node;
4050               ubound = lower[n];
4051             }
4052         }
4053       gfc_conv_descriptor_lbound_set (pblock, descriptor, gfc_rank_cst[n],
4054                                       se.expr);
4055
4056       if (n < rank + corank - 1)
4057         {
4058           gfc_init_se (&se, NULL);
4059           gcc_assert (ubound);
4060           gfc_conv_expr_type (&se, ubound, gfc_array_index_type);
4061           gfc_add_block_to_block (pblock, &se.pre);
4062           gfc_conv_descriptor_ubound_set (pblock, descriptor,
4063                                           gfc_rank_cst[n], se.expr);
4064         }
4065     }
4066
4067   /* The stride is the number of elements in the array, so multiply by the
4068      size of an element to get the total size.  */
4069   tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type));
4070   size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
4071                           stride, fold_convert (gfc_array_index_type, tmp));
4072
4073   if (poffset != NULL)
4074     {
4075       offset = gfc_evaluate_now (offset, pblock);
4076       *poffset = offset;
4077     }
4078
4079   if (integer_zerop (or_expr))
4080     return size;
4081   if (integer_onep (or_expr))
4082     return gfc_index_zero_node;
4083
4084   var = gfc_create_var (TREE_TYPE (size), "size");
4085   gfc_start_block (&thenblock);
4086   gfc_add_modify (&thenblock, var, gfc_index_zero_node);
4087   thencase = gfc_finish_block (&thenblock);
4088
4089   gfc_start_block (&elseblock);
4090   gfc_add_modify (&elseblock, var, size);
4091   elsecase = gfc_finish_block (&elseblock);
4092
4093   tmp = gfc_evaluate_now (or_expr, pblock);
4094   tmp = build3_v (COND_EXPR, tmp, thencase, elsecase);
4095   gfc_add_expr_to_block (pblock, tmp);
4096
4097   return var;
4098 }
4099
4100
4101 /* Initializes the descriptor and generates a call to _gfor_allocate.  Does
4102    the work for an ALLOCATE statement.  */
4103 /*GCC ARRAYS*/
4104
4105 bool
4106 gfc_array_allocate (gfc_se * se, gfc_expr * expr, tree pstat)
4107 {
4108   tree tmp;
4109   tree pointer;
4110   tree offset;
4111   tree size;
4112   gfc_expr **lower;
4113   gfc_expr **upper;
4114   gfc_ref *ref, *prev_ref = NULL;
4115   bool allocatable_array, coarray;
4116
4117   ref = expr->ref;
4118
4119   /* Find the last reference in the chain.  */
4120   while (ref && ref->next != NULL)
4121     {
4122       gcc_assert (ref->type != REF_ARRAY || ref->u.ar.type == AR_ELEMENT
4123                   || (ref->u.ar.dimen == 0 && ref->u.ar.codimen > 0));
4124       prev_ref = ref;
4125       ref = ref->next;
4126     }
4127
4128   if (ref == NULL || ref->type != REF_ARRAY)
4129     return false;
4130
4131   if (!prev_ref)
4132     {
4133       allocatable_array = expr->symtree->n.sym->attr.allocatable;
4134       coarray = expr->symtree->n.sym->attr.codimension;
4135     }
4136   else
4137     {
4138       allocatable_array = prev_ref->u.c.component->attr.allocatable;
4139       coarray = prev_ref->u.c.component->attr.codimension;
4140     }
4141
4142   /* Return if this is a scalar coarray.  */
4143   if ((!prev_ref && !expr->symtree->n.sym->attr.dimension)
4144       || (prev_ref && !prev_ref->u.c.component->attr.dimension))
4145     {
4146       gcc_assert (coarray);
4147       return false;
4148     }
4149
4150   /* Figure out the size of the array.  */
4151   switch (ref->u.ar.type)
4152     {
4153     case AR_ELEMENT:
4154       if (!coarray)
4155         {
4156           lower = NULL;
4157           upper = ref->u.ar.start;
4158           break;
4159         }
4160       /* Fall through.  */
4161
4162     case AR_SECTION:
4163       lower = ref->u.ar.start;
4164       upper = ref->u.ar.end;
4165       break;
4166
4167     case AR_FULL:
4168       gcc_assert (ref->u.ar.as->type == AS_EXPLICIT);
4169
4170       lower = ref->u.ar.as->lower;
4171       upper = ref->u.ar.as->upper;
4172       break;
4173
4174     default:
4175       gcc_unreachable ();
4176       break;
4177     }
4178
4179   size = gfc_array_init_size (se->expr, ref->u.ar.as->rank,
4180                               ref->u.ar.as->corank, &offset, lower, upper,
4181                               &se->pre);
4182
4183   /* Allocate memory to store the data.  */
4184   pointer = gfc_conv_descriptor_data_get (se->expr);
4185   STRIP_NOPS (pointer);
4186
4187   /* The allocate_array variants take the old pointer as first argument.  */
4188   if (allocatable_array)
4189     tmp = gfc_allocate_array_with_status (&se->pre, pointer, size, pstat, expr);
4190   else
4191     tmp = gfc_allocate_with_status (&se->pre, size, pstat);
4192   tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node, pointer,
4193                          tmp);
4194   gfc_add_expr_to_block (&se->pre, tmp);
4195
4196   gfc_conv_descriptor_offset_set (&se->pre, se->expr, offset);
4197
4198   if (expr->ts.type == BT_DERIVED
4199         && expr->ts.u.derived->attr.alloc_comp)
4200     {
4201       tmp = gfc_nullify_alloc_comp (expr->ts.u.derived, se->expr,
4202                                     ref->u.ar.as->rank);
4203       gfc_add_expr_to_block (&se->pre, tmp);
4204     }
4205
4206   return true;
4207 }
4208
4209
4210 /* Deallocate an array variable.  Also used when an allocated variable goes
4211    out of scope.  */
4212 /*GCC ARRAYS*/
4213
4214 tree
4215 gfc_array_deallocate (tree descriptor, tree pstat, gfc_expr* expr)
4216 {
4217   tree var;
4218   tree tmp;
4219   stmtblock_t block;
4220
4221   gfc_start_block (&block);
4222   /* Get a pointer to the data.  */
4223   var = gfc_conv_descriptor_data_get (descriptor);
4224   STRIP_NOPS (var);
4225
4226   /* Parameter is the address of the data component.  */
4227   tmp = gfc_deallocate_with_status (var, pstat, false, expr);
4228   gfc_add_expr_to_block (&block, tmp);
4229
4230   /* Zero the data pointer.  */
4231   tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node,
4232                          var, build_int_cst (TREE_TYPE (var), 0));
4233   gfc_add_expr_to_block (&block, tmp);
4234
4235   return gfc_finish_block (&block);
4236 }
4237
4238
4239 /* Create an array constructor from an initialization expression.
4240    We assume the frontend already did any expansions and conversions.  */
4241
4242 tree
4243 gfc_conv_array_initializer (tree type, gfc_expr * expr)
4244 {
4245   gfc_constructor *c;
4246   tree tmp;
4247   gfc_se se;
4248   HOST_WIDE_INT hi;
4249   unsigned HOST_WIDE_INT lo;
4250   tree index;
4251   VEC(constructor_elt,gc) *v = NULL;
4252
4253   switch (expr->expr_type)
4254     {
4255     case EXPR_CONSTANT:
4256     case EXPR_STRUCTURE:
4257       /* A single scalar or derived type value.  Create an array with all
4258          elements equal to that value.  */
4259       gfc_init_se (&se, NULL);
4260       
4261       if (expr->expr_type == EXPR_CONSTANT)
4262         gfc_conv_constant (&se, expr);
4263       else
4264         gfc_conv_structure (&se, expr, 1);
4265
4266       tmp = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
4267       gcc_assert (tmp && INTEGER_CST_P (tmp));
4268       hi = TREE_INT_CST_HIGH (tmp);
4269       lo = TREE_INT_CST_LOW (tmp);
4270       lo++;
4271       if (lo == 0)
4272         hi++;
4273       /* This will probably eat buckets of memory for large arrays.  */
4274       while (hi != 0 || lo != 0)
4275         {
4276           CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, se.expr);
4277           if (lo == 0)
4278             hi--;
4279           lo--;
4280         }
4281       break;
4282
4283     case EXPR_ARRAY:
4284       /* Create a vector of all the elements.  */
4285       for (c = gfc_constructor_first (expr->value.constructor);
4286            c; c = gfc_constructor_next (c))
4287         {
4288           if (c->iterator)
4289             {
4290               /* Problems occur when we get something like
4291                  integer :: a(lots) = (/(i, i=1, lots)/)  */
4292               gfc_fatal_error ("The number of elements in the array constructor "
4293                                "at %L requires an increase of the allowed %d "
4294                                "upper limit.   See -fmax-array-constructor "
4295                                "option", &expr->where,
4296                                gfc_option.flag_max_array_constructor);
4297               return NULL_TREE;
4298             }
4299           if (mpz_cmp_si (c->offset, 0) != 0)
4300             index = gfc_conv_mpz_to_tree (c->offset, gfc_index_integer_kind);
4301           else
4302             index = NULL_TREE;
4303
4304           gfc_init_se (&se, NULL);
4305           switch (c->expr->expr_type)
4306             {
4307             case EXPR_CONSTANT:
4308               gfc_conv_constant (&se, c->expr);
4309               CONSTRUCTOR_APPEND_ELT (v, index, se.expr);
4310               break;
4311
4312             case EXPR_STRUCTURE:
4313               gfc_conv_structure (&se, c->expr, 1);
4314               CONSTRUCTOR_APPEND_ELT (v, index, se.expr);
4315               break;
4316
4317
4318             default:
4319               /* Catch those occasional beasts that do not simplify
4320                  for one reason or another, assuming that if they are
4321                  standard defying the frontend will catch them.  */
4322               gfc_conv_expr (&se, c->expr);
4323               CONSTRUCTOR_APPEND_ELT (v, index, se.expr);
4324               break;
4325             }
4326         }
4327       break;
4328
4329     case EXPR_NULL:
4330       return gfc_build_null_descriptor (type);
4331
4332     default:
4333       gcc_unreachable ();
4334     }
4335
4336   /* Create a constructor from the list of elements.  */
4337   tmp = build_constructor (type, v);
4338   TREE_CONSTANT (tmp) = 1;
4339   return tmp;
4340 }
4341
4342
4343 /* Generate code to evaluate non-constant array bounds.  Sets *poffset and
4344    returns the size (in elements) of the array.  */
4345
4346 static tree
4347 gfc_trans_array_bounds (tree type, gfc_symbol * sym, tree * poffset,
4348                         stmtblock_t * pblock)
4349 {
4350   gfc_array_spec *as;
4351   tree size;
4352   tree stride;
4353   tree offset;
4354   tree ubound;
4355   tree lbound;
4356   tree tmp;
4357   gfc_se se;
4358
4359   int dim;
4360
4361   as = sym->as;
4362
4363   size = gfc_index_one_node;
4364   offset = gfc_index_zero_node;
4365   for (dim = 0; dim < as->rank; dim++)
4366     {
4367       /* Evaluate non-constant array bound expressions.  */
4368       lbound = GFC_TYPE_ARRAY_LBOUND (type, dim);
4369       if (as->lower[dim] && !INTEGER_CST_P (lbound))
4370         {
4371           gfc_init_se (&se, NULL);
4372           gfc_conv_expr_type (&se, as->lower[dim], gfc_array_index_type);
4373           gfc_add_block_to_block (pblock, &se.pre);
4374           gfc_add_modify (pblock, lbound, se.expr);
4375         }
4376       ubound = GFC_TYPE_ARRAY_UBOUND (type, dim);
4377       if (as->upper[dim] && !INTEGER_CST_P (ubound))
4378         {
4379           gfc_init_se (&se, NULL);
4380           gfc_conv_expr_type (&se, as->upper[dim], gfc_array_index_type);
4381           gfc_add_block_to_block (pblock, &se.pre);
4382           gfc_add_modify (pblock, ubound, se.expr);
4383         }
4384       /* The offset of this dimension.  offset = offset - lbound * stride.  */
4385       tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
4386                              lbound, size);
4387       offset = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
4388                                 offset, tmp);
4389
4390       /* The size of this dimension, and the stride of the next.  */
4391       if (dim + 1 < as->rank)
4392         stride = GFC_TYPE_ARRAY_STRIDE (type, dim + 1);
4393       else
4394         stride = GFC_TYPE_ARRAY_SIZE (type);
4395
4396       if (ubound != NULL_TREE && !(stride && INTEGER_CST_P (stride)))
4397         {
4398           /* Calculate stride = size * (ubound + 1 - lbound).  */
4399           tmp = fold_build2_loc (input_location, MINUS_EXPR,
4400                                  gfc_array_index_type,
4401                                  gfc_index_one_node, lbound);
4402           tmp = fold_build2_loc (input_location, PLUS_EXPR,
4403                                  gfc_array_index_type, ubound, tmp);
4404           tmp = fold_build2_loc (input_location, MULT_EXPR,
4405                                  gfc_array_index_type, size, tmp);
4406           if (stride)
4407             gfc_add_modify (pblock, stride, tmp);
4408           else
4409             stride = gfc_evaluate_now (tmp, pblock);
4410
4411           /* Make sure that negative size arrays are translated
4412              to being zero size.  */
4413           tmp = fold_build2_loc (input_location, GE_EXPR, boolean_type_node,
4414                                  stride, gfc_index_zero_node);
4415           tmp = fold_build3_loc (input_location, COND_EXPR,
4416                                  gfc_array_index_type, tmp,
4417                                  stride, gfc_index_zero_node);
4418           gfc_add_modify (pblock, stride, tmp);
4419         }
4420
4421       size = stride;
4422     }
4423
4424   gfc_trans_vla_type_sizes (sym, pblock);
4425
4426   *poffset = offset;
4427   return size;
4428 }
4429
4430
4431 /* Generate code to initialize/allocate an array variable.  */
4432
4433 void
4434 gfc_trans_auto_array_allocation (tree decl, gfc_symbol * sym,
4435                                  gfc_wrapped_block * block)
4436 {
4437   stmtblock_t init;
4438   tree type;
4439   tree tmp;
4440   tree size;
4441   tree offset;
4442   bool onstack;
4443
4444   gcc_assert (!(sym->attr.pointer || sym->attr.allocatable));
4445
4446   /* Do nothing for USEd variables.  */
4447   if (sym->attr.use_assoc)
4448     return;
4449
4450   type = TREE_TYPE (decl);
4451   gcc_assert (GFC_ARRAY_TYPE_P (type));
4452   onstack = TREE_CODE (type) != POINTER_TYPE;
4453
4454   gfc_start_block (&init);
4455
4456   /* Evaluate character string length.  */
4457   if (sym->ts.type == BT_CHARACTER
4458       && onstack && !INTEGER_CST_P (sym->ts.u.cl->backend_decl))
4459     {
4460       gfc_conv_string_length (sym->ts.u.cl, NULL, &init);
4461
4462       gfc_trans_vla_type_sizes (sym, &init);
4463
4464       /* Emit a DECL_EXPR for this variable, which will cause the
4465          gimplifier to allocate storage, and all that good stuff.  */
4466       tmp = fold_build1_loc (input_location, DECL_EXPR, TREE_TYPE (decl), decl);
4467       gfc_add_expr_to_block (&init, tmp);
4468     }
4469
4470   if (onstack)
4471     {
4472       gfc_add_init_cleanup (block, gfc_finish_block (&init), NULL_TREE);
4473       return;
4474     }
4475
4476   type = TREE_TYPE (type);
4477
4478   gcc_assert (!sym->attr.use_assoc);
4479   gcc_assert (!TREE_STATIC (decl));
4480   gcc_assert (!sym->module);
4481
4482   if (sym->ts.type == BT_CHARACTER
4483       && !INTEGER_CST_P (sym->ts.u.cl->backend_decl))
4484     gfc_conv_string_length (sym->ts.u.cl, NULL, &init);
4485
4486   size = gfc_trans_array_bounds (type, sym, &offset, &init);
4487
4488   /* Don't actually allocate space for Cray Pointees.  */
4489   if (sym->attr.cray_pointee)
4490     {
4491       if (TREE_CODE (GFC_TYPE_ARRAY_OFFSET (type)) == VAR_DECL)
4492         gfc_add_modify (&init, GFC_TYPE_ARRAY_OFFSET (type), offset);
4493
4494       gfc_add_init_cleanup (block, gfc_finish_block (&init), NULL_TREE);
4495       return;
4496     }
4497
4498   /* The size is the number of elements in the array, so multiply by the
4499      size of an element to get the total size.  */
4500   tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type));
4501   size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
4502                           size, fold_convert (gfc_array_index_type, tmp));
4503
4504   /* Allocate memory to hold the data.  */
4505   tmp = gfc_call_malloc (&init, TREE_TYPE (decl), size);
4506   gfc_add_modify (&init, decl, tmp);
4507
4508   /* Set offset of the array.  */
4509   if (TREE_CODE (GFC_TYPE_ARRAY_OFFSET (type)) == VAR_DECL)
4510     gfc_add_modify (&init, GFC_TYPE_ARRAY_OFFSET (type), offset);
4511
4512   /* Automatic arrays should not have initializers.  */
4513   gcc_assert (!sym->value);
4514
4515   /* Free the temporary.  */
4516   tmp = gfc_call_free (convert (pvoid_type_node, decl));
4517
4518   gfc_add_init_cleanup (block, gfc_finish_block (&init), tmp);
4519 }
4520
4521
4522 /* Generate entry and exit code for g77 calling convention arrays.  */
4523
4524 void
4525 gfc_trans_g77_array (gfc_symbol * sym, gfc_wrapped_block * block)
4526 {
4527   tree parm;
4528   tree type;
4529   locus loc;
4530   tree offset;
4531   tree tmp;
4532   tree stmt;  
4533   stmtblock_t init;
4534
4535   gfc_get_backend_locus (&loc);
4536   gfc_set_backend_locus (&sym->declared_at);
4537
4538   /* Descriptor type.  */
4539   parm = sym->backend_decl;
4540   type = TREE_TYPE (parm);
4541   gcc_assert (GFC_ARRAY_TYPE_P (type));
4542
4543   gfc_start_block (&init);
4544
4545   if (sym->ts.type == BT_CHARACTER
4546       && TREE_CODE (sym->ts.u.cl->backend_decl) == VAR_DECL)
4547     gfc_conv_string_length (sym->ts.u.cl, NULL, &init);
4548
4549   /* Evaluate the bounds of the array.  */
4550   gfc_trans_array_bounds (type, sym, &offset, &init);
4551
4552   /* Set the offset.  */
4553   if (TREE_CODE (GFC_TYPE_ARRAY_OFFSET (type)) == VAR_DECL)
4554     gfc_add_modify (&init, GFC_TYPE_ARRAY_OFFSET (type), offset);
4555
4556   /* Set the pointer itself if we aren't using the parameter directly.  */
4557   if (TREE_CODE (parm) != PARM_DECL)
4558     {
4559       tmp = convert (TREE_TYPE (parm), GFC_DECL_SAVED_DESCRIPTOR (parm));
4560       gfc_add_modify (&init, parm, tmp);
4561     }
4562   stmt = gfc_finish_block (&init);
4563
4564   gfc_set_backend_locus (&loc);
4565
4566   /* Add the initialization code to the start of the function.  */
4567
4568   if (sym->attr.optional || sym->attr.not_always_present)
4569     {
4570       tmp = gfc_conv_expr_present (sym);
4571       stmt = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt (input_location));
4572     }
4573   
4574   gfc_add_init_cleanup (block, stmt, NULL_TREE);
4575 }
4576
4577
4578 /* Modify the descriptor of an array parameter so that it has the
4579    correct lower bound.  Also move the upper bound accordingly.
4580    If the array is not packed, it will be copied into a temporary.
4581    For each dimension we set the new lower and upper bounds.  Then we copy the
4582    stride and calculate the offset for this dimension.  We also work out
4583    what the stride of a packed array would be, and see it the two match.
4584    If the array need repacking, we set the stride to the values we just
4585    calculated, recalculate the offset and copy the array data.
4586    Code is also added to copy the data back at the end of the function.
4587    */
4588
4589 void
4590 gfc_trans_dummy_array_bias (gfc_symbol * sym, tree tmpdesc,
4591                             gfc_wrapped_block * block)
4592 {
4593   tree size;
4594   tree type;
4595   tree offset;
4596   locus loc;
4597   stmtblock_t init;
4598   tree stmtInit, stmtCleanup;
4599   tree lbound;
4600   tree ubound;
4601   tree dubound;
4602   tree dlbound;
4603   tree dumdesc;
4604   tree tmp;
4605   tree stride, stride2;
4606   tree stmt_packed;
4607   tree stmt_unpacked;
4608   tree partial;
4609   gfc_se se;
4610   int n;
4611   int checkparm;
4612   int no_repack;
4613   bool optional_arg;
4614
4615   /* Do nothing for pointer and allocatable arrays.  */
4616   if (sym->attr.pointer || sym->attr.allocatable)
4617     return;
4618
4619   if (sym->attr.dummy && gfc_is_nodesc_array (sym))
4620     {
4621       gfc_trans_g77_array (sym, block);
4622       return;
4623     }
4624
4625   gfc_get_backend_locus (&loc);
4626   gfc_set_backend_locus (&sym->declared_at);
4627
4628   /* Descriptor type.  */
4629   type = TREE_TYPE (tmpdesc);
4630   gcc_assert (GFC_ARRAY_TYPE_P (type));
4631   dumdesc = GFC_DECL_SAVED_DESCRIPTOR (tmpdesc);
4632   dumdesc = build_fold_indirect_ref_loc (input_location, dumdesc);
4633   gfc_start_block (&init);
4634
4635   if (sym->ts.type == BT_CHARACTER
4636       && TREE_CODE (sym->ts.u.cl->backend_decl) == VAR_DECL)
4637     gfc_conv_string_length (sym->ts.u.cl, NULL, &init);
4638
4639   checkparm = (sym->as->type == AS_EXPLICIT
4640                && (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS));
4641
4642   no_repack = !(GFC_DECL_PACKED_ARRAY (tmpdesc)
4643                 || GFC_DECL_PARTIAL_PACKED_ARRAY (tmpdesc));
4644
4645   if (GFC_DECL_PARTIAL_PACKED_ARRAY (tmpdesc))
4646     {
4647       /* For non-constant shape arrays we only check if the first dimension
4648          is contiguous.  Repacking higher dimensions wouldn't gain us
4649          anything as we still don't know the array stride.  */
4650       partial = gfc_create_var (boolean_type_node, "partial");
4651       TREE_USED (partial) = 1;
4652       tmp = gfc_conv_descriptor_stride_get (dumdesc, gfc_rank_cst[0]);
4653       tmp = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, tmp,
4654                              gfc_index_one_node);
4655       gfc_add_modify (&init, partial, tmp);
4656     }
4657   else
4658     partial = NULL_TREE;
4659
4660   /* The naming of stmt_unpacked and stmt_packed may be counter-intuitive
4661      here, however I think it does the right thing.  */
4662   if (no_repack)
4663     {
4664       /* Set the first stride.  */
4665       stride = gfc_conv_descriptor_stride_get (dumdesc, gfc_rank_cst[0]);
4666       stride = gfc_evaluate_now (stride, &init);
4667
4668       tmp = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
4669                              stride, gfc_index_zero_node);
4670       tmp = fold_build3_loc (input_location, COND_EXPR, gfc_array_index_type,
4671                              tmp, gfc_index_one_node, stride);
4672       stride = GFC_TYPE_ARRAY_STRIDE (type, 0);
4673       gfc_add_modify (&init, stride, tmp);
4674
4675       /* Allow the user to disable array repacking.  */
4676       stmt_unpacked = NULL_TREE;
4677     }
4678   else
4679     {
4680       gcc_assert (integer_onep (GFC_TYPE_ARRAY_STRIDE (type, 0)));
4681       /* A library call to repack the array if necessary.  */
4682       tmp = GFC_DECL_SAVED_DESCRIPTOR (tmpdesc);
4683       stmt_unpacked = build_call_expr_loc (input_location,
4684                                        gfor_fndecl_in_pack, 1, tmp);
4685
4686       stride = gfc_index_one_node;
4687
4688       if (gfc_option.warn_array_temp)
4689         gfc_warning ("Creating array temporary at %L", &loc);
4690     }
4691
4692   /* This is for the case where the array data is used directly without
4693      calling the repack function.  */
4694   if (no_repack || partial != NULL_TREE)
4695     stmt_packed = gfc_conv_descriptor_data_get (dumdesc);
4696   else
4697     stmt_packed = NULL_TREE;
4698
4699   /* Assign the data pointer.  */
4700   if (stmt_packed != NULL_TREE && stmt_unpacked != NULL_TREE)
4701     {
4702       /* Don't repack unknown shape arrays when the first stride is 1.  */
4703       tmp = fold_build3_loc (input_location, COND_EXPR, TREE_TYPE (stmt_packed),
4704                              partial, stmt_packed, stmt_unpacked);
4705     }
4706   else
4707     tmp = stmt_packed != NULL_TREE ? stmt_packed : stmt_unpacked;
4708   gfc_add_modify (&init, tmpdesc, fold_convert (type, tmp));
4709
4710   offset = gfc_index_zero_node;
4711   size = gfc_index_one_node;
4712
4713   /* Evaluate the bounds of the array.  */
4714   for (n = 0; n < sym->as->rank; n++)
4715     {
4716       if (checkparm || !sym->as->upper[n])
4717         {
4718           /* Get the bounds of the actual parameter.  */
4719           dubound = gfc_conv_descriptor_ubound_get (dumdesc, gfc_rank_cst[n]);
4720           dlbound = gfc_conv_descriptor_lbound_get (dumdesc, gfc_rank_cst[n]);
4721         }
4722       else
4723         {
4724           dubound = NULL_TREE;
4725           dlbound = NULL_TREE;
4726         }
4727
4728       lbound = GFC_TYPE_ARRAY_LBOUND (type, n);
4729       if (!INTEGER_CST_P (lbound))
4730         {
4731           gfc_init_se (&se, NULL);
4732           gfc_conv_expr_type (&se, sym->as->lower[n],
4733                               gfc_array_index_type);
4734           gfc_add_block_to_block (&init, &se.pre);
4735           gfc_add_modify (&init, lbound, se.expr);
4736         }
4737
4738       ubound = GFC_TYPE_ARRAY_UBOUND (type, n);
4739       /* Set the desired upper bound.  */
4740       if (sym->as->upper[n])
4741         {
4742           /* We know what we want the upper bound to be.  */
4743           if (!INTEGER_CST_P (ubound))
4744             {
4745               gfc_init_se (&se, NULL);
4746               gfc_conv_expr_type (&se, sym->as->upper[n],
4747                                   gfc_array_index_type);
4748               gfc_add_block_to_block (&init, &se.pre);
4749               gfc_add_modify (&init, ubound, se.expr);
4750             }
4751
4752           /* Check the sizes match.  */
4753           if (checkparm)
4754             {
4755               /* Check (ubound(a) - lbound(a) == ubound(b) - lbound(b)).  */
4756               char * msg;
4757               tree temp;
4758
4759               temp = fold_build2_loc (input_location, MINUS_EXPR,
4760                                       gfc_array_index_type, ubound, lbound);
4761               temp = fold_build2_loc (input_location, PLUS_EXPR,
4762                                       gfc_array_index_type,
4763                                       gfc_index_one_node, temp);
4764               stride2 = fold_build2_loc (input_location, MINUS_EXPR,
4765                                          gfc_array_index_type, dubound,
4766                                          dlbound);
4767               stride2 = fold_build2_loc (input_location, PLUS_EXPR,
4768                                          gfc_array_index_type,
4769                                          gfc_index_one_node, stride2);
4770               tmp = fold_build2_loc (input_location, NE_EXPR,
4771                                      gfc_array_index_type, temp, stride2);
4772               asprintf (&msg, "Dimension %d of array '%s' has extent "
4773                         "%%ld instead of %%ld", n+1, sym->name);
4774
4775               gfc_trans_runtime_check (true, false, tmp, &init, &loc, msg, 
4776                         fold_convert (long_integer_type_node, temp),
4777                         fold_convert (long_integer_type_node, stride2));
4778
4779               gfc_free (msg);
4780             }
4781         }
4782       else
4783         {
4784           /* For assumed shape arrays move the upper bound by the same amount
4785              as the lower bound.  */
4786           tmp = fold_build2_loc (input_location, MINUS_EXPR,
4787                                  gfc_array_index_type, dubound, dlbound);
4788           tmp = fold_build2_loc (input_location, PLUS_EXPR,
4789                                  gfc_array_index_type, tmp, lbound);
4790           gfc_add_modify (&init, ubound, tmp);
4791         }
4792       /* The offset of this dimension.  offset = offset - lbound * stride.  */
4793       tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
4794                              lbound, stride);
4795       offset = fold_build2_loc (input_location, MINUS_EXPR,
4796                                 gfc_array_index_type, offset, tmp);
4797
4798       /* The size of this dimension, and the stride of the next.  */
4799       if (n + 1 < sym->as->rank)
4800         {
4801           stride = GFC_TYPE_ARRAY_STRIDE (type, n + 1);
4802
4803           if (no_repack || partial != NULL_TREE)
4804             stmt_unpacked =
4805               gfc_conv_descriptor_stride_get (dumdesc, gfc_rank_cst[n+1]);
4806
4807           /* Figure out the stride if not a known constant.  */
4808           if (!INTEGER_CST_P (stride))
4809             {
4810               if (no_repack)
4811                 stmt_packed = NULL_TREE;
4812               else
4813                 {
4814                   /* Calculate stride = size * (ubound + 1 - lbound).  */
4815                   tmp = fold_build2_loc (input_location, MINUS_EXPR,
4816                                          gfc_array_index_type,
4817                                          gfc_index_one_node, lbound);
4818                   tmp = fold_build2_loc (input_location, PLUS_EXPR,
4819                                          gfc_array_index_type, ubound, tmp);
4820                   size = fold_build2_loc (input_location, MULT_EXPR,
4821                                           gfc_array_index_type, size, tmp);
4822                   stmt_packed = size;
4823                 }
4824
4825               /* Assign the stride.  */
4826               if (stmt_packed != NULL_TREE && stmt_unpacked != NULL_TREE)
4827                 tmp = fold_build3_loc (input_location, COND_EXPR,
4828                                        gfc_array_index_type, partial,
4829                                        stmt_unpacked, stmt_packed);
4830               else
4831                 tmp = (stmt_packed != NULL_TREE) ? stmt_packed : stmt_unpacked;
4832               gfc_add_modify (&init, stride, tmp);
4833             }
4834         }
4835       else
4836         {
4837           stride = GFC_TYPE_ARRAY_SIZE (type);
4838
4839           if (stride && !INTEGER_CST_P (stride))
4840             {
4841               /* Calculate size = stride * (ubound + 1 - lbound).  */
4842               tmp = fold_build2_loc (input_location, MINUS_EXPR,
4843                                      gfc_array_index_type,
4844                                      gfc_index_one_node, lbound);
4845               tmp = fold_build2_loc (input_location, PLUS_EXPR,
4846                                      gfc_array_index_type,
4847                                      ubound, tmp);
4848               tmp = fold_build2_loc (input_location, MULT_EXPR,
4849                                      gfc_array_index_type,
4850                                      GFC_TYPE_ARRAY_STRIDE (type, n), tmp);
4851               gfc_add_modify (&init, stride, tmp);
4852             }
4853         }
4854     }
4855
4856   /* Set the offset.  */
4857   if (TREE_CODE (GFC_TYPE_ARRAY_OFFSET (type)) == VAR_DECL)
4858     gfc_add_modify (&init, GFC_TYPE_ARRAY_OFFSET (type), offset);
4859
4860   gfc_trans_vla_type_sizes (sym, &init);
4861
4862   stmtInit = gfc_finish_block (&init);
4863
4864   /* Only do the entry/initialization code if the arg is present.  */
4865   dumdesc = GFC_DECL_SAVED_DESCRIPTOR (tmpdesc);
4866   optional_arg = (sym->attr.optional
4867                   || (sym->ns->proc_name->attr.entry_master
4868                       && sym->attr.dummy));
4869   if (optional_arg)
4870     {
4871       tmp = gfc_conv_expr_present (sym);
4872       stmtInit = build3_v (COND_EXPR, tmp, stmtInit,
4873                            build_empty_stmt (input_location));
4874     }
4875
4876   /* Cleanup code.  */
4877   if (no_repack)
4878     stmtCleanup = NULL_TREE;
4879   else
4880     {
4881       stmtblock_t cleanup;
4882       gfc_start_block (&cleanup);
4883
4884       if (sym->attr.intent != INTENT_IN)
4885         {
4886           /* Copy the data back.  */
4887           tmp = build_call_expr_loc (input_location,
4888                                  gfor_fndecl_in_unpack, 2, dumdesc, tmpdesc);
4889           gfc_add_expr_to_block (&cleanup, tmp);
4890         }
4891
4892       /* Free the temporary.  */
4893       tmp = gfc_call_free (tmpdesc);
4894       gfc_add_expr_to_block (&cleanup, tmp);
4895
4896       stmtCleanup = gfc_finish_block (&cleanup);
4897         
4898       /* Only do the cleanup if the array was repacked.  */
4899       tmp = build_fold_indirect_ref_loc (input_location, dumdesc);
4900       tmp = gfc_conv_descriptor_data_get (tmp);
4901       tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
4902                              tmp, tmpdesc);
4903       stmtCleanup = build3_v (COND_EXPR, tmp, stmtCleanup,
4904                               build_empty_stmt (input_location));
4905
4906       if (optional_arg)
4907         {
4908           tmp = gfc_conv_expr_present (sym);
4909           stmtCleanup = build3_v (COND_EXPR, tmp, stmtCleanup,
4910                                   build_empty_stmt (input_location));
4911         }
4912     }
4913
4914   /* We don't need to free any memory allocated by internal_pack as it will
4915      be freed at the end of the function by pop_context.  */
4916   gfc_add_init_cleanup (block, stmtInit, stmtCleanup);
4917 }
4918
4919
4920 /* Calculate the overall offset, including subreferences.  */
4921 static void
4922 gfc_get_dataptr_offset (stmtblock_t *block, tree parm, tree desc, tree offset,
4923                         bool subref, gfc_expr *expr)
4924 {
4925   tree tmp;
4926   tree field;
4927   tree stride;
4928   tree index;
4929   gfc_ref *ref;
4930   gfc_se start;
4931   int n;
4932
4933   /* If offset is NULL and this is not a subreferenced array, there is
4934      nothing to do.  */
4935   if (offset == NULL_TREE)
4936     {
4937       if (subref)
4938         offset = gfc_index_zero_node;
4939       else
4940         return;
4941     }
4942
4943   tmp = gfc_conv_array_data (desc);
4944   tmp = build_fold_indirect_ref_loc (input_location,
4945                                  tmp);
4946   tmp = gfc_build_array_ref (tmp, offset, NULL);
4947
4948   /* Offset the data pointer for pointer assignments from arrays with
4949      subreferences; e.g. my_integer => my_type(:)%integer_component.  */
4950   if (subref)
4951     {
4952       /* Go past the array reference.  */
4953       for (ref = expr->ref; ref; ref = ref->next)
4954         if (ref->type == REF_ARRAY &&
4955               ref->u.ar.type != AR_ELEMENT)
4956           {
4957             ref = ref->next;
4958             break;
4959           }
4960
4961       /* Calculate the offset for each subsequent subreference.  */
4962       for (; ref; ref = ref->next)
4963         {
4964           switch (ref->type)
4965             {
4966             case REF_COMPONENT:
4967               field = ref->u.c.component->backend_decl;
4968               gcc_assert (field && TREE_CODE (field) == FIELD_DECL);
4969               tmp = fold_build3_loc (input_location, COMPONENT_REF,
4970                                      TREE_TYPE (field),
4971                                      tmp, field, NULL_TREE);
4972               break;
4973
4974             case REF_SUBSTRING:
4975               gcc_assert (TREE_CODE (TREE_TYPE (tmp)) == ARRAY_TYPE);
4976               gfc_init_se (&start, NULL);
4977               gfc_conv_expr_type (&start, ref->u.ss.start, gfc_charlen_type_node);
4978               gfc_add_block_to_block (block, &start.pre);
4979               tmp = gfc_build_array_ref (tmp, start.expr, NULL);
4980               break;
4981
4982             case REF_ARRAY:
4983               gcc_assert (TREE_CODE (TREE_TYPE (tmp)) == ARRAY_TYPE
4984                             && ref->u.ar.type == AR_ELEMENT);
4985
4986               /* TODO - Add bounds checking.  */
4987               stride = gfc_index_one_node;
4988               index = gfc_index_zero_node;
4989               for (n = 0; n < ref->u.ar.dimen; n++)
4990                 {
4991                   tree itmp;
4992                   tree jtmp;
4993
4994                   /* Update the index.  */
4995                   gfc_init_se (&start, NULL);
4996                   gfc_conv_expr_type (&start, ref->u.ar.start[n], gfc_array_index_type);
4997                   itmp = gfc_evaluate_now (start.expr, block);
4998                   gfc_init_se (&start, NULL);
4999                   gfc_conv_expr_type (&start, ref->u.ar.as->lower[n], gfc_array_index_type);
5000                   jtmp = gfc_evaluate_now (start.expr, block);
5001                   itmp = fold_build2_loc (input_location, MINUS_EXPR,
5002                                           gfc_array_index_type, itmp, jtmp);
5003                   itmp = fold_build2_loc (input_location, MULT_EXPR,
5004                                           gfc_array_index_type, itmp, stride);
5005                   index = fold_build2_loc (input_location, PLUS_EXPR,
5006                                           gfc_array_index_type, itmp, index);
5007                   index = gfc_evaluate_now (index, block);
5008
5009                   /* Update the stride.  */
5010                   gfc_init_se (&start, NULL);
5011                   gfc_conv_expr_type (&start, ref->u.ar.as->upper[n], gfc_array_index_type);
5012                   itmp =  fold_build2_loc (input_location, MINUS_EXPR,
5013                                            gfc_array_index_type, start.expr,
5014                                            jtmp);
5015                   itmp =  fold_build2_loc (input_location, PLUS_EXPR,
5016                                            gfc_array_index_type,
5017                                            gfc_index_one_node, itmp);
5018                   stride =  fold_build2_loc (input_location, MULT_EXPR,
5019                                              gfc_array_index_type, stride, itmp);
5020                   stride = gfc_evaluate_now (stride, block);
5021                 }
5022
5023               /* Apply the index to obtain the array element.  */
5024               tmp = gfc_build_array_ref (tmp, index, NULL);
5025               break;
5026
5027             default:
5028               gcc_unreachable ();
5029               break;
5030             }
5031         }
5032     }
5033
5034   /* Set the target data pointer.  */
5035   offset = gfc_build_addr_expr (gfc_array_dataptr_type (desc), tmp);
5036   gfc_conv_descriptor_data_set (block, parm, offset);
5037 }
5038
5039
5040 /* gfc_conv_expr_descriptor needs the string length an expression
5041    so that the size of the temporary can be obtained.  This is done
5042    by adding up the string lengths of all the elements in the
5043    expression.  Function with non-constant expressions have their
5044    string lengths mapped onto the actual arguments using the
5045    interface mapping machinery in trans-expr.c.  */
5046 static void
5047 get_array_charlen (gfc_expr *expr, gfc_se *se)
5048 {
5049   gfc_interface_mapping mapping;
5050   gfc_formal_arglist *formal;
5051   gfc_actual_arglist *arg;
5052   gfc_se tse;
5053
5054   if (expr->ts.u.cl->length
5055         && gfc_is_constant_expr (expr->ts.u.cl->length))
5056     {
5057       if (!expr->ts.u.cl->backend_decl)
5058         gfc_conv_string_length (expr->ts.u.cl, expr, &se->pre);
5059       return;
5060     }
5061
5062   switch (expr->expr_type)
5063     {
5064     case EXPR_OP:
5065       get_array_charlen (expr->value.op.op1, se);
5066
5067       /* For parentheses the expression ts.u.cl is identical.  */
5068       if (expr->value.op.op == INTRINSIC_PARENTHESES)
5069         return;
5070
5071      expr->ts.u.cl->backend_decl =
5072                 gfc_create_var (gfc_charlen_type_node, "sln");
5073
5074       if (expr->value.op.op2)
5075         {
5076           get_array_charlen (expr->value.op.op2, se);
5077
5078           gcc_assert (expr->value.op.op == INTRINSIC_CONCAT);
5079
5080           /* Add the string lengths and assign them to the expression
5081              string length backend declaration.  */
5082           gfc_add_modify (&se->pre, expr->ts.u.cl->backend_decl,
5083                           fold_build2_loc (input_location, PLUS_EXPR,
5084                                 gfc_charlen_type_node,
5085                                 expr->value.op.op1->ts.u.cl->backend_decl,
5086                                 expr->value.op.op2->ts.u.cl->backend_decl));
5087         }
5088       else
5089         gfc_add_modify (&se->pre, expr->ts.u.cl->backend_decl,
5090                         expr->value.op.op1->ts.u.cl->backend_decl);
5091       break;
5092
5093     case EXPR_FUNCTION:
5094       if (expr->value.function.esym == NULL
5095             || expr->ts.u.cl->length->expr_type == EXPR_CONSTANT)
5096         {
5097           gfc_conv_string_length (expr->ts.u.cl, expr, &se->pre);
5098           break;
5099         }
5100
5101       /* Map expressions involving the dummy arguments onto the actual
5102          argument expressions.  */
5103       gfc_init_interface_mapping (&mapping);
5104       formal = expr->symtree->n.sym->formal;
5105       arg = expr->value.function.actual;
5106
5107       /* Set se = NULL in the calls to the interface mapping, to suppress any
5108          backend stuff.  */
5109       for (; arg != NULL; arg = arg->next, formal = formal ? formal->next : NULL)
5110         {
5111           if (!arg->expr)
5112             continue;
5113           if (formal->sym)
5114           gfc_add_interface_mapping (&mapping, formal->sym, NULL, arg->expr);
5115         }
5116
5117       gfc_init_se (&tse, NULL);
5118
5119       /* Build the expression for the character length and convert it.  */
5120       gfc_apply_interface_mapping (&mapping, &tse, expr->ts.u.cl->length);
5121
5122       gfc_add_block_to_block (&se->pre, &tse.pre);
5123       gfc_add_block_to_block (&se->post, &tse.post);
5124       tse.expr = fold_convert (gfc_charlen_type_node, tse.expr);
5125       tse.expr = fold_build2_loc (input_location, MAX_EXPR,
5126                                   gfc_charlen_type_node, tse.expr,
5127                                   build_int_cst (gfc_charlen_type_node, 0));
5128       expr->ts.u.cl->backend_decl = tse.expr;
5129       gfc_free_interface_mapping (&mapping);
5130       break;
5131
5132     default:
5133       gfc_conv_string_length (expr->ts.u.cl, expr, &se->pre);
5134       break;
5135     }
5136 }
5137
5138
5139 /* Convert an array for passing as an actual argument.  Expressions and
5140    vector subscripts are evaluated and stored in a temporary, which is then
5141    passed.  For whole arrays the descriptor is passed.  For array sections
5142    a modified copy of the descriptor is passed, but using the original data.
5143
5144    This function is also used for array pointer assignments, and there
5145    are three cases:
5146
5147      - se->want_pointer && !se->direct_byref
5148          EXPR is an actual argument.  On exit, se->expr contains a
5149          pointer to the array descriptor.
5150
5151      - !se->want_pointer && !se->direct_byref
5152          EXPR is an actual argument to an intrinsic function or the
5153          left-hand side of a pointer assignment.  On exit, se->expr
5154          contains the descriptor for EXPR.
5155
5156      - !se->want_pointer && se->direct_byref
5157          EXPR is the right-hand side of a pointer assignment and
5158          se->expr is the descriptor for the previously-evaluated
5159          left-hand side.  The function creates an assignment from
5160          EXPR to se->expr.  
5161
5162
5163    The se->force_tmp flag disables the non-copying descriptor optimization
5164    that is used for transpose. It may be used in cases where there is an
5165    alias between the transpose argument and another argument in the same
5166    function call.  */
5167
5168 void
5169 gfc_conv_expr_descriptor (gfc_se * se, gfc_expr * expr, gfc_ss * ss)
5170 {
5171   gfc_loopinfo loop;
5172   gfc_ss_info *info;
5173   int need_tmp;
5174   int n;
5175   tree tmp;
5176   tree desc;
5177   stmtblock_t block;
5178   tree start;
5179   tree offset;
5180   int full;
5181   bool subref_array_target = false;
5182   gfc_expr *arg;
5183
5184   gcc_assert (ss != NULL);
5185   gcc_assert (ss != gfc_ss_terminator);
5186
5187   /* Special case things we know we can pass easily.  */
5188   switch (expr->expr_type)
5189     {
5190     case EXPR_VARIABLE:
5191       /* If we have a linear array section, we can pass it directly.
5192          Otherwise we need to copy it into a temporary.  */
5193
5194       gcc_assert (ss->type == GFC_SS_SECTION);
5195       gcc_assert (ss->expr == expr);
5196       info = &ss->data.info;
5197
5198       /* Get the descriptor for the array.  */
5199       gfc_conv_ss_descriptor (&se->pre, ss, 0);
5200       desc = info->descriptor;
5201
5202       subref_array_target = se->direct_byref && is_subref_array (expr);
5203       need_tmp = gfc_ref_needs_temporary_p (expr->ref)
5204                         && !subref_array_target;
5205
5206       if (se->force_tmp)
5207         need_tmp = 1;
5208
5209       if (need_tmp)
5210         full = 0;
5211       else if (GFC_ARRAY_TYPE_P (TREE_TYPE (desc)))
5212         {
5213           /* Create a new descriptor if the array doesn't have one.  */
5214           full = 0;
5215         }
5216       else if (info->ref->u.ar.type == AR_FULL)
5217         full = 1;
5218       else if (se->direct_byref)
5219         full = 0;
5220       else
5221         full = gfc_full_array_ref_p (info->ref, NULL);
5222
5223       if (full)
5224         for (n = 0; n < info->dimen; n++)
5225           if (info->dim[n] != n)
5226             {
5227               full = 0;
5228               break;
5229             }
5230
5231       if (full)
5232         {
5233           if (se->direct_byref && !se->byref_noassign)
5234             {
5235               /* Copy the descriptor for pointer assignments.  */
5236               gfc_add_modify (&se->pre, se->expr, desc);
5237
5238               /* Add any offsets from subreferences.  */
5239               gfc_get_dataptr_offset (&se->pre, se->expr, desc, NULL_TREE,
5240                                       subref_array_target, expr);
5241             }
5242           else if (se->want_pointer)
5243             {
5244               /* We pass full arrays directly.  This means that pointers and
5245                  allocatable arrays should also work.  */
5246               se->expr = gfc_build_addr_expr (NULL_TREE, desc);
5247             }
5248           else
5249             {
5250               se->expr = desc;
5251             }
5252
5253           if (expr->ts.type == BT_CHARACTER)
5254             se->string_length = gfc_get_expr_charlen (expr);
5255
5256           return;
5257         }
5258       break;
5259       
5260     case EXPR_FUNCTION:
5261
5262       /* We don't need to copy data in some cases.  */
5263       arg = gfc_get_noncopying_intrinsic_argument (expr);
5264       if (arg)
5265         {
5266           /* This is a call to transpose...  */
5267           gcc_assert (expr->value.function.isym->id == GFC_ISYM_TRANSPOSE);
5268           /* ... which has already been handled by the scalarizer, so
5269              that we just need to get its argument's descriptor.  */
5270           gfc_conv_expr_descriptor (se, expr->value.function.actual->expr, ss);
5271           return;
5272         }
5273
5274       /* A transformational function return value will be a temporary
5275          array descriptor.  We still need to go through the scalarizer
5276          to create the descriptor.  Elemental functions ar handled as
5277          arbitrary expressions, i.e. copy to a temporary.  */
5278
5279       if (se->direct_byref)
5280         {
5281           gcc_assert (ss->type == GFC_SS_FUNCTION && ss->expr == expr);
5282
5283           /* For pointer assignments pass the descriptor directly.  */
5284           if (se->ss == NULL)
5285             se->ss = ss;
5286           else
5287             gcc_assert (se->ss == ss);
5288           se->expr = gfc_build_addr_expr (NULL_TREE, se->expr);
5289           gfc_conv_expr (se, expr);
5290           return;
5291         }
5292
5293       if (ss->expr != expr || ss->type != GFC_SS_FUNCTION)
5294         {
5295           if (ss->expr != expr)
5296             /* Elemental function.  */
5297             gcc_assert ((expr->value.function.esym != NULL
5298                          && expr->value.function.esym->attr.elemental)
5299                         || (expr->value.function.isym != NULL
5300                             && expr->value.function.isym->elemental));
5301           else
5302             gcc_assert (ss->type == GFC_SS_INTRINSIC);
5303
5304           need_tmp = 1;
5305           if (expr->ts.type == BT_CHARACTER
5306                 && expr->ts.u.cl->length->expr_type != EXPR_CONSTANT)
5307             get_array_charlen (expr, se);
5308
5309           info = NULL;
5310         }
5311       else
5312         {
5313           /* Transformational function.  */
5314           info = &ss->data.info;
5315           need_tmp = 0;
5316         }
5317       break;
5318
5319     case EXPR_ARRAY:
5320       /* Constant array constructors don't need a temporary.  */
5321       if (ss->type == GFC_SS_CONSTRUCTOR
5322           && expr->ts.type != BT_CHARACTER
5323           && gfc_constant_array_constructor_p (expr->value.constructor))
5324         {
5325           need_tmp = 0;
5326           info = &ss->data.info;
5327         }
5328       else
5329         {
5330           need_tmp = 1;
5331           info = NULL;
5332         }
5333       break;
5334
5335     default:
5336       /* Something complicated.  Copy it into a temporary.  */
5337       need_tmp = 1;
5338       info = NULL;
5339       break;
5340     }
5341
5342   /* If we are creating a temporary, we don't need to bother about aliases
5343      anymore.  */
5344   if (need_tmp)
5345     se->force_tmp = 0;
5346
5347   gfc_init_loopinfo (&loop);
5348
5349   /* Associate the SS with the loop.  */
5350   gfc_add_ss_to_loop (&loop, ss);
5351
5352   /* Tell the scalarizer not to bother creating loop variables, etc.  */
5353   if (!need_tmp)
5354     loop.array_parameter = 1;
5355   else
5356     /* The right-hand side of a pointer assignment mustn't use a temporary.  */
5357     gcc_assert (!se->direct_byref);
5358
5359   /* Setup the scalarizing loops and bounds.  */
5360   gfc_conv_ss_startstride (&loop);
5361
5362   if (need_tmp)
5363     {
5364       /* Tell the scalarizer to make a temporary.  */
5365       loop.temp_ss = gfc_get_ss ();
5366       loop.temp_ss->type = GFC_SS_TEMP;
5367       loop.temp_ss->next = gfc_ss_terminator;
5368
5369       if (expr->ts.type == BT_CHARACTER
5370             && !expr->ts.u.cl->backend_decl)
5371         get_array_charlen (expr, se);
5372
5373       loop.temp_ss->data.temp.type = gfc_typenode_for_spec (&expr->ts);
5374
5375       if (expr->ts.type == BT_CHARACTER)
5376         loop.temp_ss->string_length = expr->ts.u.cl->backend_decl;
5377       else
5378         loop.temp_ss->string_length = NULL;
5379
5380       se->string_length = loop.temp_ss->string_length;
5381       loop.temp_ss->data.temp.dimen = loop.dimen;
5382       gfc_add_ss_to_loop (&loop, loop.temp_ss);
5383     }
5384
5385   gfc_conv_loop_setup (&loop, & expr->where);
5386
5387   if (need_tmp)
5388     {
5389       /* Copy into a temporary and pass that.  We don't need to copy the data
5390          back because expressions and vector subscripts must be INTENT_IN.  */
5391       /* TODO: Optimize passing function return values.  */
5392       gfc_se lse;
5393       gfc_se rse;
5394
5395       /* Start the copying loops.  */
5396       gfc_mark_ss_chain_used (loop.temp_ss, 1);
5397       gfc_mark_ss_chain_used (ss, 1);
5398       gfc_start_scalarized_body (&loop, &block);
5399
5400       /* Copy each data element.  */
5401       gfc_init_se (&lse, NULL);
5402       gfc_copy_loopinfo_to_se (&lse, &loop);
5403       gfc_init_se (&rse, NULL);
5404       gfc_copy_loopinfo_to_se (&rse, &loop);
5405
5406       lse.ss = loop.temp_ss;
5407       rse.ss = ss;
5408
5409       gfc_conv_scalarized_array_ref (&lse, NULL);
5410       if (expr->ts.type == BT_CHARACTER)
5411         {
5412           gfc_conv_expr (&rse, expr);
5413           if (POINTER_TYPE_P (TREE_TYPE (rse.expr)))
5414             rse.expr = build_fold_indirect_ref_loc (input_location,
5415                                                 rse.expr);
5416         }
5417       else
5418         gfc_conv_expr_val (&rse, expr);
5419
5420       gfc_add_block_to_block (&block, &rse.pre);
5421       gfc_add_block_to_block (&block, &lse.pre);
5422
5423       lse.string_length = rse.string_length;
5424       tmp = gfc_trans_scalar_assign (&lse, &rse, expr->ts, true,
5425                                      expr->expr_type == EXPR_VARIABLE, true);
5426       gfc_add_expr_to_block (&block, tmp);
5427
5428       /* Finish the copying loops.  */
5429       gfc_trans_scalarizing_loops (&loop, &block);
5430
5431       desc = loop.temp_ss->data.info.descriptor;
5432     }
5433   else if (expr->expr_type == EXPR_FUNCTION)
5434     {
5435       desc = info->descriptor;
5436       se->string_length = ss->string_length;
5437     }
5438   else
5439     {
5440       /* We pass sections without copying to a temporary.  Make a new
5441          descriptor and point it at the section we want.  The loop variable
5442          limits will be the limits of the section.
5443          A function may decide to repack the array to speed up access, but
5444          we're not bothered about that here.  */
5445       int dim, ndim;
5446       tree parm;
5447       tree parmtype;
5448       tree stride;
5449       tree from;
5450       tree to;
5451       tree base;
5452
5453       /* Set the string_length for a character array.  */
5454       if (expr->ts.type == BT_CHARACTER)
5455         se->string_length =  gfc_get_expr_charlen (expr);
5456
5457       desc = info->descriptor;
5458       if (se->direct_byref && !se->byref_noassign)
5459         {
5460           /* For pointer assignments we fill in the destination.  */
5461           parm = se->expr;
5462           parmtype = TREE_TYPE (parm);
5463         }
5464       else
5465         {
5466           /* Otherwise make a new one.  */
5467           parmtype = gfc_get_element_type (TREE_TYPE (desc));
5468           parmtype = gfc_get_array_type_bounds (parmtype, loop.dimen, 0,
5469                                                 loop.from, loop.to, 0,
5470                                                 GFC_ARRAY_UNKNOWN, false);
5471           parm = gfc_create_var (parmtype, "parm");
5472         }
5473
5474       offset = gfc_index_zero_node;
5475
5476       /* The following can be somewhat confusing.  We have two
5477          descriptors, a new one and the original array.
5478          {parm, parmtype, dim} refer to the new one.
5479          {desc, type, n, loop} refer to the original, which maybe
5480          a descriptorless array.
5481          The bounds of the scalarization are the bounds of the section.
5482          We don't have to worry about numeric overflows when calculating
5483          the offsets because all elements are within the array data.  */
5484
5485       /* Set the dtype.  */
5486       tmp = gfc_conv_descriptor_dtype (parm);
5487       gfc_add_modify (&loop.pre, tmp, gfc_get_dtype (parmtype));
5488
5489       /* Set offset for assignments to pointer only to zero if it is not
5490          the full array.  */
5491       if (se->direct_byref
5492           && info->ref && info->ref->u.ar.type != AR_FULL)
5493         base = gfc_index_zero_node;
5494       else if (GFC_ARRAY_TYPE_P (TREE_TYPE (desc)))
5495         base = gfc_evaluate_now (gfc_conv_array_offset (desc), &loop.pre);
5496       else
5497         base = NULL_TREE;
5498
5499       ndim = info->ref ? info->ref->u.ar.dimen : info->dimen;
5500       for (n = 0; n < ndim; n++)
5501         {
5502           stride = gfc_conv_array_stride (desc, n);
5503
5504           /* Work out the offset.  */
5505           if (info->ref
5506               && info->ref->u.ar.dimen_type[n] == DIMEN_ELEMENT)
5507             {
5508               gcc_assert (info->subscript[n]
5509                       && info->subscript[n]->type == GFC_SS_SCALAR);
5510               start = info->subscript[n]->data.scalar.expr;
5511             }
5512           else
5513             {
5514               /* Evaluate and remember the start of the section.  */
5515               start = info->start[n];
5516               stride = gfc_evaluate_now (stride, &loop.pre);
5517             }
5518
5519           tmp = gfc_conv_array_lbound (desc, n);
5520           tmp = fold_build2_loc (input_location, MINUS_EXPR, TREE_TYPE (tmp),
5521                                  start, tmp);
5522           tmp = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (tmp),
5523                                  tmp, stride);
5524           offset = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (tmp),
5525                                     offset, tmp);
5526
5527           if (info->ref
5528               && info->ref->u.ar.dimen_type[n] == DIMEN_ELEMENT)
5529             {
5530               /* For elemental dimensions, we only need the offset.  */
5531               continue;
5532             }
5533
5534           /* Vector subscripts need copying and are handled elsewhere.  */
5535           if (info->ref)
5536             gcc_assert (info->ref->u.ar.dimen_type[n] == DIMEN_RANGE);
5537  
5538           /* look for the corresponding scalarizer dimension: dim.  */
5539           for (dim = 0; dim < ndim; dim++)
5540             if (info->dim[dim] == n)
5541               break;
5542
5543           /* loop exited early: the DIM being looked for has been found.  */
5544           gcc_assert (dim < ndim);
5545
5546           /* Set the new lower bound.  */
5547           from = loop.from[dim];
5548           to = loop.to[dim];
5549
5550           /* If we have an array section or are assigning make sure that
5551              the lower bound is 1.  References to the full
5552              array should otherwise keep the original bounds.  */
5553           if ((!info->ref
5554                   || info->ref->u.ar.type != AR_FULL)
5555               && !integer_onep (from))
5556             {
5557               tmp = fold_build2_loc (input_location, MINUS_EXPR,
5558                                      gfc_array_index_type, gfc_index_one_node,
5559                                      from);
5560               to = fold_build2_loc (input_location, PLUS_EXPR,
5561                                     gfc_array_index_type, to, tmp);
5562               from = gfc_index_one_node;
5563             }
5564           gfc_conv_descriptor_lbound_set (&loop.pre, parm,
5565                                           gfc_rank_cst[dim], from);
5566
5567           /* Set the new upper bound.  */
5568           gfc_conv_descriptor_ubound_set (&loop.pre, parm,
5569                                           gfc_rank_cst[dim], to);
5570
5571           /* Multiply the stride by the section stride to get the
5572              total stride.  */
5573           stride = fold_build2_loc (input_location, MULT_EXPR,
5574                                     gfc_array_index_type,
5575                                     stride, info->stride[n]);
5576
5577           if (se->direct_byref
5578               && info->ref
5579               && info->ref->u.ar.type != AR_FULL)
5580             {
5581               base = fold_build2_loc (input_location, MINUS_EXPR,
5582                                       TREE_TYPE (base), base, stride);
5583             }
5584           else if (GFC_ARRAY_TYPE_P (TREE_TYPE (desc)))
5585             {
5586               tmp = gfc_conv_array_lbound (desc, n);
5587               tmp = fold_build2_loc (input_location, MINUS_EXPR,
5588                                      TREE_TYPE (base), tmp, loop.from[dim]);
5589               tmp = fold_build2_loc (input_location, MULT_EXPR,
5590                                      TREE_TYPE (base), tmp,
5591                                      gfc_conv_array_stride (desc, n));
5592               base = fold_build2_loc (input_location, PLUS_EXPR,
5593                                      TREE_TYPE (base), tmp, base);
5594             }
5595
5596           /* Store the new stride.  */
5597           gfc_conv_descriptor_stride_set (&loop.pre, parm,
5598                                           gfc_rank_cst[dim], stride);
5599         }
5600
5601       if (se->data_not_needed)
5602         gfc_conv_descriptor_data_set (&loop.pre, parm,
5603                                       gfc_index_zero_node);
5604       else
5605         /* Point the data pointer at the 1st element in the section.  */
5606         gfc_get_dataptr_offset (&loop.pre, parm, desc, offset,
5607                                 subref_array_target, expr);
5608
5609       if ((se->direct_byref || GFC_ARRAY_TYPE_P (TREE_TYPE (desc)))
5610           && !se->data_not_needed)
5611         {
5612           /* Set the offset.  */
5613           gfc_conv_descriptor_offset_set (&loop.pre, parm, base);
5614         }
5615       else
5616         {
5617           /* Only the callee knows what the correct offset it, so just set
5618              it to zero here.  */
5619           gfc_conv_descriptor_offset_set (&loop.pre, parm, gfc_index_zero_node);
5620         }
5621       desc = parm;
5622     }
5623
5624   if (!se->direct_byref || se->byref_noassign)
5625     {
5626       /* Get a pointer to the new descriptor.  */
5627       if (se->want_pointer)
5628         se->expr = gfc_build_addr_expr (NULL_TREE, desc);
5629       else
5630         se->expr = desc;
5631     }
5632
5633   gfc_add_block_to_block (&se->pre, &loop.pre);
5634   gfc_add_block_to_block (&se->post, &loop.post);
5635
5636   /* Cleanup the scalarizer.  */
5637   gfc_cleanup_loop (&loop);
5638 }
5639
5640 /* Helper function for gfc_conv_array_parameter if array size needs to be
5641    computed.  */
5642
5643 static void
5644 array_parameter_size (tree desc, gfc_expr *expr, tree *size)
5645 {
5646   tree elem;
5647   if (GFC_ARRAY_TYPE_P (TREE_TYPE (desc)))
5648     *size = GFC_TYPE_ARRAY_SIZE (TREE_TYPE (desc));
5649   else if (expr->rank > 1)
5650     *size = build_call_expr_loc (input_location,
5651                              gfor_fndecl_size0, 1,
5652                              gfc_build_addr_expr (NULL, desc));
5653   else
5654     {
5655       tree ubound = gfc_conv_descriptor_ubound_get (desc, gfc_index_zero_node);
5656       tree lbound = gfc_conv_descriptor_lbound_get (desc, gfc_index_zero_node);
5657
5658       *size = fold_build2_loc (input_location, MINUS_EXPR,
5659                                gfc_array_index_type, ubound, lbound);
5660       *size = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
5661                                *size, gfc_index_one_node);
5662       *size = fold_build2_loc (input_location, MAX_EXPR, gfc_array_index_type,
5663                                *size, gfc_index_zero_node);
5664     }
5665   elem = TYPE_SIZE_UNIT (gfc_get_element_type (TREE_TYPE (desc)));
5666   *size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
5667                            *size, fold_convert (gfc_array_index_type, elem));
5668 }
5669
5670 /* Convert an array for passing as an actual parameter.  */
5671 /* TODO: Optimize passing g77 arrays.  */
5672
5673 void
5674 gfc_conv_array_parameter (gfc_se * se, gfc_expr * expr, gfc_ss * ss, bool g77,
5675                           const gfc_symbol *fsym, const char *proc_name,
5676                           tree *size)
5677 {
5678   tree ptr;
5679   tree desc;
5680   tree tmp = NULL_TREE;
5681   tree stmt;
5682   tree parent = DECL_CONTEXT (current_function_decl);
5683   bool full_array_var;
5684   bool this_array_result;
5685   bool contiguous;
5686   bool no_pack;
5687   bool array_constructor;
5688   bool good_allocatable;
5689   bool ultimate_ptr_comp;
5690   bool ultimate_alloc_comp;
5691   gfc_symbol *sym;
5692   stmtblock_t block;
5693   gfc_ref *ref;
5694
5695   ultimate_ptr_comp = false;
5696   ultimate_alloc_comp = false;
5697
5698   for (ref = expr->ref; ref; ref = ref->next)
5699     {
5700       if (ref->next == NULL)
5701         break;
5702
5703       if (ref->type == REF_COMPONENT)
5704         {
5705           ultimate_ptr_comp = ref->u.c.component->attr.pointer;
5706           ultimate_alloc_comp = ref->u.c.component->attr.allocatable;
5707         }
5708     }
5709
5710   full_array_var = false;
5711   contiguous = false;
5712
5713   if (expr->expr_type == EXPR_VARIABLE && ref && !ultimate_ptr_comp)
5714     full_array_var = gfc_full_array_ref_p (ref, &contiguous);
5715
5716   sym = full_array_var ? expr->symtree->n.sym : NULL;
5717
5718   /* The symbol should have an array specification.  */
5719   gcc_assert (!sym || sym->as || ref->u.ar.as);
5720
5721   if (expr->expr_type == EXPR_ARRAY && expr->ts.type == BT_CHARACTER)
5722     {
5723       get_array_ctor_strlen (&se->pre, expr->value.constructor, &tmp);
5724       expr->ts.u.cl->backend_decl = tmp;
5725       se->string_length = tmp;
5726     }
5727
5728   /* Is this the result of the enclosing procedure?  */
5729   this_array_result = (full_array_var && sym->attr.flavor == FL_PROCEDURE);
5730   if (this_array_result
5731         && (sym->backend_decl != current_function_decl)
5732         && (sym->backend_decl != parent))
5733     this_array_result = false;
5734
5735   /* Passing address of the array if it is not pointer or assumed-shape.  */
5736   if (full_array_var && g77 && !this_array_result)
5737     {
5738       tmp = gfc_get_symbol_decl (sym);
5739
5740       if (sym->ts.type == BT_CHARACTER)
5741         se->string_length = sym->ts.u.cl->backend_decl;
5742
5743       if (sym->ts.type == BT_DERIVED)
5744         {
5745           gfc_conv_expr_descriptor (se, expr, ss);
5746           se->expr = gfc_conv_array_data (se->expr);
5747           return;
5748         }
5749
5750       if (!sym->attr.pointer
5751             && sym->as
5752             && sym->as->type != AS_ASSUMED_SHAPE 
5753             && !sym->attr.allocatable)
5754         {
5755           /* Some variables are declared directly, others are declared as
5756              pointers and allocated on the heap.  */
5757           if (sym->attr.dummy || POINTER_TYPE_P (TREE_TYPE (tmp)))
5758             se->expr = tmp;
5759           else
5760             se->expr = gfc_build_addr_expr (NULL_TREE, tmp);
5761           if (size)
5762             array_parameter_size (tmp, expr, size);
5763           return;
5764         }
5765
5766       if (sym->attr.allocatable)
5767         {
5768           if (sym->attr.dummy || sym->attr.result)
5769             {
5770               gfc_conv_expr_descriptor (se, expr, ss);
5771               tmp = se->expr;
5772             }
5773           if (size)
5774             array_parameter_size (tmp, expr, size);
5775           se->expr = gfc_conv_array_data (tmp);
5776           return;
5777         }
5778     }
5779
5780   /* A convenient reduction in scope.  */
5781   contiguous = g77 && !this_array_result && contiguous;
5782
5783   /* There is no need to pack and unpack the array, if it is contiguous
5784      and not a deferred- or assumed-shape array, or if it is simply
5785      contiguous.  */
5786   no_pack = ((sym && sym->as
5787                   && !sym->attr.pointer
5788                   && sym->as->type != AS_DEFERRED
5789                   && sym->as->type != AS_ASSUMED_SHAPE)
5790                       ||
5791              (ref && ref->u.ar.as
5792                   && ref->u.ar.as->type != AS_DEFERRED
5793                   && ref->u.ar.as->type != AS_ASSUMED_SHAPE)
5794                       ||
5795              gfc_is_simply_contiguous (expr, false));
5796
5797   no_pack = contiguous && no_pack;
5798
5799   /* Array constructors are always contiguous and do not need packing.  */
5800   array_constructor = g77 && !this_array_result && expr->expr_type == EXPR_ARRAY;
5801
5802   /* Same is true of contiguous sections from allocatable variables.  */
5803   good_allocatable = contiguous
5804                        && expr->symtree
5805                        && expr->symtree->n.sym->attr.allocatable;
5806
5807   /* Or ultimate allocatable components.  */
5808   ultimate_alloc_comp = contiguous && ultimate_alloc_comp; 
5809
5810   if (no_pack || array_constructor || good_allocatable || ultimate_alloc_comp)
5811     {
5812       gfc_conv_expr_descriptor (se, expr, ss);
5813       if (expr->ts.type == BT_CHARACTER)
5814         se->string_length = expr->ts.u.cl->backend_decl;
5815       if (size)
5816         array_parameter_size (se->expr, expr, size);
5817       se->expr = gfc_conv_array_data (se->expr);
5818       return;
5819     }
5820
5821   if (this_array_result)
5822     {
5823       /* Result of the enclosing function.  */
5824       gfc_conv_expr_descriptor (se, expr, ss);
5825       if (size)
5826         array_parameter_size (se->expr, expr, size);
5827       se->expr = gfc_build_addr_expr (NULL_TREE, se->expr);
5828
5829       if (g77 && TREE_TYPE (TREE_TYPE (se->expr)) != NULL_TREE
5830               && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (TREE_TYPE (se->expr))))
5831         se->expr = gfc_conv_array_data (build_fold_indirect_ref_loc (input_location,
5832                                                                  se->expr));
5833
5834       return;
5835     }
5836   else
5837     {
5838       /* Every other type of array.  */
5839       se->want_pointer = 1;
5840       gfc_conv_expr_descriptor (se, expr, ss);
5841       if (size)
5842         array_parameter_size (build_fold_indirect_ref_loc (input_location,
5843                                                        se->expr),
5844                                   expr, size);
5845     }
5846
5847   /* Deallocate the allocatable components of structures that are
5848      not variable.  */
5849   if (expr->ts.type == BT_DERIVED
5850         && expr->ts.u.derived->attr.alloc_comp
5851         && expr->expr_type != EXPR_VARIABLE)
5852     {
5853       tmp = build_fold_indirect_ref_loc (input_location,
5854                                      se->expr);
5855       tmp = gfc_deallocate_alloc_comp (expr->ts.u.derived, tmp, expr->rank);
5856       gfc_add_expr_to_block (&se->post, tmp);
5857     }
5858
5859   if (g77 || (fsym && fsym->attr.contiguous
5860               && !gfc_is_simply_contiguous (expr, false)))
5861     {
5862       tree origptr = NULL_TREE;
5863
5864       desc = se->expr;
5865
5866       /* For contiguous arrays, save the original value of the descriptor.  */
5867       if (!g77)
5868         {
5869           origptr = gfc_create_var (pvoid_type_node, "origptr");
5870           tmp = build_fold_indirect_ref_loc (input_location, desc);
5871           tmp = gfc_conv_array_data (tmp);
5872           tmp = fold_build2_loc (input_location, MODIFY_EXPR,
5873                                  TREE_TYPE (origptr), origptr,
5874                                  fold_convert (TREE_TYPE (origptr), tmp));
5875           gfc_add_expr_to_block (&se->pre, tmp);
5876         }
5877
5878       /* Repack the array.  */
5879       if (gfc_option.warn_array_temp)
5880         {
5881           if (fsym)
5882             gfc_warning ("Creating array temporary at %L for argument '%s'",
5883                          &expr->where, fsym->name);
5884           else
5885             gfc_warning ("Creating array temporary at %L", &expr->where);
5886         }
5887
5888       ptr = build_call_expr_loc (input_location,
5889                              gfor_fndecl_in_pack, 1, desc);
5890
5891       if (fsym && fsym->attr.optional && sym && sym->attr.optional)
5892         {
5893           tmp = gfc_conv_expr_present (sym);
5894           ptr = build3_loc (input_location, COND_EXPR, TREE_TYPE (se->expr),
5895                         tmp, fold_convert (TREE_TYPE (se->expr), ptr),
5896                         fold_convert (TREE_TYPE (se->expr), null_pointer_node));
5897         }
5898
5899       ptr = gfc_evaluate_now (ptr, &se->pre);
5900
5901       /* Use the packed data for the actual argument, except for contiguous arrays,
5902          where the descriptor's data component is set.  */
5903       if (g77)
5904         se->expr = ptr;
5905       else
5906         {
5907           tmp = build_fold_indirect_ref_loc (input_location, desc);
5908           gfc_conv_descriptor_data_set (&se->pre, tmp, ptr);
5909         }
5910
5911       if (gfc_option.rtcheck & GFC_RTCHECK_ARRAY_TEMPS)
5912         {
5913           char * msg;
5914
5915           if (fsym && proc_name)
5916             asprintf (&msg, "An array temporary was created for argument "
5917                       "'%s' of procedure '%s'", fsym->name, proc_name);
5918           else
5919             asprintf (&msg, "An array temporary was created");
5920
5921           tmp = build_fold_indirect_ref_loc (input_location,
5922                                          desc);
5923           tmp = gfc_conv_array_data (tmp);
5924           tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
5925                                  fold_convert (TREE_TYPE (tmp), ptr), tmp);
5926
5927           if (fsym && fsym->attr.optional && sym && sym->attr.optional)
5928             tmp = fold_build2_loc (input_location, TRUTH_AND_EXPR,
5929                                    boolean_type_node,
5930                                    gfc_conv_expr_present (sym), tmp);
5931
5932           gfc_trans_runtime_check (false, true, tmp, &se->pre,
5933                                    &expr->where, msg);
5934           gfc_free (msg);
5935         }
5936
5937       gfc_start_block (&block);
5938
5939       /* Copy the data back.  */
5940       if (fsym == NULL || fsym->attr.intent != INTENT_IN)
5941         {
5942           tmp = build_call_expr_loc (input_location,
5943                                  gfor_fndecl_in_unpack, 2, desc, ptr);
5944           gfc_add_expr_to_block (&block, tmp);
5945         }
5946
5947       /* Free the temporary.  */
5948       tmp = gfc_call_free (convert (pvoid_type_node, ptr));
5949       gfc_add_expr_to_block (&block, tmp);
5950
5951       stmt = gfc_finish_block (&block);
5952
5953       gfc_init_block (&block);
5954       /* Only if it was repacked.  This code needs to be executed before the
5955          loop cleanup code.  */
5956       tmp = build_fold_indirect_ref_loc (input_location,
5957                                      desc);
5958       tmp = gfc_conv_array_data (tmp);
5959       tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
5960                              fold_convert (TREE_TYPE (tmp), ptr), tmp);
5961
5962       if (fsym && fsym->attr.optional && sym && sym->attr.optional)
5963         tmp = fold_build2_loc (input_location, TRUTH_AND_EXPR,
5964                                boolean_type_node,
5965                                gfc_conv_expr_present (sym), tmp);
5966
5967       tmp = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt (input_location));
5968
5969       gfc_add_expr_to_block (&block, tmp);
5970       gfc_add_block_to_block (&block, &se->post);
5971
5972       gfc_init_block (&se->post);
5973
5974       /* Reset the descriptor pointer.  */
5975       if (!g77)
5976         {
5977           tmp = build_fold_indirect_ref_loc (input_location, desc);
5978           gfc_conv_descriptor_data_set (&se->post, tmp, origptr);
5979         }
5980
5981       gfc_add_block_to_block (&se->post, &block);
5982     }
5983 }
5984
5985
5986 /* Generate code to deallocate an array, if it is allocated.  */
5987
5988 tree
5989 gfc_trans_dealloc_allocated (tree descriptor)
5990
5991   tree tmp;
5992   tree var;
5993   stmtblock_t block;
5994
5995   gfc_start_block (&block);
5996
5997   var = gfc_conv_descriptor_data_get (descriptor);
5998   STRIP_NOPS (var);
5999
6000   /* Call array_deallocate with an int * present in the second argument.
6001      Although it is ignored here, it's presence ensures that arrays that
6002      are already deallocated are ignored.  */
6003   tmp = gfc_deallocate_with_status (var, NULL_TREE, true, NULL);
6004   gfc_add_expr_to_block (&block, tmp);
6005
6006   /* Zero the data pointer.  */
6007   tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node,
6008                          var, build_int_cst (TREE_TYPE (var), 0));
6009   gfc_add_expr_to_block (&block, tmp);
6010
6011   return gfc_finish_block (&block);
6012 }
6013
6014
6015 /* This helper function calculates the size in words of a full array.  */
6016
6017 static tree
6018 get_full_array_size (stmtblock_t *block, tree decl, int rank)
6019 {
6020   tree idx;
6021   tree nelems;
6022   tree tmp;
6023   idx = gfc_rank_cst[rank - 1];
6024   nelems = gfc_conv_descriptor_ubound_get (decl, idx);
6025   tmp = gfc_conv_descriptor_lbound_get (decl, idx);
6026   tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
6027                          nelems, tmp);
6028   tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
6029                          tmp, gfc_index_one_node);
6030   tmp = gfc_evaluate_now (tmp, block);
6031
6032   nelems = gfc_conv_descriptor_stride_get (decl, idx);
6033   tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
6034                          nelems, tmp);
6035   return gfc_evaluate_now (tmp, block);
6036 }
6037
6038
6039 /* Allocate dest to the same size as src, and copy src -> dest.
6040    If no_malloc is set, only the copy is done.  */
6041
6042 static tree
6043 duplicate_allocatable (tree dest, tree src, tree type, int rank,
6044                        bool no_malloc)
6045 {
6046   tree tmp;
6047   tree size;
6048   tree nelems;
6049   tree null_cond;
6050   tree null_data;
6051   stmtblock_t block;
6052
6053   /* If the source is null, set the destination to null.  Then,
6054      allocate memory to the destination.  */
6055   gfc_init_block (&block);
6056
6057   if (rank == 0)
6058     {
6059       tmp = null_pointer_node;
6060       tmp = fold_build2_loc (input_location, MODIFY_EXPR, type, dest, tmp);
6061       gfc_add_expr_to_block (&block, tmp);
6062       null_data = gfc_finish_block (&block);
6063
6064       gfc_init_block (&block);
6065       size = TYPE_SIZE_UNIT (type);
6066       if (!no_malloc)
6067         {
6068           tmp = gfc_call_malloc (&block, type, size);
6069           tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node,
6070                                  dest, fold_convert (type, tmp));
6071           gfc_add_expr_to_block (&block, tmp);
6072         }
6073
6074       tmp = built_in_decls[BUILT_IN_MEMCPY];
6075       tmp = build_call_expr_loc (input_location, tmp, 3,
6076                                  dest, src, size);
6077     }
6078   else
6079     {
6080       gfc_conv_descriptor_data_set (&block, dest, null_pointer_node);
6081       null_data = gfc_finish_block (&block);
6082
6083       gfc_init_block (&block);
6084       nelems = get_full_array_size (&block, src, rank);
6085       tmp = fold_convert (gfc_array_index_type,
6086                           TYPE_SIZE_UNIT (gfc_get_element_type (type)));
6087       size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
6088                               nelems, tmp);
6089       if (!no_malloc)
6090         {
6091           tmp = TREE_TYPE (gfc_conv_descriptor_data_get (src));
6092           tmp = gfc_call_malloc (&block, tmp, size);
6093           gfc_conv_descriptor_data_set (&block, dest, tmp);
6094         }
6095
6096       /* We know the temporary and the value will be the same length,
6097          so can use memcpy.  */
6098       tmp = built_in_decls[BUILT_IN_MEMCPY];
6099       tmp = build_call_expr_loc (input_location,
6100                         tmp, 3, gfc_conv_descriptor_data_get (dest),
6101                         gfc_conv_descriptor_data_get (src), size);
6102     }
6103
6104   gfc_add_expr_to_block (&block, tmp);
6105   tmp = gfc_finish_block (&block);
6106
6107   /* Null the destination if the source is null; otherwise do
6108      the allocate and copy.  */
6109   if (rank == 0)
6110     null_cond = src;
6111   else
6112     null_cond = gfc_conv_descriptor_data_get (src);
6113
6114   null_cond = convert (pvoid_type_node, null_cond);
6115   null_cond = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
6116                                null_cond, null_pointer_node);
6117   return build3_v (COND_EXPR, null_cond, tmp, null_data);
6118 }
6119
6120
6121 /* Allocate dest to the same size as src, and copy data src -> dest.  */
6122
6123 tree
6124 gfc_duplicate_allocatable (tree dest, tree src, tree type, int rank)
6125 {
6126   return duplicate_allocatable (dest, src, type, rank, false);
6127 }
6128
6129
6130 /* Copy data src -> dest.  */
6131
6132 tree
6133 gfc_copy_allocatable_data (tree dest, tree src, tree type, int rank)
6134 {
6135   return duplicate_allocatable (dest, src, type, rank, true);
6136 }
6137
6138
6139 /* Recursively traverse an object of derived type, generating code to
6140    deallocate, nullify or copy allocatable components.  This is the work horse
6141    function for the functions named in this enum.  */
6142
6143 enum {DEALLOCATE_ALLOC_COMP = 1, NULLIFY_ALLOC_COMP, COPY_ALLOC_COMP,
6144       COPY_ONLY_ALLOC_COMP};
6145
6146 static tree
6147 structure_alloc_comps (gfc_symbol * der_type, tree decl,
6148                        tree dest, int rank, int purpose)
6149 {
6150   gfc_component *c;
6151   gfc_loopinfo loop;
6152   stmtblock_t fnblock;
6153   stmtblock_t loopbody;
6154   tree decl_type;
6155   tree tmp;
6156   tree comp;
6157   tree dcmp;
6158   tree nelems;
6159   tree index;
6160   tree var;
6161   tree cdecl;
6162   tree ctype;
6163   tree vref, dref;
6164   tree null_cond = NULL_TREE;
6165
6166   gfc_init_block (&fnblock);
6167
6168   decl_type = TREE_TYPE (decl);
6169
6170   if ((POINTER_TYPE_P (decl_type) && rank != 0)
6171         || (TREE_CODE (decl_type) == REFERENCE_TYPE && rank == 0))
6172
6173     decl = build_fold_indirect_ref_loc (input_location,
6174                                     decl);
6175
6176   /* Just in case in gets dereferenced.  */
6177   decl_type = TREE_TYPE (decl);
6178
6179   /* If this an array of derived types with allocatable components
6180      build a loop and recursively call this function.  */
6181   if (TREE_CODE (decl_type) == ARRAY_TYPE
6182         || GFC_DESCRIPTOR_TYPE_P (decl_type))
6183     {
6184       tmp = gfc_conv_array_data (decl);
6185       var = build_fold_indirect_ref_loc (input_location,
6186                                      tmp);
6187         
6188       /* Get the number of elements - 1 and set the counter.  */
6189       if (GFC_DESCRIPTOR_TYPE_P (decl_type))
6190         {
6191           /* Use the descriptor for an allocatable array.  Since this
6192              is a full array reference, we only need the descriptor
6193              information from dimension = rank.  */
6194           tmp = get_full_array_size (&fnblock, decl, rank);
6195           tmp = fold_build2_loc (input_location, MINUS_EXPR,
6196                                  gfc_array_index_type, tmp,
6197                                  gfc_index_one_node);
6198
6199           null_cond = gfc_conv_descriptor_data_get (decl);
6200           null_cond = fold_build2_loc (input_location, NE_EXPR,
6201                                        boolean_type_node, null_cond,
6202                                        build_int_cst (TREE_TYPE (null_cond), 0));
6203         }
6204       else
6205         {
6206           /*  Otherwise use the TYPE_DOMAIN information.  */
6207           tmp =  array_type_nelts (decl_type);
6208           tmp = fold_convert (gfc_array_index_type, tmp);
6209         }
6210
6211       /* Remember that this is, in fact, the no. of elements - 1.  */
6212       nelems = gfc_evaluate_now (tmp, &fnblock);
6213       index = gfc_create_var (gfc_array_index_type, "S");
6214
6215       /* Build the body of the loop.  */
6216       gfc_init_block (&loopbody);
6217
6218       vref = gfc_build_array_ref (var, index, NULL);
6219
6220       if (purpose == COPY_ALLOC_COMP)
6221         {
6222           if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (dest)))
6223             {
6224               tmp = gfc_duplicate_allocatable (dest, decl, decl_type, rank);
6225               gfc_add_expr_to_block (&fnblock, tmp);
6226             }
6227           tmp = build_fold_indirect_ref_loc (input_location,
6228                                          gfc_conv_array_data (dest));
6229           dref = gfc_build_array_ref (tmp, index, NULL);
6230           tmp = structure_alloc_comps (der_type, vref, dref, rank, purpose);
6231         }
6232       else if (purpose == COPY_ONLY_ALLOC_COMP)
6233         {
6234           tmp = build_fold_indirect_ref_loc (input_location,
6235                                          gfc_conv_array_data (dest));
6236           dref = gfc_build_array_ref (tmp, index, NULL);
6237           tmp = structure_alloc_comps (der_type, vref, dref, rank,
6238                                        COPY_ALLOC_COMP);
6239         }
6240       else
6241         tmp = structure_alloc_comps (der_type, vref, NULL_TREE, rank, purpose);
6242
6243       gfc_add_expr_to_block (&loopbody, tmp);
6244
6245       /* Build the loop and return.  */
6246       gfc_init_loopinfo (&loop);
6247       loop.dimen = 1;
6248       loop.from[0] = gfc_index_zero_node;
6249       loop.loopvar[0] = index;
6250       loop.to[0] = nelems;
6251       gfc_trans_scalarizing_loops (&loop, &loopbody);
6252       gfc_add_block_to_block (&fnblock, &loop.pre);
6253
6254       tmp = gfc_finish_block (&fnblock);
6255       if (null_cond != NULL_TREE)
6256         tmp = build3_v (COND_EXPR, null_cond, tmp,
6257                         build_empty_stmt (input_location));
6258
6259       return tmp;
6260     }
6261
6262   /* Otherwise, act on the components or recursively call self to
6263      act on a chain of components.  */
6264   for (c = der_type->components; c; c = c->next)
6265     {
6266       bool cmp_has_alloc_comps = (c->ts.type == BT_DERIVED)
6267                                     && c->ts.u.derived->attr.alloc_comp;
6268       cdecl = c->backend_decl;
6269       ctype = TREE_TYPE (cdecl);
6270
6271       switch (purpose)
6272         {
6273         case DEALLOCATE_ALLOC_COMP:
6274           /* Do not deallocate the components of ultimate pointer
6275              components.  */
6276           if (cmp_has_alloc_comps && !c->attr.pointer)
6277             {
6278               comp = fold_build3_loc (input_location, COMPONENT_REF, ctype,
6279                                       decl, cdecl, NULL_TREE);
6280               rank = c->as ? c->as->rank : 0;
6281               tmp = structure_alloc_comps (c->ts.u.derived, comp, NULL_TREE,
6282                                            rank, purpose);
6283               gfc_add_expr_to_block (&fnblock, tmp);
6284             }
6285
6286           if (c->attr.allocatable && c->attr.dimension)
6287             {
6288               comp = fold_build3_loc (input_location, COMPONENT_REF, ctype,
6289                                       decl, cdecl, NULL_TREE);
6290               tmp = gfc_trans_dealloc_allocated (comp);
6291               gfc_add_expr_to_block (&fnblock, tmp);
6292             }
6293           else if (c->attr.allocatable)
6294             {
6295               /* Allocatable scalar components.  */
6296               comp = fold_build3_loc (input_location, COMPONENT_REF, ctype,
6297                                       decl, cdecl, NULL_TREE);
6298
6299               tmp = gfc_deallocate_with_status (comp, NULL_TREE, true, NULL);
6300               gfc_add_expr_to_block (&fnblock, tmp);
6301
6302               tmp = fold_build2_loc (input_location, MODIFY_EXPR,
6303                                      void_type_node, comp,
6304                                      build_int_cst (TREE_TYPE (comp), 0));
6305               gfc_add_expr_to_block (&fnblock, tmp);
6306             }
6307           else if (c->ts.type == BT_CLASS && CLASS_DATA (c)->attr.allocatable)
6308             {
6309               /* Allocatable scalar CLASS components.  */
6310               comp = fold_build3_loc (input_location, COMPONENT_REF, ctype,
6311                                       decl, cdecl, NULL_TREE);
6312               
6313               /* Add reference to '$data' component.  */
6314               tmp = CLASS_DATA (c)->backend_decl;
6315               comp = fold_build3_loc (input_location, COMPONENT_REF,
6316                                       TREE_TYPE (tmp), comp, tmp, NULL_TREE);
6317
6318               tmp = gfc_deallocate_with_status (comp, NULL_TREE, true, NULL);
6319               gfc_add_expr_to_block (&fnblock, tmp);
6320
6321               tmp = fold_build2_loc (input_location, MODIFY_EXPR,
6322                                      void_type_node, comp,
6323                                      build_int_cst (TREE_TYPE (comp), 0));
6324               gfc_add_expr_to_block (&fnblock, tmp);
6325             }
6326           break;
6327
6328         case NULLIFY_ALLOC_COMP:
6329           if (c->attr.pointer)
6330             continue;
6331           else if (c->attr.allocatable && c->attr.dimension)
6332             {
6333               comp = fold_build3_loc (input_location, COMPONENT_REF, ctype,
6334                                       decl, cdecl, NULL_TREE);
6335               gfc_conv_descriptor_data_set (&fnblock, comp, null_pointer_node);
6336             }
6337           else if (c->attr.allocatable)
6338             {
6339               /* Allocatable scalar components.  */
6340               comp = fold_build3_loc (input_location, COMPONENT_REF, ctype,
6341                                       decl, cdecl, NULL_TREE);
6342               tmp = fold_build2_loc (input_location, MODIFY_EXPR,
6343                                      void_type_node, comp,
6344                                      build_int_cst (TREE_TYPE (comp), 0));
6345               gfc_add_expr_to_block (&fnblock, tmp);
6346             }
6347           else if (c->ts.type == BT_CLASS && CLASS_DATA (c)->attr.allocatable)
6348             {
6349               /* Allocatable scalar CLASS components.  */
6350               comp = fold_build3_loc (input_location, COMPONENT_REF, ctype,
6351                                       decl, cdecl, NULL_TREE);
6352               /* Add reference to '$data' component.  */
6353               tmp = CLASS_DATA (c)->backend_decl;
6354               comp = fold_build3_loc (input_location, COMPONENT_REF,
6355                                       TREE_TYPE (tmp), comp, tmp, NULL_TREE);
6356               tmp = fold_build2_loc (input_location, MODIFY_EXPR,
6357                                      void_type_node, comp,
6358                                      build_int_cst (TREE_TYPE (comp), 0));
6359               gfc_add_expr_to_block (&fnblock, tmp);
6360             }
6361           else if (cmp_has_alloc_comps)
6362             {
6363               comp = fold_build3_loc (input_location, COMPONENT_REF, ctype,
6364                                       decl, cdecl, NULL_TREE);
6365               rank = c->as ? c->as->rank : 0;
6366               tmp = structure_alloc_comps (c->ts.u.derived, comp, NULL_TREE,
6367                                            rank, purpose);
6368               gfc_add_expr_to_block (&fnblock, tmp);
6369             }
6370           break;
6371
6372         case COPY_ALLOC_COMP:
6373           if (c->attr.pointer)
6374             continue;
6375
6376           /* We need source and destination components.  */
6377           comp = fold_build3_loc (input_location, COMPONENT_REF, ctype, decl,
6378                                   cdecl, NULL_TREE);
6379           dcmp = fold_build3_loc (input_location, COMPONENT_REF, ctype, dest,
6380                                   cdecl, NULL_TREE);
6381           dcmp = fold_convert (TREE_TYPE (comp), dcmp);
6382
6383           if (c->attr.allocatable && !cmp_has_alloc_comps)
6384             {
6385               rank = c->as ? c->as->rank : 0;
6386               tmp = gfc_duplicate_allocatable (dcmp, comp, ctype, rank);
6387               gfc_add_expr_to_block (&fnblock, tmp);
6388             }
6389
6390           if (cmp_has_alloc_comps)
6391             {
6392               rank = c->as ? c->as->rank : 0;
6393               tmp = fold_convert (TREE_TYPE (dcmp), comp);
6394               gfc_add_modify (&fnblock, dcmp, tmp);
6395               tmp = structure_alloc_comps (c->ts.u.derived, comp, dcmp,
6396                                            rank, purpose);
6397               gfc_add_expr_to_block (&fnblock, tmp);
6398             }
6399           break;
6400
6401         default:
6402           gcc_unreachable ();
6403           break;
6404         }
6405     }
6406
6407   return gfc_finish_block (&fnblock);
6408 }
6409
6410 /* Recursively traverse an object of derived type, generating code to
6411    nullify allocatable components.  */
6412
6413 tree
6414 gfc_nullify_alloc_comp (gfc_symbol * der_type, tree decl, int rank)
6415 {
6416   return structure_alloc_comps (der_type, decl, NULL_TREE, rank,
6417                                 NULLIFY_ALLOC_COMP);
6418 }
6419
6420
6421 /* Recursively traverse an object of derived type, generating code to
6422    deallocate allocatable components.  */
6423
6424 tree
6425 gfc_deallocate_alloc_comp (gfc_symbol * der_type, tree decl, int rank)
6426 {
6427   return structure_alloc_comps (der_type, decl, NULL_TREE, rank,
6428                                 DEALLOCATE_ALLOC_COMP);
6429 }
6430
6431
6432 /* Recursively traverse an object of derived type, generating code to
6433    copy it and its allocatable components.  */
6434
6435 tree
6436 gfc_copy_alloc_comp (gfc_symbol * der_type, tree decl, tree dest, int rank)
6437 {
6438   return structure_alloc_comps (der_type, decl, dest, rank, COPY_ALLOC_COMP);
6439 }
6440
6441
6442 /* Recursively traverse an object of derived type, generating code to
6443    copy only its allocatable components.  */
6444
6445 tree
6446 gfc_copy_only_alloc_comp (gfc_symbol * der_type, tree decl, tree dest, int rank)
6447 {
6448   return structure_alloc_comps (der_type, decl, dest, rank, COPY_ONLY_ALLOC_COMP);
6449 }
6450
6451
6452 /* NULLIFY an allocatable/pointer array on function entry, free it on exit.
6453    Do likewise, recursively if necessary, with the allocatable components of
6454    derived types.  */
6455
6456 void
6457 gfc_trans_deferred_array (gfc_symbol * sym, gfc_wrapped_block * block)
6458 {
6459   tree type;
6460   tree tmp;
6461   tree descriptor;
6462   stmtblock_t init;
6463   stmtblock_t cleanup;
6464   locus loc;
6465   int rank;
6466   bool sym_has_alloc_comp;
6467
6468   sym_has_alloc_comp = (sym->ts.type == BT_DERIVED)
6469                           && sym->ts.u.derived->attr.alloc_comp;
6470
6471   /* Make sure the frontend gets these right.  */
6472   if (!(sym->attr.pointer || sym->attr.allocatable || sym_has_alloc_comp))
6473     fatal_error ("Possible frontend bug: Deferred array size without pointer, "
6474                  "allocatable attribute or derived type without allocatable "
6475                  "components.");
6476
6477   gfc_init_block (&init);
6478
6479   gcc_assert (TREE_CODE (sym->backend_decl) == VAR_DECL
6480                 || TREE_CODE (sym->backend_decl) == PARM_DECL);
6481
6482   if (sym->ts.type == BT_CHARACTER
6483       && !INTEGER_CST_P (sym->ts.u.cl->backend_decl))
6484     {
6485       gfc_conv_string_length (sym->ts.u.cl, NULL, &init);
6486       gfc_trans_vla_type_sizes (sym, &init);
6487     }
6488
6489   /* Dummy, use associated and result variables don't need anything special.  */
6490   if (sym->attr.dummy || sym->attr.use_assoc || sym->attr.result)
6491     {
6492       gfc_add_init_cleanup (block, gfc_finish_block (&init), NULL_TREE);
6493       return;
6494     }
6495
6496   gfc_get_backend_locus (&loc);
6497   gfc_set_backend_locus (&sym->declared_at);
6498   descriptor = sym->backend_decl;
6499
6500   /* Although static, derived types with default initializers and
6501      allocatable components must not be nulled wholesale; instead they
6502      are treated component by component.  */
6503   if (TREE_STATIC (descriptor) && !sym_has_alloc_comp)
6504     {
6505       /* SAVEd variables are not freed on exit.  */
6506       gfc_trans_static_array_pointer (sym);
6507
6508       gfc_add_init_cleanup (block, gfc_finish_block (&init), NULL_TREE);
6509       return;
6510     }
6511
6512   /* Get the descriptor type.  */
6513   type = TREE_TYPE (sym->backend_decl);
6514
6515   if (sym_has_alloc_comp && !(sym->attr.pointer || sym->attr.allocatable))
6516     {
6517       if (!sym->attr.save
6518           && !(TREE_STATIC (sym->backend_decl) && sym->attr.is_main_program))
6519         {
6520           if (sym->value == NULL
6521               || !gfc_has_default_initializer (sym->ts.u.derived))
6522             {
6523               rank = sym->as ? sym->as->rank : 0;
6524               tmp = gfc_nullify_alloc_comp (sym->ts.u.derived,
6525                                             descriptor, rank);
6526               gfc_add_expr_to_block (&init, tmp);
6527             }
6528           else
6529             gfc_init_default_dt (sym, &init, false);
6530         }
6531     }
6532   else if (!GFC_DESCRIPTOR_TYPE_P (type))
6533     {
6534       /* If the backend_decl is not a descriptor, we must have a pointer
6535          to one.  */
6536       descriptor = build_fold_indirect_ref_loc (input_location,
6537                                                 sym->backend_decl);
6538       type = TREE_TYPE (descriptor);
6539     }
6540   
6541   /* NULLIFY the data pointer.  */
6542   if (GFC_DESCRIPTOR_TYPE_P (type) && !sym->attr.save)
6543     gfc_conv_descriptor_data_set (&init, descriptor, null_pointer_node);
6544
6545   gfc_init_block (&cleanup);
6546   gfc_set_backend_locus (&loc);
6547
6548   /* Allocatable arrays need to be freed when they go out of scope.
6549      The allocatable components of pointers must not be touched.  */
6550   if (sym_has_alloc_comp && !(sym->attr.function || sym->attr.result)
6551       && !sym->attr.pointer && !sym->attr.save)
6552     {
6553       int rank;
6554       rank = sym->as ? sym->as->rank : 0;
6555       tmp = gfc_deallocate_alloc_comp (sym->ts.u.derived, descriptor, rank);
6556       gfc_add_expr_to_block (&cleanup, tmp);
6557     }
6558
6559   if (sym->attr.allocatable && sym->attr.dimension
6560       && !sym->attr.save && !sym->attr.result)
6561     {
6562       tmp = gfc_trans_dealloc_allocated (sym->backend_decl);
6563       gfc_add_expr_to_block (&cleanup, tmp);
6564     }
6565
6566   gfc_add_init_cleanup (block, gfc_finish_block (&init),
6567                         gfc_finish_block (&cleanup));
6568 }
6569
6570 /************ Expression Walking Functions ******************/
6571
6572 /* Walk a variable reference.
6573
6574    Possible extension - multiple component subscripts.
6575     x(:,:) = foo%a(:)%b(:)
6576    Transforms to
6577     forall (i=..., j=...)
6578       x(i,j) = foo%a(j)%b(i)
6579     end forall
6580    This adds a fair amount of complexity because you need to deal with more
6581    than one ref.  Maybe handle in a similar manner to vector subscripts.
6582    Maybe not worth the effort.  */
6583
6584
6585 static gfc_ss *
6586 gfc_walk_variable_expr (gfc_ss * ss, gfc_expr * expr)
6587 {
6588   gfc_ref *ref;
6589   gfc_array_ref *ar;
6590   gfc_ss *newss;
6591   int n;
6592
6593   for (ref = expr->ref; ref; ref = ref->next)
6594     if (ref->type == REF_ARRAY && ref->u.ar.type != AR_ELEMENT)
6595       break;
6596
6597   for (; ref; ref = ref->next)
6598     {
6599       if (ref->type == REF_SUBSTRING)
6600         {
6601           newss = gfc_get_ss ();
6602           newss->type = GFC_SS_SCALAR;
6603           newss->expr = ref->u.ss.start;
6604           newss->next = ss;
6605           ss = newss;
6606
6607           newss = gfc_get_ss ();
6608           newss->type = GFC_SS_SCALAR;
6609           newss->expr = ref->u.ss.end;
6610           newss->next = ss;
6611           ss = newss;
6612         }
6613
6614       /* We're only interested in array sections from now on.  */
6615       if (ref->type != REF_ARRAY)
6616         continue;
6617
6618       ar = &ref->u.ar;
6619
6620       if (ar->as->rank == 0)
6621         {
6622           /* Scalar coarray.  */
6623           continue;
6624         }
6625
6626       switch (ar->type)
6627         {
6628         case AR_ELEMENT:
6629           for (n = 0; n < ar->dimen; n++)
6630             {
6631               newss = gfc_get_ss ();
6632               newss->type = GFC_SS_SCALAR;
6633               newss->expr = ar->start[n];
6634               newss->next = ss;
6635               ss = newss;
6636             }
6637           break;
6638
6639         case AR_FULL:
6640           newss = gfc_get_ss ();
6641           newss->type = GFC_SS_SECTION;
6642           newss->expr = expr;
6643           newss->next = ss;
6644           newss->data.info.dimen = ar->as->rank;
6645           newss->data.info.ref = ref;
6646
6647           /* Make sure array is the same as array(:,:), this way
6648              we don't need to special case all the time.  */
6649           ar->dimen = ar->as->rank;
6650           for (n = 0; n < ar->dimen; n++)
6651             {
6652               newss->data.info.dim[n] = n;
6653               ar->dimen_type[n] = DIMEN_RANGE;
6654
6655               gcc_assert (ar->start[n] == NULL);
6656               gcc_assert (ar->end[n] == NULL);
6657               gcc_assert (ar->stride[n] == NULL);
6658             }
6659           ss = newss;
6660           break;
6661
6662         case AR_SECTION:
6663           newss = gfc_get_ss ();
6664           newss->type = GFC_SS_SECTION;
6665           newss->expr = expr;
6666           newss->next = ss;
6667           newss->data.info.dimen = 0;
6668           newss->data.info.ref = ref;
6669
6670           /* We add SS chains for all the subscripts in the section.  */
6671           for (n = 0; n < ar->dimen; n++)
6672             {
6673               gfc_ss *indexss;
6674
6675               switch (ar->dimen_type[n])
6676                 {
6677                 case DIMEN_ELEMENT:
6678                   /* Add SS for elemental (scalar) subscripts.  */
6679                   gcc_assert (ar->start[n]);
6680                   indexss = gfc_get_ss ();
6681                   indexss->type = GFC_SS_SCALAR;
6682                   indexss->expr = ar->start[n];
6683                   indexss->next = gfc_ss_terminator;
6684                   indexss->loop_chain = gfc_ss_terminator;
6685                   newss->data.info.subscript[n] = indexss;
6686                   break;
6687
6688                 case DIMEN_RANGE:
6689                   /* We don't add anything for sections, just remember this
6690                      dimension for later.  */
6691                   newss->data.info.dim[newss->data.info.dimen] = n;
6692                   newss->data.info.dimen++;
6693                   break;
6694
6695                 case DIMEN_VECTOR:
6696                   /* Create a GFC_SS_VECTOR index in which we can store
6697                      the vector's descriptor.  */
6698                   indexss = gfc_get_ss ();
6699                   indexss->type = GFC_SS_VECTOR;
6700                   indexss->expr = ar->start[n];
6701                   indexss->next = gfc_ss_terminator;
6702                   indexss->loop_chain = gfc_ss_terminator;
6703                   newss->data.info.subscript[n] = indexss;
6704                   newss->data.info.dim[newss->data.info.dimen] = n;
6705                   newss->data.info.dimen++;
6706                   break;
6707
6708                 default:
6709                   /* We should know what sort of section it is by now.  */
6710                   gcc_unreachable ();
6711                 }
6712             }
6713           /* We should have at least one non-elemental dimension.  */
6714           gcc_assert (newss->data.info.dimen > 0);
6715           ss = newss;
6716           break;
6717
6718         default:
6719           /* We should know what sort of section it is by now.  */
6720           gcc_unreachable ();
6721         }
6722
6723     }
6724   return ss;
6725 }
6726
6727
6728 /* Walk an expression operator. If only one operand of a binary expression is
6729    scalar, we must also add the scalar term to the SS chain.  */
6730
6731 static gfc_ss *
6732 gfc_walk_op_expr (gfc_ss * ss, gfc_expr * expr)
6733 {
6734   gfc_ss *head;
6735   gfc_ss *head2;
6736   gfc_ss *newss;
6737
6738   head = gfc_walk_subexpr (ss, expr->value.op.op1);
6739   if (expr->value.op.op2 == NULL)
6740     head2 = head;
6741   else
6742     head2 = gfc_walk_subexpr (head, expr->value.op.op2);
6743
6744   /* All operands are scalar.  Pass back and let the caller deal with it.  */
6745   if (head2 == ss)
6746     return head2;
6747
6748   /* All operands require scalarization.  */
6749   if (head != ss && (expr->value.op.op2 == NULL || head2 != head))
6750     return head2;
6751
6752   /* One of the operands needs scalarization, the other is scalar.
6753      Create a gfc_ss for the scalar expression.  */
6754   newss = gfc_get_ss ();
6755   newss->type = GFC_SS_SCALAR;
6756   if (head == ss)
6757     {
6758       /* First operand is scalar.  We build the chain in reverse order, so
6759          add the scalar SS after the second operand.  */
6760       head = head2;
6761       while (head && head->next != ss)
6762         head = head->next;
6763       /* Check we haven't somehow broken the chain.  */
6764       gcc_assert (head);
6765       newss->next = ss;
6766       head->next = newss;
6767       newss->expr = expr->value.op.op1;
6768     }
6769   else                          /* head2 == head */
6770     {
6771       gcc_assert (head2 == head);
6772       /* Second operand is scalar.  */
6773       newss->next = head2;
6774       head2 = newss;
6775       newss->expr = expr->value.op.op2;
6776     }
6777
6778   return head2;
6779 }
6780
6781
6782 /* Reverse a SS chain.  */
6783
6784 gfc_ss *
6785 gfc_reverse_ss (gfc_ss * ss)
6786 {
6787   gfc_ss *next;
6788   gfc_ss *head;
6789
6790   gcc_assert (ss != NULL);
6791
6792   head = gfc_ss_terminator;
6793   while (ss != gfc_ss_terminator)
6794     {
6795       next = ss->next;
6796       /* Check we didn't somehow break the chain.  */
6797       gcc_assert (next != NULL);
6798       ss->next = head;
6799       head = ss;
6800       ss = next;
6801     }
6802
6803   return (head);
6804 }
6805
6806
6807 /* Walk the arguments of an elemental function.  */
6808
6809 gfc_ss *
6810 gfc_walk_elemental_function_args (gfc_ss * ss, gfc_actual_arglist *arg,
6811                                   gfc_ss_type type)
6812 {
6813   int scalar;
6814   gfc_ss *head;
6815   gfc_ss *tail;
6816   gfc_ss *newss;
6817
6818   head = gfc_ss_terminator;
6819   tail = NULL;
6820   scalar = 1;
6821   for (; arg; arg = arg->next)
6822     {
6823       if (!arg->expr)
6824         continue;
6825
6826       newss = gfc_walk_subexpr (head, arg->expr);
6827       if (newss == head)
6828         {
6829           /* Scalar argument.  */
6830           newss = gfc_get_ss ();
6831           newss->type = type;
6832           newss->expr = arg->expr;
6833           newss->next = head;
6834         }
6835       else
6836         scalar = 0;
6837
6838       head = newss;
6839       if (!tail)
6840         {
6841           tail = head;
6842           while (tail->next != gfc_ss_terminator)
6843             tail = tail->next;
6844         }
6845     }
6846
6847   if (scalar)
6848     {
6849       /* If all the arguments are scalar we don't need the argument SS.  */
6850       gfc_free_ss_chain (head);
6851       /* Pass it back.  */
6852       return ss;
6853     }
6854
6855   /* Add it onto the existing chain.  */
6856   tail->next = ss;
6857   return head;
6858 }
6859
6860
6861 /* Walk a function call.  Scalar functions are passed back, and taken out of
6862    scalarization loops.  For elemental functions we walk their arguments.
6863    The result of functions returning arrays is stored in a temporary outside
6864    the loop, so that the function is only called once.  Hence we do not need
6865    to walk their arguments.  */
6866
6867 static gfc_ss *
6868 gfc_walk_function_expr (gfc_ss * ss, gfc_expr * expr)
6869 {
6870   gfc_ss *newss;
6871   gfc_intrinsic_sym *isym;
6872   gfc_symbol *sym;
6873   gfc_component *comp = NULL;
6874   int n;
6875
6876   isym = expr->value.function.isym;
6877
6878   /* Handle intrinsic functions separately.  */
6879   if (isym)
6880     return gfc_walk_intrinsic_function (ss, expr, isym);
6881
6882   sym = expr->value.function.esym;
6883   if (!sym)
6884       sym = expr->symtree->n.sym;
6885
6886   /* A function that returns arrays.  */
6887   gfc_is_proc_ptr_comp (expr, &comp);
6888   if ((!comp && gfc_return_by_reference (sym) && sym->result->attr.dimension)
6889       || (comp && comp->attr.dimension))
6890     {
6891       newss = gfc_get_ss ();
6892       newss->type = GFC_SS_FUNCTION;
6893       newss->expr = expr;
6894       newss->next = ss;
6895       newss->data.info.dimen = expr->rank;
6896       for (n = 0; n < newss->data.info.dimen; n++)
6897         newss->data.info.dim[n] = n;
6898       return newss;
6899     }
6900
6901   /* Walk the parameters of an elemental function.  For now we always pass
6902      by reference.  */
6903   if (sym->attr.elemental)
6904     return gfc_walk_elemental_function_args (ss, expr->value.function.actual,
6905                                              GFC_SS_REFERENCE);
6906
6907   /* Scalar functions are OK as these are evaluated outside the scalarization
6908      loop.  Pass back and let the caller deal with it.  */
6909   return ss;
6910 }
6911
6912
6913 /* An array temporary is constructed for array constructors.  */
6914
6915 static gfc_ss *
6916 gfc_walk_array_constructor (gfc_ss * ss, gfc_expr * expr)
6917 {
6918   gfc_ss *newss;
6919   int n;
6920
6921   newss = gfc_get_ss ();
6922   newss->type = GFC_SS_CONSTRUCTOR;
6923   newss->expr = expr;
6924   newss->next = ss;
6925   newss->data.info.dimen = expr->rank;
6926   for (n = 0; n < expr->rank; n++)
6927     newss->data.info.dim[n] = n;
6928
6929   return newss;
6930 }
6931
6932
6933 /* Walk an expression.  Add walked expressions to the head of the SS chain.
6934    A wholly scalar expression will not be added.  */
6935
6936 gfc_ss *
6937 gfc_walk_subexpr (gfc_ss * ss, gfc_expr * expr)
6938 {
6939   gfc_ss *head;
6940
6941   switch (expr->expr_type)
6942     {
6943     case EXPR_VARIABLE:
6944       head = gfc_walk_variable_expr (ss, expr);
6945       return head;
6946
6947     case EXPR_OP:
6948       head = gfc_walk_op_expr (ss, expr);
6949       return head;
6950
6951     case EXPR_FUNCTION:
6952       head = gfc_walk_function_expr (ss, expr);
6953       return head;
6954
6955     case EXPR_CONSTANT:
6956     case EXPR_NULL:
6957     case EXPR_STRUCTURE:
6958       /* Pass back and let the caller deal with it.  */
6959       break;
6960
6961     case EXPR_ARRAY:
6962       head = gfc_walk_array_constructor (ss, expr);
6963       return head;
6964
6965     case EXPR_SUBSTRING:
6966       /* Pass back and let the caller deal with it.  */
6967       break;
6968
6969     default:
6970       internal_error ("bad expression type during walk (%d)",
6971                       expr->expr_type);
6972     }
6973   return ss;
6974 }
6975
6976
6977 /* Entry point for expression walking.
6978    A return value equal to the passed chain means this is
6979    a scalar expression.  It is up to the caller to take whatever action is
6980    necessary to translate these.  */
6981
6982 gfc_ss *
6983 gfc_walk_expr (gfc_expr * expr)
6984 {
6985   gfc_ss *res;
6986
6987   res = gfc_walk_subexpr (gfc_ss_terminator, expr);
6988   return gfc_reverse_ss (res);
6989 }