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