OSDN Git Service

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