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